Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <mont29>2022-09-05 16:46:00 +0300
committerBastien Montagne <bastien@blender.org>2022-09-05 17:12:54 +0300
commitcd49fee741148dc9dcc0cbefce0b70ea0f2d55c6 (patch)
treee8dc62543d0706f127a4e80683ab18dc72ec0494 /source/blender/blenkernel/intern/node.cc
parentdd19d6456abf9ee230bcce62fd67f6ab7ab91f16 (diff)
IDMAnagement: Add owner ID pointer to embedded ones.
Add a dedicated `owner_id` pointer to ID types that can be embedded (Collections and NodeTrees), and modify slightly come code to make handling those more safe and consistent. This implements first part of T69169. Reviewed By: brecht Differential Revision: https://developer.blender.org/D15838
Diffstat (limited to 'source/blender/blenkernel/intern/node.cc')
-rw-r--r--source/blender/blenkernel/intern/node.cc64
1 files changed, 36 insertions, 28 deletions
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index e1eaed71f37..3cb2b80813f 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -325,6 +325,8 @@ static void node_foreach_id(ID *id, LibraryForeachIDData *data)
{
bNodeTree *ntree = (bNodeTree *)id;
+ BKE_LIB_FOREACHID_PROCESS_ID(data, ntree->owner_id, IDWALK_CB_LOOPBACK);
+
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, ntree->gpd, IDWALK_CB_USER);
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
@@ -399,7 +401,7 @@ static void node_foreach_path(ID *id, BPathForeachPathData *bpath_data)
}
}
-static ID *node_owner_get(Main *bmain, ID *id, ID *owner_id_hint)
+static ID *node_owner_get(Main *UNUSED(bmain), ID *id, ID *UNUSED(owner_id_hint))
{
if ((id->flag & LIB_EMBEDDED_DATA) == 0) {
return id;
@@ -408,30 +410,10 @@ static ID *node_owner_get(Main *bmain, ID *id, ID *owner_id_hint)
// BLI_assert((id->tag & LIB_TAG_NO_MAIN) == 0);
bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
+ BLI_assert(ntree->owner_id != NULL);
+ BLI_assert(ntreeFromID(ntree->owner_id) == ntree);
- if (owner_id_hint != nullptr && ntreeFromID(owner_id_hint) == ntree) {
- return owner_id_hint;
- }
-
- ListBase *lists[] = {&bmain->materials,
- &bmain->lights,
- &bmain->worlds,
- &bmain->textures,
- &bmain->scenes,
- &bmain->linestyles,
- &bmain->simulations,
- nullptr};
-
- for (int i = 0; lists[i] != nullptr; i++) {
- LISTBASE_FOREACH (ID *, id_iter, lists[i]) {
- if (ntreeFromID(id_iter) == ntree) {
- return id_iter;
- }
- }
- }
-
- BLI_assert_msg(0, "Embedded node tree with no owner. Critical Main inconsistency.");
- return nullptr;
+ return ntree->owner_id;
}
static void write_node_socket_default_value(BlendWriter *writer, bNodeSocket *sock)
@@ -667,8 +649,13 @@ static void direct_link_node_socket(BlendDataReader *reader, bNodeSocket *sock)
sock->runtime = MEM_new<bNodeSocketRuntime>(__func__);
}
-void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
+void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
{
+ /* Special case for this pointer, do not rely on regular `lib_link` process here. Avoids needs
+ * for do_versioning, and ensures coherence of data in any case. */
+ BLI_assert((ntree->id.flag & LIB_EMBEDDED_DATA) != 0 || owner_id == nullptr);
+ ntree->owner_id = owner_id;
+
/* NOTE: writing and reading goes in sync, for speed. */
ntree->is_updating = false;
ntree->typeinfo = nullptr;
@@ -830,7 +817,7 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
static void ntree_blend_read_data(BlendDataReader *reader, ID *id)
{
bNodeTree *ntree = (bNodeTree *)id;
- ntreeBlendReadData(reader, ntree);
+ ntreeBlendReadData(reader, nullptr, ntree);
}
static void lib_link_node_socket(BlendLibReader *reader, Library *lib, bNodeSocket *sock)
@@ -2575,12 +2562,12 @@ void nodePositionPropagate(bNode *node)
}
}
-bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
+static bNodeTree *ntreeAddTree_do(
+ Main *bmain, ID *owner_id, const bool is_embedded, const char *name, const char *idname)
{
/* trees are created as local trees for compositor, material or texture nodes,
* node groups and other tree types are created as library data.
*/
- const bool is_embedded = (bmain == nullptr);
int flag = 0;
if (is_embedded) {
flag |= LIB_ID_CREATE_NO_MAIN;
@@ -2588,7 +2575,15 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
bNodeTree *ntree = (bNodeTree *)BKE_libblock_alloc(bmain, ID_NT, name, flag);
BKE_libblock_init_empty(&ntree->id);
if (is_embedded) {
+ BLI_assert(owner_id != NULL);
ntree->id.flag |= LIB_EMBEDDED_DATA;
+ ntree->owner_id = owner_id;
+ bNodeTree **ntree_owner_ptr = BKE_ntree_ptr_from_id(owner_id);
+ BLI_assert(ntree_owner_ptr != NULL);
+ *ntree_owner_ptr = ntree;
+ }
+ else {
+ BLI_assert(owner_id == NULL);
}
BLI_strncpy(ntree->idname, idname, sizeof(ntree->idname));
@@ -2597,6 +2592,19 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
return ntree;
}
+bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
+{
+ return ntreeAddTree_do(bmain, nullptr, false, name, idname);
+}
+
+bNodeTree *ntreeAddTreeEmbedded(Main *UNUSED(bmain),
+ ID *owner_id,
+ const char *name,
+ const char *idname)
+{
+ return ntreeAddTree_do(nullptr, owner_id, true, name, idname);
+}
+
bNodeTree *ntreeCopyTree_ex(const bNodeTree *ntree, Main *bmain, const bool do_id_user)
{
const int flag = do_id_user ? 0 : LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_MAIN;