aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/declarative/particles/trails/overburst.qml6
-rw-r--r--src/declarative/particles/qsgparticlesystem.cpp61
-rw-r--r--src/declarative/particles/qsgparticlesystem_p.h11
3 files changed, 63 insertions, 15 deletions
diff --git a/examples/declarative/particles/trails/overburst.qml b/examples/declarative/particles/trails/overburst.qml
index ca6bc6dedc..620ae46088 100644
--- a/examples/declarative/particles/trails/overburst.qml
+++ b/examples/declarative/particles/trails/overburst.qml
@@ -45,7 +45,10 @@ Rectangle{
color: "black"
width: 360
height: 540
- ParticleSystem{ id: sys }
+ ParticleSystem{
+ id: sys
+ onClearChanged: if (clear) sys.pause();
+ }
ImageParticle{
system: sys
id: cp
@@ -69,6 +72,7 @@ Rectangle{
}
MouseArea{
anchors.fill: parent
+ onPressed: sys.resume()
id: ma
}
MouseArea{
diff --git a/src/declarative/particles/qsgparticlesystem.cpp b/src/declarative/particles/qsgparticlesystem.cpp
index 8bd39984ee..0888e7b90e 100644
--- a/src/declarative/particles/qsgparticlesystem.cpp
+++ b/src/declarative/particles/qsgparticlesystem.cpp
@@ -80,10 +80,25 @@ DEFINE_BOOL_CONFIG_OPTION(qmlParticlesDebug, QML_PARTICLES_DEBUG)
paused is set to false again, the simulation will resume from the same point it was
paused.
+ The simulation will automatically pause if it detects that there are no live particles
+ left, and unpause when new live particles are added.
+
It can also be controlled with the pause() and resume() methods.
*/
/*!
+ \qmlproperty bool QtQuick.Particles2::ParticleSystem::clear
+
+ clear is set to true when there are no live particles left in the system.
+
+ You can use this to pause the system, keeping it from spending any time updating,
+ but you will need to resume it in order for additional particles to be generated
+ by the system.
+
+ To kill all the particles in the system, use a Kill affector.
+*/
+
+/*!
\qmlproperty int QtQuick.Particles2::ParticleSystem::startTime
If start time is specified, then the system will simulate up to this time
@@ -267,7 +282,8 @@ void QSGParticleGroupData::initList()
dataHeap.clear();
}
-void QSGParticleGroupData::kill(QSGParticleData* d){
+void QSGParticleGroupData::kill(QSGParticleData* d)
+{
Q_ASSERT(d->group == index);
d->lifeSpan = 0;//Kill off
foreach (QSGParticlePainter* p, painters)
@@ -275,21 +291,14 @@ void QSGParticleGroupData::kill(QSGParticleData* d){
reusableIndexes << d->index;
}
-QSGParticleData* QSGParticleGroupData::newDatum(bool respectsLimits){
- while (dataHeap.top() <= m_system->m_timeInt){
- foreach (QSGParticleData* datum, dataHeap.pop()){
- if (!datum->stillAlive()){
- reusableIndexes << datum->index;
- }else{
- prepareRecycler(datum); //ttl has been altered mid-way, put it back
- }
- }
- }
+QSGParticleData* QSGParticleGroupData::newDatum(bool respectsLimits)
+{
+ //recycle();//Extra recycler round to be sure?
while (!reusableIndexes.empty()){
int idx = *(reusableIndexes.begin());
reusableIndexes.remove(idx);
- if (data[idx]->stillAlive()){// ### This means resurrection of dead particles. Is that allowed?
+ if (data[idx]->stillAlive()){// ### This means resurrection of 'dead' particles. Is that allowed?
prepareRecycler(data[idx]);
continue;
}
@@ -304,6 +313,22 @@ QSGParticleData* QSGParticleGroupData::newDatum(bool respectsLimits){
return data[oldSize];
}
+bool QSGParticleGroupData::recycle()
+{
+ while (dataHeap.top() <= m_system->m_timeInt){
+ foreach (QSGParticleData* datum, dataHeap.pop()){
+ if (!datum->stillAlive()){
+ reusableIndexes << datum->index;
+ }else{
+ prepareRecycler(datum); //ttl has been altered mid-way, put it back
+ }
+ }
+ }
+
+ //TODO: If the data is clear, gc (consider shrinking stack size)?
+ return reusableIndexes.count() == m_size;
+}
+
void QSGParticleGroupData::prepareRecycler(QSGParticleData* d){
dataHeap.insert(d);
}
@@ -870,6 +895,7 @@ QSGParticleData* QSGParticleSystem::newDatum(int groupId, bool respectLimits, in
if (m_spriteEngine)
m_spriteEngine->startSprite(ret->systemIndex, ret->group);
+ m_clear = false;
return ret;
}
@@ -899,8 +925,6 @@ void QSGParticleSystem::finishNewDatum(QSGParticleData *pd){
void QSGParticleSystem::updateCurrentTime( int currentTime )
{
- if (!m_running)
- return;
if (!m_initialized)
return;//error in initialization
@@ -910,6 +934,12 @@ void QSGParticleSystem::updateCurrentTime( int currentTime )
qreal time = m_timeInt / 1000.;
dt = time - dt;
m_needsReset.clear();
+
+ bool oldClear = m_clear;
+ m_clear = true;
+ foreach (QSGParticleGroupData* gd, m_groupData)//Recycle all groups and see if they're out of live particles
+ m_clear = m_clear && gd->recycle();
+
if (m_spriteEngine)
m_spriteEngine->updateSprites(m_timeInt);
@@ -923,6 +953,9 @@ void QSGParticleSystem::updateCurrentTime( int currentTime )
foreach (QSGParticlePainter* p, m_groupData[d->group]->painters)
if (p && d)
p->reload(d);
+
+ if (oldClear != m_clear)
+ clearChanged(m_clear);
}
int QSGParticleSystem::systemSync(QSGParticlePainter* p)
diff --git a/src/declarative/particles/qsgparticlesystem_p.h b/src/declarative/particles/qsgparticlesystem_p.h
index f578c43378..5df6afb923 100644
--- a/src/declarative/particles/qsgparticlesystem_p.h
+++ b/src/declarative/particles/qsgparticlesystem_p.h
@@ -117,6 +117,7 @@ public:
QVector<QSGParticleData*> data;
QSGParticleDataHeap dataHeap;
QSet<int> reusableIndexes;
+ bool recycle(); //Force recycling round, reutrns true if all indexes are now reusable
void initList();
void kill(QSGParticleData* d);
@@ -219,6 +220,7 @@ class QSGParticleSystem : public QSGItem
Q_OBJECT
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged)
+ Q_PROPERTY(bool clear READ isClear NOTIFY clearChanged)
Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged)
Q_PROPERTY(QDeclarativeListProperty<QSGSprite> particleStates READ particleStates)
@@ -250,6 +252,8 @@ signals:
void pausedChanged(bool arg);
+ void clearChanged(bool arg);
+
public slots:
void start(){setRunning(true);}
void stop(){setRunning(false);}
@@ -315,6 +319,11 @@ public://###but only really for related class usage. Perhaps we should all be fr
return m_paused;
}
+ bool isClear() const
+ {
+ return m_clear;
+ }
+
private:
void initializeSystem();
void initGroups();
@@ -337,6 +346,8 @@ private:
QSGParticleSystemAnimation* m_animation;
bool m_paused;
bool m_debugMode;
+ bool m_allDead;
+ bool m_clear;
};
// Internally, this animation drives all the timing. Painters sync up in their updatePaintNode