Snippet RegisterPlayerUnitEvent

Magthridon96

Member
Reaction score
2
I submitted this a while ago on The Hive and thought it
would be appropriate to post it here as well.

What it does:
- Replaces Blizzard's "CreateTrigger - RegisterEvent - AddCondition - AddAction" with a simple "RegisterPlayerUnitEvent"
- Optimizes scripts (You know what slows down your map? Hundreds upon hundreds of triggers firing.)
- This also reduces the amount of RAM used.

Special Thanks to Bribe, azlier and BBQ :)

JASS:
/**************************************************************
*
*   RegisterPlayerUnitEvent
*   v4.2.0.0
*   By Magtheridon96
*
*   I would like to give a special thanks to Bribe, azlier
*   and BBQ for improving this library. For modularity, it only 
*   supports player unit events.
*
*   Functions passed to RegisterPlayerUnitEvent must
*   return false. They can return nothing as well.
*
*   Disclaimer:
*   -----------
*
*       - Don't use TriggerSleepAction inside registered code.
*
*      API:
*      ----
*
*       function RegisterPlayerUnitEvent
*           takes
*               playerunitevent whichEvent  :   The event you would like to register
*               code whichFunction          :   The code you would like to register
*           returns
*               nothing
*
*           - Registers code that will execute when an event fires.
*
**************************************************************/
library RegisterPlayerUnitEvent // Special Thanks to Bribe and azlier
    globals
        private trigger array t
    endglobals
    
    function RegisterPlayerUnitEvent takes playerunitevent p, code c returns nothing
        local integer i = GetHandleId(p)
        local integer k = 15
        if t<i> == null then
            set t<i> = CreateTrigger()
            loop
                call TriggerRegisterPlayerUnitEvent(t<i>, Player(k), p, null)
                exitwhen k == 0
                set k = k - 1
            endloop
        endif
        call TriggerAddCondition(t<i>, Filter(c))
    endfunction
endlibrary</i></i></i></i>


Feel free to comment..
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
Magthridon96:
1. - Optimizes scripts (You know what slows down your map? Hundreds upon hundreds of triggers firing.)

1. Well I can see how this reduces RAM but can you elaborate more on this (optimizes scripts) point. I mean scripts start executing/running after the triggers have fired so where is the script optimization? Do you mean that the optimization is that it (RegisterPlayerUnitEvent) reduces the lines of script required? Or the optimization is that less triggers have to fire?

Edit:

Is there anything that prevents the other event groups (unitevent, playerevent, gameevent) being wrapped in a similar function? Why just the playerunitevent =)?
 

luorax

Invasion in Duskwood
Reaction score
67
Well, imagine, you have 30 triggers with an "A hero learns a skill" event. When you learn one, each trigger fires and does it job, in a different thread, at the same time. This might cause lags depending on how many triggers you have.

If you use this snippet, those 30 events will be fired by the same trigger, after each other.
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
luorax:
1. This might cause lags depending on how many triggers you have.

2. If you use this snippet, those 30 events will be fired by the same trigger, after each other.

1. How many triggers with the same event does one needs to have to actually get lag from the firing of the triggers themselves not the action they perform 30, 300 or 3000?

2. Sure I agree less triggers, less events less RAM usage but does someone know if there is a limit to the amount of conditions/actions a trigger can have or does their "stack" increases as needed?
 

Bribe

vJass errors are legion
Reaction score
67
No one's ever reported a condition limit on triggers.

This also saves 17 handles per duplicate playerunitevent. Saves creation of trigger and 16 event handles.
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
Bribe:
1. No one's ever reported a condition limit on triggers.

1. Yeah guess their "stack" really does increase, tested with 350.
 

tooltiperror

Super Moderator
Reaction score
231
This is a lot less overhead than GTrigger, that is good. But it should still work with trigger(condition)s, as it does in GTrigger.

JASS:
if (TriggerEvaluate(t)) then
    call TriggerExecute(t)
endif
 

Nestharus

o-o
Reaction score
84
JASS:

if (TriggerEvaluate(t)) then
    call TriggerExecute(t)
endif


This is no good unless you split the triggers up... you are merging trigger conditions here, meaning that any of these trigger conditions could return any boolean. That means the trigger execute may or may not fire from different resources that are unrelated.

The if statement is completely useless, thus this shouldn't be done.

If the triggers were completely split up, that'd be a different story ; ).

edit
It seems that I misunderstood what you were saying. I believe that mag wrote this with combining all triggers into one trigger and running off of conditions in mind. He didn't write this to support the normal TriggerEvaluate TriggerExecute stuff = ).

Yes, I can understand why you are saying that the thing should work just like regular triggers, but mag didn't write it for regular triggers ^^. It's more for the onInit stuff in libraries = ). It's like a RegisterAnyPlayerEvent for a function condition =).


I personally find it easy to use myself and like how it combines the triggers ^)^. I was never a fan of GTrigger, heh, that did way more than I needed or wanted =).
 

Bribe

vJass errors are legion
Reaction score
67
I don't understand why anyone wants both triggers and trigger actions. Conditions can "return nothing" now as Blizzard fixed the Mac bug, and anything else that makes trigger actions valuable is either deprecated or easy to implement using an ExecuteFunc statement.
 

tooltiperror

Super Moderator
Reaction score
231
Because WC3 events are great, and they are a lot better for extending code and keeping it mangeable. Event systems work with triggers, I don't see why you would want to limit your system to be less functional.
 

Magthridon96

Member
Reaction score
2
If you need conditions, just do this:

JASS:
function TriggerAction takes nothing returns nothing
    if Conditions() then
        // run
    endif
endfunction

private struct Inits extends array
    private static method onInit takes nothing returns nothing
        call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function TriggerActions)
    endmethod
endstruct


Pretty simple.

Is there anything that prevents the other event groups (unitevent, playerevent, gameevent) being wrapped in a similar function? Why just the playerunitevent =)?

playerunitevents are the ones that we want to optimize because of how often they're used =)

If you use this snippet, those 30 events will be fired by the same trigger, after each other.

The original trigger-registry method does the same thing. This has much less overhead though because it limits the number of triggers per event to 1 -> Less RAM and less trigger evaluations/executions.

Example:
30 triggers -> Each with one death event and 1 function
1 triggers -> 30 events and 30 functions

A unit dies
30 triggers -> 30 TriggerEvaluations
1 trigger -> 1 TriggerEvaluation
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
What is the point of multiple triggers, if they are all getting passed the same conditions? Wouldn't it be simpler to just put them all on one trigger, since there isn't any code that actually differentiates between the different triggers?

You need to include its limitations, and the things it requires to work. For example:
Code passed cannot use TriggerSleepAction or PolledWaits.
All code passed must return a boolean.
All code passed must return true.
etc.
 

Bribe

vJass errors are legion
Reaction score
67
Code passed can return false.
Code passed can return true.
Code passed can return nothing (newsflash: it is no longer a bug for Mac, and yes pJass lets it compile with RegisterPlayerUnitEvent)

Someone using trigger sleep actions is going to get trolled and flamed.
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Code passed can return false.
Code passed can return true.

I haven't worked much with using trigger actions as conditions. All conditions are evaluated, even if one returns false in the process? I assumed it would follow short-circuit evaluation.

Code passed can return nothing (newsflash: it is no longer a bug for Mac, and yes pJass lets it compile with RegisterPlayerUnitEvent)

What would the trigger condition default it to?

Someone using trigger sleep actions is going to get trolled and flamed.

It is valid JASS, and it DOES have its uses, believe it or not. This thinking is similar to the thinking of "All BJs are bad".

JASS:
library foo initializer init uses RegisterPlayerUnitEvent

    function condition takes nothing returns nothing
        local item it = GetManipulatedItem()
        local real x = GetItemX(it)
        local real y = GetItemY(it)
        call BJDebugMsg(&quot;Item is located at (&quot; + R2S(x) + &quot;, &quot; + R2S(y) + &quot;).&quot;) // Item is located at (0, 0).  (or wherever the last time the item was when it was picked up)
        call TriggerSleepAction(0)
        set x = GetItemX(it)
        set y = GetItemY(it)
        call BJDebugMsg(&quot;Item is located at (&quot; + R2S(x) + &quot;, &quot; + R2S(y) + &quot;).&quot;) // This line is never reached.  Uh oh.
    endfunction

    function action takes nothing returns nothing
        local item it = GetManipulatedItem()
        local real x = GetItemX(it)
        local real y = GetItemY(it)
        call BJDebugMsg(&quot;Item is located at (&quot; + R2S(x) + &quot;, &quot; + R2S(y) + &quot;).&quot;) // Item is located at (0, 0).  (or wherever the last time the item was when it was picked up)
        call TriggerSleepAction(0)
        set x = GetItemX(it)
        set y = GetItemY(it)
        call BJDebugMsg(&quot;Item is located at (&quot; + R2S(x) + &quot;, &quot; + R2S(y) + &quot;).&quot;) // Item is located at (12.6500, 999.3000). (the actual correct location)
    endfunction

    function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DROP_ITEM, function condition)
        call TriggerRegisterPlayerUnitEvent(t, Player(0), EVENT_PLAYER_UNIT_DROP_ITEM, null)
        // Repeat for other players...
        call TriggerAddAction(t, function action)
    endfunction
endlibrary
 

Bribe

vJass errors are legion
Reaction score
67
Only [ljass]Or[/ljass]/[ljass]And[/ljass] short circuit and I don't know why trigger conditions are different but they are you can have as many returning false or returning nothing as you want and the next one in the queue will fire regardless. And since there are no actions the condition return value doesn't even matter.

If I had to guess "return nothing" would default "false" but I have not tested it. I don't use it with actions anyway.

Yeah it is extremely rare and 99.999999% of the time needs to be replaced with a timer, but I can see the point in him adding a disclaimer saying "don't use TSA with this".

I know the uses of having a TSA, and I am not a raving moron stating "all bj's are bad" in fact I have met people so naive they won't even use bj_lastCreatedGroup or bj_mapInitialPlayableArea. The math BJ's are among my favorites to use, it is a shame they are highlighted red. BJDebugMsg is a pretty good one because I hate typing the ridiculously long DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "").
 

Magthridon96

Member
Reaction score
2
Going to fix documentation.

And yeah, it is a shame that the Math BJs are in red :O
I only avoid them because of the evil red color.
 

Magthridon96

Member
Reaction score
2
Updated.

Added some really cool functions:
EnablePlayerUnitEvent
DisablePlayerUnitEvent

These are really useful when you want to do some very 'sensitive' actions like adding items to a unit that get removed at the end of a function.

edit
Bad idea. Removed.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • tom_mai78101 tom_mai78101:
    As for Github, I often frequent there, boasting about my genetic algorithm for tools-assisted speedrunning and such. I'm also pretty active on Discord, with my tag @asperatology.
  • tom_mai78101 tom_mai78101:
    Yeah, the whole earthquake + air pollution combo made me completely forget about bringing updates. I'll be sure to keep on top of things after all things are less requiring my attentions.
    +2
  • The Helper The Helper:
    I am just glad that you are OK Tom! Thank you for the update!
  • Varine Varine:
    Glad to hear you're okay! I only knew about your Github cuz I tried to follow some of you when I was learning how to program, but didn't understand any of it so kind of quit paying attention to what anyone does on it
  • The Helper The Helper:
    Freaking storm outside is kicking!
  • Blackveiled Blackveiled:
    I wouldn't know, I'm in Joliet, Illinois right now working. I left Houston area about 2 weeks ago lol
  • Blackveiled Blackveiled:
    Not permanently of course, just a temporary job.
    +1
  • jonas jonas:
    Glad you're ok @tom_mai78101
  • jonas jonas:
    @Blackveiled you know another word for permanent? temporary
    +1
  • Varine Varine:
    Briefly, he'll only be there for the interim. Like a stopgap of sorts, he'll be back home in short time
  • O Old Mountain Shadow:
    Hurray! Tom has reappeared!
  • The Helper The Helper:
    Happy Thursday!
  • Blackveiled Blackveiled:
    Yep. Just another fun night at work.
  • Varine Varine:
    Broke the nozzle on my 3d printer and I don't have another heater block. So... I guess I'm fucked on that this weekend
  • The Helper The Helper:
    that sucks i bet they are expensive
  • Varine Varine:
    Not really
  • Varine Varine:
    The entire hot end is like 20 dollars, I just can't get anymore until next week
  • Varine Varine:
    I ordered like five blocks for 15 dollars. They're just little aluminum blocks with holes drilled into them
  • Varine Varine:
    They are pretty much disposable. I have shitty nozzles though, and I don't think these were designed for how hot I've run them
  • Varine Varine:
    I tried to extract it but the thing is pretty stuck. Idk what else I can use this for
  • Varine Varine:
    I'll throw it into my scrap stuff box, I'm sure can be used for something
  • Varine Varine:
    I have spare parts for like, everything BUT that block lol. Oh well, I'll print this shit next week I guess. Hopefully it fits

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top