//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef SIMTIMER_H #define SIMTIMER_H #if defined(_WIN32) #pragma once #endif #define ST_EPS 0.001 #define DEFINE_SIMTIMER(type, name) DEFINE_EMBEDDED(type, name) //----------------------------------------------------------------------------- class CSimpleSimTimer { public: CSimpleSimTimer() : m_next(-1) {} void Force() { m_next = -1; } bool Expired() const { return (gpGlobals->curtime - m_next > -ST_EPS); } float Delay(float delayTime) { return (m_next += delayTime); } float GetNext() const { return m_next; } void Set(float interval) { m_next = gpGlobals->curtime + interval; } void Set(float minInterval, float maxInterval) { if (maxInterval > 0.0) m_next = gpGlobals->curtime + random->RandomFloat(minInterval, maxInterval); else m_next = gpGlobals->curtime + minInterval; } float GetRemaining() const { float result = m_next - gpGlobals->curtime; if (result < 0) return 0; return result; } DECLARE_SIMPLE_DATADESC(); protected: float m_next; }; //----------------------------------------------------------------------------- class CSimTimer : public CSimpleSimTimer { public: CSimTimer(float interval = 0.0, bool startExpired = true) { Set(interval, startExpired); } void Set(float interval, bool startExpired = true) { m_interval = interval; m_next = (startExpired) ? -1.0 : gpGlobals->curtime + m_interval; } void Reset(float interval = -1.0) { if (interval == -1.0) { m_next = gpGlobals->curtime + m_interval; } else { m_next = gpGlobals->curtime + interval; } } float GetInterval() const { return m_interval; } DECLARE_SIMPLE_DATADESC(); private: float m_interval; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- class CRandSimTimer : public CSimpleSimTimer { public: CRandSimTimer(float minInterval = 0.0, float maxInterval = 0.0, bool startExpired = true) { Set(minInterval, maxInterval, startExpired); } void Set(float minInterval, float maxInterval = 0.0, bool startExpired = true) { m_minInterval = minInterval; m_maxInterval = maxInterval; if (startExpired) { m_next = -1; } else { if (m_maxInterval == 0) m_next = gpGlobals->curtime + m_minInterval; else m_next = gpGlobals->curtime + random->RandomFloat(m_minInterval, m_maxInterval); } } void Reset() { if (m_maxInterval == 0) m_next = gpGlobals->curtime + m_minInterval; else m_next = gpGlobals->curtime + random->RandomFloat(m_minInterval, m_maxInterval); } float GetMinInterval() const { return m_minInterval; } float GetMaxInterval() const { return m_maxInterval; } DECLARE_SIMPLE_DATADESC(); private: float m_minInterval; float m_maxInterval; }; //----------------------------------------------------------------------------- class CStopwatchBase : public CSimpleSimTimer { public: CStopwatchBase() { m_fIsRunning = false; } bool IsRunning() const { return m_fIsRunning; } void Stop() { m_fIsRunning = false; } bool Expired() const { return (m_fIsRunning && CSimpleSimTimer::Expired()); } DECLARE_SIMPLE_DATADESC(); protected: bool m_fIsRunning; }; //------------------------------------- class CSimpleStopwatch : public CStopwatchBase { public: void Start(float minCountdown, float maxCountdown = 0.0) { m_fIsRunning = true; CSimpleSimTimer::Set(minCountdown, maxCountdown); } void Stop() { m_fIsRunning = false; } bool Expired() const { return (m_fIsRunning && CSimpleSimTimer::Expired()); } }; //------------------------------------- class CStopwatch : public CStopwatchBase { public: CStopwatch(float interval = 0.0) { Set(interval); } void Set(float interval) { m_interval = interval; } void Start(float intervalOverride) { m_fIsRunning = true; m_next = gpGlobals->curtime + intervalOverride; } void Start() { Start(m_interval); } float GetInterval() const { return m_interval; } DECLARE_SIMPLE_DATADESC(); private: float m_interval; }; //------------------------------------- class CRandStopwatch : public CStopwatchBase { public: CRandStopwatch(float minInterval = 0.0, float maxInterval = 0.0) { Set(minInterval, maxInterval); } void Set(float minInterval, float maxInterval = 0.0) { m_minInterval = minInterval; m_maxInterval = maxInterval; } void Start(float minOverride, float maxOverride = 0.0) { m_fIsRunning = true; if (maxOverride == 0) m_next = gpGlobals->curtime + minOverride; else m_next = gpGlobals->curtime + random->RandomFloat(minOverride, maxOverride); } void Start() { Start(m_minInterval, m_maxInterval); } float GetInterval() const { return m_minInterval; } float GetMinInterval() const { return m_minInterval; } float GetMaxInterval() const { return m_maxInterval; } DECLARE_SIMPLE_DATADESC(); private: float m_minInterval; float m_maxInterval; }; //----------------------------------------------------------------------------- class CThinkOnceSemaphore { public: CThinkOnceSemaphore() : m_lastTime(-1) {} bool EnterThink() { if (m_lastTime == gpGlobals->curtime) return false; m_lastTime = gpGlobals->curtime; return true; } bool DidThink() const { return (gpGlobals->curtime == m_lastTime); } void SetDidThink() { m_lastTime = gpGlobals->curtime; } private: float m_lastTime; }; //----------------------------------------------------------------------------- #endif // SIMTIMER_H