Move DBus event processing from DBusConnection to DBusDispatcher

ref T291
This commit is contained in:
Roland Winklmeier
2018-07-26 22:26:45 +02:00
committed by Klaus Basan
parent 59da68da5e
commit a764fa0d03
6 changed files with 414 additions and 316 deletions

View File

@@ -19,137 +19,21 @@
namespace XSwiftBus
{
//! Functor struct deleteing an event
struct EventDeleter
{
//! Delete functor
void operator()(event *obj) const
{
event_del(obj);
event_free(obj);
}
};
//! DBus watch handler
class WatchHandler
{
public:
//! Constructor
WatchHandler(CDBusConnection *parent, DBusWatch *watch)
: m_parent(parent), m_watch(watch)
{
const unsigned int flags = dbus_watch_get_flags(watch);
short monitoredEvents = EV_PERSIST;
if (flags & DBUS_WATCH_READABLE) { monitoredEvents |= EV_READ; }
if (flags & DBUS_WATCH_WRITABLE) { monitoredEvents |= EV_WRITE; }
const int fd = dbus_watch_get_unix_fd(watch);
m_event.reset(event_new(parent->m_eventBase.get(), fd, monitoredEvents, callback, this));
event_add(m_event.get(), nullptr);
}
//! Get DBus watch
DBusWatch *getWatch() { return m_watch; }
//! Get DBus watch
const DBusWatch *getWatch() const { return m_watch; }
private:
//! Event callback
static void callback(evutil_socket_t fd, short event, void *data)
{
auto *watchHandler = static_cast<WatchHandler *>(data);
watchHandler->m_parent->handleSocketReady(fd, event);
}
CDBusConnection *m_parent = nullptr;
std::unique_ptr<event, EventDeleter> m_event;
DBusWatch *m_watch = nullptr;
};
//! DBus timeout handler
class TimeoutHandler
{
public:
//! Constructor
TimeoutHandler(CDBusConnection *parent, DBusTimeout *timeout)
: m_timeout(timeout)
{
timeval timer;
const int interval = dbus_timeout_get_interval(timeout);
timer.tv_sec = interval / 1000;
timer.tv_usec = (interval % 1000) * 1000;
m_event.reset(evtimer_new(parent->m_eventBase.get(), callback, this));
evtimer_add(m_event.get(), &timer);
}
//! Get DBus timeout
const DBusTimeout *getTimeout() const { return m_timeout; }
private:
//! Event callback
static void callback(evutil_socket_t fd, short event, void *data)
{
(void) fd; // unused
(void) event; // unused
auto *timeoutHandler = static_cast<TimeoutHandler *>(data);
dbus_timeout_handle(timeoutHandler->m_timeout);
}
std::unique_ptr<event, EventDeleter> m_event;
DBusTimeout *m_timeout = nullptr;
};
//! Generic Timer
class Timer
{
public:
Timer() = default;
//! Constructor
Timer(CDBusConnection *parent, const timeval &timeout, const std::function<void()> &func)
: m_func(func)
{
m_event.reset(evtimer_new(parent->m_eventBase.get(), callback, this));
evtimer_add(m_event.get(), &timeout);
}
private:
//! Event callback
static void callback(evutil_socket_t fd, short event, void *data)
{
(void) fd; // unused
(void) event; // unused
auto *timer = static_cast<Timer *>(data);
timer->m_func();
delete timer;
}
std::unique_ptr<event, EventDeleter> m_event;
std::function<void()> m_func;
};
CDBusConnection::CDBusConnection()
: m_eventBase(event_base_new())
{
dbus_threads_init_default();
using namespace std::placeholders;
m_watchCallbacks = WatchCallbacks(std::bind(&CDBusConnection::dbusAddWatch, this, _1),
std::bind(&CDBusConnection::dbusRemoveWatch, this, _1),
std::bind(&CDBusConnection::dbusWatchToggled, this, _1));
}
m_timeoutCallbacks = TimeoutCallbacks(std::bind(&CDBusConnection::dbusAddTimeout, this, _1),
std::bind(&CDBusConnection::dbusRemoveTimeout, this, _1),
std::bind(&CDBusConnection::dbusTimeoutToggled, this, _1));
}
CDBusConnection::~CDBusConnection()
{
close();
if (m_connection) { dispatch(); }
if (m_dispatcher) { m_dispatcher->remove(this); }
}
bool CDBusConnection::connect(BusType type, const std::string &service)
bool CDBusConnection::connect(BusType type)
{
assert(type == SessionBus);
DBusError error;
@@ -170,23 +54,39 @@ namespace XSwiftBus
// Don't exit application, if the connection is disconnected
dbus_connection_set_exit_on_disconnect(m_connection.get(), false);
if (!setupMainloop())
{
m_connection.release();
return false;
}
dbus_bus_request_name(m_connection.get(), service.c_str(), 0, &error);
if (dbus_error_is_set(&error))
{
m_lastError = CDBusError(&error);
return false;
}
return true;
}
void CDBusConnection::setDispatcher(CDBusDispatcher *dispatcher)
{
assert(dispatcher);
m_dispatcher = dispatcher;
m_dispatcher->add(this);
dbus_connection_set_watch_functions(
m_connection.get(),
dispatcher->m_watchCallbacks.add,
dispatcher->m_watchCallbacks.remove,
dispatcher->m_watchCallbacks.toggled,
&dispatcher->m_watchCallbacks, nullptr);
dbus_connection_set_timeout_functions(
m_connection.get(),
dispatcher->m_timeoutCallbacks.add,
dispatcher->m_timeoutCallbacks.remove,
dispatcher->m_timeoutCallbacks.toggled,
&dispatcher->m_timeoutCallbacks, nullptr);
}
void CDBusConnection::requestName(const std::string &name)
{
DBusError error;
dbus_error_init(&error);
dbus_bus_request_name(m_connection.get(), name.c_str(), 0, &error);
}
bool CDBusConnection::isConnected() const
{
return static_cast<bool>(m_connection);
@@ -212,155 +112,35 @@ namespace XSwiftBus
if (m_connection) { dbus_connection_close(m_connection.get()); }
}
void CDBusConnection::runEventLoop()
void CDBusConnection::dispatch()
{
if (!m_eventBase || !isConnected()) { return; }
event_base_loop(m_eventBase.get(), EVLOOP_NONBLOCK);
}
void CDBusConnection::runBlockingEventLoop()
{
if (!m_eventBase || !isConnected()) { return; }
event_base_dispatch(m_eventBase.get());
}
bool CDBusConnection::setupMainloop()
{
DBusDispatchStatus status;
if (dbus_connection_set_watch_functions(
m_connection.get(),
m_watchCallbacks.add,
m_watchCallbacks.remove,
m_watchCallbacks.toggled,
&m_watchCallbacks, nullptr) == FALSE)
{
return false;
}
if (dbus_connection_set_timeout_functions(
m_connection.get(),
m_timeoutCallbacks.add,
m_timeoutCallbacks.remove,
m_timeoutCallbacks.toggled,
&m_timeoutCallbacks, nullptr) == FALSE)
{
return false;
}
dbus_connection_set_dispatch_status_function(
m_connection.get(),
dbusUpdateDispatchStatus,
this, nullptr);
status = dbus_connection_get_dispatch_status(m_connection.get());
if (status == DBUS_DISPATCH_DATA_REMAINS) { scheduleDBusDispatch(); }
return true;
}
dbus_bool_t CDBusConnection::dbusAddWatch(DBusWatch *watch)
{
if (dbus_watch_get_enabled(watch) == FALSE) { return true; }
int fd = dbus_watch_get_unix_fd(watch);
m_watchers.emplace(fd, std::make_unique<WatchHandler>(this, watch));
return true;
}
void CDBusConnection::dbusRemoveWatch(DBusWatch *watch)
{
for (auto it = m_watchers.begin(); it != m_watchers.end();)
{
if (it->second->getWatch() == watch) { it = m_watchers.erase(it); }
else { ++it; }
}
}
void CDBusConnection::dbusWatchToggled(DBusWatch *watch)
{
if (dbus_watch_get_enabled(watch) == TRUE) { dbusAddWatch(watch); }
else { dbusRemoveWatch(watch); }
}
dbus_bool_t CDBusConnection::dbusAddTimeout(DBusTimeout *timeout)
{
if (dbus_timeout_get_enabled(timeout) == FALSE) { return TRUE; }
m_timeouts.emplace(m_timeouts.end(), std::make_unique<TimeoutHandler>(this, timeout));
return true;
}
void CDBusConnection::dbusRemoveTimeout(DBusTimeout *timeout)
{
auto predicate = [timeout](const std::unique_ptr<TimeoutHandler> &ptr)
{
return ptr->getTimeout() == timeout;
};
m_timeouts.erase(std::remove_if(m_timeouts.begin(), m_timeouts.end(), predicate), m_timeouts.end());
}
void CDBusConnection::dbusTimeoutToggled(DBusTimeout *timeout)
{
if (dbus_timeout_get_enabled(timeout) == TRUE)
dbusAddTimeout(timeout);
else
dbusRemoveTimeout(timeout);
}
void CDBusConnection::scheduleDBusDispatch()
{
const timeval timeout = {0, 0};
// This is no memory leak. The allocated timer will be deleted in its own callback
new Timer(this, timeout, [this]() { dbusDispatch(); });
}
void CDBusConnection::handleSocketReady(evutil_socket_t fd, short event)
{
DBusDispatchStatus status;
unsigned int flags = 0;
auto watcher = m_watchers.find(fd);
if (watcher == m_watchers.end()) { return; }
dbus_connection_ref(m_connection.get());
if (evutil_socket_geterror(fd) != 0) { flags |= DBUS_WATCH_ERROR; }
if (event & EV_READ) { flags |= DBUS_WATCH_READABLE; }
if (event & EV_WRITE) { flags |= DBUS_WATCH_WRITABLE; }
dbus_watch_handle(watcher->second->getWatch(), flags);
status = dbus_connection_get_dispatch_status(m_connection.get());
if (status == DBUS_DISPATCH_DATA_REMAINS) { dbusDispatch(); }
if (dbus_connection_get_dispatch_status(m_connection.get()) == DBUS_DISPATCH_DATA_REMAINS)
{
while (dbus_connection_dispatch(m_connection.get()) == DBUS_DISPATCH_DATA_REMAINS);
}
dbus_connection_unref(m_connection.get());
}
void CDBusConnection::dbusDispatch()
void CDBusConnection::setDispatchStatus(DBusConnection *connection, DBusDispatchStatus status)
{
dbus_connection_ref(m_connection.get());
while (dbus_connection_dispatch(m_connection.get()) == DBUS_DISPATCH_DATA_REMAINS);
dbus_connection_unref(m_connection.get());
}
void CDBusConnection::dbusUpdateDispatchStatus(DBusConnection *connection, DBusDispatchStatus newStatus)
{
(void)newStatus; // unused
DBusDispatchStatus status;
if (dbus_connection_get_is_connected(connection) == FALSE) { return; }
status = dbus_connection_get_dispatch_status(connection);
if (status == DBUS_DISPATCH_DATA_REMAINS) { scheduleDBusDispatch(); }
switch (status)
{
case DBUS_DISPATCH_DATA_REMAINS:
//m_dispatcher->add(this);
break;
case DBUS_DISPATCH_COMPLETE:
case DBUS_DISPATCH_NEED_MEMORY:
break;
}
}
void CDBusConnection::dbusUpdateDispatchStatus(DBusConnection *connection, DBusDispatchStatus newStatus, void *data)
void CDBusConnection::setDispatchStatus(DBusConnection *connection, DBusDispatchStatus status, void *data)
{
auto *obj = static_cast<CDBusConnection *>(data);
return obj->dbusUpdateDispatchStatus(connection, newStatus);
return obj->setDispatchStatus(connection, status);
}
}

View File

@@ -13,6 +13,7 @@
#include "dbusmessage.h"
#include "dbuserror.h"
#include "dbuscallbacks.h"
#include "dbusdispatcher.h"
#include <event2/event.h>
#include <dbus/dbus.h>
@@ -24,12 +25,10 @@
namespace XSwiftBus
{
class WatchHandler;
class TimeoutHandler;
class CDBusObject;
//! DBus connection
class CDBusConnection
class CDBusConnection : public IDispatchable
{
public:
//! Bus type
@@ -47,7 +46,13 @@ namespace XSwiftBus
CDBusConnection &operator=(const CDBusConnection &) = delete;
//! Connect to bus
bool connect(BusType type, const std::string &service);
bool connect(BusType type);
//! Set dispatcher
void setDispatcher(CDBusDispatcher *dispatcher);
//! Request name to the bus
void requestName(const std::string &name);
//! Is connected?
bool isConnected() const;
@@ -65,58 +70,24 @@ namespace XSwiftBus
//! Close connection
void close();
//! Run DBus event loop (non-blocking)
void runEventLoop();
//! Run DBus event loop (blocking)
void runBlockingEventLoop();
//! Get the last error
CDBusError lastError() const { return m_lastError; }
protected:
virtual void dispatch();
private:
friend class WatchHandler;
friend class TimeoutHandler;
friend class Timer;
using WatchCallbacks = DBusAsyncCallbacks<DBusWatch>;
using TimeoutCallbacks = DBusAsyncCallbacks<DBusTimeout>;
bool setupMainloop();
dbus_bool_t dbusAddWatch(DBusWatch *watch);
void dbusRemoveWatch(DBusWatch *watch);
void dbusWatchToggled(DBusWatch *watch);
dbus_bool_t dbusAddTimeout(DBusTimeout *timeout);
void dbusRemoveTimeout(DBusTimeout *timeout);
void dbusTimeoutToggled(DBusTimeout *timeout);
void scheduleDBusDispatch();
void handleSocketReady(evutil_socket_t fd, short event);
void dbusDispatch();
void dbusUpdateDispatchStatus(DBusConnection *connection, DBusDispatchStatus newStatus);
static void dbusUpdateDispatchStatus(DBusConnection *connection, DBusDispatchStatus newStatus, void *data);
struct EventBaseDeleter
{
void operator()(event_base *obj) const { event_base_free(obj); }
};
void setDispatchStatus(DBusConnection *connection, DBusDispatchStatus status);
static void setDispatchStatus(DBusConnection *connection, DBusDispatchStatus status, void *data);
struct DBusConnectionDeleter
{
void operator()(DBusConnection *obj) const { dbus_connection_unref(obj); }
};
std::unique_ptr<event_base, EventBaseDeleter> m_eventBase;
CDBusDispatcher *m_dispatcher = nullptr;
std::unique_ptr<DBusConnection, DBusConnectionDeleter> m_connection;
CDBusError m_lastError;
WatchCallbacks m_watchCallbacks;
TimeoutCallbacks m_timeoutCallbacks;
std::unordered_multimap<evutil_socket_t, std::unique_ptr<WatchHandler>> m_watchers;
std::vector<std::unique_ptr<TimeoutHandler>> m_timeouts;
};
}

View File

@@ -0,0 +1,236 @@
/* Copyright (C) 2018
* 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 and at http://www.swift-project.org/license.html. 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.
*/
#include "dbusdispatcher.h"
#include "dbusconnection.h"
#include <algorithm>
namespace XSwiftBus
{
//! Functor struct deleteing an event
struct EventDeleter
{
//! Delete functor
void operator()(event *obj) const
{
event_del(obj);
event_free(obj);
}
};
//! DBus watch handler
class WatchHandler
{
public:
//! Constructor
WatchHandler(event_base *base, DBusWatch *watch)
: m_base(base), m_watch(watch)
{
const unsigned int flags = dbus_watch_get_flags(watch);
short monitoredEvents = EV_PERSIST;
if (flags & DBUS_WATCH_READABLE) { monitoredEvents |= EV_READ; }
if (flags & DBUS_WATCH_WRITABLE) { monitoredEvents |= EV_WRITE; }
const int fd = dbus_watch_get_unix_fd(watch);
m_event.reset(event_new(m_base, fd, monitoredEvents, callback, this));
event_add(m_event.get(), nullptr);
}
//! Get DBus watch
DBusWatch *getWatch() { return m_watch; }
//! Get DBus watch
const DBusWatch *getWatch() const { return m_watch; }
private:
//! Event callback
static void callback(evutil_socket_t fd, short event, void *data)
{
(void) fd; // Not really unused, but GCC/Clang still complain about it.
auto *watchHandler = static_cast<WatchHandler *>(data);
unsigned int flags = 0;
if (evutil_socket_geterror(fd) != 0) { flags |= DBUS_WATCH_ERROR; }
if (event & EV_READ) { flags |= DBUS_WATCH_READABLE; }
if (event & EV_WRITE) { flags |= DBUS_WATCH_WRITABLE; }
dbus_watch_handle(watchHandler->m_watch, flags);
}
event_base *m_base = nullptr;
std::unique_ptr<event, EventDeleter> m_event;
DBusWatch *m_watch = nullptr;
};
//! DBus timeout handler
class TimeoutHandler
{
public:
//! Constructor
TimeoutHandler(event_base *base, DBusTimeout *timeout)
: m_base(base), m_timeout(timeout)
{
timeval timer;
const int interval = dbus_timeout_get_interval(timeout);
timer.tv_sec = interval / 1000;
timer.tv_usec = (interval % 1000) * 1000;
m_event.reset(evtimer_new(m_base, callback, this));
evtimer_add(m_event.get(), &timer);
}
//! Get DBus timeout
const DBusTimeout *getTimeout() const { return m_timeout; }
private:
//! Event callback
static void callback(evutil_socket_t fd, short event, void *data)
{
(void) fd; // unused
(void) event; // unused
auto *timeoutHandler = static_cast<TimeoutHandler *>(data);
dbus_timeout_handle(timeoutHandler->m_timeout);
}
event_base *m_base = nullptr;
std::unique_ptr<event, EventDeleter> m_event;
DBusTimeout *m_timeout = nullptr;
};
//! Generic Timer
class Timer
{
public:
Timer() = default;
//! Constructor
Timer(event_base *base, const timeval &timeout, const std::function<void()> &func)
: m_base(base), m_func(func)
{
m_event.reset(evtimer_new(m_base, callback, this));
evtimer_add(m_event.get(), &timeout);
}
private:
//! Event callback
static void callback(evutil_socket_t fd, short event, void *data)
{
(void) fd; // unused
(void) event; // unused
auto *timer = static_cast<Timer *>(data);
timer->m_func();
delete timer;
}
event_base *m_base = nullptr;
std::unique_ptr<event, EventDeleter> m_event;
std::function<void()> m_func;
};
CDBusDispatcher::CDBusDispatcher() :
m_eventBase(event_base_new())
{
using namespace std::placeholders;
m_watchCallbacks = WatchCallbacks(std::bind(&CDBusDispatcher::dbusAddWatch, this, _1),
std::bind(&CDBusDispatcher::dbusRemoveWatch, this, _1),
std::bind(&CDBusDispatcher::dbusWatchToggled, this, _1));
m_timeoutCallbacks = TimeoutCallbacks(std::bind(&CDBusDispatcher::dbusAddTimeout, this, _1),
std::bind(&CDBusDispatcher::dbusRemoveTimeout, this, _1),
std::bind(&CDBusDispatcher::dbusTimeoutToggled, this, _1));
}
CDBusDispatcher::~CDBusDispatcher()
{
}
void CDBusDispatcher::add(IDispatchable *dispatchable)
{
m_dispatchList.push_back(dispatchable);
}
void CDBusDispatcher::remove(IDispatchable *dispatchable)
{
auto it = std::find(m_dispatchList.begin(), m_dispatchList.end(), dispatchable);
if (it != m_dispatchList.end()) { m_dispatchList.erase(it); }
}
void CDBusDispatcher::waitAndRun()
{
if (!m_eventBase) { return; }
event_base_dispatch(m_eventBase.get());
}
void CDBusDispatcher::runOnce()
{
if (!m_eventBase) { return; }
event_base_loop(m_eventBase.get(), EVLOOP_NONBLOCK);
dispatch();
}
void CDBusDispatcher::dispatch()
{
if (m_dispatchList.empty()) { return; }
for (IDispatchable *dispatchable : m_dispatchList)
{
dispatchable->dispatch();
}
}
dbus_bool_t CDBusDispatcher::dbusAddWatch(DBusWatch *watch)
{
if (dbus_watch_get_enabled(watch) == FALSE) { return true; }
int fd = dbus_watch_get_unix_fd(watch);
m_watchers.emplace(fd, std::make_unique<WatchHandler>(m_eventBase.get(), watch));
return true;
}
void CDBusDispatcher::dbusRemoveWatch(DBusWatch *watch)
{
for (auto it = m_watchers.begin(); it != m_watchers.end();)
{
if (it->second->getWatch() == watch) { it = m_watchers.erase(it); }
else { ++it; }
}
}
void CDBusDispatcher::dbusWatchToggled(DBusWatch *watch)
{
if (dbus_watch_get_enabled(watch) == TRUE) { dbusAddWatch(watch); }
else { dbusRemoveWatch(watch); }
}
dbus_bool_t CDBusDispatcher::dbusAddTimeout(DBusTimeout *timeout)
{
if (dbus_timeout_get_enabled(timeout) == FALSE) { return TRUE; }
m_timeouts.emplace(m_timeouts.end(), std::make_unique<TimeoutHandler>(m_eventBase.get(), timeout));
return true;
}
void CDBusDispatcher::dbusRemoveTimeout(DBusTimeout *timeout)
{
auto predicate = [timeout](const std::unique_ptr<TimeoutHandler> &ptr)
{
return ptr->getTimeout() == timeout;
};
m_timeouts.erase(std::remove_if(m_timeouts.begin(), m_timeouts.end(), predicate), m_timeouts.end());
}
void CDBusDispatcher::dbusTimeoutToggled(DBusTimeout *timeout)
{
if (dbus_timeout_get_enabled(timeout) == TRUE)
dbusAddTimeout(timeout);
else
dbusRemoveTimeout(timeout);
}
}

View File

@@ -0,0 +1,104 @@
/* Copyright (C) 2018
* 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 and at http://www.swift-project.org/license.html. 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.
*/
#ifndef BLACKSIM_XSWIFTBUS_DBUSDISPATCHER_H
#define BLACKSIM_XSWIFTBUS_DBUSDISPATCHER_H
#include "dbuscallbacks.h"
#include <event2/event.h>
#include <dbus/dbus.h>
#include <unordered_map>
#include <vector>
#include <memory>
namespace XSwiftBus
{
class WatchHandler;
class TimeoutHandler;
class CDBusConnection;
class CDBusDispatcher;
//! Dispatchable Interface
class IDispatchable
{
public:
//! Default constructor
IDispatchable() = default;
//! Default destructor
virtual ~IDispatchable() = default;
//! Dispatch execution method
virtual void dispatch() = 0;
private:
friend CDBusDispatcher;
};
//! DBus Dispatcher
class CDBusDispatcher
{
public:
//! Constructor
CDBusDispatcher();
//! Destructor
virtual ~CDBusDispatcher();
//! Add dispatchable object
void add(IDispatchable *dispatchable);
//! Remove dispatchable object
void remove(IDispatchable *dispatchable);
//! Waits for events to be dispatched and handles them
void waitAndRun();
//! Dispatches ready handlers and returns without waiting
void runOnce();
private:
friend class WatchHandler;
friend class TimeoutHandler;
friend class Timer;
friend class CDBusConnection;
friend class CDBusServer;
struct EventBaseDeleter
{
void operator()(event_base *obj) const { event_base_free(obj); }
};
using WatchCallbacks = DBusAsyncCallbacks<DBusWatch>;
using TimeoutCallbacks = DBusAsyncCallbacks<DBusTimeout>;
void dispatch();
dbus_bool_t dbusAddWatch(DBusWatch *watch);
void dbusRemoveWatch(DBusWatch *watch);
void dbusWatchToggled(DBusWatch *watch);
dbus_bool_t dbusAddTimeout(DBusTimeout *timeout);
void dbusRemoveTimeout(DBusTimeout *timeout);
void dbusTimeoutToggled(DBusTimeout *timeout);
WatchCallbacks m_watchCallbacks;
TimeoutCallbacks m_timeoutCallbacks;
std::unordered_multimap<evutil_socket_t, std::unique_ptr<WatchHandler>> m_watchers;
std::vector<std::unique_ptr<TimeoutHandler>> m_timeouts;
std::unique_ptr<event_base, EventBaseDeleter> m_eventBase;
std::vector<IDispatchable*> m_dispatchList;
};
}
#endif

View File

@@ -68,7 +68,7 @@ namespace XSwiftBus
m_traffic->setPlaneViewMenu(m_planeViewSubMenu);
// Todo: retry if it fails
bool success = m_dbusConnection->connect(CDBusConnection::SessionBus, xswiftbusServiceName());
bool success = m_dbusConnection->connect(CDBusConnection::SessionBus);
if (!success)
{
@@ -76,6 +76,9 @@ namespace XSwiftBus
return;
}
m_dbusConnection->setDispatcher(&m_dbusDispatcher);
m_dbusConnection->requestName(xswiftbusServiceName());
m_service->setDBusConnection(m_dbusConnection);
m_service->registerDBusObjectPath(m_service->InterfaceName(), m_service->ObjectPath());
m_traffic->setDBusConnection(m_dbusConnection);
@@ -83,6 +86,7 @@ namespace XSwiftBus
m_weather->setDBusConnection(m_dbusConnection);
m_weather->registerDBusObjectPath(m_weather->InterfaceName(), m_weather->ObjectPath());
INFO_LOG("XSwiftBus started.");
}
@@ -117,6 +121,7 @@ namespace XSwiftBus
float CPlugin::flightLoopCallback(float, float, int, void *refcon)
{
auto *plugin = static_cast<CPlugin *>(refcon);
plugin->m_dbusDispatcher.runOnce();
if (plugin->m_service) { plugin->m_service->processDBus(); }
if (plugin->m_weather) { plugin->m_weather->processDBus(); }
if (plugin->m_traffic) { plugin->m_traffic->processDBus(); }

View File

@@ -22,6 +22,7 @@
#endif
#include "dbusconnection.h"
#include "dbusdispatcher.h"
#include "datarefs.h"
#include "XPLM/XPLMCamera.h"
#include "menus.h"
@@ -53,6 +54,7 @@ namespace XSwiftBus
void onAircraftRepositioned();
private:
CDBusDispatcher m_dbusDispatcher;
std::shared_ptr<CDBusConnection> m_dbusConnection;
std::unique_ptr<CService> m_service;
std::unique_ptr<CTraffic> m_traffic;