@mezzy/signals
Version:
A luxurious user experience framework, developed by your friends at Mezzanine.
117 lines • 4.27 kB
JavaScript
"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