Revert "fix: Remove pending timer logic" (#1417)

This commit is contained in:
Aaron Kimbrell 2024-01-14 15:05:50 -06:00 committed by GitHub
parent c83ec8228c
commit 99b3705a76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 18 deletions

View File

@ -1243,18 +1243,12 @@ void Entity::Update(const float deltaTime) {
// If the timer is expired, erase it and dont increment the position because the next timer will be at the same position. // If the timer is expired, erase it and dont increment the position because the next timer will be at the same position.
// Before: [0, 1, 2, 3, ..., n] // Before: [0, 1, 2, 3, ..., n]
// timerPosition ^ // timerPosition ^
// After: [0, 1, n, ..., n - 1] 2 is expired and removed now // After: [0, 1, 3, ..., n]
// timerPosition ^ // timerPosition ^
if (timer.GetTime() <= 0) { if (timer.GetTime() <= 0) {
// Remove the timer from the list of timers first so that scripts and events can remove timers without causing iterator invalidation // Remove the timer from the list of timers first so that scripts and events can remove timers without causing iterator invalidation
auto timerName = timer.GetName(); auto timerName = timer.GetName();
// We don't need to copy the element if there is only 1 element nor do we need to copy if we are on the last element. m_Timers.erase(m_Timers.begin() + timerPosition);
// This is a clever removal trick that avoids having to copy the entire vector and instead replaces this now expired
// element with the last element in the vector and then removes the last element.
if (m_Timers.size() > 1 && timerPosition < m_Timers.size() - 1) {
m_Timers[timerPosition] = m_Timers[m_Timers.size() - 1];
}
m_Timers.erase(m_Timers.end() - 1);
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) {
script->OnTimerDone(this, timerName); script->OnTimerDone(this, timerName);
} }
@ -1270,26 +1264,31 @@ void Entity::Update(const float deltaTime) {
// If the timer is expired, erase it and dont increment the position because the next timer will be at the same position. // If the timer is expired, erase it and dont increment the position because the next timer will be at the same position.
// Before: [0, 1, 2, 3, ..., n] // Before: [0, 1, 2, 3, ..., n]
// timerPosition ^ // timerPosition ^
// After: [0, 1, n, ..., n - 1] 2 is expired and removed now // After: [0, 1, 3, ..., n]
// timerPosition ^ // timerPosition ^
auto& callbackTimer = m_CallbackTimers[timerPosition]; auto& callbackTimer = m_CallbackTimers[timerPosition];
callbackTimer.Update(deltaTime); callbackTimer.Update(deltaTime);
if (callbackTimer.GetTime() <= 0) { if (callbackTimer.GetTime() <= 0) {
// Remove the timer from the list of timers first so that callbacks can remove timers without causing iterator invalidation // Remove the timer from the list of timers first so that callbacks can remove timers without causing iterator invalidation
auto callback = callbackTimer.GetCallback(); auto callback = callbackTimer.GetCallback();
// We don't need to copy the element if there is only 1 element nor do we need to copy if we are on the last element. m_CallbackTimers.erase(m_CallbackTimers.begin() + timerPosition);
// This is a clever removal trick that avoids having to copy the entire vector and instead replaces this now expired
// element with the last element in the vector and then removes the last element.
if (m_CallbackTimers.size() > 1 && timerPosition < m_CallbackTimers.size() - 1) {
m_CallbackTimers[timerPosition] = m_CallbackTimers[m_CallbackTimers.size() - 1];
}
m_CallbackTimers.erase(m_CallbackTimers.end() - 1);
callback(); callback();
} else { } else {
timerPosition++; timerPosition++;
} }
} }
// Add pending timers to the list of timers so they start next tick.
if (!m_PendingTimers.empty()) {
m_Timers.insert(m_Timers.end(), m_PendingTimers.begin(), m_PendingTimers.end());
m_PendingTimers.clear();
}
if (!m_PendingCallbackTimers.empty()) {
m_CallbackTimers.insert(m_CallbackTimers.end(), m_PendingCallbackTimers.begin(), m_PendingCallbackTimers.end());
m_PendingCallbackTimers.clear();
}
if (IsSleeping()) { if (IsSleeping()) {
Sleep(); Sleep();
@ -1725,11 +1724,11 @@ void Entity::RemoveParent() {
} }
void Entity::AddTimer(std::string name, float time) { void Entity::AddTimer(std::string name, float time) {
m_Timers.emplace_back(name, time); m_PendingTimers.emplace_back(name, time);
} }
void Entity::AddCallbackTimer(float time, std::function<void()> callback) { void Entity::AddCallbackTimer(float time, std::function<void()> callback) {
m_CallbackTimers.emplace_back(time, callback); m_PendingCallbackTimers.emplace_back(time, callback);
} }
bool Entity::HasTimer(const std::string& name) { bool Entity::HasTimer(const std::string& name) {
@ -1738,6 +1737,7 @@ bool Entity::HasTimer(const std::string& name) {
void Entity::CancelCallbackTimers() { void Entity::CancelCallbackTimers() {
m_CallbackTimers.clear(); m_CallbackTimers.clear();
m_PendingCallbackTimers.clear();
} }
void Entity::ScheduleKillAfterUpdate(Entity* murderer) { void Entity::ScheduleKillAfterUpdate(Entity* murderer) {
@ -1759,7 +1759,9 @@ void Entity::CancelTimer(const std::string& name) {
void Entity::CancelAllTimers() { void Entity::CancelAllTimers() {
m_Timers.clear(); m_Timers.clear();
m_PendingTimers.clear();
m_CallbackTimers.clear(); m_CallbackTimers.clear();
m_PendingCallbackTimers.clear();
} }
bool Entity::IsPlayer() const { bool Entity::IsPlayer() const {

View File

@ -330,7 +330,9 @@ protected:
std::unordered_map<eReplicaComponentType, Component*> m_Components; std::unordered_map<eReplicaComponentType, Component*> m_Components;
std::vector<EntityTimer> m_Timers; std::vector<EntityTimer> m_Timers;
std::vector<EntityTimer> m_PendingTimers;
std::vector<EntityCallbackTimer> m_CallbackTimers; std::vector<EntityCallbackTimer> m_CallbackTimers;
std::vector<EntityCallbackTimer> m_PendingCallbackTimers;
bool m_ShouldDestroyAfterUpdate = false; bool m_ShouldDestroyAfterUpdate = false;