HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Fuckup script - how to avoid?

02-20-2009, 12:11 PM#1
Vestras
So I'm making this script - which basically just has one timer to run a lot of callbacks - but it fuck ups when more than one instance is running. (Of course it does, just look at the code)

So how can I avoid this? Loops? Hashes? Clues pl0x.
Collapse JASS:
library Timer initializer Init

//* Configuration - start

globals
    //* Interval of the global timer
    private constant real TIMER_INTERVAL = 0.03
    //* Maximum number of instances at one time
    private constant integer MAXIMUM_TIMERS = 8190
endglobals

//* Configuration - end

globals
    private timer T = CreateTimer()
    private real array Interval
    private boolean array Periodic
    private boolean array Running
    private real array Counter
    private trigger array Trg
    private integer Count = 0
endglobals

public function Release takes integer i returns nothing
    set Running[i] = false
    set Count = Count - 1
endfunction

private function Handler takes nothing returns nothing
    local integer j = Count
    loop
        exitwhen j == 0
        set Counter[j] = Counter[j] + TIMER_INTERVAL
        if Counter[j] >= Interval[j] then
            call TriggerEvaluate(Trg[j])
            if Periodic[j] then
                set Counter[j] = 0.00
            else
                call TriggerClearConditions(Trg[j])
                call Release(j)
            endif
        endif
        set j = j - 1
    endloop
endfunction

public function Add takes real interval, boolean periodic, code callback returns boolean
    set Count = Count + 1
    if not Running[Count] then
        set Interval[Count] = interval
        set Periodic[Count] = periodic
        set Counter[Count]  = 0.00
        if Trg[Count] == null then
            set Trg[Count] = CreateTrigger()
        else
            call TriggerClearConditions(Trg[Count]) //* Just to be sure
        endif
        call TriggerAddCondition(Trg[Count], Condition(callback))
        if Count == 1 then
            call TimerStart(T, TIMER_INTERVAL, true, function Handler)
        endif
    else
        set Count = Count - 1
    endif
    return true
endfunction

private function Init takes nothing returns nothing
    local integer j = 0
    loop
        exitwhen j == MAXIMUM_TIMERS
        set Running[j] = false
        set j = j + 1
    endloop
endfunction

endlibrary

Oh, and how can I attach data in 'categories'? Like gamecache? Because I want the user of this to be able to attach and get data, but it's a bit hard to do that when I only have one handle to attach it to... could I attach it to the trigger, maybe?
02-20-2009, 12:39 PM#2
xombie
If you're trying to do what I think you are then you should refer to TimerUtils by Vexorian.
02-20-2009, 12:51 PM#3
Vestras
Quote:
Originally Posted by xombie
If you're trying to do what I think you are then you should refer to TimerUtils by Vexorian.

I'm obviously not, or, depends on the attaching or the idea.
And with the attaching it's really not what I want either, I want the data to be stored in different categories of a variable.

Like a house, for example. It has rooms with people, or here, data. In the house lives a family of data, but they are divided into different rooms, where they can be reached.

Get it? Because I don't know how to explain better.

The system is supposed to handle a lot of callbacks, like some kind of a GUI-timer. It's a timer on the outside, but on the inside, it's just a bunch of set variables which are run through when the user wants.
02-20-2009, 12:59 PM#4
xombie
What difference does it make whether or not they are in different rooms? Accessing data is accessing data. Are you saying you'd rather only be able to access whichever room you choose to at any given time? That would just slow down the entire process of you 'attaching' data to a handle. Also, with structs, there is no real need to be attaching anything other than integers.
02-20-2009, 01:19 PM#5
Vestras
Quote:
Originally Posted by xombie
What difference does it make whether or not they are in different rooms? Accessing data is accessing data. Are you saying you'd rather only be able to access whichever room you choose to at any given time? That would just slow down the entire process of you 'attaching' data to a handle. Also, with structs, there is no real need to be attaching anything other than integers.

If I just attached the data in one 'room', to the global timer, then when accessing, it would just return random data. Wouldn't it?
02-20-2009, 01:24 PM#6
Vexorian
Just keep trying, you might eventually reinvent interfaces.

Really though, why do this when there are already 20 versions of TT? Cause that's what you are trying to code here, TT. Except that on top of it you have some interval variable so you can have timeouts higher than 0.03... Which is a bad idea isn't it? Besides that you have TriggerEvaluates in timer callbacks, you will periodically iterate on timers that did not timeout yet.

Oh, get rid of the Running array, you don't need it , its logic is badly coded and it will ultimately just limit the maximum number of timers. No, you don't need it, just think stuff better when removing an element of the array, you do not need to keep the original order..
02-20-2009, 02:00 PM#7
Vestras
Please apologize my utter stupidity, but I understood nothing of this: "Really though, why do this when there are already 20 versions of TT? Cause that's what you are trying to code here, TT. Except that on top of it you have some interval variable so you can have timeouts higher than 0.03... Which is a bad idea isn't it? Besides that you have TriggerEvaluates in timer callbacks, you will periodically iterate on timers that did not timeout yet." except the TT thing, which really wasn't intended, as I thought TT did something else, obviously.

> Oh, get rid of the Running array, you don't need it , its logic is badly coded and it will ultimately just limit the maximum number of timers. No, you don't need it, just think stuff better when removing an element of the array, you do not need to keep the original order..

I'd love to, but mind sharing what I should replace it with?

> Just keep trying, you might eventually reinvent interfaces.

I'm sorry... what?
02-20-2009, 04:20 PM#8
Kyrbi0
Quote:
Originally Posted by Vestras
Quote:
Originally Posted by Vexorian
Just keep trying, you might eventually reinvent interfaces.
I'm sorry... what?
I believe he was employing Sarcasm (tm).
02-21-2009, 01:20 AM#9
dead_or_alivex
Quote:
I'd love to, but mind sharing what I should replace it with?
A struct array, which you add instances to and remove them from. Every time the global timer times out, loop through the array and check the instances for expiry, execute functions, etc.

I've heard that using and recycling individual timers with TimerUtils is more efficient, though. This one-timer stuff is best suited for periodic effects. Anitarf's post on the matter.

Quote:
If I just attached the data in one 'room', to the global timer, then when accessing, it would just return random data. Wouldn't it?
Yes. Of course you shouldn't do that. Attach the data to the instances, i.e. associate it somehow with the individual instances that run. Use a struct or something.

Really, this is like the whole basis of MUI in spell-making. You don't make all variables global for a reason.