aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@theqtcompany.com>2014-11-10 11:39:03 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2014-12-22 21:48:11 +0100
commitfa3cf15e0577fe382ac577456422ad78325a3977 (patch)
tree3323ab526433f73fb644b1692c10629f01093d62 /src/qml/qml
parentee771dda2e9e304edea88e6d5f6e6d540a0bab97 (diff)
Initial work on gadget support
Changed built-in QtQml value types to use gadgets. This is in preparation for supporting external gadgets. This replaces the mostly direct inheritance of the concrete value types with gadgets and "dynamic" inheritance through QQmlValueType being generic. Over time as some of the value types may become gadgets, we can remove the ones here. It's important that these "separate" gadgets have the same memory layout as the actual types (QPointF, etc.). Also while QQmlValueType remains practically a singleton, it's not required anymore to be one. Consequently the JS wrappers for value types keep their own instance of QQmlValueType. This allows eliminating the qobject_cast in various places that dealt with the singleton nature. This comes at a cost, making the JS wrappers slightly heavier. However that is meant to be a temporary situation and finally the value type wrapper should merely store the meta-object in addition to the data and the type. Change-Id: I15071ded0a1e54203f29ec1ecf7a9ab646d1168e Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqmlglobal.cpp10
-rw-r--r--src/qml/qml/qqmlglobal_p.h6
-rw-r--r--src/qml/qml/qqmlproperty.cpp20
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp198
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h158
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp35
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h6
-rw-r--r--src/qml/qml/v8/qv8engine.cpp8
8 files changed, 210 insertions, 231 deletions
diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp
index 492836ae03..57c0993d00 100644
--- a/src/qml/qml/qqmlglobal.cpp
+++ b/src/qml/qml/qqmlglobal.cpp
@@ -50,14 +50,12 @@ QQmlValueTypeProvider::~QQmlValueTypeProvider()
QQml_removeValueTypeProvider(this);
}
-QQmlValueType *QQmlValueTypeProvider::createValueType(int type)
+const QMetaObject *QQmlValueTypeProvider::metaObjectForMetaType(int type)
{
- QQmlValueType *value = 0;
-
QQmlValueTypeProvider *p = this;
do {
- if (p->create(type, value))
- return value;
+ if (const QMetaObject *mo = p->getMetaObjectForMetaType(type))
+ return mo;
} while ((p = p->next));
return 0;
@@ -245,7 +243,7 @@ bool QQmlValueTypeProvider::writeValueType(int type, const void *src, void *dst,
return false;
}
-bool QQmlValueTypeProvider::create(int, QQmlValueType *&) { return false; }
+const QMetaObject *QQmlValueTypeProvider::getMetaObjectForMetaType(int) { return 0; }
bool QQmlValueTypeProvider::init(int, void *, size_t) { return false; }
bool QQmlValueTypeProvider::destroy(int, void *, size_t) { return false; }
bool QQmlValueTypeProvider::copy(int, const void *, void *, size_t) { return false; }
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index 1d0bf59670..2832d0338d 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -215,7 +215,6 @@ inline void QQml_setParent_noEvent(QObject *object, QObject *parent)
}
-class QQmlValueType;
class QV8Engine;
class Q_QML_PRIVATE_EXPORT QQmlValueTypeProvider
{
@@ -223,7 +222,7 @@ public:
QQmlValueTypeProvider();
virtual ~QQmlValueTypeProvider();
- QQmlValueType *createValueType(int);
+ const QMetaObject *metaObjectForMetaType(int);
bool initValueType(int, void *, size_t);
bool destroyValueType(int, void *, size_t);
@@ -243,8 +242,7 @@ public:
bool writeValueType(int, const void *, void *, size_t);
private:
- virtual bool create(int, QQmlValueType *&);
-
+ virtual const QMetaObject *getMetaObjectForMetaType(int);
virtual bool init(int, void *, size_t);
virtual bool destroy(int, void *, size_t);
virtual bool copy(int, const void *, void *, size_t);
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 635e4d4a54..0ee8f94a66 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -284,13 +284,13 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name)
if (ii == (path.count() - 2) && QQmlValueTypeFactory::isValueType(property->propType)) {
// We're now at a value type property
- QObject *typeObject = QQmlValueTypeFactory::valueType(property->propType);
- if (!typeObject) return; // Not a value type
+ const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType);
+ if (!valueTypeMetaObject) return; // Not a value type
- int idx = typeObject->metaObject()->indexOfProperty(path.last().toUtf8().constData());
+ int idx = valueTypeMetaObject->indexOfProperty(path.last().toUtf8().constData());
if (idx == -1) return; // Value type property does not exist
- QMetaProperty vtProp = typeObject->metaObject()->property(idx);
+ QMetaProperty vtProp = valueTypeMetaObject->property(idx);
Q_ASSERT(QQmlPropertyData::flagsForProperty(vtProp) <= QQmlPropertyData::ValueTypeFlagMask);
Q_ASSERT(vtProp.userType() <= 0x0000FFFF);
@@ -463,9 +463,9 @@ const char *QQmlProperty::propertyTypeName() const
if (!d)
return 0;
if (d->isValueType()) {
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(d->core.propType);
- Q_ASSERT(valueType);
- return valueType->metaObject()->property(d->core.valueTypeCoreIndex).typeName();
+ const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType);
+ Q_ASSERT(valueTypeMetaObject);
+ return valueTypeMetaObject->property(d->core.valueTypeCoreIndex).typeName();
} else if (d->object && type() & Property && d->core.isValid()) {
return d->object->metaObject()->property(d->core.coreIndex).typeName();
} else {
@@ -642,10 +642,10 @@ QString QQmlProperty::name() const
} else if (d->isValueType()) {
QString rv = d->core.name(d->object) + QLatin1Char('.');
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(d->core.propType);
- Q_ASSERT(valueType);
+ const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType);
+ Q_ASSERT(valueTypeMetaObject);
- const char *vtName = valueType->metaObject()->property(d->core.valueTypeCoreIndex).name();
+ const char *vtName = valueTypeMetaObject->property(d->core.valueTypeCoreIndex).name();
rv += QString::fromUtf8(vtName);
d->nameCache = rv;
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index f73b50ad46..20f3027e4c 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -36,6 +36,7 @@
#include <private/qqmlglobal_p.h>
#include <QtCore/qdebug.h>
+#include <private/qmetaobjectbuilder_p.h>
QT_BEGIN_NAMESPACE
@@ -48,7 +49,7 @@ struct QQmlValueTypeFactoryImpl
bool isValueType(int idx);
- QQmlValueType *createValueType(int);
+ const QMetaObject *metaObjectForMetaType(int);
QQmlValueType *valueType(int);
QQmlValueType *valueTypes[QVariant::UserType];
@@ -83,39 +84,30 @@ bool QQmlValueTypeFactoryImpl::isValueType(int idx)
return false;
}
-QQmlValueType *QQmlValueTypeFactoryImpl::createValueType(int t)
+const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
{
- QQmlValueType *rv = 0;
-
switch (t) {
case QVariant::Point:
- rv = new QQmlPointValueType;
- break;
+ return &QQmlPointValueType::staticMetaObject;
case QVariant::PointF:
- rv = new QQmlPointFValueType;
- break;
+ return &QQmlPointFValueType::staticMetaObject;
case QVariant::Size:
- rv = new QQmlSizeValueType;
- break;
+ return &QQmlSizeValueType::staticMetaObject;
case QVariant::SizeF:
- rv = new QQmlSizeFValueType;
- break;
+ return &QQmlSizeFValueType::staticMetaObject;
case QVariant::Rect:
- rv = new QQmlRectValueType;
- break;
+ return &QQmlRectValueType::staticMetaObject;
case QVariant::RectF:
- rv = new QQmlRectFValueType;
- break;
+ return &QQmlRectFValueType::staticMetaObject;
case QVariant::EasingCurve:
- rv = new QQmlEasingValueType;
- break;
+ return &QQmlEasingValueType::staticMetaObject;
default:
- rv = QQml_valueTypeProvider()->createValueType(t);
+ if (const QMetaObject *mo = QQml_valueTypeProvider()->metaObjectForMetaType(t))
+ return mo;
break;
}
- Q_ASSERT(!rv || rv->metaObject()->propertyCount() < 32);
- return rv;
+ return 0;
}
QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx)
@@ -126,7 +118,10 @@ QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx)
QHash<int, QQmlValueType *>::iterator it = userTypes.find(idx);
if (it == userTypes.end()) {
- it = userTypes.insert(idx, createValueType(idx));
+ QQmlValueType *vt = 0;
+ if (const QMetaObject *mo = metaObjectForMetaType(idx))
+ vt = new QQmlValueType(idx, mo);
+ it = userTypes.insert(idx, vt);
}
mutex.unlock();
@@ -139,7 +134,8 @@ QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx)
// TODO: Investigate the performance/memory characteristics of
// removing the preallocated array
- if ((rv = createValueType(idx))) {
+ if (const QMetaObject *mo = metaObjectForMetaType(idx)) {
+ rv = new QQmlValueType(idx, mo);
valueTypes[idx] = rv;
}
}
@@ -161,20 +157,116 @@ QQmlValueType *QQmlValueTypeFactory::valueType(int idx)
return factoryImpl()->valueType(idx);
}
+const QMetaObject *QQmlValueTypeFactory::metaObjectForMetaType(int type)
+{
+ return factoryImpl()->metaObjectForMetaType(type);
+}
+
void QQmlValueTypeFactory::registerValueTypes(const char *uri, int versionMajor, int versionMinor)
{
qmlRegisterValueTypeEnums<QQmlEasingValueType>(uri, versionMajor, versionMinor, "Easing");
}
+QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject)
+ : typeId(typeId)
+ , gadgetPtr(QMetaType::create(typeId))
+{
+ QObjectPrivate *op = QObjectPrivate::get(this);
+ Q_ASSERT(!op->metaObject);
+ op->metaObject = this;
+
+ QMetaObjectBuilder builder(gadgetMetaObject);
+ _metaObject = builder.toMetaObject();
+
+ *static_cast<QMetaObject*>(this) = *_metaObject;
+}
+
+QQmlValueType::~QQmlValueType()
+{
+ QObjectPrivate *op = QObjectPrivate::get(this);
+ Q_ASSERT(op->metaObject == this);
+ op->metaObject = 0;
+ ::free((void*)_metaObject);
+ QMetaType::destroy(typeId, gadgetPtr);
+}
+
+void QQmlValueType::read(QObject *obj, int idx)
+{
+ readProperty(obj, idx, gadgetPtr);
+}
+
+void QQmlValueType::readVariantValue(QObject *obj, int idx, QVariant *into)
+{
+ // important: must not change the userType of the variant
+ readProperty(obj, idx, into);
+}
+
+void QQmlValueType::write(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags)
+{
+ Q_ASSERT(gadgetPtr);
+ writeProperty(obj, idx, flags, gadgetPtr);
+}
+
+void QQmlValueType::writeVariantValue(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags, QVariant *from)
+{
+ writeProperty(obj, idx, flags, from);
+}
+
+QVariant QQmlValueType::value()
+{
+ Q_ASSERT(gadgetPtr);
+ return QVariant(typeId, gadgetPtr);
+}
+
+void QQmlValueType::setValue(const QVariant &value)
+{
+ Q_ASSERT(typeId == value.userType());
+ QMetaType::destruct(typeId, gadgetPtr);
+ QMetaType::construct(typeId, gadgetPtr, value.constData());
+}
+
+bool QQmlValueType::isEqual(const QVariant &other) const
+{
+ Q_ASSERT(gadgetPtr);
+ return QVariant(typeId, gadgetPtr) == other;
+}
+
+QString QQmlValueType::toString() const
+{
+ const QMetaObject *mo = metaObject();
+ const int toStringIndex = mo->indexOfMethod("toString()");
+ if (toStringIndex != -1) {
+ QString result;
+ void *args[] = { &result, 0 };
+ _metaObject->d.static_metacall(reinterpret_cast<QObject*>(gadgetPtr), QMetaObject::InvokeMetaMethod, toStringIndex, args);
+ return result;
+ }
+ QString result = QString::fromUtf8(QMetaType::typeName(typeId));
+ result += QLatin1Char('(');
+ const int propCount = mo->propertyCount();
+ for (int i = 0; i < propCount; ++i) {
+ QVariant value = mo->property(i).read(this);
+ result += value.toString();
+ if (i < propCount - 1)
+ result += QStringLiteral(", ");
+ }
+ result += QLatin1Char(')');
+ return result;
+}
+
+QAbstractDynamicMetaObject *QQmlValueType::toDynamicMetaObject(QObject *)
+{
+ return this;
+}
-QQmlValueType::QQmlValueType(int userType, QObject *parent)
-: QObject(parent), m_userType(userType)
+void QQmlValueType::objectDestroyed(QObject *)
{
}
-QQmlPointFValueType::QQmlPointFValueType(QObject *parent)
- : QQmlValueTypeBase<QPointF>(QMetaType::QPointF, parent)
+int QQmlValueType::metaCall(QObject *, QMetaObject::Call type, int _id, void **argv)
{
+ d.static_metacall(reinterpret_cast<QObject*>(gadgetPtr), type, _id, argv);
+ return _id;
}
QString QQmlPointFValueType::toString() const
@@ -203,16 +295,6 @@ void QQmlPointFValueType::setY(qreal y)
}
-QQmlPointValueType::QQmlPointValueType(QObject *parent)
- : QQmlValueTypeBase<QPoint>(QMetaType::QPoint, parent)
-{
-}
-
-QString QQmlPointValueType::toString() const
-{
- return QString(QLatin1String("QPoint(%1, %2)")).arg(v.x()).arg(v.y());
-}
-
int QQmlPointValueType::x() const
{
return v.x();
@@ -234,11 +316,6 @@ void QQmlPointValueType::setY(int y)
}
-QQmlSizeFValueType::QQmlSizeFValueType(QObject *parent)
- : QQmlValueTypeBase<QSizeF>(QMetaType::QSizeF, parent)
-{
-}
-
QString QQmlSizeFValueType::toString() const
{
return QString(QLatin1String("QSizeF(%1, %2)")).arg(v.width()).arg(v.height());
@@ -265,16 +342,6 @@ void QQmlSizeFValueType::setHeight(qreal h)
}
-QQmlSizeValueType::QQmlSizeValueType(QObject *parent)
- : QQmlValueTypeBase<QSize>(QMetaType::QSize, parent)
-{
-}
-
-QString QQmlSizeValueType::toString() const
-{
- return QString(QLatin1String("QSize(%1, %2)")).arg(v.width()).arg(v.height());
-}
-
int QQmlSizeValueType::width() const
{
return v.width();
@@ -295,12 +362,6 @@ void QQmlSizeValueType::setHeight(int h)
v.setHeight(h);
}
-
-QQmlRectFValueType::QQmlRectFValueType(QObject *parent)
- : QQmlValueTypeBase<QRectF>(QMetaType::QRectF, parent)
-{
-}
-
QString QQmlRectFValueType::toString() const
{
return QString(QLatin1String("QRectF(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.width()).arg(v.height());
@@ -346,17 +407,6 @@ void QQmlRectFValueType::setHeight(qreal h)
v.setHeight(h);
}
-
-QQmlRectValueType::QQmlRectValueType(QObject *parent)
- : QQmlValueTypeBase<QRect>(QMetaType::QRect, parent)
-{
-}
-
-QString QQmlRectValueType::toString() const
-{
- return QString(QLatin1String("QRect(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.width()).arg(v.height());
-}
-
int QQmlRectValueType::x() const
{
return v.x();
@@ -398,16 +448,6 @@ void QQmlRectValueType::setHeight(int h)
}
-QQmlEasingValueType::QQmlEasingValueType(QObject *parent)
- : QQmlValueTypeBase<QEasingCurve>(QMetaType::QEasingCurve, parent)
-{
-}
-
-QString QQmlEasingValueType::toString() const
-{
- return QString(QLatin1String("QEasingCurve(%1, %2, %3, %4)")).arg(v.type()).arg(v.amplitude()).arg(v.overshoot()).arg(v.period());
-}
-
QQmlEasingValueType::Type QQmlEasingValueType::type() const
{
return (QQmlEasingValueType::Type)v.type();
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index 5a6bcdd003..2f6a192f77 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -57,34 +57,37 @@
QT_BEGIN_NAMESPACE
-class Q_QML_PRIVATE_EXPORT QQmlValueType : public QObject
+class Q_QML_PRIVATE_EXPORT QQmlValueType : public QObject, public QAbstractDynamicMetaObject
{
- Q_OBJECT
public:
- QQmlValueType(int userType, QObject *parent = 0);
- virtual void read(QObject *, int) = 0;
- virtual void readVariantValue(QObject *, int, QVariant *) = 0;
- virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags flags) = 0;
- virtual void writeVariantValue(QObject *, int, QQmlPropertyPrivate::WriteFlags, QVariant *) = 0;
- virtual QVariant value() = 0;
- virtual void setValue(const QVariant &) = 0;
-
- virtual QString toString() const = 0;
- virtual bool isEqual(const QVariant &value) const = 0;
-
- virtual void onLoad() {}
+ QQmlValueType(int userType, const QMetaObject *metaObject);
+ ~QQmlValueType();
+ void read(QObject *, int);
+ void readVariantValue(QObject *, int, QVariant *);
+ void write(QObject *, int, QQmlPropertyPrivate::WriteFlags flags);
+ void writeVariantValue(QObject *, int, QQmlPropertyPrivate::WriteFlags, QVariant *);
+ QVariant value();
+ void setValue(const QVariant &);
+
+ QString toString() const;
+ bool isEqual(const QVariant &value) const;
inline int userType() const
{
- return m_userType;
+ return typeId;
+
}
+ // ---- dynamic meta object data interface
+ virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *);
+ virtual void objectDestroyed(QObject *);
+ virtual int metaCall(QObject *obj, QMetaObject::Call type, int _id, void **argv);
+ // ----
protected:
inline void readProperty(QObject *obj, int idx, void *p)
{
void *a[] = { p, 0 };
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
- onLoad();
}
inline void writeProperty(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags, void *p)
@@ -95,59 +98,9 @@ protected:
}
private:
- int m_userType;
-};
-
-template <typename T>
-class QQmlValueTypeBase : public QQmlValueType
-{
-public:
- typedef T ValueType;
-
- QQmlValueTypeBase(int userType, QObject *parent)
- : QQmlValueType(userType, parent)
- {
- }
-
- virtual void read(QObject *obj, int idx)
- {
- readProperty(obj, idx, &v);
- }
-
- virtual void readVariantValue(QObject *obj, int idx, QVariant *into)
- {
- // important: must not change the userType of the variant
- readProperty(obj, idx, into);
- }
-
- virtual void write(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags)
- {
- writeProperty(obj, idx, flags, &v);
- }
-
- virtual void writeVariantValue(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags, QVariant *from)
- {
- writeProperty(obj, idx, flags, from);
- }
-
- virtual QVariant value()
- {
- return QVariant::fromValue(v);
- }
-
- virtual void setValue(const QVariant &value)
- {
- v = qvariant_cast<T>(value);
- onLoad();
- }
-
- virtual bool isEqual(const QVariant &other) const
- {
- return QVariant::fromValue(v) == other;
- }
-
-protected:
- ValueType v;
+ const QMetaObject *_metaObject;
+ int typeId;
+ void *gadgetPtr;
};
class Q_QML_PRIVATE_EXPORT QQmlValueTypeFactory
@@ -155,86 +108,75 @@ class Q_QML_PRIVATE_EXPORT QQmlValueTypeFactory
public:
static bool isValueType(int);
static QQmlValueType *valueType(int idx);
+ static const QMetaObject *metaObjectForMetaType(int type);
static void registerValueTypes(const char *uri, int versionMajor, int versionMinor);
};
-class Q_QML_PRIVATE_EXPORT QQmlPointFValueType : public QQmlValueTypeBase<QPointF>
+struct QQmlPointFValueType
{
+ QPointF v;
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQmlPointFValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
+ Q_INVOKABLE QString toString() const;
qreal x() const;
qreal y() const;
void setX(qreal);
void setY(qreal);
};
-class Q_QML_PRIVATE_EXPORT QQmlPointValueType : public QQmlValueTypeBase<QPoint>
+struct QQmlPointValueType
{
+ QPoint v;
Q_PROPERTY(int x READ x WRITE setX FINAL)
Q_PROPERTY(int y READ y WRITE setY FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQmlPointValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
int x() const;
int y() const;
void setX(int);
void setY(int);
};
-class Q_QML_PRIVATE_EXPORT QQmlSizeFValueType : public QQmlValueTypeBase<QSizeF>
+struct QQmlSizeFValueType
{
+ QSizeF v;
Q_PROPERTY(qreal width READ width WRITE setWidth FINAL)
Q_PROPERTY(qreal height READ height WRITE setHeight FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQmlSizeFValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
+ Q_INVOKABLE QString toString() const;
qreal width() const;
qreal height() const;
void setWidth(qreal);
void setHeight(qreal);
};
-class Q_QML_PRIVATE_EXPORT QQmlSizeValueType : public QQmlValueTypeBase<QSize>
+struct QQmlSizeValueType
{
+ QSize v;
Q_PROPERTY(int width READ width WRITE setWidth FINAL)
Q_PROPERTY(int height READ height WRITE setHeight FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQmlSizeValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
int width() const;
int height() const;
void setWidth(int);
void setHeight(int);
};
-class Q_QML_PRIVATE_EXPORT QQmlRectFValueType : public QQmlValueTypeBase<QRectF>
+struct QQmlRectFValueType
{
+ QRectF v;
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
Q_PROPERTY(qreal width READ width WRITE setWidth FINAL)
Q_PROPERTY(qreal height READ height WRITE setHeight FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQmlRectFValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
+ Q_INVOKABLE QString toString() const;
qreal x() const;
qreal y() const;
void setX(qreal);
@@ -246,18 +188,15 @@ public:
void setHeight(qreal);
};
-class Q_QML_PRIVATE_EXPORT QQmlRectValueType : public QQmlValueTypeBase<QRect>
+struct QQmlRectValueType
{
+ QRect v;
Q_PROPERTY(int x READ x WRITE setX FINAL)
Q_PROPERTY(int y READ y WRITE setY FINAL)
Q_PROPERTY(int width READ width WRITE setWidth FINAL)
Q_PROPERTY(int height READ height WRITE setHeight FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQmlRectValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
int x() const;
int y() const;
void setX(int);
@@ -269,9 +208,10 @@ public:
void setHeight(int);
};
-class Q_QML_PRIVATE_EXPORT QQmlEasingValueType : public QQmlValueTypeBase<QEasingCurve>
+struct QQmlEasingValueType
{
- Q_OBJECT
+ QEasingCurve v;
+ Q_GADGET
Q_ENUMS(Type)
Q_PROPERTY(QQmlEasingValueType::Type type READ type WRITE setType FINAL)
@@ -307,10 +247,6 @@ public:
Bezier = QEasingCurve::BezierSpline
};
- QQmlEasingValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
Type type() const;
qreal amplitude() const;
qreal overshoot() const;
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index ede55d033f..d2fccb5273 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -120,7 +120,10 @@ static bool readReferenceValue(const QmlValueTypeReference *reference)
// We need to modify this reference to the updated value type, if
// possible, or return false if it is not a value type.
if (QQmlValueTypeFactory::isValueType(variantReferenceType)) {
- reference->d()->type = QQmlValueTypeFactory::valueType(variantReferenceType);
+ QQmlValueType *vt = 0;
+ if (const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(variantReferenceType))
+ vt = new QQmlValueType(variantReferenceType, mo);
+ reference->d()->type.reset(vt);
if (!reference->d()->type) {
return false;
}
@@ -147,7 +150,7 @@ void QmlValueTypeWrapper::initProto(ExecutionEngine *v4)
v4->qmlExtensions()->valueTypeWrapperPrototype = o->d();
}
-ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, QQmlValueType *type)
+ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, const QMetaObject *metaObject, int typeId)
{
ExecutionEngine *v4 = QV8Engine::getV4(v8);
Scope scope(v4);
@@ -156,11 +159,11 @@ ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int pr
Scoped<QmlValueTypeReference> r(scope, v4->memoryManager->alloc<QmlValueTypeReference>(v8));
ScopedObject proto(scope, v4->qmlExtensions()->valueTypeWrapperPrototype);
r->setPrototype(proto);
- r->d()->type = type; r->d()->object = object; r->d()->property = property;
+ r->d()->type.reset(new QQmlValueType(typeId, metaObject)); r->d()->object = object; r->d()->property = property;
return r->asReturnedValue();
}
-ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValueType *type)
+ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, const QMetaObject *metaObject, int typeId)
{
ExecutionEngine *v4 = QV8Engine::getV4(v8);
Scope scope(v4);
@@ -169,7 +172,7 @@ ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value,
Scoped<QmlValueTypeCopy> r(scope, v4->memoryManager->alloc<QmlValueTypeCopy>(v8));
ScopedObject proto(scope, v4->qmlExtensions()->valueTypeWrapperPrototype);
r->setPrototype(proto);
- r->d()->type = type; r->d()->value = value;
+ r->d()->type.reset(new QQmlValueType(typeId, metaObject)); r->d()->value = value;
return r->asReturnedValue();
}
@@ -220,11 +223,11 @@ PropertyAttributes QmlValueTypeWrapper::query(const Managed *m, String *name)
QQmlPropertyData local;
QQmlPropertyData *result = 0;
{
- QQmlData *ddata = QQmlData::get(r->d()->type, false);
+ QQmlData *ddata = QQmlData::get(r->d()->type.data(), false);
if (ddata && ddata->propertyCache)
result = ddata->propertyCache->property(name, 0, 0);
else
- result = QQmlPropertyCache::property(r->d()->v8->engine(), r->d()->type, name, 0, local);
+ result = QQmlPropertyCache::property(r->d()->v8->engine(), r->d()->type.data(), name, 0, local);
}
return result ? Attr_Data : Attr_Invalid;
}
@@ -278,6 +281,10 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper
QmlValueTypeWrapper *r = static_cast<QmlValueTypeWrapper *>(m);
QV4::ExecutionEngine *v4 = m->engine();
+ // ### Remove this once we can do proper this calls.
+ if (name == v4->id_toString)
+ return Object::get(m, name, hasProperty);
+
// Note: readReferenceValue() can change the reference->type.
if (r->d()->objectType == Heap::QmlValueTypeWrapper::Reference) {
QmlValueTypeReference *reference = static_cast<QmlValueTypeReference *>(r);
@@ -296,11 +303,11 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper
QQmlPropertyData local;
QQmlPropertyData *result = 0;
{
- QQmlData *ddata = QQmlData::get(r->d()->type, false);
+ QQmlData *ddata = QQmlData::get(r->d()->type.data(), false);
if (ddata && ddata->propertyCache)
result = ddata->propertyCache->property(name, 0, 0);
else
- result = QQmlPropertyCache::property(r->d()->v8->engine(), r->d()->type, name, 0, local);
+ result = QQmlPropertyCache::property(r->d()->v8->engine(), r->d()->type.data(), name, 0, local);
}
if (!result)
@@ -313,14 +320,14 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper
// calling a Q_INVOKABLE function of a value type
Scope scope(v4);
ScopedContext c(scope, v4->rootContext());
- return QV4::QObjectMethod::create(c, r->d()->type, result->coreIndex);
+ return QV4::QObjectMethod::create(c, r->d()->type.data(), result->coreIndex);
}
#define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \
if (result->propType == metatype) { \
cpptype v; \
void *args[] = { &v, 0 }; \
- r->d()->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); \
+ QMetaObject::metacall(r->d()->type.data(), QMetaObject::ReadProperty, result->coreIndex, args); \
return constructor(v); \
}
@@ -332,7 +339,7 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper
QVariant v(result->propType, (void *)0);
void *args[] = { v.data(), 0 };
- r->d()->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args);
+ QMetaObject::metacall(r->d()->type.data(), QMetaObject::ReadProperty, result->coreIndex, args);
return r->d()->v8->fromVariant(v);
#undef VALUE_TYPE_ACCESSOR
}
@@ -402,7 +409,7 @@ void QmlValueTypeWrapper::put(Managed *m, String *name, const ValueRef value)
if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
v = v.toInt();
- p.write(reference->d()->type, v);
+ p.write(reference->d()->type.data(), v);
if (writebackProperty.userType() == QMetaType::QVariant) {
QVariant variantReferenceValue = r->d()->type->value();
@@ -425,7 +432,7 @@ void QmlValueTypeWrapper::put(Managed *m, String *name, const ValueRef value)
r->d()->type->setValue(copy->d()->value);
QMetaProperty p = r->d()->type->metaObject()->property(index);
- p.write(r->d()->type, v);
+ p.write(r->d()->type.data(), v);
copy->d()->value = r->d()->type->value();
}
}
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index d15a4b0cef..4946c13e42 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -65,7 +65,7 @@ struct QmlValueTypeWrapper : Object {
QmlValueTypeWrapper(QV8Engine *engine, ObjectType type);
QV8Engine *v8;
ObjectType objectType;
- mutable QQmlValueType *type;
+ mutable QScopedPointer<QQmlValueType> type;
};
}
@@ -77,8 +77,8 @@ struct Q_QML_EXPORT QmlValueTypeWrapper : Object
public:
- static ReturnedValue create(QV8Engine *v8, QObject *, int, QQmlValueType *);
- static ReturnedValue create(QV8Engine *v8, const QVariant &, QQmlValueType *);
+ static ReturnedValue create(QV8Engine *v8, QObject *, int, const QMetaObject *metaObject, int typeId);
+ static ReturnedValue create(QV8Engine *v8, const QVariant &, const QMetaObject *metaObject, int typeId);
QVariant toVariant() const;
bool isEqual(const QVariant& value);
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 5e9e20b416..ee124aeed0 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -413,8 +413,8 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant)
break;
}
- if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type))
- return QV4::QmlValueTypeWrapper::create(this, variant, vt);
+ if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(type))
+ return QV4::QmlValueTypeWrapper::create(this, variant, vtmo, type);
} else {
QV4::Scope scope(m_v4Engine);
if (type == qMetaTypeId<QQmlListReference>()) {
@@ -454,8 +454,8 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant)
if (succeeded)
return retn.asReturnedValue();
- if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type))
- return QV4::QmlValueTypeWrapper::create(this, variant, vt);
+ if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(type))
+ return QV4::QmlValueTypeWrapper::create(this, variant, vtmo, type);
}
// XXX TODO: To be compatible, we still need to handle: