diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2014-10-15 08:00:59 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2014-10-17 15:11:25 +0200 |
commit | fccd1f97a69b483a7048d3005e38e427db16a9eb (patch) | |
tree | 4a717e3e50f894542a01da7237144f4c51a102f8 /src/core/nodes | |
parent | 30bb04b8290dc78faa8ccfd89387e0f0949c0a24 (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.cpp | 54 | ||||
-rw-r--r-- | src/core/nodes/nodevisitor.h | 161 |
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 |