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
19 void ITimer::Initialize(ITimedEvent *pCallbacks, float fInterval, float fToExec, void *pData, int flags)
21 m_Listener = pCallbacks;
22 m_Interval = fInterval;
30 TimerSystem::~TimerSystem()
32 CStack<ITimer *>::iterator iter;
33 for (iter=m_FreeTimers.begin(); iter!=m_FreeTimers.end(); iter++)
37 m_FreeTimers.popall();
40 void TimerSystem::OnSourceModAllInitialized()
42 g_ShareSys.AddInterface(NULL, this);
45 void TimerSystem::RunFrame()
50 for (iter=m_SingleTimers.begin(); iter!=m_SingleTimers.end(); )
53 if (gpGlobals->curtime >= pTimer->m_ToExec)
55 pTimer->m_InExec = true;
56 pTimer->m_Listener->OnTimer(pTimer, pTimer->m_pData);
57 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
58 iter = m_SingleTimers.erase(iter);
59 m_FreeTimers.push(pTimer);
66 for (iter=m_LoopTimers.begin(); iter!=m_LoopTimers.end(); )
69 if (gpGlobals->curtime >= pTimer->m_ToExec)
71 pTimer->m_InExec = true;
72 res = pTimer->m_Listener->OnTimer(pTimer, pTimer->m_pData);
73 if (pTimer->m_KillMe || (res == Pl_Stop))
75 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
76 iter = m_LoopTimers.erase(iter);
77 m_FreeTimers.push(pTimer);
80 pTimer->m_InExec = false;
81 pTimer->m_ToExec = gpGlobals->curtime + pTimer->m_Interval;
86 m_LastExecTime = gpGlobals->curtime;
89 ITimer *TimerSystem::CreateTimer(ITimedEvent *pCallbacks, float fInterval, void *pData, int flags)
93 float to_exec = gpGlobals->curtime + fInterval;
95 if (m_FreeTimers.empty())
99 pTimer = m_FreeTimers.front();
103 pTimer->Initialize(pCallbacks, fInterval, to_exec, pData, flags);
105 if (flags & TIMER_FLAG_REPEAT)
107 m_LoopTimers.push_back(pTimer);
111 if (m_SingleTimers.size() >= 1)
113 iter = --m_SingleTimers.end();
114 if ((*iter)->m_ToExec <= to_exec)
120 for (iter=m_SingleTimers.begin(); iter!=m_SingleTimers.end(); iter++)
122 if ((*iter)->m_ToExec >= to_exec)
124 m_SingleTimers.insert(iter, pTimer);
130 m_SingleTimers.push_back(pTimer);
136 void TimerSystem::FireTimerOnce(ITimer *pTimer, bool delayExec)
140 if (pTimer->m_InExec)
145 pTimer->m_InExec = true;
146 res = pTimer->m_Listener->OnTimer(pTimer, pTimer->m_pData);
148 if (!(pTimer->m_Flags & TIMER_FLAG_REPEAT))
150 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
151 m_SingleTimers.remove(pTimer);
152 m_FreeTimers.push(pTimer);
154 if ((res != Pl_Stop) && !pTimer->m_KillMe)
158 pTimer->m_ToExec = gpGlobals->curtime + pTimer->m_Interval;
160 pTimer->m_InExec = false;
163 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
164 m_LoopTimers.remove(pTimer);
165 m_FreeTimers.push(pTimer);
169 void TimerSystem::KillTimer(ITimer *pTimer)
173 if (pTimer->m_KillMe)
178 if (pTimer->m_InExec)
180 pTimer->m_KillMe = true;
184 pTimer->m_InExec = true; /* The timer it's not really executed but this check needs to be done */
185 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
187 pList = (pTimer->m_Flags & TIMER_FLAG_REPEAT) ? &m_LoopTimers : &m_SingleTimers;
189 pList->remove(pTimer);
190 m_FreeTimers.push(pTimer);
193 void TimerSystem::MapChange()
198 for (iter=m_SingleTimers.begin(); iter!=m_SingleTimers.end(); iter++)
201 pTimer->m_ToExec = pTimer->m_ToExec - m_LastExecTime + gpGlobals->curtime;
204 for (iter=m_LoopTimers.begin(); iter!=m_LoopTimers.end(); iter++)
207 pTimer->m_ToExec = pTimer->m_ToExec - m_LastExecTime + gpGlobals->curtime;