From f3be75ce3cce8dc3223c4718a443ed4852bdedf1 Mon Sep 17 00:00:00 2001 From: Swann Martinez <s.martinez@cubedns.fr> Date: Wed, 10 Apr 2019 18:01:55 +0200 Subject: [PATCH] feat: serialisation refactoring --- client.py | 25 +++++---- helpers.py | 145 ++++++++++++++++++++++++++++++++++++--------------- operators.py | 23 ++------ 3 files changed, 122 insertions(+), 71 deletions(-) diff --git a/client.py b/client.py index 656b9ad..b0a25b4 100644 --- a/client.py +++ b/client.py @@ -76,12 +76,12 @@ class RCFClient(object): self.pipe.send_multipart([b"CONNECT", (address.encode() if isinstance( address, str) else address), b'%d' % port]) - def set(self, key, value): + def set(self, key): """Set new value in distributed hash table Sends [SET][key][value] to the agent """ self.pipe.send_multipart( - [b"SET", umsgpack.packb(key), umsgpack.packb(value)]) + [b"SET", umsgpack.packb(key)]) def get(self, key): """Lookup value in distributed hash table @@ -161,14 +161,20 @@ class RCFClientAgent(object): logger.error("E: too many servers (max. %i)", SERVER_MAX) elif command == b"SET": - key, value = msg + key = umsgpack.unpackb(msg[0]) + value = None + + value = helpers.dump(key) + + if value: + logger.info(key,"dumped") + # Send key-value pair on to server + rcfmsg = message.RCFMessage(key=key, id=self.id, mtype="", body=value) - # Send key-value pair on to server - rcfmsg = message.RCFMessage(key=umsgpack.unpackb( - key), id=self.id, mtype="", body=umsgpack.unpackb(value)) - rcfmsg.store(self.property_map) - - rcfmsg.send(self.publisher) + rcfmsg.store(self.property_map) + rcfmsg.send(self.publisher) + else: + logger.error("Fail to dump ") elif command == b"GET": key = umsgpack.unpackb(msg[0]) @@ -223,6 +229,7 @@ def rcf_client_agent(ctx, pipe): rcfmsg.store(agent.property_map) elif agent.state == State.ACTIVE: if rcfmsg.id != agent.id: + helpers.load(rcfmsg.key,rcfmsg.body) rcfmsg.store(agent.property_map) action = "update" if rcfmsg.body else "delete" logging.info("I: received from {}:{},{} {}".format( diff --git a/helpers.py b/helpers.py index 814d49d..0149509 100644 --- a/helpers.py +++ b/helpers.py @@ -1,55 +1,56 @@ import bpy from .libs import dump_anything -def dump_datablock(datablock, depth): - if datablock: - print("sending {}".format(datablock.name)) +CORRESPONDANCE = {'Collection': 'collections', 'Mesh': 'meshes', 'Object': 'objects', 'Material': 'materials', + 'Texture': 'textures', 'Scene': 'scenes', 'Light': 'lights', 'Camera': 'cameras', 'Action': 'actions', 'Armature': 'armatures', 'GreasePencil': 'grease_pencils'} - dumper = dump_anything.Dumper() - dumper.type_subset = dumper.match_subset_all - dumper.depth = depth +# LOAD HELPERS - datablock_type = datablock.bl_rna.name - key = "{}/{}".format(datablock_type, datablock.name) - data = dumper.dump(datablock) +def load(key, value): + target = resolve_bpy_path(key) + target_type = target.__class__.__name__ + if target: + target.is_updating = True - client.push_update(key, datablock_type, data) + if target_type == 'Object': + load_object(target=target, data=value, + create=True) + elif target_type == 'Mesh': + load_mesh(target=target, data=value, + create=True) + elif target_type == 'Collection': + load_collection(target=target, data=value, + create=True) + elif target_type == 'Material': + load_material(target=target, data=value, + create=True) + elif target_type == 'Grease Pencil': + load_gpencil(target=target, data=value, + create=True) + elif target_type == 'Scene': + load_scene(target=target, data=value, + create=True) + elif 'Light' in target_type: + load_light(target=target, data=value, + create=True) + else: + load_default(target=target, data=value, + create=True, type=target_type) +def resolve_bpy_path(path): + """ + Get bpy property value from path + """ + item = None -def dump_datablock_attibute(datablock, attributes, depth=1): - if datablock: - dumper = dump_anything.Dumper() - dumper.type_subset = dumper.match_subset_all - dumper.depth = depth + try: + path = path.split('/') + item = getattr(bpy.data, CORRESPONDANCE[path[0]])[path[1]] - datablock_type = datablock.bl_rna.name - key = "{}/{}".format(datablock_type, datablock.name) - - data = {} - for attr in attributes: - try: - data[attr] = dumper.dump(getattr(datablock, attr)) - except: - pass - - client.push_update(key, datablock_type, data) - - -def upload_mesh(mesh): - if mesh.bl_rna.name == 'Mesh': - dump_datablock_attibute( - mesh, ['name', 'polygons', 'edges', 'vertices'], 6) - - -def upload_material(material): - if material.bl_rna.name == 'Material': - dump_datablock_attibute(material, ['name', 'node_tree'], 7) - - -def upload_gpencil(gpencil): - if gpencil.bl_rna.name == 'Grease Pencil': - dump_datablock_attibute(gpencil, ['name', 'layers','materials'], 9) + except: + pass + return item def load_mesh(target=None, data=None, create=False): import bmesh @@ -272,3 +273,63 @@ def load_default(target=None, data=None, create=False, type=None): dump_anything.load(target, data) except: print("default loading error") + +# DUMP HELPERS + +def dump(key): + target = resolve_bpy_path(key) + target_type = target.__class__.__name__ + data = None + + if target_type == 'Material': + data = dump_datablock_attibute(target, ['name', 'node_tree'], 7) + elif target_type == 'Grease Pencil': + data = dump_datablock_attibute(target, ['name', 'layers','materials'], 9) + elif target_type == 'Camera': + data = dump_datablock(target, 1) + elif target_type == 'Light': + data = dump_datablock(target, 1) + elif target_type == 'Mesh': + data = dump_datablock_attibute( + target, ['name', 'polygons', 'edges', 'vertices'], 6) + elif target_type == 'Object': + data = dump_datablock(target, 1) + elif target_type == 'Collection': + data = dump_datablock(target, 4) + elif target_type == 'Scene': + data = dump_datablock(target, 4) + + return data + + +def dump_datablock(datablock, depth): + if datablock: + dumper = dump_anything.Dumper() + dumper.type_subset = dumper.match_subset_all + dumper.depth = depth + + datablock_type = datablock.bl_rna.name + key = "{}/{}".format(datablock_type, datablock.name) + data = dumper.dump(datablock) + + return data + + +def dump_datablock_attibute(datablock, attributes, depth=1): + if datablock: + dumper = dump_anything.Dumper() + dumper.type_subset = dumper.match_subset_all + dumper.depth = depth + + datablock_type = datablock.bl_rna.name + key = "{}/{}".format(datablock_type, datablock.name) + + data = {} + for attr in attributes: + try: + data[attr] = dumper.dump(getattr(datablock, attr)) + except: + pass + + return data + diff --git a/operators.py b/operators.py index 31f8e25..410c0ca 100644 --- a/operators.py +++ b/operators.py @@ -53,8 +53,7 @@ SUPPORTED_DATABLOCKS = ['collections', 'meshes', 'objects', 'materials', 'textures', 'lights', 'cameras', 'actions', 'armatures', 'grease_pencils'] SUPPORTED_TYPES = ['Mesh', 'Grease Pencil', 'Material', 'Texture', 'Light', 'Camera', 'Object', 'Action', 'Armature','Collection', 'Scene'] -CORRESPONDANCE = {'Collection': 'collections', 'Mesh': 'meshes', 'Object': 'objects', 'Material': 'materials', - 'Texture': 'textures', 'Scene': 'scenes', 'Light': 'lights', 'Camera': 'cameras', 'Action': 'actions', 'Armature': 'armatures', 'GreasePencil': 'grease_pencils'} + # UTILITY FUNCTIONS @@ -78,22 +77,6 @@ def randomColor(): return [r, v, b] -def resolve_bpy_path(path): - """ - Get bpy property value from path - """ - item = None - - try: - path = path.split('/') - item = getattr(bpy.data, CORRESPONDANCE[path[0]])[path[1]] - - except: - pass - - return item - - def refresh_window(): import bpy bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1) @@ -443,8 +426,8 @@ class session_add_property(bpy.types.Operator): def execute(self, context): global client_instance - client_instance.set('key', 1) - print(client_instance.get('key')) + client_instance.set(self.property_path) + # print(client_instance.get('key')) # item = resolve_bpy_path(self.property_path) # print(item)