aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/particles/qsgparticlepainter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/particles/qsgparticlepainter.cpp')
-rw-r--r--src/declarative/particles/qsgparticlepainter.cpp79
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