Add clear property to QSGParticleSystem
Makes it possible to pause the system when all particles are expired. Change-Id: Iebeb987c2e2af261bdffa4584d75f3b108dcf050 Reviewed-on: http://codereview.qt-project.org/4046 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Martin Jones <martin.jones@nokia.com>
This commit is contained in:
parent
fee3fe7d76
commit
d00a2ef6ab
|
@ -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{
|
||||
|
|
|
@ -80,9 +80,24 @@ 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
|
||||
|
||||
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue