From 37fbe667e6b5a528592b244124189981ba4aada9 Mon Sep 17 00:00:00 2001 From: Frank Meerkoetter Date: Sat, 25 Jul 2015 19:43:43 +0200 Subject: Adapt the ValueTypeProvider interface and port its types The ValueTypeProvider system allows non-QML modules to add new basic QML types. It needs to be changed when porting away from QQmlVmeVariant as underlying type of properties. Change-Id: I2b52d7e6f578647a39832896c28553404b9a679f Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlglobal.cpp | 29 ++++----- src/qml/qml/qqmlglobal_p.h | 16 ++--- src/qml/qml/qqmlvmemetaobject.cpp | 35 ++++++++-- src/quick/util/qquickglobal.cpp | 132 ++++++++++++-------------------------- 4 files changed, 90 insertions(+), 122 deletions(-) diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp index 2e772eaaf0..17de696af3 100644 --- a/src/qml/qml/qqmlglobal.cpp +++ b/src/qml/qml/qqmlglobal.cpp @@ -62,13 +62,11 @@ const QMetaObject *QQmlValueTypeProvider::metaObjectForMetaType(int type) return 0; } -bool QQmlValueTypeProvider::initValueType(int type, void *data, size_t n) +bool QQmlValueTypeProvider::initValueType(int type, QVariant& dst) { - Q_ASSERT(data); - QQmlValueTypeProvider *p = this; do { - if (p->init(type, data, n)) + if (p->init(type, dst)) return true; } while ((p = p->next)); @@ -174,14 +172,13 @@ QVariant QQmlValueTypeProvider::createVariantFromJsObject(int type, QQmlV4Handle return QVariant(); } -bool QQmlValueTypeProvider::equalValueType(int type, const void *lhs, const void *rhs, size_t rhsSize) +bool QQmlValueTypeProvider::equalValueType(int type, const void *lhs, const QVariant& rhs) { Q_ASSERT(lhs); - Q_ASSERT(rhs); QQmlValueTypeProvider *p = this; do { - if (p->equal(type, lhs, rhs, rhsSize)) + if (p->equal(type, lhs, rhs)) return true; } while ((p = p->next)); @@ -202,28 +199,26 @@ bool QQmlValueTypeProvider::storeValueType(int type, const void *src, void *dst, return false; } -bool QQmlValueTypeProvider::readValueType(int srcType, const void *src, size_t srcSize, int dstType, void *dst) +bool QQmlValueTypeProvider::readValueType(const QVariant& src, void *dst, int dstType) { - Q_ASSERT(src); Q_ASSERT(dst); QQmlValueTypeProvider *p = this; do { - if (p->read(srcType, src, srcSize, dstType, dst)) + if (p->read(src, dst, dstType)) return true; } while ((p = p->next)); return false; } -bool QQmlValueTypeProvider::writeValueType(int type, const void *src, void *dst, size_t n) +bool QQmlValueTypeProvider::writeValueType(int type, const void *src, QVariant& dst) { Q_ASSERT(src); - Q_ASSERT(dst); QQmlValueTypeProvider *p = this; do { - if (p->write(type, src, dst, n)) + if (p->write(type, src, dst)) return true; } while ((p = p->next)); @@ -231,7 +226,7 @@ bool QQmlValueTypeProvider::writeValueType(int type, const void *src, void *dst, } const QMetaObject *QQmlValueTypeProvider::getMetaObjectForMetaType(int) { return 0; } -bool QQmlValueTypeProvider::init(int, void *, size_t) { return false; } +bool QQmlValueTypeProvider::init(int, QVariant&) { return false; } bool QQmlValueTypeProvider::destroy(int, void *, size_t) { return false; } bool QQmlValueTypeProvider::create(int, int, const void *[], QVariant *) { return false; } bool QQmlValueTypeProvider::createFromString(int, const QString &, void *, size_t) { return false; } @@ -239,10 +234,10 @@ bool QQmlValueTypeProvider::createStringFrom(int, const void *, QString *) { ret bool QQmlValueTypeProvider::variantFromString(const QString &, QVariant *) { return false; } bool QQmlValueTypeProvider::variantFromString(int, const QString &, QVariant *) { return false; } bool QQmlValueTypeProvider::variantFromJsObject(int, QQmlV4Handle, QV4::ExecutionEngine *, QVariant *) { return false; } -bool QQmlValueTypeProvider::equal(int, const void *, const void *, size_t) { return false; } +bool QQmlValueTypeProvider::equal(int, const void *, const QVariant&) { return false; } bool QQmlValueTypeProvider::store(int, const void *, void *, size_t) { return false; } -bool QQmlValueTypeProvider::read(int, const void *, size_t, int, void *) { return false; } -bool QQmlValueTypeProvider::write(int, const void *, void *, size_t) { return false; } +bool QQmlValueTypeProvider::read(const QVariant&, void *, int) { return false; } +bool QQmlValueTypeProvider::write(int, const void *, QVariant&) { return false; } Q_GLOBAL_STATIC(QQmlValueTypeProvider, nullValueTypeProvider) static QQmlValueTypeProvider *valueTypeProvider = 0; diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index 8ed044d2c9..c19f7dab64 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -224,7 +224,7 @@ public: const QMetaObject *metaObjectForMetaType(int); - bool initValueType(int, void *, size_t); + bool initValueType(int, QVariant&); bool destroyValueType(int, void *, size_t); QVariant createValueType(int, int, const void *[]); @@ -235,14 +235,14 @@ public: QVariant createVariantFromString(int, const QString &, bool *); QVariant createVariantFromJsObject(int, QQmlV4Handle, QV4::ExecutionEngine *, bool*); - bool equalValueType(int, const void *, const void *, size_t); + bool equalValueType(int, const void *, const QVariant&); bool storeValueType(int, const void *, void *, size_t); - bool readValueType(int, const void *, size_t, int, void *); - bool writeValueType(int, const void *, void *, size_t); + bool readValueType(const QVariant&, void *, int); + bool writeValueType(int, const void *, QVariant&); private: virtual const QMetaObject *getMetaObjectForMetaType(int); - virtual bool init(int, void *, size_t); + virtual bool init(int, QVariant&); virtual bool destroy(int, void *, size_t); virtual bool create(int, int, const void *[], QVariant *); @@ -253,10 +253,10 @@ private: virtual bool variantFromString(int, const QString &, QVariant *); virtual bool variantFromJsObject(int, QQmlV4Handle, QV4::ExecutionEngine *, QVariant *); - virtual bool equal(int, const void *, const void *, size_t); + virtual bool equal(int, const void *, const QVariant&); virtual bool store(int, const void *, void *, size_t); - virtual bool read(int, const void *, size_t, int, void *); - virtual bool write(int, const void *, void *, size_t); + virtual bool read(const QVariant&, void *, int); + virtual bool write(int, const void *, QVariant&); friend Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *); friend Q_QML_PRIVATE_EXPORT void QQml_removeValueTypeProvider(QQmlValueTypeProvider *); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 0d10550fab..a960797626 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -1026,9 +1026,20 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) *reinterpret_cast(a[0]) = readPropertyAsVariant(id); break; default: - QQml_valueTypeProvider()->readValueType(data[id].dataType(), data[id].dataPtr(), data->dataSize(), t, a[0]); + { + if (ensurePropertiesAllocated()) { + QV4::ExecutionEngine *v4 = properties.engine(); + QV4::Scope scope(v4); + QV4::ScopedObject o(scope, properties.value()); + QV4::ScopedValue sv(scope, o->getIndexed(id)); + const QV4::VariantObject *v = sv->as(); + if (v) { + QQml_valueTypeProvider()->readValueType(v->d()->data, a[0], t); + } + } break; } + } if (t == qMetaTypeId >()) { const int listIndex = readPropertyAsInt(id); const List *list = &listProperties.at(listIndex); @@ -1088,12 +1099,26 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) case QMetaType::QVariant: writeProperty(id, *reinterpret_cast(a[0])); break; - default: - data[id].ensureValueType(t); - needActivate = !QQml_valueTypeProvider()->equalValueType(t, a[0], data[id].dataPtr(), data[id].dataSize()); - QQml_valueTypeProvider()->writeValueType(t, a[0], data[id].dataPtr(), data[id].dataSize()); + default: { + if (ensurePropertiesAllocated()) { + QV4::ExecutionEngine *v4 = properties.engine(); + QV4::Scope scope(v4); + QV4::ScopedObject o(scope, properties.value()); + QV4::ScopedValue sv(scope, o->getIndexed(id)); + QV4::VariantObject *v = sv->as(); + if (!v) { + QV4::ScopedValue svo(scope, properties.engine()->newVariantObject(QVariant())); + o->putIndexed(id, svo); + svo = o->getIndexed(id); + v = svo->as(); + } + QQmlValueTypeProvider().initValueType(t, v->d()->data); + needActivate = !QQml_valueTypeProvider()->equalValueType(t, a[0], v->d()->data); + QQml_valueTypeProvider()->writeValueType(t, a[0], v->d()->data); + } break; } + } } } diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp index fd172006e0..adf3a68e92 100644 --- a/src/quick/util/qquickglobal.cpp +++ b/src/quick/util/qquickglobal.cpp @@ -397,41 +397,30 @@ public: return 0; } - template - bool typedInit(void *data, size_t dataSize) - { - ASSERT_VALID_SIZE(dataSize, sizeof(T)); - T *t = reinterpret_cast(data); - new (t) T(); - return true; - } - - bool init(int type, void *data, size_t dataSize) + bool init(int type, QVariant& dst) { switch (type) { case QMetaType::QColor: - return typedInit(data, dataSize); + dst.setValue(QColor()); + return true; case QMetaType::QFont: - return typedInit(data, dataSize); + dst.setValue(QFont()); + return true; case QMetaType::QVector2D: - return typedInit(data, dataSize); + dst.setValue(QVector2D()); + return true; case QMetaType::QVector3D: - return typedInit(data, dataSize); + dst.setValue(QVector3D()); + return true; case QMetaType::QVector4D: - return typedInit(data, dataSize); + dst.setValue(QVector4D()); + return true; case QMetaType::QQuaternion: - return typedInit(data, dataSize); + dst.setValue(QQuaternion()); + return true; case QMetaType::QMatrix4x4: - { - if (dataSize >= sizeof(QMatrix4x4)) - return typedInit(data, dataSize); - - // special case: init matrix-containing qvariant. - Q_ASSERT(dataSize >= sizeof(QVariant)); - QVariant *matvar = reinterpret_cast(data); - new (matvar) QVariant(QMatrix4x4()); + dst.setValue(QMatrix4x4()); return true; - } default: break; } @@ -691,12 +680,12 @@ public: } template - bool typedEqual(const void *lhs, const void *rhs) + bool typedEqual(const void *lhs, const QVariant& rhs) { - return (*(reinterpret_cast(lhs)) == *(reinterpret_cast(rhs))); + return (*(reinterpret_cast(lhs)) == rhs.value()); } - bool equal(int type, const void *lhs, const void *rhs, size_t rhsSize) + bool equal(int type, const void *lhs, const QVariant &rhs) { switch (type) { case QMetaType::QColor: @@ -712,14 +701,7 @@ public: case QMetaType::QQuaternion: return typedEqual(lhs, rhs); case QMetaType::QMatrix4x4: - { - if (rhsSize >= sizeof(QMatrix4x4)) - return typedEqual(lhs, rhs); - - Q_ASSERT(rhsSize >= sizeof(QVariant)); - QMatrix4x4 rhsmat = reinterpret_cast(rhs)->value(); - return typedEqual(lhs, &rhsmat); - } + return typedEqual(lhs, rhs); default: break; } @@ -778,50 +760,34 @@ public: } template - bool typedRead(int srcType, const void *src, size_t srcSize, int dstType, void *dst) + bool typedRead(const QVariant& src, int dstType, void *dst) { T *dstT = reinterpret_cast(dst); - if (srcType == dstType) { - ASSERT_VALID_SIZE(srcSize, sizeof(T)); - const T *srcT = reinterpret_cast(src); - *dstT = *srcT; + if (src.type() == static_cast(dstType)) { + *dstT = src.value(); } else { *dstT = T(); } return true; } - bool read(int srcType, const void *src, size_t srcSize, int dstType, void *dst) + bool read(const QVariant &src, void *dst, int dstType) { switch (dstType) { case QMetaType::QColor: - return typedRead(srcType, src, srcSize, dstType, dst); + return typedRead(src, dstType, dst); case QMetaType::QFont: - return typedRead(srcType, src, srcSize, dstType, dst); + return typedRead(src, dstType, dst); case QMetaType::QVector2D: - return typedRead(srcType, src, srcSize, dstType, dst); + return typedRead(src, dstType, dst); case QMetaType::QVector3D: - return typedRead(srcType, src, srcSize, dstType, dst); + return typedRead(src, dstType, dst); case QMetaType::QVector4D: - return typedRead(srcType, src, srcSize, dstType, dst); + return typedRead(src, dstType, dst); case QMetaType::QQuaternion: - return typedRead(srcType, src, srcSize, dstType, dst); + return typedRead(src, dstType, dst); case QMetaType::QMatrix4x4: - { - if (srcSize >= sizeof(QMatrix4x4)) - return typedRead(srcType, src, srcSize, dstType, dst); - - // the source data may be stored in a QVariant. - QMatrix4x4 *dstMat = reinterpret_cast(dst); - if (srcType == dstType) { - Q_ASSERT(srcSize >= sizeof(QVariant)); - const QVariant *srcMatVar = reinterpret_cast(src); - *dstMat = srcMatVar->value(); - } else { - *dstMat = QMatrix4x4(); - } - return true; - } + return typedRead(src, dstType, dst); default: break; } @@ -829,51 +795,33 @@ public: } template - bool typedWrite(const void *src, void *dst, size_t dstSize) + bool typedWrite(const void *src, QVariant& dst) { - ASSERT_VALID_SIZE(dstSize, sizeof(T)); const T *srcT = reinterpret_cast(src); - T *dstT = reinterpret_cast(dst); - if (*dstT != *srcT) { - *dstT = *srcT; + if (dst.value() != *srcT) { + dst = *srcT; return true; } return false; } - bool write(int type, const void *src, void *dst, size_t dstSize) + bool write(int type, const void *src, QVariant& dst) { switch (type) { case QMetaType::QColor: - return typedWrite(src, dst, dstSize); + return typedWrite(src, dst); case QMetaType::QFont: - return typedWrite(src, dst, dstSize); + return typedWrite(src, dst); case QMetaType::QVector2D: - return typedWrite(src, dst, dstSize); + return typedWrite(src, dst); case QMetaType::QVector3D: - return typedWrite(src, dst, dstSize); + return typedWrite(src, dst); case QMetaType::QVector4D: - return typedWrite(src, dst, dstSize); + return typedWrite(src, dst); case QMetaType::QQuaternion: - return typedWrite(src, dst, dstSize); + return typedWrite(src, dst); case QMetaType::QMatrix4x4: - { - if (dstSize >= sizeof(QMatrix4x4)) - return typedWrite(src, dst, dstSize); - - // special case: storing matrix into variant - // eg, QVMEMO QVMEVariant data cell is big enough to store - // QVariant, but not large enough to store QMatrix4x4. - Q_ASSERT(dstSize >= sizeof(QVariant)); - const QMatrix4x4 *srcMat = reinterpret_cast(src); - QVariant *dstMatVar = reinterpret_cast(dst); - QMatrix4x4 dstMatVal = dstMatVar->value(); - if (dstMatVal != *srcMat) { - *dstMatVar = QVariant(*srcMat); - return true; - } - return false; - } + return typedWrite(src, dst); default: break; } -- cgit v1.2.3