From 4a7ad09e46626d57ddaddad5cb48a41a30c18b84 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Tue, 11 Jul 2017 03:31:43 +0200 Subject: [PATCH] Ref T105, m_updateTimer as protected member of CContinuousWorker * stop timer * default cleanup implementation * set timer name --- src/blackmisc/worker.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/blackmisc/worker.h | 15 +++++++++++---- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/blackmisc/worker.cpp b/src/blackmisc/worker.cpp index 4aeb9c848..4f66758ce 100644 --- a/src/blackmisc/worker.cpp +++ b/src/blackmisc/worker.cpp @@ -116,6 +116,12 @@ namespace BlackMisc return thread()->isInterruptionRequested(); } + CContinuousWorker::CContinuousWorker(QObject *owner, const QString &name) : + m_owner(owner), m_name(name) + { + m_updateTimer.setObjectName(name + ":timer"); + } + void CContinuousWorker::start(QThread::Priority priority) { BLACK_VERIFY_X(!hasStarted(), Q_FUNC_INFO, "Tried to start a worker that was already started"); @@ -137,6 +143,7 @@ namespace BlackMisc moveToThread(thread); connect(thread, &QThread::started, this, &CContinuousWorker::initialize); + connect(thread, &QThread::finished, &m_updateTimer, &QTimer::stop); connect(thread, &QThread::finished, this, &CContinuousWorker::cleanup); connect(thread, &QThread::finished, this, &CContinuousWorker::finish); thread->start(priority); @@ -146,6 +153,7 @@ namespace BlackMisc { Q_ASSERT_X(!CThreadUtils::isApplicationThreadObjectThread(this), Q_FUNC_INFO, "Try to stop main thread"); setEnabled(false); + // remark: cannot stop timer here, as I am normally not in the correct thread thread()->quit(); } @@ -158,6 +166,36 @@ namespace BlackMisc ownThread->wait(); } + void CContinuousWorker::startUpdating(int updateTimeSecs) + { + Q_ASSERT_X(hasStarted(), Q_FUNC_INFO, "Worker not yet started"); + if (!CThreadUtils::isCurrentThreadObjectThread(this)) + { + // shift in correct thread + if (!this->isFinished()) + { + QTimer::singleShot(0, this, [this, updateTimeSecs] + { + if (this->isFinished()) { return; } + this->startUpdating(updateTimeSecs); + }); + } + return; + } + + // here in correct timer thread + if (updateTimeSecs < 0) + { + setEnabled(false); + m_updateTimer.stop(); + } + else + { + setEnabled(true); + m_updateTimer.start(1000 * updateTimeSecs); + } + } + void CContinuousWorker::finish() { setFinished(); diff --git a/src/blackmisc/worker.h b/src/blackmisc/worker.h index bd3b74815..4e6639c18 100644 --- a/src/blackmisc/worker.h +++ b/src/blackmisc/worker.h @@ -52,7 +52,7 @@ namespace BlackMisc template void singleShot(int msec, QObject *target, F &&task) { - QSharedPointer timer(new QTimer, [](QObject *o) { QMetaObject::invokeMethod(o, "deleteLater"); }); + QSharedPointer timer(new QTimer, [](QObject * o) { QMetaObject::invokeMethod(o, "deleteLater"); }); timer->setSingleShot(true); timer->moveToThread(target->thread()); QObject::connect(timer.data(), &QTimer::timeout, target, [trace = getStackTrace(), task = std::forward(task), timer]() mutable @@ -75,7 +75,7 @@ namespace BlackMisc CRegularThread(QObject *parent = nullptr) : QThread(parent) {} //! Destructor - ~CRegularThread(); + virtual ~CRegularThread(); protected: //! \copydoc QThread::run @@ -149,7 +149,8 @@ namespace BlackMisc void doIfFinishedElse(F1 ifFunctor, F2 elseFunctor) const { QMutexLocker lock(&m_finishedMutex); - if (m_finished) { ifFunctor(); } else { elseFunctor(); } + if (m_finished) { ifFunctor(); } + else { elseFunctor(); } } //! Blocks until the task is finished. @@ -275,7 +276,7 @@ namespace BlackMisc * \param owner Will be the parent of the new thread (the worker has no parent). * \param name A name for the worker, which will be used to create a name for the thread. */ - CContinuousWorker(QObject *owner, const QString &name = "") : m_owner(owner), m_name(name) {} + CContinuousWorker(QObject *owner, const QString &name = ""); //! Starts a thread and moves the worker into it. void start(QThread::Priority priority = QThread::InheritPriority); @@ -297,6 +298,10 @@ namespace BlackMisc //! \threadsafe void setEnabled(bool enabled) { m_enabled = enabled; } + //! Start updating (start/stop timer) + //! \threadsafe + void startUpdating(int updateTimeSecs); + protected: //! Called when the thread is started. virtual void initialize() {} @@ -307,6 +312,8 @@ namespace BlackMisc //! Name of the worker const QString &getName() { return m_name; } + QTimer m_updateTimer { this }; //!< timer which can be used by implementing classes + private: //! Called after cleanup(). void finish();