diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2019-06-06 09:55:20 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2019-06-11 09:18:49 +0200 |
commit | bf8862a3bfa3010986ed638e90d870fbd2a61435 (patch) | |
tree | 3a35d92336bcec3164d2ebef1af10a6c839f6c08 /src/qml | |
parent | b0829884c8da99a8ca7d9bd933980fef2527638f (diff) |
add std::function overload to qmlRegisterSingletonType
This changes enables passing stateful lambdas to
qmlRegisterSingletonType, which helps when porting away from
setContextProperty.
Unfortunately, we cannot directly add an overload for std::function, as
this causes ambiguity in the overload set when a lambda of the form
auto f = [](QQmlEngine*, QJSEngine*) -> QObject*
is passed to the function (which is what the examples do)
We therefore use a template to support abribtrary callables f, then SFINAE
them out if f is not convertible to the desired std::function, or when
f is convertible to a plain C function pointer, thus removing the
ambiguity
Change-Id: I6ca95ad692d8bb785e420b85bf3d8c1d0007ce17
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/doc/src/qmlfunctions.qdoc | 8 | ||||
-rw-r--r-- | src/qml/qml/qqml.h | 25 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 10 | ||||
-rw-r--r-- | src/qml/qml/qqmlprivate.h | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmltype_p.h | 4 |
5 files changed, 43 insertions, 7 deletions
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc index 3c80f16c8f..ab54b5fd1d 100644 --- a/src/qml/doc/src/qmlfunctions.qdoc +++ b/src/qml/doc/src/qmlfunctions.qdoc @@ -564,6 +564,14 @@ \sa {Choosing the Correct Integration Method Between C++ and QML} */ + +/*! + \fn int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, std::function<QObject*(QQmlEngine *, QJSEngine *)> callback) + \relates QQmlEngine + + \overload qmlRegisterSingletonType +*/ + /*! \fn int qmlRegisterSingletonType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName) \relates QQmlEngine diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index f84a1b2109..4f3bfb76b0 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -624,13 +624,13 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi uri, versionMajor, versionMinor, typeName, - callback, nullptr, nullptr, 0, 0 + callback, nullptr, nullptr, 0, 0, {} }; return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); } -enum { QmlCurrentSingletonTypeRegistrationVersion = 2 }; +enum { QmlCurrentSingletonTypeRegistrationVersion = 3 }; template <typename T> inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *(*callback)(QQmlEngine *, QJSEngine *)) @@ -642,7 +642,26 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi uri, versionMajor, versionMinor, typeName, - nullptr, callback, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0 + nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, callback + }; + + return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); +} + +template <typename T, typename F, typename std::enable_if<std::is_convertible<F, std::function<QObject *(QQmlEngine *, QJSEngine *)>>::value + && !std::is_convertible<F, QObject *(*)(QQmlEngine *, QJSEngine *)>::value, void>::type* = nullptr> +inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, + F&& callback) +{ + + QML_GETTYPENAMES + + QQmlPrivate::RegisterSingletonType api = { + QmlCurrentSingletonTypeRegistrationVersion, + + uri, versionMajor, versionMinor, typeName, + + nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, callback }; return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index c6858780a1..a2c2ae47af 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -107,7 +107,7 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el d->version_maj = type.versionMajor; d->version_min = type.versionMinor; - if (type.qobjectApi) { + if (type.qobjectApi || (type.version >= 3 && type.generalizedQobjectApi)) { if (type.version >= 1) // static metaobject added in version 1 d->baseMetaObject = type.instanceMetaObject; if (type.version >= 2) // typeId added in version 2 @@ -118,10 +118,14 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el d->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo; d->extraData.sd->singletonInstanceInfo->scriptCallback = type.scriptApi; - d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi; + if (type.version >= 3) { + d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.generalizedQobjectApi; + } else { + d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi; + } d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName); d->extraData.sd->singletonInstanceInfo->instanceMetaObject - = (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : nullptr; + = ((type.qobjectApi || (type.version >= 3 && type.generalizedQobjectApi) ) && type.version >= 1) ? type.instanceMetaObject : nullptr; return d; } diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index ae84803648..a07736c6fc 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -51,6 +51,8 @@ // We mean it. // +#include <functional> + #include <QtQml/qtqmlglobal.h> #include <QtCore/qglobal.h> @@ -276,6 +278,7 @@ namespace QQmlPrivate const QMetaObject *instanceMetaObject; // new in version 1 int typeId; // new in version 2 int revision; // new in version 2 + std::function<QObject*(QQmlEngine *, QJSEngine *)> generalizedQobjectApi; // new in version 3 // If this is extended ensure "version" is bumped!!! }; diff --git a/src/qml/qml/qqmltype_p.h b/src/qml/qml/qqmltype_p.h index 1d65a08c8f..158fefad2c 100644 --- a/src/qml/qml/qqmltype_p.h +++ b/src/qml/qml/qqmltype_p.h @@ -51,6 +51,8 @@ // We mean it. // +#include <functional> + #include <private/qtqmlglobal_p.h> #include <private/qqmlrefcount_p.h> @@ -145,7 +147,7 @@ public: struct Q_QML_PRIVATE_EXPORT SingletonInstanceInfo { QJSValue (*scriptCallback)(QQmlEngine *, QJSEngine *) = nullptr; - QObject *(*qobjectCallback)(QQmlEngine *, QJSEngine *) = nullptr; + std::function<QObject *(QQmlEngine *, QJSEngine *)> qobjectCallback = {}; const QMetaObject *instanceMetaObject = nullptr; QString typeName; QUrl url; // used by composite singletons |