| @@ -194,6 +194,8 @@ class GraphState(object): | |||
| def layout(self): | |||
| """ Automatically lay out the graph """ | |||
| if self.order()==0: | |||
| return | |||
| g = self.to_networkx() | |||
| pos = nx.spring_layout(g, dim=3, scale=10) | |||
| average = lambda axis: sum(p[axis] | |||
| @@ -2,9 +2,23 @@ import requests | |||
| import abp, json | |||
| import time | |||
| client = abp.Client() | |||
| client = abp.Client(clear=True) | |||
| client.add_node(0) | |||
| time.sleep(2) | |||
| client.add_node(1) | |||
| client.add_node(99) | |||
| time.sleep(2) | |||
| client.act_local_rotation(0, 10) | |||
| client.act_local_rotation(1, 10) | |||
| client.act_local_rotation(99, 10) | |||
| client.act_cz(0, 1) | |||
| client.act_cz(0, 99) | |||
| client.act_cz(1, 99) | |||
| time.sleep(2) | |||
| for i in range(10): | |||
| client.add_node(i+10) | |||
| client.act_local_rotation(i+10, 10) | |||
| client.act_cz(0, i+10) | |||
| print client.get_state() | |||
| @@ -6,7 +6,7 @@ import abp | |||
| #TODO: only send deltas | |||
| #graphstate = abp.GraphState() | |||
| cache=SimpleCache() | |||
| cache = SimpleCache(default_timeout = 10000) | |||
| cache.set("state", abp.GraphState()) | |||
| app = Flask(__name__) | |||
| @@ -17,8 +17,13 @@ def index(): | |||
| @app.route("/state", methods = ["GET", "POST"]) | |||
| def state(): | |||
| if request.method == "GET": | |||
| return jsonify(cache.get("state").to_json()) | |||
| state = cache.get("state") | |||
| output = state.to_json() | |||
| output["update_required"] = cache.get("update") | |||
| cache.set("update", False) | |||
| return jsonify(output) | |||
| elif request.method == "POST": | |||
| cache.set("update", True) | |||
| graphstate = abp.GraphState() | |||
| graphstate.from_json(json.loads(request.data)) | |||
| cache.set("state", graphstate) | |||
| @@ -29,32 +34,42 @@ def add_node(node): | |||
| """ Add a node to the graph """ | |||
| graphstate = cache.get("state") | |||
| graphstate.add_node(node) | |||
| graphstate.layout() | |||
| cache.set("update", True) | |||
| cache.set("state", graphstate) | |||
| return jsonify({"add_node": "okay"}) | |||
| @app.route("/act_local_rotation/<int:node>/<int:operation>") | |||
| def act_local_rotation(node): | |||
| def act_local_rotation(node, operation): | |||
| """ Add a node to the graph """ | |||
| # TODO: try to lookup the operation first | |||
| graphstate = cache.get("state") | |||
| graphstate.act_local_rotation(node, operation) | |||
| cache.set("update", True) | |||
| cache.set("state", graphstate) | |||
| return jsonify({"act_local_rotation": "okay"}) | |||
| @app.route("/act_cz/<int:a>/<int:b>") | |||
| def act_cz(a, b): | |||
| """ Add a node to the graph """ | |||
| graphstate = cache.get("state") | |||
| graphstate.act_cz(a, b) | |||
| graphstate.layout() | |||
| cache.set("update", True) | |||
| cache.set("state", graphstate) | |||
| return jsonify({"act_cz": "okay"}) | |||
| @app.route("/clear") | |||
| def clear(): | |||
| """ Clear the current state """ | |||
| graphstate = abp.GraphState() | |||
| cache.set("update", True) | |||
| cache.set("state", graphstate) | |||
| return jsonify({"clear": "okay"}) | |||
| if __name__ == "__main__": | |||
| app.debug = False | |||
| app.debug = True | |||
| app.run(host="0.0.0.0") | |||
| @@ -45,7 +45,7 @@ function loopForever() { | |||
| function startMainLoop() { | |||
| scene = makeScene(); | |||
| controls.addEventListener("change", render); | |||
| //poll(); | |||
| poll(); | |||
| loopForever(); | |||
| } | |||
| @@ -75,7 +75,7 @@ function init() { | |||
| camera.position.set(0, 0, 20); | |||
| // Start polling | |||
| //setInterval(poll, 1000); | |||
| setInterval(poll, 500); | |||
| // Run | |||
| startMainLoop(); | |||
| @@ -1,2 +1,53 @@ | |||
| function poll() { | |||
| var xhr = new XMLHttpRequest(); | |||
| xhr.onload = function() { | |||
| var state = JSON.parse(xhr.responseText); | |||
| updateScene(state); | |||
| }; | |||
| xhr.onerror = function(e){ | |||
| //soft_console.innerHTML = "\n" + "Lost connection to server"; | |||
| }; | |||
| xhr.open("GET", "/state", true); | |||
| xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); | |||
| xhr.send(); | |||
| } | |||
| function updateScene(state) { | |||
| //if (state.update_required === false){return;} | |||
| var oldState = scene.getObjectByName("graphstate"); | |||
| scene.remove(oldState); | |||
| oldState = null; | |||
| var geometry = new THREE.Geometry(); | |||
| //nodeGeometry.labels = []; | |||
| //nodeGeometry.colors = []; | |||
| for (var i in state.nodes) { | |||
| var node = state.nodes[i]; | |||
| var pos = state.meta[i].pos; | |||
| var vertex = new THREE.Vector3(pos.x, pos.y, pos.z); | |||
| geometry.vertices.push(vertex); | |||
| //geometry.colors[i] = new THREE.Color(n.color); | |||
| //geometry.labels[i] = n.label; | |||
| } | |||
| var edges = new THREE.Object3D(); | |||
| for (i=0; i < state.edges.length; ++i) { | |||
| var edge = state.edges[i]; | |||
| var start = state.meta[edge[0]].pos; | |||
| var end = state.meta[edge[1]].pos; | |||
| var newEdge = makeEdge(start, end); | |||
| edges.add(newEdge); | |||
| } | |||
| var particles = new THREE.Points(geometry, materials.qubit); | |||
| var newState = new THREE.Object3D(); | |||
| newState.name = "graphstate"; | |||
| newState.add(particles); | |||
| newState.add(edges); | |||
| scene.add(newState); | |||
| render(); | |||
| } | |||