Skip to content

Instantly share code, notes, and snippets.

@sTiLL-iLL
Last active August 29, 2015 14:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sTiLL-iLL/34a9a604da54b4fdeb52 to your computer and use it in GitHub Desktop.
Save sTiLL-iLL/34a9a604da54b4fdeb52 to your computer and use it in GitHub Desktop.
Signals.js... A fast and efficient event system in javascript.
// SignalsBest2.js 8;]
var Signals = (function() {
'use strict';
var sigCache = {}, singleRtnVal = false,
received = function(eventName, func) {
return wen(eventName, function(evnt) {
return func(evnt);
});
},
dropReceivers = function(eventName, func) {
if (eventName && func && typeof func === "function") {
dropReceiver(eventName, func);
return this;
}
if (!eventName) {
sigCache = {};
return this;
}
if (sigCache && sigCache[eventName]) {
sigCache[eventName] = null;
}
return this;
},
setSingleRV = function(val) {
singleRtnVal = val;
return this;
},
getSingleRV = function() {
if (receivers.hasOwnProperty('singleRtnVal')) {
return singleRtnVal;
}
else {
return true;
}
},
dropReceiver = function(eventName, func) {
if (sigCache && sigCache[eventName]) {
var sigLst = sigCache[eventName];
if (isAry(sigLst)) {
var idx = -1;
for (var i = 0, l = sigLst.length; i < l; i++) {
if (sigLst[i] === func || (sigLst[i].receiver && sigLst[i].receiver === func)) {
idx = i;
break;
}
}
if (idx < 0) {
return this;
}
sigLst.splice(idx, 1);
if (!sigLst.length) {
delete sigCache[eventName];
}
}
else if (sigLst === func || (sigLst.receiver && sigLst.receiver === func)) {
delete sigCache[eventName];
}
}
return this;
},
signalOnce = function(eventName, func) {
var slf = this;
setSingleRV(true);
wen.receiver = function onit() {
dropReceiver(eventName, this);
func.apply(slf, arguments);
};
wen(eventName, onit);
return this;
},
castSignal = function(eventName, args) {
var recvrLst = receiverObjects(eventName),
k = {}, recvr = [], i = 0, rspns = {};
for (k in recvrLst) {
if (recvrLst.hasOwnProperty(k)) {
i = recvrLst[k].length;
while (i--) {
recvr = recvrLst[k][i];
if (recvr.signalOnce === true) {
dropReceiver(eventName, recvr);
}
rspns = recvr.call(this, args || []);
if (rspns === getSingleRV()) {
dropReceiver(eventName, recvr);
}
}
}
}
return this;
};
function isAry(obj) {
return (obj.constructor === Array);
};
function receiverObjects(eventName) {
var recvrLst = receivers(eventName), rspns;
if (isAry(recvrLst)) {
rspns = {};
rspns[eventName] = recvrLst;
}
return rspns || recvrLst;
};
function receivers(eventName) {
if (!sigCache) {
sigCache = {};
}
if (!sigCache[eventName]) {
sigCache[eventName] = [];
}
if (!isAry(sigCache[eventName])) {
sigCache[eventName] = [sigCache[eventName]];
}
return sigCache[eventName];
};
function wen(eventName, func) {
if (!sigCache) {
sigCache = {};
}
if (!sigCache[eventName]) {
sigCache[eventName] = func;
}
else if (isAry(sigCache[eventName])) {
sigCache[eventName].push(func);
}
else {
sigCache[eventName] = [sigCache[eventName], func];
}
return this;
};
return {
signal: castSignal,
signaled: received,
receive: received,
receiveOnce: signalOnce,
receivers: receivers,
dropReceivers: dropReceivers
};
}());
// exports.Signals = Signals; //<-- for nodejs
// use it...
var signals = Signals;
signals.receive("myEvent", function(dta) {
console.log(dta);
});
signals.signal("myEvent", "data to send in event...");
// note: this will drop just this receiver.
// If there are no arguments included it drops all the receivers
signals.dropReceivers("myEvent");
// you can also use inheritance to bake the signals functionality into your own objects
function usrID(uId) {
var id = uId.toString(),
slf = this;
this.setId = function(val) {
if(id !== val){
id = val.toString();
slf.signal("change", this);
}
else {
return;
}
};
this.getId = function() {
var x = id;
return x;
}
}
usrID.prototype = Signals;
usrID.constructor = usrID;
// now use it and abuse it!
var oID = new usrID("sytw94pt8");
oID.receive("change", function(dta) {
alert("'change' signal data: " + dta);
});
oID.getId(); // sytw94pt8
// executing this will trigger the alert box defined in the "receive" callback
oID.setId("000XXX"); // "000XXX"
// you can also observe the signals of any/all signalCasters using the static Signals object you inherited from
// It knows all and receives all signals.... So backing up a bit, we could do something like this...
userID.prototype = Signals;
userID.constructor = userID;
// now use it and abuse it!
var uID = new userID("sytw94pt8");
uID.receive("change", function(dta) {
alert("'change' signal data from uID Object: " + dta);
});
// AND SOMEWHERE ELSE IN THE CODE AN OBSERVER.... *LoL
Signals.receive("change", function(dta) {
alert("I also heard " + dta.target + "'s 'change' signal data: " + dta);
});
uID.getId(); // sytw94pt8
// executing this will trigger the BOTH alert boxs defined above
uID.setId("000XXX"); // "000XXX"
// ENJOY!!! --sTiLL-iLL--
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment