//-=-=-=-=-=-=--=-=-=-=-=-=-=-=-
//-=-=-=-] QuantumTimer [-=-=-=-
//-=-=-=-=-=- v0.920 -=-=-=-=-=-
/*******************************************************
* Fields
* readonly integer ExpiredTimer.data
* - Returns data stored for the timer expired
* Functions
* function SetWorldTimeSensitivity takes integer conglomerate returns integer
* - Sets time sensitivity to quantum conglomerate (positive) / subquantum conglomerate (negative)
* function GetWorldTimeSensitivity takes nothing returns integer
* - Returns quantum conglomerate (positive) / subquantum conglomerate (negative)
* ! Quantum conglomerate scales time rate by value / time by (1 / value)
* ! Subquantum conglomerate scales time rate by (-1 / value) / time by -value
* function StartTimer takes integer quantums, boolean periodic, boolexpr func, integer data returns integer
* - Starts timer with specified configuration
* function RemoveTimer takes integer timercode returns nothing
* - Removes specified timer
* function StopTimer takes integer timercode returns nothing
* - Stops specified timer
* function RestartTimer takes integer timercode returns nothing
* - Restarts specified timer
* function SetTimerData takes integer timercode, integer data returns nothing
* - Set data for specified timer
* function SetTimerTick takes integer timercode, integer quantums returns nothing
* - Set tick quantum time for specified timer
*******************************************************/
library QuantumTimer initializer Init requires Indexer
//-=-=-=- Settings -=-=-=-
globals
constant real TIME_QUANTUM = .03
private constant integer MAX_TIMERS = 30
private constant integer QUANTUMS_AVAILABLE = 2147483647
private constant boolean SAFE = false
//-=-=-=-==-=-=-=-=-=-=-=-
private integer Conglomerate
private integer Count
private boolean Pause
private timer QuantumTimer
private integer Indexer
private integer array Quantums
private boolean array Periodic
private trigger array Trigger
private integer array Data
private integer array TriggerQuantum
private integer WorkInteger
private integer WorkInteger2
endglobals
//! textmacro onExpireBegin takes increment, sign
set Count = Count + $increment$
static if SAFE then
if Count > QUANTUMS_AVAILABLE then
set Count = Count - QUANTUMS_AVAILABLE
endif
endif
set WorkInteger = 0
loop
exitwhen WorkInteger == IndexCount(Indexer)
if Trigger[WorkInteger] != null and TriggerQuantum[WorkInteger] $sign$ Count then
set data = Data[WorkInteger]
//! endtextmacro
//! textmacro onExpireEnd
if Periodic[WorkInteger] then
set TriggerQuantum[WorkInteger] = Count + Quantums[WorkInteger]
static if SAFE then
if TriggerQuantum[WorkInteger] > QUANTUMS_AVAILABLE then
set TriggerQuantum[WorkInteger] = TriggerQuantum[WorkInteger] - QUANTUMS_AVAILABLE
endif
endif
else
call Deindex(Indexer, WorkInteger)
call TriggerClearConditions(Trigger[WorkInteger])
endif
endif
set WorkInteger = WorkInteger + 1
endloop
if IndexCount(Indexer) == 0 then
set Pause = true
call PauseTimer(QuantumTimer)
endif
//! endtextmacro
struct ExpiredTimer extends array
readonly static integer data
static method onQuantumConglomerateExpire takes nothing returns nothing
//! runtextmacro onExpireBegin("Conglomerate", "<=")
if Quantums[WorkInteger] > Conglomerate then
call TriggerEvaluate(Trigger[WorkInteger])
else
set WorkInteger2 = Conglomerate / Quantums[WorkInteger]
if GetRandomInt(0, Quantums[WorkInteger] - 1) < Conglomerate - WorkInteger2 * Quantums[WorkInteger] then
set WorkInteger2 = WorkInteger2 + 1
endif
loop
call TriggerEvaluate(Trigger[WorkInteger])
exitwhen WorkInteger2 == 1
set WorkInteger2 = WorkInteger2 - 1
endloop
endif
//! runtextmacro onExpireEnd()
endmethod
static method onSubquantumConglomerateExpire takes nothing returns nothing
//! runtextmacro onExpireBegin("1", "==")
call TriggerEvaluate(Trigger[WorkInteger])
//! runtextmacro onExpireEnd()
endmethod
endstruct
//! textmacro Run
if Pause and Conglomerate != 0 then
set Pause = false
if Conglomerate > 0 then
call TimerStart(QuantumTimer, TIME_QUANTUM, true, function ExpiredTimer.onQuantumConglomerateExpire)
else
call TimerStart(QuantumTimer, -Conglomerate * TIME_QUANTUM, true, function ExpiredTimer.onSubquantumConglomerateExpire)
endif
endif
//! endtextmacro
function SetWorldTimeSensitivity takes integer conglomerate returns nothing
if conglomerate > 0 then
call TimerStart(QuantumTimer, TIME_QUANTUM, true, function ExpiredTimer.onQuantumConglomerateExpire)
elseif conglomerate < 0 then
call TimerStart(QuantumTimer, -conglomerate * TIME_QUANTUM, true, function ExpiredTimer.onSubquantumConglomerateExpire)
else
if Pause == false then
set Pause = true
call PauseTimer(QuantumTimer)
endif
endif
set Conglomerate = conglomerate
endfunction
function GetWorldTimeSensitivity takes nothing returns integer
return Conglomerate
endfunction
//! textmacro Safe takes i
static if SAFE then
if $i$ > QUANTUMS_AVAILABLE then
set $i$ = $i$ - QUANTUMS_AVAILABLE
endif
endif
//! endtextmacro
function StartTimer takes integer quantums, boolean periodic, boolexpr func, integer data returns integer
set WorkInteger = Index(Indexer)
set Quantums[WorkInteger] = quantums
set TriggerQuantum[WorkInteger] = Count + quantums
//! runtextmacro Safe("TriggerQuantum[WorkInteger]")
set Periodic[WorkInteger] = periodic
set Data[WorkInteger] = data
if Trigger[WorkInteger] == null then
set Trigger[WorkInteger] = CreateTrigger()
endif
call TriggerAddCondition(Trigger[WorkInteger], func)
//! runtextmacro Run()
return WorkInteger
endfunction
function RemoveTimer takes integer timercode returns nothing
call Deindex(Indexer, timercode)
call TriggerClearConditions(Trigger[timercode])
endfunction
function StopTimer takes integer timercode returns nothing
set TriggerQuantum[timercode] = -1
endfunction
function RestartTimer takes integer timercode returns nothing
set TriggerQuantum[timercode] = Count + Quantums[timercode]
//! runtextmacro Safe("TriggerQuantum[timercode]")
//! runtextmacro Run()
endfunction
function SetTimerData takes integer timercode, integer data returns nothing
set Data[timercode] = data
endfunction
function SetTimerTick takes integer timercode, integer quantums returns nothing
set Quantums[timercode] = quantums
endfunction
private function Init takes nothing returns nothing
set Conglomerate = 1
set Count = 1
set Pause = true
set Indexer = CreateIndexer(MAX_TIMERS)
set QuantumTimer = CreateTimer()
endfunction
endlibrary