/**************************************************************************** ** ** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:COMM$ ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** $QT_END_LICENSE$ ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ****************************************************************************/ #ifndef QT3DCORE_QNODEVISITOR_P_H #define QT3DCORE_QNODEVISITOR_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience // of other Qt classes. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include #include QT_BEGIN_NAMESPACE namespace Qt3DCore { class Q_3DCORESHARED_EXPORT QNodeVisitor { public: QNodeVisitor(); virtual ~QNodeVisitor(); template void traverse(QNode *rootNode_, NodeVisitorFunc fN) { startTraversing(rootNode_, createFunctor(fN)); } template void traverse(QNode *rootNode_, Obj *instance, NodeVisitorFunc fN) { startTraversing(rootNode_, createFunctor(instance, fN)); } template void traverse(QNode *rootNode_, NodeVisitorFunc fN, EntityVisitorFunc fE) { startTraversing(rootNode_, createFunctor(fN), createFunctor(fE)); } template void traverse(QNode *rootNode_, Obj *instance, NodeVisitorFunc fN, EntityVisitorFunc fE) { startTraversing(rootNode_, createFunctor(instance, fN), createFunctor(instance, fE)); } QNode *rootNode() const; QNode *currentNode() const; void setPath(QNodeVector path); QNodeVector path() const; void append(QNode *n); void pop_back(); private: Q_DISABLE_COPY(QNodeVisitor) QNodeVector m_path; template void startTraversing(QNode *rootNode_, NodeVisitorFunctor fN) { setPath(QNodeVector() << rootNode_); if (rootNode_) visitNode(rootNode_, fN); } template void startTraversing(QNode *rootNode_, NodeVisitorFunctor fN, EntityVisitorFunctor fE) { setPath(QNodeVector() << rootNode_); QEntity* rootEntity = qobject_cast(rootNode_); if (rootEntity) visitEntity(rootEntity, fN, fE); else if (rootNode_) visitNode(rootNode_, fN, fE); } template void visitNode(QNode *nd, NodeVisitorFunctor &fN) { fN(nd); traverseChildren(fN); } template void visitNode(QNode *nd, NodeVisitorFunctor &fN, EntityVisitorFunctor &fE) { fN(nd); traverseChildren(fN, fE); } template void visitEntity(QEntity *ent, NodeVisitorFunctor &fN, EntityVisitorFunctor &fE) { fE(ent); visitNode(ent, fN, fE); } template void traverseChildren(NodeVisitorFunctor &fN, EntityVisitorFunctor &fE) { for (QObject *n : currentNode()->children()) { QNode *node = qobject_cast(n); if (node != nullptr) outerVisitNode(node, fN, fE); } // of children iteration } template void traverseChildren(NodeVisitorFunctor &fN) { for (QObject *n : currentNode()->children()) { QNode *node = qobject_cast(n); if (node != nullptr) outerVisitNode(node, fN); } // of children iteration } template void outerVisitNode(QNode *n, NodeVisitorFunctor &fN, EntityVisitorFunctor &fE) { append(n); QEntity* e = qobject_cast(n); if (e) { visitEntity(e, fN, fE); } else { visitNode(n, fN, fE); } pop_back(); } template void outerVisitNode(QNode *n, NodeVisitorFunctor &fN) { append(n); visitNode(n, fN); pop_back(); } template class FunctionFunctor { public: typedef ReturnType (*functionPtr)(NodeType); FunctionFunctor(functionPtr fPtr) : m_functionPointer(fPtr) {} void operator()(NodeType node) { (*m_functionPointer)(node); } private: functionPtr m_functionPointer; }; template class MemberFunctionFunctor { public: typedef ReturnType (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 class ConstMemberFunctionFunctor { public: typedef ReturnType (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 const T& createFunctor(const T& t) { return t; } template FunctionFunctor createFunctor(ReturnType (*fPtr)(NodeType)) { return FunctionFunctor(fPtr); } template MemberFunctionFunctor createFunctor(C *instance, ReturnType (C::*fPtr)(NodeType)) { return MemberFunctionFunctor(instance, fPtr); } template ConstMemberFunctionFunctor createFunctor(C *instance, ReturnType (C::*fPtr)(NodeType) const) { return ConstMemberFunctionFunctor(instance, fPtr); } }; } // namespace Qt3DCore QT_END_NAMESPACE #endif // QT3DCORE_QNODEVISITOR_P_H