diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2016-04-09 19:46:04 +0100 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2016-04-12 12:44:45 +0000 |
commit | 6737083f5c743820af5e7c0424f265911a412ba7 (patch) | |
tree | 6905b255bee4434c803c67a7c1b4a9f488792884 /src | |
parent | c598dfdbec92963ec4e7107a5f266f119fd09214 (diff) |
Add QNodeDestroyedChange and send from QNode dtor
Taking care not to do this recursively. One event can take care of
notifying the backend of an entire sub-tree being destroyed.
Change-Id: Iabf849317943b982eebac72e201e117c2f174026
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/aspects/qaspectengine.cpp | 7 | ||||
-rw-r--r-- | src/core/core.pri | 6 | ||||
-rw-r--r-- | src/core/nodes/nodes.pri | 6 | ||||
-rw-r--r-- | src/core/nodes/qdestructionidandtypecollector.cpp | 51 | ||||
-rw-r--r-- | src/core/nodes/qdestructionidandtypecollector_p.h | 83 | ||||
-rw-r--r-- | src/core/nodes/qnode.cpp | 12 | ||||
-rw-r--r-- | src/core/nodes/qnode_p.h | 2 | ||||
-rw-r--r-- | src/core/qnodedestroyedchange.cpp | 51 | ||||
-rw-r--r-- | src/core/qnodedestroyedchange_p.h | 76 |
9 files changed, 290 insertions, 4 deletions
diff --git a/src/core/aspects/qaspectengine.cpp b/src/core/aspects/qaspectengine.cpp index b76aae603..6a33c4536 100644 --- a/src/core/aspects/qaspectengine.cpp +++ b/src/core/aspects/qaspectengine.cpp @@ -109,6 +109,13 @@ void QAspectEnginePrivate::createCreationChange(QNode *node) { const auto creationChange = node->createNodeCreationChange(); m_creationChanges.push_back(creationChange); + + // Store the metaobject of the node in the QNode so that we have it available + // to us during destruction in the QNode destructor. This allows us to send + // the QNodeId and the metaobject as typeinfo to the backend aspects so they + // in turn can find the correct QBackendNodeMapper object to handle the destruction + // of the corresponding backend nodes. + QNodePrivate::get(node)->m_typeInfo = const_cast<QMetaObject*>(creationChange->metaObject()); } QAspectEngine::QAspectEngine(QObject *parent) diff --git a/src/core/core.pri b/src/core/core.pri index 606a72174..36c134ee9 100644 --- a/src/core/core.pri +++ b/src/core/core.pri @@ -34,7 +34,8 @@ HEADERS += \ $$PWD/qt3dcore_global_p.h \ $$PWD/qscene_p.h \ $$PWD/qnodecreatedchange_p.h \ - $$PWD/qnodecreatedchange.h + $$PWD/qnodecreatedchange.h \ + $$PWD/qnodedestroyedchange_p.h SOURCES += \ $$PWD/qtickclock.cpp \ @@ -51,4 +52,5 @@ SOURCES += \ $$PWD/qscene.cpp \ $$PWD/qbackendscenepropertychange.cpp \ $$PWD/qbackendnodefactory.cpp \ - $$PWD/qnodecreatedchange.cpp + $$PWD/qnodecreatedchange.cpp \ + $$PWD/qnodedestroyedchange.cpp diff --git a/src/core/nodes/nodes.pri b/src/core/nodes/nodes.pri index 5ecf2f36a..56e90b2fd 100644 --- a/src/core/nodes/nodes.pri +++ b/src/core/nodes/nodes.pri @@ -12,7 +12,8 @@ HEADERS += \ $$PWD/qnodeid.h \ $$PWD/qnodevisitor_p.h \ $$PWD/qabstractnodefactory.h \ - $$PWD/propertychangehandler_p.h + $$PWD/propertychangehandler_p.h \ + $$PWD/qdestructionidandtypecollector_p.h SOURCES += \ $$PWD/qnode.cpp \ @@ -22,4 +23,5 @@ SOURCES += \ $$PWD/qnodeid.cpp \ $$PWD/qnodevisitor.cpp \ $$PWD/qabstractnodefactory.cpp \ - $$PWD/propertychangehandler.cpp + $$PWD/propertychangehandler.cpp \ + $$PWD/qdestructionidandtypecollector.cpp diff --git a/src/core/nodes/qdestructionidandtypecollector.cpp b/src/core/nodes/qdestructionidandtypecollector.cpp new file mode 100644 index 000000000..2c611a490 --- /dev/null +++ b/src/core/nodes/qdestructionidandtypecollector.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdestructionidandtypecollector_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DCore { + +QDestructionIdAndTypeCollector::QDestructionIdAndTypeCollector(QNode *rootNode) +{ + QNodeVisitor visitor; + visitor.traverse(rootNode, this, &QDestructionIdAndTypeCollector::collectIdAndType); +} + +QT_END_NAMESPACE + +} // namespace Qt3DCore diff --git a/src/core/nodes/qdestructionidandtypecollector_p.h b/src/core/nodes/qdestructionidandtypecollector_p.h new file mode 100644 index 000000000..3f64a409e --- /dev/null +++ b/src/core/nodes/qdestructionidandtypecollector_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DCORE_QIDTYPEVISITOR_H +#define QT3DCORE_QIDTYPEVISITOR_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 <Qt3DCore/private/qnodevisitor_p.h> +#include <Qt3DCore/private/qentity_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DCore { + +class QDestructionIdAndTypeCollector +{ +public: + QDestructionIdAndTypeCollector(QNode *rootNode); + + QVector<QNodeIdTypePair> subtreeIdsAndTypes() const { return m_subtreeIdsAndTypes; } + +private: + void collectIdAndType(QNode *node) + { + QNodeIdTypePair idAndType(node->id(), QNodePrivate::get(node)->m_typeInfo); + m_subtreeIdsAndTypes.push_back(idAndType); + + // Mark this node as having been handled for destruction so we don't + // repeat it unnecessarily in an O(n^2) manner + QNodePrivate::get(node)->m_destroyedChangeCreated = true; + } + + QVector<QNodeIdTypePair> m_subtreeIdsAndTypes; +}; + +} // namespace Qt3DCore + +QT_END_NAMESPACE + +#endif // QT3DCORE_QIDTYPEVISITOR_H diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp index 7d872de5f..f6b43a925 100644 --- a/src/core/nodes/qnode.cpp +++ b/src/core/nodes/qnode.cpp @@ -43,6 +43,8 @@ #include <Qt3DCore/qentity.h> #include <Qt3DCore/qscenepropertychange.h> #include <Qt3DCore/qaspectengine.h> +#include <Qt3DCore/private/qdestructionidandtypecollector_p.h> +#include <Qt3DCore/private/qnodedestroyedchange_p.h> #include <Qt3DCore/private/qscene_p.h> #include <Qt3DCore/private/qpostman_p.h> #include <QEvent> @@ -66,6 +68,7 @@ QNodePrivate::QNodePrivate() , m_id(QNodeId::createId()) , m_blockNotifications(false) , m_wasCleanedUp(false) + , m_destroyedChangeCreated(false) , m_enabled(true) , m_propertyChangesSetup(false) , m_signals(this) @@ -467,6 +470,15 @@ void QNode::copy(const QNode *ref) QNode::~QNode() { Q_ASSERT_X(QNodePrivate::get(this)->m_wasCleanedUp, Q_FUNC_INFO, "QNode::cleanup should have been called by now. A Qt3DCore::QNode subclass didn't call QNode::cleanup in its destructor"); + + // Create a QNodeDestroyedChange for this node that informs the backend that + // this node and all of its children are going away + Q_D(QNode); + if (!d->m_destroyedChangeCreated) { + const QDestructionIdAndTypeCollector collector(this); + const auto destroyedChange = QNodeDestroyedChangePtr::create(this, collector.subtreeIdsAndTypes()); + d->notifyObservers(destroyedChange); + } } /*! diff --git a/src/core/nodes/qnode_p.h b/src/core/nodes/qnode_p.h index c01da7adc..d8aa7e98f 100644 --- a/src/core/nodes/qnode_p.h +++ b/src/core/nodes/qnode_p.h @@ -85,10 +85,12 @@ public: // For now this just protects access to the m_changeArbiter. // Later on we may decide to extend support for multiple observers. QAbstractArbiter *m_changeArbiter; + QMetaObject *m_typeInfo; QScene *m_scene; mutable QNodeId m_id; bool m_blockNotifications; bool m_wasCleanedUp; + bool m_destroyedChangeCreated; bool m_enabled; static QNodePrivate *get(QNode *q); diff --git a/src/core/qnodedestroyedchange.cpp b/src/core/qnodedestroyedchange.cpp new file mode 100644 index 000000000..08c7e83ae --- /dev/null +++ b/src/core/qnodedestroyedchange.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnodedestroyedchange_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DCore { + +QNodeDestroyedChange::QNodeDestroyedChange(const QNode *node, const QVector<QNodeIdTypePair> &subtreeIdsAndTypes) + : QSceneChange(NodeDeleted, QSceneChange::Node, node->id(), QSceneChange::Standard) + , m_subtreeIdsAndTypes(subtreeIdsAndTypes) +{ +} + +} // namespace Qt3DCore + +QT_END_NAMESPACE diff --git a/src/core/qnodedestroyedchange_p.h b/src/core/qnodedestroyedchange_p.h new file mode 100644 index 000000000..bef65cbb5 --- /dev/null +++ b/src/core/qnodedestroyedchange_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DCORE_QNODEDESTROYEDCHANGE_H +#define QT3DCORE_QNODEDESTROYEDCHANGE_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 <Qt3DCore/qscenechange.h> +#include <Qt3DCore/private/qentity_p.h> +#include <QtCore/qsharedpointer.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DCore { + +class QNodeDestroyedChange : public QSceneChange +{ +public: + explicit QNodeDestroyedChange(const QNode *node, const QVector<QNodeIdTypePair> &subtreeIdsAndTypes); + + QVector<QNodeIdTypePair> subtreeIdsAndTypes() const { return m_subtreeIdsAndTypes; } + +private: + QVector<QNodeIdTypePair> m_subtreeIdsAndTypes; +}; + +typedef QSharedPointer<QNodeDestroyedChange> QNodeDestroyedChangePtr; + +} // namespace Qt3DCore + +QT_END_NAMESPACE + +#endif // QT3DCORE_QNODEDESTROYEDCHANGE_H |