@@ -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(): | ||||