mirror of
				https://github.com/DarkflameUniverse/DarkflameServer.git
				synced 2025-11-04 14:42:02 +00:00 
			
		
		
		
	fix: Remove pending timer logic (#1416)
* remove pending timers they serve no purpose anymore since iterator invalidation is a non-issue. I added this initially to make it so if you added a timer this frame, there would be at least 1 frame before you would start it, but this in practice doesnt serve a purpose * timers still work
This commit is contained in:
		@@ -1243,12 +1243,18 @@ 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.
 | 
			
		||||
		// Before: [0, 1, 2, 3, ..., n]
 | 
			
		||||
		// timerPosition  ^
 | 
			
		||||
		// After:  [0, 1, 3, ..., n]
 | 
			
		||||
		// After:  [0, 1, n, ..., n - 1] 2 is expired and removed now
 | 
			
		||||
		// timerPosition  ^
 | 
			
		||||
		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
 | 
			
		||||
			auto timerName = timer.GetName();
 | 
			
		||||
			m_Timers.erase(m_Timers.begin() + timerPosition);
 | 
			
		||||
			// 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.
 | 
			
		||||
			// 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)) {
 | 
			
		||||
				script->OnTimerDone(this, timerName);
 | 
			
		||||
			}
 | 
			
		||||
@@ -1264,31 +1270,26 @@ 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.
 | 
			
		||||
		// Before: [0, 1, 2, 3, ..., n]
 | 
			
		||||
		// timerPosition  ^
 | 
			
		||||
		// After:  [0, 1, 3, ..., n]
 | 
			
		||||
		// After:  [0, 1, n, ..., n - 1] 2 is expired and removed now
 | 
			
		||||
		// timerPosition  ^
 | 
			
		||||
		auto& callbackTimer = m_CallbackTimers[timerPosition];
 | 
			
		||||
		callbackTimer.Update(deltaTime);
 | 
			
		||||
		if (callbackTimer.GetTime() <= 0) {
 | 
			
		||||
			// Remove the timer from the list of timers first so that callbacks can remove timers without causing iterator invalidation
 | 
			
		||||
			auto callback = callbackTimer.GetCallback();
 | 
			
		||||
			m_CallbackTimers.erase(m_CallbackTimers.begin() + timerPosition);
 | 
			
		||||
			// 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.
 | 
			
		||||
			// 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();
 | 
			
		||||
		} else {
 | 
			
		||||
			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()) {
 | 
			
		||||
		Sleep();
 | 
			
		||||
 | 
			
		||||
@@ -1724,11 +1725,11 @@ void Entity::RemoveParent() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Entity::AddTimer(std::string name, float time) {
 | 
			
		||||
	m_PendingTimers.emplace_back(name, time);
 | 
			
		||||
	m_Timers.emplace_back(name, time);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Entity::AddCallbackTimer(float time, std::function<void()> callback) {
 | 
			
		||||
	m_PendingCallbackTimers.emplace_back(time, callback);
 | 
			
		||||
	m_CallbackTimers.emplace_back(time, callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Entity::HasTimer(const std::string& name) {
 | 
			
		||||
@@ -1737,7 +1738,6 @@ bool Entity::HasTimer(const std::string& name) {
 | 
			
		||||
 | 
			
		||||
void Entity::CancelCallbackTimers() {
 | 
			
		||||
	m_CallbackTimers.clear();
 | 
			
		||||
	m_PendingCallbackTimers.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Entity::ScheduleKillAfterUpdate(Entity* murderer) {
 | 
			
		||||
@@ -1759,9 +1759,7 @@ void Entity::CancelTimer(const std::string& name) {
 | 
			
		||||
 | 
			
		||||
void Entity::CancelAllTimers() {
 | 
			
		||||
	m_Timers.clear();
 | 
			
		||||
	m_PendingTimers.clear();
 | 
			
		||||
	m_CallbackTimers.clear();
 | 
			
		||||
	m_PendingCallbackTimers.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Entity::IsPlayer() const {
 | 
			
		||||
 
 | 
			
		||||
@@ -330,9 +330,7 @@ protected:
 | 
			
		||||
 | 
			
		||||
	std::unordered_map<eReplicaComponentType, Component*> m_Components;
 | 
			
		||||
	std::vector<EntityTimer> m_Timers;
 | 
			
		||||
	std::vector<EntityTimer> m_PendingTimers;
 | 
			
		||||
	std::vector<EntityCallbackTimer> m_CallbackTimers;
 | 
			
		||||
	std::vector<EntityCallbackTimer> m_PendingCallbackTimers;
 | 
			
		||||
 | 
			
		||||
	bool m_ShouldDestroyAfterUpdate = false;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user