aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqml.cpp43
-rw-r--r--src/qml/qml/qqml.h33
-rw-r--r--src/qml/qml/qqmlmetatype.cpp6
-rw-r--r--src/qml/qml/qqmlprivate.h46
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,