summaryrefslogtreecommitdiffstats
path: root/src/core/nodes/qnode_p.h
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2016-05-20 17:11:37 +0200
committerSean Harmer <sean.harmer@kdab.com>2016-05-23 16:31:55 +0000
commit073930f2ef030b3019c323999d910185f4639d9b (patch)
tree0c2bba252f7a92d4f3841fbe42eeca27e2a8a838 /src/core/nodes/qnode_p.h
parent15dace7c02bc5acdf02f94c8be08fec1a792383c (diff)
Shared node bookkeeping
Any time a property references a QNode there is a risk that the node gets destroyed and then the property is left pointing to a dangling pointer. To handle such cases, setters of such properties are able to use a helper that internally connect QObject::destroyed signal to a setter removal method. Change-Id: I42428c851d0e3d2d88ab0cf6a5b75605334ec648 Task-number: QTBUG-53456 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/core/nodes/qnode_p.h')
-rw-r--r--src/core/nodes/qnode_p.h29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/core/nodes/qnode_p.h b/src/core/nodes/qnode_p.h
index e290ffe32..8f48dd728 100644
--- a/src/core/nodes/qnode_p.h
+++ b/src/core/nodes/qnode_p.h
@@ -57,6 +57,7 @@
#include <Qt3DCore/private/qchangearbiter_p.h>
#include <Qt3DCore/private/qt3dcore_global_p.h>
#include "propertychangehandler_p.h"
+#include <functional>
QT_BEGIN_NAMESPACE
@@ -100,6 +101,33 @@ public:
static QNodePrivate *get(QNode *q);
static void nodePtrDeleter(QNode *q);
+ template<typename Caller, typename NodeType>
+ using DestructionFunction = void (Caller::*)(NodeType *);
+
+ template<typename Caller, typename NodeType, typename PropertyType>
+ void registerDestructionHelper(NodeType *, DestructionFunction<Caller, NodeType>, PropertyType);
+
+ template<typename Caller, typename NodeType>
+ void registerDestructionHelper(NodeType *node, DestructionFunction<Caller, NodeType> func, NodeType *&)
+ {
+ // If the node is destoyed, we make sure not to keep a dangling pointer to it
+ auto f = std::bind(func, static_cast<Caller *>(q_func()), nullptr);
+ m_destructionConnections.insert(node, QObject::connect(node, &QNode::nodeDestroyed, f));
+ }
+
+ template<typename Caller, typename NodeType>
+ void registerDestructionHelper(NodeType *node, DestructionFunction<Caller, NodeType> func, QVector<NodeType*> &)
+ {
+ // If the node is destoyed, we make sure not to keep a dangling pointer to it
+ auto f = std::bind(func, static_cast<Caller *>(q_func()), node);
+ m_destructionConnections.insert(node, QObject::connect(node, &QNode::nodeDestroyed, f));
+ }
+
+ void unregisterDestructionHelper(QNode *node)
+ {
+ QObject::disconnect(m_destructionConnections.take(node));
+ }
+
private:
void notifyCreationChange();
void notifyDestructionChangesAndRemoveFromScene();
@@ -118,6 +146,7 @@ private:
friend class PropertyChangeHandler<QNodePrivate>;
bool m_propertyChangesSetup;
PropertyChangeHandler<QNodePrivate> m_signals;
+ QHash<QNode *, QMetaObject::Connection> m_destructionConnections;
};
} // namespace Qt3DCore