Last active
August 29, 2015 14:00
-
-
Save bananu7/11257792 to your computer and use it in GitHub Desktop.
This file contains 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
<!doctype html> | |
<html> | |
<head> | |
<title>Blocks Proof of Concept</title> | |
<style type="text/css"> | |
div.block { | |
background-color: #36C; | |
min-width: 200px; | |
height: 100px; | |
float: left; | |
padding: 10px; | |
text-align: center; | |
vertical-align: middle; | |
font-size: 3em; | |
position:absolute; | |
} | |
</style> | |
</head> | |
<body> | |
<pre id="output"></pre> | |
<div id="content"></div> | |
<script src="jquery-2.1.0.js" type="text/javascript"></script> | |
<script src="jquery-ui-1.10.4.min.js" type="text/javascript"></script> | |
<script src="jquery.jsPlumb-1.5.5-min.js" type="text/javascript"></script> | |
<!--script src="underscore-min.js" type="text/javascript"></script--> | |
<!--script src="traceur/traceur.js" type="text/javascript"></script> | |
<script src="traceur/bootstrap.js" type="text/javascript"></script--> | |
<!-- | |
<script src="https://traceur-compiler.googlecode.com/git/bin/traceur.js" | |
type="text/javascript"></script> | |
<script src="https://traceur-compiler.googlecode.com/git/src/bootstrap.js" | |
type="text/javascript"></script> | |
--> | |
<!--script> | |
//traceur.options.experimental = true; | |
</script--> | |
<script> | |
var exampleDropOptions = { | |
tolerance:"touch", | |
hoverClass:"dropHover", | |
activeClass:"dragActive", | |
connector: ["Bezier", { curviness:1 } ], | |
maxConnections:3, | |
endpoint:["Dot", { radius:11 }], | |
}; | |
function getEndpointColorFromType(type) { | |
switch (type) { | |
case "int" : return "#3399FF"; | |
case "string" : return "#FF9933"; | |
default: return "#999999"; | |
} | |
} | |
function createTypeEndpoint(type, isInput) { | |
var color = getEndpointColorFromType(type); | |
return { | |
paintStyle:{ fillStyle:color }, | |
scope: type, | |
connectorStyle:{ strokeStyle:color, lineWidth:6 }, | |
dropOptions : exampleDropOptions, | |
isSource: !isInput, | |
isTarget: isInput, | |
} | |
} | |
</script> | |
<script> | |
var print = function () { | |
var output = document.getElementById("output"); | |
return function (text) { | |
output.innerText = output.innerText + "\n" + String(text); | |
}; | |
}(); | |
var num = 1; | |
var objects = {}; | |
map = function (o, fn) { | |
var result = []; | |
for (var objectName in objects) { | |
var object = objects[objectName]; | |
result.push(fn(object)); | |
} | |
return result; | |
}; | |
function createInputBlock() { | |
var block = document.createElement('div'); | |
block.className = 'block'; | |
block.id = "inputBlock" + num; | |
document.getElementById("content").appendChild(block); | |
var input = document.createElement('input'); | |
block.appendChild(input); | |
// this starts propagating change | |
input.addEventListener("change", function () { | |
alert("running computations"); | |
run(block, true); | |
}, false); | |
// this just passes current value (and is used by input.change) | |
block.process = function () { | |
return this.value; | |
}.bind(input); | |
objects[block.id] = { | |
process: block.process, | |
id: block.id, | |
}; | |
jsPlumb.draggable(block); | |
var endpoint = createTypeEndpoint("string", false); | |
jsPlumb.addEndpoint(block, { anchor: [1, 0.5, 1, 0] }, endpoint); | |
} | |
function createOutputBlock() { | |
var block = document.createElement('div'); | |
block.className = 'block'; | |
block.id = "outputBlock" + num; | |
block.type = "outputBlock"; //temp | |
document.getElementById("content").appendChild(block); | |
var input = document.createElement('input'); | |
block.appendChild(input); | |
block.process = function (input) { | |
this.value = input; | |
}.bind(input); | |
objects[block.id] = { | |
process: block.process, | |
id: block.id, | |
}; | |
jsPlumb.draggable(block); | |
var endpoint = createTypeEndpoint("string", true); | |
jsPlumb.addEndpoint(block, { anchor: [0, 0.5, -1, 0] }, endpoint); | |
} | |
function createBlock(f) { | |
var block = document.createElement('div'); | |
block.className = 'block'; | |
block.textContent = f.name; | |
block.id = String(num++); | |
document.getElementById("content").appendChild(block); | |
jsPlumb.draggable(block); | |
block.process = f; | |
// todo: repetition | |
objects[block.id] = { | |
process: block.process, | |
id: block.id, | |
}; | |
f.signature.outs.forEach(function (elem, i) { | |
// this formula leaves space before first and after last element | |
var pos = (1.0 / (f.signature.outs.length + 1)) * (i + 1); | |
var endpoint = createTypeEndpoint(elem, false); | |
jsPlumb.addEndpoint(block, { anchor: [1, pos, 1, 0] }, endpoint); | |
}); | |
f.signature.ins.forEach(function (elem, i) { | |
// this formula leaves space before first and after last element | |
var pos = (1.0 / (f.signature.ins.length + 1)) * (i + 1); | |
var endpoint = createTypeEndpoint(elem, true); | |
jsPlumb.addEndpoint(block, { anchor: [0, pos, -1, 0] }, endpoint); | |
}); | |
} | |
function exportBlocks() { | |
var connections = jsPlumb.getAllConnections(); | |
var exportObjects = map(objects, function (object) { | |
var $position = $("#" + object.id).position(); | |
// "object" represents logical layer | |
// "block" part of it is the display/editor layer | |
object.block = { | |
position: { x: $position.left, y: $position.top }, | |
}; | |
return object; | |
}); | |
return { | |
connections: connections, | |
objects: exportObjects, | |
}; | |
} | |
// Usercode | |
function add(x, y) { | |
return x + y; | |
} | |
add.signature = { ins: ["int", "int"], outs: ["int"] }; | |
function mul(x, y) { | |
return x * y; | |
} | |
mul.signature = { ins: ["int", "int"], outs: ["int"] }; | |
function toUpper(str) { | |
return str; | |
} | |
toUpper.signature = { ins: ["string"], outs: ["string"] }; | |
function toInt(str) { | |
return parseInt(str, 10); | |
} | |
toInt.signature = { ins: ["string"], outs: ["int"] }; | |
function toString(num) { | |
return String(num); | |
} | |
toString.signature = { ins: ["int"], outs: ["string"] }; | |
// more like "poke" | |
function run(node, propagate) { | |
// todo: profile that vs select | |
var inputs = jsPlumb.getAllConnections().filter(function (conn) { return conn.target === node }); | |
var inputValues = inputs.map(function (input) { return run(input.source, false); }); | |
var outputValues = node.process.apply(null, inputValues); | |
if (node.type === "outputBlock") { | |
return; | |
} | |
if (propagate) { | |
var outputs = jsPlumb.select({ source: node.id }); | |
outputs.each(function (output) { run(output.target, true); }); | |
} | |
else { | |
return outputValues; | |
} | |
} | |
$(function () { | |
createInputBlock(); | |
createBlock(add); | |
createBlock(mul); | |
createBlock(toInt); | |
createBlock(toString); | |
createOutputBlock(); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment