Dirac
22710180
- Reaction score
- 147
This is very insane, but i already did it and i find no reason to not post it.
JASS:
library SingleTimer
//**************************************************
//SingleTimer
//A system that allows you to fire timers and attach data to them.
// -Uses only 1 timer for the entire system
// -Does not uses hahstables
// -Timers don't have to be initialized or destroyed
//How to implement?
// -Create a new trigger called SingleTimer and copy-paste
// this library into it
// -It requires JNGP
//API:
// function STimer takes integer Data, real Timeout, function Code
// -Puts a timer in a queue, fires it after the timeout completes,
// this timer can't be stopped once fired.
// function GetExpiredTimerData takes nothing returns integer
// -Returns the data attached to the timer, use only at the code that
// the timer fires when finished.
//**************************************************
globals
private timer mt=CreateTimer()
endglobals
private struct ST
thistype prev
thistype next
real e
trigger t
integer i
static thistype first=0
static thistype data
private static method onInit takes nothing returns nothing
//this is not a magic number
set thistype(0).e=36000
endmethod
endstruct
private function hookTimer takes nothing returns nothing
local ST this=ST.first
local ST prev=this
//Removes the instance from the chain
set this.prev.next=this.next
set this.next.prev=this.prev
//Prepares to start the next timer
set this=this.next
set ST.first=this
//This reduces the time remaining of each timer after a timer ends
loop
exitwhen this==0
set this.e=this.e-prev.e
set this=this.next
endloop
//Start the next timer
if ST.first>0 then
call TimerStart(mt,ST.first.e,false,function hookTimer)
endif
//Fires the code attached to the timer
set ST.data=prev
call TriggerEvaluate(prev.t)
call DestroyTrigger(prev.t)
call prev.destroy()
endfunction
function GetExpiredTimerData takes nothing returns integer
return ST.data.i
endfunction
function STimer takes integer i,real d,code c returns nothing
local real r=TimerGetElapsed(mt)
local ST this=ST.create()
local ST prev=this
//Linked-list magic
set ST(0).next.prev=this
set this.next=ST(0).next
set ST(0).next=this
set this.prev=ST(0)
set this.i=i
if d>r then
set this.e=d-r
else
set this.e=d
endif
//I hate to have to do this
set this.t=CreateTrigger()
call TriggerAddCondition(this.t,Condition(c))
//This magic loop orders the chain according to this.e
loop
exitwhen this==0
if this.next.e<this.e then
set this.next.prev=this.prev
set this.prev=this.next
set this.next=this.next.next
set this.prev.next=this
set this.next.prev=this
set this.prev.prev.next=this.prev
else
set this=this.next
endif
endloop
//if the previous member of this instance is 0 that means it's the first timer
if prev.prev==0 then
set ST.first.e=ST.first.e-r
set ST.first=prev
call TimerStart(mt,ST.first.e,false,function hookTimer)
endif
endfunction
endlibrary