diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/depsgraph/DEG_depsgraph_query.h | 8 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_query_foreach.cc | 97 |
2 files changed, 87 insertions, 18 deletions
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h index 4148529d3f8..35176284abb 100644 --- a/source/blender/depsgraph/DEG_depsgraph_query.h +++ b/source/blender/depsgraph/DEG_depsgraph_query.h @@ -219,6 +219,9 @@ void DEG_iterator_ids_end(struct BLI_Iterator *iter); /* ************************ DEG traversal ********************* */ typedef void (*DEGForeachIDCallback)(ID *id, void *user_data); +typedef void (*DEGForeachIDComponentCallback)(ID *id, + eDepsObjectComponentType component, + void *user_data); /* NOTE: Modifies runtime flags in depsgraph nodes, so can not be used in * parallel. Keep an eye on that! @@ -232,6 +235,11 @@ void DEG_foreach_dependent_ID(const Depsgraph *depsgraph, DEGForeachIDCallback callback, void *user_data); +void DEG_foreach_dependent_ID_component(const Depsgraph *depsgraph, + const ID *id, + DEGForeachIDComponentCallback callback, + void *user_data); + void DEG_foreach_ID(const Depsgraph *depsgraph, DEGForeachIDCallback callback, void *user_data); #ifdef __cplusplus diff --git a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc index 717793d60f1..f5fcdf8e5d1 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc @@ -48,25 +48,29 @@ extern "C" { /* ************************ DEG TRAVERSAL ********************* */ namespace DEG { +namespace { typedef std::deque<OperationNode *> TraversalQueue; enum { DEG_NODE_VISITED = (1 << 0), }; -static void deg_foreach_clear_flags(const Depsgraph *graph) +typedef void (*DEGForeachOperation)(OperationNode *op_node, void *user_data); + +void deg_foreach_clear_flags(const Depsgraph *graph) { for (OperationNode *op_node : graph->operations) { op_node->scheduled = false; + op_node->owner->custom_flags = 0; } for (IDNode *id_node : graph->id_nodes) { id_node->custom_flags = 0; } } -static void deg_foreach_dependent_ID(const Depsgraph *graph, +void deg_foreach_dependent_operation(const Depsgraph *graph, const ID *id, - DEGForeachIDCallback callback, + DEGForeachOperation callback, void *user_data) { /* Start with getting ID node from the graph. */ @@ -84,6 +88,7 @@ static void deg_foreach_dependent_ID(const Depsgraph *graph, for (OperationNode *op_node : comp_node->operations) { queue.push_back(op_node); op_node->scheduled = true; + op_node->owner->custom_flags |= DEG_NODE_VISITED; } } GHASH_FOREACH_END(); @@ -94,14 +99,7 @@ static void deg_foreach_dependent_ID(const Depsgraph *graph, OperationNode *op_node = queue.front(); queue.pop_front(); for (;;) { - /* Check whether we need to inform callee about corresponding ID node. */ - ComponentNode *comp_node = op_node->owner; - IDNode *id_node = comp_node->owner; - if ((id_node->custom_flags & DEG_NODE_VISITED) == 0) { - /* TODO(sergey): Is it orig or CoW? */ - callback(id_node->id_orig, user_data); - id_node->custom_flags |= DEG_NODE_VISITED; - } + callback(op_node, user_data); /* Schedule outgoing operation nodes. */ if (op_node->outlinks.size() == 1) { OperationNode *to_node = (OperationNode *)op_node->outlinks[0]->to; @@ -127,10 +125,65 @@ static void deg_foreach_dependent_ID(const Depsgraph *graph, } } -static void deg_foreach_ancestor_ID(const Depsgraph *graph, - const ID *id, - DEGForeachIDCallback callback, - void *user_data) +struct ForeachIDComponentData { + DEGForeachIDComponentCallback callback; + void *user_data; +}; + +void deg_foreach_dependent_component_callback(OperationNode *op_node, void *user_data_v) +{ + ForeachIDComponentData *user_data = reinterpret_cast<ForeachIDComponentData *>(user_data_v); + ComponentNode *comp_node = op_node->owner; + if ((comp_node->custom_flags & DEG_NODE_VISITED) == 0) { + IDNode *id_node = comp_node->owner; + user_data->callback( + id_node->id_orig, nodeTypeToObjectComponent(comp_node->type), user_data->user_data); + comp_node->custom_flags |= DEG_NODE_VISITED; + } +} + +void deg_foreach_dependent_ID_component(const Depsgraph *graph, + const ID *id, + DEGForeachIDComponentCallback callback, + void *user_data) +{ + ForeachIDComponentData data; + data.callback = callback; + data.user_data = user_data; + deg_foreach_dependent_operation(graph, id, deg_foreach_dependent_component_callback, &data); +} + +struct ForeachIDData { + DEGForeachIDCallback callback; + void *user_data; +}; + +void deg_foreach_dependent_ID_callback(OperationNode *op_node, void *user_data_v) +{ + ForeachIDData *user_data = reinterpret_cast<ForeachIDData *>(user_data_v); + ComponentNode *comp_node = op_node->owner; + IDNode *id_node = comp_node->owner; + if ((id_node->custom_flags & DEG_NODE_VISITED) == 0) { + user_data->callback(id_node->id_orig, user_data->user_data); + id_node->custom_flags |= DEG_NODE_VISITED; + } +} + +void deg_foreach_dependent_ID(const Depsgraph *graph, + const ID *id, + DEGForeachIDCallback callback, + void *user_data) +{ + ForeachIDData data; + data.callback = callback; + data.user_data = user_data; + deg_foreach_dependent_operation(graph, id, deg_foreach_dependent_ID_callback, &data); +} + +void deg_foreach_ancestor_ID(const Depsgraph *graph, + const ID *id, + DEGForeachIDCallback callback, + void *user_data) { /* Start with getting ID node from the graph. */ IDNode *target_id_node = graph->find_id_node(id); @@ -196,15 +249,14 @@ static void deg_foreach_ancestor_ID(const Depsgraph *graph, } } -static void deg_foreach_id(const Depsgraph *depsgraph, - DEGForeachIDCallback callback, - void *user_data) +void deg_foreach_id(const Depsgraph *depsgraph, DEGForeachIDCallback callback, void *user_data) { for (const IDNode *id_node : depsgraph->id_nodes) { callback(id_node->id_orig, user_data); } } +} // namespace } // namespace DEG void DEG_foreach_dependent_ID(const Depsgraph *depsgraph, @@ -215,6 +267,15 @@ void DEG_foreach_dependent_ID(const Depsgraph *depsgraph, DEG::deg_foreach_dependent_ID((const DEG::Depsgraph *)depsgraph, id, callback, user_data); } +void DEG_foreach_dependent_ID_component(const Depsgraph *depsgraph, + const ID *id, + DEGForeachIDComponentCallback callback, + void *user_data) +{ + DEG::deg_foreach_dependent_ID_component( + (const DEG::Depsgraph *)depsgraph, id, callback, user_data); +} + void DEG_foreach_ancestor_ID(const Depsgraph *depsgraph, const ID *id, DEGForeachIDCallback callback, |