diff options
author | Maximilian Goldstein <max.goldstein@qt.io> | 2021-01-19 17:54:45 +0100 |
---|---|---|
committer | Maximilian Goldstein <max.goldstein@qt.io> | 2021-01-20 12:07:34 +0100 |
commit | bf573ad295fbc1eee9379bfaafcded293c4b81f4 (patch) | |
tree | 330a69b72e7de269753c4563c8d59bac5a533d3d /src/qml | |
parent | e9997bc96911923355af2e1dd081cc039a2b2b8f (diff) |
QML_SINGLETON: Handle local create() functions with foreign types
Previously only the foreign type was searched for a create method.
Now the wrapping type can also contain it.
Change-Id: I05fb9e0c0a54c14530eb9adcae5a44df5c208be3
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/qml/qqml.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlprivate.h | 53 |
2 files changed, 34 insertions, 21 deletions
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index bac8039251..61eb5e1ffe 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -841,7 +841,7 @@ struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false, false static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, const QMetaObject *extension) { - QQmlPrivate::qmlRegisterSingletonAndRevisions<Resolved, Extended>( + QQmlPrivate::qmlRegisterSingletonAndRevisions<Resolved, Extended, T>( uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), qmlTypeIds, extension); } diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index ce83b33eaa..1b994b88e1 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -149,30 +149,33 @@ namespace QQmlPrivate { None, Constructor, - Factory + Factory, + FactoryWrapper }; - template<typename T, typename = std::void_t<>> + template<typename T, typename WrapperT = T, typename = std::void_t<>> struct HasSingletonFactory { static constexpr bool value = false; }; - template<typename T> - struct HasSingletonFactory<T, std::void_t<decltype(T::create( - static_cast<QQmlEngine *>(nullptr), - static_cast<QJSEngine *>(nullptr)))>> + template<typename T, typename WrapperT> + struct HasSingletonFactory<T, WrapperT, std::void_t<decltype(WrapperT::create( + static_cast<QQmlEngine *>(nullptr), + static_cast<QJSEngine *>(nullptr)))>> { static constexpr bool value = std::is_same_v< - decltype(T::create(static_cast<QQmlEngine *>(nullptr), + decltype(WrapperT::create(static_cast<QQmlEngine *>(nullptr), static_cast<QJSEngine *>(nullptr))), T *>; }; - template<typename T> + template<typename T, typename WrapperT> constexpr ConstructionMode constructionMode() { if constexpr (!std::is_base_of<QObject, T>::value) return ConstructionMode::None; + if constexpr (!std::is_same_v<T, WrapperT> && HasSingletonFactory<T, WrapperT>::value) + return ConstructionMode::FactoryWrapper; if constexpr (std::is_default_constructible<T>::value) return ConstructionMode::Constructor; if constexpr (HasSingletonFactory<T>::value) @@ -184,7 +187,7 @@ namespace QQmlPrivate template<typename T> void createInto(void *memory, void *) { new (memory) QQmlElement<T>; } - template<typename T, ConstructionMode Mode> + template<typename T, typename WrapperT, ConstructionMode Mode> QObject *createSingletonInstance(QQmlEngine *q, QJSEngine *j) { Q_UNUSED(q); @@ -193,6 +196,8 @@ namespace QQmlPrivate return new T; else if constexpr (Mode == ConstructionMode::Factory) return T::create(q, j); + else if constexpr (Mode == ConstructionMode::FactoryWrapper) + return WrapperT::create(q, j); else return nullptr; } @@ -205,31 +210,39 @@ namespace QQmlPrivate using CreateParentFunction = QObject *(*)(QObject *); using CreateValueTypeFunction = QVariant (*)(const QJSValue &); - template<typename T, ConstructionMode Mode = constructionMode<T>()> + template<typename T, typename WrapperT = T, ConstructionMode Mode = constructionMode<T, WrapperT>()> struct Constructors; - template<typename T> - struct Constructors<T, ConstructionMode::Constructor> + template<typename T, typename WrapperT> + struct Constructors<T, WrapperT, ConstructionMode::Constructor> { static constexpr CreateIntoFunction createInto = QQmlPrivate::createInto<T>; static constexpr CreateSingletonFunction createSingletonInstance - = QQmlPrivate::createSingletonInstance<T, ConstructionMode::Constructor>; + = QQmlPrivate::createSingletonInstance<T, WrapperT, ConstructionMode::Constructor>; }; - template<typename T> - struct Constructors<T, ConstructionMode::None> + template<typename T, typename WrapperT> + struct Constructors<T, WrapperT, ConstructionMode::None> { static constexpr CreateIntoFunction createInto = nullptr; static constexpr CreateSingletonFunction createSingletonInstance = nullptr; }; - template<typename T> - struct Constructors<T, ConstructionMode::Factory> + template<typename T, typename WrapperT> + struct Constructors<T, WrapperT, ConstructionMode::Factory> { static constexpr CreateIntoFunction createInto = nullptr; static constexpr CreateSingletonFunction createSingletonInstance - = QQmlPrivate::createSingletonInstance<T, ConstructionMode::Factory>; + = QQmlPrivate::createSingletonInstance<T, WrapperT, ConstructionMode::Factory>; + }; + + template<typename T, typename WrapperT> + struct Constructors<T, WrapperT, ConstructionMode::FactoryWrapper> + { + static constexpr CreateIntoFunction createInto = nullptr; + static constexpr CreateSingletonFunction createSingletonInstance + = QQmlPrivate::createSingletonInstance<T, WrapperT, ConstructionMode::FactoryWrapper>; }; template<typename T, @@ -805,7 +818,7 @@ namespace QQmlPrivate } }; - template<typename T, typename E> + template<typename T, typename E, typename WrapperT = T> void qmlRegisterSingletonAndRevisions(const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject, QVector<int> *qmlTypeIds, const QMetaObject *extension) @@ -816,7 +829,7 @@ namespace QQmlPrivate uri, QTypeRevision::fromMajorVersion(versionMajor), - Constructors<T>::createSingletonInstance, + Constructors<T, WrapperT>::createSingletonInstance, StaticMetaObject<T>::staticMetaObject(), classInfoMetaObject, |