diff --git a/client.py b/client.py index 278b8d3..24ad19d 100644 --- a/client.py +++ b/client.py @@ -85,6 +85,14 @@ class RCFClient(object): self.pipe.send_multipart( [b"SET", umsgpack.packb(key), (umsgpack.packb(value) if value else umsgpack.packb('None'))]) + def add(self, key, value=None): + """Set new value in distributed hash table + Sends [SET][key][value] to the agent + """ + self.pipe.send_multipart( + [b"ADD", umsgpack.packb(key), (umsgpack.packb(value) if value else umsgpack.packb('None'))]) + + def get(self, key): """Lookup value in distributed hash table Sends [GET][key] to the agent and waits for a value response @@ -181,13 +189,30 @@ class RCFClientAgent(object): elif command == b"SET": key = umsgpack.unpackb(msg[0]) - value = None + value = umsgpack.unpackb(msg[1]) + if key in self.property_map.keys(): + if self.property_map[key].id == self.id: + if value == 'None': + value = helpers.dump(key) + + if value: + rcfmsg = message.RCFMessage( + key=key, id=self.id,uuid=value['uuid'], mtype="", body=value) + + rcfmsg.store(self.property_map) + rcfmsg.send(self.publisher) + else: + logger.error("Fail to dump ") + + elif command == b"ADD": + key = umsgpack.unpackb(msg[0]) value = umsgpack.unpackb(msg[1]) if value == 'None': + # try to dump from bpy value = helpers.dump(key) - + if value: rcfmsg = message.RCFMessage( key=key, id=self.id,uuid=value['uuid'], mtype="", body=value) @@ -268,30 +293,37 @@ def rcf_client_agent(ctx, pipe, queue): client_dict = helpers.init_client(key=client_key) client_store = message.RCFMessage( - key=client_key, id=agent.id.decode(), body=client_dict) + key=client_key, id=agent.id, body=client_dict) logger.info(client_store) - client_store.store(agent.property_map) - + client_store.store(agent.property_map, True) + client_store.send(agent.publisher) logger.info("snapshot complete") agent.state = State.ACTIVE else: helpers.load(rcfmsg.key, rcfmsg.body) + rcfmsg.store(agent.property_map) + logger.info("snapshot from {} stored".format(rcfmsg.id)) elif agent.state == State.ACTIVE: if rcfmsg.id != agent.id: # update_queue.put((rcfmsg.key,rcfmsg.body)) + with lock: helpers.load(rcfmsg.key, rcfmsg.body) - # logger.info("load") - # agent.serial.send_multipart([b"LOAD", umsgpack.packb(rcfmsg.key), umsgpack.packb(rcfmsg.body)]) - - # reply = agent.serial.recv_multipart() - - # if reply == b"DONE": rcfmsg.store(agent.property_map) - # action = "update" if rcfmsg.body else "delete" - # logging.info("{}: received from {}:{},{} {}".format(rcfmsg.key, - # server.address, rcfmsg.id, server.port, action)) + # elif rcfmsg.id == agent.property_map[rcfmsg.key].id: + # with lock: + # helpers.load(rcfmsg.key, rcfmsg.body) + # logger.info("load") + # agent.serial.send_multipart([b"LOAD", umsgpack.packb(rcfmsg.key), umsgpack.packb(rcfmsg.body)]) + + # reply = agent.serial.recv_multipart() + + # if reply == b"DONE": + # rcfmsg.store(agent.property_map) + # action = "update" if rcfmsg.body else "delete" + # logging.info("{}: received from {}:{},{} {}".format(rcfmsg.key, + # server.address, rcfmsg.id, server.port, action)) else: logger.debug("{} nothing to do".format(agent.id)) diff --git a/message.py b/message.py index 9bc0d42..ce282d4 100644 --- a/message.py +++ b/message.py @@ -37,11 +37,15 @@ class RCFMessage(object): def apply(self): pass - def store(self, dikt): + def store(self, dikt, override=False): """Store me in a dict if I have anything to store""" # this currently erasing old value - if self.key is not None: - dikt[self.key] = self + if self in dikt: + if override: + dikt[self.key] = self + else: + if self.key is not None: + dikt[self.key] = self # elif self.key in dikt: # del dikt[self.key] diff --git a/operators.py b/operators.py index d5ac8c5..4ac3881 100644 --- a/operators.py +++ b/operators.py @@ -142,7 +142,7 @@ def init_datablocks(): item.uuid = str(uuid4()) key = "{}/{}".format(datatype, item.name) print(key) - client_instance.set(key) + client_instance.add(key) def default_tick(): @@ -259,7 +259,7 @@ class session_add_property(bpy.types.Operator): def execute(self, context): global client_instance - client_instance.set(self.property_path) + client_instance.add(self.property_path) return {"FINISHED"} @@ -474,39 +474,42 @@ def depsgraph_update(scene): update_selected_object(bpy.context) selected_objects = helpers.get_selected_objects(scene) - if len(selected_objects) > 0: - for update in updates: - update_key = "{}/{}".format(update.id.bl_rna.name, update.id.name) - remote_update = client_instance.get(update_key) - - if remote_update and remote_update[0][1]["uuid"] == update.id.uuid: - print("{} sending update".format(username)) - client_instance.set( - "{}/{}".format(update.id.bl_rna.name, update.id.name)) - else: - print("{} applying update".format(username)) - # if is_dirty(updates): - # for update in ordered(updates): - # if update[2] == "Master Collection": - # pass - # elif update[1] in SUPPORTED_TYPES: - # client_instance.set("{}/{}".format(update[1], update[2])) - # if hasattr(bpy.context, 'selected_objects'): - # selected_objects = helpers.get_selected_objects(scene) + + # if len(selected_objects) > 0: - # for updated_data in updates: - # if updated_data.id.name in selected_objects: - # if updated_data.is_updated_transform or updated_data.is_updated_geometry: - # client_instance.set( - # "{}/{}".format(updated_data.id.bl_rna.name, updated_data.id.name)) + # for update in updates: + # update_key = "{}/{}".format(update.id.bl_rna.name, update.id.name) + # remote_update = client_instance.get(update_key) + + # if remote_update and remote_update[0][1]["uuid"] == update.id.uuid: + # print("{} sending update".format(username)) + # client_instance.set( + # "{}/{}".format(update.id.bl_rna.name, update.id.name)) + # else: + # print("{} applying update".format(username)) + + # if is_dirty(updates): + # for update in ordered(updates): + # if update[2] == "Master Collection": + # pass + # elif update[1] in SUPPORTED_TYPES: + # client_instance.set("{}/{}".format(update[1], update[2])) + + if hasattr(bpy.context, 'selected_objects'): + selected_objects = helpers.get_selected_objects(scene) + if len(selected_objects) > 0: + for updated_data in updates: + if updated_data.id.name in selected_objects: + if updated_data.is_updated_transform or updated_data.is_updated_geometry: + client_instance.set( + "{}/{}".format(updated_data.id.bl_rna.name, updated_data.id.name)) def register(): from bpy.utils import register_class for cls in classes: register_class(cls) - bpy.types.ID.is_dirty = bpy.props.BoolProperty(default=False) bpy.types.ID.uuid = bpy.props.StringProperty(default="None") bpy.types.Scene.session_settings = bpy.props.PointerProperty( type=session_settings) @@ -538,7 +541,6 @@ def unregister(): unregister_class(cls) del bpy.types.Scene.session_settings - del bpy.types.ID.is_dirty if __name__ == "__main__": diff --git a/ui.py b/ui.py index 2b6cfd9..75d8688 100644 --- a/ui.py +++ b/ui.py @@ -155,7 +155,11 @@ class SessionPropertiesPanel(bpy.types.Panel): icon="UV_SYNC_SELECT") if operators.client_keys and len(operators.client_keys) > 0: for item in operators.client_keys: - owner = item[1].decode() + owner = 'toto' + try: + owner = item[1].decode() + except: + pass item_box = area_msg.box() detail_item_box = item_box.row(align = True)