• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[The world needs one more timer system] TimerStack

Level 17
Joined
Apr 27, 2008
Messages
2,455
Because there are not already enough timer systems available, i come with this one to save the world.

The main point is to keep it simple, you don't have to know how many timers at max you will use, and cut off much verbosity.
This is not for speedfreaks.

Personnaly when i need to get a timer, i obviously need to start it and most of time link an integer data to it (even if you don't need it you can still use 0).
Also, there is no real point to decide if it will be a periodic time or not, since if it is not supposed to be a periodic one, you will still have to release it on timer expiration, always periodic is enough.

And when you need to release it on timer expiration, the release function will give the integer data linked to the timer (less verbosity).

Well, i don't really know if it's enough for approval, but i don't care that much if it's rejected, at least it's a proof of concept.

JASS:
library TimerStack

    globals
        private constant integer DOUBLE_FREE = -42 // used on debug mode only
        private integer N = 0
        private timer array Tim
        private hashtable Hash_t = InitHashtable()
    endglobals
    
    function TimerSetData takes timer tim , integer data returns nothing // public for completness reason but i have not used it yet
        call SaveInteger(Hash_t,GetHandleId(tim),0,data)
    endfunction
    
    function TimerNew takes real period, code c , integer data returns timer
        if N == 0 then
            set Tim[0] = CreateTimer()
        else
            set N = N-1
        endif
        call TimerSetData(Tim[N],data)
        call TimerStart(Tim[N],period,true,c)
        return Tim[N]
    endfunction
    
    function TimerGetData takes timer tim returns integer
        return LoadInteger(Hash_t,GetHandleId(tim),0)
    endfunction
    
    function TimerRelease takes timer tim returns integer
        local integer data = TimerGetData(tim)
        debug    if not SaveTimerHandle(Hash_t,0,0,tim) then
        debug        call BJDebugMsg("TimerRelease : invalid timer (null or ghost) on trigger : " + I2S(GetHandleId(GetTriggeringTrigger())))
        debug        return 0
        debug    endif
        debug    if TimerGetData(tim) == DOUBLE_FREE then
        debug        call BJDebugMsg("TimerRelease : double free of timer : " + I2S(GetHandleId(tim)) + " on trigger : " + I2S(GetHandleId(GetTriggeringTrigger())))
        debug        return 0
        debug    endif
        debug    call TimerSetData(tim,DOUBLE_FREE)
        set Tim[N] = tim
        call PauseTimer(tim)
        set N = N+1
        debug    if N > 8190 then
        debug        call BJDebugMsg("TimerRelease : something really wrong is happening, you were using more than 8190 timers at the same time !")
        debug        return 0
        debug    endif
        return data
    endfunction

endlibrary
 
Level 6
Joined
Jun 20, 2011
Messages
249
When i read timer stack i though you were doing some kind of 1 timer system with queued expiration time, huge dissapointment. The stack is used only for recycling.
Hashtable use
No preloaded timers
Only supports periodic timers (what?)
This is a bad version of timer utils.
 
It's still geared quite heavily for speed freaks because all the safety is kept in debug-mode only. Still it could potentially serve as a replacement for TimerUtils once a map maker has debugged everything (when is a map completely debugged?)

It is pretty much TimerUtilsEx by Magtheridon96 in the flavor which uses hashtable. Though it's a readable example to show people how TimerUtils works because Vexorian/Anitarf's mess looks quite complicated and has some bad programming structure as well.

Edit: looking at Dirac's reply, I noticed the extra parameters in TimerNew. I recommend adding a parameter to define if it should be periodic.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
My dear Dirac i expected your objective and really thought comments.

- I don't care to use one hashtable instead of a Table, really, unless you spam hashtables you won't reach the limit of 256

- Ofc not periodic timers are supported, but internally they are all periodic.
The reason is simple : even for not periodic ones you still have to release it on timer expiration.
So the boolean argument is pointless.

- "blue" version of TimerUtils is bad in many ways, i'm not going to preload timers, just because if you go this way it also needs more "optimizations" which is not compatible with less verbosity.
 
Mag, if you are using timers just for recycling (I think this was CSSafety by Vexorian), you might as well just be using regular timers and destroying them.

Though I like the idea of TimerNew not taking an integer argument, and TimerNewEx taking one.

@ Troll-Brain, you don't need the "DOUBLE_FREE" value. Just set a boolean to the hashtable to the key of 1 if it's in-use, instead of 0, and use RemoveSavedBoolean when it is released.
 
Level 6
Joined
Jun 20, 2011
Messages
249
- I don't care to use one hashtable instead of a Table, really, unless you spam hashtables you won't reach the limit of 256
What on earth? ... who said anything about Table?
I just feel that "using a hashtable" is bad and there should be ways around it, but i've tried them all, the only way to gain performance without using one is merging timers (TimerTools) and it's extremely unstable.
I like Mag's version over this one just because it has the same API as TimerUtils. (I really hate that vex hasn't modified release timer so it would return the data)
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I've designed it to set the data only on timer get, but well i suppose that's not much a big deal to also destroy the data on timer release. (talking about split TimerNew in TimerNew and TimerNewEx).
Now, i'm not sure this new function is really needed, coz of what Bribe said, and anyway most of time you need to link an integer data. And even if you want to recycle timers and don't need to link a data, using "0" as an argument is fair enough.

As stated by Bribe, the DOUBLE_FREE value is not needed.

Now about debug stuff, maybe i should just debug the messages and keep the ifs, i'm not sure.
For me if you're going to double free, the map script already wouldn't work so well, but in some case it could.
Well, i suppose i will use a static if and constant safety boolean, which will be true by default :p

What on earth? ... who said anything about Table?
I just feel that "using a hashtable" is bad and there should be ways around it, but i've tried them all, the only way to gain performance without using one is merging timers (TimerTools) and it's extremely unstable.

I'm not in your mind.
Anyway the only faster and "safe" way without hashtable is to preload timers, i don't want to preload timers, because it's pointless and the user have to know how many timers he needs.
I also like the idea to use only as many timers as needed, no more, no less.


I like Mag's version over this one just because it has the same API as TimerUtils. (I really hate that vex hasn't modified release timer so it would return the data)

You don't need to preload timers on the blue version, it's not the point of it.
ReleaseTimer will probably never change, the .evaluate() is also fun, and finally i think i've already talked enough about less verbosity.
You don't like it ? Don't use it, simple as that.
 
Last edited:

BBQ

BBQ

Level 4
Joined
Jun 7, 2011
Messages
97
debug use static if (DEBUG_MODE)
debug instead of this debug eyesore
debug do you see how ugly it is?
debug nevertheless
debug this system is utterly pointless
debug if you care so much (if I were still modding, I would)
debug just post a "proper" version of TimerUtils
debug with the same API and everything
debug it's not like it's licensed or copyrighted or something
debug thank you for your time
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Great, an other troll joins the party.

There is a reason why i use debug instead of static ifs, just because static ifs are too closed than normal ifs (visually).
Not to mention that it actually doesn't matter.

There are reasons why i don't use the same API, and i've already explained it.
 

BBQ

BBQ

Level 4
Joined
Jun 7, 2011
Messages
97
We call it backward- and forward-compatibility. That is more than a reason to use the same API. If you were around at the same time as Vexorian, perhaps you would have been the one to write a library like TimerUtils, and it will be your very own API that we will be debating over now. Even if it sucked hard, I would still insist that it remains in use.

For specific map-making, there may not be much reason, but for sharing things with a community? Oh, there is one hell of a reason.

EDIT: At your comment about the fact that static ifs are closed just like the normal ones. Static and stub methods are closed like normal ones, too. Hell, even operators are closed like methods. Do you not use them?

Also, what about the curly-bracket-family of languages, where everything is closed with a curly bracket? They all suck, right.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
We call it backward- and forward-compatibility. That is more than a reason to use the same API. If you were around at the same time as Vexorian, you would have written a library like TimerUtils by yourself and your API would have been the one that will be used by both spell- and system-makers.

For specific map-making, there may not be much reason, but for sharing things with a community? Oh, there is one hell of a reason.

Ok, i think it's the time to actually read my code and comments.

Now, as said i don't really care if it is rejected, as you said nothing will stop me to use it personnaly.
I know that TimerUtils is a "De Facto" standard, but just because it is, doesn't mean you can't submit anything else.
Just say "use TimerUtils" and "this is utterly useless" is nothing more or less than trolling.

EDIT: At your comment about the fact that static ifs are closed just like the normal ones. Static and stub methods are closed like normal ones, too. Hell, even operators are closed like methods. Do you not use them?

Also, what about the curly-bracket-family of languages, where everything is closed with a curly bracket? They all suck, right.

Totally off-topic and different.
statics ifs in C are better (just as an example)

Well, take it as you want but for me it's clear that you are trolling.
I don't bother to answer more of your "comments".
 

BBQ

BBQ

Level 4
Joined
Jun 7, 2011
Messages
97
I don't like TimerUtils. I had never used TimerUtils in anything I made. The code that is written specifically for my own use can follow whatever personal standards I like.

On the other hand, sharing a code with a group of people requires standardization — at least in a community such as the WC3 one (I wonder if I can even call it a community). So, you either make Bribe approve your system and go around updating every system/snippet/spell out there, or follow the API that has been used for ages.

Also, your so-called "static ifs in C" are nothing like the "vJass ones."
 
Level 6
Joined
Jun 20, 2011
Messages
249
So, you either make Bribe approve your system and go around updating every system/snippet/spell out there, or follow the API that has been used for ages.
I guess i've been either too stupid or too cocky to say that, but that was the point i was trying to make.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Also, your so-called "static ifs in C" are nothing like the "vJass ones."

Ofc, but quite nothing in "real" languages is like (v)Jass (stop to understand my sentences "word by word", i obviously talked about the visual part of #if, not about the 'static' keyword used in C, no more, no less).
And plz don't tell me that jass is a real language, you know what i want mean.

So, you either make Bribe approve your system and go around updating every system/snippet/spell out there, or follow the API that has been used for ages.

To be honest, i've just realized that even with a different API, TimerUtils and this together wouldn't work (if the user mix my release/get and set/get data with TimerUtils ones, which is likely to happen).
So meh, i suppose it's just too much.
You can graveyard this, not because it's bad by itself, but because for the best and the worst, TimerUtils was, is, and will be heavily used, and this is not safely compatible together.
And ofc update older resources is a big no.
 
Last edited:
Top