Issue #15 Added CActiveObserver and CActiveMutator

These extend CPassiveObserver and CPassiveMutator with a one-to-many request/reply pattern.
This commit is contained in:
Mat Sutcliffe
2019-02-26 01:51:43 +00:00
parent 333804a0e6
commit 741dd45f67
4 changed files with 171 additions and 0 deletions

View File

@@ -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<CVariant> CActiveMutator::handleRequest(const CVariant& param) const
{
return m_requestHandler(param);
}
}
}

View File

@@ -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 <QObject>
#include <QFuture>
#include <functional>
namespace BlackMisc
{
namespace SharedState
{
/*!
* Extends CPassiveMutator with the ability to respond to requests.
*/
class BLACKMISC_EXPORT CActiveMutator final : public CPassiveMutator
{
Q_OBJECT
friend QSharedPointer<CActiveMutator>;
template <typename T, typename F>
CActiveMutator(T *parent, F requestHandler) :
CPassiveMutator(parent),
m_requestHandler([ = ](const CVariant &param) { return Private::invokeMethod(parent, requestHandler, param); })
{}
public:
//! Factory method.
template <typename T, typename F>
static auto create(T *parent, F requestHandler) { return QSharedPointer<CActiveMutator>::create(parent, requestHandler); }
//! Respond to a request and return a reply.
QFuture<CVariant> handleRequest(const CVariant& param) const;
//! Get a QWeakPointer pointing to this object.
QWeakPointer<const CActiveMutator> weakRef() const { return qSharedPointerCast<const CActiveMutator>(CPassiveMutator::weakRef()); }
private:
const std::function<QFuture<CVariant>(const CVariant &)> m_requestHandler;
};
}
}
#endif

View File

@@ -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 &param)
{
CPromise<CVariant> promise;
emit requestPosted(param, promise);
return promise.future().result();
}
void CActiveObserver::requestAsync(const CVariant &param, std::function<void(const CVariant &)> callback)
{
CPromise<CVariant> 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); }
});
}
}
}

View File

@@ -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 <QObject>
#include <QSharedPointer>
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<CActiveObserver>;
template <typename T, typename F>
CActiveObserver(T *parent, F eventHandler) : CPassiveObserver(parent, eventHandler) {}
public:
//! Factory method.
template <typename T, typename F>
static auto create(T *parent, F eventHandler) { return QSharedPointer<CActiveObserver>::create(parent, eventHandler); }
//! Send a request and receive a synchronous reply.
CVariant request(const CVariant &param);
//! 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 &param, std::function<void(const CVariant &)> callback);
//! Get a QWeakPointer pointing to this object.
QWeakPointer<const CActiveObserver> weakRef() const { return qSharedPointerCast<const CActiveObserver>(CPassiveObserver::weakRef()); }
signals:
//! Emitted by request and requestAsync.
void requestPosted(const CVariant &param, BlackMisc::CPromise<BlackMisc::CVariant> o_reply);
};
}
}
#endif