![]() |
#1 |
User
|
![]() This is a fixed version of Vexorian's TimerUtils.
It allows you to call NewTimer inside module initializers (Useful for elapsed game time events and other things) ![]() library TimerUtilsEx /************************************************* * * TimerUtilsEx * v2.1.0.3 * By Vexorian, Bribe & Magtheridon96 * * Original version by Vexorian. * * Flavors: * Hashtable: * - RAM: Minimal * - TimerData: Slow * * Array: * - RAM: Maximal * - TimerData: Fast * * All the functions have O(1) complexity. * The Array version is the fastest, but the hashtable * version is the safest. The Array version is still * quite safe though, and I would recommend using it. * The system is much slower in debug mode. * * API: * ---- * - function NewTimer takes nothing returns timer * - Returns a new timer from the stack. * - function NewTimerEx takes integer i returns timer * - Returns a new timer from the stack and attaches a value to it. * - function ReleaseTimer takes timer t returns integer * - Throws a timer back into the stack. Also returns timer data. * - function SetTimerData takes timer t, integer value returns nothing * - Attaches a value to a timer. * - function GetTimerData takes timer t returns integer * - Returns the attached value. * *************************************************/ globals //Calibration //Use hashtable, or fast array? private constant boolean USE_HASH = false //Max Number of Timers Held in Stack private constant integer QUANTITY = 256 endglobals globals private timer array tT private integer tN = 0 private hashtable ht = InitHashtable() endglobals private module Init static if not USE_HASH then private static method onInit takes nothing returns nothing local integer i = QUANTITY loop set i = i - 1 set tT[i] = CreateTimer() exitwhen i == 0 endloop set tN = QUANTITY endmethod endif endmodule // JassHelper doesn't support static ifs for globals. private struct Data extends array static if not USE_HASH then static integer array data endif implement Init endstruct // Double free protection private function ValidTimer takes integer i returns boolean return LoadBoolean(ht, i, 1) endfunction private function Get takes integer id returns integer debug if not ValidTimer(id) then debug call BJDebugMsg("[TimerUtils]Error: Tried to get data from invalid timer.") debug endif static if USE_HASH then return LoadInteger(ht, id, 0) else return Data.data[id - 0x100000] endif endfunction private function Set takes integer id, integer data returns nothing debug if not ValidTimer(id) then debug call BJDebugMsg("[TimerUtils]Error: Tried to attach data to invalid timer.") debug endif static if USE_HASH then call SaveInteger(ht, id, 0, data) else set Data.data[id - 0x100000] = data endif endfunction function SetTimerData takes timer t, integer data returns nothing call Set(GetHandleId(t), data) endfunction function GetTimerData takes timer t returns integer return Get(GetHandleId(t)) endfunction function NewTimerEx takes integer data returns timer local integer id if tN == 0 then static if USE_HASH then set tT[0] = CreateTimer() else debug call BJDebugMsg("[TimerUtils]Error: No Timers In The Stack! You must increase 'QUANTITY'") return null endif else set tN = tN - 1 endif set id = GetHandleId(tT[tN]) call SaveBoolean(ht, id, 1, true) call Set(id, data) return tT[tN] endfunction function NewTimer takes nothing returns timer return NewTimerEx(0) endfunction function ReleaseTimer takes timer t returns integer local integer id = GetHandleId(t) local integer data = 0 // Pause the timer just in case. call PauseTimer(t) // Make sure the timer is valid. if ValidTimer(id) then // Get the timer's data. set data = Get(id) // Unmark handle id as a valid timer. call RemoveSavedBoolean(ht, id, 1) //If it's not run in USE_HASH mode, this next block is useless. static if USE_HASH then //At least clear hash memory while it's in the recycle stack. call RemoveSavedInteger(ht, id, 0) // If the recycle limit is reached if tN == QUANTITY then // then we destroy the timer. call DestroyTimer(t) return data endif endif //Recycle the timer. set tT[tN] = t set tN = tN + 1 //Tried to pass a bad timer. debug else debug call BJDebugMsg("[TimerUtils]Error: Tried to release non-active timer!") endif //Return Timer Data. return data endfunction endlibrary library TimerUtils requires TimerUtilsEx endlibrary Last edited by Bribe : 10-27-2011 at 02:59 PM. |
![]() |
![]() |
Sponsored Links - Login to hide this ad! |
|
![]() |
#2 | |
Free Software Terrorist
Technical Director
|
![]() Quote:
It doesn't seem like you are the author of this. The rest seems rather unnecessary and probably even slower. Except for NewTimerEx which can easily be added to the real timer utils anyway. |
|
![]() |
![]() |
![]() |
#3 |
User
|
![]() Vexorian, nice to see you around I must say. It's inspiring.
Magtheridon96 and I wrote this revised script, it is a co-authorship of sorts. I suppose I could write "by Vexorian, Magtheridon96 and Bribe" but I'd really prefer if you just updated TimerUtils. The reason it doesn't work in module initializers is because when you use hashtable a new timer isn't created because tN is equal to 0 (because you initialize in a library Init instead of a module init and TimerUtils bugs in hashtable mode when timers overflow). If I had my wishes I would really like it if you updated your TimerUtils library. Then we can stop with this unpleasant trend of re-writing systems. In fact, while we are on this subject it would make the most sense humanly possible if JassHelper were updated so that initializers, whether be module, struct or library, initialized before any library requiring it. The rest are not needed features, though nice to have, but don't slow anything down except in ReleaseTimer. I made the change in ReleaseTimer so that more than QUANTITY timers could not be recycled, because there are sometimes spikes in the game where lots of timers might be needed but not all would need to be recycled. You can view the development on this crap-tastic subject here: http://www.hiveworkshop.com/forums/j...00/index5.html Last edited by Bribe : 10-27-2011 at 02:25 PM. |
![]() |
![]() |
![]() |
#4 |
Free Software Terrorist
Technical Director
|
![]() I figured out about the thing with onInit when I wasn't looking at the site. Quite honestly, I think the best thing I could do is update jassHelper to remove struct and module onInit altogether, because it is really ridiculous how every library wants to initialize before modules.. But then modules wouldn't work very great, I guess.
__________________I will update TimerUtils to have NewTimerEx and a module onInit. sigh. |
![]() |
![]() |
![]() |
#5 | |
Procrastination Incarnate
Development Director
|
![]() Quote:
I agree about the widespread use of module initializers being ridiculous, though. Most libraries don't need to do it. Are the edits Vex made to TimerUtils adequate for me to graveyard this, Bribe? |
|
![]() |
![]() |
![]() |
#6 |
User
|
![]() There is still the issue that you and I have addressed where overflow timers in hashtable-mode bug because the "set tT[0] = CreateTimer()" line is only there if hashtable mode is "off".
You can go ahead and ditch this resource as I never wanted it in the first place, what I wanted was a system that can be linked to that works 100%. On an side note Vex now uses .evaluate() on the init function plus a textmacro instead of a wrapper, which unfortunately makes the code way longer than before while being completely avoidable by doing the approach I have here. |
![]() |
![]() |
![]() |
Thread Tools | Search this Thread |
|
|