summaryrefslogtreecommitdiff
path: root/gif-encode/tube.js
diff options
context:
space:
mode:
Diffstat (limited to 'gif-encode/tube.js')
-rw-r--r--gif-encode/tube.js323
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;
-})()
-