Clean up dangling pointers in the particle system
authorGunnar Sletta <gunnar.sletta@nokia.com>
Thu, 15 Mar 2012 15:14:45 +0000 (16:14 +0100)
committerQt by Nokia <qt-info@nokia.com>
Mon, 19 Mar 2012 16:09:14 +0000 (17:09 +0100)
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 <kim.kalland@nokia.com>
Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
src/quick/particles/qquickcustomparticle.cpp
src/quick/particles/qquickcustomparticle_p.h
src/quick/particles/qquickimageparticle.cpp
src/quick/particles/qquickimageparticle_p.h
src/quick/particles/qquickparticlepainter.cpp
src/quick/particles/qquickparticlepainter_p.h

index 3647e5b..6f10307 100644 (file)
@@ -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)
index 29f3d19..e04ac70 100644 (file)
@@ -93,6 +93,8 @@ protected:
     QQuickShaderEffectNode *buildCustomNodes();
     void performPendingResize();
 
+    void sceneGraphInvalidated();
+
 private:
     void buildData();
 
index 386892a..d9eb6ed 100644 (file)
@@ -839,6 +839,13 @@ QQmlListProperty<QQuickSprite> QQuickImageParticle::sprites()
     return QQmlListProperty<QQuickSprite>(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()){
index dca524b..4db2c98 100644 (file)
@@ -348,6 +348,8 @@ protected:
     void prepareNextFrame();
     void buildParticleNodes();
 
+    void sceneGraphInvalidated();
+
 private slots:
     void createEngine(); //### method invoked by sprite list changing (in engine.h) - pretty nasty
 
index f46f2f2..e490b70 100644 (file)
@@ -40,6 +40,7 @@
 ****************************************************************************/
 
 #include "qquickparticlepainter_p.h"
+#include <QQuickCanvas>
 #include <QDebug>
 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<QQuickParticleSystem*>(parentItem()))
index ebe76d9..1ae4625 100644 (file)
@@ -76,6 +76,8 @@ public:
         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 @@ protected:
     QStringList m_groups;
     QPointF m_systemOffset;
 
+    QQuickCanvas *m_canvas;
+
 private:
     QSet<QPair<int,int> > m_pendingCommits;
 };