aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <[email protected]>2023-09-23 08:52:54 +0200
committerUlf Hermann <[email protected]>2023-10-19 09:30:53 +0200
commitc85695369c065d3735dc58d7e50c901c20f4bb35 (patch)
tree2055354fef65bbb8bffbc4ad21abf53031e1dc40
parent742fba7d7a60de1f81c15d442e510946abaaefcf (diff)
Make QQuickV4ParticleData a value type
We don't need all the QJSValue wrangling. Change-Id: I683e3edc55de2cf3457cb86f952cf1eb717ae395 Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Shawn Rutledge (away) <[email protected]>
-rw-r--r--src/particles/qquickcustomaffector.cpp27
-rw-r--r--src/particles/qquickcustomaffector_p.h2
-rw-r--r--src/particles/qquickparticleemitter.cpp26
-rw-r--r--src/particles/qquickparticleemitter_p.h2
-rw-r--r--src/particles/qquickparticlesystem.cpp14
-rw-r--r--src/particles/qquickparticlesystem_p.h6
-rw-r--r--src/particles/qquicktrailemitter.cpp30
-rw-r--r--src/particles/qquicktrailemitter_p.h4
-rw-r--r--src/particles/qquickv4particledata.cpp265
-rw-r--r--src/particles/qquickv4particledata_p.h107
10 files changed, 145 insertions, 338 deletions
diff --git a/src/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp
index d34e256e40..2ba7b4c536 100644
--- a/src/particles/qquickcustomaffector.cpp
+++ b/src/particles/qquickcustomaffector.cpp
@@ -2,11 +2,12 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickcustomaffector_p.h"
-#include <private/qqmlengine_p.h>
+
+#include <private/qquickv4particledata_p.h>
#include <private/qqmlglobal_p.h>
-#include <private/qjsvalue_p.h>
-#include <QQmlEngine>
-#include <QDebug>
+
+#include <QtCore/qdebug.h>
+
QT_BEGIN_NAMESPACE
//TODO: Move docs (and inheritence) to real base when docs can propagate. Currently this pretends to be the base class!
@@ -66,7 +67,9 @@ QQuickCustomAffector::QQuickCustomAffector(QQuickItem *parent) :
bool QQuickCustomAffector::isAffectConnected()
{
- IS_SIGNAL_CONNECTED(this, QQuickCustomAffector, affectParticles, (const QJSValue &, qreal));
+ IS_SIGNAL_CONNECTED(
+ this, QQuickCustomAffector, affectParticles,
+ (const QList<QQuickV4ParticleData> &, qreal));
}
void QQuickCustomAffector::affectSystem(qreal dt)
@@ -110,19 +113,13 @@ void QQuickCustomAffector::affectSystem(qreal dt)
if (m_onceOff)
dt = 1.0;
- QQmlEngine *qmlEngine = ::qmlEngine(this);
- QV4::ExecutionEngine *v4 = qmlEngine->handle();
-
- QV4::Scope scope(v4);
- QV4::ScopedArrayObject array(scope, v4->newArrayObject(toAffect.size()));
- QV4::ScopedValue v(scope);
- for (int i=0; i<toAffect.size(); i++)
- array->put(i, (v = toAffect[i]->v4Value(m_system)));
+ QList<QQuickV4ParticleData> particles;
+ particles.reserve(toAffect.size());
+ for (QQuickParticleData *data: std::as_const(toAffect))
+ particles.push_back(data->v4Value(m_system));
const auto doAffect = [&](qreal dt) {
affectProperties(toAffect, dt);
- QJSValue particles;
- QJSValuePrivate::setValue(&particles, array);
emit affectParticles(particles, dt);
};
diff --git a/src/particles/qquickcustomaffector_p.h b/src/particles/qquickcustomaffector_p.h
index 50793f6a20..9222dd3ea8 100644
--- a/src/particles/qquickcustomaffector_p.h
+++ b/src/particles/qquickcustomaffector_p.h
@@ -75,7 +75,7 @@ public:
Q_SIGNALS:
- void affectParticles(const QJSValue &particles, qreal dt);
+ void affectParticles(const QList<QQuickV4ParticleData> &particles, qreal dt);
void positionChanged(QQuickDirection * arg);
diff --git a/src/particles/qquickparticleemitter.cpp b/src/particles/qquickparticleemitter.cpp
index 5e743137aa..ff5336a73d 100644
--- a/src/particles/qquickparticleemitter.cpp
+++ b/src/particles/qquickparticleemitter.cpp
@@ -4,10 +4,12 @@
#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
#include "qquickparticleemitter_p.h"
-#include <private/qqmlengine_p.h>
+
#include <private/qqmlglobal_p.h>
-#include <private/qjsvalue_p.h>
-#include <QRandomGenerator>
+#include <private/qquickv4particledata_p.h>
+
+#include <QtCore/qrandom.h>
+
QT_BEGIN_NAMESPACE
/*!
@@ -221,7 +223,8 @@ QQuickParticleEmitter::~QQuickParticleEmitter()
bool QQuickParticleEmitter::isEmitConnected()
{
- IS_SIGNAL_CONNECTED(this, QQuickParticleEmitter, emitParticles, (const QJSValue &));
+ IS_SIGNAL_CONNECTED(
+ this, QQuickParticleEmitter, emitParticles, (const QList<QQuickV4ParticleData> &));
}
void QQuickParticleEmitter::reclaculateGroupId() const
@@ -449,19 +452,14 @@ void QQuickParticleEmitter::emitWindow(int timeStamp)
m_system->emitParticle(d, this);
if (isEmitConnected()) {
- QQmlEngine *qmlEngine = ::qmlEngine(this);
- QV4::ExecutionEngine *v4 = qmlEngine->handle();
- QV4::Scope scope(v4);
-
//Done after emitParticle so that the Painter::load is done first, this allows you to customize its static variables
//We then don't need to request another reload, because the first reload isn't scheduled until we get back to the render thread
- QV4::ScopedArrayObject array(scope, v4->newArrayObject(toEmit.size()));
- QV4::ScopedValue v(scope);
- for (int i=0; i<toEmit.size(); i++)
- array->put(i, (v = toEmit[i]->v4Value(m_system)));
- QJSValue particles;
- QJSValuePrivate::setValue(&particles, array);
+ QList<QQuickV4ParticleData> particles;
+ particles.reserve(toEmit.size());
+ for (QQuickParticleData *particle : std::as_const(toEmit))
+ particles.push_back(particle->v4Value(m_system));
+
emit emitParticles(particles);//A chance for arbitrary JS changes
}
diff --git a/src/particles/qquickparticleemitter_p.h b/src/particles/qquickparticleemitter_p.h
index 155599c714..85df686269 100644
--- a/src/particles/qquickparticleemitter_p.h
+++ b/src/particles/qquickparticleemitter_p.h
@@ -101,7 +101,7 @@ public:
void setVelocityFromMovement(qreal s);
void componentComplete() override;
Q_SIGNALS:
- void emitParticles(const QJSValue &particles);
+ void emitParticles(const QList<QQuickV4ParticleData> &particles);
void particlesPerSecondChanged(qreal);
void particleDurationChanged(int);
void enabledChanged(bool);
diff --git a/src/particles/qquickparticlesystem.cpp b/src/particles/qquickparticlesystem.cpp
index 5d7ef12ed6..003cea4da6 100644
--- a/src/particles/qquickparticlesystem.cpp
+++ b/src/particles/qquickparticlesystem.cpp
@@ -14,6 +14,7 @@
#include "qquicktrailemitter_p.h"//###For auto-follow on states, perhaps should be in emitter?
#include <private/qqmlengine_p.h>
#include <private/qqmlglobal_p.h>
+#include <private/qqmlvaluetypewrapper_p.h>
#include <cmath>
#include <QDebug>
@@ -392,7 +393,6 @@ QQuickParticleData::QQuickParticleData()
, rotationOwner(nullptr)
, deformationOwner(nullptr)
, animationOwner(nullptr)
- , v4Datum(nullptr)
{
x = 0;
y = 0;
@@ -427,11 +427,6 @@ QQuickParticleData::QQuickParticleData()
delegate = nullptr;
}
-QQuickParticleData::~QQuickParticleData()
-{
- delete v4Datum;
-}
-
QQuickParticleData::QQuickParticleData(const QQuickParticleData &other)
{
*this = other;
@@ -445,7 +440,6 @@ QQuickParticleData &QQuickParticleData::operator=(const QQuickParticleData &othe
index = other.index;
systemIndex = other.systemIndex;
// Lazily initialized
- v4Datum = nullptr;
return *this;
}
@@ -486,11 +480,9 @@ void QQuickParticleData::clone(const QQuickParticleData& other)
animationOwner = other.animationOwner;
}
-QV4::ReturnedValue QQuickParticleData::v4Value(QQuickParticleSystem* particleSystem)
+QQuickV4ParticleData QQuickParticleData::v4Value(QQuickParticleSystem *particleSystem)
{
- if (!v4Datum)
- v4Datum = new QQuickV4ParticleData(qmlEngine(particleSystem)->handle(), this, particleSystem);
- return v4Datum->v4Value();
+ return QQuickV4ParticleData(this, particleSystem);
}
void QQuickParticleData::debugDump(QQuickParticleSystem* particleSystem) const
diff --git a/src/particles/qquickparticlesystem_p.h b/src/particles/qquickparticlesystem_p.h
index 6310528ef2..d68ad35532 100644
--- a/src/particles/qquickparticlesystem_p.h
+++ b/src/particles/qquickparticlesystem_p.h
@@ -212,7 +212,6 @@ class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleData {
public:
//TODO: QObject like memory management (without the cost, just attached to system)
QQuickParticleData();
- ~QQuickParticleData();
QQuickParticleData(const QQuickParticleData &other);
QQuickParticleData &operator=(const QQuickParticleData &other);
@@ -300,13 +299,10 @@ public:
float curSize(QQuickParticleSystem *particleSystem) const;
void clone(const QQuickParticleData& other);//Not =, leaves meta-data like index
- QV4::ReturnedValue v4Value(QQuickParticleSystem *particleSystem);
+ QQuickV4ParticleData v4Value(QQuickParticleSystem *particleSystem);
void extendLife(float time, QQuickParticleSystem *particleSystem);
static inline constexpr float EPSILON() noexcept { return 0.001f; }
-
-private:
- QQuickV4ParticleData* v4Datum;
};
class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleSystem : public QQuickItem
diff --git a/src/particles/qquicktrailemitter.cpp b/src/particles/qquicktrailemitter.cpp
index b1c754ca54..e5cd0891a5 100644
--- a/src/particles/qquicktrailemitter.cpp
+++ b/src/particles/qquicktrailemitter.cpp
@@ -4,11 +4,14 @@
#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
#include "qquicktrailemitter_p.h"
-#include <private/qqmlengine_p.h>
+
#include <private/qqmlglobal_p.h>
-#include <private/qjsvalue_p.h>
-#include <QRandomGenerator>
+#include <private/qquickv4particledata_p.h>
+
+#include <QtCore/qrandom.h>
+
#include <cmath>
+
QT_BEGIN_NAMESPACE
/*!
@@ -94,8 +97,9 @@ QQuickTrailEmitter::QQuickTrailEmitter(QQuickItem *parent) :
bool QQuickTrailEmitter::isEmitFollowConnected()
{
- IS_SIGNAL_CONNECTED(this, QQuickTrailEmitter, emitFollowParticles,
- (const QJSValue &, const QJSValue &));
+ IS_SIGNAL_CONNECTED(
+ this, QQuickTrailEmitter, emitFollowParticles,
+ (const QList<QQuickV4ParticleData> &, const QQuickV4ParticleData &));
}
void QQuickTrailEmitter::recalcParticlesPerSecond(){
@@ -234,21 +238,15 @@ void QQuickTrailEmitter::emitWindow(int timeStamp)
m_system->emitParticle(d, this);
if (isEmitConnected() || isEmitFollowConnected()) {
- QQmlEngine *qmlEngine = ::qmlEngine(this);
- QV4::ExecutionEngine *v4 = qmlEngine->handle();
- QV4::Scope scope(v4);
- QV4::ScopedArrayObject array(scope, v4->newArrayObject(toEmit.size()));
- QV4::ScopedValue v(scope);
- for (int i=0; i<toEmit.size(); i++)
- array->put(i, (v = toEmit[i]->v4Value(m_system)));
+ QList<QQuickV4ParticleData> particles;
+ particles.reserve(toEmit.size());
+ for (QQuickParticleData *particle : std::as_const(toEmit))
+ particles.push_back(particle->v4Value(m_system));
- QJSValue particles;
- QJSValuePrivate::setValue(&particles, array);
if (isEmitFollowConnected()) {
//A chance for many arbitrary JS changes
- emit emitFollowParticles(
- particles, QJSValuePrivate::fromReturnedValue(d->v4Value(m_system)));
+ emit emitFollowParticles(particles, d->v4Value(m_system));
} else if (isEmitConnected()) {
emit emitParticles(particles);//A chance for arbitrary JS changes
}
diff --git a/src/particles/qquicktrailemitter_p.h b/src/particles/qquicktrailemitter_p.h
index 7a4757898a..13183cc7d0 100644
--- a/src/particles/qquicktrailemitter_p.h
+++ b/src/particles/qquicktrailemitter_p.h
@@ -66,7 +66,9 @@ public:
}
Q_SIGNALS:
- void emitFollowParticles(const QJSValue &particles, const QJSValue &followed);
+ void emitFollowParticles(
+ const QList<QQuickV4ParticleData> &particles,
+ const QQuickV4ParticleData &followed);
void particlesPerParticlePerSecondChanged(int arg);
diff --git a/src/particles/qquickv4particledata.cpp b/src/particles/qquickv4particledata.cpp
index 7988259140..14b327d04a 100644
--- a/src/particles/qquickv4particledata.cpp
+++ b/src/particles/qquickv4particledata.cpp
@@ -3,7 +3,6 @@
#include <math.h>
#include "qquickv4particledata_p.h"
-#include "qquickparticlesystem_p.h"//for QQuickParticleData
#include <QDebug>
#include <private/qv4engine_p.h>
#include <private/qv4functionobject_p.h>
@@ -231,268 +230,4 @@ QT_BEGIN_NAMESPACE
The currentSize of the particle, interpolating between startSize and endSize based on the currentTime.
*/
-namespace QV4 {
-namespace Heap {
-struct QV4ParticleData : QV4::Object::Data {
- void init(QQuickParticleData *datum, QQuickParticleSystem* particleSystem)
- {
- Object::init();
- this->datum = datum;
- this->particleSystem = particleSystem;
- }
- QQuickParticleData* datum;//TODO: Guard needed?
- QQuickParticleSystem* particleSystem;
-};
-}
-}
-
-//### Particle data handles are not locked to within certain scopes like QQuickContext2D, but there's no way to reload either...
-struct QV4ParticleData : public QV4::Object
-{
- V4_OBJECT2(QV4ParticleData, QV4::Object)
-};
-
-DEFINE_OBJECT_VTABLE(QV4ParticleData);
-
-class QV4ParticleDataDeletable : public QV4::ExecutionEngine::Deletable
-{
-public:
- QV4ParticleDataDeletable(QV4::ExecutionEngine *engine);
- ~QV4ParticleDataDeletable() override;
-
- QV4::PersistentValue proto;
-};
-
-static QV4::ReturnedValue particleData_discard(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
-{
- QV4::Scope scope(b);
- QV4::Scoped<QV4ParticleData> r(scope, *thisObject);
-
- if (!r || !r->d()->datum)
- RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));
-
- r->d()->datum->lifeSpan = 0; //Don't kill(), because it could still be in the middle of being created
- RETURN_RESULT(QV4::Encode::undefined());
-}
-
-static QV4::ReturnedValue particleData_lifeLeft(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
-{
- QV4::Scope scope(b);
- QV4::Scoped<QV4ParticleData> r(scope, *thisObject);
-
- if (!r || !r->d()->datum)
- RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));
-
- RETURN_RESULT(QV4::Encode(r->d()->datum->lifeLeft(r->d()->particleSystem)));
-}
-
-static QV4::ReturnedValue particleData_curSize(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
-{
- QV4::Scope scope(b);
- QV4::Scoped<QV4ParticleData> r(scope, *thisObject);
-
- if (!r || !r->d()->datum)
- RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));
-
- RETURN_RESULT(QV4::Encode(r->d()->datum->curSize(r->d()->particleSystem)));
-}
-#define COLOR_GETTER_AND_SETTER(VAR, NAME) static QV4::ReturnedValue particleData_get_ ## NAME (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) \
-{ \
- QV4::Scope scope(b); \
- QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
- if (!r || !r->d()->datum) \
- RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object"))); \
-\
- RETURN_RESULT(QV4::Encode((r->d()->datum->color. VAR )/255.0));\
-}\
-\
-static QV4::ReturnedValue particleData_set_ ## NAME (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)\
-{\
- QV4::Scope scope(b); \
- QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
- if (!r || !r->d()->datum)\
- RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));\
-\
- double d = argc ? argv[0].toNumber() : 0; \
- r->d()->datum->color. VAR = qMin(255, qMax(0, (int)::floor(d * 255.0)));\
- RETURN_UNDEFINED(); \
-}
-
-
-#define SEMIBOOL_GETTER_AND_SETTER(VARIABLE) static QV4::ReturnedValue particleData_get_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) \
-{ \
- QV4::Scope scope(b); \
- QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
- if (!r || !r->d()->datum) \
- RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object"))); \
-\
- RETURN_RESULT(QV4::Encode(r->d()->datum-> VARIABLE));\
-}\
-\
-static QV4::ReturnedValue particleData_set_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)\
-{\
- QV4::Scope scope(b); \
- QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
- if (!r || !r->d()->datum)\
- RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));\
-\
- r->d()->datum-> VARIABLE = (argc && argv[0].toBoolean()) ? 1.0 : 0.0;\
- RETURN_UNDEFINED(); \
-}
-
-#define FLOAT_GETTER_AND_SETTER(VARIABLE) static QV4::ReturnedValue particleData_get_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) \
-{ \
- QV4::Scope scope(b); \
- QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
- if (!r || !r->d()->datum) \
- RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object"))); \
-\
- RETURN_RESULT(QV4::Encode(r->d()->datum-> VARIABLE));\
-}\
-\
-static QV4::ReturnedValue particleData_set_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)\
-{\
- QV4::Scope scope(b); \
- QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
- if (!r || !r->d()->datum)\
- RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));\
-\
- r->d()->datum-> VARIABLE = argc ? argv[0].toNumber() : qt_qnan();\
- RETURN_UNDEFINED(); \
-}
-
-#define FAKE_FLOAT_GETTER_AND_SETTER(VARIABLE, GETTER, SETTER) static QV4::ReturnedValue particleData_get_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) \
-{ \
- QV4::Scope scope(b); \
- QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
- if (!r || !r->d()->datum) \
- RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object"))); \
-\
- RETURN_RESULT(QV4::Encode(r->d()->datum-> GETTER (r->d()->particleSystem)));\
-}\
-\
-static QV4::ReturnedValue particleData_set_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)\
-{\
- QV4::Scope scope(b); \
- QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
- if (!r || !r->d()->datum)\
- RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));\
-\
- r->d()->datum-> SETTER (argc ? argv[0].toNumber() : qt_qnan(), r->d()->particleSystem);\
- RETURN_UNDEFINED(); \
-}
-
-#define REGISTER_ACCESSOR(PROTO, ENGINE, VARIABLE, NAME) \
- PROTO ->defineAccessorProperty( QStringLiteral( #NAME ), particleData_get_ ## VARIABLE , particleData_set_ ## VARIABLE )
-
-COLOR_GETTER_AND_SETTER(r, red)
-COLOR_GETTER_AND_SETTER(g, green)
-COLOR_GETTER_AND_SETTER(b, blue)
-COLOR_GETTER_AND_SETTER(a, alpha)
-SEMIBOOL_GETTER_AND_SETTER(autoRotate)
-SEMIBOOL_GETTER_AND_SETTER(update)
-FLOAT_GETTER_AND_SETTER(x)
-FLOAT_GETTER_AND_SETTER(y)
-FLOAT_GETTER_AND_SETTER(t)
-FLOAT_GETTER_AND_SETTER(lifeSpan)
-FLOAT_GETTER_AND_SETTER(size)
-FLOAT_GETTER_AND_SETTER(endSize)
-FLOAT_GETTER_AND_SETTER(vx)
-FLOAT_GETTER_AND_SETTER(vy)
-FLOAT_GETTER_AND_SETTER(ax)
-FLOAT_GETTER_AND_SETTER(ay)
-FLOAT_GETTER_AND_SETTER(xx)
-FLOAT_GETTER_AND_SETTER(xy)
-FLOAT_GETTER_AND_SETTER(yx)
-FLOAT_GETTER_AND_SETTER(yy)
-FLOAT_GETTER_AND_SETTER(rotation)
-FLOAT_GETTER_AND_SETTER(rotationVelocity)
-FLOAT_GETTER_AND_SETTER(animIdx)
-FLOAT_GETTER_AND_SETTER(frameDuration)
-FLOAT_GETTER_AND_SETTER(frameAt)
-FLOAT_GETTER_AND_SETTER(frameCount)
-FLOAT_GETTER_AND_SETTER(animT)
-FAKE_FLOAT_GETTER_AND_SETTER(curX, curX, setInstantaneousX)
-FAKE_FLOAT_GETTER_AND_SETTER(curVX, curVX, setInstantaneousVX)
-FAKE_FLOAT_GETTER_AND_SETTER(curAX, curAX, setInstantaneousAX)
-FAKE_FLOAT_GETTER_AND_SETTER(curY, curY, setInstantaneousY)
-FAKE_FLOAT_GETTER_AND_SETTER(curVY, curVY, setInstantaneousVY)
-FAKE_FLOAT_GETTER_AND_SETTER(curAY, curAY, setInstantaneousAY)
-
-QV4ParticleDataDeletable::QV4ParticleDataDeletable(QV4::ExecutionEngine *v4)
-{
- QV4::Scope scope(v4);
- QV4::ScopedObject p(scope, v4->newObject());
-
- p->defineDefaultProperty(QStringLiteral("discard"), particleData_discard);
- p->defineDefaultProperty(QStringLiteral("lifeLeft"), particleData_lifeLeft);
- p->defineDefaultProperty(QStringLiteral("currentSize"), particleData_curSize);
-
- REGISTER_ACCESSOR(p, v4, x, initialX);
- REGISTER_ACCESSOR(p, v4, y, initialY);
- REGISTER_ACCESSOR(p, v4, t, t);
- REGISTER_ACCESSOR(p, v4, lifeSpan, lifeSpan);
- REGISTER_ACCESSOR(p, v4, size, startSize);
- REGISTER_ACCESSOR(p, v4, endSize, endSize);
- REGISTER_ACCESSOR(p, v4, vx, initialVX);
- REGISTER_ACCESSOR(p, v4, vy, initialVY);
- REGISTER_ACCESSOR(p, v4, ax, initialAX);
- REGISTER_ACCESSOR(p, v4, ay, initialAY);
- REGISTER_ACCESSOR(p, v4, xx, xDeformationVectorX);
- REGISTER_ACCESSOR(p, v4, xy, xDeformationVectorY);
- REGISTER_ACCESSOR(p, v4, yx, yDeformationVectorX);
- REGISTER_ACCESSOR(p, v4, yy, yDeformationVectorY);
- REGISTER_ACCESSOR(p, v4, rotation, rotation);
- REGISTER_ACCESSOR(p, v4, rotationVelocity, rotationVelocity);
- REGISTER_ACCESSOR(p, v4, autoRotate, autoRotate);
- REGISTER_ACCESSOR(p, v4, animIdx, animationIndex);
- REGISTER_ACCESSOR(p, v4, frameDuration, frameDuration);
- REGISTER_ACCESSOR(p, v4, frameAt, frameAt);
- REGISTER_ACCESSOR(p, v4, frameCount, frameCount);
- REGISTER_ACCESSOR(p, v4, animT, animationT);
- REGISTER_ACCESSOR(p, v4, update, update);
- REGISTER_ACCESSOR(p, v4, curX, x);
- REGISTER_ACCESSOR(p, v4, curVX, vx);
- REGISTER_ACCESSOR(p, v4, curAX, ax);
- REGISTER_ACCESSOR(p, v4, curY, y);
- REGISTER_ACCESSOR(p, v4, curVY, vy);
- REGISTER_ACCESSOR(p, v4, curAY, ay);
- REGISTER_ACCESSOR(p, v4, red, red);
- REGISTER_ACCESSOR(p, v4, green, green);
- REGISTER_ACCESSOR(p, v4, blue, blue);
- REGISTER_ACCESSOR(p, v4, alpha, alpha);
-
- proto = p;
-}
-
-QV4ParticleDataDeletable::~QV4ParticleDataDeletable()
-{
-}
-
-V4_DEFINE_EXTENSION(QV4ParticleDataDeletable, particleV4Data);
-
-
-QQuickV4ParticleData::QQuickV4ParticleData(QV4::ExecutionEngine* v4, QQuickParticleData* datum,
- QQuickParticleSystem *system)
-{
- if (!v4 || !datum)
- return;
-
- QV4::Scope scope(v4);
- QV4ParticleDataDeletable *d = particleV4Data(scope.engine);
- QV4::ScopedObject o(scope, v4->memoryManager->allocate<QV4ParticleData>(datum, system));
- QV4::ScopedObject p(scope, d->proto.value());
- o->setPrototypeUnchecked(p);
- m_v4Value = o;
-}
-
-QQuickV4ParticleData::~QQuickV4ParticleData()
-{
-}
-
-QV4::ReturnedValue QQuickV4ParticleData::v4Value() const
-{
- return m_v4Value.value();
-}
-
QT_END_NAMESPACE
diff --git a/src/particles/qquickv4particledata_p.h b/src/particles/qquickv4particledata_p.h
index 1bc6d24527..81c859802d 100644
--- a/src/particles/qquickv4particledata_p.h
+++ b/src/particles/qquickv4particledata_p.h
@@ -15,20 +15,109 @@
// We mean it.
//
-#include <private/qv4persistent_p.h>
-#include <private/qv4value_p.h>
+#include <private/qquickparticlesystem_p.h>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
-class QQuickParticleData;
-class QQuickParticleSystem;
-class QQuickV4ParticleData {
+class QQuickV4ParticleData
+{
+ Q_GADGET
+ QML_VALUE_TYPE(particle)
+ QML_ADDED_IN_VERSION(6, 7)
+
+#define Q_QUICK_PARTICLE_ACCESSOR(TYPE, VARIABLE, NAME) \
+ Q_PROPERTY(TYPE NAME READ NAME WRITE set_ ## NAME) \
+ TYPE NAME() const { return datum ? datum->VARIABLE : TYPE(); } \
+ void set_ ## NAME(TYPE a) { if (datum) datum->VARIABLE = a; }
+
+ Q_QUICK_PARTICLE_ACCESSOR(float, x, initialX)
+ Q_QUICK_PARTICLE_ACCESSOR(float, vx, initialVX)
+ Q_QUICK_PARTICLE_ACCESSOR(float, ax, initialAX)
+ Q_QUICK_PARTICLE_ACCESSOR(float, y, initialY)
+ Q_QUICK_PARTICLE_ACCESSOR(float, vy, initialVY)
+ Q_QUICK_PARTICLE_ACCESSOR(float, ay, initialAY)
+ Q_QUICK_PARTICLE_ACCESSOR(float, t, t)
+ Q_QUICK_PARTICLE_ACCESSOR(float, size, startSize)
+ Q_QUICK_PARTICLE_ACCESSOR(float, endSize, endSize)
+ Q_QUICK_PARTICLE_ACCESSOR(float, lifeSpan, lifeSpan)
+ Q_QUICK_PARTICLE_ACCESSOR(float, rotation, rotation)
+ Q_QUICK_PARTICLE_ACCESSOR(float, rotationVelocity, rotationVelocity)
+ Q_QUICK_PARTICLE_ACCESSOR(bool, autoRotate, autoRotate)
+ Q_QUICK_PARTICLE_ACCESSOR(bool, update, update)
+ Q_QUICK_PARTICLE_ACCESSOR(float, xx, xDeformationVectorX)
+ Q_QUICK_PARTICLE_ACCESSOR(float, yx, yDeformationVectorX)
+ Q_QUICK_PARTICLE_ACCESSOR(float, xy, xDeformationVectorY)
+ Q_QUICK_PARTICLE_ACCESSOR(float, yy, yDeformationVectorY)
+
+ // Undocumented?
+ Q_QUICK_PARTICLE_ACCESSOR(float, animIdx, animationIndex)
+ Q_QUICK_PARTICLE_ACCESSOR(float, frameDuration, frameDuration)
+ Q_QUICK_PARTICLE_ACCESSOR(float, frameAt, frameAt)
+ Q_QUICK_PARTICLE_ACCESSOR(float, frameCount, frameCount)
+ Q_QUICK_PARTICLE_ACCESSOR(float, animT, animationT)
+
+#undef Q_QUICK_PARTICLE_ACCESSOR
+
+#define Q_QUICK_PARTICLE_SYSTEM_ACCESSOR(GETTER, SETTER, NAME) \
+ Q_PROPERTY(float NAME READ NAME WRITE set_ ## NAME) \
+ float NAME() const { return (datum && particleSystem) ? datum->GETTER(particleSystem) : 0; } \
+ void set_ ## NAME(float a) { if (datum && particleSystem) datum->SETTER(a, particleSystem); }
+
+ Q_QUICK_PARTICLE_SYSTEM_ACCESSOR(curX, setInstantaneousX, x)
+ Q_QUICK_PARTICLE_SYSTEM_ACCESSOR(curVX, setInstantaneousVX, vx)
+ Q_QUICK_PARTICLE_SYSTEM_ACCESSOR(curAX, setInstantaneousAX, ax)
+ Q_QUICK_PARTICLE_SYSTEM_ACCESSOR(curY, setInstantaneousY, y)
+ Q_QUICK_PARTICLE_SYSTEM_ACCESSOR(curVY, setInstantaneousVY, vy)
+ Q_QUICK_PARTICLE_SYSTEM_ACCESSOR(curAY, setInstantaneousAY, ay)
+
+#undef Q_QUICK_PARTICLE_SYSTEM_ACCESSOR
+
+#define Q_QUICK_PARTICLE_COLOR_ACCESSOR(VAR, NAME) \
+ Q_PROPERTY(float NAME READ NAME WRITE set_ ## NAME) \
+ float NAME() const { return datum ? datum->color.VAR / 255.0 : 0.0; } \
+ void set_ ## NAME(float a)\
+ {\
+ if (datum)\
+ datum->color.VAR = qMin(255, qMax(0, (int)::floor(a * 255.0)));\
+ }
+
+ Q_QUICK_PARTICLE_COLOR_ACCESSOR(r, red)
+ Q_QUICK_PARTICLE_COLOR_ACCESSOR(g, green)
+ Q_QUICK_PARTICLE_COLOR_ACCESSOR(b, blue)
+ Q_QUICK_PARTICLE_COLOR_ACCESSOR(a, alpha)
+
+#undef Q_QUICK_PARTICLE_COLOR_ACCESSOR
+
+ Q_PROPERTY(float lifeLeft READ lifeLeft)
+ Q_PROPERTY(float currentSize READ currentSize)
+
public:
- QQuickV4ParticleData(QV4::ExecutionEngine*, QQuickParticleData*, QQuickParticleSystem *system);
- ~QQuickV4ParticleData();
- QV4::ReturnedValue v4Value() const;
+ QQuickV4ParticleData() = default;
+ QQuickV4ParticleData(QQuickParticleData *datum, QQuickParticleSystem *system)
+ : datum(datum)
+ , particleSystem(system)
+ {}
+
+ Q_INVOKABLE void discard()
+ {
+ if (datum)
+ datum->lifeSpan = 0;
+ }
+
+ float lifeLeft() const
+ {
+ return (datum && particleSystem) ? datum->lifeLeft(particleSystem) : 0.0;
+ }
+
+ float currentSize() const
+ {
+ return (datum && particleSystem) ? datum->curSize(particleSystem) : 0.0;
+ }
+
private:
- QV4::PersistentValue m_v4Value;
+ QQuickParticleData *datum = nullptr;
+ QQuickParticleSystem *particleSystem = nullptr;
};