diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-06-18 03:03:52 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-06-18 03:03:52 +0200 |
commit | 186b082e965a965bd5ded451e5ab533b7757c821 (patch) | |
tree | d558e1a5e2550677ac3800162ceed8b448b0f1a6 /src/core | |
parent | c61479f9a6be1ee239aef48babc854bbebec4b31 (diff) | |
parent | 5c61a32369b003bae6ed045da230db8d8dd0f82d (diff) |
Merge remote-tracking branch 'origin/5.13' into dev
Change-Id: I942a33e63084b346702577e28c70f2111e40a4d5
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/nodes/qcomponent.cpp | 5 | ||||
-rw-r--r-- | src/core/nodes/qentity.cpp | 22 | ||||
-rw-r--r-- | src/core/nodes/qentity_p.h | 1 | ||||
-rw-r--r-- | src/core/nodes/qnode_p.h | 8 |
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)); |