| @@ -0,0 +1,48 @@ | |||||
| import time, atexit, json | |||||
| import networkx | |||||
| import numpy as np | |||||
| import websocket | |||||
| from socket import error as socket_error | |||||
| import graphstate | |||||
| import util | |||||
| class GraphState(graphstate.GraphState, networkx.Graph): | |||||
| def __init__(self, *args, **kwargs): | |||||
| graphstate.GraphState.__init__(self, *args, **kwargs) | |||||
| self.connect_to_server() | |||||
| def connect_to_server(self, uri = "ws://localhost:5000"): | |||||
| """ Attempt to connect to the websocket server """ | |||||
| try: | |||||
| self.ws = websocket.create_connection(uri) | |||||
| atexit.register(self.shutdown) | |||||
| except socket_error: | |||||
| self.ws = None | |||||
| def shutdown(self): | |||||
| """ Close the connection to the websocket """ | |||||
| self.update() | |||||
| self.ws.close() | |||||
| def update(self, delay = 0.5): | |||||
| """ Call this function when you are ready to send data to the browser """ | |||||
| if not self.ws: | |||||
| return | |||||
| # Automatically perform layout if position is not provided | |||||
| if not all(("position" in node) for node in self.node.values()): | |||||
| self.layout() | |||||
| # Send data to browser and rate-limit | |||||
| self.ws.send(json.dumps(self.to_json())) | |||||
| time.sleep(delay) | |||||
| def layout(self, dim=3): | |||||
| """ Automatically lay out the graph """ | |||||
| pos = networkx.spring_layout(self, dim, scale=np.sqrt(self.order())) | |||||
| middle = np.average(pos.values(), axis=0) | |||||
| pos = {key: value - middle for key, value in pos.items()} | |||||
| for key, (x, y, z) in pos.items(): | |||||
| self.node[key]["position"] = util.xyz(x, y, z) | |||||
| @@ -3,27 +3,14 @@ Provides an extremely basic graph structure, based on neighbour lists | |||||
| """ | """ | ||||
| import itertools as it | import itertools as it | ||||
| import clifford | |||||
| import json | import json | ||||
| import qi | |||||
| try: | |||||
| from networkx import Graph as NXGraph | |||||
| except ImportError: | |||||
| NXGraph = object | |||||
| try: | |||||
| import websocket | |||||
| from socket import error as socket_error | |||||
| import time, atexit | |||||
| except ImportError: | |||||
| websocket = None | |||||
| class GraphState(NXGraph): | |||||
| def __init__(self, nodes=[], connect_to_server=True): | |||||
| import qi, clifford, util | |||||
| class GraphState(object): | |||||
| def __init__(self, nodes=[]): | |||||
| self.adj, self.node = {}, {} | self.adj, self.node = {}, {} | ||||
| self.add_nodes(nodes) | self.add_nodes(nodes) | ||||
| if connect_to_server: | |||||
| self.connect_to_server() | |||||
| def add_node(self, v, **kwargs): | def add_node(self, v, **kwargs): | ||||
| """ Add a node """ | """ Add a node """ | ||||
| @@ -206,27 +193,3 @@ class GraphState(NXGraph): | |||||
| """ Check equality between graphs """ | """ Check equality between graphs """ | ||||
| return self.adj == other.adj and self.node == other.node | return self.adj == other.adj and self.node == other.node | ||||
| def connect_to_server(self, uri = "ws://localhost:5000"): | |||||
| """ Attempt to connect to the websocket server """ | |||||
| if not websocket: | |||||
| return | |||||
| try: | |||||
| self.ws = websocket.create_connection(uri) | |||||
| atexit.register(self.shutdown) | |||||
| except socket_error: | |||||
| #print "Could not establish connection to server ({}).".format(uri) | |||||
| self.ws = None | |||||
| def shutdown(self): | |||||
| """ Close the connection to the websocket """ | |||||
| self.update() | |||||
| self.ws.close() | |||||
| def update(self, delay = 0.5): | |||||
| """ Call this function when you are ready to send data to the browser """ | |||||
| if not self.ws: | |||||
| return | |||||
| data = json.dumps(self.to_json()) | |||||
| self.ws.send(data) | |||||
| time.sleep(delay) | |||||
| @@ -1,4 +1,4 @@ | |||||
| from abp.graphstate import GraphState | |||||
| from abp.fancy import GraphState | |||||
| from abp.util import xyz | from abp.util import xyz | ||||
| import numpy as np | import numpy as np | ||||
| import time | import time | ||||
| @@ -1,8 +1,8 @@ | |||||
| from abp.viz import VisibleGraphState | |||||
| from abp.fancy import GraphState | |||||
| from abp.util import xyz | from abp.util import xyz | ||||
| from abp.clifford import * | from abp.clifford import * | ||||
| psi = VisibleGraphState() | |||||
| psi = GraphState() | |||||
| psi.add_node(0, position = xyz(0, 0)) | psi.add_node(0, position = xyz(0, 0)) | ||||
| psi.add_node(1, position = xyz(1, 1)) | psi.add_node(1, position = xyz(1, 1)) | ||||
| psi.add_node(2, position = xyz(3, 2)) | psi.add_node(2, position = xyz(3, 2)) | ||||
| @@ -0,0 +1,6 @@ | |||||
| from abp.fancy import GraphState | |||||
| g = GraphState() | |||||
| n = 10 | |||||
| g.add_nodes_from(range(n)) | |||||
| g.add_edges_from([i, i+1] for i in range(n-1)) | |||||
| @@ -0,0 +1,33 @@ | |||||
| from websocket_server import WebsocketServer | |||||
| import threading | |||||
| import abp | |||||
| import json | |||||
| clients = [] | |||||
| def new_message(client, server, message): | |||||
| decoded_message = json.loads(message) | |||||
| if "diff" in decoded_message: | |||||
| server.send_message_to_all(message) | |||||
| elif "method" in decoded_message: | |||||
| message = compute_diff(decoded_message) | |||||
| server.send_message_to_all(message) | |||||
| else: | |||||
| print "Could not interpret message" | |||||
| def new_client(client, server): | |||||
| print "Client {} connected.".format(client["id"]) | |||||
| clients.append(client) | |||||
| def client_left(client, server): | |||||
| print "Client {} disconnected.".format(client["id"]) | |||||
| clients.remove(client) | |||||
| if __name__ == '__main__': | |||||
| server = WebsocketServer(5001) | |||||
| server.set_fn_new_client(new_client) | |||||
| server.set_fn_message_received(new_message) | |||||
| server.set_fn_client_left(client_left) | |||||
| server.run_forever() | |||||
| @@ -1,4 +1,4 @@ | |||||
| from abp import GraphState | |||||
| from abp.fancy import GraphState | |||||
| from abp import qi | from abp import qi | ||||
| def test_local_comp(): | def test_local_comp(): | ||||