UNPKG

@mezzy/signals

Version:

A luxurious user experience framework, developed by your friends at Mezzanine.

153 lines (115 loc) 4.51 kB
import ISignal from './iSignal'; import ISignalBinding from './iSignalBinding'; /** * @desc An object that represents a binding between a Signal and a listener function. * Released under the MIT license * http://millermedeiros.github.com/js-signals/ * * @version 1.0 - 7th March 2013 * * @author Richard Davey, TypeScript conversion * @author Miller Medeiros, JS Signals * @author Robert Penner, AS Signals * * @url http://www.kiwijs.org * */ export class SignalBinding<T> implements ISignalBinding<T> { /** * Object that represents a binding between a Signal and a listener function. * <br />- <strong>This is an internal constructor and shouldn't be called by regular users.</strong> * <br />- inspired by Joa Ebert AS3 SignalBinding and Robert Penner's Slot classes. * @author Miller Medeiros * @constructor * @internal * @key SignalBinding * @param Signal signal Reference to Signal object that listener is currently bound to. * @param {(value:T) => void} listener Handler function bound to the signal. * @param {boolean} isOnce If binding should be executed just once. * @param {Object} [listenerContext] Context on which listener will be executed (object that should represent the `this` variable inside listener function). * @param {Number} [priority] The priority level of the event listener. (default = 0). */ constructor(signal:ISignal<T>, listener:(value:T) => void, isOnce:boolean, listenerContext:any, priority:number = 0) { this._listener = listener; this._isOnce = isOnce; this._context = listenerContext; this._signal = signal; this.priority = priority; } /** * @return {(value:T) => void} Handler function bound to the signal. */ get listener():(value:T) => void { return this._listener; } private _listener:(value:T) => void; // Not readonly, so it can be deleted. /** * If binding should be executed just once. */ private readonly _isOnce:boolean; /** * Context on which listener will be executed (object that should represent the `this` variable inside listener function). */ get context():any { return this._context; } set context(value:any) { this._context = value; } private _context:any; /** * @return Signal Signal that listener is currently bound to. */ private _signal:ISignal<T>; // Not readonly, so it can be deleted. /** * Listener priority */ public priority:number; /** * If binding is active and should be executed. */ isActive:boolean = true; /** * Call listener passing arbitrary parameters. * <p>If binding was added using `Signal.listenOnce()` it will be automatically deleted from signal dispatch queue, * this method is used internally for the signal dispatch.</p> * @param {T} [param] Parameter that should be passed to the listener * @return {*} Value returned by the listener. */ execute(param:T):any { let handlerReturn:any; if (this.isActive && !!this._listener) { handlerReturn = this._listener.apply(this._context, [param]); if (this._isOnce) { this.detach(); } } return handlerReturn; } /** * Detach binding from signal. * - alias to: mySignal.delete(myBinding.getListener()); * @return {(value:T) => void|null} Handler function bound to the signal or `null` if binding was previously detached. */ detach():(value:T) => void { return this.isBound() ? this._signal.delete(this._listener, this._context) : null; } /** * @return {boolean} Is the binding still bound to the signal with a listener? */ isBound():boolean { return (!!this._signal && !!this._listener); } /** * @return {boolean} Will SignalBinding be executed only once? */ isOnce():boolean { return this._isOnce; } /** * Delete instance properties * @private */ destroy():void { delete this._signal; delete this._listener; delete this._context; } /** * @return {string} String representation of the object. */ toString():string { return '[SignalBinding isOnce:' + this._isOnce + ', isBound:' + this.isBound() + ', isActive:' + this.isActive + ']'; } } // End class export default SignalBinding;