UNPKG

@mezzy/signals

Version:

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

117 lines 4.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const ids_1 = require("@mezzy/ids"); const signalBinding_1 = require("./signalBinding"); class Signal { constructor(isMemorize = false) { this._key = `signal_${ids_1.default.getSessionUniqueInteger()}`; this._bindings = []; this._prevParam = null; this._isMemorize = isMemorize; this._isDispatched = false; this._isShouldPropagate = true; this.isActive = true; } get key() { return this._key; } get listenerCount() { return !!this._bindings ? this._bindings.length : 0; } get isMemorize() { return this._isMemorize; } ; validateListener(listener, fnName) { if (typeof listener !== 'function') { throw new Error('listener is a required param of {fn}() and should be a Function.'.replace('{fn}', fnName)); } } _registerListener(listener, isOnce, listenerContext, priority) { let prevIndex = this._indexOfListener(listener, listenerContext); let binding; if (prevIndex !== -1) { binding = this._bindings[prevIndex]; if (binding.isOnce() !== isOnce) { throw new Error('You cannot listen' + (isOnce ? '' : 'Once') + '() then add' + (!isOnce ? '' : 'Once') + '() the same listener without removing the relationship first.'); } } else { binding = new signalBinding_1.default(this, listener, isOnce, listenerContext, priority); this._addBinding(binding); } if (this.isMemorize && this._isDispatched) { binding.execute(this._prevParam); } return binding; } _addBinding(binding) { let n = this._bindings.length; do { --n; } while (this._bindings[n] && binding.priority <= this._bindings[n].priority); this._bindings.splice(n + 1, 0, binding); } _indexOfListener(listener, context) { let indexCurrent = this._bindings.length; let bindingCurrent; while (indexCurrent--) { bindingCurrent = this._bindings[indexCurrent]; if (bindingCurrent.listener === listener && bindingCurrent.context === context) return indexCurrent; } return -1; } has(listener, context = null) { return this._indexOfListener(listener, context) !== -1; } listen(listener, listenerContext = null, priority = 0) { this.validateListener(listener, 'listen'); return this._registerListener(listener, false, listenerContext, priority); } listenOnce(listener, listenerContext = null, priority = 0) { this.validateListener(listener, 'listenOnce'); return this._registerListener(listener, true, listenerContext, priority); } delete(listener, context = null) { this.validateListener(listener, 'remove'); let i = this._indexOfListener(listener, context); if (i !== -1) { this._bindings[i].destroy(); this._bindings.splice(i, 1); } return listener; } deleteAll() { let n = this._bindings.length; while (n--) { this._bindings[n].destroy(); } this._bindings.length = 0; } halt() { this._isShouldPropagate = false; } dispatch(param) { if (!this.isActive) return; let n = this._bindings.length; let bindings; if (this.isMemorize) { this._prevParam = param; this._isDispatched = true; } if (!n) { return; } bindings = this._bindings.slice(0); this._isShouldPropagate = true; do { n--; } while (bindings[n] && this._isShouldPropagate && bindings[n].execute(param) !== false); } forget() { this._prevParam = null; this._isDispatched = false; } dispose() { this.deleteAll(); this._bindings.splice(0); delete this._prevParam; } toString() { return '[Signal isActive:' + this.isActive + ' numListeners:' + this.listenerCount + ']'; } } exports.Signal = Signal; exports.default = Signal; //# sourceMappingURL=signal.js.map