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::OnSourceModLevelChange(const char *mapName)
50 void TimerSystem::RunFrame()
55 for (iter=m_SingleTimers.begin(); iter!=m_SingleTimers.end(); )
58 if (gpGlobals->curtime >= pTimer->m_ToExec)
60 pTimer->m_InExec = true;
61 pTimer->m_Listener->OnTimer(pTimer, pTimer->m_pData);
62 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
63 iter = m_SingleTimers.erase(iter);
64 m_FreeTimers.push(pTimer);
71 for (iter=m_LoopTimers.begin(); iter!=m_LoopTimers.end(); )
74 if (gpGlobals->curtime >= pTimer->m_ToExec)
76 pTimer->m_InExec = true;
77 res = pTimer->m_Listener->OnTimer(pTimer, pTimer->m_pData);
78 if (pTimer->m_KillMe || (res == Pl_Stop))
80 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
81 iter = m_LoopTimers.erase(iter);
82 m_FreeTimers.push(pTimer);
85 pTimer->m_InExec = false;
86 pTimer->m_ToExec = gpGlobals->curtime + pTimer->m_Interval;
91 m_LastExecTime = gpGlobals->curtime;
94 ITimer *TimerSystem::CreateTimer(ITimedEvent *pCallbacks, float fInterval, void *pData, int flags)
98 float to_exec = gpGlobals->curtime + fInterval;
100 if (m_FreeTimers.empty())
104 pTimer = m_FreeTimers.front();
108 pTimer->Initialize(pCallbacks, fInterval, to_exec, pData, flags);
110 if (flags & TIMER_FLAG_REPEAT)
112 m_LoopTimers.push_back(pTimer);
116 if (m_SingleTimers.size() >= 1)
118 iter = --m_SingleTimers.end();
119 if ((*iter)->m_ToExec <= to_exec)
125 for (iter=m_SingleTimers.begin(); iter!=m_SingleTimers.end(); iter++)
127 if ((*iter)->m_ToExec >= to_exec)
129 m_SingleTimers.insert(iter, pTimer);
135 m_SingleTimers.push_back(pTimer);
141 void TimerSystem::FireTimerOnce(ITimer *pTimer, bool delayExec)
145 if (pTimer->m_InExec)
150 pTimer->m_InExec = true;
151 res = pTimer->m_Listener->OnTimer(pTimer, pTimer->m_pData);
153 if (!(pTimer->m_Flags & TIMER_FLAG_REPEAT))
155 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
156 m_SingleTimers.remove(pTimer);
157 m_FreeTimers.push(pTimer);
159 if ((res != Pl_Stop) && !pTimer->m_KillMe)
163 pTimer->m_ToExec = gpGlobals->curtime + pTimer->m_Interval;
165 pTimer->m_InExec = false;
168 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
169 m_LoopTimers.remove(pTimer);
170 m_FreeTimers.push(pTimer);
174 void TimerSystem::KillTimer(ITimer *pTimer)
178 if (pTimer->m_KillMe)
183 if (pTimer->m_InExec)
185 pTimer->m_KillMe = true;
189 pTimer->m_InExec = true; /* The timer it's not really executed but this check needs to be done */
190 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
192 pList = (pTimer->m_Flags & TIMER_FLAG_REPEAT) ? &m_LoopTimers : &m_SingleTimers;
194 pList->remove(pTimer);
195 m_FreeTimers.push(pTimer);
198 void TimerSystem::MapChange()
203 for (iter=m_SingleTimers.begin(); iter!=m_SingleTimers.end(); iter++)
206 pTimer->m_ToExec = pTimer->m_ToExec - m_LastExecTime + gpGlobals->curtime;
209 for (iter=m_LoopTimers.begin(); iter!=m_LoopTimers.end(); iter++)
212 pTimer->m_ToExec = pTimer->m_ToExec - m_LastExecTime + gpGlobals->curtime;