3rd Apr 2013

Signals are a light-weight, strongly typed messaging tool and we use them extensively in our game framework. And we’ve just released our TypeScript implementation for others to benefit from. It’s a conversion of js-signals by Miller Medeiros, which is of course in turn a conversion of AS3-Signals by Robert Penner.

You can get TypeScript-Signals from github.

If you are unfamiliar with Signals, how they work and how they compare to Events then this short summary is well worth a quick read, but to summarise:

A Signal is essentially a mini-dispatcher specific to one event, with its own array of listeners.

A Signal gives an event a concrete membership in a class.

Listeners subscribe to real objects, not to string-based channels.

Event string constants are no longer needed.

Signals are inspired by C# events and signals/slots in Qt.

I ported over all of the 18 unit tests to TypeScript as well. So you have plenty of examples: from adding a basic listener up to manual binding and dynamic context switching.

Here is an example of how we use a Signal within our Position component in our framework. In this case ‘updated’ is our Signal and when the Position component is updated we dispatch it:

this.updated.dispatch(this._point.x, this._point.y, this._z, this.cssTranslate3d, this.cssLeft, this.cssTop); 1 this . updated . dispatch ( this . _point . x , this . _point . y , this . _z , this . cssTranslate3d , this . cssLeft , this . cssTop ) ;

Anything that is listening to the ‘updated’ Signal is notified of the new values being sent. For example our Sprite game object listens for updates:

this.position.updated.add(this._updatePosition, this); 1 this . position . updated . add ( this . _updatePosition , this ) ;

And a local private method _updatePosition responds to the new values being sent.

The reason we use Signals, aside from the fact that they are blisteringly fast, is that they are not bound to strings but rather to objects. And more importantly they can dispatch a dynamic number of properties which can be strongly typed in TypeScript if you wish. But you don’t have to respond to all of the parmeters if you don’t wish. For example although the updated Signal was sending through x, y, z and other values, the method that listens to the Signal doesn’t have to take all of those parameters.

This is perfectly valid:

private _updatePosition(x: number, y: number, z: number, cssTranslate3d: string, cssLeft: string, cssTop: string) { } 1 private _updatePosition ( x : number , y : number , z : number , cssTranslate3d : string , cssLeft : string , cssTop : string ) { }

But if you only need the x,y values then so is this:

private _updatePosition(x: number, y: number) { } 1 private _updatePosition ( x : number , y : number ) { }

Even though all values are sent it doesn’t matter how many of them you state in your method.

There are lots of other benefits too. The passing of context and priority orders being especially useful. I have to admit that in AS3 I never really found a use for Signals as Events were so tightly coupled with the language, but in TypeScript they make perfect sense. They are one of those things that are really quite hard to explain or make you understand why they’re great to use until you actually do it. But once you do start using them it’s like a “light bulb” moment and you probably won’t want to go back to Events again.

Checkout TypeScript-Signals on github.