diff options
Diffstat (limited to 'gif-encode/tube.js')
| -rw-r--r-- | gif-encode/tube.js | 323 |
1 files changed, 0 insertions, 323 deletions
diff --git a/gif-encode/tube.js b/gif-encode/tube.js deleted file mode 100644 index 17d3bfd..0000000 --- a/gif-encode/tube.js +++ /dev/null @@ -1,323 +0,0 @@ -var nextTick = (function(){ - // postMessage behaves badly on IE8 - if (window.ActiveXObject || !window.postMessage) { - var nextTick = function(fn) { - setTimeout(fn, 0); - } - } else { - // based on setZeroTimeout by David Baron - // - http://dbaron.org/log/20100309-faster-timeouts - var timeouts = [] - , name = 'next-tick-zero-timeout' - - window.addEventListener('message', function(e){ - if (e.source == window && e.data == name) { - if (e.stopPropagation) e.stopPropagation(); - if (timeouts.length) timeouts.shift()(); - } - }, true); - - var nextTick = function(fn){ - timeouts.push(fn); - window.postMessage(name, '*'); - } - } - - return nextTick; -})() - -var Uid = (function(){ - var id = 0 - return function(){ return id++ + "" } -})() - - -var tokenize = (function(){ - var tokenize = function(str, splitOn){ - return str - .trim() - .split(splitOn || tokenize.default); - }; - - tokenize.default = /\s+/g; - - return tokenize; -})() - -// globber("*".split(":"), "a:b:c".split(":")) => true -// globber("*:c".split(":"), "a:b:c".split(":")) => true -// globber("a:*".split(":"), "a:b:c".split(":")) => true -// globber("a:*:c".split(":"), "a:b:c".split(":")) => true - -// based on codegolf.stackexchange.com/questions/467/implement-glob-matcher -var globber = function(patterns, strings) { - // console.log("globber called with: " + patterns.join(":"), strings.join(":")) - var first = patterns[0], - rest = patterns.slice(1), - len = strings.length, - matchFound; - - if(first === '*') { - for(var i = 0; i <= len; ++i) { - // console.log("* " + i + " trying " + rest.join(":") + " with " + strings.slice(i).join(":")) - if(globber(rest, strings.slice(i))) return true; - } - return false; - } else { - matchFound = (first === strings[0]); - // console.log ("literal matching " + first + " " + strings[0] + " " + !!matched) - } - - return matchFound && ((!rest.length && !len) || globber(rest, strings.slice(1))); -}; - -var setproto = function(obj, proto){ - if (obj.__proto__) - obj.__proto__ = proto; - else - for (var key in proto) - obj[key] = proto[key]; -}; - - -var Tube = (function(){ - var globcache = {}; - var Tube = function(opts){ - opts = opts || {}; - if (opts.queue){ - var c = function(){ - var args = arguments; - // queueOrNextTick (function(){ c.send.apply(c, args) }); - nextTick (function(){ c.send.apply(c, args) }); - return c; - }; - } else { - var c = function(){ - c.send.apply(c, arguments); - return c; - }; - } - - setproto(c, Tube.proto); - c.listeners = {}; - c.globListeners = {}; - - return c; - }; - - Tube.total = {}; - Tube.proto = {}; - - /* - adds fns as listeners to a channel - - on("msg", fn, {opts}) - on("msg", [fn, fn2], {opts}) - on("msg msg2 msg3", fn, {opts}) - on({"msg": fn, "msg2": fn2}, {opts}) - */ - - Tube.proto.on = function(){ - var chan = this; - if (typeof arguments[0] === "string") { - //if (arguments.length > 1) { // on("msg", f) - var msgMap = {}; - msgMap[arguments[0]] = arguments[1]; - var opts = arguments[2] || {}; - } else { // on({"msg": f, ...}) - var msgMap = arguments[0]; - var opts = arguments[1] || {}; - } - - for (var string in msgMap){ - var msgs = string.split(" "); - var fs = msgMap[string]; - if (!Array.isArray(fs)) fs = [fs]; - - for(var i=0, f; f=fs[i]; i++){ - if (!f.uid) f.uid = Uid(); - } - - for(var i=0, msg; msg=msgs[i]; i++){ - var listeners = (msg.indexOf("*") === -1) ? - chan.listeners : - chan.globListeners; - - // todo: this probably wastes a lot of memory? - // make a copy of the listener, add to it, and replace the listener - // why not just push directly? - // send might be iterating over it... and that will fuck up the iteration - - listeners[msg] = (msg in listeners) ? - listeners[msg].concat(fs) : - fs.concat(); - } - } - - return chan; - }; - - /* - off() - off("a:b:c") - off(f) - off("a:b:c", f) - off("a:b:c d:e:f") - off([f, f2]) - off({"a": f, "b": f2}) - */ - - Tube.proto.off = function(){ var chan = this; - - var listeners, i, msgs, msg; - - // off() : delete all listeners. but replace, instead of delete - if (arguments.length === 0) { - chan.listeners = {}; - chan.globListeners = {}; - return chan; - } - - // off("a:b:c d:e:f") - // remove all matching listeners - if (arguments.length === 1 && typeof arguments[0] === "string"){ - // question... will this fuck up send if we delete in the middle of it dispatching? - msgs = arguments[0].split(" "); - - for (i=0; msg=msgs[i]; i++){ - delete chan.listeners[msg]; - delete chan.globListeners[msg]; - } - return chan; - } - - // off(f) or off([f, f2]) - // remove all matching functions - if (typeof arguments[0] === "function" || Array.isArray(arguments[0])) { - var fs = (typeof arguments[0] === "function") ? - [arguments[0]] : - arguments[0]; - // TODO - return chan; - } - - // off("a:b:c", f) or off({"a": f, "b": f2}) - if (arguments.length > 1) { // off("msg", f) - var msgMap = {}; - msgMap[arguments[0]] = arguments[1]; - } else { // off({"msg": f, ...}) - var msgMap = arguments[0]; - } - - for (var string in msgMap){ - msgs = string.split(" "); - - var fs = msgMap[string]; - if (typeof fs === "function") fs = [fs]; - - for(var i=0; msg=msgs[i]; i++){ - if (msg in chan.listeners) - listeners = chan.listeners; - else if (msg in chan.globListeners) - listeners = chan.globListeners; - else - continue; - - // gotta do this carefully in case we are still iterating through the listener in send - // build a new array and assign it to the property, instead of mutating it. - - // console.log(" length of listeners[" + msg + "]: " + listeners[msg].length) - // console.log(listeners[msg].join(",")); - // console.log(fs.join(",")); - - listeners[msg] = listeners[msg].filter( - function(f){ return fs.indexOf(f) === -1 } - ); - - // console.log(" length of listeners[" + msg + "]: " + listeners[msg].length) - - } - } - - return chan; - - }; - - /* - c = Tube() - c.on("foo", fn) - c("foo", "bar", []) - - will call fn("bar", [], "foo") - */ - - Tube.proto.send = function(msgString /*, data... */){ - // todo: don't do this? - if (!Tube.total[msgString]) Tube.total[msgString] = 0 - Tube.total[msgString]+=1; - - var listener, - listeners = this.listeners, - globListeners = this.globListeners, - //args = Array.prototype.splice.call(arguments, 1), - msgs = tokenize(msgString), - msg, f; - - if (arguments.length) { - var args = Array.prototype.splice.call(arguments, 1); - args.push(msgString); - - } else { - var args = []; - } - - for (var m=0; msg=msgs[m]; m++){ - - var fsToRun = []; - var uidKeyFnValue = {}; - var uidKeyMsgStringValue = {}; - - // note this will die on errors - // todo: implement http://dean.edwards.name/weblog/2009/03/callbacks-vs-events/ - // exact matches - if (listener = listeners[msg]) { - for (var i=0; f=listener[i]; i++){ - // fsToRun.push([f, msg]); - uidKeyFnValue[f.uid] = f; - uidKeyMsgStringValue[f.uid] = msg; - } - } - - // glob matches - var msgSplit = msg.split(":"); - - for (var pattern in globListeners){ - - if (pattern !== "*") { // * always matches - var patternSplit = globcache[pattern] || (globcache[pattern] = pattern.split(":")); - if (!globber(patternSplit, msgSplit)) continue; - } - - listener = globListeners[pattern]; - - for (var i=0; f=listener[i]; i++){ - //f.apply(window, args); // hm possibly pass the actual message to the func - // fsToRun.push([f, msg]); - uidKeyFnValue[f.uid] = f; - uidKeyMsgStringValue[f.uid] = msg; - } - } - - var fns = []; - for (var f in uidKeyFnValue) fns.push(uidKeyFnValue[f]); - - for (var i=0, f; f=fns[i]; i++) - f.apply(f, args); - - } - return this; - }; - - return Tube; -})() - |
