library CTL initializer Ini /* v1.3.0.0
*************************************************************************************
*
* CTL or Constant Timer Loop provides a loop for constant merged timers at 32 fps.
*
* Similar to T32 but pauses timer when no structs have instances and removes structs
* from timer trigger when those structs have no instances.
*
* This can also create new timers after destroying a previous timer and generates less
* code in the module. It also generates no triggers so long as the module is implemented
* at the top of the struct.
*
************************************************************************************
*
* static method create takes nothing returns thistype
* - CTL
* - Creates new timer
*
* method destroy takes nothing returns nothing
* - CTL
* - Destroys created timer
*
* method insert takes nothing returns nothing
* - CTList
* - Inserts "this" into the list
*
* method remove takes nothing returns nothing
* - CTList
* - Removes "this" from this list
*
* Module
*
* module CTL
* - Declare locals in here
* - Run ini code
* module CTLExpire
* - Run timer code
* -
* - thistype this refers to current expiring timer\
* module CTLNull
* - Null locals here
* module CTLEnd
*
* module CTList
* - Declare locals in here
* - Run ini code
* module CTListExpire
* - Run timer code
* -
* - thistype this refers to current expiring timer\
* module CTListNull
* - Null locals here
* module CTListEnd
*
* Example of Constant Timer Loop 32
* struct MyTimer extends array
* integer myValue
* implement CTL
* local string s="My value is "
* implement CTLExpire
* call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,s+I2S(myValue))
* call destroy()
* implement CTLNull
* set s=null //pointless, but shows how to use null block
* implement CTLEnd
* endstruct
*
* set MyTimer.create().myValue=16 //will display "My value is 16" 32x a second
*
* module CT32
* - A constant running timer. Useful when the timer is pretty much never ever
* - going to stop. Also allows control over loop (just provides an expiring timer).
* - Code goes in between two methods
* module CT32End
*
* Example of Constant Timer 32
*
* //Displays
* // 1
* // 2
* // 3
* struct MyTimers extends array
* integer myValue
* thistype next
* implement CTL2
* local thistype this=thistype(0).next
* loop
* exitwhen 0==this
* call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,s+I2S(myValue))
* set this=next
* endloop
* implement CTL2End
* private static method onInit takes nothing returns nothing
* set thistype(0).next=1
* set thistype(1).next=2
* set thistype(2).next=3
* set thistype(1).myValue=1
* set thistype(2).myValue=2
* set thistype(3).myValue=3
* endmethod
* endstruct
*
************************************************************************************/
globals
private integer ic = 0 //instance count
private integer array rf //root first
private integer array p //previous
private integer array n //next
private integer array th //timer head
private integer tt //temp timer head
private integer array ns //next stack
private trigger t = CreateTrigger()
private triggercondition array ct
private boolexpr array rc
endglobals
private function E2 takes integer i returns nothing
local integer a = n[i]
set ns[0] = 0
loop
if 0 == p[i] then
//If this was the root first.
set tt = th[i]
if 0 == a then
//The list is empty
call TriggerRemoveCondition(t, ct[tt])
set ct[tt] = null
set rf[tt] = 0
else
//The list requires a new root first.
set rf[tt] = a
set p[a] = 0
endif
else
//Nothing extraordinary, simply remove the node
set p[a] = p[i]
set n[p[i]] = a
endif
//Deallocate the node
set n[i] = a
set n[0] = i
set i = ns[i]
exitwhen 0 == i
set a = n[i]
endloop
endfunction
private function E takes nothing returns nothing
if ns[0] != 0 then
call E2(ns[0])
endif
call TriggerEvaluate(t)
endfunction
private function Ini takes nothing returns nothing
call TimerStart(CreateTimer(), .031250000, true, function E)
endfunction
private function CT takes integer r returns integer
local integer i = n[0]
local integer f = rf[r]
if 0 == i then
set i = ic + 1
set ic = i
else
set n[0] = n[i]
endif
set th[i] = r
debug set ns[i] = -1
if 0 == f then
//Make "i" the root.
set n[i] = 0
set p[i] = 0
set rf[r] = i
set ct[r] = TriggerAddCondition(t, rc[r])
else
//Simply add "i" to the list.
set n[i] = f
set p[i] = 0
set p[f] = i
set rf[r] = i
endif
return i
endfunction
private function DT takes integer t returns nothing
debug if 0 > ns[t] then
set ns[t] = ns[0]
set ns[0] = t
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"TIMER LOOP ERROR: ATTEMPT TO DESTROY NULL TIMER")
debug endif
endfunction
private function A takes code c returns integer
set ic = ic + 1
set rc[ic] = Filter(c)
return ic
endfunction
private keyword r
private keyword e
module CTL
static integer r
static method create takes nothing returns thistype
return CT(.r)
endmethod
method destroy takes nothing returns nothing
call DT(this)
endmethod
static method e takes nothing returns nothing
local thistype this = rf[.r]
endmodule
module CTLExpire
implement CTL
loop
exitwhen 0 == this
endmodule
module CTLNull
set this = n[this]
endloop
endmodule
module CTLEnd
implement CTLNull
endmethod
private static method onInit takes nothing returns nothing
set .r = A(function thistype.e)
endmethod
endmodule
private keyword d
private keyword ne
private keyword pr
module CTList
static integer r
static integer d
static integer array ne
static integer array pr
method remove takes nothing returns nothing
debug if .pr[this] != 0 or .ne[0] == this then
set .ne[.pr[this]] = .ne[this]
set .pr[.ne[this]] = .pr[this]
set .pr[this] = 0
if .ne[0] == 0 then
call DT(.d)
endif
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"TIMER LOOP ERROR: ATTEMPT TO REMOVE INVALID INDEX")
debug endif
endmethod
method insert takes nothing returns nothing
debug if .pr[this] == 0 and .ne[0] != this then
if .ne[0] == 0 then
set .d = CT(.r)
endif
set .pr[.ne[0]] = this
set .ne[this] = .ne[0]
set .ne[0] = this
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"TIMER LOOP ERROR: ATTEMPT TO DOUBLY-ADD INDEX")
debug endif
endmethod
static method e takes nothing returns nothing
local thistype this = .ne[0]
endmodule
module CTListExpire
implement CTList
loop
exitwhen 0 == this
endmodule
module CTListNull
set this = .ne[this]
endloop
endmodule
module CTListEnd
implement CTListNull
endmethod
private static method onInit takes nothing returns nothing
set .r = A(function thistype.e)
endmethod
endmodule
module CT32
static method e takes nothing returns boolean
endmodule
module CT32End
return false
endmethod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(t, Filter(function thistype.e))
endmethod
endmodule
endlibrary