System GTrigger Event System

Jesus4Lyf

Good Idea™
Reaction score
397
I can only assume that:
call TriggerRegisterPlayerUnitEvent(trig,GetLocalPlayer(),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
would cause desynchs in multiplayer maps. I don't feel like testing if it would cause desynchs. Let me know if it doesn't.

I'll repeat that one test with the exact same BJ inlined immediately. Obviously it has no impact on the other test whatsoever. Of course, this test is irrelevant in the first place. -.-

Edit:
But before I go run this test, I need to make you feel a little silly for making me do it...
  • DestroyTrigger clocked at ~6 nanosec on my computer. GTrigger's register event function is faster (at ~4 nanosec). So I don't see why you're making me do this. It's faster than a commonly used and quite fast native.
  • A basic function call is under 1 or 2 nanosec (do keep in mind these speeds are all on my computer, in case you test them yourself, but the percentages differences should be right). The margin of error on the BJ was 30 nanosec. The different will be within margin of error, making it undetectable.
  • The different is 100x. Do you think it's going to be suddenly faster? Or even down to 50x?
Anyway, I'll be back with the results in 10 minutes.

Edit: Sorry, 10 mins turned into 30. I found some strange things.

Firstly, I optimized the test as tight as possible, basically...
JASS:
local trigger t=CreateTrigger()
local integer i=bj_MAX_PLAYER_SLOTS
loop
    set i=i-1
    call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
    exitwhen i==0
endloop

Very aware this leaks a trigger, as it is meant to. The triggers are supposed to persist, and such, like in a real situation.

Now initially I tested over 10,000 executions, and got that massive result.

This time I first tested over 2,000 and as I ran the test over and over, I found out that the time was going up. I mean... I hit F10 --> restart map basically and the time continued going up from when it left off. I restarted WC3 and the process repeated. There seems to be some very serious leaks to do with trigger events here, or something. They didn't get flushed out when the map was restarted or something. I honestly don't know what.

Anyway, on a fresh restart of WC3, and a run of 100 executions, GTrigger was ~4-5 nanosec and that optimized code above was ~32 nanosec. This is a realistic example.

But more puzzling is that example I listed. It actually takes longer and longer, each time it is called, until WC3 is restarted? I'd love for other people to test this, if they are considering it.

Anyway, so I'll say the old method runs as a cool 32 nanosec, as opposed to my obtained value of 470 before. So GTrigger is still about 7 times faster. :)

But! If this effect really persists like that (until WC3 is restarted), then adding events unnecessarily is really quite bad. So this is yet another reason to use GTrigger. :)
 

Tom Jones

N/A
Reaction score
437
would cause desynchs in multiplayer maps. I don't feel like testing if it would cause desynchs. Let me know if it doesn't.
I've once heard that it should work, however I've never personally tested it, neither have I ever been comfortable using it. However if it works you cant get a faster native alternative. I'll log on later and test it out.

I'll repeat that one test with the exact same BJ inlined immediately. Obviously it has no impact on the other test whatsoever. Of course, this test is irrelevant in the first place. -.-
If those results are irrelevant I don't understand why you posted them in the first place.

But before I go run this test, I need to make you feel a little silly for making me do it...
You aint never going to make me feel silly about questioning either your results or methods.
 

Viikuna

No Marlo no game.
Reaction score
265
I've once heard that it should work, however I've never personally tested it, neither have I ever been comfortable using it. However if it works you cant get a faster native alternative. I'll log on later and test it out.

I remember that there was some reason why you should not use it. ( Gotta check wc3c , I dont quite remember )

Anyways, having only your own event in your computer, but not other players events, feels quite dangerous.
 

saw792

Is known to say things. That is all.
Reaction score
280
JASS:
call TriggerRegisterPlayerUnitEvent(trig,GetLocalPlayer(),EVENT_PLAYER_UNIT _SPELL_EFFECT,null)


Player 1 will have the event registered for his own units, but not other player's units.
Player 2 will have the event registered for his own units, but not other player's units.

If Player 1 casts the spell the event is triggered on his computer, but not Player 2s. Hmm. Sounds like a desync to me.
 

Jesus4Lyf

Good Idea™
Reaction score
397
That was my assumption. Especially because in single player maps, when you code for player 2 casting a spell, it works and fires on your machine.

>You aint never going to make me feel silly about questioning either your results or methods.

Fine by me. *Shrugs*

>I remember that there was some reason why you should not use it.

I'd be curious to hear more on it.


... So the point is, GTrigger is the fastest... XD
But the real reasons to use it are listed in the "pros" section of it's internal documentation thingie at the top. :thup:
 

emjlr3

Change can be a good thing
Reaction score
395
i dont understand how you benchmarked casting 100 (or so) abilities at a time???

nor do I really see an explanation
 

Jesus4Lyf

Good Idea™
Reaction score
397
That is more the response I expected. :)
In case you're wondering how I tested the firing, there's a spell that fires IMMEDIATELY on unit death (as in, if you call KillUnit, the triggers for that spell will fire before the next line of code is run), and that's Phoenix morph. So I simply registered 50 abilities on that spell effect, then started a stop watch, killed a phoenix, and clocked the stop watch. Each test repeated this 50 times, and I repeated each test about 5 times. I then reduced that 50 to 20, still being slower I reduced it to 5, then 2, then 1 failing trigger and 1 working trigger (both attaching using conditions only). Quite a reliable, appropriate test. :)
Just to clarify that, all triggers in my bench test attached with a single condition only.
Ok, to make this any clearer... I triggered 50 triggers on when ability 'A00F' is cast (doesn't actually exist, just to add the effect of having 50 abilities in the map) and 1 trigger fired off when Phoenix Morph was cast (by cast I mean SpellEffect). This means when I call KillUnit on any Phoenix, all 51 triggers fire immediately. I can therefore time that Kill action, and compare it to if I implemented the same stuff using GTrigger. Of course, it has the overhead of the Phoenix turning into an egg and such, but that's not important, because it is assumed to be constant.

When I did the test, the traditional method registered at about 1300 nanosec initially, while GTrigger registered at about... 470? I forget. Long story short, when there were no triggers except the one firing on Phoenix Morph, the traditional method was faster. When there was that one AND one firing on 'A00F', the GTrigger method was faster. And adding more firing on a separate ability added more and more delay to the traditional method, as predicted.

Hence, the answer, is 2.

From 2 abilities in the map, GTrigger is faster. Therefore, every map with triggers firing off abilities should use it. Well, that's my logic. :)

If people want to design other tests, I welcome it. If you can find any result, similar or different, I'd love to hear about it.

Furthermore, if you want to review my test more carefully, I can upload them...

All I can say... is APPROVE MAH SYSTEMZZOR! :D

PS. Actually, here's the test. Take a look. Let me know if you really must see it with any certain modifications.

PPS. Yeah, not casting 100 abilities at a time. At all. Just casting one ability 50 times, in a map with "50" abilities (and then 20, 5, 2, and 1).
 

Attachments

  • BenchSys.GTrigger.VS.Normal.zip
    112.5 KB · Views: 337

Romek

Super Moderator
Reaction score
963
This needs a demo map demonstrating it's usage.
 

Sim

Forum Administrator
Staff member
Reaction score
534
The only problem I have is this:

JASS:
call TriggerRegisterPlayerUnitEvent($NAME$Trigger,Player(i),EVENT_PLAYER_UNIT_$EVENT$,null)


"null" leaks. You would need a global variable so

JASS:
globals
private filterfunc non_leaking_filter = null
endglobals

private constant function DummyFilter takes nothing returns boolean
    return TRUE
endfunction

set non_leaking_filter = Filter( function DummyFilter )
call TriggerRegisterPlayerUnitEvent(whichTimer, whichPlayer, whichEvent, non_leaking_filter)


Dark_Dragon said:
boolexpr is like a table with condition you typed ~via Filter() or Condition() well since script does not know what pointer null is since it will not have table, the leak in memory is created because it will allocate something because you typed null and that something is some part of memory which can contain some data as well but will never again, until you leave the game. So the only thing you have to do is a valid boolexpr table, in your case it should only do nothing (no condition) in trigger registration so do it like next:

we must NOT destroy that filter and we can use that filter unlimited number of times you don't have to make it private if its in your map.

That, added to the fact every event is processed through this system, will effectively create a boolexpr table best suited for its purpose.
 

Azlier

Old World Ghost
Reaction score
461
'null' doesn't leak in trigger registry. I never really understood why, but it doesn't. Blizzard likes to mess with us.
 

Sim

Forum Administrator
Staff member
Reaction score
534
If you could point me to a valid test I would be very, very glad, as I'm in fact tired of "wondering".

But, for now, this guy's summed it up quite well.
 

Azlier

Old World Ghost
Reaction score
461
I would love to, but the thread is... lost in time? I don't even remember the name or author. It wasn't too old, but what was it?!

EDIT: Got it! The search button is magical!
 

Sim

Forum Administrator
Staff member
Reaction score
534
Well, the conclusions drawn by the last poster are pointing towards a bigger memory usage when using null than a function. In an event. ;)

That isn't quite the results the others got though.
 

Jesus4Lyf

Good Idea™
Reaction score
397
I don't take people's word at face value anyway, so when you say "they leak", I investigate further, ignoring the heresay.

But I don't even need to, for null events. I have a beautiful test for this, which is being overlooked. I know for a fact that events with null boolexpr for player unit leak into other maps, even. See the previous posts in this thread, I already prooved it by writing a speed test for adding an event, and it keeps taking longer and longer to add the event, until I restart WC3 - even restarting the map does not reset the speed it takes to add an event.

I do not know yet if adding the "return true" filter/condition changes anything. I'm happy to try that out when I get home to proove one way or the other, and update GTrigger if need be.

Ultimate fact: GTrigger does not have these problems as the leaks are capped because a fixed number of events are created. This is yet another reason to use GTrigger.

To-do:
  • Investigate the null boolexpr leak and publish my results here.
  • Upload a test map for this system's approval.
 

Andrewgosu

The Silent Pandaren Helper
Reaction score
715
Seems as a very nice system, looking forward to the updates!


Though, the only thing that bothers me is the way you name your variables.

They should be short and explanatory, instead of long sentances saying what the variables exactly does.

Not like it affects performance, but it looks weird to me. :)
 

Jesus4Lyf

Good Idea™
Reaction score
397
Thanks, Andrew.

In regards to variable names, I do that because they're actually globals, simulating locals (in one situation I had to make them actually locals, because the function could end up being recursive). So I add parts of the function names to the start to make sure I don't mix things up.

Why don't I just use locals? Because deep down, my belief is if it's easy to make more efficient, do it. Initializing a local and setting it takes twice as long as setting a global. :eek:

I would never recommend anyone to code like this, but I like to in my systems, because the penalty of my style is not passed on to the user in any way, just the tiny, tiny, efficiency bonus. :rolleyes:

To-do:
  • Investigate the null boolexpr leak and publish my results here.
  • Upload a test map for this system's approval.
  • Add AnyUnitDies style event. :D
I swear, I'll get around to it some time! Holidays start after tomorrow! ;)
 

Viikuna

No Marlo no game.
Reaction score
265
Add AnyUnitDies style event.

hm..?

What this has to do with spell events?

Why don't I just use locals? Because deep down, my belief is if it's easy to make more efficient, do it. Initializing a local and setting it takes twice as long as setting a global.

If you have loads of globals, it slows them all down. But yea, its probably still faster.
 

Jesus4Lyf

Good Idea™
Reaction score
397
>What this has to do with spell events?

Who said GTrigger was limited to spells? :D

>If you have loads of globals, it slows them all down. But yea, its probably still faster.

Hang on, we're talking about a game engine where people freely declare arrays of size 8192. I'm talking about 10-20 globals. ;) I don't even know if what you're saying there is true. :p
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top