diff --git a/src/blackmisc/blackmisc.h b/src/blackmisc/blackmisc.h index e47c80df1..ceddc4ab4 100644 --- a/src/blackmisc/blackmisc.h +++ b/src/blackmisc/blackmisc.h @@ -27,6 +27,11 @@ * \brief Classes related to configuration settings. */ +/*! + * \namespace BlackMisc::SharedState + * \brief Utilities for sharing state between multiple objects. + */ + /*! * \namespace BlackMisc::Predicates * \brief Functor classes for evaluating predicate calculus expressions. diff --git a/src/blackmisc/blackmisc.pro b/src/blackmisc/blackmisc.pro index cb1c0399c..475ab64d0 100644 --- a/src/blackmisc/blackmisc.pro +++ b/src/blackmisc/blackmisc.pro @@ -38,6 +38,7 @@ HEADERS += *.h \ $$files($$PWD/network/settings/*.h) \ $$files($$PWD/network/external/*.h) \ $$files($$PWD/pq/*.h) \ + $$files($$PWD/sharedstate/*.h) \ $$files($$PWD/simulation/*.h) \ $$files($$PWD/simulation/data/*.h) \ $$files($$PWD/simulation/settings/*.h) \ @@ -61,6 +62,7 @@ SOURCES += *.cpp \ $$files($$PWD/network/settings/*.cpp) \ $$files($$PWD/network/external/*.cpp) \ $$files($$PWD/pq/*.cpp) \ + $$files($$PWD/sharedstate/*.cpp) \ $$files($$PWD/simulation/*.cpp) \ $$files($$PWD/simulation/data/*.cpp) \ $$files($$PWD/simulation/settings/*.cpp) \ diff --git a/src/blackmisc/registermetadata.cpp b/src/blackmisc/registermetadata.cpp index a9893a3c8..75f544e60 100644 --- a/src/blackmisc/registermetadata.cpp +++ b/src/blackmisc/registermetadata.cpp @@ -17,6 +17,7 @@ #include "blackmisc/geo/registermetadatageo.h" #include "blackmisc/pq/registermetadatapq.h" +#include "blackmisc/sharedstate/passiveobserver.h" #include "blackmisc/applicationinfolist.h" #include "blackmisc/countrylist.h" #include "blackmisc/crashsettings.h" @@ -100,6 +101,8 @@ namespace BlackMisc Settings::CCrashSettings::registerMetadata(); Weather::registerMetadata(); + SharedState::CAnyMatch::registerMetadata(); + // needed by XSwiftBus proxy class qDBusRegisterMetaType>(); qRegisterMetaTypeStreamOperators>(); diff --git a/src/blackmisc/sharedstate/passivemutator.cpp b/src/blackmisc/sharedstate/passivemutator.cpp new file mode 100644 index 000000000..d94ea8169 --- /dev/null +++ b/src/blackmisc/sharedstate/passivemutator.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/passivemutator.h" + +namespace BlackMisc +{ + namespace SharedState + { + void CPassiveMutator::postEvent(const CVariant ¶m) + { + emit eventPosted(param); + } + } +} diff --git a/src/blackmisc/sharedstate/passivemutator.h b/src/blackmisc/sharedstate/passivemutator.h new file mode 100644 index 000000000..f3af23bc3 --- /dev/null +++ b/src/blackmisc/sharedstate/passivemutator.h @@ -0,0 +1,53 @@ +/* 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_PASSIVEMUTATOR_H +#define BLACKMISC_SHAREDSTATE_PASSIVEMUTATOR_H + +#include "blackmisc/variant.h" +#include "blackmisc/blackmiscexport.h" +#include +#include + +namespace BlackMisc +{ + namespace SharedState + { + class CActiveMutator; + + /*! + * Endpoint which can emit events to subscribers. + */ + class BLACKMISC_EXPORT CPassiveMutator : public QObject, public QEnableSharedFromThis + { + Q_OBJECT + friend CActiveMutator; + friend QSharedPointer; + + CPassiveMutator(QObject* parent) : QObject(parent) {} + + public: + //! Factory method. + static auto create(QObject *parent) { return QSharedPointer::create(parent); } + + //! Emit an event. + void postEvent(const CVariant ¶m); + + //! Get a QWeakPointer pointing to this object. + QWeakPointer weakRef() const { return sharedFromThis(); } + + signals: + //! Emitted by postEvent. + void eventPosted(const BlackMisc::CVariant ¶m); + }; + } +} + +#endif diff --git a/src/blackmisc/sharedstate/passiveobserver.cpp b/src/blackmisc/sharedstate/passiveobserver.cpp new file mode 100644 index 000000000..186766865 --- /dev/null +++ b/src/blackmisc/sharedstate/passiveobserver.cpp @@ -0,0 +1,36 @@ +/* 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/passiveobserver.h" + +namespace BlackMisc +{ + namespace SharedState + { + void CPassiveObserver::setEventSubscription(const CVariant ¶m) + { + QMutexLocker lock(&m_eventSubscriptionMutex); + m_eventSubscription = param; + lock.unlock(); + emit eventSubscriptionChanged(param); + } + + CVariant CPassiveObserver::eventSubscription() const + { + QMutexLocker lock(&m_eventSubscriptionMutex); + return m_eventSubscription; + } + + void CPassiveObserver::handleEvent(const CVariant& param) const + { + m_eventHandler(param); + } + } +} diff --git a/src/blackmisc/sharedstate/passiveobserver.h b/src/blackmisc/sharedstate/passiveobserver.h new file mode 100644 index 000000000..f81691c3e --- /dev/null +++ b/src/blackmisc/sharedstate/passiveobserver.h @@ -0,0 +1,92 @@ +/* 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_PASSIVEOBSERVER_H +#define BLACKMISC_SHAREDSTATE_PASSIVEOBSERVER_H + +#include "blackmisc/variant.h" +#include "blackmisc/valueobject.h" +#include "blackmisc/blackmiscexport.h" +#include +#include +#include + +namespace BlackMisc +{ + namespace SharedState + { + class CActiveObserver; + + /*! + * Endpoint which can subscribe to events emitted by CPassiveMutator. + */ + class BLACKMISC_EXPORT CPassiveObserver : public QObject, public QEnableSharedFromThis + { + Q_OBJECT + friend CActiveObserver; + friend QSharedPointer; + + template + CPassiveObserver(T *parent, F eventHandler) : + QObject(parent), + m_eventHandler([ = ](const CVariant ¶m) { Private::invokeMethod(parent, eventHandler, param); }) + {} + + public: + //! Factory method. + template + static auto create(T *parent, F eventHandler) { return QSharedPointer::create(parent, eventHandler); } + + //! Set the object that determines which events are subscribed to. + void setEventSubscription(const CVariant ¶m); + + //! Get the object that determines which events are subscribed to. + CVariant eventSubscription() const; + + //! Called when a subscribed event is emitted. + void handleEvent(const CVariant& param) const; + + //! Get a QWeakPointer pointing to this object. + QWeakPointer weakRef() const { return sharedFromThis(); } + + signals: + //! Emitted by setEventSubscription. + void eventSubscriptionChanged(const BlackMisc::CVariant ¶m); + + private: + const std::function m_eventHandler; + + mutable QMutex m_eventSubscriptionMutex; + CVariant m_eventSubscription; + }; + + /*! + * Dummy value class that matches any event. + */ + class BLACKMISC_EXPORT CAnyMatch : public CValueObject + { + public: + //! Returns true. + bool matches(const CVariant &) const { return true; } + + //! To string. + QString convertToQString(bool = false) const { return QStringLiteral("any"); } + + private: + int m_dummy = 0; + + BLACK_METACLASS(CAnyMatch, BLACK_METAMEMBER(dummy)); + }; + } +} + +Q_DECLARE_METATYPE(BlackMisc::SharedState::CAnyMatch) + +#endif