From 3bf01de85d943432d66b5fa8048275817fd20020 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 15 Mar 2012 16:14:45 +0100 Subject: [PATCH] Clean up dangling pointers in the particle system When the scenegraph has been invalidated all node pointers have been deleted. In the image particle case the material is managed by the nodes and must also be reset. Change-Id: I867f0d36a3ea281a58c21f04c937b16b042ef373 Reviewed-by: Kim M. Kalland Reviewed-by: Alan Alpert --- src/quick/particles/qquickcustomparticle.cpp | 6 ++++++ src/quick/particles/qquickcustomparticle_p.h | 2 ++ src/quick/particles/qquickimageparticle.cpp | 7 +++++++ src/quick/particles/qquickimageparticle_p.h | 2 ++ src/quick/particles/qquickparticlepainter.cpp | 15 ++++++++++++++- src/quick/particles/qquickparticlepainter_p.h | 7 +++++++ 6 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/quick/particles/qquickcustomparticle.cpp b/src/quick/particles/qquickcustomparticle.cpp index 3647e5bfc5..6f10307851 100644 --- a/src/quick/particles/qquickcustomparticle.cpp +++ b/src/quick/particles/qquickcustomparticle.cpp @@ -139,6 +139,12 @@ QQuickCustomParticle::QQuickCustomParticle(QQuickItem* parent) class QQuickShaderEffectMaterialObject : public QObject, public QQuickShaderEffectMaterial { }; +void QQuickCustomParticle::sceneGraphInvalidated() +{ + m_nodes.clear(); + m_rootNode = 0; +} + QQuickCustomParticle::~QQuickCustomParticle() { if (m_material) diff --git a/src/quick/particles/qquickcustomparticle_p.h b/src/quick/particles/qquickcustomparticle_p.h index 29f3d19657..e04ac704d0 100644 --- a/src/quick/particles/qquickcustomparticle_p.h +++ b/src/quick/particles/qquickcustomparticle_p.h @@ -93,6 +93,8 @@ public Q_SLOTS: QQuickShaderEffectNode *buildCustomNodes(); void performPendingResize(); + void sceneGraphInvalidated(); + private: void buildData(); diff --git a/src/quick/particles/qquickimageparticle.cpp b/src/quick/particles/qquickimageparticle.cpp index 386892a12a..d9eb6ed01b 100644 --- a/src/quick/particles/qquickimageparticle.cpp +++ b/src/quick/particles/qquickimageparticle.cpp @@ -839,6 +839,13 @@ QQmlListProperty QQuickImageParticle::sprites() return QQmlListProperty(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear); } +void QQuickImageParticle::sceneGraphInvalidated() +{ + m_nodes.clear(); + m_rootNode = 0; + m_material = 0; +} + void QQuickImageParticle::setImage(const QUrl &image) { if (image.isEmpty()){ diff --git a/src/quick/particles/qquickimageparticle_p.h b/src/quick/particles/qquickimageparticle_p.h index dca524bcab..4db2c9801a 100644 --- a/src/quick/particles/qquickimageparticle_p.h +++ b/src/quick/particles/qquickimageparticle_p.h @@ -348,6 +348,8 @@ public slots: void prepareNextFrame(); void buildParticleNodes(); + void sceneGraphInvalidated(); + private slots: void createEngine(); //### method invoked by sprite list changing (in engine.h) - pretty nasty diff --git a/src/quick/particles/qquickparticlepainter.cpp b/src/quick/particles/qquickparticlepainter.cpp index f46f2f2235..e490b70240 100644 --- a/src/quick/particles/qquickparticlepainter.cpp +++ b/src/quick/particles/qquickparticlepainter.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qquickparticlepainter_p.h" +#include #include QT_BEGIN_NAMESPACE /*! @@ -65,10 +66,22 @@ QT_BEGIN_NAMESPACE */ QQuickParticlePainter::QQuickParticlePainter(QQuickItem *parent) : QQuickItem(parent), - m_system(0), m_count(0), m_pleaseReset(true) + m_system(0), m_count(0), m_pleaseReset(true), m_canvas(0) { } +void QQuickParticlePainter::itemChange(ItemChange change, const ItemChangeData &data) +{ + if (change == QQuickItem::ItemSceneChange) { + if (m_canvas) + disconnect(m_canvas, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated())); + m_canvas = data.canvas; + if (m_canvas) + connect(m_canvas, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated()), Qt::DirectConnection); + + } +} + void QQuickParticlePainter::componentComplete() { if (!m_system && qobject_cast(parentItem())) diff --git a/src/quick/particles/qquickparticlepainter_p.h b/src/quick/particles/qquickparticlepainter_p.h index ebe76d98ea..1ae4625856 100644 --- a/src/quick/particles/qquickparticlepainter_p.h +++ b/src/quick/particles/qquickparticlepainter_p.h @@ -76,6 +76,8 @@ class QQuickParticlePainter : public QQuickItem return m_groups; } + void itemChange(ItemChange, const ItemChangeData &); + signals: void countChanged(); void systemChanged(QQuickParticleSystem* arg); @@ -96,6 +98,9 @@ public slots: void calcSystemOffset(bool resetPending = false); +private slots: + virtual void sceneGraphInvalidated() {} + protected: /* Reset resets all your internal data structures. But anything attached to a particle should be in attached data. So reset + reloads should have no visible effect. @@ -121,6 +126,8 @@ public slots: QStringList m_groups; QPointF m_systemOffset; + QQuickCanvas *m_canvas; + private: QSet > m_pendingCommits; };