diff options
Diffstat (limited to 'src/declarative/particles/qsgparticlepainter.cpp')
-rw-r--r-- | src/declarative/particles/qsgparticlepainter.cpp | 77 |
1 files changed, 64 insertions, 13 deletions
diff --git a/src/declarative/particles/qsgparticlepainter.cpp b/src/declarative/particles/qsgparticlepainter.cpp index a5e8c0a3e6..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_system(0), m_count(0), m_lastStart(0), m_sentinel(new QSGParticleData) { connect(this, SIGNAL(xChanged()), this, SLOT(calcSystemOffset())); @@ -67,7 +67,7 @@ void QSGParticlePainter::setSystem(QSGParticleSystem *arg) if (m_system != arg) { m_system = arg; if(m_system){ - m_system->registerParticleType(this); + m_system->registerParticlePainter(this); connect(m_system, SIGNAL(xChanged()), this, SLOT(calcSystemOffset())); connect(m_system, SIGNAL(yChanged()), @@ -78,26 +78,81 @@ 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 && !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 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; } + void QSGParticlePainter::setCount(int c) { + Q_ASSERT(c >= 0); //XXX if(c == m_count) return; + int lastCount = m_count; m_count = c; + resize(lastCount, m_count); emit countChanged(); } @@ -106,15 +161,11 @@ int QSGParticlePainter::count() return m_count; } - int QSGParticlePainter::particleTypeIndex(QSGParticleData* d) { - if(!m_particleStarts.contains(d->group)){ - m_particleStarts.insert(d->group, m_lastStart); - m_lastStart += m_system->m_groupData[d->group]->size; - } - int ret = m_particleStarts[d->group] + d->particleIndex; - Q_ASSERT(ret >=0 && ret < m_count);//XXX: Possibly shouldn't assert, but bugs here were hard to find in the past + Q_ASSERT(d && m_particleStarts.contains(d->group));//XXX + int ret = m_particleStarts[d->group].second + d->index; + Q_ASSERT(ret >=0 && ret < m_count);//XXX:shouldn't assert, but bugs here were hard to find in the past return ret; } @@ -129,8 +180,8 @@ void QSGParticlePainter::calcSystemOffset() //Reload all particles//TODO: Necessary? foreach(const QString &g, m_particles){ int gId = m_system->m_groupIds[g]; - for(int i=0; i<m_system->m_groupData[gId]->size; i++) - reload(m_system->m_data[m_system->m_groupData[gId]->start + i]); + foreach(QSGParticleData* d, m_system->m_groupData[gId]->data) + reload(d); } } } |