• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Snippet] RegisterPlayerUnitEvent

Level 8
Joined
Oct 3, 2008
Messages
367
Ran my own benchmark. Not much of a measurable difference, if any. Here's the script I used and I attached the benchmarking map for good measure.

JASS:
//! zinc
library Benchmark {

//Test results (Azlier):
// Or: 13.8 fps
// TriggerAddCondition: 13.9 fps

constant real TICK = 0.01;
constant integer COND_COUNT = 1500;
constant boolean USE_OR = true;

trigger Trig = CreateTrigger();
boolexpr Cond = null;
code Dummy;

function DummyFunc () {}

function Execute () {
    TriggerEvaluate(Trig);
}

function AddConds () {
    integer i = COND_COUNT;
    while (i != 0) {
        i -= 1;
        if (USE_OR) {
            if (Cond == null) {
                Cond = Condition(Dummy);
            } else {
                Cond = Or(Cond, Condition(Dummy));
                TriggerClearConditions(Trig);
            }
            TriggerAddCondition(Trig, Cond);
        } else {
            TriggerAddCondition(Trig, Condition(Dummy));
        }
    }
}

function BeginTest () -> boolean {
    TimerStart(CreateTimer(), TICK, true, function Execute);
    DestroyTrigger(GetTriggeringTrigger());
    return false;
}

function onInit () {
    trigger t = CreateTrigger();
    Dummy = function DummyFunc;
    
    AddConds.evaluate();
    
    TriggerRegisterPlayerEvent(t, GetLocalPlayer(), EVENT_PLAYER_END_CINEMATIC);
    TriggerAddCondition(t, function BeginTest);
    t = null;
    
    if (USE_OR) {
        DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Test: Or.");
    } else {
        DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Test: TriggerAddCondition.");
    }
    DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Press Esc to begin the test.");
}

}
//! endzinc
 

Attachments

  • Benchmark.w3x
    8.4 KB · Views: 126

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Another benefit to using this is that you can allow your functions to return nothing (it doesn't crash Mac computers any more). pJass won't let Filter(function thatReturnsNothing) parse but if you first pass the code argument as a variable and then pass the code argument to the Filter it compiles just fine.

Therefore we can stop with the spamming of "return false" once and for all! Hah hah hah hah hah (evil victorious laugh).
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Btw, in most situations you should return true instead of false in such boolexprs, for many reasons :

- It makes sense to returns true when a code is succesfuly finished.
- This way you can easily check if you don't reach the limit op (if TriggerEvaluate returns true it doesn't, if it returns false you have reached it)
- Even if you use trigger actions, the actions will not be called if the trigger conditions were evaluated with a TriggerEvaluate.
- Trigger conditions don't use short-circuit evaluation anyway
 
Another benefit to using this is that you can allow your functions to return nothing (it doesn't crash Mac computers any more). pJass won't let Filter(function thatReturnsNothing) parse but if you first pass the code argument as a variable and then pass the code argument to the Filter it compiles just fine.

Therefore we can stop with the spamming of "return false" once and for all! Hah hah hah hah hah (evil victorious laugh).

cool
 
Level 16
Joined
Aug 7, 2009
Messages
1,403
Another benefit to using this is that you can allow your functions to return nothing (it doesn't crash Mac computers any more). pJass won't let Filter(function thatReturnsNothing) parse but if you first pass the code argument as a variable and then pass the code argument to the Filter it compiles just fine.

Therefore we can stop with the spamming of "return false" once and for all! Hah hah hah hah hah (evil victorious laugh).

That's cool!
 
Another benefit to using this is that you can allow your functions to return nothing (it doesn't crash Mac computers any more). pJass won't let Filter(function thatReturnsNothing) parse but if you first pass the code argument as a variable and then pass the code argument to the Filter it compiles just fine.

Therefore we can stop with the spamming of "return false" once and for all! Hah hah hah hah hah (evil victorious laugh).

That's cool!

:ogre_hurrhurr:
 
Yeah, I guess a disclaimer would be good :)

edit
Bad idea. Removed the 2 functions.

If you disable EVENT_PLAYER_UNIT_PICKUP_ITEM, Nestharus' GetItemOwner won't function.
If you disable EVENT_PLAYER_UNIT_DEATH, all hell would break loose.
If you disable EVENT_PLAYER_UNIT_ISSUED_ORDER, any library that logs unit orders wouldn't function properly.

It was a bad idea, and above all that, an epic fail.
 
Last edited:
Level 7
Joined
Dec 3, 2006
Messages
339
How does someone use this on a Player Unit Event that requires a condition? Or is it not possible?

Edit: Well, i guess I could replace the condition by using an if then else but eh.
 
Level 7
Joined
Dec 3, 2006
Messages
339
I'm working on a major recoding of this: http://www.wc3c.net/showthread.php?t=108895


To be as updated as possible. Including using Dirac's Linked List Module. But I guess it's gonna be a lot of work mainly cause I'm not familiar with linked lists really.

I've already re-organized the Camera/Math libraries to be readable and better.

But yeah it's a selection event, so it should be if/then/else. And for the order of the right click that will be an OrderEvent.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I've realized something with this approach against X triggers with the same event.

Let's say there is a trigger that needs to register any orders (for debugging or whatever).
An other trigger for forbid the point order "move", by using the trick pause unit/ issue immediate order 851973 / unpause unit.
You have to pause this last trigger to avoid an infinite recursive fire event.

With the X triggers approach it can be done easily, Disable/Enable/Trigger(GetTriggeringTrigger()), and you're done.

With this approach, you still have to do that but that will deactivate all things, including the debugging trigger.

I mean it's something that should be kept in mind, and X triggers are sometimes the way to go.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
It sounds like the solution would be to use multiple triggers to handle that sort of firing, sort of like the Advent library where you can disable certain registries. Other than that, you'd pretty much need to disable the entire system, issue the order, then enable the entire system. I think this is enough of a solution. If anyone has any problems with doing that they can post it here.
 
I provided EnablePlayerUnitEvent and DisablePlayerUnitEvent functions awhile ago.
Then I removed them cause they were dangerous =p
I guess the only time you need those functions is when avoiding infinite loops, but then
again, if you're trying to avoid an infinite loop, you're going to be calling it from a function
registered to a trigger with a specific playerunitevent obviously, so why not just turn off
that trigger ;P
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Plus, it's not because you give an order, that it will be given (unit get stunned, invalid order, and such).

So plz admit that in some cases the multiple triggers is the only way to go (i'm not saying it happens that many times though)
 
Updated to 5.0.0.0
Don't worry, backwards compatibility is NOT broken, I just added a new function.

function RegisterPlayerUnitEventForPlayer takes playerunitevent p, code c, player pl returns nothing

This function will register a playerunitevent for one player.
This was added because of special cases I found in which using TriggerRegisterPlayerUnitEvent would be much more of a bonus than using this library.
(When there are tons of events)
 
Level 10
Joined
May 27, 2009
Messages
494
Uhuh i don't know why this problem is arising on my map

well, i tried using everything of this snippet on each and every spell unfortunately, i'm having a stuck with a hero of mine with some synergy spells (like a skill will only work if a skill is cast or skill is learned or whatever)

And if there are many conditions with GetSpellAbilityId() running like (my theory)
GetSpellAbilityId() == SPECIFIC_ABIL
some parts might not work.. So i decided to change some of it to triggers or the normal creation of triggers blah blah
is that a war3 engine problem? or just this snippet
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Meh, playerevents are not so bad. There are only a few and most are useless:

JASS:
    constant playerevent EVENT_PLAYER_STATE_LIMIT               = ConvertPlayerEvent(11)
    constant playerevent EVENT_PLAYER_ALLIANCE_CHANGED          = ConvertPlayerEvent(12)

    constant playerevent EVENT_PLAYER_DEFEAT                    = ConvertPlayerEvent(13)
    constant playerevent EVENT_PLAYER_VICTORY                   = ConvertPlayerEvent(14)
    constant playerevent EVENT_PLAYER_LEAVE                     = ConvertPlayerEvent(15)
    constant playerevent EVENT_PLAYER_CHAT                      = ConvertPlayerEvent(16)
    constant playerevent EVENT_PLAYER_END_CINEMATIC             = ConvertPlayerEvent(17)

For the other playerevents, those are all taken care of by ArrowKeyEvent.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Edit: Never mind, I forgot that playerunitevents start at index 18.



JASS:
    function RegisterPlayerUnitEventForPlayer takes playerunitevent p, code c, player pl returns nothing
        local integer i = @260@ /* Needs to be 277 */ + 16 * GetHandleId(p) + GetPlayerId(pl)
        if t[i] == null then
            set t[i] = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent(t[i], pl, p, null)
        endif
        call TriggerAddCondition(t[i], Filter(c))
    endfunction
 
Top