summaryrefslogtreecommitdiffstats
path: root/src/core/nodes
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2014-10-15 08:00:59 +0200
committerPaul Lemire <paul.lemire@kdab.com>2014-10-17 15:11:25 +0200
commitfccd1f97a69b483a7048d3005e38e427db16a9eb (patch)
tree4a717e3e50f894542a01da7237144f4c51a102f8 /src/core/nodes
parent30bb04b8290dc78faa8ccfd89387e0f0949c0a24 (diff)
NodeVisitor refactoring
Allow to pass a function pointers to NodeVisitor called during visitNode and visitEntity so that using NodeVisitor doesn't require subclassing. Change-Id: Ic87f71bcd0d788a1e08dfac67ef08c13566b2b2e Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/core/nodes')
-rw-r--r--src/core/nodes/nodevisitor.cpp54
-rw-r--r--src/core/nodes/nodevisitor.h161
2 files changed, 143 insertions, 72 deletions
diff --git a/src/core/nodes/nodevisitor.cpp b/src/core/nodes/nodevisitor.cpp
index f830b6bb4..31b582d4f 100644
--- a/src/core/nodes/nodevisitor.cpp
+++ b/src/core/nodes/nodevisitor.cpp
@@ -41,9 +41,6 @@
#include "nodevisitor.h"
-#include "qnode.h"
-#include "qentity.h"
-
QT_BEGIN_NAMESPACE
namespace Qt3D {
@@ -57,19 +54,6 @@ NodeVisitor::~NodeVisitor()
{
}
-void NodeVisitor::traverse(QNode *rootNode)
-{
- m_path = NodeList() << rootNode;
-
- m_matrixStack.clear();
- QEntity* rootEntity = qobject_cast<QEntity *>(rootNode);
-
- if (rootEntity)
- visitEntity(rootEntity);
- else
- visitNode(rootNode);
-}
-
QNode* NodeVisitor::rootNode() const
{
return m_path.front();
@@ -80,11 +64,6 @@ QNode* NodeVisitor::currentNode() const
return m_path.back();
}
-QMatrix4x4 NodeVisitor::currentMatrix() const
-{
- return m_matrixStack.back();
-}
-
NodeList NodeVisitor::path() const
{
return m_path;
@@ -95,39 +74,6 @@ void NodeVisitor::setTraverseDisabled(bool on)
m_traverseDisabled = on;
}
-void NodeVisitor::visitNode(QNode *nd)
-{
- Q_UNUSED(nd);
- traverseChildren();
-}
-
-void NodeVisitor::visitEntity(QEntity *nd)
-{
- visitNode(nd);
-}
-
-void NodeVisitor::traverseChildren()
-{
- foreach (QObject *n, currentNode()->children()) {
- QNode *node = qobject_cast<QNode *>(n);
- if (node != Q_NULLPTR)
- outerVisitNode(node);
- } // of children iteration
-}
-
-void NodeVisitor::outerVisitNode(QNode *n)
-{
- m_path.append(n);
- QEntity* e = qobject_cast<QEntity *>(n);
- if (e) {
- visitEntity(e);
- m_path.pop_back();
- }
- else {
- visitNode(n);
- }
-}
-
} // namespace Qt3D
QT_END_NAMESPACE
diff --git a/src/core/nodes/nodevisitor.h b/src/core/nodes/nodevisitor.h
index 9b4e9c350..b5a5b16b4 100644
--- a/src/core/nodes/nodevisitor.h
+++ b/src/core/nodes/nodevisitor.h
@@ -43,16 +43,14 @@
#define NODEVISITOR_H
#include <Qt3DCore/qt3dcore_global.h>
-#include <QMatrix4x4>
+#include <Qt3DCore/qnode.h>
+#include <Qt3DCore/qentity.h>
QT_BEGIN_NAMESPACE
namespace Qt3D
{
-class QNode;
-class QEntity;
-
typedef QList<QNode *> NodeList;
class QT3DCORESHARED_EXPORT NodeVisitor
@@ -61,30 +59,157 @@ public:
NodeVisitor();
virtual ~NodeVisitor();
- void traverse(QNode *rootNode);
+ template<typename NodeVisitorFunc, typename EntityVisitorFunc>
+ void traverse(QNode *rootNode, NodeVisitorFunc fN, EntityVisitorFunc fE)
+ {
+ startTraversing(rootNode, createFunctor(fN), createFunctor(fE));
+ }
- QNode *rootNode() const;
+ template<typename Obj, typename NodeVisitorFunc, typename EntityVisitorFunc>
+ void traverse(QNode *rootNode, Obj *instance, NodeVisitorFunc fN, EntityVisitorFunc fE)
+ {
+ startTraversing(rootNode, createFunctor(instance, fN), createFunctor(instance, fE));
+ }
+ QNode *rootNode() const;
QNode *currentNode() const;
-
- QMatrix4x4 currentMatrix() const;
-
NodeList path() const;
-
void setTraverseDisabled(bool on);
-protected:
- virtual void visitNode(QNode *nd);
- virtual void visitEntity(QEntity *ent);
-
- void traverseChildren();
-
private:
NodeList m_path;
- QVector<QMatrix4x4> m_matrixStack;
bool m_traverseDisabled;
- void outerVisitNode(QNode *n);
+ template<typename NodeVisitorFunctor, typename EntityVisitorFunctor>
+ void startTraversing(QNode *rootNode, NodeVisitorFunctor fN, EntityVisitorFunctor fE)
+ {
+ m_path = NodeList() << rootNode;
+ QEntity* rootEntity = qobject_cast<QEntity *>(rootNode);
+
+ if (rootEntity)
+ visitEntity(rootEntity, fN, fE);
+ else
+ visitNode(rootNode, fN, fE);
+ }
+
+ template<typename NodeVisitorFunctor, typename EntityVisitorFunctor>
+ void visitNode(QNode *nd, NodeVisitorFunctor &fN, EntityVisitorFunctor &fE)
+ {
+ fN(nd);
+ traverseChildren(fN, fE);
+ }
+
+ template<typename NodeVisitorFunctor, typename EntityVisitorFunctor>
+ void visitEntity(QEntity *ent, NodeVisitorFunctor &fN, EntityVisitorFunctor &fE)
+ {
+ fE(ent);
+ visitNode(ent, fN, fE);
+ }
+
+ template<typename NodeVisitorFunctor, typename EntityVisitorFunctor>
+ void traverseChildren(NodeVisitorFunctor &fN, EntityVisitorFunctor &fE)
+ {
+ Q_FOREACH (QObject *n, currentNode()->children()) {
+ QNode *node = qobject_cast<QNode *>(n);
+ if (node != Q_NULLPTR)
+ outerVisitNode(node, fN, fE);
+ } // of children iteration
+ }
+
+ template<typename NodeVisitorFunctor, typename EntityVisitorFunctor>
+ void outerVisitNode(QNode *n, NodeVisitorFunctor &fN, EntityVisitorFunctor &fE)
+ {
+ m_path.append(n);
+ QEntity* e = qobject_cast<QEntity *>(n);
+ if (e) {
+ visitEntity(e, fN, fE);
+ m_path.pop_back();
+ } else {
+ visitNode(n, fN, fE);
+ }
+ }
+
+ template <typename NodeType>
+ class FunctionFunctor {
+ public:
+ typedef void (*functionPtr)(NodeType);
+
+ FunctionFunctor(functionPtr fPtr)
+ : m_functionPointer(fPtr)
+ {}
+
+ void operator()(NodeType node)
+ {
+ (*m_functionPointer)(node);
+ }
+
+ private:
+ functionPtr m_functionPointer;
+ };
+
+ template <typename C, typename NodeType>
+ class MemberFunctionFunctor {
+ public:
+ typedef void (C::*functionPtr)(NodeType);
+
+ MemberFunctionFunctor(C* instance, functionPtr fPtr)
+ : m_instance(instance)
+ , m_functionPointer(fPtr)
+ {}
+
+ void operator()(NodeType node)
+ {
+ (*m_instance.*m_functionPointer)(node);
+ }
+
+ private:
+ C *m_instance;
+ functionPtr m_functionPointer;
+ };
+
+ template <typename C, typename NodeType>
+ class ConstMemberFunctionFunctor {
+ public:
+ typedef void (C::*functionPtr)(NodeType) const;
+
+ ConstMemberFunctionFunctor(C* instance, functionPtr fPtr)
+ : m_instance(instance)
+ , m_functionPointer(fPtr)
+ {}
+
+ void operator()(NodeType node) const
+ {
+ (*m_instance.*m_functionPointer)(node);
+ }
+
+ private:
+ C *m_instance;
+ functionPtr m_functionPointer;
+ };
+
+ template <typename T>
+ const T& createFunctor(const T& t)
+ {
+ return t;
+ }
+
+ template <typename NodeType>
+ FunctionFunctor<NodeType> createFunctor(void (*fPtr)(NodeType))
+ {
+ return FunctionFunctor<NodeType>(fPtr);
+ }
+
+ template <typename C, typename NodeType>
+ MemberFunctionFunctor<C, NodeType> createFunctor(C *instance, void (C::*fPtr)(NodeType))
+ {
+ return MemberFunctionFunctor<C, NodeType>(instance, fPtr);
+ }
+
+ template <typename C, typename NodeType>
+ ConstMemberFunctionFunctor<C, NodeType> createFunctor(C *instance, void (C::*fPtr)(NodeType) const)
+ {
+ return ConstMemberFunctionFunctor<C, NodeType>(instance, fPtr);
+ }
};
} // namespace Qt3D