diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-11-06 15:13:27 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-11-11 11:37:49 +0100 |
commit | f0908255c9921371d886eff0b8ce245929b50d88 (patch) | |
tree | b246bca2fcdae9ee906acc6e2b54a874b36734ea /src/qml/qml/qqml.cpp | |
parent | 40c0cbda771e9888999d8b78179e9600de4e7795 (diff) |
QtQml: Integrate sequences with registration macros
You get to write QML_SEQUENTIAL_CONTAINER(value_type) now, and
qmltyperegistrar will generate a sensible registration call from that.
A registration might look like this:
struct MyStringListForeign
{
Q_GADGET
QML_ANONYMOUS
QML_SEQUENTIAL_CONTAINER(QString)
QML_FOREIGN(MyStringList)
QML_ADDED_IN_VERSION(3, 1)
};
It's unfortunate that we need to use a metaobject to transfer all of
this information, but there is no other sensible way.
Transform the containers defined in qv4sequenceobject.cpp to use the new
style, and move them out of the builtins, into QtQml. Recognize that
only one of them was ever tested, and add tests for the rest.
Task-number: QTBUG-82443
Change-Id: I3a30f9e27266bb575eea26c5daf5dad1ec461cc5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqml.cpp')
-rw-r--r-- | src/qml/qml/qqml.cpp | 43 |
1 files changed, 43 insertions, 0 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 |