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#ifndef QT3DCORE_QNODEVISITOR_P_H
4#define QT3DCORE_QNODEVISITOR_P_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists for the convenience
11// of other Qt classes. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include <Qt3DCore/qentity.h>
18#include <Qt3DCore/qnode.h>
19#include <Qt3DCore/qt3dcore_global.h>
20#include <private/qglobal_p.h>
21
22QT_BEGIN_NAMESPACE
23
24namespace Qt3DCore
25{
26
27class Q_3DCORESHARED_EXPORT QNodeVisitor
28{
29public:
30 QNodeVisitor();
31 virtual ~QNodeVisitor();
32
33 template<typename NodeVisitorFunc>
34 void traverse(QNode *rootNode_, NodeVisitorFunc fN)
35 {
36 startTraversing(rootNode_, createFunctor(fN));
37 }
38
39 template<typename Obj, typename NodeVisitorFunc>
40 void traverse(QNode *rootNode_, Obj *instance, NodeVisitorFunc fN)
41 {
42 startTraversing(rootNode_, createFunctor(instance, fN));
43 }
44
45 template<typename NodeVisitorFunc, typename EntityVisitorFunc>
46 void traverse(QNode *rootNode_, NodeVisitorFunc fN, EntityVisitorFunc fE)
47 {
48 startTraversing(rootNode_, createFunctor(fN), createFunctor(fE));
49 }
50
51 template<typename Obj, typename NodeVisitorFunc, typename EntityVisitorFunc>
52 void traverse(QNode *rootNode_, Obj *instance, NodeVisitorFunc fN, EntityVisitorFunc fE)
53 {
54 startTraversing(rootNode_, createFunctor(instance, fN), createFunctor(instance, fE));
55 }
56
57 QNode *rootNode() const;
58 QNode *currentNode() const;
59 void setPath(QNodeVector path);
60 QNodeVector path() const;
61 void append(QNode *n);
62 void pop_back();
63
64private:
65 Q_DISABLE_COPY(QNodeVisitor)
66 QNodeVector m_path;
67
68 template<typename NodeVisitorFunctor>
69 void startTraversing(QNode *rootNode_, NodeVisitorFunctor fN)
70 {
71 setPath(QNodeVector() << rootNode_);
72 if (rootNode_)
73 visitNode(rootNode_, fN);
74 }
75
76 template<typename NodeVisitorFunctor, typename EntityVisitorFunctor>
77 void startTraversing(QNode *rootNode_, NodeVisitorFunctor fN, EntityVisitorFunctor fE)
78 {
79 setPath(QNodeVector() << rootNode_);
80 QEntity* rootEntity = qobject_cast<QEntity *>(object: rootNode_);
81
82 if (rootEntity)
83 visitEntity(rootEntity, fN, fE);
84 else if (rootNode_)
85 visitNode(rootNode_, fN, fE);
86 }
87
88 template<typename NodeVisitorFunctor>
89 void visitNode(QNode *nd, NodeVisitorFunctor &fN)
90 {
91 fN(nd);
92 traverseChildren(fN);
93 }
94
95 template<typename NodeVisitorFunctor, typename EntityVisitorFunctor>
96 void visitNode(QNode *nd, NodeVisitorFunctor &fN, EntityVisitorFunctor &fE)
97 {
98 fN(nd);
99 traverseChildren(fN, fE);
100 }
101
102 template<typename NodeVisitorFunctor, typename EntityVisitorFunctor>
103 void visitEntity(QEntity *ent, NodeVisitorFunctor &fN, EntityVisitorFunctor &fE)
104 {
105 fE(ent);
106 visitNode(ent, fN, fE);
107 }
108
109 template<typename NodeVisitorFunctor, typename EntityVisitorFunctor>
110 void traverseChildren(NodeVisitorFunctor &fN, EntityVisitorFunctor &fE)
111 {
112 // iterate on copy, in case user code changes children list
113 const QObjectList children = currentNode()->children();
114 for (QObject *n : children) {
115 QNode *node = qobject_cast<QNode *>(object: n);
116 if (node != nullptr)
117 outerVisitNode(node, fN, fE);
118 } // of children iteration
119 }
120
121 template<typename NodeVisitorFunctor>
122 void traverseChildren(NodeVisitorFunctor &fN)
123 {
124 // iterate on copy, in case user code changes children list
125 const QObjectList children = currentNode()->children();
126 for (QObject *n : children) {
127 QNode *node = qobject_cast<QNode *>(object: n);
128 if (node != nullptr)
129 outerVisitNode(node, fN);
130 } // of children iteration
131 }
132
133 template<typename NodeVisitorFunctor, typename EntityVisitorFunctor>
134 void outerVisitNode(QNode *n, NodeVisitorFunctor &fN, EntityVisitorFunctor &fE)
135 {
136 append(n);
137 QEntity* e = qobject_cast<QEntity *>(object: n);
138 if (e) {
139 visitEntity(e, fN, fE);
140 } else {
141 visitNode(n, fN, fE);
142 }
143 pop_back();
144 }
145
146 template<typename NodeVisitorFunctor>
147 void outerVisitNode(QNode *n, NodeVisitorFunctor &fN)
148 {
149 append(n);
150 visitNode(n, fN);
151 pop_back();
152 }
153
154 template <typename ReturnType, typename NodeType>
155 class FunctionFunctor {
156 public:
157 typedef ReturnType (*functionPtr)(NodeType);
158
159 FunctionFunctor(functionPtr fPtr)
160 : m_functionPointer(fPtr)
161 {}
162
163 void operator()(NodeType node)
164 {
165 (*m_functionPointer)(node);
166 }
167
168 private:
169 functionPtr m_functionPointer;
170 };
171
172 template <typename C, typename ReturnType, typename NodeType>
173 class MemberFunctionFunctor {
174 public:
175 typedef ReturnType (C::*functionPtr)(NodeType);
176
177 MemberFunctionFunctor(C* instance, functionPtr fPtr)
178 : m_instance(instance)
179 , m_functionPointer(fPtr)
180 {}
181
182 void operator()(NodeType node)
183 {
184 (*m_instance.*m_functionPointer)(node);
185 }
186
187 private:
188 C *m_instance;
189 functionPtr m_functionPointer;
190 };
191
192 template <typename C, typename ReturnType, typename NodeType>
193 class ConstMemberFunctionFunctor {
194 public:
195 typedef ReturnType (C::*functionPtr)(NodeType) const;
196
197 ConstMemberFunctionFunctor(C* instance, functionPtr fPtr)
198 : m_instance(instance)
199 , m_functionPointer(fPtr)
200 {}
201
202 void operator()(NodeType node) const
203 {
204 (*m_instance.*m_functionPointer)(node);
205 }
206
207 private:
208 C *m_instance;
209 functionPtr m_functionPointer;
210 };
211
212 template <typename T>
213 const T& createFunctor(const T& t)
214 {
215 return t;
216 }
217
218 template <typename ReturnType, typename NodeType>
219 FunctionFunctor<ReturnType, NodeType> createFunctor(ReturnType (*fPtr)(NodeType))
220 {
221 return FunctionFunctor<ReturnType, NodeType>(fPtr);
222 }
223
224 template <typename C, typename ReturnType, typename NodeType>
225 MemberFunctionFunctor<C, ReturnType, NodeType> createFunctor(C *instance, ReturnType (C::*fPtr)(NodeType))
226 {
227 return MemberFunctionFunctor<C, ReturnType, NodeType>(instance, fPtr);
228 }
229
230 template <typename C, typename ReturnType, typename NodeType>
231 ConstMemberFunctionFunctor<C, ReturnType, NodeType> createFunctor(C *instance, ReturnType (C::*fPtr)(NodeType) const)
232 {
233 return ConstMemberFunctionFunctor<C, ReturnType, NodeType>(instance, fPtr);
234 }
235};
236
237} // namespace Qt3DCore
238
239QT_END_NAMESPACE
240
241#endif // QT3DCORE_QNODEVISITOR_P_H
242

source code of qt3d/src/core/nodes/qnodevisitor_p.h