• 🏆 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!

[Solved] Variable Event vs. Manual Trigger Firing

Status
Not open for further replies.

AGD

AGD

Level 16
Joined
Mar 29, 2016
Messages
688
I just want to ask which is faster and which is more efficient, manually firing a trigger like so
JASS:
function OnCertainEvent takes nothing returns nothing
    call TriggerEvaluate(trig)
endfunction

function SomFunction takes nothing returns nothing
    //actions
endfunction

function A takes nothing returns nothing
    set trig = CreateTrigger()
    call TriggerAddCondition(trig, Filter(function SomeFunction))
endfunction

or this

JASS:
function OnCertainEvent takes nothing returns nothing
    set switch = 0
    set switch = 1
    set switch = 0
endfunction

function SomFunction takes nothing returns nothing
    //actions
endfunction

function A takes nothing returns nothing
    set trig = CreateTrigger()
    call TriggerRegisterVariableEvent(trig, "switch", EQUAL, 1)
    call TriggerAddCondition(trig, Filter(function SomeFunction))
endfunction
 
Level 13
Joined
Nov 7, 2014
Messages
571
Well in order for TriggerEvaluate (which calls the condition functions of a specified trigger) to be slower than the calling of the condition functions of TriggerRegisterVariableEvent (which happens implicitly when the event fires)
there has to be two versions of TriggerEvaluate, i.e "TriggerEvalauteSlow", which TriggerEvaluate would use and
"TriggerEvaluateFast" which the TriggerRegisterVariableEvent (TRVE) would use.
Now, what are the chances of that? Why make a slow code path and a fast code path and only use the fast one for the event handler functions of TriggerRegisterVariableEvent. It just doesn't make sense...

In fact, if we theorise how TRVE might be implemented, i.e the Jass VM when it executes an assignment to a scalar (non-array) variable of type real, it would have to check if the name of the variable is in "this list" of names that were passed to TRVE and if it matches, all the triggers must be retrieved and then for each of those their condition/action functions would have to get called.
Note that this checking would have to be done for every assignment of a scalar variable of type real! And there a bunch of those in blizzard.j alone... (My guess is that even using a single TRVE, one is slowing the execution of all the assignments of scalar real variables).

With that said, I think for performance sensitive scripts neither should be used. Instead a direct function call should be prefered. User/custom code can be passed/injected to library code with modules in vJass.
 

AGD

AGD

Level 16
Joined
Mar 29, 2016
Messages
688
With that said, I think for performance sensitive scripts neither should be used. Instead a direct function call should be prefered. User/custom code can be passed/injected to library code with modules in vJass.
But the problem is that I'm doing something like this
JASS:
set i = 0
loop
    set i = i + 1
    call TriggerEvaluate(trig[i])
    exitwhen i == end
endloop
which the module method can't possibly do.

Well in order for
TriggerEvaluate
(which calls the condition functions of a specified trigger) to be slower than the calling of the condition functions of
TriggerRegisterVariableEvent
(which happens implicitly when the event fires)
there has to be two versions of TriggerEvaluate, i.e "
TriggerEvalauteSlow
", which
TriggerEvaluate
would use and
"
TriggerEvaluateFast
" which the
TriggerRegisterVariableEvent
(
TRVE
) would use.
Now, what are the chances of that? Why make a slow code path and a fast code path and only use the fast one for the event handler functions of
TriggerRegisterVariableEvent
. It just doesn't make sense...

In fact, if we theorise how
TRVE
might be implemented, i.e the Jass VM when it executes an assignment to a scalar (non-array) variable of type
real
, it would have to check if the name of the variable is in "this list" of names that were passed to
TRVE
and if it matches, all the triggers must be retrieved and then for each of those their condition/action functions would have to get called.
Note that this checking would have to be done for every assignment of a scalar variable of type
real
! And there a bunch of those in blizzard.j alone... (My guess is that even using a single
TRVE
, one is slowing the execution of all the assignments of scalar
real
variables).
So based on what you said maybe I'll use TRVE. But before that, has TRVE already been proven to be a bit faster than TriggerEvaluate()?
 
Level 13
Joined
Nov 7, 2014
Messages
571
But the problem is that I'm doing something like this
JASS:
set i = 0
loop
    set i = i + 1
    call TriggerEvaluate(trig[i])
    exitwhen i == end
endloop
which the module method can't possibly do.

The end variable can have an upper limit (4 .. 8 or whatever, something reasonable) and the loop can be unrolled. I pretty sure that's explained in the post I linked.

So based on what you said maybe I'll use TRVE. But before that, has TRVE already been proven to be a bit faster than TriggerEvaluate()?
O.O?!, I don't know how you came up with this conclusion after reading what I wrote, but go ahead and "maybe use" TRVE anyway...
 

AGD

AGD

Level 16
Joined
Mar 29, 2016
Messages
688
You can bound the
end
variable to have an upper limit (4 .. 8 or whatever) and the loop can be unrolled. I pretty sure that's explained in the post I linked.
Another thing I failed to mention is that I can't unroll the loop. It's because that end is updated dynamically depending on other stuffs.

O.O?!, I don't know how you came up with this conclusion after reading what I wrote, but go ahead and "maybe use"
TRVE
anyway...
So well I read again. Seems that I'll use TriggerEvaluate() instead. I read too fast previously =).
 
I got it from @DracoL1ch .

put the .mix file into the folder where the wc3.exe is located

JASS:
constant native StartPerfCounter                 takes nothing returns nothing
constant native StopPerfCounter                 takes nothing returns nothing

you need to define the natives somewhere on top of the .j with mpq editor

then write the natives where ever you want in your code, and close mpq

then you can run the map with warcraft

( you need to switch wc3 version to 1.26 to make the .mix file work, Warcraft 3 Frozen Throne 1.27a Patch Download with Version Switcher | Dota-Utilities)

later, when you switch back to 1.27 you need to remove the .mix file again from your warcraft folder, because it still will try to load it.
 
I'm not sure but I think it did not work without defining the natives.

Also, you are not supposed to run JassHelper with the modified map. Just manipulate the .j file with mpq editor (adding natives and calling them where you need) and then close the mpq and move the map into the wacraft map folders. Then start wc3 and test the map without editing it with editor again.
 
Status
Not open for further replies.
Top