diff --git a/src/blackmisc/loghandler.cpp b/src/blackmisc/loghandler.cpp index 85afeb00d..1d3f5b6d4 100644 --- a/src/blackmisc/loghandler.cpp +++ b/src/blackmisc/loghandler.cpp @@ -12,7 +12,7 @@ #include "blackmisc/algorithm.h" #include "blackmisc/mixin/mixincompare.h" #include "blackmisc/crashhandler.h" -#include "blackmisc/worker.h" +#include "blackmisc/threadutils.h" #include "blackconfig/buildconfig.h" #ifdef BLACK_USE_CRASHPAD diff --git a/src/blackmisc/threadutils.h b/src/blackmisc/threadutils.h index 39ee6658b..95748d1e0 100644 --- a/src/blackmisc/threadutils.h +++ b/src/blackmisc/threadutils.h @@ -12,11 +12,40 @@ #define BLACKMISC_THREADUTILS_H #include "blackmisc/blackmiscexport.h" +#include "blackmisc/stacktrace.h" +#include "blackmisc/promise.h" +#include #include +#include +#include +#include #include namespace BlackMisc { + /*! + * Starts a single-shot timer which will call a task in the thread of the given object when it times out. + * + * Differs from QTimer::singleShot in that this implementation interacts better with QObject::moveToThread, + * and returns a QFuture which can be used to detect when the task has finished or obtain its return value. + */ + template + auto singleShot(int msec, QObject *target, F &&task) + { + CPromise promise; + QSharedPointer timer(new QTimer, [](QObject * o) { QMetaObject::invokeMethod(o, &QObject::deleteLater); }); + timer->setSingleShot(true); + timer->moveToThread(target->thread()); + QObject::connect(timer.data(), &QTimer::timeout, target, [trace = getStackTrace(), task = std::forward(task), timer, promise]() mutable + { + static_cast(trace); + timer.clear(); + promise.setResultFrom(task); + }); + QMetaObject::invokeMethod(timer.data(), [t = timer.data(), msec] { t->start(msec); }); + return promise.future(); + } + /*! * Utility class for threaded operations */ diff --git a/src/blackmisc/worker.h b/src/blackmisc/worker.h index 85401480f..c207fae73 100644 --- a/src/blackmisc/worker.h +++ b/src/blackmisc/worker.h @@ -42,29 +42,6 @@ namespace BlackMisc { - /*! - * Starts a single-shot timer which will call a task in the thread of the given object when it times out. - * - * Differs from QTimer::singleShot in that this implementation interacts better with QObject::moveToThread, - * and returns a QFuture which can be used to detect when the task has finished or obtain its return value. - */ - template - auto singleShot(int msec, QObject *target, F &&task) - { - CPromise promise; - QSharedPointer timer(new QTimer, [](QObject * o) { QMetaObject::invokeMethod(o, &QObject::deleteLater); }); - timer->setSingleShot(true); - timer->moveToThread(target->thread()); - QObject::connect(timer.data(), &QTimer::timeout, target, [trace = getStackTrace(), task = std::forward(task), timer, promise]() mutable - { - static_cast(trace); - timer.clear(); - promise.setResultFrom(task); - }); - QMetaObject::invokeMethod(timer.data(), [t = timer.data(), msec] { t->start(msec); }); - return promise.future(); - } - /*! * Just a subclass of QThread whose destructor waits for the thread to finish. */