Fix QQuickItemParticle timing issues
authorAlan Alpert <alan.alpert@nokia.com>
Mon, 9 Jan 2012 00:26:35 +0000 (10:26 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 9 Jan 2012 04:49:03 +0000 (05:49 +0100)
It was possible for m_loadables to be reset before the items were
loaded, and the datum pointer was lost. This was exacerbated by another
bug where reset was called every frame for no reason. Both bugs are now
fixed.

Task-number: QTBUG-23491
Change-Id: I9b60858621b697fc46de1e964cb27ddc0d2dbc65
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
src/quick/particles/qquickitemparticle.cpp
src/quick/particles/qquickitemparticle_p.h
tests/auto/particles/qquickitemparticle/qquickitemparticle.pro

index 56661ff..0b7cbe4 100644 (file)
@@ -103,12 +103,8 @@ QQuickItemParticle::QQuickItemParticle(QQuickItem *parent) :
     QQuickParticlePainter(parent), m_fade(true), m_delegate(0)
 {
     setFlag(QQuickItem::ItemHasContents);
-    QTimer* manageDelegates = new QTimer(this);//TODO: don't leak
-    connect(manageDelegates, SIGNAL(timeout()),
-            this, SLOT(tick()));
-    manageDelegates->setInterval(16);
-    manageDelegates->setSingleShot(false);
-    manageDelegates->start();
+    clock = new Clock(this, this);
+    clock->start();
 }
 
 
@@ -146,8 +142,9 @@ void QQuickItemParticle::commit(int, int)
 {
 }
 
-void QQuickItemParticle::tick()
+void QQuickItemParticle::tick(int time)
 {
+    Q_UNUSED(time);//only needed because QTickAnimationProxy expects one
     foreach (QQuickItem* item, m_deletables){
         if (m_fade)
             item->setOpacity(0.);
@@ -194,8 +191,8 @@ void QQuickItemParticle::tick()
 void QQuickItemParticle::reset()
 {
     QQuickParticlePainter::reset();
-    //TODO: Cleanup items?
     m_loadables.clear();
+    //TODO: Cleanup items?
     //deletables?
 }
 
@@ -205,7 +202,14 @@ QSGNode* QQuickItemParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d)
     //Dummy update just to get painting tick
     if (m_pleaseReset){
         m_pleaseReset = false;
-        reset();
+        //Refill loadables, delayed here so as to only happen once per frame max
+        //### Constant resetting might lead to m_loadables never being populated when tick() occurs
+        foreach (const QString group, m_groups){
+            int gIdx = m_system->groupIds[group];
+            foreach (QQuickParticleData* d, m_system->groupData[gIdx]->data)
+                if (!d->delegate && d->t != -1  && d->stillAlive())
+                    m_loadables << d;
+        }
     }
     prepareNextFrame();
 
index 84f60ac..d528443 100644 (file)
@@ -44,6 +44,7 @@
 #include "qquickparticlepainter_p.h"
 #include <QPointer>
 #include <QSet>
+#include <private/qdeclarativeanimation_p_p.h>
 QT_BEGIN_HEADER
 
 QT_BEGIN_NAMESPACE
@@ -95,9 +96,8 @@ protected:
     virtual void commit(int gIdx, int pIdx);
     virtual void initialize(int gIdx, int pIdx);
     void prepareNextFrame();
-private slots:
-    void tick();
 private:
+    void tick(int time = 0);
     QList<QQuickItem* > m_deletables;
     QList< QQuickParticleData* > m_loadables;
     bool m_fade;
@@ -108,6 +108,9 @@ private:
     qreal m_lastT;
     int m_activeCount;
     QDeclarativeComponent* m_delegate;
+
+    typedef QTickAnimationProxy<QQuickItemParticle, &QQuickItemParticle::tick> Clock;
+    Clock *clock;
 };
 
 class QQuickItemParticleAttached : public QObject
index 9d78c2b..c36dabb 100644 (file)
@@ -7,7 +7,5 @@ testDataFiles.files = data
 testDataFiles.path = .
 DEPLOYMENT += testDataFiles
 
-CONFIG += insignificant_test    #temporary
-
 QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib