From 0511dfc0b8851baf84df73780e770f1025261068 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 20 Jul 2011 13:46:52 +1000 Subject: Initial CustomEmitter and CustomAffector implementation Currently basic and can't access all properties. Change-Id: I66efc235112cffcf1a3ca5cc69099a5d09ec7691 Reviewed-on: http://codereview.qt.nokia.com/1950 Reviewed-by: Martin Jones --- src/declarative/particles/particles.pri | 10 +- src/declarative/particles/qsgcustomaffector.cpp | 73 ++++++++ src/declarative/particles/qsgcustomaffector_p.h | 69 ++++++++ src/declarative/particles/qsgcustomemitter.cpp | 189 +++++++++++++++++++++ src/declarative/particles/qsgcustomemitter_p.h | 76 +++++++++ src/declarative/particles/qsgemitter_p.h | 2 +- src/declarative/particles/qsgparticlesmodule.cpp | 8 +- src/declarative/particles/qsgparticlesystem.cpp | 11 +- src/declarative/particles/qsgparticlesystem_p.h | 5 + src/declarative/particles/qsgv8particledata.cpp | 204 +++++++++++++++++++++++ src/declarative/particles/qsgv8particledata_p.h | 69 ++++++++ src/declarative/qml/v8/qv8engine.cpp | 1 + src/declarative/qml/v8/qv8engine_p.h | 2 +- 13 files changed, 712 insertions(+), 7 deletions(-) create mode 100644 src/declarative/particles/qsgcustomaffector.cpp create mode 100644 src/declarative/particles/qsgcustomaffector_p.h create mode 100644 src/declarative/particles/qsgcustomemitter.cpp create mode 100644 src/declarative/particles/qsgcustomemitter_p.h create mode 100644 src/declarative/particles/qsgv8particledata.cpp create mode 100644 src/declarative/particles/qsgv8particledata_p.h (limited to 'src/declarative') diff --git a/src/declarative/particles/particles.pri b/src/declarative/particles/particles.pri index bdd42aea70..582e1d3f8c 100644 --- a/src/declarative/particles/particles.pri +++ b/src/declarative/particles/particles.pri @@ -28,7 +28,10 @@ HEADERS += \ $$PWD/qsgturbulence_p.h \ $$PWD/qsgwander_p.h \ $$PWD/qsgtargetaffector_p.h \ - $$PWD/qsgcumulativedirection_p.h + $$PWD/qsgcumulativedirection_p.h \ + $$PWD/qsgcustomemitter_p.h \ + $$PWD/qsgcustomaffector_p.h \ + $$PWD/qsgv8particledata_p.h SOURCES += \ $$PWD/qsgangleddirection.cpp \ @@ -58,7 +61,10 @@ SOURCES += \ $$PWD/qsgturbulence.cpp \ $$PWD/qsgwander.cpp \ $$PWD/qsgtargetaffector.cpp \ - $$PWD/qsgcumulativedirection.cpp + $$PWD/qsgcumulativedirection.cpp \ + $$PWD/qsgcustomemitter.cpp \ + $$PWD/qsgcustomaffector.cpp \ + $$PWD/qsgv8particledata.cpp RESOURCES += \ $$PWD/particles.qrc diff --git a/src/declarative/particles/qsgcustomaffector.cpp b/src/declarative/particles/qsgcustomaffector.cpp new file mode 100644 index 0000000000..9832399661 --- /dev/null +++ b/src/declarative/particles/qsgcustomaffector.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgcustomaffector_p.h" +QT_BEGIN_NAMESPACE +/*! + \qmlclass CustomAffector QSGCustomAffector + \inqmlmodule QtQuick.Particles 2 + \since QtQuick.Particles 2.0 + \inherits Affector + \brief The Custom affector allows you to modify affected particles + +*/ + +//TODO: Document particle 'type' +/*! + \qmlsignal Timer::affecting(particle, dt) + + This handler is called when a particle is selected to be affected. + + dt is the time since the last time it was affected. Use dt to normalize + trajectory manipulations to real time. +*/ +QSGCustomAffector::QSGCustomAffector(QSGItem *parent) : + QSGParticleAffector(parent) +{ +} + + +bool QSGCustomAffector::affectParticle(QSGParticleData *d, qreal dt) +{ + emit affectParticle(d->v8Value(), dt); + return true;//TODO: Work it out (best added alongside autoTimeScaling) +} +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgcustomaffector_p.h b/src/declarative/particles/qsgcustomaffector_p.h new file mode 100644 index 0000000000..b4d0ca7417 --- /dev/null +++ b/src/declarative/particles/qsgcustomaffector_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CUSTOMAFFECTOR_H +#define CUSTOMAFFECTOR_H +#include "qsgparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGCustomAffector : public QSGParticleAffector +{ + Q_OBJECT +public: + explicit QSGCustomAffector(QSGItem *parent = 0); +protected: + virtual bool affectParticle(QSGParticleData *d, qreal dt); +signals: + void affectParticle(QDeclarativeV8Handle particle, qreal dt); + +public slots: + +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // CUSTOMAFFECTOR_H diff --git a/src/declarative/particles/qsgcustomemitter.cpp b/src/declarative/particles/qsgcustomemitter.cpp new file mode 100644 index 0000000000..4a379a3d72 --- /dev/null +++ b/src/declarative/particles/qsgcustomemitter.cpp @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgcustomemitter_p.h" +#include "qsgparticlesystem_p.h" +QT_BEGIN_NAMESPACE +/*! + \qmlclass CustomEmitter QSGCustomEmitter + \inqmlmodule QtQuick.Particles 2 + \since QtQuick.Particles 2.0 + \inherits Emitter + \brief The Custom emitter allows you to modify particles as they are emitted + +*/ + +//TODO: Document particle 'type' +/*! + \qmlsignal CustomEmitter::emitting(particle) + + This handler is called when a particle is emitted. You can modify particle + attributes from within the handler. +*/ + +QSGCustomEmitter::QSGCustomEmitter(QSGItem* parent) + : QSGParticleEmitter(parent) + , m_particle_count(0) + , m_reset_last(true) + , m_last_timestamp(0) + , m_last_emission(0) +{ +} + +void QSGCustomEmitter::reset() +{ + m_reset_last = true; +} + +void QSGCustomEmitter::emitWindow(int timeStamp) +{ + if (m_system == 0) + return; + if ((!m_emitting || !m_particlesPerSecond)&& !m_burstLeft && m_burstQueue.isEmpty()){ + m_reset_last = true; + return; + } + + if (m_reset_last) { + m_last_emitter = m_last_last_emitter = QPointF(x(), y()); + m_last_timestamp = timeStamp/1000.; + m_last_emission = m_last_timestamp; + m_reset_last = false; + } + + if (m_burstLeft){ + m_burstLeft -= timeStamp - m_last_timestamp * 1000.; + if (m_burstLeft < 0){ + if (!m_emitting) + timeStamp += m_burstLeft; + m_burstLeft = 0; + } + } + + qreal time = timeStamp / 1000.; + + qreal particleRatio = 1. / m_particlesPerSecond; + qreal pt = m_last_emission; + + qreal opt = pt; // original particle time + qreal dt = time - m_last_timestamp; // timestamp delta... + if (!dt) + dt = 0.000001; + + // emitter difference since last... + qreal dex = (x() - m_last_emitter.x()); + qreal dey = (y() - m_last_emitter.y()); + + qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize; + qreal emitter_x_offset = m_last_emitter.x() - x(); + qreal emitter_y_offset = m_last_emitter.y() - y(); + if (!m_burstQueue.isEmpty() && !m_burstLeft && !m_emitting)//'outside time' emissions only + pt = time; + while (pt < time || !m_burstQueue.isEmpty()) { + //int pos = m_last_particle % m_particle_count; + QSGParticleData* datum = m_system->newDatum(m_system->m_groupIds[m_particle]); + if (datum){//actually emit(otherwise we've been asked to skip this one) + datum->e = this;//###useful? + qreal t = 1 - (pt - opt) / dt; + + + // Particle timestamp + datum->t = pt; + datum->lifeSpan = //TODO:Promote to base class? + (m_particleDuration + + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation)) + / 1000.0; + + // Particle position + QRectF boundsRect; + if (!m_burstQueue.isEmpty()){ + boundsRect = QRectF(m_burstQueue.first().second.x() - x(), m_burstQueue.first().second.y() - y(), + width(), height()); + } else { + boundsRect = QRectF(emitter_x_offset + dex * (pt - opt) / dt, emitter_y_offset + dey * (pt - opt) / dt + , width(), height()); + } + QPointF newPos = effectiveExtruder()->extrude(boundsRect); + datum->x = newPos.x(); + datum->y = newPos.y(); + + // Particle speed + const QPointF &speed = m_speed->sample(newPos); + datum->sx = speed.x(); + datum->sy = speed.y(); + + // Particle acceleration + const QPointF &accel = m_acceleration->sample(newPos); + datum->ax = accel.x(); + datum->ay = accel.y(); + + // Particle size + float sizeVariation = -m_particleSizeVariation + + rand() / float(RAND_MAX) * m_particleSizeVariation * 2; + + float size = qMax((qreal)0.0 , m_particleSize + sizeVariation); + float endSize = qMax((qreal)0.0 , sizeAtEnd + sizeVariation); + + datum->size = size; + datum->endSize = endSize; + + emitParticle(datum->v8Value());//A chance for arbitrary JS changes + + m_system->emitParticle(datum); + } + if (m_burstQueue.isEmpty()){ + pt += particleRatio; + }else{ + m_burstQueue.first().first--; + if (m_burstQueue.first().first <= 0) + m_burstQueue.pop_front(); + } + } + m_last_emission = pt; + + m_last_last_last_emitter = m_last_last_emitter; + m_last_last_emitter = m_last_emitter; + m_last_emitter = QPointF(x(), y()); + m_last_timestamp = time; +} + + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgcustomemitter_p.h b/src/declarative/particles/qsgcustomemitter_p.h new file mode 100644 index 0000000000..4d22490fb6 --- /dev/null +++ b/src/declarative/particles/qsgcustomemitter_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGCUSTOMEMITTER_H +#define QSGCUSTOMEMITTER_H +#include "qsgparticleemitter_p.h" +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGCustomEmitter : public QSGParticleEmitter +{ + Q_OBJECT +public: + explicit QSGCustomEmitter(QSGItem* parent=0); + virtual ~QSGCustomEmitter(){} + virtual void emitWindow(int timeStamp); + virtual void reset(); +Q_SIGNALS: + void emitParticle(QDeclarativeV8Handle particle); +private: + int m_particle_count; + bool m_reset_last; + qreal m_last_timestamp; + qreal m_last_emission; + + QPointF m_last_emitter; + QPointF m_last_last_emitter; + QPointF m_last_last_last_emitter; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // QSGCUSTOMEMITTER_H diff --git a/src/declarative/particles/qsgemitter_p.h b/src/declarative/particles/qsgemitter_p.h index 0303c29d88..f61da15012 100644 --- a/src/declarative/particles/qsgemitter_p.h +++ b/src/declarative/particles/qsgemitter_p.h @@ -42,7 +42,7 @@ #ifndef TRAILSEMITTER_H #define TRAILSEMITTER_H -#include +#include //FIXME #include #include "qsgparticleemitter_p.h" diff --git a/src/declarative/particles/qsgparticlesmodule.cpp b/src/declarative/particles/qsgparticlesmodule.cpp index 330ff81e01..1bb06eae35 100644 --- a/src/declarative/particles/qsgparticlesmodule.cpp +++ b/src/declarative/particles/qsgparticlesmodule.cpp @@ -67,6 +67,8 @@ #include "qsgwander_p.h" #include "qsgtargetaffector_p.h" #include "qsgcumulativedirection_p.h" +#include "qsgcustomemitter_p.h" +#include "qsgcustomaffector_p.h" QT_BEGIN_NAMESPACE @@ -87,7 +89,8 @@ void QSGParticlesModule::defineModule() qmlRegisterType(uri, 2, 0, "ItemParticle"); qmlRegisterType(uri, 2, 0, "ModelParticle"); - qmlRegisterType(uri, 2, 0, "Emitter"); + qmlRegisterType(uri, 2, 0, "Emitter");//TODO: Rename BasicEmitter? + qmlRegisterType(uri, 2, 0, "CustomEmitter"); qmlRegisterType(uri, 2, 0, "FollowEmitter"); qmlRegisterType(uri, 2, 0, "EllipseShape"); @@ -99,7 +102,8 @@ void QSGParticlesModule::defineModule() qmlRegisterType(uri, 2, 0, "TargetedDirection"); qmlRegisterType(uri, 2, 0, "CumulativeDirection"); - qmlRegisterType(uri, 2, 0, "Affector");//for the triggered signal + qmlRegisterType(uri, 2, 0, "Affector");//useful for the triggered signal + qmlRegisterType(uri, 2, 0, "CustomAffector"); qmlRegisterType(uri, 2, 0, "Wander"); qmlRegisterType(uri, 2, 0, "Friction"); qmlRegisterType(uri, 2, 0, "PointAttractor"); diff --git a/src/declarative/particles/qsgparticlesystem.cpp b/src/declarative/particles/qsgparticlesystem.cpp index f25172dbda..6f4a6171c2 100644 --- a/src/declarative/particles/qsgparticlesystem.cpp +++ b/src/declarative/particles/qsgparticlesystem.cpp @@ -46,8 +46,10 @@ #include "qsgparticlepainter_p.h" #include "qsgspriteengine_p.h" #include "qsgsprite_p.h" +#include "qsgv8particledata_p.h" #include "qsgfollowemitter_p.h"//###For auto-follow on states, perhaps should be in emitter? +#include #include #include @@ -114,7 +116,7 @@ void QSGParticleDataHeap::grow() //###Consider automatic growth vs resize() call m_data.resize(1 << ++m_size); } -void QSGParticleDataHeap::insert(QSGParticleData* data) +void QSGParticleDataHeap::insert(QSGParticleData* data)//TODO: Optimize 0 lifespan (or already dead) case { int time = roundedTime(data->t + data->lifeSpan); if (m_lookups.contains(time)){ @@ -296,6 +298,7 @@ QSGParticleData::QSGParticleData(QSGParticleSystem* sys) , system(sys) , index(0) , systemIndex(-1) + , v8Datum(0) { x = 0; y = 0; @@ -359,6 +362,12 @@ void QSGParticleData::clone(const QSGParticleData& other) modelIndex = other.modelIndex; } +QDeclarativeV8Handle QSGParticleData::v8Value() +{ + if (!v8Datum) + v8Datum = new QSGV8ParticleData(QDeclarativeEnginePrivate::getV8Engine(qmlEngine(system)), this); + return v8Datum->v8Value(); +} //sets the x accleration without affecting the instantaneous x velocity or position void QSGParticleData::setInstantaneousAX(qreal ax) { diff --git a/src/declarative/particles/qsgparticlesystem_p.h b/src/declarative/particles/qsgparticlesystem_p.h index b9729f9ffd..fd46ee25c5 100644 --- a/src/declarative/particles/qsgparticlesystem_p.h +++ b/src/declarative/particles/qsgparticlesystem_p.h @@ -51,6 +51,7 @@ #include #include #include +#include //For QDeclarativeV8Handle QT_BEGIN_HEADER @@ -66,6 +67,7 @@ class QSGParticleData; class QSGParticleSystemAnimation; class QSGSpriteEngine; class QSGSprite; +class QSGV8ParticleData; struct QSGParticleDataHeapNode{ int time;//in ms @@ -204,6 +206,9 @@ public: float lifeLeft(); float curSize(); void clone(const QSGParticleData& other);//Not =, leaves meta-data like index + QDeclarativeV8Handle v8Value(); +private: + QSGV8ParticleData* v8Datum; }; class QSGParticleSystem : public QSGItem diff --git a/src/declarative/particles/qsgv8particledata.cpp b/src/declarative/particles/qsgv8particledata.cpp new file mode 100644 index 0000000000..6b31e3771e --- /dev/null +++ b/src/declarative/particles/qsgv8particledata.cpp @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgv8particledata_p.h" +#include "qsgparticlesystem_p.h"//for QSGParticleData +#include + +QT_BEGIN_NAMESPACE + +//### Particle data handles are not locked to within certain scopes like QSGContext2D, but there's no way to reload either... +class QV8ParticleDataResource : public QV8ObjectResource +{ + V8_RESOURCE_TYPE(ParticleDataType) +public: + QV8ParticleDataResource(QV8Engine *e) : QV8ObjectResource(e) {} + QSGParticleData* datum;//TODO: Guard needed? +}; + +class QV8ParticleDataDeletable : public QV8Engine::Deletable +{ +public: + QV8ParticleDataDeletable(QV8Engine *engine); + ~QV8ParticleDataDeletable(); + + v8::Persistent constructor; +}; + +static v8::Handle particleData_discard(const v8::Arguments &args) +{ + QV8ParticleDataResource *r = v8_resource_cast(args.This()); + + if (!r || !r->datum) + V8THROW_ERROR("Not a valid ParticleData object"); + + r->datum->lifeSpan = 0; //Don't kill(), because it could still be in the middle of being created + return v8::Undefined(); +} + +static v8::Handle particleData_lifeLeft(const v8::Arguments &args) +{ + QV8ParticleDataResource *r = v8_resource_cast(args.This()); + if (!r || !r->datum) + V8THROW_ERROR("Not a valid ParticleData object"); + + return v8::Number::New(r->datum->lifeLeft()); +} + +static v8::Handle particleData_curSize(const v8::Arguments &args) +{ + QV8ParticleDataResource *r = v8_resource_cast(args.This()); + if (!r || !r->datum) + V8THROW_ERROR("Not a valid ParticleData object"); + + return v8::Number::New(r->datum->curSize()); +} + +#define FLOAT_GETTER_AND_SETTER(VARIABLE) static v8::Handle particleData_get_ ## VARIABLE (v8::Local, const v8::AccessorInfo &info) \ +{ \ + QV8ParticleDataResource *r = v8_resource_cast(info.This()); \ + if (!r || !r->datum) \ + V8THROW_ERROR("Not a valid ParticleData object"); \ +\ + return v8::Number::New(r->datum-> VARIABLE);\ +}\ +\ +static void particleData_set_ ## VARIABLE (v8::Local, v8::Local value, const v8::AccessorInfo &info)\ +{\ + QV8ParticleDataResource *r = v8_resource_cast(info.This());\ + if (!r || !r->datum)\ + V8THROW_ERROR_SETTER("Not a valid ParticleData object");\ +\ + r->datum-> VARIABLE = value->NumberValue();\ +} + +#define FLOAT_REGISTER_ACCESSOR(FT, ENGINE, VARIABLE) FT ->PrototypeTemplate()->SetAccessor( v8::String::New( #VARIABLE ), particleData_get_ ## VARIABLE , particleData_set_ ## VARIABLE , v8::External::Wrap(ENGINE)) + +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(sx) +FLOAT_GETTER_AND_SETTER(sy) +FLOAT_GETTER_AND_SETTER(ax) +FLOAT_GETTER_AND_SETTER(ay) +FLOAT_GETTER_AND_SETTER(xx) +FLOAT_GETTER_AND_SETTER(xy) +FLOAT_GETTER_AND_SETTER(rotation) +FLOAT_GETTER_AND_SETTER(rotationSpeed) +FLOAT_GETTER_AND_SETTER(autoRotate) +FLOAT_GETTER_AND_SETTER(animIdx) +FLOAT_GETTER_AND_SETTER(frameDuration) +FLOAT_GETTER_AND_SETTER(frameCount) +FLOAT_GETTER_AND_SETTER(animT) +FLOAT_GETTER_AND_SETTER(r) + +//TODO: Non-floats (color) and special floats (curX) once basic floats are working well + +QV8ParticleDataDeletable::QV8ParticleDataDeletable(QV8Engine *engine) +{ + v8::HandleScope handle_scope; + v8::Context::Scope scope(engine->context()); + + v8::Local ft = v8::FunctionTemplate::New(); + ft->InstanceTemplate()->SetHasExternalResource(true); + ft->PrototypeTemplate()->Set(v8::String::New("discard"), V8FUNCTION(particleData_discard, engine)); + ft->PrototypeTemplate()->Set(v8::String::New("lifeLeft"), V8FUNCTION(particleData_lifeLeft, engine)); + ft->PrototypeTemplate()->Set(v8::String::New("curSize"), V8FUNCTION(particleData_curSize, engine)); + FLOAT_REGISTER_ACCESSOR(ft, engine, x); + FLOAT_REGISTER_ACCESSOR(ft, engine, y); + FLOAT_REGISTER_ACCESSOR(ft, engine, t); + FLOAT_REGISTER_ACCESSOR(ft, engine, lifeSpan); + FLOAT_REGISTER_ACCESSOR(ft, engine, size); + FLOAT_REGISTER_ACCESSOR(ft, engine, endSize); + FLOAT_REGISTER_ACCESSOR(ft, engine, sx); + FLOAT_REGISTER_ACCESSOR(ft, engine, sy); + FLOAT_REGISTER_ACCESSOR(ft, engine, ax); + FLOAT_REGISTER_ACCESSOR(ft, engine, ay); + FLOAT_REGISTER_ACCESSOR(ft, engine, xx); + FLOAT_REGISTER_ACCESSOR(ft, engine, xy); + FLOAT_REGISTER_ACCESSOR(ft, engine, rotation); + FLOAT_REGISTER_ACCESSOR(ft, engine, rotationSpeed); + FLOAT_REGISTER_ACCESSOR(ft, engine, autoRotate); + FLOAT_REGISTER_ACCESSOR(ft, engine, animIdx); + FLOAT_REGISTER_ACCESSOR(ft, engine, frameDuration); + FLOAT_REGISTER_ACCESSOR(ft, engine, frameCount); + FLOAT_REGISTER_ACCESSOR(ft, engine, animT); + FLOAT_REGISTER_ACCESSOR(ft, engine, r); + + constructor = qPersistentNew(ft->GetFunction()); +} + +QV8ParticleDataDeletable::~QV8ParticleDataDeletable() +{ + qPersistentDispose(constructor); +} + +V8_DEFINE_EXTENSION(QV8ParticleDataDeletable, particleV8Data); + + +QSGV8ParticleData::QSGV8ParticleData(QV8Engine* engine, QSGParticleData* datum) +{ + if (!engine || !datum) + return; + v8::HandleScope handle_scope; + v8::Context::Scope scope(engine->context()); + + QV8ParticleDataDeletable *d = particleV8Data(engine); + m_v8Value = qPersistentNew(d->constructor->NewInstance()); + QV8ParticleDataResource *r = new QV8ParticleDataResource(engine); + r->datum = datum; + m_v8Value->SetExternalResource(r); +} + +QSGV8ParticleData::~QSGV8ParticleData() +{ + qPersistentDispose(m_v8Value); +} + +QDeclarativeV8Handle QSGV8ParticleData::v8Value() +{ + return QDeclarativeV8Handle::fromHandle(m_v8Value); +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgv8particledata_p.h b/src/declarative/particles/qsgv8particledata_p.h new file mode 100644 index 0000000000..e4a78a9131 --- /dev/null +++ b/src/declarative/particles/qsgv8particledata_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGV8PARTICLEDATA_H +#define QSGV8PARTICLEDATA_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGParticleData; +class QSGV8ParticleData { +public: + QSGV8ParticleData(QV8Engine*,QSGParticleData*); + ~QSGV8ParticleData(); + QDeclarativeV8Handle v8Value(); +private: + v8::Persistent m_v8Value; +}; + + +QT_END_NAMESPACE + +QT_END_HEADER + + +#endif diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp index 2dd52b0ac3..056924291e 100644 --- a/src/declarative/qml/v8/qv8engine.cpp +++ b/src/declarative/qml/v8/qv8engine.cpp @@ -188,6 +188,7 @@ QVariant QV8Engine::toVariant(v8::Handle value, int typeHint) case QV8ObjectResource::SQLDatabaseType: case QV8ObjectResource::ListModelType: case QV8ObjectResource::Context2DType: + case QV8ObjectResource::ParticleDataType: return QVariant(); case QV8ObjectResource::QObjectType: return qVariantFromValue(m_qobjectWrapper.toQObject(r)); diff --git a/src/declarative/qml/v8/qv8engine_p.h b/src/declarative/qml/v8/qv8engine_p.h index d9f4feeb86..5058eee59f 100644 --- a/src/declarative/qml/v8/qv8engine_p.h +++ b/src/declarative/qml/v8/qv8engine_p.h @@ -125,7 +125,7 @@ public: QV8ObjectResource(QV8Engine *engine) : engine(engine) { Q_ASSERT(engine); } enum ResourceType { ContextType, QObjectType, TypeType, ListType, VariantType, ValueTypeType, XMLHttpRequestType, DOMNodeType, SQLDatabaseType, - ListModelType, Context2DType }; + ListModelType, Context2DType, ParticleDataType }; virtual ResourceType resourceType() const = 0; QV8Engine *engine; -- cgit v1.2.3