8#include <QDBusConnection>
9#include <QDBusServiceWatcher>
18using namespace swift::misc::shared_state::dbus;
25 m_watchTimer.setInterval(1000);
34 Q_ASSERT_X(!m_hub, Q_FUNC_INFO,
"Already initialized");
42 Q_ASSERT_X(!m_hub, Q_FUNC_INFO,
"Already initialized");
43 m_hub =
IHub::create(
true,
nullptr, connection, service,
this);
48 void CDataLinkDBus::checkConnection()
60 void CDataLinkDBus::onConnected()
68 std::tie(m_duplex, ready) = m_hub->getDuplex(m_identifier);
72 doAfter(ready, m_duplex.get(), [
this] {
73 m_duplex->requestPeerSubscriptions();
74 announceLocalSubscriptions();
75 setConnectionStatus(true);
79 void CDataLinkDBus::onDisconnected()
85 void CDataLinkDBus::handleLocalEvent(
const QString &channel,
const CVariant ¶m)
87 handlePeerEvent(channel, param);
94 for (
const auto &filter : std::as_const(getChannel(channel).peerSubscriptions))
98 m_duplex->postEvent(channel, param);
104 void CDataLinkDBus::handlePeerEvent(
const QString &channel,
const CVariant ¶m)
106 for (
const auto &observerWeak : std::as_const(getChannel(channel).passiveObservers))
108 auto observer = observerWeak.lock();
109 if (observer && observer->eventSubscription().matches(param))
111 observer->handleEvent(param);
116 void CDataLinkDBus::announceLocalSubscriptions()
118 for (
const auto &channel : getChannelNames())
120 announceLocalSubscriptions(channel);
124 void CDataLinkDBus::announceLocalSubscriptions(
const QString &channel)
126 CVariantList filters;
127 for (
const auto &observerWeak : std::as_const(getChannel(channel).passiveObservers))
129 auto observer = observerWeak.lock();
132 filters.
push_back(observer->eventSubscription());
135 m_duplex->setSubscription(channel, filters);
138 void CDataLinkDBus::setPeerSubscriptions(
const QString &channel,
const CVariantList &filters)
140 getChannel(channel).peerSubscriptions = filters;
143 QFuture<CVariant> CDataLinkDBus::handleLocalRequest(
const QString &channel,
const CVariant ¶m)
145 auto mutator = getChannel(channel).activeMutator.lock();
148 return mutator->handleRequest(param);
156 return m_duplex->submitRequest(channel, param);
159 void CDataLinkDBus::handlePeerRequest(
const QString &channel,
const CVariant ¶m, quint32 token)
161 auto mutator = getChannel(channel).activeMutator.lock();
164 doAfter(mutator->handleRequest(param),
this, [
this, token](
auto future) {
167 m_duplex->reply(future.result(), token);
183 auto &channel = getChannel(mutator);
184 Q_ASSERT_X(!channel.activeMutator, Q_FUNC_INFO,
"Tried to publish two active mutators on one channel");
185 channel.activeMutator = mutator->
weakRef();
194 m_duplex->withdraw(channel);
201 getChannel(observer).passiveObservers.push_back(observer->
weakRef());
206 announceLocalSubscriptions(channel);
220 reply.
chainResult(handleLocalRequest(channel, param));
227 return m_channels.keys();
230 CDataLinkDBus::Channel &CDataLinkDBus::getChannel(
const QString &name)
233 return m_channels[name];
236 CDataLinkDBus::Channel &CDataLinkDBus::getChannel(
const QObject *
object)
238 return getChannel(getChannelName(
object));
Value object encapsulating information identifying a component of a modular distributed swift process...
A promise-based interface to QFuture, similar to std::promise for std::future.
void chainResult(QFuture< U > future)
When the given future is ready, use its result to set the result of this promise.
void push_back(const T &value)
Appends an element at the end of the sequence.
Wrapper around QVariant which provides transparent access to CValueObject methods of the contained ob...
Extends CPassiveMutator with the ability to respond to requests.
QWeakPointer< const CActiveMutator > weakRef() const
Get a QWeakPointer pointing to this object.
Extends CPassiveObserver with the ability to send requests and receive replies.
void requestPosted(const swift::misc::CVariant ¶m, swift::misc::CPromise< swift::misc::CVariant > o_reply)
Emitted by request and requestAsync.
void subscribe(const CPassiveObserver *observer)
Register an observer with this transport mechanism.
void publish(const CPassiveMutator *mutator)
Register a mutator with this transport mechanism.
void initializeRemote(const QDBusConnection &connection, const QString &service)
Initialize on client side.
void initializeLocal(CDBusServer *server=nullptr)
Initialize on server side.
void overrideIdentifier(const CIdentifier &)
Override identifier for testing purposes.
~CDataLinkDBus()
Destructor.
CDataLinkDBus(QObject *parent=nullptr)
Constructor.
Endpoint which can emit events to subscribers.
void eventPosted(const swift::misc::CVariant ¶m)
Emitted by postEvent.
Endpoint which can subscribe to events emitted by CPassiveMutator.
QWeakPointer< const CPassiveObserver > weakRef() const
Get a QWeakPointer pointing to this object.
void eventSubscriptionChanged(const swift::misc::CVariant ¶m)
Emitted by setEventSubscription.
static QString getChannelName(const QObject *object)
Get the channel name for child endpoints of the given object.
void setConnectionStatus(bool connected)
Set the connection status visible through the watcher.
void requestReceived(const QString &channel, const swift::misc::CVariant ¶m, quint32 token, QPrivateSignal)
Server has submitted a request to be handled by the client.
void eventPosted(const QString &channel, const swift::misc::CVariant ¶m)
Server has notified the client that an event has been posted.
void peerSubscriptionsReceived(const QString &channel, const swift::misc::CVariantList &filters)
Server has notified the client that other clients' event subscriptions have changed.
virtual bool isConnected() const =0
Is connected?
static IHub * create(bool proxy, CDBusServer *server, const QDBusConnection &connection, const QString &service, QObject *parent=nullptr)
Construct a new hub.
Utilities for sharing state between multiple objects.
void doAfter(QFuture< T > future, QObject *context, F &&func)
Connect a slot or function to be invoked in the given context when a QFuture is finished.
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void destroyed(QObject *obj)
QObject * parent() const const
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)