[Snippet] RegisterAnyUnitEvent

Level 15
Joined
Feb 15, 2006
Messages
852
A library to reduce the time writing the same shit. I took some code ideas from a similar resource. approved here. This one supports all the possibilities in calling the trigger. If user defines the condition and action functions this function will return the respective trigger, so it can be controlled by other instance (just in case).
If the user only sets a condition or action, then it will return null because this trigger handles a lot of conditions and actions and it shouldn't be accessible by the user.

Usage:

  • For functions without triggersleepaction or waits, it's recommended to use call RegisterAnyUnitEvent(<Event>, code Function, null)
  • For functions with triggersleepaction or waits, it's recommended to use call RegisterAnyUnitEvent(<Event>, null, code Function)
  • For triggers which condition and action codes must be separated (it could happen) you set this:
    JASS:
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == 'A000'
    endfunction
    
    private function Actions takes nothing returns nothing
        // your stuff...
    endfunction
    
    private function init takes nothing returns nothing
        local trigger t = RegisterAnyUnitEvent(EVENT_PLAYER_UNIT_SPELL_CAST, function Conditions, function Actions)
    endfunction

Actual code
JASS:
//************************************************************************
//                    RegisterAnyUnitEvent by moyack
//************************************************************************
// Code improved with the idea developed by Magtheridon96 , Bribe, azlier
//************************************************************************
/*
A library to reduce the time writing the same shit. I took some code ideas from a similar 
resource approved here. This one supports all the possibilities in calling the trigger.
If user defines the condition and action functions this function will return the respective 
trigger, so it can be controlled by other instance (just in case).

If the user only sets a condition or action, then it will return null because this
trigger handles a lot of conditions and actions and it shouldn't be accessible by the user.

 * For functions without triggersleepaction or waits, it's recommended to use:
    call RegisterAnyUnitEvent(<Event>, code Function, null)

 * For functions with triggersleepaction or waits, it's recommended to use:
    call RegisterAnyUnitEvent(<Event>, null, code Function)
*/

library RegisterAnyUnitEvent

globals
    private trigger array ts
endglobals

function RegisterAnyUnitEvent takes playerunitevent e, code cond, code act returns nothing
    local integer i = GetHandleId(e)
    local trigger t
    if act != null then
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, e)
        if cond != null then
            call TriggerAddCondition(t, Filter(cond))
        endif
        call TriggerAddAction(t, act)
        set t = null
    else
        if ts[i] == null then
            set ts[i] = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(ts[i], e)
        endif
        call TriggerAddCondition(ts[i], Filter(cond))
    endif
endfunction

endlibrary

Examples:
Condition only
JASS:
scope test initializer init

private function Conditions takes nothing returns boolean
    // your code... please DO NOT use waits or triggersleeaction...
    return false // please always set it to false
endfunction

private function init takes nothing returns nothing
    // that's the recommended way, it's faster and nice :)
    call RegisterAnyUnitEvent(EVENT_PLAYER_UNIT_SPELL_CAST, function Conditions, null)
endfunction

endscope

Action Code Only
JASS:
scope test initializer init

private function Actions takes nothing returns nothing
    // your stuff...
endfunction

private function init takes nothing returns nothing
    // It's valid but not as faster as using conditions. Use it when you have in the code
    // Polledwait(), triggersleepaction() or wait()
    call RegisterAnyUnitEvent(EVENT_PLAYER_UNIT_SPELL_CAST, null, function Actions)
endfunction

endscope

Condition and action separated
JASS:
scope test initializer init

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

private function Actions takes nothing returns nothing
    // your stuff...
endfunction

private function init takes nothing returns nothing
    call RegisterAnyUnitEvent(EVENT_PLAYER_UNIT_SPELL_CAST, function Conditions, function Actions)
endfunction

endscope
 
Last edited:
JASS:
function RegisterAnyUnitEvent takes playerunitevent e, code c, code a returns trigger
    local integer i = 0
    local integer id = GetHandleId(e)
    
    // Yes, you can have globals within a function.
    globals
        private trigger t
    endglobals
    
    if c != null then
        if a != null then
            set t = CreateTrigger()
            loop
                call TriggerRegisterPlayerUnitEvent(t, Player(i), e, null)
                exitwhen i == 15
                set i = i + 1
            endloop
            call TriggerAddCondition(t, Filter(c))
            call TriggerAddAction(t, a)
            return t
        else
            if tc[id] == null then
                set tc[id] = CreateTrigger()
                loop
                    call TriggerRegisterPlayerUnitEvent(tc[id], Player(i), e, null)
                    exitwhen i == 15
                    set i = i + 1
                endloop
            endif
            call TriggerAddCondition(tc[id], Condition(c))
            return null
        endif
    elseif a != null then
        if ta[id] == null then
            set ta[id] = CreateTrigger()
            loop
                call TriggerRegisterPlayerUnitEvent(ta[id], Player(i), e, null)
                exitwhen i == 15
                set i = i + 1
            endloop
        endif
        call TriggerAddAction(ta[id], a)
        return null
    endif
    
    return null
endfunction

This is a bit more optimal and it doesn't leak the trigger that never gets nulled because the function doesn't reach "set t = null" after it returns it.

Also, I'm not using the BJ here because the purpose of using it is to reduce map-code size, but anyone using this resource wouldn't be using the BJ, so the whole purpose of using it is defeated, and thus the native usage would be better.

edit

I think this is pretty useful if you want to use TriggerSleepAction in your code :)
 

Bribe

Code Moderator
Level 42
Joined
Sep 26, 2009
Messages
8,794
@Mag, but there's really still no point to inline it. It's more readable to keep it as-is. With indentation, with the PHP-parsing fail fix and with the not-nulled handle fix, the resource should look like this:

JASS:
/*
//------------------------------------------------------------------------//
//                    RegisterAnyUnitEvent by moyack                      //
//------------------------------------------------------------------------//
// Code improved with the idea developed by Magtheridon96 , Bribe, azlier //
//------------------------------------------------------------------------//

A library to reduce the time writing the same shit. I took some code ideas from a similar 
resource approved here. This one supports all the possibilities in calling the trigger.
If user defines the condition and action functions this function will return the respective 
trigger, so it can be controlled by other instance (just in case).

If the user only sets a condition or action, then it will return null because this
trigger handles a lot of conditions and actions and it shouldn't be accessible by the user.

 * For functions without triggersleepaction or waits, it's recommended to use:
    call RegisterAnyUnitEvent(<Event>, code Function, null)

 * For functions with triggersleepaction or waits, it's recommended to use:
    call RegisterAnyUnitEvent(<Event>, null, code Function)
*/

library RegisterAnyUnitEvent

globals
    private trigger t
    private trigger array tc
    private trigger array ta
endglobals

function RegisterAnyUnitEvent takes playerunitevent e, code cond, code act returns trigger
    local integer i = GetHandleId(e)
    if cond != null and act != null then
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, e)
        call TriggerAddCondition(t, Filter(cond))
        call TriggerAddAction(t, act)
        return t
    elseif act == null then
        if tc[i] == null then
            set tc[i] = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(tc[i], e)
        endif
        call TriggerAddCondition(tc[i], Filter(cond))
    else
        if ta[i] == null then
            set ta[i] = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(ta[i], e)
        endif
        call TriggerAddAction(ta[i], act)
    endif
    return null
endfunction

endlibrary
 
Last edited:
Level 6
Joined
Jun 20, 2011
Messages
249
return false // please always set it to false
If anything it should be set to true, setting it to false would cause the conditions-to-evaluate queue to clear inmediately (in case that more than one function is linked to the same event, which is highly probable)
But you can also not return anything, code added through arguments as filters to conditions can and should return nothing.
I really can't see how is this any better than mag's RegisterPlayerUnitEvent
 

Bribe

Code Moderator
Level 42
Joined
Sep 26, 2009
Messages
8,794
It is better because 1) it allows trigger sleep action (great for in-game scenarios believe it or not) and 2) because if you really want classic triggers (condition + action) Mag's system does not support it.

However, Moyack should find a way to remove a trigger's action, because I trigger actions don't get destroyed when the trigger is destroyed.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
This is dangerous.. if all of the conditions return false, the actions will never run >.>.


The only way to make this safe is to evaluate the triggers inside of another trigger, which would add some extra overhead.


All of this for a native that is never used by pros anyways (TriggerSleepAction) >.>... I think the costs outweigh the benefits.
 
Some people like using TriggerSleepAction while map-making.

Also:

162098-albums5026-picture55601.jpg
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
There are still cases that you need a TSA, and have to use a trigger action.
Sure they are not legion, but here is a sample :

Tell me how to pause the game during X seconds and then resume it.
(And no PauseGame doesn't work in a trigger condition, and the first who say that you still can avoid the trigger action with an ExecuteFunc, plz go to hell)

I mean you have to know that TSA isn't paused when the game is paused like timers are.
Sure, most of time it's a feature rather than a con.

Also seriously sometimes a TSA is just fine, you have to admit that split the code every time you need to apply a wait is booorring.
 

Bribe

Code Moderator
Level 42
Joined
Sep 26, 2009
Messages
8,794
that's even slower than evaluation + execution inside of a trigger ;\.

It's pretty much the only way to make it run properly - actually though when I think about it triggeractions will only fire off once the triggersleepactions of the triggeractions before have completed, so this actually is not going to work as intended :/

Try to run this:

JASS:
function Poop takes nothing returns nothing
    call TriggerSleepAction(1)
    call BJDebugMsg("Hello")
endfunction

function Stick takes nothing returns nothing
    call BJDebugMsg("World")
endfunction

//===========================================================================
function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
    local trigger trig = CreateTrigger()
    call TriggerAddAction(trig, function Poop)
    call TriggerAddAction(trig, function Stick)
    call TriggerExecute(trig)
endfunction

It prints "Hello\nWorld" all at once instead of "World" then a second later "Hello".

Edit:

If a system like this is gonna stick around, it would be too complicated to try to detach the actions of a trigger registered on this scheme, so I think it'd be equally useless to return the trigger in cases where trigger actions are used, and the overall package turns out like this:

JASS:
/*
//------------------------------------------------------------------------//
//                    RegisterAnyUnitEvent by moyack                      //
//------------------------------------------------------------------------//
// Code improved with the idea developed by Magtheridon96 , Bribe, azlier //
//------------------------------------------------------------------------//

A library to reduce the time writing the same shit. I took some code ideas from a similar 
resource approved here. This one supports all the possibilities in calling the trigger.
If user defines the condition and action functions this function will return the respective 
trigger, so it can be controlled by other instance (just in case).

If the user only sets a condition or action, then it will return null because this
trigger handles a lot of conditions and actions and it shouldn't be accessible by the user.

 * For functions without triggersleepaction or waits, it's recommended to use:
    call RegisterAnyUnitEvent(<Event>, code Function, null)

 * For functions with triggersleepaction or waits, it's recommended to use:
    call RegisterAnyUnitEvent(<Event>, null, code Function)
*/

library RegisterAnyUnitEvent

globals
    private trigger array ts
endglobals

function RegisterAnyUnitEvent takes playerunitevent e, code cond, code act returns nothing
    local integer i = GetHandleId(e)
    local trigger t
    if act != null then
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, e)
        if cond != null then
            call TriggerAddCondition(t, Filter(cond))
        endif
        call TriggerAddAction(t, act)
        set t = null
    else
        if ts[i] == null then
            set ts[i] = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(ts[i], e)
        endif
        call TriggerAddCondition(ts[i], Filter(cond))
    endif
endfunction

endlibrary
 
Level 15
Joined
Feb 15, 2006
Messages
852
Well, it took me a while to read all your comments :)

I did this snippet in order to reduce code writing. Allowing actions was with the intention of allowing all possibilities a map triggering could have.

In the other hand, TSA actions is helpful if you know what you're doing, and I decided by my experience that a code can't be limited just because I believe something is a bad practice, unless it makes the code totally hard to develop.

So the code should look like this:

JASS:
library RegisterAnyUnitEvent

globals
    private trigger array tc
    private trigger array ta
endglobals

function RegisterAnyUnitEvent takes playerunitevent E, code Cond, code Act returns nothing
    local trigger t
    local integer i = GetHandleId(E)
    if Cond != null and Act != null then
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, E)
        call TriggerAddCondition(t, Condition(Cond))
        call TriggerAddAction(t, Act)
        set t = null
        return
    endif
    set t = null
    if Cond != null and Act == null then
        if tc[i] == null then
            set tc[i] = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(tc[i], E)
        endif
        call TriggerAddCondition(tc[i], Condition(Cond))
        return
    endif
    if Cond == null and Act != null then
        if ta[i] == null then
            set ta[i] = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(ta[i], E)
        endif
        call TriggerAddAction(ta[i], Act)
    endif
endfunction

endlibrary

JASS:
function RegisterAnyUnitEvent takes playerunitevent e, code c, code a returns trigger
    local integer i = 0
    local integer id = GetHandleId(e)
    
    // Yes, you can have globals within a function.
    globals
        private trigger t
    endglobals
    
    if c != null then
        if a != null then
            set t = CreateTrigger()
            loop
                call TriggerRegisterPlayerUnitEvent(t, Player(i), e, null)
                exitwhen i == 15
                set i = i + 1
            endloop
            call TriggerAddCondition(t, Filter(c))
            call TriggerAddAction(t, a)
            return t
        else
            if tc[id] == null then
                set tc[id] = CreateTrigger()
                loop
                    call TriggerRegisterPlayerUnitEvent(tc[id], Player(i), e, null)
                    exitwhen i == 15
                    set i = i + 1
                endloop
            endif
            call TriggerAddCondition(tc[id], Condition(c))
            return null
        endif
    elseif a != null then
        if ta[id] == null then
            set ta[id] = CreateTrigger()
            loop
                call TriggerRegisterPlayerUnitEvent(ta[id], Player(i), e, null)
                exitwhen i == 15
                set i = i + 1
            endloop
        endif
        call TriggerAddAction(ta[id], a)
        return null
    endif
    
    return null
endfunction

This is a bit more optimal and it doesn't leak the trigger that never gets nulled because the function doesn't reach "set t = null" after it returns it.

Also, I'm not using the BJ here because the purpose of using it is to reduce map-code size, but anyone using this resource wouldn't be using the BJ, so the whole purpose of using it is defeated, and thus the native usage would be better.

edit

I think this is pretty useful if you want to use TriggerSleepAction in your code :)
Hey Mag, I was thinking in "inline" de TriggerRegisterAnyUnitEvent but I thought: well, it runs at map init, so it doesn't have any influence in the map performance. unless a nooster create lots of triggers after map init :p



If a system like this is gonna stick around, it would be too complicated to try to detach the actions of a trigger registered on this scheme, so I think it'd be equally useless to return the trigger in cases where trigger actions are used, and the overall package turns out like this:

JASS:
/*
//------------------------------------------------------------------------//
//                    RegisterAnyUnitEvent by moyack                      //
//------------------------------------------------------------------------//
// Code improved with the idea developed by Magtheridon96 , Bribe, azlier //
//------------------------------------------------------------------------//

A library to reduce the time writing the same shit. I took some code ideas from a similar 
resource approved here. This one supports all the possibilities in calling the trigger.
If user defines the condition and action functions this function will return the respective 
trigger, so it can be controlled by other instance (just in case).

If the user only sets a condition or action, then it will return null because this
trigger handles a lot of conditions and actions and it shouldn't be accessible by the user.

 * For functions without triggersleepaction or waits, it's recommended to use:
    call RegisterAnyUnitEvent(<Event>, code Function, null)

 * For functions with triggersleepaction or waits, it's recommended to use:
    call RegisterAnyUnitEvent(<Event>, null, code Function)
*/

library RegisterAnyUnitEvent

globals
    private trigger array ts
endglobals

function RegisterAnyUnitEvent takes playerunitevent e, code cond, code act returns nothing
    local integer i = GetHandleId(e)
    local trigger t
    if act != null then
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, e)
        if cond != null then
            call TriggerAddCondition(t, Filter(cond))
        endif
        call TriggerAddAction(t, act)
        set t = null
    else
        if ts[i] == null then
            set ts[i] = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(ts[i], e)
        endif
        call TriggerAddCondition(ts[i], Filter(cond))
    endif
endfunction

endlibrary

Hmmm looks tewmpting... but... mixing in one trigger array conditions & actions will make the actions don't run... as far as I know.... right?
 

Bribe

Code Moderator
Level 42
Joined
Sep 26, 2009
Messages
8,794
@Moyack, as you might notice I removed the array of triggers for the actions, because that won't work properly. I just split it into two: an array of triggers for conditions and a normal trigger for actions/conditions.

The reason why I removed it is because if you have two actions on a trigger, the second actions won't run until the first one's TriggerSleepActions have finished, as you can see from this test:

JASS:
function Poop takes nothing returns nothing
    call TriggerSleepAction(1)
    call BJDebugMsg("Hello")
endfunction

function Stick takes nothing returns nothing
    call BJDebugMsg("World")
endfunction

//===========================================================================
function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
    local trigger trig = CreateTrigger()
    call TriggerAddAction(trig, function Poop)
    call TriggerAddAction(trig, function Stick)
    call TriggerExecute(trig)
endfunction
 
Level 15
Joined
Feb 15, 2006
Messages
852
@Moyack, as you might notice I removed the array of triggers for the actions, because that won't work properly. I just split it into two: an array of triggers for conditions and a normal trigger for actions/conditions.

The reason why I removed it is because if you have two actions on a trigger, the second actions won't run until the first one's TriggerSleepActions have finished, as you can see from this test:

JASS:
function Poop takes nothing returns nothing
    call TriggerSleepAction(1)
    call BJDebugMsg("Hello")
endfunction

function Stick takes nothing returns nothing
    call BJDebugMsg("World")
endfunction

//===========================================================================
function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
    local trigger trig = CreateTrigger()
    call TriggerAddAction(trig, function Poop)
    call TriggerAddAction(trig, function Stick)
    call TriggerExecute(trig)
endfunction
OHHHHH.... I get it :)

Yes you're right.... that can cause serious problems. All right I'll modify it with the changes proposed.
 
Level 7
Joined
Apr 30, 2011
Messages
359
your header bugs ~.~

JASS:
/*
//************************************************************************//
//                    RegisterAnyUnitEvent by moyack                      //
//************************************************************************//
// Code improved with the idea developed by Magtheridon96 , Bribe, azlier //
//************************************************************************//

A library to reduce the time writing the same shit. I took some code ideas from a similar 
resource approved here. This one supports all the possibilities in calling the trigger.
If user defines the condition and action functions this function will return the respective 
trigger, so it can be controlled by other instance (just in case).

If the user only sets a condition or action, then it will return null because this
trigger handles a lot of conditions and actions and it shouldn't be accessible by the user.

 * For functions without triggersleepaction or waits, it's recommended to use:
    call RegisterAnyUnitEvent(<Event>, code Function, null)

 * For functions with triggersleepaction or waits, it's recommended to use:
    call RegisterAnyUnitEvent(<Event>, null, code Function)
*/

//! should be:

/*
//************************************************************************
//                    RegisterAnyUnitEvent by moyack
//************************************************************************
// Code improved with the idea developed by Magtheridon96 , Bribe, azlier
//************************************************************************

A library to reduce the time writing the same shit. I took some code ideas from a similar 
resource approved here. This one supports all the possibilities in calling the trigger.
If user defines the condition and action functions this function will return the respective 
trigger, so it can be controlled by other instance (just in case).

If the user only sets a condition or action, then it will return null because this
trigger handles a lot of conditions and actions and it shouldn't be accessible by the user.

 * For functions without triggersleepaction or waits, it's recommended to use:
    call RegisterAnyUnitEvent(<Event>, code Function, null)

 * For functions with triggersleepaction or waits, it's recommended to use:
    call RegisterAnyUnitEvent(<Event>, null, code Function)
*/
 

BBQ

BBQ

Level 4
Joined
Jun 7, 2011
Messages
97
You should attach the trigger action to the trigger (with a hashtable), hook the DestroyTrigger native and remove the trigger action before the trigger is destroyed.

Or better yet; make some tests first and see if trigger actions behave the same as they did aeons ago.

And before somebody brings the speed of hooks as an issue, how often do you see DestroyTrigger? Furthermore, cohadar may improve them in the future.
 

Bribe

Code Moderator
Level 42
Joined
Sep 26, 2009
Messages
8,794
I completely disagree, BBQ. If someone wants dynamism like that they shouldn't be using a function which can only return a trigger or a triggeraction. Someone like that should be inlining the traditional script (which is pretty the only advantage of this resource over RegisterPlayerUnitEvent - that the same stuff doesn't need to be typed out).

Also, trigger actions leak when the trigger they're attached to is destroyed. I tested it 2 days ago to double-check, watching the handle stack go up and up. If you use TriggerRemoveAction, the handle stack doesn't grow, but without it the trigger actions are leaking.

Destroying a trigger with trigger conditions does not leak, though. The handles are getting recycled appropriately, then.
 

BBQ

BBQ

Level 4
Joined
Jun 7, 2011
Messages
97
Why would somebody have to resort on both this and the "traditional" way, depending on whether the trigger will be destroyed, when this sole snippet can be configured to suffice for both?

Also, I was in a hurry and forgot to mention that the RegisterPlayerUnitEvent function should either return the trigger, or something like a TriggerRegisterAnyUnitEvent should be added (else there can be no dynamism, as you call it).
 

Bribe

Code Moderator
Level 42
Joined
Sep 26, 2009
Messages
8,794
Because having someone do it the "traditional way" avoids needing to hook DestroyTrigger or to save the trigger action into a hashtable, if you notice a big part of the pitch of this resource is "to avoid writing the same s*it over and over" and obviously if you need to remember the trigger (instead of "local trigger t") or if you need to remove any actions from that trigger then you're doing something outside the norm that is not "the same s*it".
 

BBQ

BBQ

Level 4
Joined
Jun 7, 2011
Messages
97
If you want to "avoid writing the same shit all over again", why don't you start using Zinc (and nag cohadar to work on it instead of vJass)? The very nature of JASS2 (and hence vJass) involves stupid and unnecessary verbosity.
 

Bribe

Code Moderator
Level 42
Joined
Sep 26, 2009
Messages
8,794
The problem is Zinc doesn't mingle with vJass or JASS code at all. You can't even insert Zinc snippets into vJass code. Zinc failed with the "->" operator and for having LESS features than vJass (some of the best stuff doesn't even compile, like "readonly", custom natives, "keyword").

On topic, I'm going to approve this resource. I find it a good alternative to RegisterPlayerUnitEvent and a map maker can taylor their map to use both or to use one or the other, but what I like is that this version allows you to use TriggerSleepAction which can save time when building a map.
 

BBQ

BBQ

Level 4
Joined
Jun 7, 2011
Messages
97
There are no hooks in Zinc, no readonly and no custom natives (keyword work just well, although they are not really needed, as stuff in Zinc is library-private by default, whereas in vJass you need to use keyword to make something library-private). Everything else is better than vJass, at least in my eyes.

But let's not get off-topic, if you think that this is a nice snippet (you do, and so do many others), then I have nothing against it. Was just throwing some food for thought. "Dynamic" triggers are just as useful as TriggerSleepAction is.
 

AGD

AGD

Level 15
Joined
Mar 29, 2016
Messages
688
Sorry for reviving an old thread but why this

JASS:
library RegisterAnyUnitEvent

globals
   private trigger array ts
endglobals

function RegisterAnyUnitEvent takes playerunitevent e, code cond, code act returns nothing
   local integer i = GetHandleId(e)
   local trigger t
   if act != null then
       set t = CreateTrigger()
       call TriggerRegisterAnyUnitEventBJ(t, e)
       if cond != null then
           call TriggerAddCondition(t, Filter(cond))
       endif
       call TriggerAddAction(t, act)
       set t = null
   else
       if ts[i] == null then
           set ts[i] = CreateTrigger()
           call TriggerRegisterAnyUnitEventBJ(ts[i], e)
       endif
       call TriggerAddCondition(ts[i], Filter(cond))
   endif
endfunction

endlibrary

over something like this

JASS:
library RegisterAnyUnitEvent

    globals
        private trigger array ta
        private trigger array tb
    endglobals

    function RegisterAnyUnitEvent takes playerunitevent e, code cond, code act returns nothing
        local integer i = GetHandleId(e)
        local trigger t
        if act != null and cond != null then
            set t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, e)
            call TriggerAddCondition(t, Filter(cond))
            call TriggerAddAction(t, act)
            set t = null
        elseif cond != null then
            if ta[i] == null then
                set ta[i] = CreateTrigger()
                call TriggerRegisterAnyUnitEventBJ(ta[i], e)
            endif
            call TriggerAddCondition(ta[i], Filter(cond))
        elseif act != null then
            if tb[i] == null then
                set tb[i] = CreateTrigger()
                call TriggerRegisterAnyUnitEventBJ(tb[i], e)
            endif
            call TriggerAddAction(tb[i], act)
        endif
    endfunction

endlibrary

when the later allows you to add both condition and action at the same time plus it also avoids redundant trigger creation if action != null (the first one does not).
 
Last edited:

Submission:
[Snippet] RegisterAnyUnitEvent

Date:
18 October 16

Status:
Graveyard
Note:

The resource was previously approved and therefore should work fine.
If you use this script already in your codes, it's okay to keep it there.
But now we have this approved [Snippet] RegisterEvent pack, and so it's time to graveyard these specializations.
 
Top