aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2011-07-20 13:46:52 +1000
committerQt by Nokia <qt-info@nokia.com>2011-07-28 11:27:26 +0200
commit0511dfc0b8851baf84df73780e770f1025261068 (patch)
tree65a9acb210ff5197c2c3f11edac594a124bfc206 /src/declarative
parent8fda8d16df9744b69a97020e3aae1ad40ff1f538 (diff)
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 <martin.jones@nokia.com>
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/particles/particles.pri10
-rw-r--r--src/declarative/particles/qsgcustomaffector.cpp73
-rw-r--r--src/declarative/particles/qsgcustomaffector_p.h69
-rw-r--r--src/declarative/particles/qsgcustomemitter.cpp189
-rw-r--r--src/declarative/particles/qsgcustomemitter_p.h76
-rw-r--r--src/declarative/particles/qsgemitter_p.h2
-rw-r--r--src/declarative/particles/qsgparticlesmodule.cpp8
-rw-r--r--src/declarative/particles/qsgparticlesystem.cpp11
-rw-r--r--src/declarative/particles/qsgparticlesystem_p.h5
-rw-r--r--src/declarative/particles/qsgv8particledata.cpp204
-rw-r--r--src/declarative/particles/qsgv8particledata_p.h69
-rw-r--r--src/declarative/qml/v8/qv8engine.cpp1
-rw-r--r--src/declarative/qml/v8/qv8engine_p.h2
13 files changed, 712 insertions, 7 deletions
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 <private/qv8engine_p.h>
+
+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 <QtCore>
+#include <QtCore>//FIXME
#include <QtGui>
#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<QSGItemParticle>(uri, 2, 0, "ItemParticle");
qmlRegisterType<QSGModelParticle>(uri, 2, 0, "ModelParticle");
- qmlRegisterType<QSGBasicEmitter>(uri, 2, 0, "Emitter");
+ qmlRegisterType<QSGBasicEmitter>(uri, 2, 0, "Emitter");//TODO: Rename BasicEmitter?
+ qmlRegisterType<QSGCustomEmitter>(uri, 2, 0, "CustomEmitter");
qmlRegisterType<QSGFollowEmitter>(uri, 2, 0, "FollowEmitter");
qmlRegisterType<QSGEllipseExtruder>(uri, 2, 0, "EllipseShape");
@@ -99,7 +102,8 @@ void QSGParticlesModule::defineModule()
qmlRegisterType<QSGTargetedDirection>(uri, 2, 0, "TargetedDirection");
qmlRegisterType<QSGCumulativeDirection>(uri, 2, 0, "CumulativeDirection");
- qmlRegisterType<QSGParticleAffector>(uri, 2, 0, "Affector");//for the triggered signal
+ qmlRegisterType<QSGParticleAffector>(uri, 2, 0, "Affector");//useful for the triggered signal
+ qmlRegisterType<QSGCustomAffector>(uri, 2, 0, "CustomAffector");
qmlRegisterType<QSGWanderAffector>(uri, 2, 0, "Wander");
qmlRegisterType<QSGFrictionAffector>(uri, 2, 0, "Friction");
qmlRegisterType<QSGPointAttractorAffector>(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 <private/qdeclarativeengine_p.h>
#include <cmath>
#include <QDebug>
@@ -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 <QtDeclarative/private/qsgsprite_p.h>
#include <QAbstractAnimation>
#include <QtDeclarative/qdeclarative.h>
+#include <private/qv8engine_p.h> //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 <QDebug>
+
+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<v8::Function> constructor;
+};
+
+static v8::Handle<v8::Value> particleData_discard(const v8::Arguments &args)
+{
+ QV8ParticleDataResource *r = v8_resource_cast<QV8ParticleDataResource>(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<v8::Value> particleData_lifeLeft(const v8::Arguments &args)
+{
+ QV8ParticleDataResource *r = v8_resource_cast<QV8ParticleDataResource>(args.This());
+ if (!r || !r->datum)
+ V8THROW_ERROR("Not a valid ParticleData object");
+
+ return v8::Number::New(r->datum->lifeLeft());
+}
+
+static v8::Handle<v8::Value> particleData_curSize(const v8::Arguments &args)
+{
+ QV8ParticleDataResource *r = v8_resource_cast<QV8ParticleDataResource>(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<v8::Value> particleData_get_ ## VARIABLE (v8::Local<v8::String>, const v8::AccessorInfo &info) \
+{ \
+ QV8ParticleDataResource *r = v8_resource_cast<QV8ParticleDataResource>(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::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)\
+{\
+ QV8ParticleDataResource *r = v8_resource_cast<QV8ParticleDataResource>(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<v8::FunctionTemplate> 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 <private/qv8engine_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QSGParticleData;
+class QSGV8ParticleData {
+public:
+ QSGV8ParticleData(QV8Engine*,QSGParticleData*);
+ ~QSGV8ParticleData();
+ QDeclarativeV8Handle v8Value();
+private:
+ v8::Persistent<v8::Object> 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<v8::Value> value, int typeHint)
case QV8ObjectResource::SQLDatabaseType:
case QV8ObjectResource::ListModelType:
case QV8ObjectResource::Context2DType:
+ case QV8ObjectResource::ParticleDataType:
return QVariant();
case QV8ObjectResource::QObjectType:
return qVariantFromValue<QObject *>(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;