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 for (QObject *n : currentNode()->children()) {
113 QNode *node = qobject_cast<QNode *>(object: n);
114 if (node != nullptr)
115 outerVisitNode(node, fN, fE);
116 } // of children iteration
117 }
118
119 template<typename NodeVisitorFunctor>
120 void traverseChildren(NodeVisitorFunctor &fN)
121 {
122 for (QObject *n : currentNode()->children()) {
123 QNode *node = qobject_cast<QNode *>(object: n);
124 if (node != nullptr)
125 outerVisitNode(node, fN);
126 } // of children iteration
127 }
128
129 template<typename NodeVisitorFunctor, typename EntityVisitorFunctor>
130 void outerVisitNode(QNode *n, NodeVisitorFunctor &fN, EntityVisitorFunctor &fE)
131 {
132 append(n);
133 QEntity* e = qobject_cast<QEntity *>(object: n);
134 if (e) {
135 visitEntity(e, fN, fE);
136 } else {
137 visitNode(n, fN, fE);
138 }
139 pop_back();
140 }
141
142 template<typename NodeVisitorFunctor>
143 void outerVisitNode(QNode *n, NodeVisitorFunctor &fN)
144 {
145 append(n);
146 visitNode(n, fN);
147 pop_back();
148 }
149
150 template <typename ReturnType, typename NodeType>
151 class FunctionFunctor {
152 public:
153 typedef ReturnType (*functionPtr)(NodeType);
154
155 FunctionFunctor(functionPtr fPtr)
156 : m_functionPointer(fPtr)
157 {}
158
159 void operator()(NodeType node)
160 {
161 (*m_functionPointer)(node);
162 }
163
164 private:
165 functionPtr m_functionPointer;
166 };
167
168 template <typename C, typename ReturnType, typename NodeType>
169 class MemberFunctionFunctor {
170 public:
171 typedef ReturnType (C::*functionPtr)(NodeType);
172
173 MemberFunctionFunctor(C* instance, functionPtr fPtr)
174 : m_instance(instance)
175 , m_functionPointer(fPtr)
176 {}
177
178 void operator()(NodeType node)
179 {
180 (*m_instance.*m_functionPointer)(node);
181 }
182
183 private:
184 C *m_instance;
185 functionPtr m_functionPointer;
186 };
187
188 template <typename C, typename ReturnType, typename NodeType>
189 class ConstMemberFunctionFunctor {
190 public:
191 typedef ReturnType (C::*functionPtr)(NodeType) const;
192
193 ConstMemberFunctionFunctor(C* instance, functionPtr fPtr)
194 : m_instance(instance)
195 , m_functionPointer(fPtr)
196 {}
197
198 void operator()(NodeType node) const
199 {
200 (*m_instance.*m_functionPointer)(node);
201 }
202
203 private:
204 C *m_instance;
205 functionPtr m_functionPointer;
206 };
207
208 template <typename T>
209 const T& createFunctor(const T& t)
210 {
211 return t;
212 }
213
214 template <typename ReturnType, typename NodeType>
215 FunctionFunctor<ReturnType, NodeType> createFunctor(ReturnType (*fPtr)(NodeType))
216 {
217 return FunctionFunctor<ReturnType, NodeType>(fPtr);
218 }
219
220 template <typename C, typename ReturnType, typename NodeType>
221 MemberFunctionFunctor<C, ReturnType, NodeType> createFunctor(C *instance, ReturnType (C::*fPtr)(NodeType))
222 {
223 return MemberFunctionFunctor<C, ReturnType, NodeType>(instance, fPtr);
224 }
225
226 template <typename C, typename ReturnType, typename NodeType>
227 ConstMemberFunctionFunctor<C, ReturnType, NodeType> createFunctor(C *instance, ReturnType (C::*fPtr)(NodeType) const)
228 {
229 return ConstMemberFunctionFunctor<C, ReturnType, NodeType>(instance, fPtr);
230 }
231};
232
233} // namespace Qt3DCore
234
235QT_END_NAMESPACE
236
237#endif // QT3DCORE_QNODEVISITOR_P_H
238

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