diff options
-rw-r--r-- | source/blender/blenkernel/BKE_lib_query.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.c | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_query.c | 39 |
3 files changed, 39 insertions, 17 deletions
diff --git a/source/blender/blenkernel/BKE_lib_query.h b/source/blender/blenkernel/BKE_lib_query.h index 4e781aea9d3..9c49514e7b8 100644 --- a/source/blender/blenkernel/BKE_lib_query.h +++ b/source/blender/blenkernel/BKE_lib_query.h @@ -70,12 +70,15 @@ enum { /** That ID is used as library override's reference by its owner. */ IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE = (1 << 5), + /** That ID pointer is not overridable. */ + IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE = (1 << 6), + /** * Indicates that this is an internal runtime ID pointer, like e.g. `ID.newid` or `ID.original`. * \note Those should be ignored in most cases, and won't be processed/generated anyway unless * `IDWALK_DO_INTERNAL_RUNTIME_POINTERS` option is enabled. */ - IDWALK_CB_INTERNAL = (1 << 6), + IDWALK_CB_INTERNAL = (1 << 7), /** * This ID usage is fully refcounted. diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index 45ba2526da2..2be67856a9d 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -480,10 +480,8 @@ static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *dat for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL; to_id_entry = to_id_entry->next) { - if ((to_id_entry->usage_flag & - (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) != 0) { - /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers), nor - * override references or embedded ID pointers, as actual dependencies. */ + if ((to_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) { + /* Never consider non-overridable relationships as actual dependencies. */ continue; } @@ -578,10 +576,8 @@ static void lib_override_local_group_tag_recursive(LibOverrideGroupTagData *data for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL; to_id_entry = to_id_entry->next) { - if ((to_id_entry->usage_flag & - (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) != 0) { - /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers), nor - * override references or embedded ID pointers, as actual dependencies. */ + if ((to_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) { + /* Never consider non-overridable relationships as actual dependencies. */ continue; } diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c index e33743eb36b..cbbe07f99d8 100644 --- a/source/blender/blenkernel/intern/lib_query.c +++ b/source/blender/blenkernel/intern/lib_query.c @@ -56,11 +56,19 @@ typedef struct LibraryForeachIDData { */ ID *self_id; + /** Flags controlling the bahaviour of the 'foreach id' looping code. */ int flag; + /** Generic flags to be passed to all callback calls for current processed data. */ int cb_flag; + /** Callback flags that are forbidden for all callback calls for current processed data. */ int cb_flag_clear; + + /* Function to call for every ID pointers of current processed data, and its opaque user data + * pointer. */ LibraryIDLinkCallback callback; void *user_data; + /** Store the returned value from the callback, to decide how to continue the processing of ID + * pointers for current data. */ int status; /* To handle recursion. */ @@ -73,13 +81,25 @@ bool BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int if (!(data->status & IDWALK_STOP)) { const int flag = data->flag; ID *old_id = *id_pp; - const int callback_return = data->callback(&(struct LibraryIDLinkCallbackData){ - .user_data = data->user_data, - .bmain = data->bmain, - .id_owner = data->owner_id, - .id_self = data->self_id, - .id_pointer = id_pp, - .cb_flag = ((cb_flag | data->cb_flag) & ~data->cb_flag_clear)}); + + /* Update the callback flags with the ones defined (or forbidden) in `data` by the generic + * caller code. */ + cb_flag = ((cb_flag | data->cb_flag) & ~data->cb_flag_clear); + + /* Update the callback flags with some extra information regarding overrides: all 'loopback', + * 'internal', 'embedded' etc. ID pointers are never overridable. */ + if (cb_flag & (IDWALK_CB_INTERNAL | IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK | + IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) { + cb_flag |= IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE; + } + + const int callback_return = data->callback( + &(struct LibraryIDLinkCallbackData){.user_data = data->user_data, + .bmain = data->bmain, + .id_owner = data->owner_id, + .id_self = data->self_id, + .id_pointer = id_pp, + .cb_flag = cb_flag}); if (flag & IDWALK_READONLY) { BLI_assert(*(id_pp) == old_id); } @@ -132,7 +152,10 @@ void BKE_lib_query_idpropertiesForeachIDLink_callback(IDProperty *id_prop, void BLI_assert(id_prop->type == IDP_ID); LibraryForeachIDData *data = (LibraryForeachIDData *)user_data; - BKE_LIB_FOREACHID_PROCESS_ID(data, id_prop->data.pointer, IDWALK_CB_USER); + const int cb_flag = IDWALK_CB_USER | ((id_prop->flag & IDP_FLAG_OVERRIDABLE_LIBRARY) ? + 0 : + IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE); + BKE_LIB_FOREACHID_PROCESS_ID(data, id_prop->data.pointer, cb_flag); } bool BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp) |