diff options
Diffstat (limited to 'src/declarative/particles/qsgparticlepainter.cpp')
-rw-r--r-- | src/declarative/particles/qsgparticlepainter.cpp | 79 |
1 files changed, 54 insertions, 25 deletions
diff --git a/src/declarative/particles/qsgparticlepainter.cpp b/src/declarative/particles/qsgparticlepainter.cpp index 0d369fd4d8..cf1d3c2894 100644 --- a/src/declarative/particles/qsgparticlepainter.cpp +++ b/src/declarative/particles/qsgparticlepainter.cpp @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE QSGParticlePainter::QSGParticlePainter(QSGItem *parent) : QSGItem(parent), - m_system(0), m_count(0), m_lastStart(0) + m_system(0), m_count(0), m_lastStart(0), m_sentinel(new QSGParticleData) { connect(this, SIGNAL(xChanged()), this, SLOT(calcSystemOffset())); @@ -78,23 +78,70 @@ void QSGParticlePainter::setSystem(QSGParticleSystem *arg) } } -void QSGParticlePainter::load(QSGParticleData*) +void QSGParticlePainter::load(QSGParticleData* d) { + int idx = particleTypeIndex(d); + m_data[idx] = d; + initialize(idx); + reload(idx); } -void QSGParticlePainter::reload(QSGParticleData*) +void QSGParticlePainter::reload(QSGParticleData* d) { + reload(particleTypeIndex(d)); } void QSGParticlePainter::reset() { //Have to every time because what it's emitting may have changed and that affects particleTypeIndex - if(m_system) - updateParticleStarts(); + if(m_system && !m_inResize) + resize(0,1);//###Fix this by making resize take sensible arguments + //###This also means double resets. Make reset not virtual? } -void QSGParticlePainter::resize(int, int) +void QSGParticlePainter::resize(int oldSize, int newSize) { + if(newSize == oldSize)//TODO: What if particles switched so indices change but total count is the same? + return; + + QHash<int, QPair<int, int> > oldStarts(m_particleStarts); + //Update particle starts datastore + m_particleStarts.clear(); + m_lastStart = 0; + QList<int> particleList; + if(m_particles.isEmpty()) + particleList << 0; + foreach(const QString &s, m_particles) + particleList << m_system->m_groupIds[s]; + foreach(int gIdx, particleList){ + QSGParticleGroupData *gd = m_system->m_groupData[gIdx]; + m_particleStarts.insert(gIdx, qMakePair<int, int>(gd->size, m_lastStart)); + m_lastStart += gd->size; + } + + //Shuffle stuff around + //TODO: In place shuffling because it's faster + QVector<QSGParticleData*> oldData(m_data); + QVector<QObject*> oldAttached(m_attachedData); + m_data.clear(); + m_data.resize(m_count); + m_attachedData.resize(m_count); + foreach(int gIdx, particleList){ + QSGParticleGroupData *gd = m_system->m_groupData[gIdx]; + for(int i=0; i<gd->data.size(); i++){//TODO: When group didn't exist before + int newIdx = m_particleStarts[gIdx].second + i; + int oldIdx = oldStarts[gIdx].second + i; + if(i >= oldStarts[gIdx].first || oldData.size() <= oldIdx){ + m_data[newIdx] = m_sentinel; + }else{ + m_data[newIdx] = oldData[oldIdx]; + m_attachedData[newIdx] = oldAttached[oldIdx]; + } + } + } + m_inResize = true; + reset(); + m_inResize = false; } @@ -105,8 +152,7 @@ void QSGParticlePainter::setCount(int c) return; int lastCount = m_count; m_count = c; - resize(lastCount, m_count);//### is virtual needed? Or should I just use the signal? - updateParticleStarts(); + resize(lastCount, m_count); emit countChanged(); } @@ -115,23 +161,6 @@ int QSGParticlePainter::count() return m_count; } - -void QSGParticlePainter::updateParticleStarts() -{ - m_particleStarts.clear(); - m_lastStart = 0; - QList<int> particleList; - if(m_particles.isEmpty()) - particleList << 0; - foreach(const QString &s, m_particles) - particleList << m_system->m_groupIds[s]; - foreach(int gIdx, particleList){ - QSGParticleGroupData *gd = m_system->m_groupData[gIdx]; - m_particleStarts.insert(gIdx, qMakePair<int, int>(gd->size, m_lastStart)); - m_lastStart += gd->size; - } -} - int QSGParticlePainter::particleTypeIndex(QSGParticleData* d) { Q_ASSERT(d && m_particleStarts.contains(d->group));//XXX |