Blender V4.5
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 }
85 "Create shallow copy for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow);
87 }
88 else {
90 }
91}
92
93/* Free 'id' node. */
95{
96 destroy();
97}
98
100{
101 if (id_orig == nullptr) {
102 return;
103 }
104
105 /* Free memory used by this evaluated ID. */
106 if (!ELEM(id_cow, id_orig, nullptr)) {
109 id_cow = nullptr;
111 "Destroy evaluated ID for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow);
112 }
113
114 for (ComponentNode *comp_node : components.values()) {
115 delete comp_node;
116 }
117
118 /* Tag that the node is freed. */
119 id_orig = nullptr;
120}
121
122std::string IDNode::identifier() const
123{
124 char orig_ptr[24], cow_ptr[24];
125 SNPRINTF(orig_ptr, "%p", id_orig);
126 SNPRINTF(cow_ptr, "%p", id_cow);
127 return std::string(nodeTypeAsString(type)) + " : " + name + " (orig: " + orig_ptr +
128 ", eval: " + cow_ptr + ", is_visible_on_build " +
129 (is_visible_on_build ? "true" : "false") + ")";
130}
131
133{
135 return components.lookup_default(key, nullptr);
136}
137
139{
140 ComponentNode *comp_node = find_component(type, name);
141 if (!comp_node) {
143 BLI_assert(factory);
144 comp_node = (ComponentNode *)factory->create_node(this->id_orig, "", name);
145
146 /* Register. */
147 ComponentIDKey key(type, comp_node->name);
148 components.add_new(key, comp_node);
149 comp_node->owner = this;
150 }
151 return comp_node;
152}
153
155{
156 for (ComponentNode *comp_node : components.values()) {
157 /* Relations update does explicit animation update when needed. Here we ignore animation
158 * component to avoid loss of possible unkeyed changes. */
159 if (comp_node->type == NodeType::ANIMATION && source == DEG_UPDATE_SOURCE_RELATIONS) {
160 continue;
161 }
162 comp_node->tag_update(graph, source);
163 }
164}
165
167{
168 /* Finalize build of all components. */
169 for (ComponentNode *comp_node : components.values()) {
170 comp_node->finalize_build(graph);
171 }
173}
174
176{
178 for (ComponentNode *comp_node : components.values()) {
179 if (comp_node->possibly_affects_visible_id) {
180 const int component_type_as_int = int(comp_node->type);
181 BLI_assert(component_type_as_int < 64);
182 result |= (1ULL << component_type_as_int);
183 }
184 }
185 return result;
186}
187
188} // namespace blender::deg
ID * BKE_libblock_alloc_notest(short type) ATTR_WARN_UNUSED_RESULT
Definition lib_id.cc:1323
#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:599
#define ELEM(...)
ID and Library types, which are fundamental for SDNA.
BPy_StructRNA * depsgraph
#define DEG_COW_PRINT(format,...)
#define this
#define GS(a)
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
uint64_t IDComponentsMask
void deg_tag_eval_copy_id(deg::Depsgraph &depsgraph, ID *id_cow, const ID *id_orig)
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:404
char name[66]
Definition DNA_ID.h:415
virtual Node * create_node(const ID *id, const char *subdata, StringRef name) const =0
IDComponentsMask previously_visible_components_mask
DEGCustomDataMeshMasks customdata_masks
DEGCustomDataMeshMasks previous_customdata_masks
ComponentNode * add_component(NodeType type, StringRef name="")
IDComponentsMask visible_components_mask
void init_copy_on_write(Depsgraph &depsgraph, ID *id_cow_hint=nullptr)
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