/* * Author: Needles * https://steamcommunity.com/profiles/76561198026257137/ */ ::Debug.Print("*** TIMERS"); const TIMER_REPEAT_INFINITE = -1; ::Timers <- {}; ::Timers.timerList <- []; ::Timers.doQueueListEdits <- false; ::Timers.timerAddQueue <- []; ::Timers.timerRemoveQueue <- []; /* * Add a new timer. The specified callback will be executed when the timer expires. * Returns a reference to the timer, which can be used as an argument in other timer functions. * * @param delay - float - The time in seconds from now when the timer's callback will be executed. * @param callback - Callback - Callback instance that will be executed when the timer expires. * @param params - table - Paramater table that will be passed to the callback function. * @param repeat - integer - How many times will these timer repeat? Set to -1 for infinite repeats. */ function Timers::AddTimer(delay, callback, params = null, repeat = 0) { local timerToAdd = { prevTime = Time(), delay = delay, callback = callback, params = params, repeat = repeat, }; if (::Timers.doQueueListEdits == true) { ::Timers.timerAddQueue.append(timerToAdd); return timerToAdd; } ::Timers.timerList.append(timerToAdd); ::Debug.Print("*** TIMERS - Added timer " + timerToAdd); return timerToAdd; } /* * Removes the specified timer and prevents the execution of its callback. */ function Timers::RemoveTimer(timerToRemove) { if (timerToRemove == null) return; if (::Timers.doQueueListEdits == true) { ::Timers.timerRemoveQueue.append(timerToRemove); return; } local index = ::Timers.timerList.find(timerToRemove); if (index != null) { ::Debug.Print("*** TIMERS - Removed timer " + timerToRemove); ::Timers.timerList.remove(index); } } /* * Resets the specified timer's countdown. */ function Timers::ResetTimer(timer) { timer.prevTime = Time(); } /* * Update all timers. Call this every frame. */ function Timers::UpdateTimers(params) { ::Timers.doQueueListEdits = true; foreach (timer in ::Timers.timerList) { if (Time() >= timer.prevTime + timer.delay) { // Attempt to execute the timer callback. Do not exit the function early. //try //{ timer.callback(params); //} //catch (exception) //{ // ::Debug.Print("*** TIMERS - Exception thrown by timer execution:\n" + exception); //} // Repeating timer? if (timer.repeat == 0) { ::Timers.RemoveTimer(timer); } else { timer.repeat--; ::Timers.ResetTimer(timer); } } } ::Timers.doQueueListEdits = false; /* The modification queue allows us to add or remove timers when executing a timer's callback. */ foreach (timerToRemove in ::Timers.timerRemoveQueue) { local index = ::Timers.timerList.find(timerToRemove); if (index != null) { ::Debug.Print("*** TIMERS - Removed queued timer " + timerToRemove); ::Timers.timerList.remove(index); } } foreach (timerToAdd in ::Timers.timerAddQueue) { local index = ::Timers.timerList.find(timerToAdd); if (index == null) { ::Debug.Print("*** TIMERS - Added queued timer " + timerToAdd); ::Timers.timerList.append(timerToAdd); } } ::Timers.timerRemoveQueue.clear(); ::Timers.timerAddQueue.clear(); } ::Events.GetGlobalEvent(EVENT.TICK).AddListener(function(params) { ::Timers.UpdateTimers(params); });