diff --git a/src/blackmisc/connectionguard.h b/src/blackmisc/connectionguard.h index ebf0397dd..cf6ab8b66 100644 --- a/src/blackmisc/connectionguard.h +++ b/src/blackmisc/connectionguard.h @@ -25,10 +25,8 @@ namespace BlackMisc * be disconnected when the object is destroyed. So it can be used with lambdas or bind which feature * non QObjects, if those might be destroyed before the signaling QObject. */ - class BLACKMISC_EXPORT CConnectionGuard : public QObject + class BLACKMISC_EXPORT CConnectionGuard { - Q_OBJECT - public: //! Constructor CConnectionGuard() = default; @@ -36,6 +34,18 @@ namespace BlackMisc //! Constructor CConnectionGuard(const QMetaObject::Connection &connection); + //! Move constructor + CConnectionGuard(CConnectionGuard &&) = default; + + //! Move assignment operator + CConnectionGuard &operator =(CConnectionGuard &&) = default; + + //! Not copyable + //! @{ + CConnectionGuard(const CConnectionGuard &) = delete; + CConnectionGuard &operator =(const CConnectionGuard &) = delete; + //! @} + //! Destructor ~CConnectionGuard(); diff --git a/src/blackmisc/worker.h b/src/blackmisc/worker.h index 276b15f86..8bd035360 100644 --- a/src/blackmisc/worker.h +++ b/src/blackmisc/worker.h @@ -13,6 +13,7 @@ #define BLACKMISC_WORKER_H #include "blackmisc/blackmiscexport.h" +#include "blackmisc/connectionguard.h" #include "blackmisc/logcategorylist.h" #include "blackmisc/invoke.h" #include "blackmisc/stacktrace.h" @@ -329,7 +330,7 @@ namespace BlackMisc { if (!ptr || static_cast(ptr)->hasStarted()) { return; } m_strong.reset(ptr); - QObject::connect(ptr, &CWorkerBase::aboutToStart, [this] { m_strong.release(); }); + connect(); } //! Construct a null pointer. @@ -338,6 +339,27 @@ namespace BlackMisc CWorkerPointer(std::nullptr_t) {} //! @} + //! Move constructor. + CWorkerPointer(CWorkerPointer &&other) : m_strong(std::move(other.m_strong)), m_weak(other.m_weak), m_guard() + { + connect(); + } + + //! Move assignment operator. + CWorkerPointer &operator =(CWorkerPointer &&other) + { + m_strong = std::move(other.m_strong); + m_weak = other.m_weak; + connect(); + return *this; + } + + //! Not copyable. + //! @{ + CWorkerPointer(const CWorkerPointer &) = delete; + CWorkerPointer &operator =(const CWorkerPointer &) = delete; + //! @} + //! Factory method. //! Arguments are forwarded to the constructor of T. Strictly more exception-safe than calling the constructor with new. template @@ -360,8 +382,15 @@ namespace BlackMisc bool isOwner() const { return m_strong; } private: + void connect() + { + if (!m_strong) { return; } + m_guard = QObject::connect(m_strong.get(), &CWorkerBase::aboutToStart, [this] { m_strong.release(); }); + } + std::unique_ptr m_strong; QPointer m_weak; + CConnectionGuard m_guard; }; }