HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Looping through structs on a timer

06-14-2008, 06:56 PM#1
the-thingy
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
Expand JASS:

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
Themerion
EDIT: This didn't turn out good. Look at code below instead :P
06-14-2008, 08:35 PM#3
Pyrogasm
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.
Collapse 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
Collapse 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
Whichever one you use is up to you.
06-14-2008, 08:39 PM#4
the-thingy
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:
Collapse 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
Collapse JASS:
        if SomeBoolean[J] == true then
            call KillUnit (someunit[J])

            set Data[J] = Data[N]
            set N = N-1
            set J = J+1
        endif
right?
06-14-2008, 08:48 PM#5
Themerion
Quote:
Themerion's code kinda confused me with the xyz within the xyz struct

Hm... Yeah, it was kind of confusing. Perhaps this is better?

Collapse 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

Collapse 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
Pyrogasm
Yeah, you'd increment N every time you added a new thing to the stack, like so:
Collapse JASS:
set N = N+1
set Data[N] = <Whatever>
06-15-2008, 02:27 PM#7
the-thingy
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?

Collapse 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