diff options
author | Ulf Hermann <[email protected]> | 2023-09-23 08:52:54 +0200 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2023-10-19 09:30:53 +0200 |
commit | c85695369c065d3735dc58d7e50c901c20f4bb35 (patch) | |
tree | 2055354fef65bbb8bffbc4ad21abf53031e1dc40 | |
parent | 742fba7d7a60de1f81c15d442e510946abaaefcf (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.cpp | 27 | ||||
-rw-r--r-- | src/particles/qquickcustomaffector_p.h | 2 | ||||
-rw-r--r-- | src/particles/qquickparticleemitter.cpp | 26 | ||||
-rw-r--r-- | src/particles/qquickparticleemitter_p.h | 2 | ||||
-rw-r--r-- | src/particles/qquickparticlesystem.cpp | 14 | ||||
-rw-r--r-- | src/particles/qquickparticlesystem_p.h | 6 | ||||
-rw-r--r-- | src/particles/qquicktrailemitter.cpp | 30 | ||||
-rw-r--r-- | src/particles/qquicktrailemitter_p.h | 4 | ||||
-rw-r--r-- | src/particles/qquickv4particledata.cpp | 265 | ||||
-rw-r--r-- | src/particles/qquickv4particledata_p.h | 107 |
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; }; |