diff --git a/abp/graphstate.py b/abp/graphstate.py index 6ba08cc..a2de423 100644 --- a/abp/graphstate.py +++ b/abp/graphstate.py @@ -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] diff --git a/examples/client.py b/examples/client.py index b1bd33b..77a06e4 100644 --- a/examples/client.py +++ b/examples/client.py @@ -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() diff --git a/server/server.py b/server/server.py index 5635939..c3ca86b 100644 --- a/server/server.py +++ b/server/server.py @@ -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//") -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//") 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") diff --git a/server/static/main.js b/server/static/main.js index 9d9c06e..513cce5 100644 --- a/server/static/main.js +++ b/server/static/main.js @@ -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(); diff --git a/server/static/poll.js b/server/static/poll.js index 139597f..ff2f0fd 100644 --- a/server/static/poll.js +++ b/server/static/poll.js @@ -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(); +}