| @@ -11,6 +11,27 @@ cache = SimpleCache(default_timeout = 10000) | |||
| cache.set("state", abp.GraphState()) | |||
| app = Flask(__name__) | |||
| class InvalidUsage(Exception): | |||
| status_code = 400 | |||
| def __init__(self, message, status_code=None, payload=None): | |||
| Exception.__init__(self) | |||
| self.message = message | |||
| if status_code is not None: | |||
| self.status_code = status_code | |||
| self.payload = payload | |||
| def to_dict(self): | |||
| rv = dict(self.payload or ()) | |||
| rv['message'] = self.message | |||
| return rv | |||
| @app.errorhandler(InvalidUsage) | |||
| def handle_invalid_usage(error): | |||
| response = jsonify(error.to_dict()) | |||
| response.status_code = error.status_code | |||
| return response | |||
| @app.before_request | |||
| def before_request(): | |||
| g.state = cache.get("state") | |||
| @@ -40,6 +61,9 @@ def state(): | |||
| @app.route("/add_node/<int:node>") | |||
| def add_node(node): | |||
| """ Add a node to the graph """ | |||
| if node in g.state.vops: | |||
| raise InvalidUsage("Node {} is already in the graph".format(node)) | |||
| g.state.add_node(node) | |||
| g.state.layout() | |||
| cache.set("needs_update", True) | |||
| @@ -49,6 +73,11 @@ def add_node(node): | |||
| def act_local_rotation(node, operation): | |||
| """ Add a node to the graph """ | |||
| # TODO: try to lookup the operation first | |||
| if not node in g.state.vops: | |||
| raise InvalidUsage("Node {} does not exist".format(node)) | |||
| if not operation in range(24): | |||
| raise InvalidUsage("Invalid local rotation {}".format(operation)) | |||
| g.state.act_local_rotation(node, operation) | |||
| cache.set("needs_update", True) | |||
| return jsonify({"act_local_rotation": "okay"}) | |||
| @@ -56,6 +85,9 @@ def act_local_rotation(node, operation): | |||
| @app.route("/act_cz/<int:a>/<int:b>") | |||
| def act_cz(a, b): | |||
| """ Add a node to the graph """ | |||
| for node in (a, b): | |||
| if not node in g.state.vops: | |||
| raise InvalidUsage("Node {} does not exist".format(node)) | |||
| g.state.act_cz(a, b) | |||
| g.state.layout() | |||
| cache.set("needs_update", True) | |||
| @@ -1,24 +1,8 @@ | |||
| //TODO Move to THREE.gridhelper | |||
| // Make a grid | |||
| function makeGrid(side, n, color) { | |||
| var markers = new THREE.Object3D(); | |||
| var gridStyle = { | |||
| color: color, | |||
| transparent: true, | |||
| linewidth: 1, | |||
| opacity: 0.5 | |||
| }; | |||
| var material = new THREE.LineBasicMaterial(gridStyle); | |||
| for (var i = -n / 2; i <= n / 2; ++i) { | |||
| var geometry = new THREE.Geometry(); | |||
| geometry.vertices.push(new THREE.Vector3(side * i / n, -side / 2, 0)); | |||
| geometry.vertices.push(new THREE.Vector3(side * i / n, side / 2, 0)); | |||
| var line = new THREE.Line(geometry, material); | |||
| var line90 = line.clone(); | |||
| line90.rotation.z = Math.PI / 2; | |||
| markers.add(line); | |||
| markers.add(line90); | |||
| } | |||
| markers.name = "grid"; | |||
| return markers; | |||
| var grid = new THREE.GridHelper(20, 2); | |||
| grid.rotation.x = Math.PI/2; | |||
| grid.setColors(0xdddddd, 0xeeeeee); | |||
| return grid; | |||
| } | |||
| @@ -13,40 +13,24 @@ window.onload = init; | |||
| // Clear the whole scene | |||
| function makeScene() { | |||
| var myScene = new THREE.Scene(); | |||
| var grid1 = makeGrid(10, 10, "lightgray"); | |||
| grid1.position.z = -5; | |||
| myScene.add(grid1); | |||
| var grid2 = makeGrid(10, 10, "lightgray"); | |||
| grid2.rotation.x = Math.PI/2; | |||
| grid2.position.y = -5; | |||
| myScene.add(grid2); | |||
| var grid3 = makeGrid(10, 10, "lightgray"); | |||
| grid3.rotation.y = Math.PI/2; | |||
| grid3.position.x = -5; | |||
| myScene.add(grid3); | |||
| var grid = makeGrid(10, 10, "lightgray"); | |||
| myScene.add(grid); | |||
| return myScene; | |||
| } | |||
| // Render the current frame to the screen | |||
| function render() { | |||
| renderer.render(scene, camera); | |||
| } | |||
| // This is the main control loop | |||
| function loopForever() { | |||
| controls.update(); | |||
| requestAnimationFrame(loopForever); | |||
| requestAnimationFrame(function () { | |||
| renderer.render(scene, camera); | |||
| }); | |||
| } | |||
| // This just organises kickoff | |||
| function startMainLoop() { | |||
| scene = makeScene(); | |||
| controls.addEventListener("change", render); | |||
| poll(); | |||
| loopForever(); | |||
| } | |||
| // Someone resized the window | |||