HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

event responses and the DestroyTrigger bug

08-25-2006, 02:31 PM#1
Vexorian
someone on bnet pointed out pretty well that the stuff called by the trigger that is destroyed might share the stack of the first trigger.

Why would a trigger pass an stack to another one? sure, because of event responses. That's the way GetTriggerUnit() survives waits, ExecuteFunc and TriggerExecute.

It at least seems to explain the thread related DestroyTrigger bug, remember this?:

Collapse JASS:
// Original code by masda70, modefied by Vexorian and by Toadcop

// Multiple peasants will have the same id


function NothingAction takes nothing returns nothing
endfunction

function CreateAction takes nothing returns nothing
    call CreateTrigger() //Create any object
endfunction

function PeasantStuff takes nothing returns nothing
local integer i=0
local unit array u
local unit utmp=null
local unit u2=null
    set i=1
    set utmp=null
    loop
        exitwhen i > 14
        set u[i]=CreateUnit(GetLocalPlayer(),'hpea',0,0,0)
        if i==1 then
             set u2=u[i]
             set udg_mmm=u2

        endif
        //call SelectUnitSingle(u[i])
        if u[i]==utmp then
            call BJDebugMsg("FATALatindex:"+I2S(i))
        endif
        set utmp=u[i]
        set i=i+1
    endloop

    call SetUnitState(i2u(h2i(u2)),UNIT_STATE_LIFE,100)

endfunction

function RunStuff takes nothing returns nothing
    call TimerStart(CreateTimer(),25.,false,function PeasantStuff)
    call TriggerSleepAction(0.00) //This wait action is needed for the bug to happen
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00)
    call TriggerSleepAction(0.00) // can have any count of Sleeps. will increase the FATAL index count =)
    call BJDebugMsg("|cfffedaacwait END !|r")
endfunction


function Trig_Test_Actions takes nothing returns nothing
local integer i=0
    call BJDebugMsg("|cfffedaacBEGIN...|r")
    call TriggerExecute(udg_t[5])
    call DestroyTrigger(GetTriggeringTrigger())  //Without this call, the bug won't happen
endfunction

//===========================================================================
function InitTrig_Test takes nothing returns nothing
    set gg_trg_Test = CreateTrigger(  )
    set udg_t[0]= CreateTrigger(  )
    set udg_t[1]= CreateTrigger(  )
    call TriggerAddAction( udg_t[0], function NothingAction )
    call TriggerAddAction( udg_t[1], function CreateAction )
    set udg_t[5]=CreateTrigger()
    call TriggerAddAction(udg_t[5],function RunStuff)
    call TriggerRegisterPlayerChatEvent( gg_trg_Test, Player(0), "test", true )
    call TriggerAddAction( gg_trg_Test, function Trig_Test_Actions )
    call BJDebugMsg("|cfffedaactype |cff00ff00test|cfffedaac in chat to start !|r")
    call BJDebugMsg("|cfffedaacafter the peasants are spawned select them several times... =)")
endfunction

If you replace the code to make the trigger execute by a periodic event instead of chat event (so there are no event responses), the bug will NOT happen.

at least the engine seems smart enough not to use an stack when it is not needed.

Now I would like to have a sample of the other DestroyTrigger bugs that don't have waits.
08-25-2006, 02:38 PM#2
Rising_Dusk
My first post in this topic.

I didnt use a single wait in that code, but it would bug out constantly, until I removed "call DestroyTrigger(trg)"s or the "set trg = null"s.
The problem was eventually resolved, but if you just want a testmap with the bug, use that one.
08-25-2006, 02:42 PM#3
Vexorian
Oh great thanks I forgot about that little bugged map. It is gonna be useful against this redscull guy
08-25-2006, 02:51 PM#4
Toadcop
Vexorian - so the events are bugged ?! but with out TriggerSleepAction() it will not happen (i mean the bugs) !
08-25-2006, 02:59 PM#5
Vexorian
Both are the reasons, the attempt to destroy a trigger while another trigger is using its stack.