Absorb CustomEmitter/Affector
authorAlan Alpert <alan.alpert@nokia.com>
Tue, 23 Aug 2011 10:03:43 +0000 (20:03 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 24 Aug 2011 10:27:43 +0000 (12:27 +0200)
The signal is now on the Emitter/Affector base type, but only
emitted if connected to (to save creating the v8 object)

Change-Id: Ib5522e0f760caa17a6ad731b2dfbce9994a7664e
Reviewed-on: http://codereview.qt.nokia.com/3393
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Martin Jones <martin.jones@nokia.com>
12 files changed:
examples/declarative/particles/custom/custom.qml
examples/declarative/particles/custom/fallingleaves.qml
src/declarative/particles/particles.pri
src/declarative/particles/qsgcustomaffector.cpp [deleted file]
src/declarative/particles/qsgcustomaffector_p.h [deleted file]
src/declarative/particles/qsgcustomemitter.cpp [deleted file]
src/declarative/particles/qsgcustomemitter_p.h [deleted file]
src/declarative/particles/qsgparticleaffector.cpp
src/declarative/particles/qsgparticleaffector_p.h
src/declarative/particles/qsgparticleemitter.cpp
src/declarative/particles/qsgparticleemitter_p.h
src/declarative/particles/qsgparticlesmodule.cpp

index 7a6b51d..9a562af 100644 (file)
@@ -27,7 +27,7 @@ ParticleSystem{
         duration: 24000
     }
     function convert(a){return a*(Math.PI/180);}
-    CustomEmitter{
+    Emitter{
         lifeSpan: 4000
         emitRate: 120
         size: 12
index 1d1282e..3572490 100644 (file)
@@ -25,7 +25,7 @@ Item {
         xVariance: 60
         pace: 60
     }
-    CustomAffector{
+    Affector{
         system: sys
         property real coefficient: 0.1
         property real speed: 1.5
@@ -56,7 +56,7 @@ Item {
         }
     }
 
-    CustomAffector{//Custom Friction, adds some 'randomness'
+    Affector{//Custom Friction, adds some 'randomness'
         system: sys
         //onceOff: true
         x: -60
index 1fc5783..9f63cd8 100644 (file)
@@ -28,8 +28,6 @@ HEADERS += \
     $$PWD/qsgwander_p.h \
     $$PWD/qsgtargetaffector_p.h \
     $$PWD/qsgcumulativedirection_p.h \
-    $$PWD/qsgcustomemitter_p.h \
-    $$PWD/qsgcustomaffector_p.h \
     $$PWD/qsgv8particledata_p.h
 
 SOURCES += \
@@ -60,8 +58,6 @@ SOURCES += \
     $$PWD/qsgwander.cpp \
     $$PWD/qsgtargetaffector.cpp \
     $$PWD/qsgcumulativedirection.cpp \
-    $$PWD/qsgcustomemitter.cpp \
-    $$PWD/qsgcustomaffector.cpp \
     $$PWD/qsgv8particledata.cpp
 
 RESOURCES += \
diff --git a/src/declarative/particles/qsgcustomaffector.cpp b/src/declarative/particles/qsgcustomaffector.cpp
deleted file mode 100644 (file)
index f28fcd8..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** 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
-    \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
deleted file mode 100644 (file)
index b4d0ca7..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644 (file)
index 6b40f17..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/****************************************************************************
-**
-** 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
-    \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->vx = speed.x();
-            datum->vy = 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
deleted file mode 100644 (file)
index 4d22490..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** 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
index 222af3d..4cb3e49 100644 (file)
@@ -94,11 +94,24 @@ QT_BEGIN_NAMESPACE
 /*!
     \qmlproperty bool QtQuick.Particles2::Affector::signal
     If this is set to true, then an affected(x,y) signal will be emitted each
-    time this affector affects a particle.
+    time this affector would affect a particle.
+
+    For Affector only, this will happen irrespective of whether any changes
+    are made to the particle, for other Affectors the signal will only fire
+    if the particle is actually affected.
 
     Default value is false.
 */
 
+//TODO: Document particle 'type'
+/*!
+    \qmlsignal QtQuick.Particles2::Affector::affectParticle(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.
+*/
 QSGParticleAffector::QSGParticleAffector(QSGItem *parent) :
     QSGItem(parent), m_needsReset(false), m_system(0), m_active(true)
   , m_updateIntSet(false), m_shape(new QSGParticleExtruder(this)), m_signal(false)
@@ -111,6 +124,12 @@ QSGParticleAffector::QSGParticleAffector(QSGItem *parent) :
             this, SLOT(updateOffsets()));//TODO: in componentComplete and all relevant signals
 }
 
+bool QSGParticleAffector::isAffectConnected()
+{
+    static int idx = QObjectPrivate::get(this)->signalIndex("affectParticle(QDeclarativeV8Handle, qreal)");
+    return QObjectPrivate::get(this)->isSignalConnected(idx);
+}
+
 void QSGParticleAffector::componentComplete()
 {
     if (!m_system && qobject_cast<QSGParticleSystem*>(parentItem()))
@@ -161,8 +180,10 @@ void QSGParticleAffector::affectSystem(qreal dt)
 
 bool QSGParticleAffector::affectParticle(QSGParticleData *d, qreal dt)
 {
-    Q_UNUSED(d);
-    Q_UNUSED(dt);
+    if (isAffectConnected()){
+        emit affectParticle(d->v8Value(), dt);
+        return true;
+    }
     return m_signal;//If signalling, then we always 'null affect' it.
 }
 
index 4479f5d..dd279c0 100644 (file)
@@ -103,6 +103,7 @@ public:
     }
 
 signals:
+    void affectParticle(QDeclarativeV8Handle particle, qreal dt);
 
     void systemChanged(QSGParticleSystem* arg);
 
@@ -189,6 +190,7 @@ protected:
     bool m_active;
     virtual void componentComplete();
     QPointF m_offset;
+    bool isAffectConnected();
 private:
     QSet<int> m_groups;
     QSet<QPair<int, int> > m_onceOffed;
index 0daf274..6155fd5 100644 (file)
@@ -43,7 +43,6 @@
 QT_BEGIN_NAMESPACE
 
 
-
 /*!
     \qmlclass Emitter QSGParticleEmitter
     \inqmlmodule QtQuick.Particles 2
@@ -180,6 +179,14 @@ QT_BEGIN_NAMESPACE
 
     Default value is 0.
 */
+//TODO: Document particle 'type'
+/*!
+    \qmlsignal QtQuick.Particles2::Emitter::emitting(particle)
+
+    This handler is called when a particle is emitted. You can modify particle
+    attributes from within the handler.
+*/
+
 
 QSGParticleEmitter::QSGParticleEmitter(QSGItem *parent) :
     QSGItem(parent)
@@ -221,6 +228,12 @@ QSGParticleEmitter::~QSGParticleEmitter()
         delete m_defaultExtruder;
 }
 
+bool QSGParticleEmitter::isEmitConnected()
+{
+    static int idx = QObjectPrivate::get(this)->signalIndex("emitParticle(QDeclarativeV8Handle)");
+    return QObjectPrivate::get(this)->isSignalConnected(idx);
+}
+
 void QSGParticleEmitter::componentComplete()
 {
     if (!m_system && qobject_cast<QSGParticleSystem*>(parentItem()))
@@ -416,6 +429,8 @@ void QSGParticleEmitter::emitWindow(int timeStamp)
             datum->size = size;// * float(m_emitting);
             datum->endSize = endSize;// * float(m_emitting);
 
+            if (isEmitConnected())
+                emitParticle(datum->v8Value());//A chance for arbitrary JS changes
             m_system->emitParticle(datum);
         }
         if (m_burstQueue.isEmpty()){
index d3c9327..2c75fbf 100644 (file)
@@ -119,6 +119,7 @@ public:
     void setSpeedFromMovement(qreal s);
     virtual void componentComplete();
 signals:
+    void emitParticle(QDeclarativeV8Handle particle);
     void particlesPerSecondChanged(qreal);
     void particleDurationChanged(int);
     void emittingChanged(bool);
@@ -348,6 +349,7 @@ protected:
        QPointF m_last_last_emitter;
        QPointF m_last_last_last_emitter;
 
+       bool isEmitConnected();
 private:
        QSGStochasticDirection m_nullVector;
 
index f87115c..e6076b9 100644 (file)
@@ -66,8 +66,6 @@
 #include "qsgwander_p.h"
 #include "qsgtargetaffector_p.h"
 #include "qsgcumulativedirection_p.h"
-#include "qsgcustomemitter_p.h"
-#include "qsgcustomaffector_p.h"
 
 QT_BEGIN_NAMESPACE
 
@@ -83,7 +81,6 @@ void QSGParticlesModule::defineModule()
     qmlRegisterType<QSGModelParticle>(uri, 2, 0, "ModelParticle");
 
     qmlRegisterType<QSGParticleEmitter>(uri, 2, 0, "Emitter");
-    qmlRegisterType<QSGCustomEmitter>(uri, 2, 0, "CustomEmitter");
     qmlRegisterType<QSGFollowEmitter>(uri, 2, 0, "FollowEmitter");
 
     qmlRegisterType<QSGEllipseExtruder>(uri, 2, 0, "EllipseShape");
@@ -96,7 +93,6 @@ void QSGParticlesModule::defineModule()
     qmlRegisterType<QSGCumulativeDirection>(uri, 2, 0, "CumulativeDirection");
 
     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");