aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp4
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp18
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp35
-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
-rw-r--r--src/quick/util/qquickglobal.cpp25
-rw-r--r--src/quick/util/qquickvaluetypes.cpp93
-rw-r--r--src/quick/util/qquickvaluetypes_p.h70
-rw-r--r--tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp23
-rw-r--r--tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp21
16 files changed, 274 insertions, 456 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 339278fbe8..07ea2a6fff 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1941,8 +1941,8 @@ static QV4::IR::Type resolveMetaObjectProperty(QQmlEnginePrivate *qmlEngine, QV4
initMetaObjectResolver(resolver, cache);
return QV4::IR::QObjectType;
}
- } else if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(property->propType)) {
- if (QQmlPropertyCache *cache = qmlEngine->cache(valueType->metaObject())) {
+ } else if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType)) {
+ if (QQmlPropertyCache *cache = qmlEngine->cache(valueTypeMetaObject)) {
initMetaObjectResolver(resolver, cache);
resolver->flags |= ResolveTypeInformationOnly;
return QV4::IR::QObjectType;
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index ada848f31d..7f399f0879 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -463,8 +463,8 @@ bool QQmlPropertyCacheCreator::buildMetaObjectRecursively(int objectIndex, int r
if (instantiatingProperty->isQObject()) {
baseTypeCache = enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType);
Q_ASSERT(baseTypeCache);
- } else if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(instantiatingProperty->propType)) {
- baseTypeCache = enginePrivate->cache(vt->metaObject());
+ } else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(instantiatingProperty->propType)) {
+ baseTypeCache = enginePrivate->cache(vtmo);
Q_ASSERT(baseTypeCache);
}
}
@@ -1630,8 +1630,8 @@ bool QQmlComponentAndAliasResolver::resolveAliases()
notifySignal = targetProperty->notifyIndex;
if (!subProperty.isEmpty()) {
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type);
- if (!valueType) {
+ const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(type);
+ if (!valueTypeMetaObject) {
recordError(p->aliasLocation, tr("Invalid alias location"));
return false;
}
@@ -1639,7 +1639,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases()
propType = type;
int valueTypeIndex =
- valueType->metaObject()->indexOfProperty(subProperty.toString().toUtf8().constData());
+ valueTypeMetaObject->indexOfProperty(subProperty.toString().toUtf8().constData());
if (valueTypeIndex == -1) {
recordError(p->aliasLocation, tr("Invalid alias location"));
return false;
@@ -1647,10 +1647,10 @@ bool QQmlComponentAndAliasResolver::resolveAliases()
Q_ASSERT(valueTypeIndex <= 0x0000FFFF);
propIdx = QQmlPropertyData::encodeValueTypePropertyIndex(propIdx, valueTypeIndex);
- if (valueType->metaObject()->property(valueTypeIndex).isEnumType())
+ if (valueTypeMetaObject->property(valueTypeIndex).isEnumType())
type = QVariant::Int;
else
- type = valueType->metaObject()->property(valueTypeIndex).userType();
+ type = valueTypeMetaObject->property(valueTypeIndex).userType();
} else {
if (targetProperty->isEnum()) {
@@ -1887,7 +1887,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
if (binding->type >= QV4::CompiledData::Binding::Type_Object && !customParser) {
qSwap(_seenObjectWithId, seenSubObjectWithId);
- const bool subObjectValid = validateObject(binding->value.objectIndex, binding, pd && QQmlValueTypeFactory::valueType(pd->propType));
+ const bool subObjectValid = validateObject(binding->value.objectIndex, binding, pd && QQmlValueTypeFactory::metaObjectForMetaType(pd->propType));
qSwap(_seenObjectWithId, seenSubObjectWithId);
if (!subObjectValid)
return false;
@@ -1961,7 +1961,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
return false;
} else if (binding->isGroupProperty()) {
if (QQmlValueTypeFactory::isValueType(pd->propType)) {
- if (QQmlValueTypeFactory::valueType(pd->propType)) {
+ if (QQmlValueTypeFactory::metaObjectForMetaType(pd->propType)) {
if (!pd->isWritable()) {
recordError(binding->location, tr("Invalid property assignment: \"%1\" is a read-only property").arg(name));
return false;
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index daaa0c16f1..c2b3b44bba 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -201,16 +201,16 @@ static QV4::ReturnedValue LoadProperty(QV8Engine *engine, QObject *object,
ReadFunction(object, property, &v, notifier);
if (QQmlValueTypeFactory::isValueType(v.userType())) {
- if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(v.userType()))
- return QV4::QmlValueTypeWrapper::create(engine, object, property.coreIndex, valueType); // VariantReference value-type.
+ if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(v.userType()))
+ return QV4::QmlValueTypeWrapper::create(engine, object, property.coreIndex, valueTypeMetaObject, v.userType()); // VariantReference value-type.
}
return engine->fromVariant(v);
} else if (QQmlValueTypeFactory::isValueType(property.propType)) {
Q_ASSERT(notifier == 0);
- if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(property.propType))
- return QV4::QmlValueTypeWrapper::create(engine, object, property.coreIndex, valueType);
+ if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property.propType))
+ return QV4::QmlValueTypeWrapper::create(engine, object, property.coreIndex, valueTypeMetaObject, property.propType);
} else {
Q_ASSERT(notifier == 0);
@@ -1134,17 +1134,6 @@ static QV4::ReturnedValue CallMethod(QObject *object, int index, int returnType,
int *argTypes, QV8Engine *engine, QV4::CallData *callArgs)
{
if (argCount > 0) {
-
- // Special handling is required for value types.
- // We need to save the current value in a temporary,
- // and reapply it after converting all arguments.
- // This avoids the "overwriting copy-value-type-value"
- // problem during Q_INVOKABLE function invocation.
- QQmlValueType *valueTypeObject = qobject_cast<QQmlValueType*>(object);
- QVariant valueTypeValue;
- if (valueTypeObject)
- valueTypeValue = valueTypeObject->value();
-
// Convert all arguments.
QVarLengthArray<CallArgument, 9> args(argCount + 1);
args[0].initAsType(returnType);
@@ -1154,10 +1143,6 @@ static QV4::ReturnedValue CallMethod(QObject *object, int index, int returnType,
for (int ii = 0; ii < args.count(); ++ii)
argData[ii] = args[ii].dataPtr();
- // Reinstate saved value type object value if required.
- if (valueTypeObject)
- valueTypeObject->setValue(valueTypeValue);
-
QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, argData.data());
return args[0].toValue(engine);
@@ -1443,16 +1428,6 @@ static QV4::ReturnedValue CallOverloaded(QObject *object, const QQmlPropertyData
int bestParameterScore = INT_MAX;
int bestMatchScore = INT_MAX;
- // Special handling is required for value types.
- // We need to save the current value in a temporary,
- // and reapply it after converting all arguments.
- // This avoids the "overwriting copy-value-type-value"
- // problem during Q_INVOKABLE function invocation.
- QQmlValueType *valueTypeObject = qobject_cast<QQmlValueType*>(object);
- QVariant valueTypeValue;
- if (valueTypeObject)
- valueTypeValue = valueTypeObject->value();
-
QQmlPropertyData dummy;
const QQmlPropertyData *attempt = &data;
@@ -1496,8 +1471,6 @@ static QV4::ReturnedValue CallOverloaded(QObject *object, const QQmlPropertyData
} while((attempt = RelatedMethod(object, attempt, dummy)) != 0);
if (best.isValid()) {
- if (valueTypeObject)
- valueTypeObject->setValue(valueTypeValue);
return CallPrecise(object, best, engine, callArgs);
} else {
QString error = QLatin1String("Unable to determine callable overload. Candidates are:");
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:
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index b507b47e6b..e3250a6309 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -364,35 +364,28 @@ public:
return QMatrix4x4(matVals);
}
- template<typename T>
- bool typedCreate(QQmlValueType *&v)
- {
- v = new T;
- return true;
- }
-
- bool create(int type, QQmlValueType *&v)
+ const QMetaObject *getMetaObjectForMetaType(int type)
{
switch (type) {
case QMetaType::QColor:
- return typedCreate<QQuickColorValueType>(v);
+ return &QQuickColorValueType::staticMetaObject;
case QMetaType::QFont:
- return typedCreate<QQuickFontValueType>(v);
+ return &QQuickFontValueType::staticMetaObject;
case QMetaType::QVector2D:
- return typedCreate<QQuickVector2DValueType>(v);
+ return &QQuickVector2DValueType::staticMetaObject;
case QMetaType::QVector3D:
- return typedCreate<QQuickVector3DValueType>(v);
+ return &QQuickVector3DValueType::staticMetaObject;
case QMetaType::QVector4D:
- return typedCreate<QQuickVector4DValueType>(v);
+ return &QQuickVector4DValueType::staticMetaObject;
case QMetaType::QQuaternion:
- return typedCreate<QQuickQuaternionValueType>(v);
+ return &QQuickQuaternionValueType::staticMetaObject;
case QMetaType::QMatrix4x4:
- return typedCreate<QQuickMatrix4x4ValueType>(v);
+ return &QQuickMatrix4x4ValueType::staticMetaObject;
default:
break;
}
- return false;
+ return 0;
}
template<typename T>
diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp
index 37a5ba307f..2e4fec0599 100644
--- a/src/quick/util/qquickvaluetypes.cpp
+++ b/src/quick/util/qquickvaluetypes.cpp
@@ -48,11 +48,6 @@ namespace QQuickValueTypes {
}
}
-QQuickColorValueType::QQuickColorValueType(QObject *parent)
- : QQmlValueTypeBase<QColor>(QMetaType::QColor, parent)
-{
-}
-
QString QQuickColorValueType::toString() const
{
// to maintain behaviour with QtQuick 1.0, we just output normal toString() value.
@@ -99,26 +94,11 @@ void QQuickColorValueType::setA(qreal a)
v.setAlphaF(a);
}
-
-QQuickVector2DValueType::QQuickVector2DValueType(QObject *parent)
- : QQmlValueTypeBase<QVector2D>(QMetaType::QVector2D, parent)
-{
-}
-
QString QQuickVector2DValueType::toString() const
{
return QString(QLatin1String("QVector2D(%1, %2)")).arg(v.x()).arg(v.y());
}
-bool QQuickVector2DValueType::isEqual(const QVariant &other) const
-{
- if (other.userType() != QMetaType::QVector2D)
- return false;
-
- QVector2D otherVector = other.value<QVector2D>();
- return (v == otherVector);
-}
-
qreal QQuickVector2DValueType::x() const
{
return v.x();
@@ -199,26 +179,11 @@ bool QQuickVector2DValueType::fuzzyEquals(const QVector2D &vec) const
return qFuzzyCompare(v, vec);
}
-
-QQuickVector3DValueType::QQuickVector3DValueType(QObject *parent)
- : QQmlValueTypeBase<QVector3D>(QMetaType::QVector3D, parent)
-{
-}
-
QString QQuickVector3DValueType::toString() const
{
return QString(QLatin1String("QVector3D(%1, %2, %3)")).arg(v.x()).arg(v.y()).arg(v.z());
}
-bool QQuickVector3DValueType::isEqual(const QVariant &other) const
-{
- if (other.userType() != QMetaType::QVector3D)
- return false;
-
- QVector3D otherVector = other.value<QVector3D>();
- return (v == otherVector);
-}
-
qreal QQuickVector3DValueType::x() const
{
return v.x();
@@ -321,26 +286,11 @@ bool QQuickVector3DValueType::fuzzyEquals(const QVector3D &vec) const
return qFuzzyCompare(v, vec);
}
-
-QQuickVector4DValueType::QQuickVector4DValueType(QObject *parent)
- : QQmlValueTypeBase<QVector4D>(QMetaType::QVector4D, parent)
-{
-}
-
QString QQuickVector4DValueType::toString() const
{
return QString(QLatin1String("QVector4D(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.z()).arg(v.w());
}
-bool QQuickVector4DValueType::isEqual(const QVariant &other) const
-{
- if (other.userType() != QMetaType::QVector4D)
- return false;
-
- QVector4D otherVector = other.value<QVector4D>();
- return (v == otherVector);
-}
-
qreal QQuickVector4DValueType::x() const
{
return v.x();
@@ -450,11 +400,6 @@ bool QQuickVector4DValueType::fuzzyEquals(const QVector4D &vec) const
return qFuzzyCompare(v, vec);
}
-QQuickQuaternionValueType::QQuickQuaternionValueType(QObject *parent)
- : QQmlValueTypeBase<QQuaternion>(QMetaType::QQuaternion, parent)
-{
-}
-
QString QQuickQuaternionValueType::toString() const
{
return QString(QLatin1String("QQuaternion(%1, %2, %3, %4)")).arg(v.scalar()).arg(v.x()).arg(v.y()).arg(v.z());
@@ -500,12 +445,6 @@ void QQuickQuaternionValueType::setZ(qreal z)
v.setZ(z);
}
-
-QQuickMatrix4x4ValueType::QQuickMatrix4x4ValueType(QObject *parent)
- : QQmlValueTypeBase<QMatrix4x4>(QMetaType::QMatrix4x4, parent)
-{
-}
-
QMatrix4x4 QQuickMatrix4x4ValueType::times(const QMatrix4x4 &m) const
{
return v * m;
@@ -579,30 +518,6 @@ bool QQuickMatrix4x4ValueType::fuzzyEquals(const QMatrix4x4 &m) const
return qFuzzyCompare(v, m);
}
-QString QQuickMatrix4x4ValueType::toString() const
-{
- return QString(QLatin1String("QMatrix4x4(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14, %15, %16)"))
- .arg(v(0, 0)).arg(v(0, 1)).arg(v(0, 2)).arg(v(0, 3))
- .arg(v(1, 0)).arg(v(1, 1)).arg(v(1, 2)).arg(v(1, 3))
- .arg(v(2, 0)).arg(v(2, 1)).arg(v(2, 2)).arg(v(2, 3))
- .arg(v(3, 0)).arg(v(3, 1)).arg(v(3, 2)).arg(v(3, 3));
-}
-
-bool QQuickMatrix4x4ValueType::isEqual(const QVariant &other) const
-{
- if (other.userType() != qMetaTypeId<QMatrix4x4>())
- return false;
-
- QMatrix4x4 otherMatrix = other.value<QMatrix4x4>();
- return (v == otherMatrix);
-
-}
-
-QQuickFontValueType::QQuickFontValueType(QObject *parent)
- : QQmlValueTypeBase<QFont>(QMetaType::QFont, parent)
-{
-}
-
QString QQuickFontValueType::toString() const
{
return QString(QLatin1String("QFont(%1)")).arg(v.toString());
@@ -681,9 +596,7 @@ void QQuickFontValueType::setStrikeout(bool b)
qreal QQuickFontValueType::pointSize() const
{
if (v.pointSizeF() == -1) {
- if (dpi.isNull)
- dpi = qt_defaultDpi();
- return v.pixelSize() * qreal(72.) / qreal(dpi);
+ return v.pixelSize() * qreal(72.) / qreal(qt_defaultDpi());
}
return v.pointSizeF();
}
@@ -703,9 +616,7 @@ void QQuickFontValueType::setPointSize(qreal size)
int QQuickFontValueType::pixelSize() const
{
if (v.pixelSize() == -1) {
- if (dpi.isNull)
- dpi = qt_defaultDpi();
- return (v.pointSizeF() * dpi) / qreal(72.);
+ return (v.pointSizeF() * qt_defaultDpi()) / qreal(72.);
}
return v.pixelSize();
}
diff --git a/src/quick/util/qquickvaluetypes_p.h b/src/quick/util/qquickvaluetypes_p.h
index 7c1cdd1148..7bd6d71dce 100644
--- a/src/quick/util/qquickvaluetypes_p.h
+++ b/src/quick/util/qquickvaluetypes_p.h
@@ -54,17 +54,16 @@ void registerValueTypes();
}
-class Q_AUTOTEST_EXPORT QQuickColorValueType : public QQmlValueTypeBase<QColor>
+class QQuickColorValueType
{
+ QColor v;
Q_PROPERTY(qreal r READ r WRITE setR FINAL)
Q_PROPERTY(qreal g READ g WRITE setG FINAL)
Q_PROPERTY(qreal b READ b WRITE setB FINAL)
Q_PROPERTY(qreal a READ a WRITE setA FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQuickColorValueType(QObject *parent = 0);
-
- virtual QString toString() const;
+ Q_INVOKABLE QString toString() const;
qreal r() const;
qreal g() const;
@@ -76,16 +75,14 @@ public:
void setA(qreal);
};
-class Q_AUTOTEST_EXPORT QQuickVector2DValueType : public QQmlValueTypeBase<QVector2D>
+class QQuickVector2DValueType
{
+ QVector2D v;
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQuickVector2DValueType(QObject *parent = 0);
-
- virtual QString toString() const;
- virtual bool isEqual(const QVariant &other) const;
+ Q_INVOKABLE QString toString() const;
qreal x() const;
qreal y() const;
@@ -105,17 +102,15 @@ public:
Q_INVOKABLE bool fuzzyEquals(const QVector2D &vec) const;
};
-class Q_AUTOTEST_EXPORT QQuickVector3DValueType : public QQmlValueTypeBase<QVector3D>
+class QQuickVector3DValueType
{
+ QVector3D v;
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
Q_PROPERTY(qreal z READ z WRITE setZ FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQuickVector3DValueType(QObject *parent = 0);
-
- virtual QString toString() const;
- virtual bool isEqual(const QVariant &other) const;
+ Q_INVOKABLE QString toString() const;
qreal x() const;
qreal y() const;
@@ -139,18 +134,16 @@ public:
Q_INVOKABLE bool fuzzyEquals(const QVector3D &vec) const;
};
-class Q_AUTOTEST_EXPORT QQuickVector4DValueType : public QQmlValueTypeBase<QVector4D>
+class QQuickVector4DValueType
{
+ QVector4D v;
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
Q_PROPERTY(qreal z READ z WRITE setZ FINAL)
Q_PROPERTY(qreal w READ w WRITE setW FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQuickVector4DValueType(QObject *parent = 0);
-
- virtual QString toString() const;
- virtual bool isEqual(const QVariant &other) const;
+ Q_INVOKABLE QString toString() const;
qreal x() const;
qreal y() const;
@@ -175,17 +168,16 @@ public:
Q_INVOKABLE bool fuzzyEquals(const QVector4D &vec) const;
};
-class Q_AUTOTEST_EXPORT QQuickQuaternionValueType : public QQmlValueTypeBase<QQuaternion>
+class QQuickQuaternionValueType
{
+ QQuaternion v;
Q_PROPERTY(qreal scalar READ scalar WRITE setScalar)
Q_PROPERTY(qreal x READ x WRITE setX)
Q_PROPERTY(qreal y READ y WRITE setY)
Q_PROPERTY(qreal z READ z WRITE setZ)
- Q_OBJECT
+ Q_GADGET
public:
- QQuickQuaternionValueType(QObject *parent = 0);
-
- virtual QString toString() const;
+ Q_INVOKABLE QString toString() const;
qreal scalar() const;
qreal x() const;
@@ -197,8 +189,9 @@ public:
void setZ(qreal);
};
-class Q_AUTOTEST_EXPORT QQuickMatrix4x4ValueType : public QQmlValueTypeBase<QMatrix4x4>
+class QQuickMatrix4x4ValueType
{
+ QMatrix4x4 v;
Q_PROPERTY(qreal m11 READ m11 WRITE setM11 FINAL)
Q_PROPERTY(qreal m12 READ m12 WRITE setM12 FINAL)
Q_PROPERTY(qreal m13 READ m13 WRITE setM13 FINAL)
@@ -215,13 +208,8 @@ class Q_AUTOTEST_EXPORT QQuickMatrix4x4ValueType : public QQmlValueTypeBase<QMat
Q_PROPERTY(qreal m42 READ m42 WRITE setM42 FINAL)
Q_PROPERTY(qreal m43 READ m43 WRITE setM43 FINAL)
Q_PROPERTY(qreal m44 READ m44 WRITE setM44 FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQuickMatrix4x4ValueType(QObject *parent = 0);
-
- virtual QString toString() const;
- virtual bool isEqual(const QVariant &other) const;
-
qreal m11() const { return v(0, 0); }
qreal m12() const { return v(0, 1); }
qreal m13() const { return v(0, 2); }
@@ -274,9 +262,10 @@ public:
Q_INVOKABLE bool fuzzyEquals(const QMatrix4x4 &m) const;
};
-class Q_AUTOTEST_EXPORT QQuickFontValueType : public QQmlValueTypeBase<QFont>
+class QQuickFontValueType
{
- Q_OBJECT
+ QFont v;
+ Q_GADGET
Q_ENUMS(FontWeight)
Q_ENUMS(Capitalization)
@@ -305,9 +294,7 @@ public:
SmallCaps = QFont::SmallCaps,
Capitalize = QFont::Capitalize };
- QQuickFontValueType(QObject *parent = 0);
-
- virtual QString toString() const;
+ Q_INVOKABLE QString toString() const;
QString family() const;
void setFamily(const QString &);
@@ -344,9 +331,6 @@ public:
qreal wordSpacing() const;
void setWordSpacing(qreal spacing);
-
-private:
- mutable QQmlNullableValue<int> dpi;
};
QT_END_NAMESPACE
diff --git a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp
index fdbcc0dbf2..cdbad96b2f 100644
--- a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp
+++ b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp
@@ -199,6 +199,8 @@ public:
bool operator==(const TestValue &other) const { return (m_p1 == other.m_p1) && (m_p2 == other.m_p2); }
bool operator!=(const TestValue &other) const { return !operator==(other); }
+ bool operator<(const TestValue &other) const { if (m_p1 < other.m_p1) return true; return m_p2 < other.m_p2; }
+
private:
int m_p1;
double m_p2;
@@ -210,16 +212,14 @@ Q_DECLARE_METATYPE(TestValue);
namespace {
-class TestValueType : public QQmlValueTypeBase<TestValue>
+class TestValueType
{
- Q_OBJECT
+ TestValue v;
+ Q_GADGET
Q_PROPERTY(int property1 READ property1 WRITE setProperty1)
Q_PROPERTY(double property2 READ property2 WRITE setProperty2)
public:
- TestValueType(QObject *parent = 0) : QQmlValueTypeBase<TestValue>(qMetaTypeId<TestValue>(), parent) {}
-
- virtual QString toString() const { return QString::number(property1()) + QLatin1Char(',') + QString::number(property2()); }
- virtual bool isEqual(const QVariant &other) const { return (other.userType() == qMetaTypeId<TestValue>()) && (v == other.value<TestValue>()); }
+ Q_INVOKABLE QString toString() const { return QString::number(property1()) + QLatin1Char(',') + QString::number(property2()); }
int property1() const { return v.property1(); }
void setProperty1(int p1) { v.setProperty1(p1); }
@@ -231,14 +231,12 @@ public:
class TestValueTypeProvider : public QQmlValueTypeProvider
{
public:
- bool create(int type, QQmlValueType *&v)
+ const QMetaObject *getMetaObjectForMetaType(int type)
{
- if (type == qMetaTypeId<TestValue>()) {
- v = new TestValueType;
- return true;
- }
+ if (type == qMetaTypeId<TestValue>())
+ return &TestValueType::staticMetaObject;
- return false;
+ return 0;
}
};
@@ -279,6 +277,7 @@ void tst_qqmlvaluetypeproviders::userType()
Q_ASSERT(qMetaTypeId<TestValue>() >= QMetaType::User);
qRegisterMetaType<TestValue>();
+ QMetaType::registerComparators<TestValue>();
qmlRegisterType<TestValueExporter>("Test", 1, 0, "TestValueExporter");
TestValueExporter exporter;
diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
index ce2723bbf9..e3703eac00 100644
--- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
+++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
@@ -79,7 +79,6 @@ private slots:
void deletedObject();
void bindingVariantCopy();
void scriptVariantCopy();
- void cppClasses();
void enums();
void conflictingBindings();
void returnValues();
@@ -1166,26 +1165,6 @@ void tst_qqmlvaluetypes::scriptVariantCopy()
delete object;
}
-
-// Test that the value type classes can be used manually
-void tst_qqmlvaluetypes::cppClasses()
-{
- CPP_TEST(QQmlPointValueType, QPoint(19, 33));
- CPP_TEST(QQmlPointFValueType, QPointF(33.6, -23));
- CPP_TEST(QQmlSizeValueType, QSize(-100, 18));
- CPP_TEST(QQmlSizeFValueType, QSizeF(-100.7, 18.2));
- CPP_TEST(QQmlRectValueType, QRect(13, 39, 10928, 88));
- CPP_TEST(QQmlRectFValueType, QRectF(88.2, -90.1, 103.2, 118));
- CPP_TEST(QQuickVector2DValueType, QVector2D(19.7f, 1002));
- CPP_TEST(QQuickVector3DValueType, QVector3D(18.2f, 19.7f, 1002));
- CPP_TEST(QQuickVector4DValueType, QVector4D(18.2f, 19.7f, 1002, 54));
- CPP_TEST(QQuickQuaternionValueType, QQuaternion(18.2f, 19.7f, 1002, 54));
- CPP_TEST(QQuickMatrix4x4ValueType,
- QMatrix4x4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16));
- CPP_TEST(QQuickFontValueType, QFont("Helvetica"));
-
-}
-
void tst_qqmlvaluetypes::enums()
{
{