diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-06-12 12:36:08 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@digia.com> | 2013-06-12 14:35:21 +0200 |
commit | c8a6cb67f09d5f714a4d388cd8710423fb0176fc (patch) | |
tree | 86c25c222c085f3201724c9db3c04556fa2a18e0 /src/particles/qquickv4particledata.cpp | |
parent | 9cd19964bb364f6dbd10b491cabd8304bdd0bc23 (diff) |
Port ParticleData to V4
Change-Id: Ifc48b73a2fbfda22d3c4419cb34dd5307107f688
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/particles/qquickv4particledata.cpp')
-rw-r--r-- | src/particles/qquickv4particledata.cpp | 519 |
1 files changed, 519 insertions, 0 deletions
diff --git a/src/particles/qquickv4particledata.cpp b/src/particles/qquickv4particledata.cpp new file mode 100644 index 0000000000..a5ec20aabb --- /dev/null +++ b/src/particles/qquickv4particledata.cpp @@ -0,0 +1,519 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#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> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Particle + \inqmlmodule QtQuick.Particles 2 + \brief Represents particles manipulated by emitters and affectors + \ingroup qtquick-particles + + Particle elements are always managed internally by the ParticleSystem and cannot be created in QML. + However, sometimes they are exposed via signals so as to allow arbitrary changes to the particle state +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::initialX + The x coordinate of the particle at the beginning of its lifetime. + + The method of simulation prefers to have the initial values changed, rather + than determining and changing the value at a given time. Change initial + values in CustomEmitters instead of the current values. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::initialVX + The x velocity of the particle at the beginning of its lifetime. + + The method of simulation prefers to have the initial values changed, rather + than determining and changing the value at a given time. Change initial + values in CustomEmitters instead of the current values. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::initialAX + The x acceleration of the particle at the beginning of its lifetime. + + The method of simulation prefers to have the initial values changed, rather + than determining and changing the value at a given time. Change initial + values in CustomEmitters instead of the current values. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::initialY + The y coordinate of the particle at the beginning of its lifetime. + + The method of simulation prefers to have the initial values changed, rather + than determining and changing the value at a given time. Change initial + values in CustomEmitters instead of the current values. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::initialVY + The y velocity of the particle at the beginning of its lifetime. + + The method of simulation prefers to have the initial values changed, rather + than determining and changing the value at a given time. Change initial + values in CustomEmitters instead of the current values. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::initialAY + The y acceleration of the particle at the beginning of its lifetime. + + The method of simulation prefers to have the initial values changed, rather + than determining and changing the value at a given time. Change initial + values in CustomEmitters instead of the current values. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::x + The current x coordinate of the particle. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::vx + The current x velocity of the particle. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::ax + The current x acceleration of the particle. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::y + The current y coordinate of the particle. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::vy + The current y velocity of the particle. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::ay + The current y acceleration of the particle. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::t + The time, in seconds since the beginning of the simulation, that the particle was born. +*/ + + +/*! + \qmlproperty real QtQuick.Particles2::Particle::startSize + The size in pixels that the particle image is at the start + of its life. +*/ + + +/*! + \qmlproperty real QtQuick.Particles2::Particle::endSize + The size in pixels that the particle image is at the end + of its life. If this value is less than 0, then it is + disregarded and the particle will have its startSize for the + entire lifetime. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::lifeSpan + The time in seconds that the particle will live for. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::rotation + Degrees clockwise that the particle image is rotated at + the beginning of its life. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::rotationVelocity + Degrees clockwise per second that the particle image is rotated at while alive. +*/ +/*! + \qmlproperty bool QtQuick.Particles2::Particle::autoRotate + If autoRotate is true, then the particle's rotation will be + set so that it faces the direction of travel, plus any + rotation from the rotation or rotationVelocity properties. +*/ + +/*! + \qmlproperty bool QtQuick.Particles2::Particle::update + + Inside an Affector, the changes made to the particle will only be + applied if update is set to true. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Particle::xDeformationVectorX + + The x component of the deformation vector along the X axis. ImageParticle + can draw particles across non-square shapes. It will draw the texture rectangle + across the parallelogram drawn with the x and y deformation vectors. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::yDeformationVectorX + + The y component of the deformation vector along the X axis. ImageParticle + can draw particles across non-square shapes. It will draw the texture rectangle + across the parallelogram drawn with the x and y deformation vectors. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::xDeformationVectorY + + The x component of the deformation vector along the X axis. ImageParticle + can draw particles across non-square shapes. It will draw the texture rectangle + across the parallelogram drawn with the x and y deformation vectors. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::yDeformationVectorY + + The y component of the deformation vector along the Y axis. ImageParticle + can draw particles across non-square shapes. It will draw the texture rectangle + across the parallelogram drawn with the x and y deformation vectors. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::red + + ImageParticle can draw colorized particles. When it does so, red is used + as the red channel of the color applied to the source image. + + Values are from 0.0 to 1.0. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::green + + ImageParticle can draw colorized particles. When it does so, green is used + as the green channel of the color applied to the source image. + + Values are from 0.0 to 1.0. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::blue + + ImageParticle can draw colorized particles. When it does so, blue is used + as the blue channel of the color applied to the source image. + + Values are from 0.0 to 1.0. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::alpha + + ImageParticle can draw colorized particles. When it does so, alpha is used + as the alpha channel of the color applied to the source image. + + Values are from 0.0 to 1.0. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Particle::lifeLeft + The time in seconds that the particle has left to live at + the current point in time. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Particle::currentSize + The currentSize of the particle, interpolating between startSize and endSize based on the currentTime. +*/ + + + +//### 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 +{ + Q_MANAGED + QV4ParticleData(QV4::ExecutionEngine *engine, QQuickParticleData *datum) + : Object(engine) + { + vtbl = &static_vtbl; + this->datum = datum; + } + + QQuickParticleData* datum;//TODO: Guard needed? + + static void destroy(Managed *that) + { that->as<QV4ParticleData>()->~QV4ParticleData(); } +}; + +DEFINE_MANAGED_VTABLE(QV4ParticleData); + +class QV8ParticleDataDeletable : public QV8Engine::Deletable +{ +public: + QV8ParticleDataDeletable(QV8Engine *engine); + ~QV8ParticleDataDeletable(); + + QV4::PersistentValue proto; +}; + +static QV4::Value particleData_discard(QV4::SimpleCallContext *ctx) +{ + QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); + + if (!r || !r->datum) + ctx->throwError(QStringLiteral("Not a valid ParticleData object")); + + r->datum->lifeSpan = 0; //Don't kill(), because it could still be in the middle of being created + return QV4::Value::undefinedValue(); +} + +static QV4::Value particleData_lifeLeft(QV4::SimpleCallContext *ctx) +{ + QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); + if (!r || !r->datum) + ctx->throwError(QStringLiteral("Not a valid ParticleData object")); + + return QV4::Value::fromDouble(r->datum->lifeLeft()); +} + +static QV4::Value particleData_curSize(QV4::SimpleCallContext *ctx) +{ + QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); + if (!r || !r->datum) + ctx->throwError(QStringLiteral("Not a valid ParticleData object")); + + return QV4::Value::fromDouble(r->datum->curSize()); +} +#define COLOR_GETTER_AND_SETTER(VAR, NAME) static QV4::Value particleData_get_ ## NAME (QV4::SimpleCallContext *ctx) \ +{ \ + QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \ + if (!r || !r->datum) \ + ctx->throwError(QStringLiteral("Not a valid ParticleData object")); \ +\ + return QV4::Value::fromDouble((r->datum->color. VAR )/255.0);\ +}\ +\ +static QV4::Value particleData_set_ ## NAME (QV4::SimpleCallContext *ctx)\ +{\ + QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \ + if (!r || !r->datum)\ + ctx->throwError(QStringLiteral("Not a valid ParticleData object"));\ +\ + r->datum->color. VAR = qMin(255, qMax(0, (int)floor(ctx->argument(0).toNumber() * 255.0)));\ + return QV4::Value::undefinedValue(); \ +} + + +#define SEMIBOOL_GETTER_AND_SETTER(VARIABLE) static QV4::Value particleData_get_ ## VARIABLE (QV4::SimpleCallContext *ctx) \ +{ \ + QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \ + if (!r || !r->datum) \ + ctx->throwError(QStringLiteral("Not a valid ParticleData object")); \ +\ + return QV4::Value::fromBoolean(r->datum-> VARIABLE);\ +}\ +\ +static QV4::Value particleData_set_ ## VARIABLE (QV4::SimpleCallContext *ctx)\ +{\ + QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \ + if (!r || !r->datum)\ + ctx->throwError(QStringLiteral("Not a valid ParticleData object"));\ +\ + r->datum-> VARIABLE = ctx->argument(0).toBoolean() ? 1.0 : 0.0;\ + return QV4::Value::undefinedValue(); \ +} + +#define FLOAT_GETTER_AND_SETTER(VARIABLE) static QV4::Value particleData_get_ ## VARIABLE (QV4::SimpleCallContext *ctx) \ +{ \ + QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \ + if (!r || !r->datum) \ + ctx->throwError(QStringLiteral("Not a valid ParticleData object")); \ +\ + return QV4::Value::fromDouble(r->datum-> VARIABLE);\ +}\ +\ +static QV4::Value particleData_set_ ## VARIABLE (QV4::SimpleCallContext *ctx)\ +{\ + QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \ + if (!r || !r->datum)\ + ctx->throwError(QStringLiteral("Not a valid ParticleData object"));\ +\ + r->datum-> VARIABLE = ctx->argument(0).toNumber();\ + return QV4::Value::undefinedValue(); \ +} + +#define FAKE_FLOAT_GETTER_AND_SETTER(VARIABLE, GETTER, SETTER) static QV4::Value particleData_get_ ## VARIABLE (QV4::SimpleCallContext *ctx) \ +{ \ + QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \ + if (!r || !r->datum) \ + ctx->throwError(QStringLiteral("Not a valid ParticleData object")); \ +\ + return QV4::Value::fromDouble(r->datum-> GETTER ());\ +}\ +\ +static QV4::Value particleData_set_ ## VARIABLE (QV4::SimpleCallContext *ctx)\ +{\ + QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \ + if (!r || !r->datum)\ + ctx->throwError(QStringLiteral("Not a valid ParticleData object"));\ +\ + r->datum-> SETTER ( ctx->argument(0).toNumber() );\ + return QV4::Value::undefinedValue(); \ +} + +#define REGISTER_ACCESSOR(PROTO, ENGINE, VARIABLE, NAME) \ + PROTO ->defineAccessorProperty( ENGINE, 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) +FLOAT_GETTER_AND_SETTER(r) +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) + +QV8ParticleDataDeletable::QV8ParticleDataDeletable(QV8Engine *engine) +{ + QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + QV4::Object *p = v4->newObject(); + + p->defineDefaultProperty(v4, QStringLiteral("discard"), particleData_discard); + p->defineDefaultProperty(v4, QStringLiteral("lifeLeft"), particleData_lifeLeft); + p->defineDefaultProperty(v4, 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, r, r); + 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 = QV4::Value::fromObject(p); +} + +QV8ParticleDataDeletable::~QV8ParticleDataDeletable() +{ +} + +V8_DEFINE_EXTENSION(QV8ParticleDataDeletable, particleV8Data); + + +QQuickV4ParticleData::QQuickV4ParticleData(QV8Engine* engine, QQuickParticleData* datum) +{ + if (!engine || !datum) + return; + + QV8ParticleDataDeletable *d = particleV8Data(engine); + QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + QV4::Object *o = new (v4->memoryManager) QV4ParticleData(v4, datum); + o->prototype = d->proto.value().asObject(); + m_v4Value = QV4::Value::fromObject(o); +} + +QQuickV4ParticleData::~QQuickV4ParticleData() +{ +} + +QQmlV4Handle QQuickV4ParticleData::v4Value() +{ + return QQmlV4Handle(m_v4Value); +} + +QT_END_NAMESPACE |