20,741
edits
Line 2,238: | Line 2,238: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Similarly, you could just as well "overload" functions like settimer() setlistener() in your script, this can be easily achieved by saving a handle to the original functions and then overriding them in your script: | |||
<syntaxhighlight lang="php"> | |||
var original_settimer = settimer; | |||
var original_setlistener = setlistener; | |||
</syntaxhighlight> | |||
Now, you have handles stored to the original functions, to make sure that you are referring to the correct version, you can also refer to the "globals" namespace. | |||
Obviously, it makes sense to only store and clean up those listeners that are not themselves required to handle initialization/resets, otherwise you'd remove the listeners for your init routines, too. | Obviously, it makes sense to only store and clean up those listeners that are not themselves required to handle initialization/resets, otherwise you'd remove the listeners for your init routines, too. | ||
Next, you can easily override settimer/setlistener in your script: | |||
<syntaxhighlight lang="php"> | |||
var original_settimer = settimer; | |||
var original_setlistener = setlistener; | |||
var settimer = func(function, time, realtime=0) { | |||
print("Using your own settimer function now"); | |||
} | |||
var setlistener = func(property, function, startup=0, runtime=1) { | |||
print("Using your own setlistener function now!"); | |||
} | |||
</syntaxhighlight> | |||
In order to call the old implementation, just use the two handles that you have stored: | |||
* original_settimer | |||
* original_setlistener | |||
<syntaxhighlight lang="php"> | |||
var original_settimer = settimer; | |||
var original_setlistener = setlistener; | |||
var settimer = func(function, time, realtime=0) { | |||
print("Using your own settimer function now"); | |||
original_settimer(function, time, realtime); | |||
} | |||
var setlistener = func(property, function, startup=0, runtime=1) { | |||
print("Using your own setlistener function now!"); | |||
original_setlistener(property, function, startup, runtime); | |||
} | |||
</syntaxhighlight> | |||
So this is a very simple and elegant way to wrap and override global behavior. So that you can easily implement script-specific semantics and behavior, i.e. to automatically store handles to registered listeners: | |||
<syntaxhighlight lang="php"> | |||
var original_settimer = settimer; | |||
var original_setlistener = setlistener; | |||
var cleanup_listeners = []; | |||
var settimer = func(function, time, realtime=0) { | |||
print("Using your own settimer function now"); | |||
original_settimer(function, time, realtime); | |||
} | |||
var setlistener = func(property, function, startup=0, runtime=1) { | |||
print("Using your own setlistener function now!"); | |||
var handle = original_setlistener(property, function, startup, runtime); | |||
append(cleanup_listeners, handle); | |||
} | |||
</syntaxhighlight> | |||
Thus, you can now have a simple "cleanup" function which processes all listeners stored in "cleanup_listeners" using a foreach loop and removes them: | |||
<syntaxhighlight lang="php"> | |||
var original_settimer = settimer; | |||
var original_setlistener = setlistener; | |||
var cleanup_listeners = []; | |||
var remove_listeners = func { | |||
foreach(var l; cleanup_listeners) { | |||
removelistener(l); | |||
} | |||
} | |||
var settimer = func(function, time, realtime=0) { | |||
print("Using your own settimer function now"); | |||
original_settimer(function, time, realtime); | |||
} | |||
var setlistener = func(property, function, startup=0, runtime=1) { | |||
print("Using your own setlistener function now!"); | |||
var handle = original_setlistener(property, function, startup, runtime); | |||
append(cleanup_listeners, handle); | |||
} | |||
</syntaxhighlight> | |||
The only thing that's needed now to handle simulator resets, is registering an "anonymous" listener which triggers your "remove_listeners" callback upon simulator reset: | |||
<syntaxhighlight lang="php"> | |||
setlistener( "/sim/signals/reinit", remove_listeners ); | |||
</syntaxhighlight> | |||
Now, you'll probably have noticed that it would make sense to consider wrapping all these helpers and variables inside an enclosing helper class, this can be accomplished in Nasal using a hash. | Now, you'll probably have noticed that it would make sense to consider wrapping all these helpers and variables inside an enclosing helper class, this can be accomplished in Nasal using a hash. |