Skip to content

Instantly share code, notes, and snippets.

@enjalot
Created May 22, 2013 18:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enjalot/5629913 to your computer and use it in GitHub Desktop.
Save enjalot/5629913 to your computer and use it in GitHub Desktop.
tributary interface prototype
{"description":"tributary interface prototype","endpoint":"","display":"div","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"thumbnail":"http://i.imgur.com/8PW9nvz.png"}
var T = {};
T.JSContext = function(frame, tributary) {
var context = function() {};
if(!tributary) tributary = {};
var code;
var parsed;
var dispatch = d3.dispatch("code", "execute", "execute:pre", "execute:error", "execute:post");
var parsers = [];
context.parse = function() {
//loop over the parsers
parsed = code;
for(var i = 0; i < parsers.length; i++) {
parsed = parsers[i](parsed);
}
}
context._execute = function() {
try {
frame.expose("initialize", parsed);
} catch (e) {
context["execute:error"](e);
}
try {
//call new Function
frame.call("initialize", tributary)
} catch (e) {
context["execute:error"](e);
}
context["execute:post"]();
};
//get/set tributary object, to share between contexts
context.tributary = function(_) {
if(arguments.length === 0) return tributary;
tributary = _;
frame.set("tributary", tributary);
return context;
};
context.frame = function(_) {
if(arguments.length === 0) return frame;
frame = _;
return context;
};
dispatch.on("code", function(newCode, silent) {
code = newCode;
if(silent) return;
//parse
context.parse();
//pre execute
context["execute:pre"]();
//
context.execute();
})
dispatch.on("execute.internal", function() {
console.log("internal js execute");
context._execute();
})
d3.rebind(context, dispatch, "on", "code", "execute", "execute:pre", "execute:error", "execute:post");
return context;
}
T.JSONContext = function(name, tributary) {
var context = function() {};
if(!tributary) tributary = {};
var code;
var parsed;
var dispatch = d3.dispatch("code", "execute", "execute:pre", "execute:error", "execute:post");
var parsers = [];
context.parse = function() {
//loop over the parsers
parsed = code;
for(var i = 0; i < parsers.length; i++) {
parsed = parsers[i](parsed);
}
}
context._execute = function() {
try {
json = JSON.parse(parsed);
tributary[name] = json;
} catch(e) {
context["execute:error"](e);
}
};
//get/set tributary object, to share between contexts
context.tributary = function(_) {
if(arguments.length === 0) return tributary;
tributary = _;
return context;
};
dispatch.on("code", function(newCode, silent) {
code = newCode;
//parse
context.parse();
if(silent) return;
//pre execute
context["execute:pre"]()
//execute
context.execute();
})
dispatch.on("execute.internal", function() {
console.log("internal json execute");
context._execute();
})
d3.rebind(context, dispatch, "on", "code", "execute", "execute:pre", "execute:error", "execute:post");
return context;
}
T.Display = function(frame, tributary) {
if(!tributary) tributary = {};
var display = function() {};
display.clear = function() {};
tributary.$el = {};
//create the html elements (svg/canvas/div) inside the frame
return display;
}
T.TimeControls = function(context, display) {
controls.parser = function(code) {
//hook up tributary.init and tributary.run
return code;
}
//context.addParser(controls.parser);
return controls;
}
T.Framer = function() {
var iframe;
var framer = function(el) {
iframe = document.createElement('iframe');
el.appendChild(iframe);
};
framer.set = function(name, obj) {
iframe.contentWindow[name] = obj;
}
framer.call = function(name, args) {
//TODO: check for array
if(Object.prototype.toString.call( args ) !== '[object Array]') args = [args];
iframe.contentWindow[name].apply(this, args);
}
framer.expose = function(name, code) {
//create's a new Function inside the frame
//and exposes it
var newCode = "window." + name + " = function(tributary) { " + code +"}";
var script = d3.select(iframe.contentDocument).select("head")
.selectAll("script." + name).data([0])
script.enter().append("script").classed(name, true);
script.text(newCode);
}
return framer;
}
// USAGE
//example where we have a js and json context
var frame = new T.Framer(); //creates an iframe for stuff to happen in
frame(d3.select("#display").node());
//we want our jscontext to execute inside a frame
var jscontext = new T.JSContext(frame);
var jsoncontext = new T.JSONContext("data", jscontext.tributary());
var display = new T.Display(frame);
//tie a display to our context
jscontext.on("execute:pre.display", function() {
console.log("pre execute: display");
display.clear();
})
jscontext.on("execute:pre.data", function() {
jsoncontext.execute();
})
//hook up time controls (this would be a plugin)
var time = new T.TimeControls(jscontext, display);
console.log("go!");
//this would come from model or code editor
jsoncontext.code('{ "y":10 }', true);
jscontext.code("var x = 5; console.log('hi', x, tributary.data)");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment