DualShock
offline
Опыт:
4,983Активность: |
Библиотека TimerUtils
Часто вижу что используют эту библиотеку на vjass (не на xgm), которая по сути сохраняет информацию (структуру) на таймер, так же зная таймер можно получить записанную информацию. Стоит ли использовать её? Какие плюсы и минусы этой библиотеки?
((код jass
library TimerUtils initializer init
********************************************************************* * TimerUtils (red+blue+orange flavors for 1.24b+) * ---------- * * To implement it , create a custom text trigger called TimerUtils * and paste the contents of this script there. * * To copy from a map to another, copy the trigger holding this * library to your map. * * (requires vJass) More scripts: htt://www.wc3c.net * * For your timer needs: * * Attaching * * Recycling (with double-free protection) * * set t=NewTimer() : Get a timer (alternative to CreateTimer) * ReleaseTimer(t) : Relese a timer (alt to DestroyTimer) * SetTimerData(t,2) : Attach value 2 to timer * GetTimerData(t) : Get the timer's value. * You can assume a timer's value is 0 * after NewTimer. * * Multi-flavor: * Set USE_HASH_TABLE to true if you don't want to complicate your life. * * If you like speed and giberish try learning about the other flavors. * ******************************************************************** ================================================================
globals How to tweak timer utils: USE_HASH_TABLE = true (new blue) * SAFEST * SLOWEST (though hash tables are kind of fast) USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = true (orange) * kinda safe (except there is a limit in the number of timers) * ALMOST FAST USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = false (red) * THE FASTEST (though is only faster than the previous method after using the optimizer on the map) * THE LEAST SAFE ( you may have to tweak OFSSET manually for it to work) private constant boolean USE_HASH_TABLE = true private constant boolean USE_FLEXIBLE_OFFSET = false private constant integer OFFSET = 0x100000
private integer VOFFSET = OFFSET Timers to preload at map init: private constant integer QUANTITY = 256 Changing this to something big will allow you to keep recycling timers even when there are already AN INCREDIBLE AMOUNT of timers in the stack. But it will make things far slower so that's probably a bad idea... private constant integer ARRAY_SIZE = 8190 endglobals
==================================================================================================
globals private integer array data[ARRAY_SIZE] private hashtable ht endglobals It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing static if(USE_HASH_TABLE) then new blue call SaveInteger(ht,0,GetHandleId(t), value) elseif (USE_FLEXIBLE_OFFSET) then orange static if (DEBUG_MODE) then if(GetHandleId(t)-VOFFSET<0) then call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer") endif endif set data[GetHandleId(t)-VOFFSET]=value else new red static if (DEBUG_MODE) then if(GetHandleId(t)-OFFSET<0) then call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer") endif endif set data[GetHandleId(t)-OFFSET]=value endif endfunction function GetTimerData takes timer t returns integer
static if(USE_HASH_TABLE) then new blue return LoadInteger(ht,0,GetHandleId(t) ) elseif (USE_FLEXIBLE_OFFSET) then orange static if (DEBUG_MODE) then if(GetHandleId(t)-VOFFSET<0) then call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer") endif endif return data[GetHandleId(t)-VOFFSET] else new red static if (DEBUG_MODE) then if(GetHandleId(t)-OFFSET<0) then call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer") endif endif return data[GetHandleId(t)-OFFSET] endif endfunction ==========================================================================================
globals private timer array tT[ARRAY_SIZE] private integer tN = 0 private constant integer HELD=0x28829022 use a totally random number here, the more improbable someone uses it, the better. endglobals ==========================================================================================
function NewTimer takes nothing returns timer if (tN==0) then If this happens then the QUANTITY rule has already been broken, try to fix the issue, else fail. debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, make sure all timers are getting recycled correctly") static if( not USE_HASH_TABLE) then debug call BJDebugMsg("In case of errors, please increase it accordingly, or set TimerUtils_USE_HASH_TABLE to true") set tT[0]=CreateTimer() static if( USE_FLEXIBLE_OFFSET) then if (GetHandleId(tT[0])-VOFFSET<0) or (GetHandleId(tT[0])-VOFFSET>=ARRAY_SIZE) then all right, couldn't fix it call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.") return null endif else if (GetHandleId(tT[0])-OFFSET<0) or (GetHandleId(tT[0])-OFFSET>=ARRAY_SIZE) then all right, couldn't fix it call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.") return null endif endif endif else set tN=tN-1 endif call SetTimerData(tT[tN],0) return tT[tN] endfunction ==========================================================================================
function ReleaseTimer takes timer t returns nothing if(t==null) then debug call BJDebugMsg("Warning: attempt to release a null timer") return endif if (tN==ARRAY_SIZE) then debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!") stack is full, the map already has much more troubles than the chance of bug
call DestroyTimer(t) else call PauseTimer(t) if(GetTimerData(t)==HELD) then debug call BJDebugMsg("Warning: ReleaseTimer: Double free!") return endif call SetTimerData(t,HELD) set tT[tN]=t set tN=tN+1 endif endfunction private function init takes nothing returns nothing
local integer i=0 local integer o=-1 local boolean oops = false static if( USE_HASH_TABLE ) then set ht = InitHashtable() loop exitwhen(i==QUANTITY) set tT[i]=CreateTimer() call SetTimerData(tT[i], HELD) set i=i+1 endloop set tN = QUANTITY else loop set i=0 loop exitwhen (i==QUANTITY) set tT[i] = CreateTimer() if(i==0) then set VOFFSET = GetHandleId(tT[i]) static if(USE_FLEXIBLE_OFFSET) then set o=VOFFSET else set o=OFFSET endif endif if (GetHandleId(tT[i])-o>=ARRAY_SIZE) then exitwhen true endif if (GetHandleId(tT[i])-o>=0) then set i=i+1 endif endloop set tN = i exitwhen(tN == QUANTITY) set oops = true exitwhen not USE_FLEXIBLE_OFFSET debug call BJDebugMsg("TimerUtils_init: Failed a initialization attempt, will try again") endloop if(oops) then static if ( USE_FLEXIBLE_OFFSET) then debug call BJDebugMsg("The problem has been fixed.") If this message doesn't appear then there is so much handle id fragmentation that it was impossible to preload so many timers and the thread crashed! Therefore this debug message is useful. elseif(DEBUG_MODE) then call BJDebugMsg("There were problems and the new timer limit is "+I2S(i)) call BJDebugMsg("This is a rare ocurrence, if the timer limit is too low:") call BJDebugMsg("a) Change USE_FLEXIBLE_OFFSET to true (reduces performance a little)") call BJDebugMsg("b) or try changing OFFSET to "+I2S(VOFFSET) ) endif endif endif endfunction
endlibrary )) |
05.12.2011, 19:02 | #1
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
FellGuard
Losyash
offline
Опыт:
39,547Активность: |
Плюсы, как от любой другой готовой системы - не нужно переизобретать колесо. Аттачит целое число к таймеру, использует в качестве БД либо хэш-таблицу, либо массив, индекс которого вычисляется из хэндла таймера. По сути всё расписано в первом толстом комментарии в коде. |
05.12.2011, 19:30 | #2
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
youtube
сктыщь
offline
Опыт:
8,025Активность: |
|
05.12.2011, 20:59 | #3
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
DualShock
offline
Опыт:
4,983Активность: |
|
05.12.2011, 21:25 | #4
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|