def connect(): logger.info("connect") BlendData.instance().reset() if share_data.client is not None: # a server shutdown was not processed logger.debug("connect: share_data.client is not None") share_data.client = None prefs = get_mixer_prefs() if not create_main_client(prefs.host, prefs.port): if is_localhost(prefs.host): start_local_server() if not wait_for_server(prefs.host, prefs.port): logger.error("Unable to start local server") return False else: logger.error("Unable to connect to remote server %s:%s", prefs.host, prefs.port) return False assert is_client_connected() set_client_attributes() return True
def join_room(room_name: str): logger.info("join_room") assert share_data.client.current_room is None BlendData.instance().reset() share_data.session_id += 1 # todo tech debt -> current_room should be set when JOIN_ROOM is received # todo _joining_room_name should be set in client timer share_data.client.current_room = room_name share_data.client._joining_room_name = room_name set_client_attributes() share_data.client.join_room(room_name) share_data.client.send_set_current_scene(bpy.context.scene.name_full) share_data.current_statistics = { "session_id": share_data.session_id, "blendfile": bpy.data.filepath, "statsfile": get_stats_filename(share_data.run_id, share_data.session_id), "user": get_mixer_prefs().user, "room": room_name, "children": {}, } prefs = get_mixer_prefs() share_data.auto_save_statistics = prefs.auto_save_statistics share_data.statistics_directory = prefs.statistics_directory share_data.set_experimental_sync(prefs.experimental_sync) share_data.pending_test_update = False # join a room <==> want to track local changes HandlerManager.set_handlers(True)
def diff(self, proxy: BpyPropDataCollectionProxy, collection_name: str, context: Context): self.items_added.clear() self.items_removed.clear() self.items_renamed.clear() proxy_items = {id_proxy.mixer_uuid(): id_proxy for id_proxy in proxy._data.values()} bl_collection = getattr(bpy.data, collection_name) blender_items = {} for name, item in bl_collection.items(): if skip_bpy_data_item(collection_name, item): continue uuid = item.mixer_uuid if uuid in blender_items.keys(): # duplicate uuid, from an object duplication original_item = blender_items[uuid] logger.info(f"Duplicate uuid {uuid} for {original_item[1]} and {item.name}...") logger.info("... assuming object was duplicated. Resetting (not an error)") # reset the uuid, ensure will regenerate item.mixer_uuid = "" ensure_uuid(item) if item.mixer_uuid in blender_items.keys(): logger.error(f"Duplicate uuid found for {item}") continue blender_items[item.mixer_uuid] = (name, collection_name) self.items_added, self.items_removed, self.items_renamed = find_renamed(proxy_items, blender_items) if not self.empty(): BlendData.instance().collection(collection_name).set_dirty()
def connect(): logger.info("connect") BlendData.instance().reset() if share_data.client is not None: # a server shutdown was not processed logger.debug("connect: share_data.client is not None") share_data.client = None prefs = get_mixer_prefs() if not create_main_client(prefs.host, prefs.port): if is_localhost(prefs.host): if prefs.no_start_server: raise RuntimeError( f"Cannot connect to existing server at {prefs.host}:{prefs.port} and MIXER_NO_START_SERVER environment variable exists" ) start_local_server() if not wait_for_server(prefs.host, prefs.port): raise RuntimeError("Unable to start local server") else: raise RuntimeError( f"Unable to connect to remote server {prefs.host}:{prefs.port}" ) assert is_client_connected() set_client_attributes()
def bpy_data_ctor(collection_name: str, proxy: BpyIDProxy) -> Union[T.ID, None]: collection = getattr(bpy.data, collection_name) BlendData.instance().collection(collection_name).set_dirty if collection_name == "images": is_packed = proxy.data("packed_file") is not None image = None if is_packed: name = proxy.data("name") size = proxy.data("size") width = size.data(0) height = size.data(1) image = collection.new(name, width, height) # remaning attributes will be saved from the received proxy attributes else: path = proxy.data("filepath") if path != "": image = collection.load(path) # we may have received an ID named xxx.001 although filepath is xxx, so fix it now image.name = proxy.data("name") return image if collection_name == "objects": name = proxy.data("name") target_proxy = proxy.data("data") if target_proxy is not None: target = target_proxy.target() else: target = None object_ = collection.new(name, target) return object_ if collection_name == "lights": name = proxy.data("name") light_type = proxy.data("type") light = collection.new(name, light_type) return light if collection_name == "sounds": filepath = proxy.data("filepath") # TODO what about "check_existing" ? id_ = collection.load(filepath) # we may have received an ID named xxx.001 although filepath is xxx, so fix it now id_.name = proxy.data("name") return id_ name = proxy.data("name") try: id_ = collection.new(name) except TypeError as e: logger.error( f"Exception while calling : bpy.data.{collection_name}.new({name})" ) logger.error(f"TypeError : {e}") return None return id_
def test_one(self): blenddata = BlendData.instance() scenes = blenddata.collection("scenes").bpy_collection() sounds = blenddata.collection("sounds").bpy_collection() # identity is not true self.assertEqual(scenes, D.scenes) self.assertEqual(sounds, D.sounds) self.assertIs(scenes["Scene_0"], D.scenes["Scene_0"])
def __init__(self, *args, **kwargs): self.state: ProxyState = ProxyState() self._data: Dict[str, DatablockCollectionProxy] = { name: DatablockCollectionProxy(name) for name in BlendData.instance().collection_names() } self._delayed_updates: Set[T.ID] = set()
def disconnect(): from mixer.bl_panels import update_ui_lists logger.info("disconnect") leave_current_room() BlendData.instance().reset() remove_draw_handlers() if bpy.app.timers.is_registered(network_consumer_timer): bpy.app.timers.unregister(network_consumer_timer) # the socket has already been disconnected if share_data.client is not None: if share_data.client.is_connected(): share_data.client.disconnect() share_data.client = None update_ui_lists()
def load(self, bl_collection: bpy.types.bpy_prop_collection, key: str, context: Context): # noqa N802 """ Load bl_collection elements as standalone datablocks. """ for name, item in bl_collection.items(): collection_name = BlendData.instance().bl_collection_name_from_ID( item) if skip_bpy_data_item(collection_name, item): continue uuid = ensure_uuid(item) self._data[uuid] = DatablockProxy().load( item, name, context, bpy_data_collection_name=collection_name) return self
def bpy_data_ctor(collection_name: str, proxy: BpyIDProxy) -> Union[T.ID, None]: collection = getattr(bpy.data, collection_name) BlendData.instance().collection(collection_name).set_dirty if collection_name == "images": is_packed = proxy.data("packed_file") is not None image = None if is_packed: name = proxy.data("name") width, height = proxy.data("size") image = collection.new(name, width, height) # remaning attributes will be saved from the received proxy attributes else: path = proxy.data("filepath") if path != "": try: image = collection.load(path) except RuntimeError as e: logger.warning( f'Cannot load image at path "{path}". Exception: ') logger.warning(f"... {e}") return None # we may have received an ID named xxx.001 although filepath is xxx, so fix it now image.name = proxy.data("name") return image if collection_name == "objects": name = proxy.data("name") target = None target_proxy = proxy.data("data") if target_proxy is not None: # use class name to work around circular references with proxy.py target_proxy_class = target_proxy.__class__.__name__ if target_proxy_class != "BpyIDRefProxy": # error on the sender side logger.warning( f"bpy.data.objects[{name}].data proxy is a {target_proxy_class}. Expected a BpyIDRefProxy" ) logger.warning("... loaded as Empty") else: target = target_proxy.target() object_ = collection.new(name, target) return object_ if collection_name == "lights": name = proxy.data("name") light_type = proxy.data("type") light = collection.new(name, light_type) return light if collection_name == "sounds": filepath = proxy.data("filepath") # TODO what about "check_existing" ? id_ = collection.load(filepath) # we may have received an ID named xxx.001 although filepath is xxx, so fix it now id_.name = proxy.data("name") return id_ name = proxy.data("name") try: id_ = collection.new(name) except TypeError as e: logger.error( f"Exception while calling : bpy.data.{collection_name}.new({name})" ) logger.error(f"TypeError : {e}") return None return id_
def test_derived_from_id(self): light = bpy.data.lights.new("new_area", "AREA") blenddata = BlendData.instance() collection_name = blenddata.bl_collection_name_from_ID(type(light)) self.assertEqual(collection_name, "lights")