diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2016-05-20 17:11:37 +0200 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2016-05-23 16:31:55 +0000 |
commit | 073930f2ef030b3019c323999d910185f4639d9b (patch) | |
tree | 0c2bba252f7a92d4f3841fbe42eeca27e2a8a838 /src/render/geometry | |
parent | 15dace7c02bc5acdf02f94c8be08fec1a792383c (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/render/geometry')
-rw-r--r-- | src/render/geometry/qattribute.cpp | 8 | ||||
-rw-r--r-- | src/render/geometry/qgeometry.cpp | 5 | ||||
-rw-r--r-- | src/render/geometry/qgeometryrenderer.cpp | 9 |
3 files changed, 22 insertions, 0 deletions
diff --git a/src/render/geometry/qattribute.cpp b/src/render/geometry/qattribute.cpp index 1e9348567..671179f20 100644 --- a/src/render/geometry/qattribute.cpp +++ b/src/render/geometry/qattribute.cpp @@ -258,6 +258,9 @@ void QAttribute::setBuffer(QBuffer *buffer) if (d->m_buffer == buffer) return; + if (d->m_buffer) + d->unregisterDestructionHelper(d->m_buffer); + // We need to add it as a child of the current node if it has been declared inline // Or not previously added as a child of the current node so that // 1) The backend gets notified about it's creation @@ -266,6 +269,11 @@ void QAttribute::setBuffer(QBuffer *buffer) buffer->setParent(this); d->m_buffer = buffer; + + // Ensures proper bookkeeping + if (d->m_buffer) + d->registerDestructionHelper(d->m_buffer, &QAttribute::setBuffer, d->m_buffer); + emit bufferChanged(buffer); } diff --git a/src/render/geometry/qgeometry.cpp b/src/render/geometry/qgeometry.cpp index 57222a364..9b6b9a8e7 100644 --- a/src/render/geometry/qgeometry.cpp +++ b/src/render/geometry/qgeometry.cpp @@ -124,6 +124,9 @@ void QGeometry::addAttribute(QAttribute *attribute) if (!d->m_attributes.contains(attribute)) { d->m_attributes.append(attribute); + // Ensures proper bookkeeping + d->registerDestructionHelper(attribute, &QGeometry::removeAttribute, d->m_attributes); + // We need to add it as a child of the current node if it has been declared inline // Or not previously added as a child of the current node so that // 1) The backend gets notified about it's creation @@ -152,6 +155,8 @@ void QGeometry::removeAttribute(QAttribute *attribute) d->notifyObservers(change); } d->m_attributes.removeOne(attribute); + // Remove bookkeeping connection + d->unregisterDestructionHelper(attribute); } void QGeometry::setBoundingVolumePositionAttribute(QAttribute *boundingVolumePositionAttribute) diff --git a/src/render/geometry/qgeometryrenderer.cpp b/src/render/geometry/qgeometryrenderer.cpp index a714c3155..db59f04a6 100644 --- a/src/render/geometry/qgeometryrenderer.cpp +++ b/src/render/geometry/qgeometryrenderer.cpp @@ -398,10 +398,19 @@ void QGeometryRenderer::setGeometry(QGeometry *geometry) d->notifyObservers(change); } + if (d->m_geometry) + d->unregisterDestructionHelper(d->m_geometry); + if (geometry && !geometry->parent()) geometry->setParent(this); d->m_geometry = geometry; + + + // Ensures proper bookkeeping + if (d->m_geometry) + d->registerDestructionHelper(d->m_geometry, &QGeometryRenderer::setGeometry, d->m_geometry); + const bool blocked = blockNotifications(true); emit geometryChanged(geometry); blockNotifications(blocked); |