// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef RY_TIMER_H #define RY_TIMER_H #include "nel/misc/types_nl.h" #include "nel/misc/common.h" #include "time_interface.h" extern NLMISC::CVariable TimerSpeedUp; //-------------------------------------------------------------------------- // CAITimer class //-------------------------------------------------------------------------- class CAITimer { public: CAITimer(uint32 dt = 0); // SET TIMER // set timer to current time +dt (in ticks) void set(uint32 dt); // EXTEND TIMER END TIME // add dt to timer's current value (in ticks) void add(uint32 dt); // EXTEND TIMER END TIME // sub dt to timer's current value (in ticks) void sub(uint32 dt); // TEST TIMER // return true if the timer expired at or before time bool test(uint32 time=CTimeInterface::gameCycle()) const; // GET TICK COUNT CAPPED BY TIMER // if test() then return (timer strat time + dt) - oldTime (in ticks) // else return current time - oldTime (in ticks) uint32 ticksSince(uint32 oldTime) const; // Returns the time spend since we start the Timer. sint32 timeSinceStart() const; // GET TIME REMAINING // if test() then return 0 // else return time remaining sint32 timeRemaining() const; // GET TOTAL TIME // return total time sint32 totalTime() const; // TIME REMAINING AS STRING FOR DEBUG std::string toString(uint padding=0) const; protected: uint32 _start; uint32 _dt; }; //-------------------------------------------------------------------------- // CAITimerWithEnable class //-------------------------------------------------------------------------- class CAITimerExtended: public CAITimer { public: CAITimerExtended(uint32 dt); CAITimerExtended(); // SET TIMER // set timer to current time +dt (in ticks) and set the '_enabled' flag, clear 'suspended' state void set(uint32 dt); // EXTEND TIMER END TIME // add dt to timer's current value (in ticks) and set the '_enabled' flag // if suspended add to suspended dt (but don't resume) void add(uint32 dt); // EXTEND TIMER END TIME // remove dt to timer's current value (in ticks) and set the '_enabled' flag // if suspended remove to suspended dt (but don't resume) void sub(uint32 dt); // DISABLE // clear the '_enabled' flag void disable(); // SUSPEND // if suspended() or not enabled() do nothing and return // store the remaining time for use in resume() void suspend(); // RESUME // set the timer with the remaining time stored by suspend() void resume(); // TEST TIMER ONCE // return true if enabled() and not suspended() set and the timer expired at or before time // if test result is true '_enabled' flag is cleared before the routine returns bool testOnce(uint32 time=CTimeInterface::gameCycle()); // GET TIME REMAINING // if test() then return 0 // else if suspended() return suspended dt // else return time remaining sint32 timeRemaining() const; // ENABLED // return state of '_enabled' flag bool isEnabled() const; // SUSPENDED // return the state of the '_suspend' flag bool isSuspended() const; // TIME REMAINING AS STRING FOR DEBUG std::string toString(uint padding=0) const; protected: bool _enabled; uint32 _suspendRemainingTime; }; //-------------------------------------------------------------------------- // CAITimer Inlines //-------------------------------------------------------------------------- inline CAITimer::CAITimer(uint32 dt /*= 0*/) { set(dt); } inline void CAITimer::set(uint32 dt) { _start = CTimeInterface::gameCycle(); _dt = dt; } inline void CAITimer::add(uint32 dt) { _start += _dt; _dt = dt; } inline void CAITimer::sub(uint32 dt) { if (_start > dt) { _start -= dt; //_dt = dt; } else { _start = 0; } } inline bool CAITimer::test(uint32 time) const { return ((sint32)(time - _start-(_dt/TimerSpeedUp))>=0); } inline uint32 CAITimer::ticksSince(uint32 oldTime) const { const uint32 curent = CTimeInterface::gameCycle(); if (_dt>=(curent-_start)) return curent-oldTime; if ( (sint32)(_start+_dt-oldTime) > 0 ) return _start+_dt-oldTime; return 0; } inline sint32 CAITimer::timeRemaining() const { const uint32 curent = CTimeInterface::gameCycle(); const uint32 elapsed = curent - _start; if (elapsed >= (_dt/TimerSpeedUp)) return 0; return (_dt/TimerSpeedUp)-elapsed; } inline sint32 CAITimer::timeSinceStart() const { return CTimeInterface::gameCycle()-_start; } inline sint32 CAITimer::totalTime() const { return _dt; } inline std::string CAITimer::toString(uint padding) const { std::string s=NLMISC::toString(timeRemaining()); while (s.size() dt) { _suspendRemainingTime -= dt; } else { _suspendRemainingTime=0; } } else { CAITimer::sub(dt); _enabled=true; } } inline void CAITimerExtended::disable() { _enabled=false; _suspendRemainingTime=0; } inline void CAITimerExtended::suspend() { if (isEnabled() && !isSuspended()) _suspendRemainingTime=CAITimer::timeRemaining(); } inline void CAITimerExtended::resume() { if (isEnabled() && isSuspended()) set(_suspendRemainingTime); _suspendRemainingTime=0; } inline bool CAITimerExtended::testOnce(uint32 time) { if (!isEnabled() || isSuspended() || !test()) return false; _enabled=false; return true; } inline sint32 CAITimerExtended::timeRemaining() const { if (isSuspended()) return _suspendRemainingTime; else if (isEnabled()) return CAITimer::timeRemaining(); else return 0; } inline bool CAITimerExtended::isEnabled() const { return _enabled; } inline bool CAITimerExtended::isSuspended() const { return _suspendRemainingTime!=0; } inline std::string CAITimerExtended::toString(uint padding) const { if (!isEnabled()) return NLMISC::toString("%*s",padding,"DISABLED"); if (isSuspended()) return NLMISC::toString("HOLD:%*i",padding-5>0?padding-5:1,_suspendRemainingTime); return CAITimer::toString(padding); } //-------------------------------------------------------------------------- #endif