Blender V5.0
deg_node_id.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2013 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
10
11#include "BLI_string.h"
12#include "BLI_utildefines.h"
13
14#include "DNA_ID.h"
15
16#include "BKE_lib_id.hh"
17
21
22namespace blender::deg {
23
25{
26 switch (linked_state) {
28 return "INDIRECTLY";
30 return "VIA_SET";
32 return "DIRECTLY";
33 }
34 BLI_assert_msg(0, "Unhandled linked state, should never happen.");
35 return "UNKNOWN";
36}
37
38void IDNode::init(const ID *id, const char * /*subdata*/)
39{
40 BLI_assert(id != nullptr);
41 /* Store ID-pointer. */
42 id_type = GS(id->name);
43 id_orig = (ID *)id;
44 id_orig_session_uid = id->session_uid;
45 eval_flags = 0;
51 is_enabled_on_eval = true;
53 has_base = false;
54 is_user_modified = false;
56
59}
60
62{
63 /* Create pointer as early as possible, so we can use it for function
64 * bindings. Rest of data we'll be copying to the new datablock when
65 * it is actually needed. */
66 if (id_cow_hint != nullptr) {
67 // BLI_assert(deg_eval_copy_is_needed(id_orig));
69 id_cow = id_cow_hint;
70
71 /* While `id_cow->orig_id == id` should be `true` most of the time (a same 'orig' ID should
72 * keep a same pointer in most cases), in can happen that the same 'orig' ID got a new
73 * address, e.g. after being deleted and re-loaded from memfile undo, without any update of
74 * the depsgraph in-between (e.g. when the depsgraph belongs to an inactive viewlayer).
75 * Ref. #145848. */
76 id_cow->orig_id = this->id_orig;
77 }
78 else {
80 }
81 }
84 /* No need to call #BKE_libblock_runtime_ensure here, this will be done by
85 * #BKE_libblock_copy_in_lib when #deg_expand_eval_copy_datablock is executed. */
87 "Allocate memory for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow);
88 }
89 else {
91 }
92}
93
94/* Free 'id' node. */
96{
97 destroy();
98}
99
101{
102 if (id_orig == nullptr) {
103 return;
104 }
105
106 /* Free memory used by this evaluated ID. */
107 if (!ELEM(id_cow, id_orig, nullptr)) {
110 id_cow = nullptr;
112 "Destroy evaluated ID for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow);
113 }
114
115 for (ComponentNode *comp_node : components.values()) {
116 delete comp_node;
117 }
118
119 /* Tag that the node is freed. */
120 id_orig = nullptr;
121}
122
123std::string IDNode::identifier() const
124{
125 char orig_ptr[24], cow_ptr[24];
126 SNPRINTF(orig_ptr, "%p", id_orig);
127 SNPRINTF(cow_ptr, "%p", id_cow);
128 return std::string(nodeTypeAsString(type)) + " : " + name + " (orig: " + orig_ptr +
129 ", eval: " + cow_ptr + ", is_visible_on_build " +
130 (is_visible_on_build ? "true" : "false") + ")";
131}
132
134{
136 return components.lookup_default(key, nullptr);
137}
138
140{
141 ComponentNode *comp_node = find_component(type, name);
142 if (!comp_node) {
144 BLI_assert(factory);
145 comp_node = (ComponentNode *)factory->create_node(this->id_orig, "", name);
146
147 /* Register. */
148 ComponentIDKey key(type, comp_node->name);
149 components.add_new(key, comp_node);
150 comp_node->owner = this;
151 }
152 return comp_node;
153}
154
156{
157 for (ComponentNode *comp_node : components.values()) {
158 /* Relations update does explicit animation update when needed. Here we ignore animation
159 * component to avoid loss of possible unkeyed changes. */
160 if (comp_node->type == NodeType::ANIMATION && source == DEG_UPDATE_SOURCE_RELATIONS) {
161 continue;
162 }
163 comp_node->tag_update(graph, source);
164 }
165}
166
168{
169 /* Finalize build of all components. */
170 for (ComponentNode *comp_node : components.values()) {
171 comp_node->finalize_build(graph);
172 }
174}
175
177{
179 for (ComponentNode *comp_node : components.values()) {
180 if (comp_node->possibly_affects_visible_id) {
181 const int component_type_as_int = int(comp_node->type);
182 BLI_assert(component_type_as_int < 64);
183 result |= (1ULL << component_type_as_int);
184 }
185 }
186 return result;
187}
188
189} // namespace blender::deg
ID * BKE_libblock_alloc_notest(short type) ATTR_WARN_UNUSED_RESULT
Definition lib_id.cc:1340
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:604
#define ELEM(...)
ID and Library types, which are fundamental for SDNA.
#define DEG_COW_PRINT(format,...)
#define GS(x)
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
uint64_t IDComponentsMask
void deg_free_eval_copy_datablock(ID *id_cow)
const char * linkedStateAsString(eDepsNode_LinkedState_Type linked_state)
bool deg_eval_copy_is_needed(const ID *id_orig)
DepsNodeFactory * type_get_factory(const NodeType type)
@ DEG_ID_LINKED_INDIRECTLY
const char * nodeTypeAsString(NodeType type)
Definition deg_node.cc:35
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
virtual Node * create_node(const ID *id, const char *subdata, StringRef name) const =0
IDComponentsMask previously_visible_components_mask
void init_copy_on_write(ID *id_cow_hint=nullptr)
DEGCustomDataMeshMasks customdata_masks
DEGCustomDataMeshMasks previous_customdata_masks
ComponentNode * add_component(NodeType type, StringRef name="")
IDComponentsMask visible_components_mask
void init(const ID *id, const char *subdata) override
Map< ComponentIDKey, ComponentNode * > components
IDComponentsMask get_visible_components_mask() const
void finalize_build(Depsgraph *graph)
std::string identifier() const override
eDepsNode_LinkedState_Type linked_state
ComponentNode * find_component(NodeType type, StringRef name="") const
void tag_update(Depsgraph *graph, eUpdateSource source) override
uint32_t previous_eval_flags
std::string name
Definition deg_node.hh:180