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).
This commit is contained in:
Bastien Montagne 2023-08-22 18:57:42 +02:00
parent 1857df8d5b
commit 710b47fe7c
1 changed files with 14 additions and 3 deletions

View File

@ -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);
}