Turns out that I needed an even smaller type of event: the signal. It is an event that has no data; it just fires. The Strongly Typed Events project started with the IEvent<TSender, TArgument> that was styled after the way .Net does event handling. Then the ISimpleEvent<TArgument> was added in 0.2.0, for scenarios when no sender is necessary. Now I've added the ISignal to version 0.3.0.
Why would we need another event type?
While programming a new TypeScript project, I got the need for a timer mechanism. I only need an event without data - much like a simple egg-timer. Implementing those events as an ISimpleEvent<void> looks ridiculous, that's why I created the ISignal and its counterparts.
Traffic light example
Its usage is best illustrated with a piece of example code. Let's create a somewhat static traffic light that will switch colors based on time. Remember: I'm Dutch, so the middle color will be orange!
class TrafficLight { private _signals = new SignalList(); private _color = 'red'; public constructor( public greenMs: number, public orangeMs: number, public redMs: number ) { this.onSwitchToGreen.subscribe(() => this._color = 'green'); this.onSwitchToOrange.subscribe(() => this._color = 'orange'); this.onSwitchToRed.subscribe(() => this._color = 'red'); this.internalStart(); } public get color(): string { return this._color; } public get onSwitchToGreen(): ISignal { return this._signals.get('green').asEvent(); } public get onSwitchToRed(): ISignal { return this._signals.get('red').asEvent(); } public get onSwitchToOrange(): ISignal { return this._signals.get('orange').asEvent(); } private internalStart(): void { window.setTimeout(() => { this._signals.get('green').dispatch(); window.setTimeout(() => { this._signals.get('orange').dispatch(); window.setTimeout(() => { this._signals.get('red').dispatch(); this.internalStart(); }, this.orangeMs); }, this.greenMs) }, this.redMs) } }
You can subscribe and unsubscribe from the signals in the usual way:
var light = new TrafficLight(5000, 1500, 10000); light.onSwitchToGreen.subscribe(() => console.log('Light is green.')); light.onSwitchToOrange.subscribe(() => console.log('Light is orange.')); light.onSwitchToRed.subscribe(() => console.log('Light is red.'));
The usual suspects
All of the usual suspects are present:
- ISignal - interface for signal event implementation and exposure.
- SignalDispatcher - implementation of a signal with a dispatch method.
- SignalList - implements named storage of auto created signals. Useful you need to implement a lot of them.
- SignalHandlingBase - to give your class named signal capabilities.
Other changes
I've removed the version numbers from the file names which makes updating easier. The tests are now wrapped in modules and have a string comment attached to them.