14 years
edited 8 years
All right, after the PeriodicLoopModule failure, this is a simpler version that is less flexible but should work, it is for structs that are exclusive for looping and will conflict with stuff that require you not to call .destroy but another method.
It is a module you implement in a struct to do the whole array+loop thing that we always do in spells. Only that this time you won't have to code it all the time... an example:
Only disadvantage against doing the loop manually is that it will do a function call (not TriggerEvaluate) for each instance in the loop. Differences with things like TT is the OOPness and the lack of TriggerEvaluate, though it uses a timer per struct type, wonder if that's important.
Usage sample
Names are now finished..
The code:
It is a module you implement in a struct to do the whole array+loop thing that we always do in spells. Only that this time you won't have to code it all the time... an example:
Only disadvantage against doing the loop manually is that it will do a function call (not TriggerEvaluate) for each instance in the loop. Differences with things like TT is the OOPness and the lack of TriggerEvaluate, though it uses a timer per struct type, wonder if that's important.
Usage sample
1 struct moveUnit2 3 unit u
4 5 //=====================================================6 // You need to code an onTimedLoop method before7 // implementing the module.8 //9 private method onTimedLoop takes nothing returns boolean
10 //instance's timer expired:11 // This will just move a unit's x coordinate with12 // a speed of 100 until it reaches 5000.013 14 call SetUnitX(u, GetUnitX(u) + 100.0* TimedLoop_PERIOD )
15 // notice the use of the TimedLoop_PERIOD constant16 // since it may be tweaked by the user...17 18 19 if ( GetUnitX(u) >= 5000) then
20 return TimedLoop_STOP21 endif22 23 return TimedLoop_CONTINUE24 25 //You are free to/should use false and true instead of the26 //constants.27 endmethod28 29 implement TimedLoop //This does the module magic
30 31 static method create takes unit u returns moveUnit
32 local moveUnit m= moveUnit.allocate()
33 set m.u = u
34 call m.startTimedLoop() //The module works by
35 // creating a startTimedLoop method that will36 // do all the dirty work and end up calling37 // .onTimedLoop...38 //39 return m40 endmethod41 42 endstruct43 //call moveUnit.create(GetTriggerUnit()) and see...44
Names are now finished..
The code:
1 library TimedLoop2 //********************************************************3 //* TimedLoop4 //* ---------5 //*6 //* Requires jasshelper 0.9.G.1 or greater.7 //*8 //* A library + module that are meant to make those9 //* array + timer loops easy, yet still faster than10 //* other alternatives meant to be easy (In other words11 //* no TriggerEvaluate is involved).12 //*13 //* The OOPness is interesting.14 //*15 //* Before implementing TimedLoop16 //* your struct needs an onTimedLoop method that takes17 //* nothing and returns boolean, if the method18 //* returns false, the instance will get removed19 //* from the loop and destroyed, else it will continue,20 //* think of it as if the call asks the method a21 //* question: "Should I continue the loop afterwards?"22 //*23 //* Alternatively, if you are not convinced, you may24 //* use the TimedLoop_CONTINUE and TimedLoop_STOP25 //* constants in the method's returns.26 //* 27 //* After implementing TimedLoop, you can call28 //* the startTimedLoop method to add the periodic event29 //* to that instance, only call it once per instance.30 //*31 //* I recommend to call implement just bellow the32 //* declaration of the onLoop method, else it will33 //* actually use TriggerEvaluate, which is lame. Remind34 //* me to implement a topsort in jasshelper.35 //*36 //* If you feel the need to destroy the struct outside37 //* the loop, well, you'll have to add a flag to it so38 //* you send a message to onLoop to make it return false.39 //* A more complicated module to allow that easily would40 //* come later.41 //*42 //********************************************************43 44 //========================================================45 // config:46 47 globals48 public constant real PERIOD = 0.025
49 // A lower value and everything using the module will50 // look better, yet performance will drop.51 endglobals52 53 //========================================================54 // implementation:55 //56 globals57 public constant boolean STOP = false
58 public constant boolean CONTINUE = true
59 endglobals60
61
62 //=========================== 63 module TimedLoop64 // god bless private module members.65 //66 private static thistype array V // The array
67 private static integer N = 0 // The count
68 private static timer T = null // the timer, one per
69 // struct that implements this70
71 private static method onExpire takes nothing returns nothing
72 local integer n = 0
73 local thistype this // yay for odd-sounding syntax constructs
74 local integer i = 0
75
76 loop77 exitwhen (i== thistype.N)
78 set this = .V[i]
79 if ( this.onTimedLoop() == CONTINUE ) then
80 set .V[n] = this
81 set n=n+1
82 else83 call this.destroy()
84 endif85 set i=i+1
86 endloop87 set thistype.N = n
88 if (n== 0) then
89 call PauseTimer(.T)
90 endif91
92 endmethod93
94 public method startTimedLoop takes nothing returns nothing
95 set .V[.N] = this
96 set .N=.N + 1
97 if (.N == 1) then
98 if (.T == null) then
99 set .T = CreateTimer()
100 endif101 call TimerStart(.T, PERIOD, true, function thistype.onExpire)
102 endif103 endmethod104
105 endmodule106 107 108 endlibrary