Trigger Evaluation Behaviour Changed in Recent Patches

Status
Not open for further replies.

AGD

AGD

Level 16
Joined
Mar 29, 2016
Messages
688
I just wanna share this. It was known in the past that removing the currently evaluated triggercondition using TriggerRemoveCondition() / TriggerClearConditions() / DestroyTrigger() will prevent the next triggerconditions in the trigger from being evaluated.
This means
JASS:
    globals
        trigger array trig
        triggercondition array tc
    endglobals

    function A takes nothing returns nothing
        call BJDebugMsg("A")
    endfunction
    function B takes nothing returns nothing
        call BJDebugMsg("B")
        call TriggerRemoveCondition(trig[0], tc[2])
    endfunction
    function C takes nothing returns nothing
        call BJDebugMsg("C")
    endfunction
    function D takes nothing returns nothing
        call BJDebugMsg("D")
    endfunction

    function OnInit takes nothing returns nothing
        set trig[0] = CreateTrigger()
        set tc[1] = TriggerAddCondition(trig[0], Filter(function A))
        set tc[2] = TriggerAddCondition(trig[0], Filter(function B))
        set tc[3] = TriggerAddCondition(trig[0], Filter(function C))
        set tc[4] = TriggerAddCondition(trig[0], Filter(function D))

        call TriggerEvaluate(trig[0])
        /*Displays:
        A
        B
        */
    endfunction
This is also true for patch 1.27.x

But in patches past 1.30.4 (I actually only tested patches 1.30.4 and 1.31. Haven't also tested patches in between 1.27 and 1.30.4 so don't exactly know when the change happened), you can safety remove the currently evaluated triggercondition without stopping the next triggerconditions in the list. The same code above would display
JASS:
A
B
C
D


It seems that in older patches, calling TriggerRemoveCondition() removes the links (A post by Nestharus says that TCs are structures as a linked-list, or that's how they behave atleast) of that TC immediately. While in the recent patches, calling TriggerRemoveCondition() inside an evaluated trigger removes the links of that TC after all TCs are the current TC is done being evaluated.

Test Code
JASS:
    globals
        trigger array trig
        triggercondition array tc
    endglobals

    function A takes nothing returns nothing
        call BJDebugMsg("A")
    endfunction
    function B takes nothing returns nothing
        call BJDebugMsg("B")
        call TriggerRemoveCondition(trig[0], tc[3]) // We remove the next TC
    endfunction
    function C takes nothing returns nothing
        call BJDebugMsg("C")
    endfunction
    function D takes nothing returns nothing
        call BJDebugMsg("D")
    endfunction

    function OnInit takes nothing returns nothing
        set trig[0] = CreateTrigger()
        set tc[1] = TriggerAddCondition(trig[0], Filter(function A))
        set tc[2] = TriggerAddCondition(trig[0], Filter(function B))
        set tc[3] = TriggerAddCondition(trig[0], Filter(function C))
        set tc[4] = TriggerAddCondition(trig[0], Filter(function D))

        call TriggerEvaluate(trig[0])
    endfunction
In older patches, it displays
JASS:
A
B
D
while in the recent ones
JASS:
A
B
 
Last edited:

AGD

AGD

Level 16
Joined
Mar 29, 2016
Messages
688
Removing the next evaluated condition caused a Warcraft crash. Tested several times.
Thanks also for this test btw, IcemanBo, as I don't have Reforged myself. Does this mean calling TriggerClearConditions(GetTriggeringTrigger()) crashes in reforged? It seems my system that has something like this causes problem for someone using it in reforged.
I'm wondering if there are other ways for example to stop the execution of triggerconditions in a trigger midway in reforged. For example a trigger has 5 triggerconditions and I only want the trigger to execute until the 3rd triggercondition.
 
Yes, correct. Calling TriggerClearConditions(GetTriggeringTrigger()) does crash warcraft, when called from a middle-running condition. ( patch 1.32.5 meanwhile )

It's definitely a bug from blizzard. Honestly, idk a good work around or hack for this. Maybe using single triggers... . Or have you tried looking on something like this from Nestharus Trigger v1.1.0.2 (it's huge, maybe there's a smaller alternative... but haven't found one atm)
 
Nes explains a TriggerCondition in his code (jass native type is "triggercondition") is allowed to be removed at any point. Or maybe I mix something up?

In cases, I could test out a code for you in reforged (discord IcemanBo#5874). I hope it gets fixed, it's really game-breaking actually. Good point, I saw your announce in the patch thread. :peasant-thumbs-up:
 

AGD

AGD

Level 16
Joined
Mar 29, 2016
Messages
688
Nes explains a TriggerCondition in his code (jass native type is "triggercondition") is allowed to be removed at any point. Or maybe I mix something up?
Yeah, but Nes' Triggers can only contain 1 TriggerCondition, which contains multiple boolexprs. So it doesn't allow stopping on a certain registered code. It runs all codes, which is actually one of the goals of Trigger - to allow removing the current code without breaking the traversal of the remaining codes. The removal only affects the next time the Trigger runs.

I'll just pm you here instead if I'll ask some favor =).
 

AGD

AGD

Level 16
Joined
Mar 29, 2016
Messages
688
In my particular case, there is only one triggercondition (statically determined) wherein an evaluation break can happen, so two triggers as an alternative should suffice. Actually the purpose of the break is just to simulate something like
JASS:
call TriggerEvaluate(genericTrigger)
if not this.blockEvent then
    call TriggerEvaluate(this.specificTrigger)
endif
As you can see, separating into two triggers is the reasonable choice here but because I insisted on having only 1 trigger evaluation that's why I forced myself into this complication :D.
 
AGD uses it for a system, where users can register code to run on certain events. Only one trigger is used, which is never destroyed. Only code or boolexpr gets registered/unregistered, that's why TriggerRemoveCondition is used.

Btw, I tested with TriggerRemoveAction, and it doesn't crash. But the removed action would still run, if it's removed from a prior trigger action.
 
Level 12
Joined
Jan 30, 2020
Messages
875
Oh ok It makes sense then.

Well I moved all my actions in my conditions a while back now so I never had any issue with destroying triggers, even when I was still using Jass ^^
 
Status
Not open for further replies.
Top