diff options
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqml.cpp | 43 | ||||
-rw-r--r-- | src/qml/qml/qqml.h | 33 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlprivate.h | 46 |
4 files changed, 120 insertions, 8 deletions
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index 20608a60e4..40e629284b 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -421,6 +421,48 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) } break; } + case SequentialContainerAndRevisionsRegistration: { + const RegisterSequentialContainerAndRevisions &type + = *reinterpret_cast<RegisterSequentialContainerAndRevisions *>(data); + const char *elementName = classElementName(type.classInfoMetaObject); + RegisterSequentialContainer revisionRegistration = { + 0, + type.uri, + type.version, + elementName, + type.typeId, + type.metaSequence, + QTypeRevision() + }; + + const QTypeRevision added = revisionClassInfo( + type.classInfoMetaObject, "QML.AddedInVersion", + QTypeRevision::fromMinorVersion(0)); + const QTypeRevision removed = revisionClassInfo( + type.classInfoMetaObject, "QML.RemovedInVersion"); + + QVector<QTypeRevision> revisions = { added }; + uniqueRevisions(&revisions, type.version, added); + + for (QTypeRevision revision : qAsConst(revisions)) { + if (revision < added) + continue; + if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion()) + break; + + // When removed, we still add revisions, but anonymous ones + if (removed.isValid() && !(revision < removed)) + revisionRegistration.typeName = nullptr; + else + revisionRegistration.typeName = elementName; + + assignVersions(&revisionRegistration, revision, type.version); + const int id = qmlregister(SequentialContainerRegistration, &revisionRegistration); + if (type.qmlTypeIds) + type.qmlTypeIds->append(id); + } + break; + } case TypeRegistration: dtype = QQmlMetaType::registerType(*reinterpret_cast<RegisterType *>(data)); break; @@ -472,6 +514,7 @@ void QQmlPrivate::qmlunregister(RegistrationType type, quintptr data) break; case TypeAndRevisionsRegistration: case SingletonAndRevisionsRegistration: + case SequentialContainerAndRevisionsRegistration: // Currently unnecessary. We'd need a special data structure to hold // URI + majorVersion and then we'd iterate the minor versions, look up the // associated QQmlType objects by uri/elementName/major/minor and qmlunregister diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index 75f7ae5f06..7f0c81c514 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -94,6 +94,14 @@ template<typename T, typename... Args> \ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *); +#define QML_SEQUENTIAL_CONTAINER(VALUE_TYPE) \ + Q_CLASSINFO("QML.Sequence", #VALUE_TYPE) \ + using QmlSequenceValueType = VALUE_TYPE; \ + enum class QmlIsSequence {yes = true}; \ + template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlSequence; \ + template<typename T, typename... Args> \ + friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *); + #define QML_ADDED_IN_MINOR_VERSION(VERSION) \ Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(VERSION)) @@ -792,17 +800,18 @@ inline int qmlRegisterAnonymousSequentialContainer(const char *uri, int versionM QTypeRevision::fromMajorVersion(versionMajor), nullptr, QMetaType::fromType<Container>(), - QMetaSequence::fromContainer<Container>() + QMetaSequence::fromContainer<Container>(), + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::SequentialContainerRegistration, &type); } -template<class T, class Resolved, class Extended, bool Singleton, bool Interface> +template<class T, class Resolved, class Extended, bool Singleton, bool Interface, bool Sequence> struct QmlTypeAndRevisionsRegistration; template<class T, class Resolved, class Extended> -struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false> { +struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false, false> { static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, const QMetaObject *extension) { @@ -812,8 +821,19 @@ struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false> { } }; +template<class T, class Resolved> +struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, false, true> { + static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, + const QMetaObject *) + { + QQmlPrivate::qmlRegisterSequenceAndRevisions<Resolved>( + uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), + qmlTypeIds); + } +}; + template<class T, class Resolved, class Extended> -struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false> { +struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false, false> { static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, const QMetaObject *extension) { @@ -824,7 +844,7 @@ struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false> { }; template<class T, class Resolved> -struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true> { +struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true, false> { static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, const QMetaObject *) { @@ -845,7 +865,8 @@ void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor, QList<int> T, typename QQmlPrivate::QmlResolved<T>::Type, typename QQmlPrivate::QmlExtended<T>::Type, QQmlPrivate::QmlSingleton<T>::Value, - QQmlPrivate::QmlInterface<T>::Value> + QQmlPrivate::QmlInterface<T>::Value, + QQmlPrivate::QmlSequence<T>::Value> ::registerTypeAndRevisions(uri, versionMajor, qmlTypeIds, QQmlPrivate::QmlExtendedNamespace<T>::metaObject()); qmlRegisterTypesAndRevisions<Args...>(uri, versionMajor, qmlTypeIds); diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index e59ebc97eb..9dea173127 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -667,7 +667,8 @@ QQmlType QQmlMetaType::registerSequentialContainer( QQmlMetaTypeDataPtr data; - if (!checkRegistration(QQmlType::SequentialContainerType, data, container.uri, QString(), + const QString typeName = QString::fromUtf8(container.typeName); + if (!checkRegistration(QQmlType::SequentialContainerType, data, container.uri, typeName, container.version, {})) { return QQmlType(); } @@ -675,8 +676,9 @@ QQmlType QQmlMetaType::registerSequentialContainer( QQmlTypePrivate *priv = new QQmlTypePrivate(QQmlType::SequentialContainerType); data->registerType(priv); - priv->setName(QString::fromUtf8(container.uri), QString()); + priv->setName(QString::fromUtf8(container.uri), typeName); priv->version = container.version; + priv->revision = container.revision; priv->typeId = container.typeId; *priv->extraData.ld = container.metaSequence; diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index 19072f0751..feee3f8686 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -574,6 +574,19 @@ namespace QQmlPrivate const char *typeName; QMetaType typeId; QMetaSequence metaSequence; + QTypeRevision revision; + }; + + struct RegisterSequentialContainerAndRevisions { + int structVersion; + const char *uri; + QTypeRevision version; + + const QMetaObject *classInfoMetaObject; + QMetaType typeId; + QMetaSequence metaSequence; + + QVector<int> *qmlTypeIds; }; struct AOTCompiledFunction { @@ -605,6 +618,7 @@ namespace QQmlPrivate TypeAndRevisionsRegistration = 7, SingletonAndRevisionsRegistration = 8, SequentialContainerRegistration = 9, + SequentialContainerAndRevisionsRegistration = 10, }; int Q_QML_EXPORT qmlregister(RegistrationType, void *); @@ -717,6 +731,20 @@ namespace QQmlPrivate }; template<class T, class = std::void_t<>> + struct QmlSequence + { + static constexpr bool Value = false; + }; + + template<class T> + struct QmlSequence<T, std::void_t<typename T::QmlIsSequence>> + { + Q_STATIC_ASSERT((std::is_same_v<typename T::QmlSequenceValueType, + typename QmlResolved<T>::Type::value_type>)); + static constexpr bool Value = bool(T::QmlIsSequence::yes); + }; + + template<class T, class = std::void_t<>> struct QmlInterface { static constexpr bool Value = false; @@ -823,6 +851,24 @@ namespace QQmlPrivate qmlregister(TypeAndRevisionsRegistration, &type); } + template<typename T> + void qmlRegisterSequenceAndRevisions(const char *uri, int versionMajor, + const QMetaObject *classInfoMetaObject, + QVector<int> *qmlTypeIds) + { + RegisterSequentialContainerAndRevisions type = { + 0, + uri, + QTypeRevision::fromMajorVersion(versionMajor), + classInfoMetaObject, + QMetaType::fromType<T>(), + QMetaSequence::fromContainer<T>(), + qmlTypeIds + }; + + qmlregister(SequentialContainerAndRevisionsRegistration, &type); + } + template<> void Q_QML_EXPORT qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>( const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject, |