Cohadar
master of fugue
- Reaction score
- 209
This system is obsolete.
It has been merged with TT. <========<<
This was once an extension library for ABC but now it is a standalone system.
It combines the algorithmic speed and power of ABC with ease of use of TT.
ABCT and TT are complementary systems.
It has been merged with TT. <========<<
JASS:
//==============================================================================
// ABCT - Timer library by Cohadar - v3.0
//==============================================================================
//
// PURPOUSE OF ABCT:
// * Passing data to timers
//
// PROS:
// * It is easier than using attaching
// * It is in fact doing a LOT of dirty work for you
//
// CONS:
// * Every Start call creates a new timer
// so for high-frequency timers it is more efficient to use TT
// Opposite is also true: for low-frequency timers ABCT is better than TT
//
// FUNCTIONS:
// * ABCT_Start(userFunc, struct, period)
// * ABCT_Zero(userFunc, struct)
// * ABCT_GetData() -> struct
//
// * userFunc is a user function that takes nothing and return boolean
// userFunc should return true to stop timer.
//
// * ABCT_Start will periodically call userFunc until it returns true.
// * ABCT_Zero will call userFunc only once after current thread is completed.
// userFunc that is called with ABCT_Zero MUST return true or it will leak.
//
// * ABCT_GetData() is a function that can be used inside userFunc
// ABCT_GetData() will return struct passed to Start function
//
// DETAILS:
// * ABCT is using smart timer and trigger preloading and simple hash
// When colliding timer handle is found that timer is simply discarded
//
// HOW TO IMPORT:
// * Just create a trigger named ABCT
// * convert it to text and replace the whole trigger text with this one
//==============================================================================
library ABCT initializer Init
globals
// how many timers and triggers to preload
private integer PRELOAD = 128
// we can safely use dummy hashing here because timers are preloaded
public constant integer HASH = 8191
// passing data
private integer bj_data
private integer array Dataz
private trigger array Triggerz
private timer array Timerz
// recycling
private integer array Indexz
private integer N = PRELOAD
endglobals
//==============================================================================
private function H2I takes handle h returns integer
return h
return 0
endfunction
//==============================================================================
// note how colliding timer handles are discarded
// so ABCT would work properly even after preload limit break
//==============================================================================
private function NewIndex takes nothing returns integer
local integer i
local timer t
if (N==0) then
loop
call BJDebugMsg("WARNING: ABCT reached preloaded timer limit!")
set t = CreateTimer()
set i = H2I(t)
set i = i - (i / HASH) * HASH // dummy modulo hash
if Timerz<i> == null then
set Timerz<i> = t
set Triggerz<i> = CreateTrigger()
return i
endif
endloop
endif
set N = N - 1
return Indexz[N]
endfunction
//==============================================================================
// This is where userFunctions actually get called.
//==============================================================================
private function Periodic takes nothing returns nothing
local integer i = H2I(GetExpiredTimer())
set i = i - (i / HASH) * HASH // dummy modulo hash
set bj_data = Dataz<i>
if TriggerEvaluate(Triggerz<i>) then
// recycle the trigger and timer
call TriggerClearConditions(Triggerz<i>)
call PauseTimer(Timerz<i>)
set Indexz[N] = i
set N = N + 1
endif
endfunction
//==============================================================================
// Blizzard should have made a native like this.
//==============================================================================
public function Start takes code userFunc, integer data, real period returns nothing
local integer i
debug if userFunc == null then
debug call BJDebugMsg("ERROR: ABCT_Start - null userFunc")
debug return
debug endif
set i = NewIndex()
call TriggerAddCondition(Triggerz<i>, Condition(userFunc))
set Dataz<i> = data
call TimerStart(Timerz<i>, period, true, function Periodic)
endfunction
//==============================================================================
// Used in places where TriggerSleepAction(0.0) does not work.
//==============================================================================
public function Zero takes code userFunc, integer data returns nothing
local integer i
debug if userFunc == null then
debug call BJDebugMsg("ERROR: ABCT_Zero - null userFunc")
debug return
debug endif
set i = NewIndex()
call TriggerAddCondition(Triggerz<i>, Condition(userFunc))
set Dataz<i> = data
call TimerStart(Timerz<i>, 0.0, false, function Periodic)
endfunction
//==============================================================================
// Use this only inside your userFunc.
//==============================================================================
public function GetData takes nothing returns integer
return bj_data
endfunction
//==============================================================================
// Smart Preloading. (avoids hash collision)
//==============================================================================
private function Init takes nothing returns nothing
local integer i
local timer t
local integer j = 0
loop
exitwhen j>=PRELOAD
set t = CreateTimer()
set i = H2I(t)
set i = i - (i / HASH) * HASH // dummy modulo hash
if Timerz<i> == null then
set Timerz<i> = t
set Triggerz<i> = CreateTrigger()
set Indexz[j] = i
set j = j + 1
endif
endloop
endfunction
endlibrary
</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
This was once an extension library for ABC but now it is a standalone system.
It combines the algorithmic speed and power of ABC with ease of use of TT.
ABCT and TT are complementary systems.