aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2011-07-21 12:15:34 +1000
committerQt by Nokia <qt-info@nokia.com>2011-07-28 08:39:33 +0200
commitcd6b2696a772fec45bc86521003a597cdd6febee (patch)
tree6a8232e0873f5f5c3950346f26b561911b1c062e /src
parente2b5681b1adab83555c7307b05f508d796a1152b (diff)
Drive ParticleSystem with an animation instead
This will be helpful later, and also keeps the work in the main thread. Change-Id: Idf4b9e82a40f31a0b70edda731b85b6c853a1dac Reviewed-on: http://codereview.qt.nokia.com/1909 Reviewed-by: Alan Alpert <alan.alpert@nokia.com> Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/declarative/particles/qsgparticlepainter.cpp12
-rw-r--r--src/declarative/particles/qsgparticlepainter_p.h8
-rw-r--r--src/declarative/particles/qsgparticlesystem.cpp69
-rw-r--r--src/declarative/particles/qsgparticlesystem_p.h85
4 files changed, 112 insertions, 62 deletions
diff --git a/src/declarative/particles/qsgparticlepainter.cpp b/src/declarative/particles/qsgparticlepainter.cpp
index 7bcaefa66f..4d795999a0 100644
--- a/src/declarative/particles/qsgparticlepainter.cpp
+++ b/src/declarative/particles/qsgparticlepainter.cpp
@@ -105,12 +105,12 @@ void QSGParticlePainter::setSystem(QSGParticleSystem *arg)
void QSGParticlePainter::load(QSGParticleData* d)
{
initialize(d->group, d->index);
- commit(d->group, d->index);
+ m_pendingCommits << qMakePair<int, int>(d->group, d->index);
}
void QSGParticlePainter::reload(QSGParticleData* d)
{
- commit(d->group, d->index);
+ m_pendingCommits << qMakePair<int, int>(d->group, d->index);
}
void QSGParticlePainter::reset()
@@ -148,4 +148,12 @@ void QSGParticlePainter::calcSystemOffset(bool resetPending)
}
}
}
+typedef QPair<int,int> intPair;
+void QSGParticlePainter::performPendingCommits()
+{
+ foreach (intPair p, m_pendingCommits)
+ commit(p.first, p.second);
+ m_pendingCommits.clear();
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/particles/qsgparticlepainter_p.h b/src/declarative/particles/qsgparticlepainter_p.h
index 9231467bff..08ae3aede8 100644
--- a/src/declarative/particles/qsgparticlepainter_p.h
+++ b/src/declarative/particles/qsgparticlepainter_p.h
@@ -44,6 +44,7 @@
#include <QObject>
#include <QDebug>
+#include <QPair>
#include "qsgparticlesystem_p.h"
QT_BEGIN_HEADER
@@ -66,6 +67,7 @@ public:
void reload(QSGParticleData*);
void setCount(int c);
int count();
+ void performPendingCommits();//Called from updatePaintNode
QSGParticleSystem* system() const
{
return m_system;
@@ -93,6 +95,7 @@ void setParticles(QStringList arg)
emit particlesChanged(arg);
}
}
+
private slots:
void calcSystemOffset(bool resetPending = false);
@@ -104,11 +107,11 @@ protected:
virtual void reset();
virtual void componentComplete();
- virtual void initialize(int gIdx, int pIdx){
+ virtual void initialize(int gIdx, int pIdx){//Called from main thread
Q_UNUSED(gIdx);
Q_UNUSED(pIdx);
}
- virtual void commit(int gIdx, int pIdx){
+ virtual void commit(int gIdx, int pIdx){//Called in Render Thread
//###If you need to do something on size changed, check m_data size in this? Or we reset you every time?
Q_UNUSED(gIdx);
Q_UNUSED(pIdx);
@@ -123,6 +126,7 @@ protected:
private:
QSGParticleData* m_sentinel;
+ QSet<QPair<int,int> > m_pendingCommits;
//QVector<QSGParticleData*> m_shadowData;//For when we implement overwrite: false
};
diff --git a/src/declarative/particles/qsgparticlesystem.cpp b/src/declarative/particles/qsgparticlesystem.cpp
index 9ba5c67296..f25172dbda 100644
--- a/src/declarative/particles/qsgparticlesystem.cpp
+++ b/src/declarative/particles/qsgparticlesystem.cpp
@@ -133,7 +133,7 @@ void QSGParticleDataHeap::insert(QSGParticleData* data)
int QSGParticleDataHeap::top()
{
if (m_end == 0)
- return 1e24;
+ return 1 << 30;
return m_data[0].time;
}
@@ -658,8 +658,8 @@ void QSGParticleSystem::componentComplete()
{
QSGItem::componentComplete();
m_componentComplete = true;
- //if (!m_emitters.isEmpty() && !m_particlePainters.isEmpty())
- reset();
+ m_animation = new QSGParticleSystemAnimation(this);
+ reset();//restarts animation as well
}
void QSGParticleSystem::reset()//TODO: Needed? Or just in component complete?
@@ -667,6 +667,7 @@ void QSGParticleSystem::reset()//TODO: Needed? Or just in component complete?
if (!m_componentComplete)
return;
+ m_timeInt = 0;
//Clear guarded pointers which have been deleted
int cleared = 0;
cleared += m_emitters.removeAll(0);
@@ -690,8 +691,10 @@ void QSGParticleSystem::reset()//TODO: Needed? Or just in component complete?
p->reset();
}
- m_timeInt = 0;
- m_timestamp.restart();//TODO: Better placement
+ if (m_animation){
+ m_animation->stop();
+ m_animation->start();
+ }
m_initialized = true;
}
@@ -831,37 +834,41 @@ void QSGParticleSystem::finishNewDatum(QSGParticleData *pd){
p->load(pd);
}
-qint64 QSGParticleSystem::systemSync(QSGParticlePainter* p)
+void QSGParticleSystem::updateCurrentTime( int currentTime )
{
if (!m_running)
- return 0;
+ return;
if (!m_initialized)
- return 0;//error in initialization
+ return;//error in initialization
+
+ //### Elapsed time never shrinks - may cause problems if left emitting for weeks at a time.
+ qreal dt = m_timeInt / 1000.;
+ m_timeInt = currentTime + m_startTime;
+ qreal time = m_timeInt / 1000.;
+ dt = time - dt;
+ m_needsReset.clear();
+ if (m_spriteEngine)
+ m_spriteEngine->updateSprites(m_timeInt);
- if (m_syncList.isEmpty() || m_syncList.contains(p)){//Need to advance the simulation
- m_syncList.clear();
+ foreach (QSGParticleEmitter* emitter, m_emitters)
+ if (emitter)
+ emitter->emitWindow(m_timeInt);
+ foreach (QSGParticleAffector* a, m_affectors)
+ if (a)
+ a->affectSystem(dt);
+ foreach (QSGParticleData* d, m_needsReset)
+ foreach (QSGParticlePainter* p, m_groupData[d->group]->painters)
+ if (p && d)
+ p->reload(d);
+}
- //### Elapsed time never shrinks - may cause problems if left emitting for weeks at a time.
- qreal dt = m_timeInt / 1000.;
- m_timeInt = m_timestamp.elapsed() + m_startTime;
- qreal time = m_timeInt / 1000.;
- dt = time - dt;
- m_needsReset.clear();
- if (m_spriteEngine)
- m_spriteEngine->updateSprites(m_timeInt);
-
- foreach (QSGParticleEmitter* emitter, m_emitters)
- if (emitter)
- emitter->emitWindow(m_timeInt);
- foreach (QSGParticleAffector* a, m_affectors)
- if (a)
- a->affectSystem(dt);
- foreach (QSGParticleData* d, m_needsReset)
- foreach (QSGParticlePainter* p, m_groupData[d->group]->painters)
- if (p && d)
- p->reload(d);
- }
- m_syncList << p;
+int QSGParticleSystem::systemSync(QSGParticlePainter* p)
+{
+ if (!m_running)
+ return 0;
+ if (!m_initialized)
+ return 0;//error in initialization
+ p->performPendingCommits();
return m_timeInt;
}
diff --git a/src/declarative/particles/qsgparticlesystem_p.h b/src/declarative/particles/qsgparticlesystem_p.h
index 45a860b579..b9729f9ffd 100644
--- a/src/declarative/particles/qsgparticlesystem_p.h
+++ b/src/declarative/particles/qsgparticlesystem_p.h
@@ -49,6 +49,8 @@
#include <QPointer>
#include <QSignalMapper>
#include <QtDeclarative/private/qsgsprite_p.h>
+#include <QAbstractAnimation>
+#include <QtDeclarative/qdeclarative.h>
QT_BEGIN_HEADER
@@ -61,6 +63,7 @@ class QSGParticleAffector;
class QSGParticleEmitter;
class QSGParticlePainter;
class QSGParticleData;
+class QSGParticleSystemAnimation;
class QSGSpriteEngine;
class QSGSprite;
@@ -208,7 +211,6 @@ class QSGParticleSystem : public QSGItem
Q_OBJECT
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged)
-
Q_PROPERTY(QDeclarativeListProperty<QSGSprite> particleStates READ particleStates)
public:
@@ -216,42 +218,46 @@ public:
~QSGParticleSystem();
QDeclarativeListProperty<QSGSprite> particleStates();
-bool isRunning() const
-{
- return m_running;
-}
+ //TODO: Hook up running and temporal manipulators to the animation
+ bool isRunning() const
+ {
+ return m_running;
+ }
-int startTime() const
-{
- return m_startTime;
-}
+ int startTime() const
+ {
+ return m_startTime;
+ }
-int count(){ return m_particle_count; }
+ int count(){ return m_particle_count; }
signals:
-void systemInitialized();
-void runningChanged(bool arg);
+ void systemInitialized();
+ void runningChanged(bool arg);
-void startTimeChanged(int arg);
+ void startTimeChanged(int arg);
public slots:
-void reset();
-void setRunning(bool arg);
+ void reset();
+ void setRunning(bool arg);
-void setStartTime(int arg)
-{
- m_startTime = arg;
-}
+ void setStartTime(int arg)
+ {
+ m_startTime = arg;
+ }
-void fastForward(int ms)
-{
- m_startTime += ms;
-}
+ void fastForward(int ms)
+ {
+ m_startTime += ms;
+ }
+
+ virtual int duration() const { return -1; }
protected:
+ //This one only once per frame (effectively)
void componentComplete();
private slots:
@@ -268,17 +274,16 @@ public://###but only really for related class usage. Perhaps we should all be fr
void moveGroups(QSGParticleData *d, int newGIdx);
int nextSystemIndex();
- //This one only once per frame (effectively)
- qint64 systemSync(QSGParticlePainter* p);
+ //This one only once per painter per frame
+ int systemSync(QSGParticlePainter* p);
- QElapsedTimer m_timestamp;
QSet<QSGParticleData*> m_needsReset;
QVector<QSGParticleData*> m_bySysIdx; //Another reference to the data (data owned by group), but by sysIdx
QHash<QString, int> m_groupIds;
QHash<int, QSGParticleGroupData*> m_groupData;
QSGSpriteEngine* m_spriteEngine;
- qint64 m_timeInt;
+ int m_timeInt;
bool m_initialized;
void registerParticlePainter(QSGParticlePainter* p);
@@ -303,6 +308,32 @@ private:
QSignalMapper m_painterMapper;
QSignalMapper m_emitterMapper;
+ friend class QSGParticleSystemAnimation;
+ void updateCurrentTime( int currentTime );
+ QSGParticleSystemAnimation* m_animation;
+};
+
+// Internally, this animation drives all the timing. Painters sync up in their updatePaintNode
+class QSGParticleSystemAnimation : public QAbstractAnimation
+{
+ Q_OBJECT
+public:
+ QSGParticleSystemAnimation(QSGParticleSystem* system)
+ : QAbstractAnimation(static_cast<QObject*>(system)), m_system(system)
+ { }
+protected:
+ virtual void updateCurrentTime( int t )
+ {
+ m_system->updateCurrentTime(t);
+ }
+
+ virtual int duration() const
+ {
+ return -1;
+ }
+
+private:
+ QSGParticleSystem* m_system;
};