diff --git a/client.py b/client.py index b8c1c70..eeb2410 100644 --- a/client.py +++ b/client.py @@ -221,7 +221,7 @@ class Server(object): self.address = address self.port = port self.snapshot = ctx.socket(zmq.DEALER) - self.snapshot.linger = 0 + self.snapshot = self.context.socket(zmq.DEALER) self.snapshot.setsockopt(zmq.IDENTITY, id) self.snapshot.connect("tcp://{}:{}".format(address.decode(), port)) self.subscriber = ctx.socket(zmq.SUB) diff --git a/replication.py b/replication.py index 452f3af..1ec8b2f 100644 --- a/replication.py +++ b/replication.py @@ -1,5 +1,4 @@ import logging -from .libs.dump_anything import dump_datablock from uuid import uuid4 try: from .libs import umsgpack @@ -19,13 +18,13 @@ class ReplicatedDataFactory(object): def __init__(self): self.supported_types = [] - def register_type(dtype, implementation): + def register_type(self,dtype, implementation): """ Register a new replicated datatype implementation """ types.append((supported_types, implementation)) - def match_type(data): + def match_type(self,data): for stypes, implementation in self.supported_types: if isinstance(data, stypes): return implementation @@ -33,8 +32,9 @@ class ReplicatedDataFactory(object): print("type not supported for replication") raise NotImplementedError - def construct(): - return + def construct(self,data): + implementation = self.match_type(data) + return implementation class ReplicatedDatablock(object): """ @@ -43,14 +43,13 @@ class ReplicatedDatablock(object): uuid = None # key (string) pointer = None # dcc data reference data = None # data blob (json) - deps = None + deps = None # dependencies references def __init__(self, owner=None, data=None): self.uuid = str(uuid4()) assert(owner) self.pointer = data - def load_serial(self): def push(self, socket): """ @@ -58,7 +57,12 @@ class ReplicatedDatablock(object): - serialize the data - send them as a multipart frame """ - pass + data = self.serialize(self.pointer) + assert(isinstance(data, bytes)) + + key = self.uuid.encode() + + socket.send_multipart([]) @classmethod def pull(cls, socket): @@ -82,65 +86,65 @@ class ReplicatedDatablock(object): dict[self.uuid] = self pass - def deserialize(self): + def deserialize(self,data): """ I want to apply changes into the DCC + + MUST RETURN AN OBJECT INSTANCE """ raise NotImplementedError - def serialize(self): + def serialize(self,data): """ I want to load data from DCC + + MUST RETURN A BYTE ARRAY """ raise NotImplementedError - -import bpy, mathutils -class BlenderTypesFactory(): - -class RepObject(ReplicatedDatablock): - def deserialize(self): - try: - if self.pointer is None: - pointer = None +# class RepObject(ReplicatedDatablock): +# def deserialize(self): +# try: +# if self.pointer is None: +# pointer = None - # Object specific constructor... - if self.data["data"] in bpy.data.meshes.keys(): - pointer = bpy.data.meshes[self.data["data"]] - elif self.data["data"] in bpy.data.lights.keys(): - pointer = bpy.data.lights[self.data["data"]] - elif self.data["data"] in bpy.data.cameras.keys(): - pointer = bpy.data.cameras[self.data["data"]] - elif self.data["data"] in bpy.data.curves.keys(): - pointer = bpy.data.curves[self.data["data"]] - elif self.data["data"] in bpy.data.armatures.keys(): - pointer = bpy.data.armatures[self.data["data"]] - elif self.data["data"] in bpy.data.grease_pencils.keys(): - pointer = bpy.data.grease_pencils[self.data["data"]] - elif self.data["data"] in bpy.data.curves.keys(): - pointer = bpy.data.curves[self.data["data"]] +# # Object specific constructor... +# if self.data["data"] in bpy.data.meshes.keys(): +# pointer = bpy.data.meshes[self.data["data"]] +# elif self.data["data"] in bpy.data.lights.keys(): +# pointer = bpy.data.lights[self.data["data"]] +# elif self.data["data"] in bpy.data.cameras.keys(): +# pointer = bpy.data.cameras[self.data["data"]] +# elif self.data["data"] in bpy.data.curves.keys(): +# pointer = bpy.data.curves[self.data["data"]] +# elif self.data["data"] in bpy.data.armatures.keys(): +# pointer = bpy.data.armatures[self.data["data"]] +# elif self.data["data"] in bpy.data.grease_pencils.keys(): +# pointer = bpy.data.grease_pencils[self.data["data"]] +# elif self.data["data"] in bpy.data.curves.keys(): +# pointer = bpy.data.curves[self.data["data"]] - self.pointer = bpy.data.objects.new(self.data["name"], pointer) +# self.pointer = bpy.data.objects.new(self.data["name"], pointer) - self.pointer.matrix_world = mathutils.Matrix(self.data["matrix_world"]) +# self.pointer.matrix_world = mathutils.Matrix(self.data["matrix_world"]) - self.pointer.id = self.data['id'] +# self.pointer.id = self.data['id'] - client = bpy.context.window_manager.session.username +# client = bpy.context.window_manager.session.username - if self.pointer.id == client or self.pointer.id == "Common": - self.pointer.hide_select = False - else: - self.pointer.hide_select = True +# if self.pointer.id == client or self.pointer.id == "Common": +# self.pointer.hide_select = False +# else: +# self.pointer.hide_select = True - except Exception as e: - logger.error("Object {} loading error: {} ".format(self.data["name"], e)) +# except Exception as e: +# logger.error("Object {} loading error: {} ".format(self.data["name"], e)) - def deserialize(self): - self.data = dump_datablock(self.pointer, 1) +# def deserialize(self): +# self.data = dump_datablock(self.pointer, 1) diff --git a/replication_client.py b/replication_client.py new file mode 100644 index 0000000..b78fdac --- /dev/null +++ b/replication_client.py @@ -0,0 +1,67 @@ +import threading +import logging +import zmq +import time + +logging.basicConfig(level=logging.DEBUG) +log = logging.getLogger(__name__) + +class Client(object): + def __init__(self): + self.rep_store = {} + self.net = ClientNetService(self.rep_store) + + def connect(self): + self.net.run() + + def stop(self): + self.net.stop() + +class ClientNetService(threading.Thread): + def __init__(self,store_reference=None): + # Threading + threading.Thread.__init__(self) + self.name = "NetLink" + self.daemon = True + self.exit_event = threading.Event() + + # Networking + self.context = zmq.Context.instance() + + self.snapshot = self.context.socket(zmq.DEALER) + self.snapshot.connect("tcp://127.0.0.1:5560") + + self.subscriber = self.context.socket(zmq.SUB) + self.subscriber.setsockopt_string(zmq.SUBSCRIBE, '') + self.subscriber.connect("tcp://127.0.0.1:5561") + self.subscriber.linger = 0 + + self.publish = self.context.socket(zmq.PULL) + self.publish.bind("tcp://*:5562") + + # For teststing purpose + + + def run(self): + log.debug("Running Net service") + + poller = zmq.Poller() + poller.register(self.snapshot, zmq.POLLIN) + poller.register(self.subscriber, zmq.POLLIN) + poller.register(self.publish, zmq.POLLOUT) + + while not self.exit_event.is_set(): + items = dict(poller.poll(10)) + + if not items: + log.error("No request ") + + + def stop(self): + self.exit_event.set() + + #Wait the end of the run + while self.exit_event.is_set(): + time.sleep(.1) + + diff --git a/test_replication.py b/test_replication.py index deab1d5..b390840 100644 --- a/test_replication.py +++ b/test_replication.py @@ -1,16 +1,56 @@ import unittest -import replication +from replication import ReplicatedDatablock, ReplicatedDataFactory +import umsgpack +import logging +from replication_client import Client + + +log = logging.getLogger(__name__) + +class SampleData(): + def __init__(self): + self.map = { + "sample":"data", + "sample":"data", + "sample":"data", + "sample":"data" + } + +class RepSampleData(ReplicatedDatablock): + def serialize(self,data): + import pickle + + return pickle.dumps(data) + + def deserialize(self,data): + import pickle + + return pickle.load(data) class TestData(unittest.TestCase): def setUp(self): self.map = {} - self.sample_data = replication.ReplicatedDatablock(owner="toto") + + self.client_api = Client() + def test_setup_data_factory(self): + factory = ReplicatedDataFactory() + factory.register_type(SampleData, RepSampleData) + + def test_run_client(self): + self.client_api.connect() + + def test_stop_client(self): + self.client_api.stop() + + def test_add_replicated_value(self): + pass def test_create_replicated_data(self): self.assertNotEqual(self.sample_data.uuid,None) - def test_push_replicated_data(self): - pass + + + if __name__ == '__main__': unittest.main() \ No newline at end of file