From a77526aac1c50ab0e948d3885b462ce0d1796ea1 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 18 Nov 2014 17:28:40 +0100 Subject: [PATCH] Begin cleaning up QQmlValueTypeWrapper Get rid of the objectType member. Instead of checking for it and then static_cast'ing to the specific class, it's easier to use Managed's as<> template cast. Also elimiate the QVariant value member for ValueTypeWrapperCopy. In fact, the entire class is folded into ValueTypeWrapper itself as d()->type has the one copy of the data. Change-Id: I0d9c794400095830540d313187623b98b686f4cd Reviewed-by: Lars Knoll --- src/qml/qml/qqmlvaluetypewrapper.cpp | 140 +++++++++++------------------------ src/qml/qml/qqmlvaluetypewrapper_p.h | 4 +- 2 files changed, 45 insertions(+), 99 deletions(-) diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index cbcc67c..5d065a7 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -60,61 +60,49 @@ struct QQmlValueTypeReference : QQmlValueTypeWrapper int property; }; -struct QQmlValueTypeCopy : QQmlValueTypeWrapper -{ - QQmlValueTypeCopy(QV8Engine *engine); - QVariant value; -}; - -} } -using namespace QV4; - struct QQmlValueTypeReference : public QQmlValueTypeWrapper { V4_OBJECT2(QQmlValueTypeReference, QQmlValueTypeWrapper) -}; -DEFINE_OBJECT_VTABLE(QQmlValueTypeReference); + static void destroy(Heap::Base *that); -struct QQmlValueTypeCopy : public QQmlValueTypeWrapper -{ - V4_OBJECT2(QQmlValueTypeCopy, QQmlValueTypeWrapper) + bool readReferenceValue() const; }; -DEFINE_OBJECT_VTABLE(QQmlValueTypeCopy); +} + +DEFINE_OBJECT_VTABLE(QV4::QQmlValueTypeReference); + +using namespace QV4; -Heap::QQmlValueTypeWrapper::QQmlValueTypeWrapper(QV8Engine *engine, ObjectType objectType) +Heap::QQmlValueTypeWrapper::QQmlValueTypeWrapper(QV8Engine *engine) : Heap::Object(QV8Engine::getV4(engine)) , v8(engine) - , objectType(objectType) { setVTable(QV4::QQmlValueTypeWrapper::staticVTable()); } Heap::QQmlValueTypeReference::QQmlValueTypeReference(QV8Engine *engine) - : Heap::QQmlValueTypeWrapper(engine, Reference) + : Heap::QQmlValueTypeWrapper(engine) { + setVTable(QV4::QQmlValueTypeReference::staticVTable()); } -Heap::QQmlValueTypeCopy::QQmlValueTypeCopy(QV8Engine *engine) - : Heap::QQmlValueTypeWrapper(engine, Copy) -{ -} - - -static bool readReferenceValue(const QQmlValueTypeReference *reference) +bool QQmlValueTypeReference::readReferenceValue() const { + if (!d()->object) + return false; // A reference resource may be either a "true" reference (eg, to a QVector3D property) // or a "variant" reference (eg, to a QVariant property which happens to contain a value-type). - QMetaProperty writebackProperty = reference->d()->object->metaObject()->property(reference->d()->property); + QMetaProperty writebackProperty = d()->object->metaObject()->property(d()->property); if (writebackProperty.userType() == QMetaType::QVariant) { // variant-containing-value-type reference QVariant variantReferenceValue; - reference->d()->type->readVariantValue(reference->d()->object, reference->d()->property, &variantReferenceValue); + d()->type->readVariantValue(d()->object, d()->property, &variantReferenceValue); int variantReferenceType = variantReferenceValue.userType(); - if (variantReferenceType != reference->d()->type->userType()) { + if (variantReferenceType != d()->type->userType()) { // This is a stale VariantReference. That is, the variant has been // overwritten with a different type in the meantime. // We need to modify this reference to the updated value type, if @@ -123,18 +111,18 @@ static bool readReferenceValue(const QQmlValueTypeReference *reference) QQmlValueType *vt = 0; if (const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(variantReferenceType)) vt = new QQmlValueType(variantReferenceType, mo); - reference->d()->type.reset(vt); - if (!reference->d()->type) { + d()->type.reset(vt); + if (!d()->type) { return false; } } else { return false; } } - reference->d()->type->setValue(variantReferenceValue); + d()->type->setValue(variantReferenceValue); } else { // value-type reference - reference->d()->type->read(reference->d()->object, reference->d()->property); + d()->type->read(d()->object, d()->property); } return true; } @@ -169,36 +157,25 @@ ReturnedValue QQmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, Scope scope(v4); initProto(v4); - Scoped r(scope, v4->memoryManager->alloc(v8)); + Scoped r(scope, v4->memoryManager->alloc(v8)); ScopedObject proto(scope, v4->qmlExtensions()->valueTypeWrapperPrototype); r->setPrototype(proto); - r->d()->type.reset(new QQmlValueType(typeId, metaObject)); r->d()->value = value; + r->d()->type.reset(new QQmlValueType(typeId, metaObject)); r->d()->type->setValue(value); return r->asReturnedValue(); } QVariant QQmlValueTypeWrapper::toVariant() const { - if (d()->objectType == Heap::QQmlValueTypeWrapper::Reference) { - const QQmlValueTypeReference *reference = static_cast(this); - - if (reference->d()->object && readReferenceValue(reference)) { - return reference->d()->type->value(); - } else { + if (const QQmlValueTypeReference *ref = as()) + if (!ref->readReferenceValue()) return QVariant(); - } - } else { - Q_ASSERT(d()->objectType == Heap::QQmlValueTypeWrapper::Copy); - return static_cast(this)->d()->value; - } + return d()->type->value(); } void QQmlValueTypeWrapper::destroy(Heap::Base *that) { Heap::QQmlValueTypeWrapper *w = static_cast(that); - if (w->objectType == Heap::QQmlValueTypeWrapper::Reference) - static_cast(w)->Heap::QQmlValueTypeReference::~QQmlValueTypeReference(); - else - static_cast(w)->Heap::QQmlValueTypeCopy::~QQmlValueTypeCopy(); + w->Heap::QQmlValueTypeWrapper::~QQmlValueTypeWrapper(); } bool QQmlValueTypeWrapper::isEqualTo(Managed *m, Managed *other) @@ -234,21 +211,12 @@ PropertyAttributes QQmlValueTypeWrapper::query(const Managed *m, String *name) bool QQmlValueTypeWrapper::isEqual(const QVariant& value) { - if (d()->objectType == Heap::QQmlValueTypeWrapper::Reference) { - QQmlValueTypeReference *reference = static_cast(this); - if (reference->d()->object && readReferenceValue(reference)) { - return reference->d()->type->isEqual(value); - } else { + if (QQmlValueTypeReference *ref = as()) + if (!ref->readReferenceValue()) return false; - } - } else { - Q_ASSERT(d()->objectType == Heap::QQmlValueTypeWrapper::Copy); - QQmlValueTypeCopy *copy = static_cast(this); - d()->type->setValue(copy->d()->value); - if (d()->type->isEqual(value)) - return true; - return (value == copy->d()->value); - } + if (d()->type->isEqual(value)) + return true; + return (value == d()->type->value()); } ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx) @@ -260,19 +228,10 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx) if (!w) return ctx->engine()->throwTypeError(); - if (w->d()->objectType == Heap::QQmlValueTypeWrapper::Reference) { - QQmlValueTypeReference *reference = static_cast(w); - if (reference->d()->object && readReferenceValue(reference)) { - return w->d()->v8->toString(w->d()->type->toString()); - } else { - return QV4::Encode::undefined(); - } - } else { - Q_ASSERT(w->d()->objectType == Heap::QQmlValueTypeWrapper::Copy); - QQmlValueTypeCopy *copy = static_cast(w); - w->d()->type->setValue(copy->d()->value); - return w->d()->v8->toString(w->d()->type->toString()); - } + if (QQmlValueTypeReference *ref = w->as()) + if (!ref->readReferenceValue()) + return Encode::undefined(); + return Encode(ctx->engine()->newString(w->d()->type->toString())); } ReturnedValue QQmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty) @@ -286,18 +245,9 @@ ReturnedValue QQmlValueTypeWrapper::get(Managed *m, String *name, bool *hasPrope return Object::get(m, name, hasProperty); // Note: readReferenceValue() can change the reference->type. - if (r->d()->objectType == Heap::QQmlValueTypeWrapper::Reference) { - QQmlValueTypeReference *reference = static_cast(r); - - if (!reference->d()->object || !readReferenceValue(reference)) + if (QQmlValueTypeReference *reference = r->as()) { + if (!reference->readReferenceValue()) return Primitive::undefinedValue().asReturnedValue(); - - } else { - Q_ASSERT(r->d()->objectType == Heap::QQmlValueTypeWrapper::Copy); - - QQmlValueTypeCopy *copy = static_cast(r); - - r->d()->type->setValue(copy->d()->value); } QQmlPropertyData local; @@ -355,11 +305,10 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const ValueRef value) Scoped r(scope, static_cast(m)); QByteArray propName = name->toQString().toUtf8(); - if (r->d()->objectType == Heap::QQmlValueTypeWrapper::Reference) { - Scoped reference(scope, static_cast(r->d())); + if (QQmlValueTypeReference *reference = r->as()) { QMetaProperty writebackProperty = reference->d()->object->metaObject()->property(reference->d()->property); - if (!reference->d()->object || !writebackProperty.isWritable() || !readReferenceValue(reference)) + if (!writebackProperty.isWritable() || !reference->readReferenceValue()) return; // we lookup the index after readReferenceValue() since it can change the reference->type. @@ -420,21 +369,20 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const ValueRef value) } } else { - Q_ASSERT(r->d()->objectType == Heap::QQmlValueTypeWrapper::Copy); - - Scoped copy(scope, static_cast(r->d())); - int index = r->d()->type->metaObject()->indexOfProperty(propName.constData()); if (index == -1) return; QVariant v = r->d()->v8->toVariant(value, -1); - r->d()->type->setValue(copy->d()->value); QMetaProperty p = r->d()->type->metaObject()->property(index); p.write(r->d()->type.data(), v); - copy->d()->value = r->d()->type->value(); } } +void QQmlValueTypeReference::destroy(Heap::Base *that) +{ + static_cast(that)->Heap::QQmlValueTypeReference::~QQmlValueTypeReference(); +} + QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h index e1c71c2..46f9f29 100644 --- a/src/qml/qml/qqmlvaluetypewrapper_p.h +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -61,10 +61,8 @@ namespace QV4 { namespace Heap { struct QQmlValueTypeWrapper : Object { - enum ObjectType { Reference, Copy }; - QQmlValueTypeWrapper(QV8Engine *engine, ObjectType type); + QQmlValueTypeWrapper(QV8Engine *engine); QV8Engine *v8; - ObjectType objectType; mutable QScopedPointer type; }; -- 2.7.4