Last active
August 29, 2015 14:10
-
-
Save sTiLL-iLL/34a9a604da54b4fdeb52 to your computer and use it in GitHub Desktop.
Signals.js... A fast and efficient event system in javascript.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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