示例#1
0
    def diff(self, collection: T.bpy_prop_collection, key: str,
             collection_property: T.Property,
             context: Context) -> Optional[DeltaUpdate]:
        """
        Computes the difference between the state of an item tracked by this proxy and its Blender state.

        As this proxy tracks a collection, the result will be a DeltaUpdate that contains a DatablockCollectionProxy
        with an Delta item per added, deleted or update item

        Args:
            collection: the collection diff against this proxy
            collection_property: the property of collection in its enclosing object
        """

        # This method is called from the depsgraph handler. The proxy holds a representation of the Blender state
        # before the modification being processed. So the changeset is (Blender state - proxy state)

        # TODO how can this replace BpyBlendDiff ?

        diff = self.__class__()

        item_property = collection_property.fixed_type

        # keys are uuids
        # BpyDataCollectionDiff.diff() for why proxies without datablocks are ignores
        proxy_keys = {k for k, v in self._data.items() if v.target(context)}

        blender_items = {
            datablock.mixer_uuid: datablock
            for datablock in collection.values()
        }
        blender_keys = blender_items.keys()
        added_keys = blender_keys - proxy_keys
        deleted_keys = proxy_keys - blender_keys
        maybe_updated_keys = proxy_keys & blender_keys

        for k in added_keys:
            value = read_attribute(blender_items[k], k, item_property,
                                   collection, context)
            assert isinstance(value, (DatablockProxy, DatablockRefProxy))
            diff._data[k] = DeltaAddition(value)

        for k in deleted_keys:
            diff._data[k] = DeltaDeletion(self._data[k])

        for k in maybe_updated_keys:
            delta = diff_attribute(blender_items[k], k, item_property,
                                   self.data(k), context)
            if delta is not None:
                assert isinstance(delta, DeltaUpdate)
                diff._data[k] = delta

        if len(diff._data):
            return DeltaUpdate(diff)

        return None
 def load(
     self,
     bl_collection: T.bpy_prop_collection,
     context: Context,
 ):
     self._sequence.clear()
     for i, v in enumerate(bl_collection.values()):
         context.visit_state.push(v, i)
         try:
             self._sequence.append(_proxy_factory(v).load(v, context))
         except Exception as e:
             logger.error(f"Exception during load at {context.visit_state.display_path()} ...")
             logger.error(f"... {e!r}")
         finally:
             context.visit_state.pop()
     return self
    def load(
        self,
        bl_collection: T.bpy_prop_collection,
        key: Union[int, str],
        bl_collection_property: T.Property,
        context: Context,
    ):

        context.visit_state.path.append(key)
        try:
            self._sequence = [
                _proxy_factory(v).load(v, i, context)
                for i, v in enumerate(bl_collection.values())
            ]
        finally:
            context.visit_state.path.pop()
        return self
示例#4
0
    def load(
        self,
        bl_collection: T.bpy_prop_collection,
        key: Union[int, str],
        bl_collection_property: T.Property,
        context: Context,
    ):

        if len(bl_collection) == 0:
            self._data.clear()
            return self

        try:
            context.visit_state.path.append(key)
            # no keys means it is a sequence. However bl_collection.items() returns [(index, item)...]
            is_sequence = not bl_collection.keys()
            if is_sequence:
                # easier for the encoder to always have a dict
                self._data = {
                    MIXER_SEQUENCE: [
                        StructProxy.make(v).load(v, i, context) for i, v in enumerate(bl_collection.values())
                    ]
                }
            else:
                self._data = {k: StructProxy().load(v, k, context) for k, v in bl_collection.items()}
        finally:
            context.visit_state.path.pop()
        return self