aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2011-09-20 15:28:14 +1000
committerQt by Nokia <qt-info@nokia.com>2011-09-21 07:11:25 +0200
commitef98f5a80369e3f014585edc3dd63a2ec331d1ea (patch)
tree4e6abd6afb7ba04422a1acc9d11c2f8ff21169c1 /src
parent4114b9dcff68cdebc36e3b4818d4463d62421ecf (diff)
CustomEmitter/Affector now affect whole lists at once
Better performance potential (fewer drops to JS, possibility of more optimzed JS). Change-Id: If386f06ac8714162a5bfc6b5eef7f2e67f9dae95 Reviewed-on: http://codereview.qt-project.org/5189 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/declarative/particles/qsgcustomaffector.cpp43
-rw-r--r--src/declarative/particles/qsgcustomaffector_p.h4
-rw-r--r--src/declarative/particles/qsgparticleaffector_p.h4
-rw-r--r--src/declarative/particles/qsgparticleemitter.cpp31
-rw-r--r--src/declarative/particles/qsgparticleemitter_p.h2
-rw-r--r--src/declarative/particles/qsgtrailemitter.cpp35
-rw-r--r--src/declarative/particles/qsgtrailemitter_p.h2
7 files changed, 87 insertions, 34 deletions
diff --git a/src/declarative/particles/qsgcustomaffector.cpp b/src/declarative/particles/qsgcustomaffector.cpp
index 70e1dbe035..77da5c58a6 100644
--- a/src/declarative/particles/qsgcustomaffector.cpp
+++ b/src/declarative/particles/qsgcustomaffector.cpp
@@ -40,15 +40,18 @@
****************************************************************************/
#include "qsgcustomaffector_p.h"
+#include <private/qv8engine_p.h>
+#include <private/qdeclarativeengine_p.h>
+#include <QDeclarativeEngine>
#include <QDebug>
QT_BEGIN_NAMESPACE
//TODO: Move docs (and inherit) to real base when docs can propagate
-//TODO: Document particle 'type'
/*!
- \qmlsignal QtQuick.Particles2::Affector::affectParticle(particle, dt)
+ \qmlsignal QtQuick.Particles2::Affector::affectParticles(Array particles, real dt)
- This handler is called when particles are selected to be affected.
+ This handler is called when particles are selected to be affected. particles contains
+ an array of particle objects which can be directly manipulated.
dt is the time since the last time it was affected. Use dt to normalize
trajectory manipulations to real time.
@@ -63,18 +66,38 @@ QSGCustomAffector::QSGCustomAffector(QSGItem *parent) :
bool QSGCustomAffector::isAffectConnected()
{
- static int idx = QObjectPrivate::get(this)->signalIndex("affectParticle(QDeclarativeV8Handle,qreal)");
+ static int idx = QObjectPrivate::get(this)->signalIndex("affectParticles(QDeclarativeV8Handle,qreal)");
return QObjectPrivate::get(this)->isSignalConnected(idx);
}
-bool QSGCustomAffector::affectParticle(QSGParticleData *d, qreal dt)
+void QSGCustomAffector::affectSystem(qreal dt)
{
- if (isAffectConnected()){
- d->update = 0.0;
- emit affectParticle(d->v8Value(), dt);
- return d->update == 1.0;
+ if (!isAffectConnected()) {
+ QSGParticleAffector::affectSystem(dt);
+ return;
}
- return true;
+ if (!m_enabled)
+ return;
+ updateOffsets();
+
+ QList<QSGParticleData*> toAffect;
+ foreach (QSGParticleGroupData* gd, m_system->m_groupData)
+ if (activeGroup(m_system->m_groupData.key(gd)))
+ foreach (QSGParticleData* d, gd->data)
+ if (shouldAffect(d))
+ toAffect << d;
+
+ v8::HandleScope handle_scope;
+ v8::Context::Scope scope(QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this))->context());
+ v8::Handle<v8::Array> array = v8::Array::New(toAffect.size());
+ for (int i=0; i<toAffect.size(); i++)
+ array->Set(i, toAffect[i]->v8Value().toHandle());
+
+ emit affectParticles(QDeclarativeV8Handle::fromHandle(array), dt);
+
+ foreach (QSGParticleData* d, toAffect)
+ if (d->update == 1.0)
+ postAffect(d);
}
QT_END_NAMESPACE
diff --git a/src/declarative/particles/qsgcustomaffector_p.h b/src/declarative/particles/qsgcustomaffector_p.h
index 7f39200298..fc0735e971 100644
--- a/src/declarative/particles/qsgcustomaffector_p.h
+++ b/src/declarative/particles/qsgcustomaffector_p.h
@@ -59,13 +59,13 @@ class QSGCustomAffector : public QSGParticleAffector
public:
explicit QSGCustomAffector(QSGItem *parent = 0);
+ virtual void affectSystem(qreal dt);
signals:
- void affectParticle(QDeclarativeV8Handle particle, qreal dt);
+ void affectParticles(QDeclarativeV8Handle particles, qreal dt);
public slots:
protected:
bool isAffectConnected();
- virtual bool affectParticle(QSGParticleData *d, qreal dt);
private:
};
diff --git a/src/declarative/particles/qsgparticleaffector_p.h b/src/declarative/particles/qsgparticleaffector_p.h
index c67912fada..c46164de5c 100644
--- a/src/declarative/particles/qsgparticleaffector_p.h
+++ b/src/declarative/particles/qsgparticleaffector_p.h
@@ -163,6 +163,8 @@ void setWhenCollidingWith(QStringList arg)
emit whenCollidingWithChanged(arg);
}
}
+public slots:
+ void updateOffsets();
protected:
friend class QSGParticleSystem;
@@ -189,8 +191,6 @@ private:
QStringList m_whenCollidingWith;
bool isColliding(QSGParticleData* d);
-private slots:
- void updateOffsets();
};
QT_END_NAMESPACE
diff --git a/src/declarative/particles/qsgparticleemitter.cpp b/src/declarative/particles/qsgparticleemitter.cpp
index f10bf1edd7..e1a7ef28a9 100644
--- a/src/declarative/particles/qsgparticleemitter.cpp
+++ b/src/declarative/particles/qsgparticleemitter.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qsgparticleemitter_p.h"
+#include <private/qdeclarativeengine_p.h>
QT_BEGIN_NAMESPACE
@@ -183,12 +184,12 @@ QT_BEGIN_NAMESPACE
Default value is 0.
*/
-//TODO: Document particle 'type'
+
/*!
- \qmlsignal QtQuick.Particles2::Emitter::onEmitParticle(Particle particle)
+ \qmlsignal QtQuick.Particles2::Emitter::onEmitParticles(Array particles)
- This handler is called when a particle is emitted. You can modify particle
- attributes from within the handler.
+ This handler is called when particles are emitted. particles is a javascript
+ array of Particle objects. You can modify particle attributes directly within the handler.
Note that JS is slower to execute, so it is not recommended to use this in
high-volume particle systems.
@@ -252,7 +253,7 @@ QSGParticleEmitter::~QSGParticleEmitter()
bool QSGParticleEmitter::isEmitConnected()
{
- static int idx = QObjectPrivate::get(this)->signalIndex("emitParticle(QDeclarativeV8Handle)");
+ static int idx = QObjectPrivate::get(this)->signalIndex("emitParticles(QDeclarativeV8Handle)");
return QObjectPrivate::get(this)->isSignalConnected(idx);
}
@@ -396,6 +397,9 @@ void QSGParticleEmitter::emitWindow(int timeStamp)
qreal emitter_y_offset = m_last_emitter.y() - y();
if (!m_burstQueue.isEmpty() && !m_burstLeft && !m_enabled)//'outside time' emissions only
pt = time;
+
+ QList<QSGParticleData*> toEmit;
+
while ((pt < time && m_emitCap) || !m_burstQueue.isEmpty()) {
//int pos = m_last_particle % m_particle_count;
QSGParticleData* datum = m_system->newDatum(m_system->m_groupIds[m_group], !m_overwrite);
@@ -459,9 +463,7 @@ void QSGParticleEmitter::emitWindow(int timeStamp)
datum->size = size;// * float(m_emitting);
datum->endSize = endSize;// * float(m_emitting);
- if (isEmitConnected())
- emitParticle(datum->v8Value());//A chance for arbitrary JS changes
- m_system->emitParticle(datum);
+ toEmit << datum;
}
if (m_burstQueue.isEmpty()){
pt += particleRatio;
@@ -471,6 +473,19 @@ void QSGParticleEmitter::emitWindow(int timeStamp)
m_burstQueue.pop_front();
}
}
+
+ if (isEmitConnected()) {
+ v8::HandleScope handle_scope;
+ v8::Context::Scope scope(QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this))->context());
+ v8::Handle<v8::Array> array = v8::Array::New(toEmit.size());
+ for (int i=0; i<toEmit.size(); i++)
+ array->Set(i, toEmit[i]->v8Value().toHandle());
+
+ emitParticles(QDeclarativeV8Handle::fromHandle(array));//A chance for arbitrary JS changes
+ }
+ foreach (QSGParticleData* d, toEmit)
+ m_system->emitParticle(d);
+
m_last_emission = pt;
m_last_last_last_emitter = m_last_last_emitter;
diff --git a/src/declarative/particles/qsgparticleemitter_p.h b/src/declarative/particles/qsgparticleemitter_p.h
index 8bd205b207..11c79ec221 100644
--- a/src/declarative/particles/qsgparticleemitter_p.h
+++ b/src/declarative/particles/qsgparticleemitter_p.h
@@ -123,7 +123,7 @@ public:
void setSpeedFromMovement(qreal s);
virtual void componentComplete();
signals:
- void emitParticle(QDeclarativeV8Handle particle);
+ void emitParticles(QDeclarativeV8Handle particles);
void particlesPerSecondChanged(qreal);
void particleDurationChanged(int);
void enabledChanged(bool);
diff --git a/src/declarative/particles/qsgtrailemitter.cpp b/src/declarative/particles/qsgtrailemitter.cpp
index 5a19ac508b..e819663870 100644
--- a/src/declarative/particles/qsgtrailemitter.cpp
+++ b/src/declarative/particles/qsgtrailemitter.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qsgtrailemitter_p.h"
+#include <private/qdeclarativeengine_p.h>
#include <cmath>
QT_BEGIN_NAMESPACE
@@ -102,18 +103,17 @@ QSGTrailEmitter::QSGTrailEmitter(QSGItem *parent) :
\qmlproperty real QtQuick.Particles2::TrailEmitter::emitRatePerParticle
*/
/*!
- \qmlsignal QtQuick.Particles2::TrailEmitter::emitFollowParticle(particle, followed)
+ \qmlsignal QtQuick.Particles2::TrailEmitter::emitFollowParticles(Array particles, real followed)
- This handler is called when a particle is emitted. You can modify particle
- attributes from within the handler. followed is the particle that this is being
- emitted off of.
+ This handler is called when particles are emitted from the \a followed particle. \a particles contains an array of particle objects which can be directly manipulated.
+
+ If you use this signal handler, emitParticles will not be emitted.
- If you use this signal handler, emitParticle will not be emitted.
*/
bool QSGTrailEmitter::isEmitFollowConnected()
{
- static int idx = QObjectPrivate::get(this)->signalIndex("emitFollowParticle(QDeclarativeV8Handle,QDeclarativeV8Handle)");
+ static int idx = QObjectPrivate::get(this)->signalIndex("emitFollowParticles(QDeclarativeV8Handle,QDeclarativeV8Handle)");
return QObjectPrivate::get(this)->isSignalConnected(idx);
}
@@ -180,6 +180,9 @@ void QSGTrailEmitter::emitWindow(int timeStamp)
m_lastEmission[d->index] = time;//jump over this time period without emitting, because it's outside
continue;
}
+
+ QList<QSGParticleData*> toEmit;
+
while (pt < time || !m_burstQueue.isEmpty()){
QSGParticleData* datum = m_system->newDatum(gId2, !m_overwrite);
if (datum){//else, skip this emission
@@ -235,10 +238,7 @@ void QSGTrailEmitter::emitWindow(int timeStamp)
datum->size = size * float(m_enabled);
datum->endSize = endSize * float(m_enabled);
- if (isEmitFollowConnected())
- emitFollowParticle(datum->v8Value(), d->v8Value());//A chance for many arbitrary JS changes
- else if (isEmitConnected())
- emitParticle(datum->v8Value());//A chance for arbitrary JS changes
+ toEmit << datum;
m_system->emitParticle(datum);
}
@@ -250,6 +250,21 @@ void QSGTrailEmitter::emitWindow(int timeStamp)
pt += particleRatio;
}
}
+
+ if (isEmitConnected() || isEmitFollowConnected()) {
+ v8::HandleScope handle_scope;
+ v8::Context::Scope scope(QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this))->context());
+ v8::Handle<v8::Array> array = v8::Array::New(toEmit.size());
+ for (int i=0; i<toEmit.size(); i++)
+ array->Set(i, toEmit[i]->v8Value().toHandle());
+
+ if (isEmitFollowConnected())
+ emitFollowParticles(QDeclarativeV8Handle::fromHandle(array), d->v8Value());//A chance for many arbitrary JS changes
+ else if (isEmitConnected())
+ emitParticles(QDeclarativeV8Handle::fromHandle(array));//A chance for arbitrary JS changes
+ }
+ foreach (QSGParticleData* d, toEmit)
+ m_system->emitParticle(d);
m_lastEmission[d->index] = pt;
}
diff --git a/src/declarative/particles/qsgtrailemitter_p.h b/src/declarative/particles/qsgtrailemitter_p.h
index 009ccd508c..e0103afdc0 100644
--- a/src/declarative/particles/qsgtrailemitter_p.h
+++ b/src/declarative/particles/qsgtrailemitter_p.h
@@ -94,7 +94,7 @@ public:
}
signals:
- void emitFollowParticle(QDeclarativeV8Handle group, QDeclarativeV8Handle followed);
+ void emitFollowParticles(QDeclarativeV8Handle particles, QDeclarativeV8Handle followed);
void particlesPerParticlePerSecondChanged(int arg);