From 741dd45f676faa94151f723776e07d5a72a52c39 Mon Sep 17 00:00:00 2001 From: Mat Sutcliffe Date: Tue, 26 Feb 2019 01:51:43 +0000 Subject: [PATCH] Issue #15 Added CActiveObserver and CActiveMutator These extend CPassiveObserver and CPassiveMutator with a one-to-many request/reply pattern. --- src/blackmisc/sharedstate/activemutator.cpp | 22 ++++++++ src/blackmisc/sharedstate/activemutator.h | 56 +++++++++++++++++++ src/blackmisc/sharedstate/activeobserver.cpp | 35 ++++++++++++ src/blackmisc/sharedstate/activeobserver.h | 58 ++++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 src/blackmisc/sharedstate/activemutator.cpp create mode 100644 src/blackmisc/sharedstate/activemutator.h create mode 100644 src/blackmisc/sharedstate/activeobserver.cpp create mode 100644 src/blackmisc/sharedstate/activeobserver.h diff --git a/src/blackmisc/sharedstate/activemutator.cpp b/src/blackmisc/sharedstate/activemutator.cpp new file mode 100644 index 000000000..25dd4f5ea --- /dev/null +++ b/src/blackmisc/sharedstate/activemutator.cpp @@ -0,0 +1,22 @@ +/* Copyright (C) 2017 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +//! \file + +#include "blackmisc/sharedstate/activemutator.h" + +namespace BlackMisc +{ + namespace SharedState + { + QFuture CActiveMutator::handleRequest(const CVariant& param) const + { + return m_requestHandler(param); + } + } +} diff --git a/src/blackmisc/sharedstate/activemutator.h b/src/blackmisc/sharedstate/activemutator.h new file mode 100644 index 000000000..b6aeb10d4 --- /dev/null +++ b/src/blackmisc/sharedstate/activemutator.h @@ -0,0 +1,56 @@ +/* Copyright (C) 2017 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_SHAREDSTATE_ACTIVEMUTATOR_H +#define BLACKMISC_SHAREDSTATE_ACTIVEMUTATOR_H + +#include "blackmisc/sharedstate/passivemutator.h" +#include "blackmisc/variant.h" +#include "blackmisc/blackmiscexport.h" +#include +#include +#include + +namespace BlackMisc +{ + namespace SharedState + { + /*! + * Extends CPassiveMutator with the ability to respond to requests. + */ + class BLACKMISC_EXPORT CActiveMutator final : public CPassiveMutator + { + Q_OBJECT + friend QSharedPointer; + + template + CActiveMutator(T *parent, F requestHandler) : + CPassiveMutator(parent), + m_requestHandler([ = ](const CVariant ¶m) { return Private::invokeMethod(parent, requestHandler, param); }) + {} + + public: + //! Factory method. + template + static auto create(T *parent, F requestHandler) { return QSharedPointer::create(parent, requestHandler); } + + //! Respond to a request and return a reply. + QFuture handleRequest(const CVariant& param) const; + + //! Get a QWeakPointer pointing to this object. + QWeakPointer weakRef() const { return qSharedPointerCast(CPassiveMutator::weakRef()); } + + private: + const std::function(const CVariant &)> m_requestHandler; + }; + } +} + +#endif diff --git a/src/blackmisc/sharedstate/activeobserver.cpp b/src/blackmisc/sharedstate/activeobserver.cpp new file mode 100644 index 000000000..9d0110113 --- /dev/null +++ b/src/blackmisc/sharedstate/activeobserver.cpp @@ -0,0 +1,35 @@ +/* Copyright (C) 2017 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +//! \file + +#include "blackmisc/sharedstate/activeobserver.h" + +namespace BlackMisc +{ + namespace SharedState + { + CVariant CActiveObserver::request(const CVariant ¶m) + { + CPromise promise; + emit requestPosted(param, promise); + return promise.future().result(); + } + + void CActiveObserver::requestAsync(const CVariant ¶m, std::function callback) + { + CPromise promise; + emit requestPosted(param, promise); + doAfter(promise.future(), this, [callback = std::move(callback), weakRef = weakRef()](const CVariant &reply) + { + const auto lock = weakRef.lock(); + if (lock) { callback(reply); } + }); + } + } +} diff --git a/src/blackmisc/sharedstate/activeobserver.h b/src/blackmisc/sharedstate/activeobserver.h new file mode 100644 index 000000000..abc7df3ca --- /dev/null +++ b/src/blackmisc/sharedstate/activeobserver.h @@ -0,0 +1,58 @@ +/* Copyright (C) 2017 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_SHAREDSTATE_ACTIVEOBSERVER_H +#define BLACKMISC_SHAREDSTATE_ACTIVEOBSERVER_H + +#include "blackmisc/sharedstate/passiveobserver.h" +#include "blackmisc/promise.h" +#include "blackmisc/variant.h" +#include "blackmisc/blackmiscexport.h" +#include +#include + +namespace BlackMisc +{ + namespace SharedState + { + /*! + * Extends CPassiveObserver with the ability to send requests and receive replies. + */ + class BLACKMISC_EXPORT CActiveObserver final : public CPassiveObserver + { + Q_OBJECT + friend QSharedPointer; + + template + CActiveObserver(T *parent, F eventHandler) : CPassiveObserver(parent, eventHandler) {} + + public: + //! Factory method. + template + static auto create(T *parent, F eventHandler) { return QSharedPointer::create(parent, eventHandler); } + + //! Send a request and receive a synchronous reply. + CVariant request(const CVariant ¶m); + + //! Send a request and receive an asynchronous reply. + //! The callback will not be called if the reply is received after the observer has been destroyed. + void requestAsync(const CVariant ¶m, std::function callback); + + //! Get a QWeakPointer pointing to this object. + QWeakPointer weakRef() const { return qSharedPointerCast(CPassiveObserver::weakRef()); } + + signals: + //! Emitted by request and requestAsync. + void requestPosted(const CVariant ¶m, BlackMisc::CPromise o_reply); + }; + } +} + +#endif