3 * ===============================================================
4 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
5 * ===============================================================
7 * This file is not open source and may not be copied without explicit
8 * written permission of AlliedModders LLC. This file may not be redistributed
9 * in whole or significant part.
10 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
17 CTimerSystem g_Timers;
19 void ITimer::Initialize(ITimedEvent *pCallbacks, float fInterval, float fToExec, void *pData, int flags)
21 m_Listener = pCallbacks;
22 m_Interval = fInterval;
30 void CTimerSystem::OnSourceModAllInitialized()
32 g_ShareSys.AddInterface(NULL, this);
35 void CTimerSystem::RunFrame()
40 for (iter=m_SingleTimers.begin(); iter!=m_SingleTimers.end(); )
43 if (gpGlobals->curtime >= pTimer->m_ToExec)
45 pTimer->m_InExec = true;
46 pTimer->m_Listener->OnTimer(pTimer, pTimer->m_pData);
49 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
51 iter = m_SingleTimers.erase(iter);
52 m_FreeTimers.push(pTimer);
59 for (iter=m_LoopTimers.begin(); iter!=m_LoopTimers.end(); )
62 if (gpGlobals->curtime >= pTimer->m_ToExec)
64 pTimer->m_InExec = true;
65 res = pTimer->m_Listener->OnTimer(pTimer, pTimer->m_pData);
66 if (pTimer->m_KillMe || (res == Pl_Stop))
68 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
69 iter = m_LoopTimers.erase(iter);
70 m_FreeTimers.push(pTimer);
73 pTimer->m_InExec = false;
74 pTimer->m_ToExec = gpGlobals->curtime + pTimer->m_Interval;
79 m_LastExecTime = gpGlobals->curtime;
82 ITimer *CTimerSystem::CreateTimer(ITimedEvent *pCallbacks, float fInterval, void *pData, int flags)
86 float to_exec = gpGlobals->curtime + fInterval;
88 if (m_FreeTimers.empty())
92 pTimer = m_FreeTimers.front();
96 pTimer->Initialize(pCallbacks, fInterval, to_exec, pData, flags);
98 if (flags & TIMER_FLAG_REPEAT)
100 m_LoopTimers.push_back(pTimer);
104 if (m_SingleTimers.size() >= 1)
106 iter = --m_SingleTimers.end();
107 if ((*iter)->m_ToExec <= to_exec)
113 for (iter=m_SingleTimers.begin(); iter!=m_SingleTimers.end(); iter++)
115 if ((*iter)->m_ToExec >= to_exec)
117 m_SingleTimers.insert(iter, pTimer);
123 m_SingleTimers.push_back(pTimer);
129 void CTimerSystem::FireTimerOnce(ITimer *pTimer, bool delayExec)
133 if (pTimer->m_InExec)
138 pTimer->m_InExec = true;
139 res = pTimer->m_Listener->OnTimer(pTimer, pTimer->m_pData);
141 if (!(pTimer->m_Flags & TIMER_FLAG_REPEAT))
143 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
144 m_SingleTimers.remove(pTimer);
145 m_FreeTimers.push(pTimer);
147 if (delayExec && (res != Pl_Stop) && !pTimer->m_KillMe)
149 pTimer->m_ToExec = gpGlobals->curtime + pTimer->m_Interval;
150 pTimer->m_InExec = false;
153 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
154 m_LoopTimers.remove(pTimer);
155 m_FreeTimers.push(pTimer);
159 void CTimerSystem::KillTimer(ITimer *pTimer)
163 if (pTimer->m_KillMe)
168 if (pTimer->m_InExec)
170 pTimer->m_KillMe = true;
174 pTimer->m_InExec = true; /* The timer it's not really executed but this check needs to be done */
175 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
177 pList = (pTimer->m_Flags & TIMER_FLAG_REPEAT) ? &m_LoopTimers : &m_SingleTimers;
179 pList->remove(pTimer);
180 m_FreeTimers.push(pTimer);
183 void CTimerSystem::MapChange()
188 for (iter=m_SingleTimers.begin(); iter!=m_SingleTimers.end(); iter++)
191 pTimer->m_ToExec = pTimer->m_ToExec - m_LastExecTime + gpGlobals->curtime;
194 for (iter=m_LoopTimers.begin(); iter!=m_LoopTimers.end(); iter++)
197 pTimer->m_ToExec = pTimer->m_ToExec - m_LastExecTime + gpGlobals->curtime;