aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/ftw
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2022-09-14 16:39:00 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2022-09-16 01:07:33 +0200
commitf1f43ec31ba4e5f20c3bec24f5d4a5756d16cc66 (patch)
tree3bfeb4e3849fde482125e47924044008b8a5ac2b /src/qml/qml/ftw
parentc0c241911123ee3e9f97b53f644e7b0c999ad5d2 (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.h222
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