summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-06-15 03:02:52 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-06-15 03:02:52 +0200
commite0548a3d24bda6ddee02c38d3abee285ddf33a6d (patch)
tree06c9d30eab9d00657a8bee8510774433c5cb0c25 /src/core
parent666a645d1edc98dfea92fdaf7eaeed10c86dbc56 (diff)
parent50d41e6f0e7dd97f3d4cbd68423d59cacd4b7700 (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Diffstat (limited to 'src/core')
-rw-r--r--src/core/nodes/qcomponent.cpp5
-rw-r--r--src/core/nodes/qentity.cpp22
-rw-r--r--src/core/nodes/qentity_p.h1
-rw-r--r--src/core/nodes/qnode_p.h8
4 files changed, 34 insertions, 2 deletions
diff --git a/src/core/nodes/qcomponent.cpp b/src/core/nodes/qcomponent.cpp
index 5ca49ff30..f67989b1e 100644
--- a/src/core/nodes/qcomponent.cpp
+++ b/src/core/nodes/qcomponent.cpp
@@ -134,10 +134,13 @@ QComponent::~QComponent()
{
Q_D(QComponent);
- for (QEntity *entity : qAsConst(d->m_entities)) {
+ // iterate on copy since removeEntity removes from the list, invalidating the iterator
+ const auto entities = std::move(d->m_entities);
+ for (QEntity *entity : entities) {
QEntityPrivate *entityPimpl = static_cast<QEntityPrivate *>(QEntityPrivate::get(entity));
if (entityPimpl)
entityPimpl->m_components.removeAll(this);
+ d->removeEntity(entity);
}
}
diff --git a/src/core/nodes/qentity.cpp b/src/core/nodes/qentity.cpp
index 164e0feff..1d16e828e 100644
--- a/src/core/nodes/qentity.cpp
+++ b/src/core/nodes/qentity.cpp
@@ -95,6 +95,26 @@ QEntityPrivate::~QEntityPrivate()
{
}
+/*! \internal */
+void QEntityPrivate::removeDestroyedComponent(QComponent *comp)
+{
+ // comp is actually no longer a QComponent, just a QObject
+
+ Q_CHECK_PTR(comp);
+ qCDebug(Nodes) << Q_FUNC_INFO << comp;
+ Q_Q(QEntity);
+
+ if (m_changeArbiter) {
+ const auto componentRemovedChange = QComponentRemovedChangePtr::create(q, comp);
+ notifyObservers(componentRemovedChange);
+ }
+
+ m_components.removeOne(comp);
+
+ // Remove bookkeeping connection
+ unregisterDestructionHelper(comp);
+}
+
/*!
Constructs a new Qt3DCore::QEntity instance with \a parent as parent.
*/
@@ -164,7 +184,7 @@ void QEntity::addComponent(QComponent *comp)
d->m_components.append(comp);
// Ensures proper bookkeeping
- d->registerDestructionHelper(comp, &QEntity::removeComponent, d->m_components);
+ d->registerPrivateDestructionHelper(comp, &QEntityPrivate::removeDestroyedComponent);
if (d->m_changeArbiter) {
const auto componentAddedChange = QComponentAddedChangePtr::create(this, comp);
diff --git a/src/core/nodes/qentity_p.h b/src/core/nodes/qentity_p.h
index ee6db75db..803754c87 100644
--- a/src/core/nodes/qentity_p.h
+++ b/src/core/nodes/qentity_p.h
@@ -82,6 +82,7 @@ public :
return typedComponents;
}
+ void removeDestroyedComponent(QComponent *comp);
QComponentVector m_components;
mutable QNodeId m_parentEntityId;
diff --git a/src/core/nodes/qnode_p.h b/src/core/nodes/qnode_p.h
index 506708762..511a0e562 100644
--- a/src/core/nodes/qnode_p.h
+++ b/src/core/nodes/qnode_p.h
@@ -145,6 +145,14 @@ public:
m_destructionConnections.insert(node, QObject::connect(node, &QNode::nodeDestroyed, f));
}
+ template<typename Caller, typename NodeType>
+ void registerPrivateDestructionHelper(NodeType *node, DestructionFunctionPointer<Caller, NodeType> func)
+ {
+ // If the node is destoyed, we make sure not to keep a dangling pointer to it
+ auto f = [this, func, node]() { (static_cast<Caller *>(this)->*func)(node); };
+ m_destructionConnections.insert(node, QObject::connect(node, &QNode::nodeDestroyed, f));
+ }
+
void unregisterDestructionHelper(QNode *node)
{
QObject::disconnect(m_destructionConnections.take(node));