-
Notifications
You must be signed in to change notification settings - Fork 7
3. Signals
Before moving on, it would be useful to visit some core components of the engine that are used throughout to make life a bit easier.
Signals are Helix's way of implementing the "obverser pattern". It basically serves the same purpose as Javascript's own Events, but handles it in a slightly different way.
Signals are object that functions can "bind" to. When the Signal is "dispatched", all the bound functions will be called. For example:
function listenerFunction()
{
console.log("Listener called!");
}
var someSignal = new HX.Signal();
someSignal.bind(listenerFunction);
someSignal.dispatch();
This will cause "Listener called!" to be logged. A contrived example, yes, but this system is also used by Helix to notify when a frame should be updated (the HX.onFrame
signal), by loaders to notify when loading has been completed, or between objects to notify each other about certain changes. It allows the owner of the Signal to communicate with other objects without knowing about their existence.
An object or a value can be passed into the dispatch function, a so-called "payload". This will then be passed into the function.
function listenerFunction(payload)
{
console.log("Listener called with payload " + payload);
}
var someSignal = new HX.Signal();
someSignal.bind(listenerFunction);
someSignal.dispatch("data");
This will cause "Listener called with payload data" to be logged.
Signals can also accept anonymous functions:
someSignal.bind(function() {
console.log("Listener called!");
});
One of my personal favourite features (and the main reason I wrote the class), is that it allows passing in a "this reference" object. One of the horrible aspects (imho) of events, is that "this" in the callback function refers to the event dispatcher rather than any decent language's this object.
In the true C++'s spirit of binding functions, passing in the "this" object prevents that.
SomeClass.prototype.init = function()
{
someSignal.bind(this.listenerMethod, this);
}
SomeClass.prototype.listenerMethod = function()
{
this.doSomething();
}
SomeClass.prototype.listenerMethod = function()
{
console.log("Doing something");
}
No more horrible inlining and doing "var self = this;" or func.bind(this).