HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Timer question

01-21-2008, 02:11 PM#1
chobibo
Is it possible to use a single global timer for multiple tasks; for example, use it to time 2 actions at once?
function a uses timer to time something for 10 seconds and function b uses the same timer to time something for 5 seconds, would their callback functions run or only the last function starting the timer ( function b ) will get its callback function run?
01-21-2008, 02:26 PM#2
Troll-Brain
Collapse JASS:
library erre initializer InitErre

globals
    constant real DMIN = 10.00
    constant integer TMIN = 1
    constant integer DETECT = 'Amdf'
    constant string ORDRE = "magicundefense"
    constant string KEY = "erre"
    gamecache G
endglobals

globals
    private integer Int1 = 0
    private timer Tim1
    private group Grp_erre
    private trigger Trig_erre
endglobals

private struct erre
    integer t
    real dMin
    real dMax
    integer tMin
    integer tMax
endstruct

private function H2I takes handle h returns integer
    return h
    return 0
endfunction

function UnitAddErre takes unit u,real dMin,real dMax,integer tMin,integer tMax returns boolean
    local integer i
    local string s
    local integer ref
    local erre e
   
    if u==null or dMax<dMin or tMax<tMin or dMin<DMIN or tMin<TMIN or GetUnitState(u,UNIT_STATE_LIFE)<=0.405 then
        return false
    endif
    if GetUnitAbilityLevel(u,DETECT)==0 then
        call UnitAddAbility(u,DETECT)
    endif
    set i=H2I(u)
    set s=I2S(i)
    set ref =GetStoredInteger(G,s,KEY)
    if ref==0 then
        set e=erre.create()
        call GroupAddUnit(Grp_erre,u)
    else
        set e=ref
    endif
        set e.t=GetRandomInt(tMin,tMax) + Int1
        set e.dMin=dMin
        set e.dMax=dMax
        set e.tMin=tMin
        set e.tMax=tMax
        call StoreInteger(G,s,KEY,e)
    return true
endfunction

private function LoopGrp takes nothing returns nothing
    local unit u = GetEnumUnit()
    local erre e
    local real d
    local real a
    local real x
    local real y
   
    if u == null then
        return
    endif
    set e = GetStoredInteger(G,I2S(H2I(u)),KEY)
    if e == 0 then
        set u = null
        return
    endif
    if e.t == Int1 then
    set d = GetRandomReal(e.dMin,e.dMax)
    set a = GetRandomReal(0,2*bj_PI)
    set x = GetUnitX(u) + d*Cos(a)
    set y = GetUnitY(u) + d*Sin(a)
    call IssuePointOrder(u,"move",x,y)
    set e.t = GetRandomInt(e.tMin,e.tMax) + Int1
    endif
    set u = null
endfunction

private function func1 takes nothing returns nothing
    set Int1=Int1+1   
    call ForGroup(Grp_erre,function LoopGrp)
endfunction

private function FilterOrder takes nothing returns boolean
    local unit u = GetTriggerUnit()
   
    if IsUnitInGroup(u,Grp_erre) and OrderId2String(GetIssuedOrderId())==ORDRE and GetUnitState(u,UNIT_STATE_LIFE)<=0.405 then
        set u = null
        return true
    endif
    set u = null
    return false
endfunction

private function DestroyErre takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local string s = I2S(H2I(u))
    local erre e = GetStoredInteger(G,s,KEY)
    call e.destroy()
    call FlushStoredInteger(G,s,KEY)
    call GroupRemoveUnit(Grp_erre,u)
    set u = null
endfunction

private function InitErre takes nothing returns nothing
    local integer i = 0
    set G = InitGameCache(KEY)
    set Tim1 = CreateTimer()
    call TimerStart(Tim1,1.00,true,function func1)
    set Grp_erre=CreateGroup()
    set Trig_erre=CreateTrigger()
    call TriggerAddAction(Trig_erre,function DestroyErre)
    call TriggerRegisterAnyUnitEventBJ(Trig_erre,EVENT_PLAYER_UNIT_ISSUED_ORDER)
    call TriggerAddCondition(Trig_erre,Condition(function FilterOrder))
   
    loop
    exitwhen i == 12
    call SetPlayerAbilityAvailable(Player(i),DETECT,false)
    set i = i + 1
    endloop
endfunction

endlibrary

In this "system" i use only one periodic timer of 1s for many units.
and i can use it also for as many functions as i want, but the first use accurate depends the time of the timer ( if you want use like a periodic one, if not it's always not accurate)
I hope you will understand the code, i'm too lazy to make a clear example, but if you don't understand what i want mean, i can make one
01-21-2008, 02:37 PM#4
Vexorian
Of course it is possible. Just use a heap and two real variables, you may have to use two timers instead of one but the count remains constant, afaik this is what magictimers do...
01-21-2008, 03:54 PM#5
chobibo
@Troll: Thanks a lot for the code, I'm examining it right now : )
@Vexorian: Umm I don't know what heaps are but I'll try searching : ), I also looked on the magictimers code, the problem is I don't understand it as I am not a programmer lol : ). I'm gonna review your magictimers again. Thanks a lot

@off-topic: Vexorian, can I use my old post " Array Cache " to post my timer attachment system, I was really intending to improve the algorithm of my first code but what I created instead was a timer attachment system lol. Should I make a new thread or just update that old one?
01-21-2008, 06:05 PM#6
Jitse
Troll-brain, your variable naming is horrible. :p
01-21-2008, 06:14 PM#7
Troll-Brain
True, but some of them are not written in english :p
01-22-2008, 05:30 AM#8
EnderA
Quote:
Originally Posted by Jitse
Troll-brain, your variable naming is horrible. :p

Find/replace for the win.
01-22-2008, 11:07 AM#9
Troll-Brain
@off-topic: i made it for someone dunno jass.

I did not planned to post here, or even to share it.
Fortunately, i can read this code perfectly :p

In fact I recreate the ability 'Awan' because while allow control of units to the player, i need to differentiate the orders given by trigger and those given by the player.
But I couldn't make the difference between the "move" by the skill and an order "move" given by the player