diff --git a/client.py b/client.py index 15788fc..cf8eb40 100644 --- a/client.py +++ b/client.py @@ -14,18 +14,18 @@ import zmq from . import helpers, message from .libs import dump_anything, umsgpack -lock = threading.Lock() -logger = logging.getLogger(__name__) -logging.basicConfig(level=logging.INFO) - - CONNECT_TIMEOUT = 2 +WATCH_FREQUENCY = 0.1 WAITING_TIME = 0.001 SERVER_MAX = 1 DUMP_AGENTS_NUMBER = 1 +lock = threading.Lock() +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) instance = None + class State(Enum): INITIAL = 1 SYNCING = 2 @@ -61,10 +61,10 @@ class Client(object): self.ctx = zmq.Context() self.pipe, peer = zpipe(self.ctx) self.store = {} - self.serial_product = queue.Queue() self.serial_feed = queue.Queue() self.stop_event = threading.Event() + # Net agent self.net_agent = threading.Thread( target=net_worker, @@ -83,7 +83,7 @@ class Client(object): # Sync agent self.watchdog_agent = threading.Thread( - target=watchdog_worker, args=(self.serial_feed, 0.2, self.stop_event), name="watchdog-agent") + target=watchdog_worker, args=(self.serial_feed,WATCH_FREQUENCY, self.stop_event), name="watchdog-agent") self.watchdog_agent.daemon = True self.watchdog_agent.start() @@ -147,7 +147,6 @@ class Client(object): self.serial_feed.put(('STOP', None, None)) # READ-ONLY FUNCTIONS - def get(self, key): """Lookup value in distributed hash table Sends [GET][key] to the agent and waits for a value response @@ -185,16 +184,24 @@ class Client(object): return dump_list def state(self): - if not self.is_busy(): - self.pipe.send_multipart([b"STATE"]) - try: - reply = self.pipe.recv_multipart() - except KeyboardInterrupt: - return - else: - return umsgpack.unpackb(reply[0]) + if self.net_agent is None or not self.net_agent.is_alive(): + return 1 #State.INITIAL + elif self.net_agent.is_alive() and self.store.keys(): + return 3 # State.ACTIVE else: - return None + return 2 #State.SYNCING + + # # return self.state + # if not self.is_busy(): + # self.pipe.send_multipart([b"STATE"]) + # try: + # reply = self.pipe.recv_multipart() + # except KeyboardInterrupt: + # return + # else: + # return umsgpack.unpackb(reply[0]) + # else: + # return None class Server(object): @@ -223,7 +230,7 @@ class ClientAgent(object): property_map = None publisher = None id = None - state = State.INITIAL + state = None server = None serial = None serialisation_agent = None diff --git a/helpers.py b/helpers.py index fac7e2c..4a47cbd 100644 --- a/helpers.py +++ b/helpers.py @@ -72,7 +72,7 @@ def load(key, value): target = resolve_bpy_path(key) target_type = key.split('/')[0] - logger.info("load {}".format(key)) + logger.debug("load {}".format(key)) if value == "None": return @@ -176,7 +176,7 @@ def load_armature(target=None, data=None, create=False): target_new_b = target.edit_bones.new[eb] dump_anything.load(target_new_b, data['bones'][eb]) - logger.info(eb) + logger.debug(eb) bpy.ops.object.mode_set(mode='OBJECT', toggle=False) fp.close() @@ -330,7 +330,7 @@ def load_collection(target=None, data=None, create=False): target.children.link( bpy.data.collections[collection]) else: - logger.info(target.name) + logger.debug(target.name) for collection in target.children.keys(): if collection not in data["children"]: @@ -371,14 +371,14 @@ def load_scene(target=None, data=None, create=False): # load collections # TODO: Recursive link - logger.info("check for scene childs") + logger.debug("check for scene childs") for collection in data["collection"]["children"]: logger.debug(collection) if collection not in target.collection.children.keys(): target.collection.children.link( bpy.data.collections[collection]) - logger.info("check for scene child to remove") + logger.debug("check for scene child to remove") for collection in target.collection.children.keys(): if collection not in data["collection"]["children"]: target.collection.children.unlink( diff --git a/operators.py b/operators.py index fdc9cdf..43e5133 100644 --- a/operators.py +++ b/operators.py @@ -18,14 +18,11 @@ from .libs import umsgpack logger = logging.getLogger(__name__) # client_instance = None -client_keys = None -client_state = 1 + server = None context = None - - def clean_scene(elements=helpers.BPY_TYPES.keys()): for datablock in elements: datablock_ref =getattr(bpy.data, helpers.BPY_TYPES[datablock]) @@ -84,21 +81,8 @@ def init_datablocks(): client.instance.set(key) -def refresh_session_data(): - global client_keys, client_state - - keys = client.instance.list() - - if keys: - client_keys = keys - state = client.instance.state() - - if state: - client_state = state - def default_tick(): - refresh_session_data() upload_client_instance_position() return .2 @@ -158,22 +142,6 @@ class SessionJoinOperator(bpy.types.Operator): return {"FINISHED"} -class SessionRefreshOperator(bpy.types.Operator): - bl_idname = "session.refresh" - bl_label = "refresh" - bl_description = "refresh client ui keys " - bl_options = {"REGISTER"} - - @classmethod - def poll(cls, context): - return True - - def execute(self, context): - refresh_session_data() - - return {"FINISHED"} - - class SessionPropertyAddOperator(bpy.types.Operator): bl_idname = "session.add_prop" bl_label = "add" @@ -279,7 +247,6 @@ class SessionStopOperator(bpy.types.Operator): def execute(self, context): global server - global client_keys, client_state net_settings = context.window_manager.session @@ -295,9 +262,8 @@ class SessionStopOperator(bpy.types.Operator): # del client_instance # client_instance = None - client_keys = None net_settings.is_admin = False - client_state = 1 + unregister_ticks() draw.renderer.stop() @@ -332,7 +298,6 @@ class SessionPropertyRightOperator(bpy.types.Operator): def execute(self, context): global server - global client_keys, client_state net_settings = context.window_manager.session @@ -380,7 +345,6 @@ class SessionSnapUserOperator(bpy.types.Operator): # TODO: Rename to match official blender convention classes = ( SessionJoinOperator, - SessionRefreshOperator, SessionPropertyAddOperator, SessionPropertyGetOperator, SessionStopOperator, @@ -392,8 +356,6 @@ classes = ( def is_replicated(update): - # global client_keys - # dickt = dict(client_keys) object_type = update.id.bl_rna.__class__.__name__ object_name = update.id.name @@ -409,7 +371,7 @@ def is_replicated(update): if client.instance.exist(key): return True else: - logger.info("{} Not rep".format(key)) + logger.debug("{} Not rep".format(key)) return False @@ -435,17 +397,14 @@ def toogle_update_dirty(context, update): data_ref = get_datablock_from_update(update,context) if data_ref: - logger.info(update.id.bl_rna.__class__.__name__) + logger.debug(update.id.bl_rna.__class__.__name__) data_ref.is_dirty= True def depsgraph_update(scene): - global client_keys - global client_state - ctx = bpy.context - if client_state == 3: + if client.instance.state() == 3: if ctx.mode in ['OBJECT','PAINT_GPENCIL']: updates = ctx.view_layer.depsgraph.updates @@ -496,7 +455,6 @@ def register(): def unregister(): global server - global client_keys draw.unregister() @@ -511,7 +469,6 @@ def unregister(): if client.instance: client.instance.exit() client.instance = None - del client_keys from bpy.utils import unregister_class for cls in reversed(classes): diff --git a/test.blend b/test.blend deleted file mode 100644 index 5bbeef7..0000000 Binary files a/test.blend and /dev/null differ diff --git a/ui.py b/ui.py index fccadb0..4ce6fb8 100644 --- a/ui.py +++ b/ui.py @@ -1,6 +1,6 @@ import bpy - -from . import client, operators +from . import client +from . import operators @@ -22,7 +22,7 @@ class SESSION_PT_settings(bpy.types.Panel): window_manager = context.window_manager row = layout.row() - if operators.client_state == 1: + if not client.instance or (client.instance and client.instance.state() == 1): row = layout.row() box = row.box() row = box.row() @@ -75,7 +75,7 @@ class SESSION_PT_settings(bpy.types.Panel): row.operator("session.join", text="CONNECT") else: - if operators.client_state == 3: + if client.instance.state() == 3: row = layout.row() row.operator("session.stop", icon='QUIT', text="Exit") @@ -107,7 +107,7 @@ class SESSION_PT_user(bpy.types.Panel): @classmethod def poll(cls, context): - return operators.client_state == 3 + return client.instance and client.instance.state() == 3 def draw(self, context): @@ -117,8 +117,9 @@ class SESSION_PT_user(bpy.types.Panel): scene = context.window_manager # Create a simple row. row = layout.row() - if operators.client_keys and len(operators.client_keys) > 0: - for key in operators.client_keys: + client_keys = client.instance.list() + if client_keys and len(client_keys) > 0: + for key in client_keys: if 'Client' in key[0]: info = "" item_box = row.box() @@ -152,7 +153,7 @@ class SESSION_PT_properties(bpy.types.Panel): @classmethod def poll(cls, context): - return operators.client_state == 3 + return client.instance and client.instance.state() == 3 def draw(self, context): layout = self.layout @@ -174,11 +175,10 @@ class SESSION_PT_properties(bpy.types.Panel): # Property area area_msg = row.box() - area_msg.operator("session.refresh", text="", - icon="UV_SYNC_SELECT") - if operators.client_keys and len(operators.client_keys) > 0: + client_keys = client.instance.list() + if client_keys and len(client_keys) > 0: - for item in sorted(operators.client_keys, key=get_client_key): + for item in sorted(client_keys, key=get_client_key): owner = 'toto' try: owner = item[1]