Jesus4Lyf
Good Idea™
- Reaction score
- 397
A trigger index recycling system based on triggers that have conditions attached which only ever return false. In other words, conditions instead of actions. And conditions returning false is mandatory.
ReleaseTrigger does not release the trigger for recycling, it only releases the index to be regenerated for reuse. This means NewTrigger has an infinite spawn.
This uses ExecCount attaching methods with straight O(1) complexity operations exposed.
Functions available are:
System code:
I intend to provide better documentation after user comments.
ReleaseTrigger does not release the trigger for recycling, it only releases the index to be regenerated for reuse. This means NewTrigger has an infinite spawn.
This uses ExecCount attaching methods with straight O(1) complexity operations exposed.
Functions available are:
JASS:
System code:
JASS:
library DTS initializer InitDTS
globals
private constant integer MAX_TRIGGERS_AT_ONCE=256
private constant integer MAX_EXECS_PER_ITER=24
private constant real RESTORE_PERIOD=0.03125
endglobals
// The System
private struct stack // Doesn't require destroy, just must be empty.
private stack next
private integer data
static method create takes nothing returns stack
return 0
endmethod
method operator push= takes integer i returns stack
local stack new=stack.allocate()
set new.data=i
set new.next=this
return new
endmethod
method pop takes nothing returns stack
call this.destroy()
return this.next
endmethod
method operator val takes nothing returns integer
return this.data
endmethod
method operator empty takes nothing returns boolean
return this==0
endmethod
endstruct
globals
private trigger array Trig
private integer NextTrig=MAX_TRIGGERS_AT_ONCE
private integer array Data
endglobals
globals
private constant timer TI=CreateTimer()
private trigger TI_Current
private integer TI_ToAdd=0
private stack IndexesToRestore=0
endglobals
private function AddTICurrentExecCount takes integer d returns nothing
loop
exitwhen d==0
set d=d-1
call TriggerExecute(TI_Current)
endloop
endfunction
private function TI_Process takes nothing returns nothing
if TI_ToAdd==0 then
if IndexesToRestore.empty then
call PauseTimer(TI)
return
else
set TI_ToAdd=IndexesToRestore.val
set IndexesToRestore=IndexesToRestore.pop()
set TI_Current=CreateTrigger()
endif
endif
if TI_ToAdd>MAX_EXECS_PER_ITER then
call AddTICurrentExecCount(MAX_EXECS_PER_ITER)
set TI_ToAdd=TI_ToAdd-MAX_EXECS_PER_ITER
else
call AddTICurrentExecCount(TI_ToAdd)
set TI_ToAdd=0
set Trig[NextTrig]=TI_Current
set NextTrig=NextTrig-1
endif
endfunction
function GetTriggerData takes trigger whichTrigger returns integer
return Data[GetTriggerExecCount(whichTrigger)]
endfunction
function SetTriggerData takes trigger whichTrigger, integer data returns nothing
set Data[GetTriggerExecCount(whichTrigger)]=data
endfunction
function NewTrigger takes nothing returns trigger
set NextTrig=NextTrig+1
return Trig[NextTrig]
endfunction
function ReleaseTrigger takes trigger whichTrigger returns nothing
if IndexesToRestore.empty then
set IndexesToRestore.push=GetTriggerExecCount(whichTrigger)
call DestroyTrigger(whichTrigger)
call ResumeTimer(TI)
else
set IndexesToRestore.push=GetTriggerExecCount(whichTrigger)
call DestroyTrigger(whichTrigger)
endif
endfunction
private function InitTrigExecCount takes trigger t, integer d returns nothing
if d>64 then
call InitTrigExecCount.execute(t,d-64)
set d=64
endif
loop
exitwhen d==0
set d=d-1
call TriggerExecute(t)
endloop
endfunction
private function InitDTS takes nothing returns nothing
call TimerStart(TI,RESTORE_PERIOD,true,function TI_Process)
loop
set Trig[NextTrig]=CreateTrigger()
call InitTrigExecCount.execute(Trig[NextTrig],NextTrig)
set NextTrig=NextTrig-1
exitwhen NextTrig==0
endloop
endfunction
endlibrary
I intend to provide better documentation after user comments.