| 06-14-2008, 06:56 PM | #1 |
How exactly do you go about looping through structs (or anything else) on a timer (or timer array)? I've seen it used in various scripts, but I haven't a clue how exactly it works (which makes it difficult for me to copy it since I don't know what should go where) Here's the Handler function from Cohadar's TT JASS:globals // List of recommended periods: // 0.04 = 25 calls per second // 0.03125 = 32 calls per second // 0.025 = 40 calls per second // 0.02 = 50 calls per second public constant real PERIOD = 0.03125 // One Timer to rule them all, One Timer to find them, // One Timer to call them all and in the jass bind them // In the land of warcraft where the desyncs lie. private timer Timer = CreateTimer() private integer Data private integer Counter = 0 private trigger array Triggz private integer array Dataz endglobals //============================================================================== private function Handler takes nothing returns nothing local trigger swap local integer i = Counter loop exitwhen i<=0 set Data = Dataz[i] if TriggerEvaluate(Triggz[i]) then set swap = Triggz[i] call TriggerClearConditions(swap) set Triggz[i] = Triggz[Counter] set Triggz[Counter] = swap set Dataz[i] = Dataz[Counter] set Counter = Counter - 1 endif set i = i - 1 endloop // who can guess why am I not nulling swap here? endfunction I don't want to use TT because the timer frequency is way too low for what I need (I only need 0.25 sec frequency) The Counter variable is the part that confuses me. When it is decreased, couldn't a value be overlooked e.g. Integer A is at slot 1 on the array Integer B is at slot 2 on the array If integer A is no longer needed, Counter is reduced by 1 from a previous value of 2, right? And if so, wouldn't the loop miss integer B since Counter is now 1? |
| 06-14-2008, 08:28 PM | #2 |
EDIT: This didn't turn out good. Look at code below instead :P |
| 06-14-2008, 08:35 PM | #3 |
No, because he's counting down instead of up and shuffling the indexes around. There are two ways to iterate through a list of structs: counting up and counting down. JASS://Counting Up globals integer N = 0 integer array Data endglobals function Expire takes nothing returns nothing local integer J = 0 loop set J = J+1 exitwhen J>N if SomeFunctionThatSaysWhenToRemoveDataFromLoop(Data[J]) then call DoSomethingWith(Data[J]) set Data[J] = Data[N] set N = N-1 set J = J-1 endif endloop endfunction JASS://Counting Down globals integer N = 0 integer array Data endglobals function Expire takes nothing returns nothing local integer J = N+1 loop set J = J-1 exitwhen J<=0 if SomeFunctionThatSaysWhenToRemoveDataFromLoop(Data[J]) then call DoSomethingWith(Data[J]) set Data[J] = Data[N] set N = N-1 set J = J+1 endif endloop endfunction |
| 06-14-2008, 08:39 PM | #4 |
Thanks to both of your for the info (Themerion's code kinda confused me with the xyz within the xyz struct )Does the value for N increase everytime a struct/something else is added the the stuff being looped through? EDIT: JASS:if SomeFunctionThatSaysWhenToRemoveDataFromLoop(Data[J]) then call DoSomethingWith(Data[J]) set Data[J] = Data[N] set N = N-1 set J = J+1 endif I could do something like JASS:if SomeBoolean[J] == true then call KillUnit (someunit[J]) set Data[J] = Data[N] set N = N-1 set J = J+1 endif |
| 06-14-2008, 08:48 PM | #5 | |
Quote:
Hm... Yeah, it was kind of confusing. Perhaps this is better? How you loop:struct Data Data next=0 endstruct globals private Data first=0 endglobals function Loop takes nothing returns nothing local Data d = first loop exitwhen d==0 // Do stuff with d... set d=d.next endloop endfunction How you add new stuff to the loop:function Add takes Data d returns nothing set d.next=first set first=d endfunction Reason I don't like the other method is because the internal workings of structs already are arrays. I figure using structs as array types would yield a double array lookup. |
| 06-14-2008, 08:57 PM | #6 |
Yeah, you'd increment N every time you added a new thing to the stack, like so: JASS:set N = N+1 set Data[N] = <Whatever> |
| 06-15-2008, 02:27 PM | #7 |
One last question about where to position some stuff. Let's say I have a real array that counts upwards to 5 seconds, and when a specific array value is above 5, it does some stuff. Where exactly should I place the value increasing line in the loop? JASS:globals integer N = 0 integer array Data private real array SomeRealCounter private constant real SomeVal = 1 endglobals function Expire takes nothing returns nothing local integer J = N+1 loop //Here? set SomeRealCounter[J] = SomeRealCounter[J] + SomeVal set J = J-1 //Or here? set SomeRealCounter[J] = SomeRealCounter[J] + SomeVal exitwhen J<=0 if SomeFunctionThatSaysWhenToRemoveDataFromLoop(Data[J]) then call DoSomethingWith(Data[J]) set Data[J] = Data[N] set N = N-1 set J = J+1 endif endloop endfunction |
