diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2016-03-03 14:18:52 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@theqtcompany.com> | 2016-03-04 10:43:03 +0000 |
commit | 62ecfe55f414d0d04a4344bc6934b4b01408190f (patch) | |
tree | b86869e2a938c4cacda2b627479479d319cd2873 | |
parent | 13c8aecdfccc9d15c367a9d45ec575f1542a90fd (diff) |
Particles: code clean-up.
Replace QHash<int, QQuickParticleGroupData*> groupData with a
QVarLengthArray, and make sure that those integers (== indices) are
continuous, re-used, and start at zero. That way a whole bunch of qhash
calls, hash node creatrion/deletion, and other overhead is removed.
Change-Id: Ie74fab8a3e3c7b6efa15b7b9ceff1d1a3e9820e9
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
-rw-r--r-- | src/particles/qquickcustomaffector.cpp | 12 | ||||
-rw-r--r-- | src/particles/qquickitemparticle.cpp | 2 | ||||
-rw-r--r-- | src/particles/qquickparticleaffector.cpp | 2 | ||||
-rw-r--r-- | src/particles/qquickparticlesystem.cpp | 72 | ||||
-rw-r--r-- | src/particles/qquickparticlesystem_p.h | 15 | ||||
-rw-r--r-- | src/particles/qquickturbulence.cpp | 2 |
6 files changed, 69 insertions, 36 deletions
diff --git a/src/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp index 55310f92d5..6f50c17287 100644 --- a/src/particles/qquickcustomaffector.cpp +++ b/src/particles/qquickcustomaffector.cpp @@ -122,11 +122,15 @@ void QQuickCustomAffector::affectSystem(qreal dt) updateOffsets(); QList<QQuickParticleData*> toAffect; - foreach (QQuickParticleGroupData* gd, m_system->groupData) - if (activeGroup(m_system->groupData.key(gd))) - foreach (QQuickParticleData* d, gd->data) - if (shouldAffect(d)) + foreach (QQuickParticleGroupData* gd, m_system->groupData) { + if (activeGroup(gd->index)) { + foreach (QQuickParticleData* d, gd->data) { + if (shouldAffect(d)) { toAffect << d; + } + } + } + } if (toAffect.isEmpty()) return; diff --git a/src/particles/qquickitemparticle.cpp b/src/particles/qquickitemparticle.cpp index 86dc04ea5a..4cd8ee9db8 100644 --- a/src/particles/qquickitemparticle.cpp +++ b/src/particles/qquickitemparticle.cpp @@ -278,7 +278,7 @@ void QQuickItemParticle::prepareNextFrame() //TODO: Size, better fade? foreach (const QString &str, m_groups){ const int gIdx = m_system->groupIds[str]; - const QVector<QQuickParticleData*> dataVector = m_system->groupData.value(gIdx)->data; + const QVector<QQuickParticleData*> dataVector = m_system->groupData[gIdx]->data; const int count = dataVector.size(); for (int i=0; i<count; i++){ diff --git a/src/particles/qquickparticleaffector.cpp b/src/particles/qquickparticleaffector.cpp index 139b0d9bbe..1878908a5d 100644 --- a/src/particles/qquickparticleaffector.cpp +++ b/src/particles/qquickparticleaffector.cpp @@ -200,7 +200,7 @@ void QQuickParticleAffector::affectSystem(qreal dt) if (m_onceOff) dt = 1.0; foreach (QQuickParticleGroupData* gd, m_system->groupData) { - if (activeGroup(m_system->groupData.key(gd))) { + if (activeGroup(gd->index)) { foreach (QQuickParticleData* d, gd->data) { if (shouldAffect(d)) { bool affected = false; diff --git a/src/particles/qquickparticlesystem.cpp b/src/particles/qquickparticlesystem.cpp index 603515dc66..c0306e9025 100644 --- a/src/particles/qquickparticlesystem.cpp +++ b/src/particles/qquickparticlesystem.cpp @@ -330,7 +330,10 @@ void QQuickParticleDataHeap::bubbleDown(int idx)//tends to be called log n times } } -QQuickParticleGroupData::QQuickParticleGroupData(int id, QQuickParticleSystem* sys):index(id),m_size(0),m_system(sys) +QQuickParticleGroupData::QQuickParticleGroupData(const QString &name, QQuickParticleSystem* sys) + : index(sys->registerParticleGroupData(name, this)) + , m_size(0) + , m_system(sys) { initList(); } @@ -703,6 +706,7 @@ void QQuickParticleData::extendLife(float time) QQuickParticleSystem::QQuickParticleSystem(QQuickItem *parent) : QQuickItem(parent), stateEngine(0), + nextFreeGroupId(0), m_animation(0), m_running(true), initialized(0), @@ -732,11 +736,11 @@ void QQuickParticleSystem::initGroups() qDeleteAll(groupData); groupData.clear(); groupIds.clear(); + nextFreeGroupId = 0; - QQuickParticleGroupData* gd = new QQuickParticleGroupData(0, this);//Default group - groupData.insert(0,gd); - groupIds.insert(QString(), 0); - m_nextGroupId = 1; + QQuickParticleGroupData *pd = new QQuickParticleGroupData(QString(), this); // Default group + Q_ASSERT(pd->index == 0); + Q_UNUSED(pd); } void QQuickParticleSystem::registerParticlePainter(QQuickParticlePainter* p) @@ -848,6 +852,34 @@ void QQuickParticleSystem::stateRedirect(QQuickParticleGroup* group, QQuickParti qWarning() << value << " was placed inside a particle system state but cannot be taken into the particle system. It will be lost."; } + +int QQuickParticleSystem::registerParticleGroupData(const QString &name, QQuickParticleGroupData *pgd) +{ + Q_ASSERT(!groupIds.contains(name)); + int id; + if (nextFreeGroupId >= groupData.size()) { + groupData.push_back(pgd); + nextFreeGroupId = groupData.size(); + id = nextFreeGroupId - 1; + } else { + id = nextFreeGroupId; + groupData[id] = pgd; + searchNextFreeGroupId(); + } + groupIds.insert(name, id); + return id; +} + +void QQuickParticleSystem::searchNextFreeGroupId() +{ + ++nextFreeGroupId; + for (int ei = groupData.size(); nextFreeGroupId != ei; ++nextFreeGroupId) { + if (groupData[nextFreeGroupId] == nullptr) { + return; + } + } +} + void QQuickParticleSystem::componentComplete() { @@ -917,11 +949,8 @@ void QQuickParticleSystem::loadPainter(QObject *p) groupData[0]->painters << painter; } else { foreach (const QString &group, painter->groups()) { - if (group != QLatin1String("") && !groupIds[group]) {//new group - int id = m_nextGroupId++; - QQuickParticleGroupData* gd = new QQuickParticleGroupData(id, this); - groupIds.insert(group, id); - groupData.insert(id, gd); + if (!group.isEmpty() && !groupIds.contains(group)) {//new group + new QQuickParticleGroupData(group, this); } particleCount += groupData[groupIds[group]]->size(); groupData[groupIds[group]]->painters << painter; @@ -939,9 +968,9 @@ void QQuickParticleSystem::emittersChanged() QVector<int> previousSizes; QVector<int> newSizes; - previousSizes.reserve(m_nextGroupId); - newSizes.reserve(m_nextGroupId); - for (int i=0; i<m_nextGroupId; i++) { + previousSizes.reserve(groupData.size()); + newSizes.reserve(groupData.size()); + for (int i = 0, ei = groupData.size(); i != ei; ++i) { previousSizes << groupData[i]->size(); newSizes << 0; } @@ -957,10 +986,7 @@ void QQuickParticleSystem::emittersChanged() if (!e->group().isEmpty() && !groupIds.contains(e->group())) { - int id = m_nextGroupId++; - QQuickParticleGroupData* gd = new QQuickParticleGroupData(id, this); - groupIds.insert(e->group(), id); - groupData.insert(id, gd); + new QQuickParticleGroupData(e->group(), this); previousSizes << 0; newSizes << 0; } @@ -970,13 +996,13 @@ void QQuickParticleSystem::emittersChanged() //TODO: Garbage collection? particleCount = 0; - for (int i=0; i<m_nextGroupId; i++) { + for (int i = 0, ei = groupData.size(); i != ei; ++i) { groupData[i]->setSize(qMax(newSizes[i], previousSizes[i])); particleCount += groupData[i]->size(); } if (m_debugMode) - qDebug() << "Particle system emitters changed. New particle count: " << particleCount; + qDebug() << "Particle system emitters changed. New particle count: " << particleCount << "in" << groupData.size() << "groups."; if (particleCount > bySysIdx.size())//New datum requests haven't updated it bySysIdx.resize(particleCount); @@ -1008,17 +1034,15 @@ void QQuickParticleSystem::createEngine() } } if (!exists) { - int id = m_nextGroupId++; - QQuickParticleGroupData* gd = new QQuickParticleGroupData(id, this); - groupIds.insert(group->name(), id); - groupData.insert(id, gd); + new QQuickParticleGroupData(group->name(), this); } } if (m_groups.count()) { //Reorder groups List so as to have the same order as groupData + // TODO: can't we just merge the two lists? QList<QQuickParticleGroup*> newList; - for (int i=0; i<m_nextGroupId; i++) { + for (int i = 0, ei = groupData.size(); i != ei; ++i) { bool exists = false; QString name = groupData[i]->name(); foreach (QQuickParticleGroup* existing, m_groups) { diff --git a/src/particles/qquickparticlesystem_p.h b/src/particles/qquickparticlesystem_p.h index 5a1ab5022d..7805f87094 100644 --- a/src/particles/qquickparticlesystem_p.h +++ b/src/particles/qquickparticlesystem_p.h @@ -111,7 +111,7 @@ private: class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleGroupData { public: - QQuickParticleGroupData(int id, QQuickParticleSystem* sys); + QQuickParticleGroupData(const QString &name, QQuickParticleSystem* sys); ~QQuickParticleGroupData(); int size(); @@ -119,7 +119,7 @@ public: void setSize(int newSize); - int index; + const int index; QSet<QQuickParticlePainter*> painters;//TODO: What if they are dynamically removed? //TODO: Refactor particle data list out into a separate class @@ -317,10 +317,13 @@ public: //Data members here for ease of related class and auto-test usage. Not "public" API. TODO: d_ptrize QSet<QQuickParticleData*> needsReset; QVector<QQuickParticleData*> bySysIdx; //Another reference to the data (data owned by group), but by sysIdx - QHash<QString, int> groupIds; - QHash<int, QQuickParticleGroupData*> groupData; QQuickStochasticEngine* stateEngine; + QHash<QString, int> groupIds; + QVarLengthArray<QQuickParticleGroupData*, 32> groupData; + int nextFreeGroupId; + int registerParticleGroupData(const QString &name, QQuickParticleGroupData *pgd); + //Also only here for auto-test usage void updateCurrentTime( int currentTime ); QQuickParticleSystemAnimation* m_animation; @@ -349,6 +352,9 @@ public: } private: + void searchNextFreeGroupId(); + +private: void initializeSystem(); void initGroups(); QList<QPointer<QQuickParticleEmitter> > m_emitters; @@ -356,7 +362,6 @@ private: QList<QPointer<QQuickParticlePainter> > m_painters; QList<QPointer<QQuickParticlePainter> > m_syncList; QList<QQuickParticleGroup*> m_groups; - int m_nextGroupId; int m_nextIndex; QSet<int> m_reusableIndexes; bool m_componentComplete; diff --git a/src/particles/qquickturbulence.cpp b/src/particles/qquickturbulence.cpp index 154235441b..eed8604438 100644 --- a/src/particles/qquickturbulence.cpp +++ b/src/particles/qquickturbulence.cpp @@ -181,7 +181,7 @@ void QQuickTurbulenceAffector::affectSystem(qreal dt) QRect boundsRect(0,0,m_gridSize,m_gridSize); foreach (QQuickParticleGroupData *gd, m_system->groupData){ - if (!activeGroup(m_system->groupData.key(gd))) + if (!activeGroup(gd->index)) continue; foreach (QQuickParticleData *d, gd->data){ if (!shouldAffect(d)) |