From 559dd9946988cd35a7c26bcafe7d0f8c42dc547a Mon Sep 17 00:00:00 2001 From: Ekdohibs Date: Mon, 21 Mar 2016 12:58:52 +0100 Subject: Make node timers more efficient --- src/nodetimer.h | 77 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 16 deletions(-) (limited to 'src/nodetimer.h') diff --git a/src/nodetimer.h b/src/nodetimer.h index 9fb56edec..0fd43b2a8 100644 --- a/src/nodetimer.h +++ b/src/nodetimer.h @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irr_v3d.h" #include #include +#include /* NodeTimer provides per-node timed callback functionality. @@ -36,8 +37,10 @@ class NodeTimer { public: NodeTimer(): timeout(0.), elapsed(0.) {} - NodeTimer(f32 timeout_, f32 elapsed_): - timeout(timeout_), elapsed(elapsed_) {} + NodeTimer(const v3s16 &position_): + timeout(0.), elapsed(0.), position(position_) {} + NodeTimer(f32 timeout_, f32 elapsed_, v3s16 position_): + timeout(timeout_), elapsed(elapsed_), position(position_) {} ~NodeTimer() {} void serialize(std::ostream &os) const; @@ -45,6 +48,7 @@ public: f32 timeout; f32 elapsed; + v3s16 position; }; /* @@ -54,37 +58,78 @@ public: class NodeTimerList { public: - NodeTimerList() {} + NodeTimerList(): m_next_trigger_time(-1.), m_time(0.) {} ~NodeTimerList() {} void serialize(std::ostream &os, u8 map_format_version) const; void deSerialize(std::istream &is, u8 map_format_version); // Get timer - NodeTimer get(v3s16 p){ - std::map::iterator n = m_data.find(p); - if(n == m_data.end()) + NodeTimer get(const v3s16 &p) { + std::map::iterator>::iterator n = + m_iterators.find(p); + if (n == m_iterators.end()) return NodeTimer(); - return n->second; + NodeTimer t = n->second->second; + t.elapsed = t.timeout - (n->second->first - m_time); + return t; } // Deletes timer - void remove(v3s16 p){ - m_data.erase(p); + void remove(v3s16 p) { + std::map::iterator>::iterator n = + m_iterators.find(p); + if(n != m_iterators.end()) { + double removed_time = n->second->first; + m_timers.erase(n->second); + m_iterators.erase(n); + // Yes, this is float equality, but it is not a problem + // since we only test equality of floats as an ordered type + // and thus we never lose precision + if (removed_time == m_next_trigger_time) { + if (m_timers.empty()) + m_next_trigger_time = -1.; + else + m_next_trigger_time = m_timers.begin()->first; + } + } + } + // Undefined behaviour if there already is a timer + void insert(NodeTimer timer) { + v3s16 p = timer.position; + double trigger_time = m_time + (double)(timer.timeout - timer.elapsed); + std::multimap::iterator it = + m_timers.insert(std::pair( + trigger_time, timer + )); + m_iterators.insert( + std::pair::iterator>(p, it)); + if (m_next_trigger_time == -1. || trigger_time < m_next_trigger_time) + m_next_trigger_time = trigger_time; } // Deletes old timer and sets a new one - void set(v3s16 p, NodeTimer t){ - m_data[p] = t; + inline void set(const NodeTimer &timer) { + remove(timer.position); + insert(timer); } // Deletes all timers - void clear(){ - m_data.clear(); + void clear() { + m_timers.clear(); + m_iterators.clear(); + m_next_trigger_time = -1.; + } + + inline double getNextTriggerTime() { + return m_next_trigger_time; } - // A step in time. Returns map of elapsed timers. - std::map step(float dtime); + // Move forward in time, returns elapsed timers + std::vector step(float dtime); private: - std::map m_data; + std::multimap m_timers; + std::map::iterator> m_iterators; + double m_next_trigger_time; + double m_time; }; #endif -- cgit v1.2.3