def save(self, collection: T.bpy_prop_collection, parent: T.bpy_struct, key: str, context: Context): """ Saves this proxy into collection Args: collection: a collection of datablock references with link/unlink interface (e.g a_Collection_instance.objects) parent: the structure that contains collection to be loaded (e.g. a Collection instance) key: the name of the bpy_collection (e.g "objects") context: """ for _, ref_proxy in self._data.items(): assert isinstance(ref_proxy, DatablockRefProxy) datablock = ref_proxy.target(context) if datablock: collection.link(datablock) else: logger.info( f"unresolved reference {parent}.{key} -> {ref_proxy.display_string} {ref_proxy.mixer_uuid}" ) add_element = collection.link context.proxy_state.unresolved_refs.append( ref_proxy.mixer_uuid, add_element, f"{collection!r}.link({ref_proxy.display_string})")
def add_datablock_ref_element(collection: T.bpy_prop_collection, datablock: T.ID): """Add an element to a bpy_prop_collection using the collection specific API""" bl_rna = getattr(collection, "bl_rna", None) if bl_rna is not None: if isinstance(bl_rna, _link_collections): collection.link(datablock) return if isinstance(bl_rna, type(T.IDMaterials.bl_rna)): collection.append(datablock) return logging.warning( f"add_datablock_ref_element : no implementation for {collection} ")
def apply( self, collection: T.bpy_prop_collection, parent: T.Collection, key: Union[int, str], delta: Delta, context: Context, to_blender: bool = True, ) -> DatablockRefCollectionProxy: """ Apply delta to this proxy and optionally to the Blender attribute its manages. Args: attribute: a bpy_prop_collection of datablock references with link/unlink API (e.g. a_collection.objects) parent: the attribute that contains attribute (e.g. a Collection instance) key: the name of the bpy_collection in parent (e.g "objects") delta: the delta to apply context: proxy and visit state to_blender: update the managed Blender attribute in addition to this Proxy """ update: DatablockRefCollectionProxy = delta.value assert type(update) == type(self) # objects or children for k, ref_delta in update._data.items(): try: if not isinstance(ref_delta, (DeltaAddition, DeltaDeletion)): logger.error( f"unexpected type for delta at {collection}[{k}]: {ref_delta}. Ignored" ) continue ref_update: DatablockRefProxy = ref_delta.value if not isinstance(ref_update, DatablockRefProxy): logger.error( f"unexpected type for delta_value at {collection}[{k}]: {ref_update}. Ignored" ) continue assert isinstance(ref_update, DatablockRefProxy) if to_blender: uuid = ref_update._datablock_uuid datablock = context.proxy_state.datablock(uuid) if isinstance(ref_delta, DeltaAddition): if datablock is not None: collection.link(datablock) else: # unloaded datablock logger.warning( f"delta apply add for {parent!r}.{key}: no datablock for {ref_update.display_string} ({uuid})" ) else: if datablock is not None: collection.unlink(datablock) # else # we have already processed an Objet removal. Not an error if isinstance(ref_delta, DeltaAddition): self._data[k] = ref_update else: del self._data[k] except Exception as e: logger.warning( f"DatablockCollectionProxy.apply(). Processing {ref_delta} to_blender {to_blender}" ) logger.warning(f"... for {collection}[{k}]") logger.warning(f"... Exception: {e!r}") logger.warning("... Update ignored") continue return self