From 710b47fe7c11fd881df5596fe714fcff634d6902 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 22 Aug 2023 18:57:42 +0200 Subject: [PATCH] Tweak SpaceNode foreach_id callback handling of nodetree ID pointer. The fact that this pointer may be either to a regular ID, or an embedded one, without any way to tell it withour accessing the nodetree data, makes it tricky to handle properly when such 'other ID' access is not allowed. Here there can still be assumptions and heuristics based on other data, but this remains fragile and really sub-optimal code. Should not have any behavioral change in current code, but required for replacing `blend_read_lib`/`blend_read_expand` by `foreach_id` (#105666). --- source/blender/editors/space_node/space_node.cc | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc index 7d128cc0c65..32803e166cb 100644 --- a/source/blender/editors/space_node/space_node.cc +++ b/source/blender/editors/space_node/space_node.cc @@ -1036,8 +1036,8 @@ static void node_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data) const int data_flags = BKE_lib_query_foreachid_process_flags_get(data); const bool is_readonly = (data_flags & IDWALK_READONLY) != 0; const bool allow_pointer_access = (data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0; - const bool is_embedded_nodetree = snode->id != nullptr && allow_pointer_access && - ntreeFromID(snode->id) == snode->nodetree; + bool is_embedded_nodetree = snode->id != nullptr && allow_pointer_access && + ntreeFromID(snode->id) == snode->nodetree; BKE_LIB_FOREACHID_PROCESS_ID(data, snode->id, IDWALK_CB_NOP); BKE_LIB_FOREACHID_PROCESS_ID(data, snode->from, IDWALK_CB_NOP); @@ -1074,10 +1074,21 @@ static void node_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data) (snode->nodetree->id.flag & LIB_EMBEDDED_DATA) == 0 || snode->nodetree == ntreeFromID(snode->id)); + /* This is mainly here for readfile case ('lib_link' process), as in such case there is no access + * to original data allowed, so no way to know whether the SpaceNode nodetree pointer is an + * embedded one or not. */ + if (!is_readonly && snode->id && !snode->nodetree) { + is_embedded_nodetree = true; + snode->nodetree = ntreeFromID(snode->id); + if (path != nullptr) { + path->nodetree = snode->nodetree; + } + } + if (path != nullptr) { for (path = path->next; path != nullptr; path = path->next) { BLI_assert(path->nodetree != nullptr); - if ((data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0) { + if (allow_pointer_access) { BLI_assert((path->nodetree->id.flag & LIB_EMBEDDED_DATA) == 0); }