• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece!🔗 Click here to enter!

[vJASS] Create an own timer

Status
Not open for further replies.
Level 16
Joined
May 1, 2008
Messages
1,605
Moin moin and hello =)

As you can think of the title, I want create from now on my own timer for my spells I create.

Up to now, I used the library "TimerUtils". With this (nice) extra library I could create a timer like this:

JASS:
// in the create method:
local timer t = NewTimer()
//...
//...
call SetTimerData(t,this)
call TimerStart(t,0.04,true,function blabla)

// in the loop method at the beginning:
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)

// After all actions and spell is done:
call ReleaseTimer(t)

So now my question: What must I type, if I create an own timer for the spell/struct and how to use it in the create for create and in the loop for the loop?? Because "NewTimer,SetTimerData,GetTimerData,ReleaseTimer" was from TimerUtils (as far as I know)

Hope someone can help me with this and please you know my bad understanding of English, so no imba-owned-vjass-words here please =)

Greetings and Peace
Dr. Boom
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
NewTimer()
This retreives a timer from the timer recycling system. Basically a list of timers that get reused instead of you creating new timers all the time. Instead of destroying a timer you add it back to the list for use later. Only if there are no free timers in the list will it create a new one. This is called "Green Coding" and is even used professionally in languages like Java to save the engine time allocating and the garbage collector from spending time recycling memory. In Jass it also means you do not have to null the local timer to avoid the handle recycler reference bug as the timer never gets destroyed.

SetTimerData(timer,integer)
This attaches the integer to the timer so that from the timer, the integer can be recalled. There are 2 ways to do this, one is to encode the integer onto the timeout of the timer and the other is to store the integer in a data structure at the location of the handle ID of the timer. I believe timer utilities uses the data structure approach where it defaults to an array offset by the null pointer and can be set to store overflows into a hashtable.

GetTimerData(timer)
Basically recalls the attached integer from the timer.

ReleaseTimer(timer)
This adds the timer back to the timer list so that it can be recalled and reused later.
 
Level 16
Joined
May 1, 2008
Messages
1,605
Yes ... well .. so far so good, but what I asked was, how to create an own timer for each spell I create ^^

Because it's possible fine to use another library for it and so on, but I want learn how to create an own timer, because when I don't use TimerUtils anymore, then I don't have these actions =)
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Taken from common.j wc3 1.26
JASS:
//============================================================================
// Timer API
//
native CreateTimer          takes nothing returns timer
native DestroyTimer         takes timer whichTimer returns nothing
native TimerStart           takes timer whichTimer, real timeout, boolean periodic, code handlerFunc returns nothing
native TimerGetElapsed      takes timer whichTimer returns real
native TimerGetRemaining    takes timer whichTimer returns real
native TimerGetTimeout      takes timer whichTimer returns real
native PauseTimer           takes timer whichTimer returns nothing
native ResumeTimer          takes timer whichTimer returns nothing
native GetExpiredTimer      takes nothing returns timer
 
Level 16
Joined
May 1, 2008
Messages
1,605
Yes well so far so good too, but how must I use it in my spell with those stuff?

JASS:
// in the create method:
local timer t = // what instead of NewTimer()? > CreateTimer()?
// ...
// ...
// normally here comes "SetTimerData". What need I do else?
call TimerStart(t,0.04,true,function soANDso)

// and then in the loop:
local timer t = GetExpiredTimer()
// local thistype this = //what instead of GetTimerData(t)?
// ...
// call //what instead of ReleaseTimer(t)? DestroyTimer(t) ?

Also need I any struct member extra for an own timer each spell? Or something else I should notice or do?

Greetings and Peace
Dr. Boom
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
There's no native implementation for SetTimerData with timers, you could use hashtables for that or use an already existing attachment system (like TimerUtils).
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Have you looked at the code for TimerUtils?

JASS:
globals
    hashtable h = InitHashtable()
endglobals


/*
    
    function toExecute takes nothing returns nothing
        local integer data = LoadInteger(h, GetHandleId(GetExpiredTimer()), 0)
        
        -- Now you can reference "data" (which can be a struct, associated with
        many types of data).
        
        -- Remember you have to recycle the parent hashtable after its use so that
        you do not waste resources.
        
        call RemoveSavedInteger(h, GetHandleId(GetExpiredTimer()), 0)
        
        -- You also have to destroy the timer when you are done with it. Apparently
        there are some bugs with this (which is why systems like TimerUtils are used).
        
        call DestroyTimer(GetExpiredTimer())
    endfunction
    
 */


// @func    -> the code that will be executed per timer interval.
// @data    -> the data associated with the timer you are executing.
function StartTimer takes integer data, code func returns nothing
    local timer t = CreateTimer()
    
    call SaveInteger(h, GetHandleId(t), 0, data)
    call TimerStart(t, 2, true, func)
    
    set t = null
endfunction
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
I know that JASS can do ALL that GUI can/cant, but that's not really my question DSG...I asked about timers (as a 'key'), coz in GUI you can have a key like picked unit, triggering unit, etc...so without using timers, is it possible to retreive data?...

btw Im talking about 'real jass', not GUI converted to jass so pls dont answer the 'EnumUnit' thing :)...
 
Level 16
Joined
May 1, 2008
Messages
1,605
Well Berb, this looks like something, what I was looking for but I still have aquestion to it:

Also there stands: "You also have to destroy the timer when you are done with it. Apparently there are some bugs with this."
What bugs are this and how often can they happen? Because what's the effect, if I use my own timer then and this will bug at the end...
 
Last edited:
Level 18
Joined
Jan 21, 2006
Messages
2,552
That's probably being a little bit paranoid. I personally have never experienced any problems creating and destroying my timers but apparently other people have - though nobody really has anything specific to say on this.

I think Rising_Dusk was the first person I talked to who "had problems with timers". He said that destroying timers would randomly cause handle stack corruptions, but again I have dealt with thousands upon thousands of timers and I have never experienced this.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
I thought it was triggers that caused random handle stack curroptions which resulted in crashes...

Anyway, the reason to recycle timers was largly because it means you do not have to null local timers before the end of the function as they will exist for the entire duration of the game.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Yes, it's triggers. link

A destroyed timer may sometimes still execute it's callback code if not paused before being destroyed, if the said timer's local pointer was nulled beforehand. I don't know if it still applies since that was way back on version 1.20 below. And as Dr. Super Good mentioned, CS_Safety (now TimerUtils) recycled timers to prevent the said bug, but it requires more memory since it caches the timers. It's also makes timer manipulation have less overhead by not requiring the user to allocate a timer object.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
The amount of memory it uses is not worth an argument. Leaks inside the game engine easilly drown out a couple of timers that constantly get recycled.

The problem is the system is poor if the map will go through a once off spike of timer use (like a cinimatic or something stupid that allocates 100 odd timers) as you will then have a few dozen timers sitting there never being used and clogging up resources. This however should never be a problem (unused resources on such small scales should make no difference) and as long as you still null the locals, you could if nescescary free up some of the timer stack at key times (like a software game reset).
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Chill dude, I'm not arguing that TimerUtils is a bad system because it caches the timers, I'm just stating the trade-offs for the said system.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
It is not the only system which recycles timers using a timer stack. I usually wip up my own in like 10 seconds when I need one. Others include a separate timer recycler only library, vexorians caster system (I think) and a few utilitiy compilations).

Yes, consistency is a problem but I am sure the vJASS makers added some reroute function call functionality to allow the easy changing of timer recycling systems.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
If I plan on donating something to the resources section I usually make sure it uses the libraries that most people would have (which typically excludes my own quick-typed ones).

Yes, it's triggers.

But by the look of it you need to use two TriggerSleepAction calls to get that. I never use a single instance of TriggerSleepAction - so am I safe?
 
But by the look of it you need to use two TriggerSleepAction calls to get that. I never use a single instance of TriggerSleepAction - so am I safe?

Yes, you would be safe from that method. Although, I have heard that there were other means of making handle stack corruptions. (eg: remove unit) I'm pretty sure there are a number of ways for it to occur, but generally, you won't experience that problem unless you have retarded code.
 
Status
Not open for further replies.
Top