Jesus4Lyf
Good Idea™
- Reaction score
- 397
Key Timers 2
Version 1.0
Requirements:
- Jass NewGen
JASS:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~ KT ~~ Key Timers 2 ~~ By Jesus4Lyf ~~ Version 1.0 ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// What is Key Timers?
// - Key Timers attaches structs to timers, or more to the point timed
// effects.
// - Key Timers only uses one timer per period to keep things efficient.
// - You can specify different periods. If you don't want to specify more
// than one period, I recommend using Timer Ticker instead.
//
// =Pros=
// - Easy to use.
// - Fastest attaching system for loading the struct each time the
// timer expires (faster than Timer Ticker).
//
// =Cons=
// - Should not be used with struct types that have more than 300 or so in
// existance at once. If lag happens when calling Add, this is why.
// - Periods should only be taken to 0.005 of a second, not 0.007 for example.
// - Limit of 20 different periods.
// - Limit of 400 instances of each period.
//
// Functions:
// - KT_Add(userFunc, period, struct)
// - GetTriggerExecCount(GetTriggeringTrigger()) returns the struct
//
// - func is to be a user function that takes nothing and return boolean.
// It will be executed by the system every period until it returns true.
//
// - GetTriggerExecCount(GetTriggeringTrigger()) is to be used inside func,
// it will return struct passed to Add function. If you don't like this
// syntax, use KT_GetData() instead, but it isn't quite as efficient.
//
// Details:
// - All user functions that should be run with the same period are stored
// in a timer that will call all those functions each period.
//
// - While func returns false the timer will continue to call it each period
// Once func returns true it will be detached from system.
//
// - When there is nothing attached, the timer for that period will pause itself.
//
// Thanks:
// - Cohadar: He actually told me to make Key Timers without a textmacro
// interface. So this is it. Thanks to him for helping me with the original
// Key Timers system too. Also, I'd like to thank him for his work on
// Timer Ticker (TT) which demonstrated how to use triggers/conditions
// in this sort of system, and it would have been much harder to create
// Key Timers 2 without his excellent innovation.
//
// How to import:
// - Create a trigger named KT.
// - Convert it to custom text and replace the whole trigger text with this.
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library KT
globals
private trigger array trig
private integer array max
private integer array timerid
private timer array KeyTimer
private integer KeyTimerMax=0
private trigger Carry
endglobals
private function KeyTimerLoop takes nothing returns nothing
local integer id=timerid[R2I(TimerGetTimeout(GetExpiredTimer())*200)]
local integer min=(id-1)*400
local integer i=max[id]
loop
exitwhen i==min
if TriggerEvaluate(trig<i>) then
set Carry=trig<i>
call TriggerClearConditions(Carry)
set trig<i>=trig[max[id]]
set trig[max[id]]=Carry
set max[id]=max[id]-1
endif
set i=i-1
endloop
if max[id]==min then
call PauseTimer(KeyTimer[id])
endif
endfunction
public function Add takes code func, integer attachment, real period returns nothing
local integer i=R2I(period*200)
local trigger t
if timerid<i><1 then
set KeyTimerMax=KeyTimerMax+1
set timerid<i>=KeyTimerMax
set KeyTimer[KeyTimerMax]=CreateTimer()
set max[KeyTimerMax]=(KeyTimerMax-1)*400
endif
set i=timerid<i>
set max<i>=max<i>+1
if trig[max<i>]==null then
set trig[max<i>]=CreateTrigger()
endif
set t=trig[max<i>]
if GetTriggerExecCount(t)>attachment then
call ResetTrigger(t)
else
set attachment=attachment-GetTriggerExecCount(t)
endif
call TriggerAddCondition(t,Condition(func))
loop
exitwhen attachment==0
call TriggerExecute(t)
set attachment=attachment-1
endloop
set t=null
if max<i>==(i-1)*400+1 then
call TimerStart(KeyTimer<i>,period,true,function KeyTimerLoop)
endif
endfunction
// This function is just here for those who don't feel confident using
// GetTriggerExecCount(GetTriggeringTrigger()) directly.
public function GetData takes nothing returns integer
return GetTriggerExecCount(GetTriggeringTrigger())
endfunction
endlibrary
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// End of Key Timers 2
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// The below is for simple implementation.
function InitTrig_KT takes nothing returns nothing
endfunction</i></i></i></i></i></i></i></i></i></i></i></i></i>
About a week ago Cohadar was telling me to make Key Timers not use a textmacro interface. Done.
This turns out to be similar to Timer Ticker, but you can use multiple periods, and it uses a more efficient load struct method.
This comes with a few other minor limits, but try it and see. If you only need one fixed period you may as well use Timer Ticker instead... It should be a tiny bit faster. However, the load struct method in this is actually faster than Ticker Timer. I tested it. It's about 3x or 4x as fast according to my test.
Below is a simple example map.