aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2016-03-03 14:18:52 +0100
committerErik Verbruggen <erik.verbruggen@theqtcompany.com>2016-03-04 10:43:03 +0000
commit62ecfe55f414d0d04a4344bc6934b4b01408190f (patch)
treeb86869e2a938c4cacda2b627479479d319cd2873
parent13c8aecdfccc9d15c367a9d45ec575f1542a90fd (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.cpp12
-rw-r--r--src/particles/qquickitemparticle.cpp2
-rw-r--r--src/particles/qquickparticleaffector.cpp2
-rw-r--r--src/particles/qquickparticlesystem.cpp72
-rw-r--r--src/particles/qquickparticlesystem_p.h15
-rw-r--r--src/particles/qquickturbulence.cpp2
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))