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 void TimerSystem::OnSourceModAllInitialized()
32 g_ShareSys.AddInterface(NULL, this);
35 void TimerSystem::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);
47 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
48 iter = m_SingleTimers.erase(iter);
49 m_FreeTimers.push(pTimer);
56 for (iter=m_LoopTimers.begin(); iter!=m_LoopTimers.end(); )
59 if (gpGlobals->curtime >= pTimer->m_ToExec)
61 pTimer->m_InExec = true;
62 res = pTimer->m_Listener->OnTimer(pTimer, pTimer->m_pData);
63 if (pTimer->m_KillMe || (res == Pl_Stop))
65 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
66 iter = m_LoopTimers.erase(iter);
67 m_FreeTimers.push(pTimer);
70 pTimer->m_InExec = false;
71 pTimer->m_ToExec = gpGlobals->curtime + pTimer->m_Interval;
76 m_LastExecTime = gpGlobals->curtime;
79 ITimer *TimerSystem::CreateTimer(ITimedEvent *pCallbacks, float fInterval, void *pData, int flags)
83 float to_exec = gpGlobals->curtime + fInterval;
85 if (m_FreeTimers.empty())
89 pTimer = m_FreeTimers.front();
93 pTimer->Initialize(pCallbacks, fInterval, to_exec, pData, flags);
95 if (flags & TIMER_FLAG_REPEAT)
97 m_LoopTimers.push_back(pTimer);
101 if (m_SingleTimers.size() >= 1)
103 iter = --m_SingleTimers.end();
104 if ((*iter)->m_ToExec <= to_exec)
110 for (iter=m_SingleTimers.begin(); iter!=m_SingleTimers.end(); iter++)
112 if ((*iter)->m_ToExec >= to_exec)
114 m_SingleTimers.insert(iter, pTimer);
120 m_SingleTimers.push_back(pTimer);
126 void TimerSystem::FireTimerOnce(ITimer *pTimer, bool delayExec)
130 if (pTimer->m_InExec)
135 pTimer->m_InExec = true;
136 res = pTimer->m_Listener->OnTimer(pTimer, pTimer->m_pData);
138 if (!(pTimer->m_Flags & TIMER_FLAG_REPEAT))
140 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
141 m_SingleTimers.remove(pTimer);
142 m_FreeTimers.push(pTimer);
144 if ((res != Pl_Stop) && !pTimer->m_KillMe)
148 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 TimerSystem::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 TimerSystem::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;