diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlbinding.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 117 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatypedata.cpp | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatypedata_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 14 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycachecreator.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycachecreator_p.h | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertyvalidator.cpp | 10 | ||||
-rw-r--r-- | src/qml/qml/qqmltypecompiler.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetype.cpp | 167 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetype_p.h | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypewrapper.cpp | 10 | ||||
-rw-r--r-- | src/qml/qml/qqmlvmemetaobject.cpp | 2 | ||||
-rw-r--r-- | src/quick/util/qquickanimation.cpp | 2 |
20 files changed, 157 insertions, 213 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp index 971404c831..be9db84272 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp @@ -258,8 +258,8 @@ QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const case QMetaType::QJsonDocument: return value.toJsonDocument().toVariant(); default: - if (QQmlValueTypeFactory::isValueType(metaType)) { - const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(metaType); + if (QQmlMetaType::isValueType(metaType)) { + const QMetaObject *mo = QQmlMetaType::metaObjectForMetaType(metaType); if (mo) { int toStringIndex = mo->indexOfMethod("toString()"); if (toStringIndex != -1) { diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 320dc15a15..7ae281fb1a 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1808,7 +1808,7 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) break; } - if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(metaType)) + if (const QMetaObject *vtmo = QQmlMetaType::metaObjectForMetaType(metaType)) return QV4::QQmlValueTypeWrapper::create(this, variant, vtmo, metaType); } else { QV4::Scope scope(this); @@ -1855,7 +1855,7 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) return sequentialIterableToJS(this, lst); } - if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(metaType)) + if (const QMetaObject *vtmo = QQmlMetaType::metaObjectForMetaType(metaType)) return QV4::QQmlValueTypeWrapper::create(this, variant, vtmo, metaType); } diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 98d69b2f80..55d62a2a8b 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -178,14 +178,14 @@ static QV4::ReturnedValue loadProperty(QV4::ExecutionEngine *v4, QObject *object QVariant v; property.readProperty(object, &v); - if (QQmlValueTypeFactory::isValueType(v.metaType())) { - if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(v.metaType())) + if (QQmlMetaType::isValueType(v.metaType())) { + if (const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForMetaType(v.metaType())) return QV4::QQmlValueTypeWrapper::create(v4, object, property.coreIndex(), valueTypeMetaObject, v.metaType()); // VariantReference value-type. } return scope.engine->fromVariant(v); - } else if (QQmlValueTypeFactory::isValueType(propMetaType)) { - if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(propMetaType)) + } else if (QQmlMetaType::isValueType(propMetaType)) { + if (const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForMetaType(propMetaType)) return QV4::QQmlValueTypeWrapper::create(v4, object, property.coreIndex(), valueTypeMetaObject, propMetaType); } else { #if QT_CONFIG(qml_sequence_object) diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 68764f1052..69ac63b0ad 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -630,7 +630,7 @@ void QQmlBinding::getPropertyData(QQmlPropertyData **propertyData, QQmlPropertyD Q_ASSERT(*propertyData); if (Q_UNLIKELY(m_targetIndex.hasValueTypeIndex() && valueTypeData)) { - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType((*propertyData)->propType()); + const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForMetaType((*propertyData)->propType()); Q_ASSERT(valueTypeMetaObject); QMetaProperty vtProp = valueTypeMetaObject->property(m_targetIndex.valueTypeIndex()); valueTypeData->setFlags(QQmlPropertyData::flagsForProperty(vtProp)); diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 9e9d24e90b..b7073ffcfd 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -291,7 +291,7 @@ public: if (it != cachedValueTypeInstances.end()) return *it; - if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type)) { + if (QQmlValueType *valueType = QQmlMetaType::valueType(type)) { QQmlGadgetPtrWrapper *instance = new QQmlGadgetPtrWrapper(valueType, q_func()); cachedValueTypeInstances.insert(typeIndex, instance); return instance; diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 16aafac6d1..7ce57c8d9f 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -44,8 +44,13 @@ #include <private/qqmltype_p_p.h> #include <private/qqmltypeloader_p.h> #include <private/qqmlextensionplugin_p.h> +#include <private/qqmlvaluetype_p.h> #include <private/qv4executablecompilationunit_p.h> +#if QT_CONFIG(qml_itemmodel) +#include <private/qqmlmodelindexvaluetype_p.h> +#endif + #include <QtCore/qcoreapplication.h> #include <QtCore/qmutex.h> #include <QtCore/qloggingcategory.h> @@ -629,11 +634,18 @@ CompositeMetaTypeIds QQmlMetaType::registerInternalCompositeType(const QByteArra void QQmlMetaType::unregisterInternalCompositeType(const CompositeMetaTypeIds &typeIds) { - QQmlMetaTypeDataPtr data; - data->qmlLists.remove(typeIds.listId.id()); QMetaType metaType(typeIds.id); - QMetaType::unregisterMetaType(metaType); QMetaType listMetaType(typeIds.listId); + + QQmlMetaTypeDataPtr data; + + if (QQmlValueType *vt = data->metaTypeToValueType.take(metaType.id())) + delete vt; + if (QQmlValueType *vt = data->metaTypeToValueType.take(listMetaType.id())) + delete vt; + + data->qmlLists.remove(listMetaType.id()); + QMetaType::unregisterMetaType(metaType); QMetaType::unregisterMetaType(listMetaType); delete static_cast<const QQmlMetaTypeInterface *>(metaType.iface()); delete static_cast<const QQmlMetaTypeInterface *>(listMetaType.iface()); @@ -1640,4 +1652,103 @@ QList<QQmlProxyMetaObject::ProxyData> QQmlMetaType::proxyData(const QMetaObject return metaObjects; } +bool isInternalType(int idx) +{ + // Qt internal types + switch (idx) { + case QMetaType::UnknownType: + case QMetaType::QStringList: + case QMetaType::QObjectStar: + case QMetaType::VoidStar: + case QMetaType::Nullptr: + case QMetaType::QVariant: + case QMetaType::QLocale: + case QMetaType::QImage: // scarce type, keep as QVariant + case QMetaType::QPixmap: // scarce type, keep as QVariant + return true; + default: + return false; + } +} + +bool QQmlMetaType::isValueType(QMetaType type) +{ + if (!type.isValid() || isInternalType(type.id())) + return false; + + return valueType(type) != nullptr; +} + +const QMetaObject *QQmlMetaType::metaObjectForMetaType(QMetaType metaType) +{ + const int t = metaType.id(); + switch (t) { + case QMetaType::QPoint: + return &QQmlPointValueType::staticMetaObject; + case QMetaType::QPointF: + return &QQmlPointFValueType::staticMetaObject; + case QMetaType::QSize: + return &QQmlSizeValueType::staticMetaObject; + case QMetaType::QSizeF: + return &QQmlSizeFValueType::staticMetaObject; + case QMetaType::QRect: + return &QQmlRectValueType::staticMetaObject; + case QMetaType::QRectF: + return &QQmlRectFValueType::staticMetaObject; +#if QT_CONFIG(easingcurve) + case QMetaType::QEasingCurve: + return &QQmlEasingValueType::staticMetaObject; +#endif +#if QT_CONFIG(qml_itemmodel) + case QMetaType::QModelIndex: + return &QQmlModelIndexValueType::staticMetaObject; + case QMetaType::QPersistentModelIndex: + return &QQmlPersistentModelIndexValueType::staticMetaObject; +#endif + default: +#if QT_CONFIG(qml_itemmodel) + if (metaType == QMetaType::fromType<QItemSelectionRange>()) + return &QQmlItemSelectionRangeValueType::staticMetaObject; +#endif + if (metaType == QMetaType::fromType<QQmlProperty>()) + return &QQmlPropertyValueType::staticMetaObject; + break; + } + + // It doesn't have to be a gadget for a QML type to exist, but we don't want to + // call QObject pointers value types. Explicitly registered types also override + // the implicit use of gadgets. + if (!(metaType.flags() & QMetaType::PointerToQObject)) { + const QQmlType qmlType = QQmlMetaType::qmlType(t, QQmlMetaType::TypeIdCategory::MetaType); + + // Prefer the extension meta object. + // Extensions allow registration of non-gadget value types. + if (const QMetaObject *extensionMetaObject = qmlType.extensionMetaObject()) + return extensionMetaObject; + + if (const QMetaObject *qmlTypeMetaObject = qmlType.metaObject()) + return qmlTypeMetaObject; + } + + // If it _is_ a gadget, we can just use it. + if (metaType.flags() & QMetaType::IsGadget) + return metaType.metaObject(); + + return nullptr; +} + +QQmlValueType *QQmlMetaType::valueType(QMetaType type) +{ + const int idx = type.id(); + QQmlMetaTypeDataPtr data; + + const auto it = data->metaTypeToValueType.constFind(idx); + if (it != data->metaTypeToValueType.constEnd()) + return *it; + + if (const QMetaObject *mo = metaObjectForMetaType(type)) + return *data->metaTypeToValueType.insert(idx, new QQmlValueType(idx, mo)); + return *data->metaTypeToValueType.insert(idx, nullptr); +} + QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 383952c41e..0cfe313421 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE class QQmlTypeModule; class QRecursiveMutex; class QQmlError; +class QQmlValueType; namespace QV4 { class ExecutableCompilationUnit; } @@ -262,6 +263,10 @@ public: static bool qmlRegisterModuleTypes(const QString &uri); static int qmlRegisteredListTypeCount(); + + static bool isValueType(QMetaType type); + static QQmlValueType *valueType(QMetaType metaType); + static const QMetaObject *metaObjectForMetaType(QMetaType type); }; Q_DECLARE_TYPEINFO(QQmlMetaType, Q_RELOCATABLE_TYPE); diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp index e973226053..4be26acdc6 100644 --- a/src/qml/qml/qqmlmetatypedata.cpp +++ b/src/qml/qml/qqmlmetatypedata.cpp @@ -57,6 +57,7 @@ QQmlMetaTypeData::~QQmlMetaTypeData() // Do this before the attached properties disappear. types.clear(); undeletableTypes.clear(); + qDeleteAll(metaTypeToValueType); } // This expects a "fresh" QQmlTypePrivate and adopts its reference. diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h index ed7c81639a..9719ec1bb4 100644 --- a/src/qml/qml/qqmlmetatypedata_p.h +++ b/src/qml/qml/qqmlmetatypedata_p.h @@ -54,6 +54,7 @@ #include <private/qqmltype_p.h> #include <private/qqmlmetatype_p.h> #include <private/qhashedstring_p.h> +#include <private/qqmlvaluetype_p.h> #include <QtCore/qset.h> #include <QtCore/qvector.h> @@ -85,6 +86,7 @@ struct QQmlMetaTypeData typedef QHash<int, QQmlMetaType::StringConverter> StringConverters; StringConverters stringConverters; QVector<QHash<QTypeRevision, QQmlRefPointer<QQmlPropertyCache>>> typePropertyCaches; + QHash<int, QQmlValueType *> metaTypeToValueType; struct VersionedUri { VersionedUri() = default; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 47d1b5e785..987b9a617e 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -846,7 +846,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper const QQmlPropertyData *valueTypeProperty = nullptr; QObject *bindingTarget = _bindingTarget; - if (QQmlValueTypeFactory::isValueType(bindingProperty->propType())) { + if (QQmlMetaType::isValueType(bindingProperty->propType())) { valueType = QQmlGadgetPtrWrapper::instance(engine, bindingProperty->propType()); if (!valueType) { recordError(binding->location, tr("Cannot set properties on %1 as it is null").arg(stringAt(binding->propertyNameIndex))); diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 2d503b053c..d178caf320 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -316,9 +316,9 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name) if (property->isFunction()) return; // Not an object property - if (ii == (path.count() - 2) && QQmlValueTypeFactory::isValueType(property->propType())) { + if (ii == (path.count() - 2) && QQmlMetaType::isValueType(property->propType())) { // We're now at a value type property - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType()); + const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForMetaType(property->propType()); if (!valueTypeMetaObject) return; // Not a value type int idx = valueTypeMetaObject->indexOfProperty(path.last().toUtf8().constData()); @@ -480,7 +480,7 @@ QQmlPropertyPrivate::propertyTypeCategory() const QMetaType type = propertyType(); if (!type.isValid()) return QQmlProperty::InvalidCategory; - else if (QQmlValueTypeFactory::isValueType(type)) + else if (QQmlMetaType::isValueType(type)) return QQmlProperty::Normal; else if (core.isQObject()) return QQmlProperty::Object; @@ -502,7 +502,7 @@ const char *QQmlProperty::propertyTypeName() const if (!d) return nullptr; if (d->isValueType()) { - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType()); + const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForMetaType(d->core.propType()); Q_ASSERT(valueTypeMetaObject); return valueTypeMetaObject->property(d->valueTypeData.coreIndex()).typeName(); } else if (d->object && type() & Property && d->core.isValid()) { @@ -681,7 +681,7 @@ QString QQmlProperty::name() const // ### if (!d->object) { } else if (d->isValueType()) { - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType()); + const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForMetaType(d->core.propType()); Q_ASSERT(valueTypeMetaObject); const char *vtName = valueTypeMetaObject->property(d->valueTypeData.coreIndex()).name(); @@ -1061,7 +1061,7 @@ QVariant QQmlPropertyPrivate::readValueProperty() if (isValueType()) { if (QQmlGadgetPtrWrapper *wrapper = QQmlGadgetPtrWrapper::instance(engine, core.propType())) return doRead(wrapper); - if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType())) { + if (QQmlValueType *valueType = QQmlMetaType::valueType(core.propType())) { QQmlGadgetPtrWrapper wrapper(valueType, nullptr); return doRead(&wrapper); } @@ -1201,7 +1201,7 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object, : nullptr; if (wrapper) { doWrite(wrapper); - } else if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType())) { + } else if (QQmlValueType *valueType = QQmlMetaType::valueType(core.propType())) { QQmlGadgetPtrWrapper wrapper(valueType, nullptr); doWrite(&wrapper); } diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp index 141aa80f85..5b44bd4f9d 100644 --- a/src/qml/qml/qqmlpropertycachecreator.cpp +++ b/src/qml/qml/qqmlpropertycachecreator.cpp @@ -132,7 +132,7 @@ QQmlRefPointer<QQmlPropertyCache> QQmlBindingInstantiationContext::instantiating // There is another overload that takes no version, which we shall not use here. return enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType().id(), instantiatingProperty->typeVersion()); - } else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(instantiatingProperty->propType())) { + } else if (const QMetaObject *vtmo = QQmlMetaType::metaObjectForMetaType(instantiatingProperty->propType())) { return enginePrivate->cache(vtmo, instantiatingProperty->typeVersion()); } } diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index ce1a830979..ca2f2effcd 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -239,7 +239,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectRecur // group properties and value type group properties. For the former the base type is derived from // the property that references us, for the latter we only need a meta-object on the referencing object // because interceptors can't go to the shared value type instances. - if (context.instantiatingProperty && QQmlValueTypeFactory::isValueType(context.instantiatingProperty->propType())) { + if (context.instantiatingProperty && QQmlMetaType::isValueType(context.instantiatingProperty->propType())) { if (!propertyCaches->needsVMEMetaObject(context.referencingObjectIndex)) { const CompiledObject *obj = objectContainer->objectAt(context.referencingObjectIndex); auto *typeRef = objectContainer->resolvedType(obj->inheritedTypeNameIndex); @@ -853,7 +853,7 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor Q_ASSERT(targetProperty); // for deep aliases, valueTypeIndex is always set - if (!QQmlValueTypeFactory::isValueType(targetProperty->propType()) && valueTypeIndex != -1) { + if (!QQmlMetaType::isValueType(targetProperty->propType()) && valueTypeIndex != -1) { // deep alias property *type = targetProperty->propType(); targetCache = enginePriv->propertyCacheForType(type->id()); @@ -878,7 +878,7 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor bindable = targetProperty->isBindable(); if (valueTypeIndex != -1) { - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(*type); + const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForMetaType(*type); if (valueTypeMetaObject->property(valueTypeIndex).isEnumType()) *type = QMetaType::fromType<int>(); else diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp index 590eee2a12..615128bfac 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -231,7 +231,7 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject( if (binding->type >= QV4::CompiledData::Binding::Type_Object && (pd || binding->isAttachedProperty())) { const bool populatingValueTypeGroupProperty = pd - && QQmlValueTypeFactory::metaObjectForMetaType(pd->propType()) + && QQmlMetaType::metaObjectForMetaType(pd->propType()) && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment); const QVector<QQmlError> subObjectValidatorErrors = validateObject(binding->value.objectIndex, binding, @@ -284,7 +284,7 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject( if (loc < (*assignedGroupProperty)->valueLocation) loc = (*assignedGroupProperty)->valueLocation; - if (pd && QQmlValueTypeFactory::isValueType(pd->propType())) + if (pd && QQmlMetaType::isValueType(pd->propType())) return recordError(loc, tr("Property has already been assigned a value")); return recordError(loc, tr("Cannot assign a value directly to a grouped property")); } @@ -298,8 +298,8 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject( if (bindingError.isValid()) return recordError(bindingError); } else if (binding->isGroupProperty()) { - if (QQmlValueTypeFactory::isValueType(pd->propType())) { - if (QQmlValueTypeFactory::metaObjectForMetaType(pd->propType())) { + if (QQmlMetaType::isValueType(pd->propType())) { + if (QQmlMetaType::metaObjectForMetaType(pd->propType())) { if (!pd->isWritable()) { return recordError(binding->location, tr("Invalid property assignment: \"%1\" is a read-only property").arg(name)); } @@ -752,7 +752,7 @@ QQmlError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *propert .arg(typeName)); } else if (propType == qMetaTypeId<QQmlScriptString>()) { return qQmlCompileError(binding->valueLocation, tr("Invalid property assignment: script expected")); - } else if (QQmlValueTypeFactory::isValueType(property->propType())) { + } else if (QQmlMetaType::isValueType(property->propType())) { return qQmlCompileError(binding->location, tr("Cannot assign value of type \"%1\" to property \"%2\", expecting an object") .arg(rhsType()).arg(propertyName)); } else { diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index cd89a908b3..e395439c10 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -1184,7 +1184,7 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, propIdx = QQmlPropertyIndex(targetProperty->coreIndex()); if (!subProperty.isEmpty()) { - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(targetProperty->propType()); + const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForMetaType(targetProperty->propType()); if (!valueTypeMetaObject) { // could be a deep alias bool isDeepAlias = subProperty.at(0).isLower(); diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index 150d70ee0c..e1f56d0d59 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -44,176 +44,9 @@ #include <QtCore/qdebug.h> #include <private/qqmlengine_p.h> #include <private/qmetaobjectbuilder_p.h> -#if QT_CONFIG(qml_itemmodel) -#include <private/qqmlmodelindexvaluetype_p.h> -#endif - -Q_DECLARE_METATYPE(QQmlProperty) QT_BEGIN_NAMESPACE -namespace { - -struct QQmlValueTypeFactoryImpl -{ - QQmlValueTypeFactoryImpl(); - ~QQmlValueTypeFactoryImpl(); - - bool isValueType(QMetaType type); - - const QMetaObject *metaObjectForMetaType(QMetaType metaType); - QQmlValueType *valueType(QMetaType type); - - QHash<int, QQmlValueType *> metaTypeToValueType; - QReadWriteLock rwLock; -}; - -QQmlValueTypeFactoryImpl::QQmlValueTypeFactoryImpl() -{ - -#if QT_CONFIG(qml_itemmodel) - // See types wrapped in qqmlmodelindexvaluetype_p.h - qRegisterMetaType<QItemSelectionRange>(); -#endif -} - -QQmlValueTypeFactoryImpl::~QQmlValueTypeFactoryImpl() -{ - qDeleteAll(metaTypeToValueType); -} - -bool isInternalType(int idx) -{ - // Qt internal types - switch (idx) { - case QMetaType::UnknownType: - case QMetaType::QStringList: - case QMetaType::QObjectStar: - case QMetaType::VoidStar: - case QMetaType::Nullptr: - case QMetaType::QVariant: - case QMetaType::QLocale: - case QMetaType::QImage: // scarce type, keep as QVariant - case QMetaType::QPixmap: // scarce type, keep as QVariant - return true; - default: - return false; - } -} - -bool QQmlValueTypeFactoryImpl::isValueType(QMetaType type) -{ - if (!type.isValid() || isInternalType(type.id())) - return false; - - return valueType(type) != nullptr; -} - -const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(QMetaType metaType) -{ - const int t = metaType.id(); - switch (t) { - case QMetaType::QPoint: - return &QQmlPointValueType::staticMetaObject; - case QMetaType::QPointF: - return &QQmlPointFValueType::staticMetaObject; - case QMetaType::QSize: - return &QQmlSizeValueType::staticMetaObject; - case QMetaType::QSizeF: - return &QQmlSizeFValueType::staticMetaObject; - case QMetaType::QRect: - return &QQmlRectValueType::staticMetaObject; - case QMetaType::QRectF: - return &QQmlRectFValueType::staticMetaObject; -#if QT_CONFIG(easingcurve) - case QMetaType::QEasingCurve: - return &QQmlEasingValueType::staticMetaObject; -#endif -#if QT_CONFIG(qml_itemmodel) - case QMetaType::QModelIndex: - return &QQmlModelIndexValueType::staticMetaObject; - case QMetaType::QPersistentModelIndex: - return &QQmlPersistentModelIndexValueType::staticMetaObject; -#endif - default: -#if QT_CONFIG(qml_itemmodel) - if (metaType == QMetaType::fromType<QItemSelectionRange>()) - return &QQmlItemSelectionRangeValueType::staticMetaObject; -#endif - if (metaType == QMetaType::fromType<QQmlProperty>()) - return &QQmlPropertyValueType::staticMetaObject; - break; - } - - // It doesn't have to be a gadget for a QML type to exist, but we don't want to - // call QObject pointers value types. Explicitly registered types also override - // the implicit use of gadgets. - if (!(metaType.flags() & QMetaType::PointerToQObject)) { - const QQmlType qmlType = QQmlMetaType::qmlType(t, QQmlMetaType::TypeIdCategory::MetaType); - - // Prefer the extension meta object. - // Extensions allow registration of non-gadget value types. - if (const QMetaObject *extensionMetaObject = qmlType.extensionMetaObject()) - return extensionMetaObject; - - if (const QMetaObject *qmlTypeMetaObject = qmlType.metaObject()) - return qmlTypeMetaObject; - } - - // If it _is_ a gadget, we can just use it. - if (metaType.flags() & QMetaType::IsGadget) - return metaType.metaObject(); - - return nullptr; -} - -QQmlValueType *QQmlValueTypeFactoryImpl::valueType(QMetaType type) -{ - int idx = type.id(); - // Protect the hash with a mutex - { - QReadLocker lock(&rwLock); - - auto it = metaTypeToValueType.constFind(idx); - if (it != metaTypeToValueType.constEnd()) { - return *it; - } - } - - { - QWriteLocker lock(&rwLock); - // TODO: we need try_emplace to avoid the double lookup - auto it = metaTypeToValueType.find(idx); - if (it != metaTypeToValueType.end()) // another thread inserted the element before we relocked - return *it; - QQmlValueType *vt = nullptr; - if (const QMetaObject *mo = metaObjectForMetaType(type)) - vt = new QQmlValueType(idx, mo); - it = metaTypeToValueType.insert(idx, vt); - return *it; - } - -} - -} - -Q_GLOBAL_STATIC(QQmlValueTypeFactoryImpl, factoryImpl); - -bool QQmlValueTypeFactory::isValueType(QMetaType type) -{ - return factoryImpl()->isValueType(type); -} - -QQmlValueType *QQmlValueTypeFactory::valueType(QMetaType type) -{ - return factoryImpl()->valueType(type); -} - -const QMetaObject *QQmlValueTypeFactory::metaObjectForMetaType(QMetaType type) -{ - return factoryImpl()->metaObjectForMetaType(type); -} - QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject) : metaType(typeId) { diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h index 177aa65a57..632405f315 100644 --- a/src/qml/qml/qqmlvaluetype_p.h +++ b/src/qml/qml/qqmlvaluetype_p.h @@ -117,14 +117,6 @@ private: void *m_gadgetPtr = nullptr; }; -class Q_QML_PRIVATE_EXPORT QQmlValueTypeFactory -{ -public: - static bool isValueType(QMetaType type); - static QQmlValueType *valueType(QMetaType metaType); - static const QMetaObject *metaObjectForMetaType(QMetaType type); -}; - struct Q_QML_PRIVATE_EXPORT QQmlPointFValueType { QPointF v; diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index e1b76cdb6f..1b3034d5d9 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -144,15 +144,15 @@ bool QQmlValueTypeReference::readReferenceValue() const // overwritten with a different type in the meantime. // 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)) { - const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(variantReferenceType); + if (QQmlMetaType::isValueType(variantReferenceType)) { + const QMetaObject *mo = QQmlMetaType::metaObjectForMetaType(variantReferenceType); if (d()->gadgetPtr()) { d()->valueType()->metaType.destruct(d()->gadgetPtr()); ::operator delete(d()->gadgetPtr()); } d()->setGadgetPtr(nullptr); d()->setMetaObject(mo); - d()->setValueType(QQmlValueTypeFactory::valueType(variantReferenceType)); + d()->setValueType(QQmlMetaType::valueType(variantReferenceType)); if (!mo) return false; } else { @@ -192,7 +192,7 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, QObject *obj r->d()->object = object; r->d()->property = property; r->d()->setMetaObject(metaObject); - auto valueType = QQmlValueTypeFactory::valueType(type); + auto valueType = QQmlMetaType::valueType(type); if (!valueType) { return engine->throwTypeError(QLatin1String("Type %1 is not a value type") .arg(QString::fromUtf8(type.name()))); @@ -209,7 +209,7 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, const QVaria Scoped<QQmlValueTypeWrapper> r(scope, engine->memoryManager->allocate<QQmlValueTypeWrapper>()); r->d()->setMetaObject(metaObject); - auto valueType = QQmlValueTypeFactory::valueType(type); + auto valueType = QQmlMetaType::valueType(type); if (!valueType) { return engine->throwTypeError(QLatin1String("Type %1 is not a value type") .arg(QString::fromUtf8(type.name()))); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 61ae1d4a06..265169a4d8 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -247,7 +247,7 @@ void QQmlVMEMetaObjectEndpoint::tryConnect() int coreIndex = encodedIndex.coreIndex(); int valueTypeIndex = encodedIndex.valueTypeIndex(); const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex); - if (pd && valueTypeIndex != -1 && !QQmlValueTypeFactory::valueType(pd->propType())) { + if (pd && valueTypeIndex != -1 && !QQmlMetaType::valueType(pd->propType())) { // deep alias QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(metaObject->compilationUnit->engine->qmlEngine()); auto const *newPropertyCache = enginePriv->propertyCacheForType(pd->propType().id()); diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index f2ee096af7..8dce372b4d 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -1982,7 +1982,7 @@ void QQuickPropertyAnimationPrivate::convertVariant(QVariant &variant, QMetaType } break; default: - if (QQmlValueTypeFactory::isValueType(type)) { + if (QQmlMetaType::isValueType(type)) { variant.convert(QMetaType(type)); } else { QQmlMetaType::StringConverter converter = QQmlMetaType::customStringConverter(type.id()); |