1 | // Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "clipblendnodevisitor_p.h" |
5 | #include <Qt3DAnimation/private/managers_p.h> |
6 | #include <Qt3DAnimation/private/clipblendnode_p.h> |
7 | |
8 | QT_BEGIN_NAMESPACE |
9 | |
10 | namespace Qt3DAnimation { |
11 | namespace Animation { |
12 | |
13 | /*! |
14 | \class ClipBlendNodeVisitor |
15 | \internal |
16 | Visits a blend tree in either pre- or post-order manner, optionally taking care |
17 | to only visit the nodes that are dependencies of evaluating the blend |
18 | tree. |
19 | */ |
20 | ClipBlendNodeVisitor::ClipBlendNodeVisitor(ClipBlendNodeManager *manager, |
21 | TraversalOrder order, |
22 | NodeFilter filter) |
23 | : m_manager(manager) |
24 | , m_order(order) |
25 | , m_filter(filter) |
26 | { |
27 | } |
28 | |
29 | void ClipBlendNodeVisitor::traverse(Qt3DCore::QNodeId rootId, |
30 | const VisitFunction &visitFunction) const |
31 | { |
32 | ClipBlendNode *node = m_manager->lookupNode(id: rootId); |
33 | if (node != nullptr) { |
34 | switch (m_order) { |
35 | case PreOrder: { |
36 | switch (m_filter) { |
37 | case VisitAllNodes: |
38 | visitPreOrderAllNodes(node, visitFunction); |
39 | break; |
40 | |
41 | case VisitOnlyDependencies: |
42 | visitPreOrderDependencyNodes(node, visitFunction); |
43 | break; |
44 | } |
45 | |
46 | break; |
47 | } |
48 | |
49 | case PostOrder: { |
50 | switch (m_filter) { |
51 | case VisitAllNodes: |
52 | visitPostOrderAllNodes(node, visitFunction); |
53 | break; |
54 | |
55 | case VisitOnlyDependencies: |
56 | visitPostOrderDependencyNodes(node, visitFunction); |
57 | break; |
58 | } |
59 | |
60 | break; |
61 | } |
62 | } |
63 | } |
64 | } |
65 | |
66 | /*! |
67 | \internal |
68 | Leaf to root traversal (Pre-order traversal) visiting all nodes even if |
69 | they will not participate in current evaluation of the blend tree. |
70 | */ |
71 | void ClipBlendNodeVisitor::visitPreOrderAllNodes(ClipBlendNode *node, |
72 | const VisitFunction &visitFunction) const |
73 | { |
74 | visitFunction(node); |
75 | const Qt3DCore::QNodeIdVector childIds = node->allDependencyIds(); |
76 | for (const Qt3DCore::QNodeId &childId: childIds) { |
77 | ClipBlendNode *childNode = m_manager->lookupNode(id: childId); |
78 | if (childNode != nullptr) |
79 | visitPreOrderAllNodes(node: childNode, visitFunction); |
80 | } |
81 | } |
82 | |
83 | /*! |
84 | \internal |
85 | Leaf to root traversal (Post-order traversal) visiting all nodes even if |
86 | they will not participate in current evaluation of the blend tree. |
87 | */ |
88 | void ClipBlendNodeVisitor::visitPostOrderAllNodes(ClipBlendNode *node, |
89 | const VisitFunction &visitFunction) const |
90 | { |
91 | const Qt3DCore::QNodeIdVector childIds = node->allDependencyIds(); |
92 | for (const Qt3DCore::QNodeId &childId: childIds) { |
93 | ClipBlendNode *childNode = m_manager->lookupNode(id: childId); |
94 | if (childNode != nullptr) |
95 | visitPostOrderAllNodes(node: childNode, visitFunction); |
96 | } |
97 | visitFunction(node); |
98 | } |
99 | |
100 | /*! |
101 | \internal |
102 | Leaf to root traversal (Pre-order traversal) visiting only nodes required |
103 | to evaluate the blend tree given its current state. |
104 | */ |
105 | void ClipBlendNodeVisitor::visitPreOrderDependencyNodes(ClipBlendNode *node, |
106 | const VisitFunction &visitFunction) const |
107 | { |
108 | visitFunction(node); |
109 | const Qt3DCore::QNodeIdVector childIds = node->currentDependencyIds(); |
110 | for (const Qt3DCore::QNodeId &childId: childIds) { |
111 | ClipBlendNode *childNode = m_manager->lookupNode(id: childId); |
112 | if (childNode != nullptr) |
113 | visitPreOrderDependencyNodes(node: childNode, visitFunction); |
114 | } |
115 | } |
116 | |
117 | /*! |
118 | \internal |
119 | Leaf to root traversal (Post-order traversal) visiting only nodes required |
120 | to evaluate the blend tree given its current state. |
121 | */ |
122 | void ClipBlendNodeVisitor::visitPostOrderDependencyNodes(ClipBlendNode *node, |
123 | const VisitFunction &visitFunction) const |
124 | { |
125 | const Qt3DCore::QNodeIdVector childIds = node->currentDependencyIds(); |
126 | for (const Qt3DCore::QNodeId &childId: childIds) { |
127 | ClipBlendNode *childNode = m_manager->lookupNode(id: childId); |
128 | if (childNode != nullptr) |
129 | visitPostOrderDependencyNodes(node: childNode, visitFunction); |
130 | } |
131 | visitFunction(node); |
132 | } |
133 | |
134 | } // Animation |
135 | } // Qt3DAnimation |
136 | |
137 | QT_END_NAMESPACE |
138 | |