2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2013 Blender Foundation.
19 * All rights reserved.
21 * Original Author: Joshua Leung
22 * Contributor(s): None Yet
24 * ***** END GPL LICENSE BLOCK *****
27 /** \file blender/depsgraph/intern/depsnode.cc
34 #include "BLI_utildefines.h"
38 #include "DNA_anim_types.h"
40 #include "BKE_animsys.h"
42 #include "DEG_depsgraph.h"
45 #include "depsnode.h" /* own include */
46 #include "depsnode_component.h"
47 #include "depsnode_operation.h"
48 #include "depsgraph_intern.h"
53 /* Add ------------------------------------------------ */
55 DepsNode::TypeInfo::TypeInfo(eDepsNode_Type type, const char *tname)
58 if (type == DEPSNODE_TYPE_OPERATION)
59 this->tclass = DEPSNODE_CLASS_OPERATION;
60 else if (type < DEPSNODE_TYPE_PARAMETERS)
61 this->tclass = DEPSNODE_CLASS_GENERIC;
63 this->tclass = DEPSNODE_CLASS_COMPONENT;
75 * note: deleting relations will remove them from the node relations set,
76 * but only touch the same position as we are using here, which is safe.
78 DEPSNODE_RELATIONS_ITER_BEGIN(this->inlinks, rel)
80 OBJECT_GUARDED_DELETE(rel, DepsRelation);
82 DEPSNODE_RELATIONS_ITER_END;
84 DEPSNODE_RELATIONS_ITER_BEGIN(this->outlinks, rel)
86 OBJECT_GUARDED_DELETE(rel, DepsRelation);
88 DEPSNODE_RELATIONS_ITER_END;
92 /* Generic identifier for Depsgraph Nodes. */
93 string DepsNode::identifier() const
96 sprintf(typebuf, "(%d)", type);
98 return string(typebuf) + " : " + name;
104 /* Time Source Node ============================================== */
106 void TimeSourceDepsNode::tag_update(Depsgraph *graph)
108 for (DepsNode::Relations::const_iterator it = outlinks.begin();
109 it != outlinks.end();
112 DepsRelation *rel = *it;
113 DepsNode *node = rel->to;
114 node->tag_update(graph);
119 /* Root Node ============================================== */
121 RootDepsNode::RootDepsNode() : time_source(NULL)
125 RootDepsNode::~RootDepsNode()
127 OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode);
130 TimeSourceDepsNode *RootDepsNode::add_time_source(const string &name)
133 DepsNodeFactory *factory = DEG_get_node_factory(DEPSNODE_TYPE_TIMESOURCE);
134 time_source = (TimeSourceDepsNode *)factory->create_node(NULL, "", name);
135 /*time_source->owner = this;*/ // XXX
140 DEG_DEPSNODE_DEFINE(RootDepsNode, DEPSNODE_TYPE_ROOT, "Root DepsNode");
141 static DepsNodeFactoryImpl<RootDepsNode> DNTI_ROOT;
143 /* Time Source Node ======================================= */
145 DEG_DEPSNODE_DEFINE(TimeSourceDepsNode, DEPSNODE_TYPE_TIMESOURCE, "Time Source");
146 static DepsNodeFactoryImpl<TimeSourceDepsNode> DNTI_TIMESOURCE;
148 /* ID Node ================================================ */
150 /* Initialize 'id' node - from pointer data given. */
151 void IDDepsNode::init(const ID *id, const string &UNUSED(subdata))
153 /* Store ID-pointer. */
154 BLI_assert(id != NULL);
156 this->layers = (1 << 20) - 1;
157 this->eval_flags = 0;
159 /* NOTE: components themselves are created if/when needed.
160 * This prevents problems with components getting added
161 * twice if an ID-Ref needs to be created to house it...
165 /* Free 'id' node. */
166 IDDepsNode::~IDDepsNode()
171 /* Copy 'id' node. */
172 void IDDepsNode::copy(DepsgraphCopyContext *dcc, const IDDepsNode *src)
174 (void)src; /* Ignored. */
175 /* Iterate over items in original hash, adding them to new hash. */
176 for (IDDepsNode::ComponentMap::const_iterator it = this->components.begin();
177 it != this->components.end();
180 /* Get current <type : component> mapping. */
181 ComponentIDKey c_key = it->first;
182 DepsNode *old_component = it->second;
184 /* Make a copy of component. */
185 ComponentDepsNode *component = (ComponentDepsNode *)DEG_copy_node(dcc, old_component);
187 /* Add new node to hash... */
188 this->components[c_key] = component;
191 // TODO: perform a second loop to fix up links?
192 BLI_assert(!"Not expected to be used");
195 ComponentDepsNode *IDDepsNode::find_component(eDepsNode_Type type,
196 const string &name) const
198 ComponentIDKey key(type, name);
199 ComponentMap::const_iterator it = components.find(key);
200 return it != components.end() ? it->second : NULL;
203 ComponentDepsNode *IDDepsNode::add_component(eDepsNode_Type type,
206 ComponentIDKey key(type, name);
207 ComponentDepsNode *comp_node = find_component(type, name);
209 DepsNodeFactory *factory = DEG_get_node_factory(type);
210 comp_node = (ComponentDepsNode *)factory->create_node(this->id, "", name);
213 this->components[key] = comp_node;
214 comp_node->owner = this;
219 void IDDepsNode::remove_component(eDepsNode_Type type, const string &name)
221 ComponentIDKey key(type, name);
222 ComponentDepsNode *comp_node = find_component(type, name);
225 this->components.erase(key);
226 OBJECT_GUARDED_DELETE(comp_node, ComponentDepsNode);
230 void IDDepsNode::clear_components()
232 for (ComponentMap::const_iterator it = components.begin();
233 it != components.end();
236 ComponentDepsNode *comp_node = it->second;
237 OBJECT_GUARDED_DELETE(comp_node, ComponentDepsNode);
242 void IDDepsNode::tag_update(Depsgraph *graph)
244 for (ComponentMap::const_iterator it = components.begin();
245 it != components.end();
248 ComponentDepsNode *comp_node = it->second;
249 /* TODO(sergey): What about drievrs? */
250 bool do_component_tag = comp_node->type != DEPSNODE_TYPE_ANIMATION;
251 if (comp_node->type == DEPSNODE_TYPE_ANIMATION) {
252 AnimData *adt = BKE_animdata_from_id(id);
253 BLI_assert(adt != NULL);
254 if (adt->recalc & ADT_RECALC_ANIM) {
255 do_component_tag = true;
258 if (do_component_tag) {
259 comp_node->tag_update(graph);
264 DEG_DEPSNODE_DEFINE(IDDepsNode, DEPSNODE_TYPE_ID_REF, "ID Node");
265 static DepsNodeFactoryImpl<IDDepsNode> DNTI_ID_REF;
267 /* Subgraph Node ========================================== */
269 /* Initialize 'subgraph' node - from pointer data given. */
270 void SubgraphDepsNode::init(const ID *id, const string &UNUSED(subdata))
272 /* Store ID-ref if provided. */
273 this->root_id = (ID *)id;
275 /* NOTE: graph will need to be added manually,
276 * as we don't have any way of passing this down.
280 /* Free 'subgraph' node */
281 SubgraphDepsNode::~SubgraphDepsNode()
283 /* Only free if graph not shared, of if this node is the first
286 // XXX: prune these flags a bit...
287 if ((this->flag & SUBGRAPH_FLAG_FIRSTREF) || !(this->flag & SUBGRAPH_FLAG_SHARED)) {
288 /* Free the referenced graph. */
289 DEG_graph_free(this->graph);
294 /* Copy 'subgraph' node - Assume that the subgraph doesn't get copied for now... */
295 void SubgraphDepsNode::copy(DepsgraphCopyContext * /*dcc*/,
296 const SubgraphDepsNode * /*src*/)
298 //const SubgraphDepsNode *src_node = (const SubgraphDepsNode *)src;
299 //SubgraphDepsNode *dst_node = (SubgraphDepsNode *)dst;
301 /* for now, subgraph itself isn't copied... */
302 BLI_assert(!"Not expected to be used");
305 DEG_DEPSNODE_DEFINE(SubgraphDepsNode, DEPSNODE_TYPE_SUBGRAPH, "Subgraph Node");
306 static DepsNodeFactoryImpl<SubgraphDepsNode> DNTI_SUBGRAPH;
309 void DEG_register_base_depsnodes()
311 DEG_register_node_typeinfo(&DNTI_ROOT);
312 DEG_register_node_typeinfo(&DNTI_TIMESOURCE);
314 DEG_register_node_typeinfo(&DNTI_ID_REF);
315 DEG_register_node_typeinfo(&DNTI_SUBGRAPH);