diff --git a/src/plugins/simulator/xplane/simulator_xplane.cpp b/src/plugins/simulator/xplane/simulator_xplane.cpp index 3e3073acc..2b4cc522e 100644 --- a/src/plugins/simulator/xplane/simulator_xplane.cpp +++ b/src/plugins/simulator/xplane/simulator_xplane.cpp @@ -4,6 +4,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "simulator_xplane.h" +#include "xbus_service_proxy.h" +#include namespace BlackSimPlugin { @@ -12,50 +14,111 @@ namespace BlackSimPlugin CSimulatorXPlane::CSimulatorXPlane(QObject *parent) : BlackCore::ISimulator(parent) { + m_watcher = new QDBusServiceWatcher(this); + m_watcher->setWatchMode(QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration); + m_watcher->addWatchedService(CXBusServiceProxy::InterfaceName()); + connect(m_watcher, &QDBusServiceWatcher::serviceRegistered, this, &CSimulatorXPlane::serviceRegistered); + connect(m_watcher, &QDBusServiceWatcher::serviceUnregistered, this, &CSimulatorXPlane::serviceUnregistered); } bool CSimulatorXPlane::isConnected() const { - return false; + return m_service; } bool CSimulatorXPlane::canConnect() { - return false; + if (isConnected()) { return true; } + auto conn = QDBusConnection::sessionBus(); // TODO make this configurable + auto dummy = new CXBusServiceProxy(conn, this, true); + bool ok = dummy->isValid(); + delete dummy; + return ok; } bool CSimulatorXPlane::connectTo() { - return false; + if (isConnected()) { return true; } + m_conn = QDBusConnection::sessionBus(); // TODO make this configurable + m_service = new CXBusServiceProxy(m_conn, this); + if (m_service->isValid()) + { + connect(m_service, &CXBusServiceProxy::aircraftModelChanged, this, &CSimulatorXPlane::aircraftModelChanged); + m_watcher->setConnection(m_conn); + emit statusChanged(ISimulator::Connected); + return true; + } + else + { + disconnectFrom(); + return false; + } } void CSimulatorXPlane::asyncConnectTo() { + // TODO + connectTo(); } bool CSimulatorXPlane::disconnectFrom() { - return false; + emit statusChanged(ISimulator::Disconnected); + m_conn = QDBusConnection { "default" }; + m_watcher->setConnection(m_conn); + delete m_service; + m_service = nullptr; + return true; + } + + void CSimulatorXPlane::serviceRegistered() + { + delete m_service; + m_service = new CXBusServiceProxy(m_conn, this); + connect(m_service, &CXBusServiceProxy::aircraftModelChanged, this, &CSimulatorXPlane::aircraftModelChanged); + emit statusChanged(ISimulator::Connected); + } + + void CSimulatorXPlane::serviceUnregistered() + { + delete m_service; + m_service = nullptr; + emit statusChanged(ISimulator::Disconnected); } BlackMisc::Aviation::CAircraft CSimulatorXPlane::getOwnAircraft() const { - return {}; + if (! m_service) { return {}; } + using namespace BlackMisc; + Aviation::CAircraftSituation situation; + situation.setPosition({ m_service->getLatitude(), m_service->getLongitude(), 0 }); + situation.setAltitude({ m_service->getAltitudeMSL(), Aviation::CAltitude::MeanSeaLevel, PhysicalQuantities::CLengthUnit::m() }); + situation.setHeading({ m_service->getTrueHeading(), Aviation::CHeading::True, PhysicalQuantities::CAngleUnit::deg() }); + situation.setPitch({ m_service->getPitch(), PhysicalQuantities::CAngleUnit::deg() }); + situation.setBank({ m_service->getRoll(), PhysicalQuantities::CAngleUnit::deg() }); + situation.setGroundspeed({ m_service->getGroundSpeed(), PhysicalQuantities::CSpeedUnit::m_s() }); + return { {}, {}, situation }; } void CSimulatorXPlane::displayStatusMessage(const BlackMisc::CStatusMessage &message) const { + if (! m_service) { return; } + // TODO Q_UNUSED(message); } BlackMisc::Network::CAircraftModel CSimulatorXPlane::getAircraftModel() const { - return {}; + if (! m_service) { return {}; } + return m_service->getAircraftModelPath(); } bool CSimulatorXPlane::updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &aircraft) { + if (! m_service) { return false; } + //TODO Q_UNUSED(aircraft); + return false; } } diff --git a/src/plugins/simulator/xplane/simulator_xplane.h b/src/plugins/simulator/xplane/simulator_xplane.h index 84c0a2ef9..98742bd45 100644 --- a/src/plugins/simulator/xplane/simulator_xplane.h +++ b/src/plugins/simulator/xplane/simulator_xplane.h @@ -9,12 +9,17 @@ //! \file #include "blackcore/simulator.h" +#include + +class QDBusServiceWatcher; namespace BlackSimPlugin { namespace XPlane { + class CXBusServiceProxy; + /*! * X-Plane ISimulator implementation */ @@ -32,6 +37,15 @@ namespace BlackSimPlugin //! \copydoc BlackCore::ISimulator::canConnect virtual bool canConnect() override; + private: + QDBusConnection m_conn { "default" }; + QDBusServiceWatcher *m_watcher { nullptr }; + CXBusServiceProxy *m_service { nullptr }; + + private slots: + void serviceRegistered(); + void serviceUnregistered(); + public slots: //! \copydoc BlackCore::ISimulator::connectTo virtual bool connectTo() override; diff --git a/src/plugins/simulator/xplane/xbus_service_proxy.cpp b/src/plugins/simulator/xplane/xbus_service_proxy.cpp index 057903640..c47ce3eae 100644 --- a/src/plugins/simulator/xplane/xbus_service_proxy.cpp +++ b/src/plugins/simulator/xplane/xbus_service_proxy.cpp @@ -12,10 +12,10 @@ namespace BlackSimPlugin namespace XPlane { - CXBusServiceProxy::CXBusServiceProxy(QDBusConnection &connection, QObject *parent) : QObject(parent) + CXBusServiceProxy::CXBusServiceProxy(QDBusConnection &connection, QObject *parent, bool dummy) : QObject(parent) { m_dbusInterface = new BlackMisc::CGenericDBusInterface(BlackCore::CDBusServer::ServiceName, ObjectPath(), InterfaceName(), connection, this); - relaySignals(); + if (! dummy) { relaySignals(); } } void CXBusServiceProxy::relaySignals() diff --git a/src/plugins/simulator/xplane/xbus_service_proxy.h b/src/plugins/simulator/xplane/xbus_service_proxy.h index 4e8381158..b3179bf16 100644 --- a/src/plugins/simulator/xplane/xbus_service_proxy.h +++ b/src/plugins/simulator/xplane/xbus_service_proxy.h @@ -43,7 +43,10 @@ namespace BlackSimPlugin } //! Constructor - CXBusServiceProxy(QDBusConnection &connection, QObject *parent = nullptr); + CXBusServiceProxy(QDBusConnection &connection, QObject *parent = nullptr, bool dummy = false); + + //! Does the remote object exist? + bool isValid() const { return m_dbusInterface->isValid(); } private: BlackMisc::CGenericDBusInterface *m_dbusInterface = nullptr;