From fd4c01a75c34fa88a20d3967d02996c0c9815efe Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 12 Mar 2021 09:39:23 +0100 Subject: LibQuery: Add an option to process internal runtime ID pointers. In some cases (advanced, low-level code) we also want to process ID pointers like `ID.newid` or `ID.orig_id`. --- source/blender/blenkernel/BKE_lib_query.h | 10 ++++++++++ source/blender/blenkernel/intern/lib_query.c | 9 ++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'source/blender/blenkernel') diff --git a/source/blender/blenkernel/BKE_lib_query.h b/source/blender/blenkernel/BKE_lib_query.h index f064d03261d..4e781aea9d3 100644 --- a/source/blender/blenkernel/BKE_lib_query.h +++ b/source/blender/blenkernel/BKE_lib_query.h @@ -70,6 +70,13 @@ enum { /** That ID is used as library override's reference by its owner. */ IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE = (1 << 5), + /** + * 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), + /** * This ID usage is fully refcounted. * Callback is responsible to deal accordingly with #ID.us if needed. @@ -126,6 +133,9 @@ enum { IDWALK_IGNORE_EMBEDDED_ID = (1 << 3), IDWALK_NO_INDIRECT_PROXY_DATA_USAGE = (1 << 8), /* Ugly special case :(((( */ + /** Also process internal ID pointers like `ID.newid` or `ID.orig_id`. + * WARNING: Dangerous, use with caution. */ + IDWALK_DO_INTERNAL_RUNTIME_POINTERS = (1 << 9), }; typedef struct LibraryForeachIDData LibraryForeachIDData; diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c index acd0c10040c..e33743eb36b 100644 --- a/source/blender/blenkernel/intern/lib_query.c +++ b/source/blender/blenkernel/intern/lib_query.c @@ -183,8 +183,9 @@ static void library_foreach_ID_link(Main *bmain, BLI_assert(inherit_data == NULL || data.bmain == inherit_data->bmain); if (flag & IDWALK_RECURSE) { - /* For now, recursion implies read-only. */ + /* For now, recursion implies read-only, and no internal pointers. */ flag |= IDWALK_READONLY; + flag &= ~IDWALK_DO_INTERNAL_RUNTIME_POINTERS; data.ids_handled = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__); BLI_LINKSTACK_INIT(data.ids_todo); @@ -230,6 +231,7 @@ static void library_foreach_ID_link(Main *bmain, } if (bmain != NULL && bmain->relations != NULL && (flag & IDWALK_READONLY) && + (flag & IDWALK_DO_INTERNAL_RUNTIME_POINTERS) == 0 && (((bmain->relations->flag & MAINIDRELATIONS_INCLUDE_UI) == 0) == ((data.flag & IDWALK_INCLUDE_UI) == 0))) { /* Note that this is minor optimization, even in worst cases (like id being an object with @@ -250,6 +252,11 @@ static void library_foreach_ID_link(Main *bmain, /* Note: ID.lib pointer is purposefully fully ignored here... * We may want to add it at some point? */ + if (flag & IDWALK_DO_INTERNAL_RUNTIME_POINTERS) { + CALLBACK_INVOKE_ID(id->newid, IDWALK_CB_INTERNAL); + CALLBACK_INVOKE_ID(id->orig_id, IDWALK_CB_INTERNAL); + } + if (id->override_library != NULL) { CALLBACK_INVOKE_ID(id->override_library->reference, IDWALK_CB_USER | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE); -- cgit v1.2.3