diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2022-09-14 16:39:00 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2022-09-16 01:07:33 +0200 |
commit | f1f43ec31ba4e5f20c3bec24f5d4a5756d16cc66 (patch) | |
tree | 3bfeb4e3849fde482125e47924044008b8a5ac2b /src/qml/qml/ftw | |
parent | c0c241911123ee3e9f97b53f644e7b0c999ad5d2 (diff) |
QQmlThread: Unify postTo/callIn methods
Instead of handling member functions of different arity with dedicated
functions, simply use variadic templates and std::tuple. Moreover, move
the creation of the Message object into a dedicated helper method, so
that it can be shared between all methods.
Change-Id: I493afb2350e9cf47ea90b3532ae2a7da074d8083
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/qml/qml/ftw')
-rw-r--r-- | src/qml/qml/ftw/qqmlthread_p.h | 222 |
1 files changed, 41 insertions, 181 deletions
diff --git a/src/qml/qml/ftw/qqmlthread_p.h b/src/qml/qml/ftw/qqmlthread_p.h index 51f64ce750..4af94036b5 100644 --- a/src/qml/qml/ftw/qqmlthread_p.h +++ b/src/qml/qml/ftw/qqmlthread_p.h @@ -46,38 +46,22 @@ public: bool isThisThread() const; // Synchronously invoke a method in the thread - template<class O> - inline void callMethodInThread(void (O::*Member)()); - template<typename T, class V, class O> - inline void callMethodInThread(void (O::*Member)(V), const T &); - template<typename T, typename T2, class V, class V2, class O> - inline void callMethodInThread(void (O::*Member)(V, V2), const T &, const T2 &); + template<typename Method, typename ...Args> + void callMethodInThread(Method &&method, Args &&...args); // Synchronously invoke a method in the main thread. If the main thread is // blocked in a callMethodInThread() call, the call is made from within that // call. - template<class O> - inline void callMethodInMain(void (O::*Member)()); - template<typename T, class V, class O> - inline void callMethodInMain(void (O::*Member)(V), const T &); - template<typename T, typename T2, class V, class V2, class O> - inline void callMethodInMain(void (O::*Member)(V, V2), const T &, const T2 &); + template<typename Method, typename ...Args> + void callMethodInMain(Method &&method, Args &&...args); // Asynchronously invoke a method in the thread. - template<class O> - inline void postMethodToThread(void (O::*Member)()); - template<typename T, class V, class O> - inline void postMethodToThread(void (O::*Member)(V), const T &); - template<typename T, typename T2, class V, class V2, class O> - inline void postMethodToThread(void (O::*Member)(V, V2), const T &, const T2 &); + template<typename Method, typename ...Args> + void postMethodToThread(Method &&method, Args &&...args); // Asynchronously invoke a method in the main thread. - template<class O> - inline void postMethodToMain(void (O::*Member)()); - template<typename T, class V, class O> - inline void postMethodToMain(void (O::*Member)(V), const T &); - template<typename T, typename T2, class V, class V2, class O> - inline void postMethodToMain(void (O::*Member)(V, V2), const T &, const T2 &); + template<typename Method, typename ...Args> + void postMethodToMain(Method &&method, Args &&...args); void waitForNextMessage(); @@ -90,6 +74,8 @@ private: Message *next; virtual void call(QQmlThread *) = 0; }; + template<typename Method, typename ...Args> + Message *createMessageFromMethod(Method &&method, Args &&...args); void internalCallMethodInThread(Message *); void internalCallMethodInMain(Message *); void internalPostMethodToThread(Message *); @@ -97,184 +83,58 @@ private: QQmlThreadPrivate *d; }; -template<class O> -void QQmlThread::callMethodInThread(void (O::*Member)()) -{ - struct I : public Message { - void (O::*Member)(); - I(void (O::*Member)()) : Member(Member) {} - void call(QQmlThread *thread) override { - O *me = static_cast<O *>(thread); - (me->*Member)(); - } - }; - internalCallMethodInThread(new I(Member)); -} - -template<typename T, class V, class O> -void QQmlThread::callMethodInThread(void (O::*Member)(V), const T &arg) -{ - struct I : public Message { - void (O::*Member)(V); - T arg; - I(void (O::*Member)(V), const T &arg) : Member(Member), arg(arg) {} - void call(QQmlThread *thread) override { - O *me = static_cast<O *>(thread); - (me->*Member)(arg); - } - }; - internalCallMethodInThread(new I(Member, arg)); -} - -template<typename T, typename T2, class V, class V2, class O> -void QQmlThread::callMethodInThread(void (O::*Member)(V, V2), const T &arg, const T2 &arg2) -{ - struct I : public Message { - void (O::*Member)(V, V2); - T arg; - T2 arg2; - I(void (O::*Member)(V, V2), const T &arg, const T2 &arg2) : Member(Member), arg(arg), arg2(arg2) {} - void call(QQmlThread *thread) override { - O *me = static_cast<O *>(thread); - (me->*Member)(arg, arg2); - } - }; - internalCallMethodInThread(new I(Member, arg, arg2)); -} - -template<class O> -void QQmlThread::callMethodInMain(void (O::*Member)()) -{ - struct I : public Message { - void (O::*Member)(); - I(void (O::*Member)()) : Member(Member) {} - void call(QQmlThread *thread) override { - O *me = static_cast<O *>(thread); - (me->*Member)(); - } - }; - internalCallMethodInMain(new I(Member)); -} - -template<typename T, class V, class O> -void QQmlThread::callMethodInMain(void (O::*Member)(V), const T &arg) -{ - struct I : public Message { - void (O::*Member)(V); - T arg; - I(void (O::*Member)(V), const T &arg) : Member(Member), arg(arg) {} - void call(QQmlThread *thread) override { - O *me = static_cast<O *>(thread); - (me->*Member)(arg); - } - }; - internalCallMethodInMain(new I(Member, arg)); -} +namespace QtPrivate { +template <typename> struct member_function_traits; -template<typename T, typename T2, class V, class V2, class O> -void QQmlThread::callMethodInMain(void (O::*Member)(V, V2), const T &arg, const T2 &arg2) +template <typename Return, typename Object, typename... Args> +struct member_function_traits<Return (Object::*)(Args...)> { - struct I : public Message { - void (O::*Member)(V, V2); - T arg; - T2 arg2; - I(void (O::*Member)(V, V2), const T &arg, const T2 &arg2) : Member(Member), arg(arg), arg2(arg2) {} - void call(QQmlThread *thread) override { - O *me = static_cast<O *>(thread); - (me->*Member)(arg, arg2); - } - }; - internalCallMethodInMain(new I(Member, arg, arg2)); + using class_type = Object; +}; } -template<class O> -void QQmlThread::postMethodToThread(void (O::*Member)()) +template<typename Method, typename ...Args> +QQmlThread::Message *QQmlThread::createMessageFromMethod(Method &&method, Args &&...args) { struct I : public Message { - void (O::*Member)(); - I(void (O::*Member)()) : Member(Member) {} + Method m; + std::tuple<std::decay_t<Args>...> arguments; + I(Method &&method, Args&& ...args) : m(std::forward<Method>(method)), arguments(std::forward<Args>(args)...) {} void call(QQmlThread *thread) override { - O *me = static_cast<O *>(thread); - (me->*Member)(); + using class_type = typename QtPrivate::member_function_traits<Method>::class_type; + class_type *me = static_cast<class_type *>(thread); + std::apply(m, std::tuple_cat(std::make_tuple(me), arguments)); } }; - internalPostMethodToThread(new I(Member)); + return new I(std::forward<Method>(method), std::forward<Args>(args)...); } -template<typename T, class V, class O> -void QQmlThread::postMethodToThread(void (O::*Member)(V), const T &arg) +template<typename Method, typename ...Args> +void QQmlThread::callMethodInMain(Method &&method, Args&& ...args) { - struct I : public Message { - void (O::*Member)(V); - T arg; - I(void (O::*Member)(V), const T &arg) : Member(Member), arg(arg) {} - void call(QQmlThread *thread) override { - O *me = static_cast<O *>(thread); - (me->*Member)(arg); - } - }; - internalPostMethodToThread(new I(Member, arg)); + Message *m = createMessageFromMethod(std::forward<Method>(method), std::forward<Args>(args)...); + internalCallMethodInMain(m); } -template<typename T, typename T2, class V, class V2, class O> -void QQmlThread::postMethodToThread(void (O::*Member)(V, V2), const T &arg, const T2 &arg2) +template<typename Method, typename ...Args> +void QQmlThread::callMethodInThread(Method &&method, Args&& ...args) { - struct I : public Message { - void (O::*Member)(V, V2); - T arg; - T2 arg2; - I(void (O::*Member)(V, V2), const T &arg, const T2 &arg2) : Member(Member), arg(arg), arg2(arg2) {} - void call(QQmlThread *thread) override { - O *me = static_cast<O *>(thread); - (me->*Member)(arg, arg2); - } - }; - internalPostMethodToThread(new I(Member, arg, arg2)); + Message *m = createMessageFromMethod(std::forward<Method>(method), std::forward<Args>(args)...); + internalCallMethodInThread(m); } -template<class O> -void QQmlThread::postMethodToMain(void (O::*Member)()) +template<typename Method, typename ...Args> +void QQmlThread::postMethodToThread(Method &&method, Args&& ...args) { - struct I : public Message { - void (O::*Member)(); - I(void (O::*Member)()) : Member(Member) {} - void call(QQmlThread *thread) override { - O *me = static_cast<O *>(thread); - (me->*Member)(); - } - }; - internalPostMethodToMain(new I(Member)); + Message *m = createMessageFromMethod(std::forward<Method>(method), std::forward<Args>(args)...); + internalPostMethodToThread(m); } -template<typename T, class V, class O> -void QQmlThread::postMethodToMain(void (O::*Member)(V), const T &arg) +template<typename Method, typename ...Args> +void QQmlThread::postMethodToMain(Method &&method, Args&& ...args) { - struct I : public Message { - void (O::*Member)(V); - T arg; - I(void (O::*Member)(V), const T &arg) : Member(Member), arg(arg) {} - void call(QQmlThread *thread) override { - O *me = static_cast<O *>(thread); - (me->*Member)(arg); - } - }; - internalPostMethodToMain(new I(Member, arg)); -} - -template<typename T, typename T2, class V, class V2, class O> -void QQmlThread::postMethodToMain(void (O::*Member)(V, V2), const T &arg, const T2 &arg2) -{ - struct I : public Message { - void (O::*Member)(V, V2); - T arg; - T2 arg2; - I(void (O::*Member)(V, V2), const T &arg, const T2 &arg2) : Member(Member), arg(arg), arg2(arg2) {} - void call(QQmlThread *thread) override { - O *me = static_cast<O *>(thread); - (me->*Member)(arg, arg2); - } - }; - internalPostMethodToMain(new I(Member, arg, arg2)); + Message *m = createMessageFromMethod(std::forward<Method>(method), std::forward<Args>(args)...); + internalPostMethodToMain(m); } QT_END_NAMESPACE |