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>
This commit is contained in:
parent
c0c2419111
commit
f1f43ec31b
|
@ -46,38 +46,22 @@ public:
|
||||||
bool isThisThread() const;
|
bool isThisThread() const;
|
||||||
|
|
||||||
// Synchronously invoke a method in the thread
|
// Synchronously invoke a method in the thread
|
||||||
template<class O>
|
template<typename Method, typename ...Args>
|
||||||
inline void callMethodInThread(void (O::*Member)());
|
void callMethodInThread(Method &&method, Args &&...args);
|
||||||
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 &);
|
|
||||||
|
|
||||||
// Synchronously invoke a method in the main thread. If the main thread is
|
// 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
|
// blocked in a callMethodInThread() call, the call is made from within that
|
||||||
// call.
|
// call.
|
||||||
template<class O>
|
template<typename Method, typename ...Args>
|
||||||
inline void callMethodInMain(void (O::*Member)());
|
void callMethodInMain(Method &&method, Args &&...args);
|
||||||
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 &);
|
|
||||||
|
|
||||||
// Asynchronously invoke a method in the thread.
|
// Asynchronously invoke a method in the thread.
|
||||||
template<class O>
|
template<typename Method, typename ...Args>
|
||||||
inline void postMethodToThread(void (O::*Member)());
|
void postMethodToThread(Method &&method, Args &&...args);
|
||||||
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 &);
|
|
||||||
|
|
||||||
// Asynchronously invoke a method in the main thread.
|
// Asynchronously invoke a method in the main thread.
|
||||||
template<class O>
|
template<typename Method, typename ...Args>
|
||||||
inline void postMethodToMain(void (O::*Member)());
|
void postMethodToMain(Method &&method, Args &&...args);
|
||||||
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 &);
|
|
||||||
|
|
||||||
void waitForNextMessage();
|
void waitForNextMessage();
|
||||||
|
|
||||||
|
@ -90,6 +74,8 @@ private:
|
||||||
Message *next;
|
Message *next;
|
||||||
virtual void call(QQmlThread *) = 0;
|
virtual void call(QQmlThread *) = 0;
|
||||||
};
|
};
|
||||||
|
template<typename Method, typename ...Args>
|
||||||
|
Message *createMessageFromMethod(Method &&method, Args &&...args);
|
||||||
void internalCallMethodInThread(Message *);
|
void internalCallMethodInThread(Message *);
|
||||||
void internalCallMethodInMain(Message *);
|
void internalCallMethodInMain(Message *);
|
||||||
void internalPostMethodToThread(Message *);
|
void internalPostMethodToThread(Message *);
|
||||||
|
@ -97,184 +83,58 @@ private:
|
||||||
QQmlThreadPrivate *d;
|
QQmlThreadPrivate *d;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class O>
|
namespace QtPrivate {
|
||||||
void QQmlThread::callMethodInThread(void (O::*Member)())
|
template <typename> struct member_function_traits;
|
||||||
|
|
||||||
|
template <typename Return, typename Object, typename... Args>
|
||||||
|
struct member_function_traits<Return (Object::*)(Args...)>
|
||||||
{
|
{
|
||||||
struct I : public Message {
|
using class_type = Object;
|
||||||
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>
|
template<typename Method, typename ...Args>
|
||||||
void QQmlThread::callMethodInThread(void (O::*Member)(V), const T &arg)
|
QQmlThread::Message *QQmlThread::createMessageFromMethod(Method &&method, Args &&...args)
|
||||||
{
|
{
|
||||||
struct I : public Message {
|
struct I : public Message {
|
||||||
void (O::*Member)(V);
|
Method m;
|
||||||
T arg;
|
std::tuple<std::decay_t<Args>...> arguments;
|
||||||
I(void (O::*Member)(V), const T &arg) : Member(Member), arg(arg) {}
|
I(Method &&method, Args&& ...args) : m(std::forward<Method>(method)), arguments(std::forward<Args>(args)...) {}
|
||||||
void call(QQmlThread *thread) override {
|
void call(QQmlThread *thread) override {
|
||||||
O *me = static_cast<O *>(thread);
|
using class_type = typename QtPrivate::member_function_traits<Method>::class_type;
|
||||||
(me->*Member)(arg);
|
class_type *me = static_cast<class_type *>(thread);
|
||||||
|
std::apply(m, std::tuple_cat(std::make_tuple(me), arguments));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
internalCallMethodInThread(new I(Member, arg));
|
return new I(std::forward<Method>(method), std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename T2, class V, class V2, class O>
|
template<typename Method, typename ...Args>
|
||||||
void QQmlThread::callMethodInThread(void (O::*Member)(V, V2), const T &arg, const T2 &arg2)
|
void QQmlThread::callMethodInMain(Method &&method, Args&& ...args)
|
||||||
{
|
{
|
||||||
struct I : public Message {
|
Message *m = createMessageFromMethod(std::forward<Method>(method), std::forward<Args>(args)...);
|
||||||
void (O::*Member)(V, V2);
|
internalCallMethodInMain(m);
|
||||||
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>
|
template<typename Method, typename ...Args>
|
||||||
void QQmlThread::callMethodInMain(void (O::*Member)())
|
void QQmlThread::callMethodInThread(Method &&method, Args&& ...args)
|
||||||
{
|
{
|
||||||
struct I : public Message {
|
Message *m = createMessageFromMethod(std::forward<Method>(method), std::forward<Args>(args)...);
|
||||||
void (O::*Member)();
|
internalCallMethodInThread(m);
|
||||||
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>
|
template<typename Method, typename ...Args>
|
||||||
void QQmlThread::callMethodInMain(void (O::*Member)(V), const T &arg)
|
void QQmlThread::postMethodToThread(Method &&method, Args&& ...args)
|
||||||
{
|
{
|
||||||
struct I : public Message {
|
Message *m = createMessageFromMethod(std::forward<Method>(method), std::forward<Args>(args)...);
|
||||||
void (O::*Member)(V);
|
internalPostMethodToThread(m);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename T2, class V, class V2, class O>
|
template<typename Method, typename ...Args>
|
||||||
void QQmlThread::callMethodInMain(void (O::*Member)(V, V2), const T &arg, const T2 &arg2)
|
void QQmlThread::postMethodToMain(Method &&method, Args&& ...args)
|
||||||
{
|
{
|
||||||
struct I : public Message {
|
Message *m = createMessageFromMethod(std::forward<Method>(method), std::forward<Args>(args)...);
|
||||||
void (O::*Member)(V, V2);
|
internalPostMethodToMain(m);
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class O>
|
|
||||||
void QQmlThread::postMethodToThread(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)();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
internalPostMethodToThread(new I(Member));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, class V, class O>
|
|
||||||
void QQmlThread::postMethodToThread(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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
internalPostMethodToThread(new I(Member, arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class O>
|
|
||||||
void QQmlThread::postMethodToMain(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)();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
internalPostMethodToMain(new I(Member));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, class V, class O>
|
|
||||||
void QQmlThread::postMethodToMain(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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
Loading…
Reference in New Issue