HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

TimedLoop

04-16-2009, 01:39 PM#1
Vexorian
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.


Collapse Usage Sample:
struct moveUnit

    unit u

    //=====================================================
    // You need to code an onTimedLoop method before
    // implementing the module.
    //
    private method onTimedLoop takes nothing returns boolean
        //instance's timer expired:
        // This will just move a unit's x coordinate with
        // a speed of 100 until it reaches 5000.0

        call SetUnitX(u, GetUnitX(u) + 100.0* TimedLoop_PERIOD )
        // notice the use of the TimedLoop_PERIOD constant
        // since it may be tweaked by the user...


        if ( GetUnitX(u) >= 5000) then
            return TimedLoop_STOP
        endif

     return TimedLoop_CONTINUE

     //You are free to/should use false and true instead of the
     //constants.
    endmethod

    implement TimedLoop //This does the module magic

    static method create takes unit u returns moveUnit
     local moveUnit m= moveUnit.allocate()
        set m.u = u
        call m.startTimedLoop() //The module works by
        // creating a startTimedLoop method that will
        // do all the dirty work and end up calling
        // .onTimedLoop...
        //
     return m
    endmethod

endstruct
//call moveUnit.create(GetTriggerUnit()) and see...

Names are now finished..

Expand thecode:
04-16-2009, 03:06 PM#2
grim001
Function calls with no parameters are pretty fast, I have heard around as fast as using trig functions, and my physics engine has managed to use hundreds of them per second without lagging. People should get over the fear of using something like this for spell development.

You could get around the one timer per struct-type problem by using a single public timer in the library. You would also need a new integer in the library that keeps track of the total instances using the timer so you know when to start/stop it. I did something like that in UnitList with a public trigger that each struct-type just adds an action to.

I vote "LoopModule" for the name; everyone is naming their module libraries SomethingModule, just like when every new game for the Nintendo 64 ended with "64".
04-16-2009, 03:12 PM#3
Vexorian
The function call actually has a single "this" argument.

PeriodicModule ? LoopModule sounds like a way to make it easy to loop through the instances of a struct anywhere. This is focused on timers.
04-16-2009, 03:18 PM#4
grim001
OK, it compiles to have one argument (I am sleepy), it's still very fast.

Since your main function name is "startLoop," LoopModule kind of fits, but it would make more sense to call it PeriodicModule and rename the method to startPeriodic.
04-16-2009, 06:09 PM#5
C2H3NaO2
I don't like having a fixed period. In my opinion it would be the better choice, to force the user to define a static constant real in ever struct using this.
In movement stuff your constant may be the right choice, but for example in my buff system 0.25 is enough or sometimes it want to move something not i a smooth way.
A feature for optimal overwriting of something from modules would be nice :)
04-16-2009, 06:17 PM#6
Anitarf
What's NOT_IN_LOOP for?

It would help understanding if the post better conveyed which part is the module and which part is the example. Perhaps add some @@ highlights to the example?

The module is very specific. I could see other uses for a list of all structs besides looping through them periodically (although that is the most common use and doing that alone is certainly justification enough for a module), could perhaps the list be one module and the timerloop another module that uses the list?
04-16-2009, 08:32 PM#7
Vexorian
Quote:
could perhaps the list be one module and the timerloop another module that uses the list?
a general purpose list is complicated to implement and requires a lot more code than that and safe guards. Yet such list module already exists and grim made two of them.

I like this module because of being so specific, most of my spells really only need a single loop.
04-16-2009, 09:47 PM#8
cohadar
Collapse JASS:
//* nothing and returns boolean, if the method
//* returns false, the instance will get removed
//* from the loop and destroyed.
Do you have to be an ass?
04-20-2009, 02:10 PM#9
Vexorian
Quote:
Originally Posted by cohadar
Collapse JASS:
//* nothing and returns boolean, if the method
//* returns false, the instance will get removed
//* from the loop and destroyed.
Do you have to be an ass?
????? Not sure why are you being so aggressive against those comments.

Ok, grim onLoop is a bad name for that method anyway. will have to think of a new name for the method and module.
04-21-2009, 10:37 AM#10
dead_or_alivex
I remember cohadar saying something about how a true return signaling that an instance should be removed from a loop has become a standard. Also, a true return is what you use in TT.

Personally I've always used false returns, in my own systems. Somehow it seems more intuitive. But yeah, it's a minor thing...
04-21-2009, 11:21 AM#11
grim001
I say that the boolean is for whether the loop should keep running. False = remove it from the loop.
04-21-2009, 11:39 AM#12
Captain Griffen
Periodic - True
Not - False

Standard established by Blizzard has been there far longer and used by everyone who uses timers directly.
04-21-2009, 11:51 AM#13
grim001
The boolean that's returned isn't an argument for starting a timer, it's an argument for whether it should continue or not.
04-21-2009, 05:10 PM#14
Captain Griffen
Quote:
Originally Posted by grim001
The boolean that's returned isn't an argument for starting a timer, it's an argument for whether it should continue or not.

It's the same principle, so it makes no sense to flip it, as you could have it as a return as to whether to stop it or not, but stopping it is more negative than positive.
04-22-2009, 10:42 PM#15
Strilanc
You should return an enum (an integer, with some public constants). Nobody disagrees about what RET_REMOVE and RET_KEEP mean.