diff --git a/docs/getting_started/quickstart.rst b/docs/getting_started/quickstart.rst index d81eff1..c3092e7 100644 --- a/docs/getting_started/quickstart.rst +++ b/docs/getting_started/quickstart.rst @@ -374,15 +374,6 @@ Network Advanced network settings -**IPC Port** is the port used for Inter Process Communication. This port is used -by the multi-user subprocesses to communicate with each other. If different instances -of multi-user are using the same IPC port, this will create conflict ! - -.. note:: - You only need to modify this setting if you need to launch multiple clients from the same - computer (or if you try to host and join from the same computer). To resolve this, you simply need to enter a different - **IPC port** for each blender instance. - **Timeout (in milliseconds)** is the maximum ping authorized before auto-disconnecting. You should only increase it if you have a bad connection. diff --git a/multi_user/__init__.py b/multi_user/__init__.py index 93e2f5c..9fe912e 100644 --- a/multi_user/__init__.py +++ b/multi_user/__init__.py @@ -19,7 +19,7 @@ bl_info = { "name": "Multi-User", "author": "Swann Martinez", - "version": (0, 3, 0), + "version": (0, 4, 0), "description": "Enable real-time collaborative workflow inside blender", "blender": (2, 82, 0), "location": "3D View > Sidebar > Multi-User tab", @@ -44,7 +44,7 @@ from . import environment DEPENDENCIES = { - ("replication", '0.1.26'), + ("replication", '0.1.33'), } diff --git a/multi_user/bl_types/__init__.py b/multi_user/bl_types/__init__.py index e71adfb..0aa2e8d 100644 --- a/multi_user/bl_types/__init__.py +++ b/multi_user/bl_types/__init__.py @@ -49,7 +49,7 @@ if bpy.app.version[1] >= 91: __all__.append('bl_volume') from . import * -from replication.data import ReplicatedDataFactory +from replication.data import DataTranslationProtocol def types_to_register(): return __all__ diff --git a/multi_user/bl_types/bl_file.py b/multi_user/bl_types/bl_file.py index 120048d..26400c3 100644 --- a/multi_user/bl_types/bl_file.py +++ b/multi_user/bl_types/bl_file.py @@ -134,6 +134,8 @@ class BlFile(ReplicatedDatablock): if self.preferences.clear_memory_filecache: return False else: + if not self.instance: + return False memory_size = sys.getsizeof(self.data['file'])-33 disk_size = self.instance.stat().st_size return memory_size != disk_size diff --git a/multi_user/bl_types/bl_image.py b/multi_user/bl_types/bl_image.py index 3a248c6..901a201 100644 --- a/multi_user/bl_types/bl_image.py +++ b/multi_user/bl_types/bl_image.py @@ -66,7 +66,7 @@ class BlImage(BlDatablock): loader = Loader() loader.load(data, target) - target.source = data['source'] + target.source = 'FILE' target.filepath_raw = get_filepath(data['filename']) color_space_name = data["colorspace_settings"]["name"] @@ -86,7 +86,7 @@ class BlImage(BlDatablock): dumper.depth = 2 dumper.include_filter = [ "name", - 'source', + # 'source', 'size', 'height', 'alpha', diff --git a/multi_user/bl_types/bl_scene.py b/multi_user/bl_types/bl_scene.py index 08a3d69..aef762a 100644 --- a/multi_user/bl_types/bl_scene.py +++ b/multi_user/bl_types/bl_scene.py @@ -368,6 +368,8 @@ def load_sequence(sequence_data: dict, sequence_editor: bpy.types.SequenceEditor class BlScene(BlDatablock): + is_root = True + bl_id = "scenes" bl_class = bpy.types.Scene bl_check_common = True diff --git a/multi_user/operators.py b/multi_user/operators.py index 981c7df..8afce01 100644 --- a/multi_user/operators.py +++ b/multi_user/operators.py @@ -32,6 +32,7 @@ from operator import itemgetter from pathlib import Path from queue import Queue from time import gmtime, strftime +import traceback try: import _pickle as pickle @@ -44,9 +45,11 @@ from bpy.app.handlers import persistent from bpy_extras.io_utils import ExportHelper, ImportHelper from replication.constants import (COMMITED, FETCHED, RP_COMMON, STATE_ACTIVE, STATE_INITIAL, STATE_SYNCING, UP) -from replication.data import ReplicatedDataFactory -from replication.exception import NonAuthorizedOperationError, ContextError +from replication.data import DataTranslationProtocol +from replication.exception import ContextError, NonAuthorizedOperationError from replication.interface import session +from replication.porcelain import add, apply +from replication.repository import Repository from . import bl_types, environment, timers, ui, utils from .presence import SessionStatusWidget, renderer, view3d_find @@ -80,8 +83,8 @@ def initialize_session(): # Step 1: Constrect nodes logging.info("Constructing nodes") - for node in session._graph.list_ordered(): - node_ref = session.get(uuid=node) + for node in session.repository.list_ordered(): + node_ref = session.repository.get_node(node) if node_ref is None: logging.error(f"Can't construct node {node}") elif node_ref.state == FETCHED: @@ -89,8 +92,8 @@ def initialize_session(): # Step 2: Load nodes logging.info("Loading nodes") - for node in session._graph.list_ordered(): - node_ref = session.get(uuid=node) + for node in session.repository.list_ordered(): + node_ref = session.repository.get_node(node) if node_ref is None: logging.error(f"Can't load node {node}") @@ -186,7 +189,7 @@ class SessionStartOperator(bpy.types.Operator): handler.setFormatter(formatter) - bpy_factory = ReplicatedDataFactory() + bpy_protocol = DataTranslationProtocol() supported_bl_types = [] # init the factory with supported types @@ -205,7 +208,7 @@ class SessionStartOperator(bpy.types.Operator): type_local_config = settings.supported_datablocks[type_impl_name] - bpy_factory.register_type( + bpy_protocol.register_type( type_module_class.bl_class, type_module_class, check_common=type_module_class.bl_check_common) @@ -215,10 +218,7 @@ class SessionStartOperator(bpy.types.Operator): else: python_binary_path = bpy.app.binary_path_python - session.configure( - factory=bpy_factory, - python_path=python_binary_path, - external_update_handling=True) + repo = Repository(data_protocol=bpy_protocol) # Host a session if self.host: @@ -229,13 +229,14 @@ class SessionStartOperator(bpy.types.Operator): runtime_settings.internet_ip = environment.get_ip() try: + # Init repository for scene in bpy.data.scenes: - session.add(scene) + add(repo, scene) session.host( + repository= repo, id=settings.username, port=settings.port, - ipc_port=settings.ipc_port, timeout=settings.connection_timeout, password=admin_pass, cache_directory=settings.cache_directory, @@ -245,7 +246,6 @@ class SessionStartOperator(bpy.types.Operator): except Exception as e: self.report({'ERROR'}, repr(e)) logging.error(f"Error: {e}") - import traceback traceback.print_exc() # Join a session else: @@ -256,10 +256,10 @@ class SessionStartOperator(bpy.types.Operator): try: session.connect( + repository= repo, id=settings.username, address=settings.ip, port=settings.port, - ipc_port=settings.ipc_port, timeout=settings.connection_timeout, password=admin_pass ) @@ -279,7 +279,9 @@ class SessionStartOperator(bpy.types.Operator): session_user_sync = timers.SessionUserSync() session_background_executor = timers.MainThreadExecutor( execution_queue=background_execution_queue) + session_listen = timers.SessionListenTimer(timeout=0.001) + session_listen.register() session_update.register() session_user_sync.register() session_background_executor.register() @@ -287,7 +289,7 @@ class SessionStartOperator(bpy.types.Operator): deleyables.append(session_background_executor) deleyables.append(session_update) deleyables.append(session_user_sync) - + deleyables.append(session_listen) self.report( @@ -328,7 +330,7 @@ class SessionInitOperator(bpy.types.Operator): utils.clean_scene() for scene in bpy.data.scenes: - session.add(scene) + add(session.repository, scene) session.init() @@ -350,7 +352,7 @@ class SessionStopOperator(bpy.types.Operator): if session: try: - session.disconnect() + session.disconnect(reason='user') except Exception as e: self.report({'ERROR'}, repr(e)) @@ -599,17 +601,22 @@ class SessionApply(bpy.types.Operator): def execute(self, context): logging.debug(f"Running apply on {self.target}") try: - node_ref = session.get(uuid=self.target) - session.apply(self.target, - force=True, - force_dependencies=self.reset_dependencies) + node_ref = session.repository.get_node(self.target) + apply(session.repository, + self.target, + force=True, + force_dependencies=self.reset_dependencies) if node_ref.bl_reload_parent: - for parent in session._graph.find_parents(self.target): + for parent in session.repository.get_parents(self.target): logging.debug(f"Refresh parent {parent}") - session.apply(parent, force=True) + + apply(session.repository, + parent.uuid, + force=True) except Exception as e: self.report({'ERROR'}, repr(e)) - return {"CANCELED"} + traceback.print_exc() + return {"CANCELLED"} return {"FINISHED"} @@ -649,15 +656,15 @@ class ApplyArmatureOperator(bpy.types.Operator): return {'CANCELLED'} if event.type == 'TIMER': - if session and session.state['STATE'] == STATE_ACTIVE: + if session and session.state == STATE_ACTIVE: nodes = session.list(filter=bl_types.bl_armature.BlArmature) for node in nodes: - node_ref = session.get(uuid=node) + node_ref = session.repository.get_node(node) if node_ref.state == FETCHED: try: - session.apply(node) + apply(session.repository, node) except Exception as e: logging.error("Fail to apply armature: {e}") @@ -794,7 +801,7 @@ class SessionSaveBackupOperator(bpy.types.Operator, ExportHelper): @classmethod def poll(cls, context): - return session.state['STATE'] == STATE_ACTIVE + return session.state == STATE_ACTIVE class SessionStopAutoSaveOperator(bpy.types.Operator): bl_idname = "session.cancel_autosave" @@ -803,7 +810,7 @@ class SessionStopAutoSaveOperator(bpy.types.Operator): @classmethod def poll(cls, context): - return (session.state['STATE'] == STATE_ACTIVE and 'SessionBackupTimer' in registry) + return (session.state == STATE_ACTIVE and 'SessionBackupTimer' in registry) def execute(self, context): autosave_timer = registry.get('SessionBackupTimer') @@ -828,7 +835,7 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper): ) def execute(self, context): - from replication.graph import ReplicationGraph + from replication.repository import Repository # TODO: add filechecks @@ -848,7 +855,7 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper): # init the factory with supported types - bpy_factory = ReplicatedDataFactory() + bpy_protocol = DataTranslationProtocol() for type in bl_types.types_to_register(): type_module = getattr(bl_types, type) name = [e.capitalize() for e in type.split('_')[1:]] @@ -856,16 +863,16 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper): type_module_class = getattr(type_module, type_impl_name) - bpy_factory.register_type( + bpy_protocol.register_type( type_module_class.bl_class, type_module_class) - graph = ReplicationGraph() + graph = Repository() for node, node_data in nodes: node_type = node_data.get('str_type') - impl = bpy_factory.get_implementation_from_net(node_type) + impl = bpy_protocol.get_implementation_from_net(node_type) if impl: logging.info(f"Loading {node}") @@ -873,7 +880,7 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper): uuid=node, dependencies=node_data['dependencies'], data=node_data['data']) - instance.store(graph) + graph.do_commit(instance) instance.state = FETCHED logging.info("Graph succefully loaded") @@ -922,7 +929,7 @@ classes = ( def update_external_dependencies(): nodes_ids = session.list(filter=bl_types.bl_file.BlFile) for node_id in nodes_ids: - node = session.get(node_id) + node = session.repository.get_node(node_id) if node and node.owner in [session.id, RP_COMMON] \ and node.has_changed(): session.commit(node_id) @@ -931,11 +938,11 @@ def update_external_dependencies(): def sanitize_deps_graph(remove_nodes: bool = False): """ Cleanup the replication graph """ - if session and session.state['STATE'] == STATE_ACTIVE: + if session and session.state == STATE_ACTIVE: start = utils.current_milli_time() rm_cpt = 0 for node_key in session.list(): - node = session.get(node_key) + node = session.repository.get_node(node_key) if node is None \ or (node.state == UP and not node.resolve(construct=False)): if remove_nodes: @@ -956,18 +963,18 @@ def resolve_deps_graph(dummy): A future solution should be to avoid storing dataclock reference... """ - if session and session.state['STATE'] == STATE_ACTIVE: + if session and session.state == STATE_ACTIVE: sanitize_deps_graph(remove_nodes=True) @persistent def load_pre_handler(dummy): - if session and session.state['STATE'] in [STATE_ACTIVE, STATE_SYNCING]: + if session and session.state in [STATE_ACTIVE, STATE_SYNCING]: bpy.ops.session.stop() @persistent def update_client_frame(scene): - if session and session.state['STATE'] == STATE_ACTIVE: + if session and session.state == STATE_ACTIVE: session.update_user_metadata({ 'frame_current': scene.frame_current }) @@ -975,7 +982,7 @@ def update_client_frame(scene): @persistent def depsgraph_evaluation(scene): - if session and session.state['STATE'] == STATE_ACTIVE: + if session and session.state == STATE_ACTIVE: context = bpy.context blender_depsgraph = bpy.context.view_layer.depsgraph dependency_updates = [u for u in blender_depsgraph.updates] @@ -988,7 +995,7 @@ def depsgraph_evaluation(scene): # Is the object tracked ? if update.id.uuid: # Retrieve local version - node = session.get(uuid=update.id.uuid) + node = session.repository.get_node(update.id.uuid) # Check our right on this update: # - if its ours or ( under common and diff), launch the @@ -1012,11 +1019,11 @@ def depsgraph_evaluation(scene): continue # A new scene is created elif isinstance(update.id, bpy.types.Scene): - ref = session.get(reference=update.id) + ref = session.repository.get_node_by_datablock(update.id) if ref: ref.resolve() else: - scn_uuid = session.add(update.id) + scn_uuid = add(session.repository, update.id) session.commit(scn_uuid) session.push(scn_uuid, check_data=False) def register(): @@ -1034,7 +1041,7 @@ def register(): def unregister(): - if session and session.state['STATE'] == STATE_ACTIVE: + if session and session.state == STATE_ACTIVE: session.disconnect() from bpy.utils import unregister_class diff --git a/multi_user/preferences.py b/multi_user/preferences.py index 790af67..7ebc2a8 100644 --- a/multi_user/preferences.py +++ b/multi_user/preferences.py @@ -66,14 +66,6 @@ def update_ip(self, context): self['ip'] = "127.0.0.1" -def update_port(self, context): - max_port = self.port + 3 - - if self.ipc_port < max_port and \ - self['ipc_port'] >= self.port: - logging.error( - "IPC Port in conflict with the port, assigning a random value") - self['ipc_port'] = random.randrange(self.port+4, 10000) def update_directory(self, context): @@ -174,12 +166,6 @@ class SessionPrefs(bpy.types.AddonPreferences): supported_datablocks: bpy.props.CollectionProperty( type=ReplicatedDatablock, ) - ipc_port: bpy.props.IntProperty( - name="ipc_port", - description='internal ttl port(only useful for multiple local instances)', - default=random.randrange(5570, 70000), - update=update_port, - ) init_method: bpy.props.EnumProperty( name='init_method', description='Init repo', diff --git a/multi_user/presence.py b/multi_user/presence.py index 4776e03..30b10d2 100644 --- a/multi_user/presence.py +++ b/multi_user/presence.py @@ -30,7 +30,7 @@ import mathutils from bpy_extras import view3d_utils from gpu_extras.batch import batch_for_shader from replication.constants import (STATE_ACTIVE, STATE_AUTH, STATE_CONFIG, - STATE_INITIAL, STATE_LAUNCHING_SERVICES, + STATE_INITIAL, CONNECTING, STATE_LOBBY, STATE_QUITTING, STATE_SRV_SYNC, STATE_SYNCING, STATE_WAITING) from replication.interface import session @@ -399,7 +399,7 @@ class SessionStatusWidget(Widget): text_scale = self.preferences.presence_hud_scale ui_scale = bpy.context.preferences.view.ui_scale color = [1, 1, 0, 1] - state = session.state.get('STATE') + state = session.state state_str = f"{get_state_str(state)}" if state == STATE_ACTIVE: diff --git a/multi_user/timers.py b/multi_user/timers.py index 1e6c64d..c184b4c 100644 --- a/multi_user/timers.py +++ b/multi_user/timers.py @@ -24,6 +24,7 @@ from replication.constants import (FETCHED, RP_COMMON, STATE_ACTIVE, STATE_SRV_SYNC, STATE_SYNCING, UP) from replication.exception import NonAuthorizedOperationError, ContextError from replication.interface import session +from replication.porcelain import apply, add from . import operators, utils from .presence import (UserFrustumWidget, UserNameWidget, UserSelectionWidget, @@ -71,7 +72,7 @@ class Timer(object): except Exception as e: logging.error(e) self.unregister() - session.disconnect() + session.disconnect(reason=f"Error during timer {self.id} execution") else: if self.is_running: return self._timeout @@ -100,25 +101,31 @@ class SessionBackupTimer(Timer): def execute(self): session.save(self._filepath) +class SessionListenTimer(Timer): + def execute(self): + session.listen() + class ApplyTimer(Timer): def execute(self): - if session and session.state['STATE'] == STATE_ACTIVE: + if session and session.state == STATE_ACTIVE: nodes = session.list() for node in nodes: - node_ref = session.get(uuid=node) + node_ref = session.repository.get_node(node) if node_ref.state == FETCHED: try: - session.apply(node) + apply(session.repository, node) except Exception as e: logging.error(f"Fail to apply {node_ref.uuid}") traceback.print_exc() else: if node_ref.bl_reload_parent: - for parent in session._graph.find_parents(node): + for parent in session.repository.get_parents(node): logging.debug("Refresh parent {node}") - session.apply(parent, force=True) + apply(session.repository, + parent.uuid, + force=True) class DynamicRightSelectTimer(Timer): @@ -131,7 +138,7 @@ class DynamicRightSelectTimer(Timer): def execute(self): settings = utils.get_preferences() - if session and session.state['STATE'] == STATE_ACTIVE: + if session and session.state == STATE_ACTIVE: # Find user if self._user is None: self._user = session.online_users.get(settings.username) @@ -145,7 +152,7 @@ class DynamicRightSelectTimer(Timer): # if an annotation exist and is tracked if annotation_gp and annotation_gp.uuid: - registered_gp = session.get(uuid=annotation_gp.uuid) + registered_gp = session.repository.get_node(annotation_gp.uuid) if is_annotating(bpy.context): # try to get the right on it if registered_gp.owner == RP_COMMON: @@ -159,7 +166,7 @@ class DynamicRightSelectTimer(Timer): affect_dependencies=False) if registered_gp.owner == settings.username: - gp_node = session.get(uuid=annotation_gp.uuid) + gp_node = session.repository.get_node(annotation_gp.uuid) if gp_node.has_changed(): session.commit(gp_node.uuid) session.push(gp_node.uuid, check_data=False) @@ -183,7 +190,7 @@ class DynamicRightSelectTimer(Timer): # change old selection right to common for obj in obj_common: - node = session.get(uuid=obj) + node = session.repository.get_node(obj) if node and (node.owner == settings.username or node.owner == RP_COMMON): recursive = True @@ -201,7 +208,7 @@ class DynamicRightSelectTimer(Timer): # change new selection to our for obj in obj_ours: - node = session.get(uuid=obj) + node = session.repository.get_node(obj) if node and node.owner == RP_COMMON: recursive = True @@ -234,7 +241,7 @@ class DynamicRightSelectTimer(Timer): owned_keys = session.list( filter_owner=settings.username) for key in owned_keys: - node = session.get(uuid=key) + node = session.repository.get_node(key) try: session.change_owner( key, @@ -263,7 +270,7 @@ class ClientUpdate(Timer): settings = utils.get_preferences() if session and renderer: - if session.state['STATE'] in [STATE_ACTIVE, STATE_LOBBY]: + if session.state in [STATE_ACTIVE, STATE_LOBBY]: local_user = session.online_users.get( settings.username) diff --git a/multi_user/ui.py b/multi_user/ui.py index b8f423b..df5ae13 100644 --- a/multi_user/ui.py +++ b/multi_user/ui.py @@ -26,7 +26,7 @@ from replication.constants import (ADDED, ERROR, FETCHED, STATE_INITIAL, STATE_SRV_SYNC, STATE_WAITING, STATE_QUITTING, STATE_LOBBY, - STATE_LAUNCHING_SERVICES) + CONNECTING) from replication import __version__ from replication.interface import session from .timers import registry @@ -71,9 +71,9 @@ class SESSION_PT_settings(bpy.types.Panel): def draw_header(self, context): layout = self.layout - if session and session.state['STATE'] != STATE_INITIAL: + if session and session.state != STATE_INITIAL: cli_state = session.state - state = session.state.get('STATE') + state = session.state connection_icon = "KEYTYPE_MOVING_HOLD_VEC" if state == STATE_ACTIVE: @@ -81,7 +81,7 @@ class SESSION_PT_settings(bpy.types.Panel): else: connection_icon = 'PROP_CON' - layout.label(text=f"Session - {get_state_str(cli_state['STATE'])}", icon=connection_icon) + layout.label(text=f"Session - {get_state_str(cli_state)}", icon=connection_icon) else: layout.label(text=f"Session - v{__version__}",icon="PROP_OFF") @@ -94,13 +94,13 @@ class SESSION_PT_settings(bpy.types.Panel): if hasattr(context.window_manager, 'session'): # STATE INITIAL if not session \ - or (session and session.state['STATE'] == STATE_INITIAL): + or (session and session.state == STATE_INITIAL): pass else: - cli_state = session.state + progress = session.state_progress row = layout.row() - current_state = cli_state['STATE'] + current_state = session.state info_msg = None if current_state in [STATE_ACTIVE]: @@ -124,8 +124,8 @@ class SESSION_PT_settings(bpy.types.Panel): if current_state in [STATE_SYNCING, STATE_SRV_SYNC, STATE_WAITING]: info_box = row.box() info_box.row().label(text=printProgressBar( - cli_state['CURRENT'], - cli_state['TOTAL'], + progress['current'], + progress['total'], length=16 )) @@ -141,7 +141,7 @@ class SESSION_PT_settings_network(bpy.types.Panel): @classmethod def poll(cls, context): return not session \ - or (session and session.state['STATE'] == 0) + or (session and session.state == 0) def draw_header(self, context): self.layout.label(text="", icon='URL') @@ -199,7 +199,7 @@ class SESSION_PT_settings_user(bpy.types.Panel): @classmethod def poll(cls, context): return not session \ - or (session and session.state['STATE'] == 0) + or (session and session.state == 0) def draw_header(self, context): self.layout.label(text="", icon='USER') @@ -230,7 +230,7 @@ class SESSION_PT_advanced_settings(bpy.types.Panel): @classmethod def poll(cls, context): return not session \ - or (session and session.state['STATE'] == 0) + or (session and session.state == 0) def draw_header(self, context): self.layout.label(text="", icon='PREFERENCES') @@ -251,9 +251,6 @@ class SESSION_PT_advanced_settings(bpy.types.Panel): emboss=False) if settings.sidebar_advanced_net_expanded: - net_section_row = net_section.row() - net_section_row.label(text="IPC Port:") - net_section_row.prop(settings, "ipc_port", text="") net_section_row = net_section.row() net_section_row.label(text="Timeout (ms):") net_section_row.prop(settings, "connection_timeout", text="") @@ -322,7 +319,7 @@ class SESSION_PT_user(bpy.types.Panel): @classmethod def poll(cls, context): - return session and session.state['STATE'] in [STATE_ACTIVE, STATE_LOBBY] + return session and session.state in [STATE_ACTIVE, STATE_LOBBY] def draw_header(self, context): self.layout.label(text="", icon='USER') @@ -353,7 +350,7 @@ class SESSION_PT_user(bpy.types.Panel): if active_user != 0 and active_user.username != settings.username: row = layout.row() user_operations = row.split() - if session.state['STATE'] == STATE_ACTIVE: + if session.state == STATE_ACTIVE: user_operations.alert = context.window_manager.session.time_snap_running user_operations.operator( @@ -411,7 +408,7 @@ class SESSION_PT_presence(bpy.types.Panel): @classmethod def poll(cls, context): return not session \ - or (session and session.state['STATE'] in [STATE_INITIAL, STATE_ACTIVE]) + or (session and session.state in [STATE_INITIAL, STATE_ACTIVE]) def draw_header(self, context): self.layout.prop(context.window_manager.session, @@ -441,7 +438,7 @@ class SESSION_PT_presence(bpy.types.Panel): def draw_property(context, parent, property_uuid, level=0): settings = get_preferences() runtime_settings = context.window_manager.session - item = session.get(uuid=property_uuid) + item = session.repository.get_node(property_uuid) area_msg = parent.row(align=True) @@ -519,8 +516,8 @@ class SESSION_PT_repository(bpy.types.Panel): admin = usr['admin'] return hasattr(context.window_manager, 'session') and \ session and \ - (session.state['STATE'] == STATE_ACTIVE or \ - session.state['STATE'] == STATE_LOBBY and admin) + (session.state == STATE_ACTIVE or \ + session.state == STATE_LOBBY and admin) def draw_header(self, context): self.layout.label(text="", icon='OUTLINER_OB_GROUP_INSTANCE') @@ -536,7 +533,7 @@ class SESSION_PT_repository(bpy.types.Panel): row = layout.row() - if session.state['STATE'] == STATE_ACTIVE: + if session.state == STATE_ACTIVE: if 'SessionBackupTimer' in registry: row.alert = True row.operator('session.cancel_autosave', icon="CANCEL") @@ -568,7 +565,7 @@ class SESSION_PT_repository(bpy.types.Panel): filter_owner=settings.username) if runtime_settings.filter_owned else session.list() client_keys = [key for key in key_to_filter - if session.get(uuid=key).str_type + if session.repository.get_node(key).str_type in types_filter] if client_keys: @@ -579,7 +576,7 @@ class SESSION_PT_repository(bpy.types.Panel): else: row.label(text="Empty") - elif session.state['STATE'] == STATE_LOBBY and usr and usr['admin']: + elif session.state == STATE_LOBBY and usr and usr['admin']: row.operator("session.init", icon='TOOL_SETTINGS', text="Init") else: row.label(text="Waiting to start") diff --git a/multi_user/utils.py b/multi_user/utils.py index 25444f9..a593015 100644 --- a/multi_user/utils.py +++ b/multi_user/utils.py @@ -36,7 +36,7 @@ from replication.constants import (STATE_ACTIVE, STATE_AUTH, STATE_INITIAL, STATE_SRV_SYNC, STATE_WAITING, STATE_QUITTING, STATE_LOBBY, - STATE_LAUNCHING_SERVICES) + CONNECTING) def find_from_attr(attr_name, attr_value, list): @@ -92,7 +92,7 @@ def get_state_str(state): state_str = 'OFFLINE' elif state == STATE_QUITTING: state_str = 'QUITTING' - elif state == STATE_LAUNCHING_SERVICES: + elif state == CONNECTING: state_str = 'LAUNCHING SERVICES' elif state == STATE_LOBBY: state_str = 'LOBBY'