diff options
Diffstat (limited to 'src/declarative')
-rw-r--r-- | src/declarative/particles/qsgparticlepainter.cpp | 12 | ||||
-rw-r--r-- | src/declarative/particles/qsgparticlepainter_p.h | 8 | ||||
-rw-r--r-- | src/declarative/particles/qsgparticlesystem.cpp | 69 | ||||
-rw-r--r-- | src/declarative/particles/qsgparticlesystem_p.h | 85 |
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; }; |