@gamestdio/signals
Version:
Minimal Signal implementation for JavaScript.
109 lines (108 loc) • 4.17 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var SlotList_1 = require("./SlotList");
var Slot_1 = require("./Slot");
var OnceSignal = (function () {
function OnceSignal() {
var valueClasses = [];
for (var _i = 0; _i < arguments.length; _i++) {
valueClasses[_i] = arguments[_i];
}
this.slots = SlotList_1.SlotList.NIL;
this.valueClasses = valueClasses.length === 1 && valueClasses[0] instanceof Array ? valueClasses[0] : valueClasses;
}
Object.defineProperty(OnceSignal.prototype, "valueClasses", {
get: function () {
return this._valueClasses;
},
set: function (value) {
this._valueClasses = value ? value.slice() : [];
for (var i = this._valueClasses.length; i--;) {
if (!(this._valueClasses[i] instanceof Object)) {
throw new Error("Invalid valueClasses argument: " +
"item at index " +
i +
" should be a Class but was:<" +
this._valueClasses[i] +
">." +
this._valueClasses[i]);
}
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(OnceSignal.prototype, "numListeners", {
get: function () {
return this.slots.length;
},
enumerable: true,
configurable: true
});
OnceSignal.prototype.addOnce = function (listener) {
return this.registerListener(listener, true);
};
OnceSignal.prototype.once = function (listener) {
return this.addOnce(listener);
};
OnceSignal.prototype.remove = function (listener) {
var slot = this.slots.find(listener);
if (!slot) {
return null;
}
this.slots = this.slots.filterNot(listener);
return slot;
};
OnceSignal.prototype.removeAll = function () {
this.slots = SlotList_1.SlotList.NIL;
};
OnceSignal.prototype.dispatch = function () {
var valueObjects = [];
for (var _i = 0; _i < arguments.length; _i++) {
valueObjects[_i] = arguments[_i];
}
var numValueClasses = this._valueClasses.length;
var numValueObjects = valueObjects.length;
if (numValueObjects < numValueClasses) {
throw new Error("Incorrect number of arguments. " + "Expected at least " + numValueClasses + " but received " + numValueObjects + ".");
}
for (var i = 0; i < numValueClasses; i++) {
if (valueObjects[i] === null ||
(valueObjects[i] instanceof this._valueClasses[i] || valueObjects[i].constructor === this._valueClasses[i])) {
continue;
}
throw new Error("Value object <" + valueObjects[i] + "> is not an instance of <" + this._valueClasses[i] + ">.");
}
var slotsToProcess = this.slots;
if (slotsToProcess.nonEmpty) {
while (slotsToProcess.nonEmpty) {
slotsToProcess.head.execute(valueObjects);
slotsToProcess = slotsToProcess.tail;
}
}
};
OnceSignal.prototype.registerListener = function (listener, once) {
if (once === void 0) { once = false; }
if (this.registrationPossible(listener, once)) {
var newSlot = new Slot_1.Slot(listener, this, once);
this.slots = this.slots.prepend(newSlot);
return newSlot;
}
return this.slots.find(listener);
};
OnceSignal.prototype.registrationPossible = function (listener, once) {
if (!this.slots.nonEmpty) {
return true;
}
var existingSlot = this.slots.find(listener);
if (!existingSlot) {
return true;
}
if (existingSlot.once !== once) {
throw new Error("You cannot addOnce() then add() the same listener without removing the relationship first.");
}
return false;
};
return OnceSignal;
}());
exports.OnceSignal = OnceSignal;