diff --git a/src/plugins/simulator/xplane/simulator_xplane.cpp b/src/plugins/simulator/xplane/simulator_xplane.cpp index 16a407650..03f162300 100644 --- a/src/plugins/simulator/xplane/simulator_xplane.cpp +++ b/src/plugins/simulator/xplane/simulator_xplane.cpp @@ -5,6 +5,7 @@ #include "simulator_xplane.h" #include "xbus_service_proxy.h" +#include "xbus_traffic_proxy.h" #include #include @@ -18,6 +19,7 @@ namespace BlackSimPlugin m_watcher = new QDBusServiceWatcher(this); m_watcher->setWatchMode(QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration); m_watcher->addWatchedService(CXBusServiceProxy::InterfaceName()); + m_watcher->addWatchedService(CXBusTrafficProxy::InterfaceName()); connect(m_watcher, &QDBusServiceWatcher::serviceRegistered, this, &CSimulatorXPlane::serviceRegistered); connect(m_watcher, &QDBusServiceWatcher::serviceUnregistered, this, &CSimulatorXPlane::serviceUnregistered); @@ -63,7 +65,7 @@ namespace BlackSimPlugin bool CSimulatorXPlane::isConnected() const { - return m_service; + return m_service && m_traffic; } bool CSimulatorXPlane::canConnect() @@ -81,7 +83,8 @@ namespace BlackSimPlugin if (isConnected()) { return true; } m_conn = QDBusConnection::sessionBus(); // TODO make this configurable m_service = new CXBusServiceProxy(m_conn, this); - if (m_service->isValid()) + m_traffic = new CXBusTrafficProxy(m_conn, this); + if (m_service->isValid() && m_traffic->isValid() && m_traffic->initialize()) { connect(m_service, &CXBusServiceProxy::aircraftModelChanged, this, &CSimulatorXPlane::aircraftModelChanged); m_watcher->setConnection(m_conn); @@ -103,26 +106,45 @@ namespace BlackSimPlugin bool CSimulatorXPlane::disconnectFrom() { + if (m_traffic) + { + m_traffic->cleanup(); + } emit statusChanged(ISimulator::Disconnected); m_conn = QDBusConnection { "default" }; m_watcher->setConnection(m_conn); delete m_service; + delete m_traffic; m_service = nullptr; + m_traffic = nullptr; return true; } - void CSimulatorXPlane::serviceRegistered() + void CSimulatorXPlane::serviceRegistered(const QString &serviceName) { - delete m_service; - m_service = new CXBusServiceProxy(m_conn, this); - connect(m_service, &CXBusServiceProxy::aircraftModelChanged, this, &CSimulatorXPlane::aircraftModelChanged); - emit statusChanged(ISimulator::Connected); + if (serviceName == CXBusServiceProxy::InterfaceName()) + { + delete m_service; + m_service = new CXBusServiceProxy(m_conn, this); + connect(m_service, &CXBusServiceProxy::aircraftModelChanged, this, &CSimulatorXPlane::aircraftModelChanged); + } + else if (serviceName == CXBusTrafficProxy::InterfaceName()) + { + delete m_traffic; + m_traffic = new CXBusTrafficProxy(m_conn, this); + } + if (m_service && m_traffic) + { + emit statusChanged(ISimulator::Connected); + } } void CSimulatorXPlane::serviceUnregistered() { delete m_service; + delete m_traffic; m_service = nullptr; + m_traffic = nullptr; emit statusChanged(ISimulator::Disconnected); } @@ -201,5 +223,35 @@ namespace BlackSimPlugin return false; } + void CSimulatorXPlane::addRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign, const QString &type, + const BlackMisc::Aviation::CAircraftSituation &initialSituation) + { + if (! isConnected()) { return; } + m_traffic->addPlane(callsign.asString(), type, "YYY", "YYY"); // TODO livery + addAircraftSituation(callsign, initialSituation); + } + + void CSimulatorXPlane::addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, + const BlackMisc::Aviation::CAircraftSituation &situ) + { + if (! isConnected()) { return; } + using namespace BlackMisc::PhysicalQuantities; + m_traffic->setPlanePosition(callsign.asString(), + situ.latitude().value(CAngleUnit::deg()), + situ.longitude().value(CAngleUnit::deg()), + situ.getAltitude().value(CLengthUnit::ft()), + situ.getPitch().value(CAngleUnit::deg()), + situ.getBank().value(CAngleUnit::deg()), + situ.getHeading().value(CAngleUnit::deg())); + m_traffic->setPlaneSurfaces(callsign.asString(), true, 0, 0, 0, 0, 0, 0, 0, 0, 0, true, true, true, true, 0); // TODO landing gear, lights, control surfaces + m_traffic->setPlaneTransponder(callsign.asString(), 2000, true, false); // TODO transponder + } + + void CSimulatorXPlane::removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) + { + if (! isConnected()) { return; } + m_traffic->removePlane(callsign.asString()); + } + } } diff --git a/src/plugins/simulator/xplane/simulator_xplane.h b/src/plugins/simulator/xplane/simulator_xplane.h index 6cf3886b6..9335ab5c4 100644 --- a/src/plugins/simulator/xplane/simulator_xplane.h +++ b/src/plugins/simulator/xplane/simulator_xplane.h @@ -19,6 +19,7 @@ namespace BlackSimPlugin { class CXBusServiceProxy; + class CXBusTrafficProxy; /*! * X-Plane ISimulator implementation @@ -51,15 +52,15 @@ namespace BlackSimPlugin virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const override; //! \copydoc BlackCore::ISimulator::addRemoteAircraft - virtual void addRemoteAircraft(const BlackMisc::Aviation::CCallsign &/*callsign*/, const QString &/*type*/, - const BlackMisc::Aviation::CAircraftSituation &/*initialSituation*/) override {} + virtual void addRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign, const QString &type, + const BlackMisc::Aviation::CAircraftSituation &initialSituation) override; //! \copydoc BlackCore::ISimulator::addAircraftSituation - virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &/*callsign*/, - const BlackMisc::Aviation::CAircraftSituation &/*initialSituation*/) override {} + virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, + const BlackMisc::Aviation::CAircraftSituation &initialSituation) override; //! \copydoc BlackCore::ISimulator::removeRemoteAircraft - virtual void removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &/*callsign*/) override {} + virtual void removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override; //! \copydoc BlackCore::ISimulator::updateOwnSimulatorCockpit virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &aircraft) override; @@ -74,7 +75,7 @@ namespace BlackSimPlugin virtual BlackMisc::Network::CAircraftModel getAircraftModel() const override; private slots: - void serviceRegistered(); + void serviceRegistered(const QString &serviceName); void serviceUnregistered(); void fastTimerTimeout(); void slowTimerTimeout(); @@ -83,6 +84,7 @@ namespace BlackSimPlugin QDBusConnection m_conn { "default" }; QDBusServiceWatcher *m_watcher { nullptr }; CXBusServiceProxy *m_service { nullptr }; + CXBusTrafficProxy *m_traffic { nullptr }; QTimer *m_fastTimer { nullptr }; QTimer *m_slowTimer { nullptr }; diff --git a/src/plugins/simulator/xplane/xbus_traffic_proxy.cpp b/src/plugins/simulator/xplane/xbus_traffic_proxy.cpp new file mode 100644 index 000000000..a21f1560b --- /dev/null +++ b/src/plugins/simulator/xplane/xbus_traffic_proxy.cpp @@ -0,0 +1,100 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xbus_traffic_proxy.h" +#include "blackcore/dbus_server.h" +#include + +#define XBUS_SERVICENAME "net.vatsim.xbus" + +namespace BlackSimPlugin +{ + namespace XPlane + { + + CXBusTrafficProxy::CXBusTrafficProxy(QDBusConnection &connection, QObject *parent, bool dummy) : QObject(parent) + { + m_dbusInterface = new BlackMisc::CGenericDBusInterface(XBUS_SERVICENAME, ObjectPath(), InterfaceName(), connection, this); + if (! dummy) { relaySignals(); } + } + + void CXBusTrafficProxy::relaySignals() + { + // TODO can this be refactored into CGenericDBusInterface? + for (int i = 0, count = metaObject()->methodCount(); i < count; ++i) + { + auto method = metaObject()->method(i); + if (method.methodType() == QMetaMethod::Signal) + { + m_dbusInterface->connection().connect(m_dbusInterface->service(), m_dbusInterface->path(), m_dbusInterface->interface(), + method.name(), this, method.methodSignature()); + } + } + } + + bool CXBusTrafficProxy::initialize() + { + return m_dbusInterface->callDBusRet(QLatin1String("initialize")); + } + + void CXBusTrafficProxy::cleanup() + { + m_dbusInterface->callDBus(QLatin1String("cleanup")); + } + + bool CXBusTrafficProxy::loadPlanesPackage(const QString &path) + { + return m_dbusInterface->callDBusRet(QLatin1String("loadPlanesPackage"), path); + } + + void CXBusTrafficProxy::setDefaultIcao(const QString &defaultIcao) + { + m_dbusInterface->callDBus(QLatin1String("setDefaultIcao"), defaultIcao); + } + + void CXBusTrafficProxy::setDrawingLabels(bool drawing) + { + m_dbusInterface->callDBus(QLatin1String("setDrawingLabels"), drawing); + } + + bool CXBusTrafficProxy::isDrawingLabels() const + { + return m_dbusInterface->callDBusRet(QLatin1String("isDrawingLabels")); + } + + void CXBusTrafficProxy::addPlane(const QString &callsign, const QString &aircraftIcao, const QString &airlineIcao, const QString &livery) + { + m_dbusInterface->callDBus(QLatin1String("addPlane"), callsign, aircraftIcao, airlineIcao, livery); + } + + void CXBusTrafficProxy::removePlane(const QString &callsign) + { + m_dbusInterface->callDBus(QLatin1String("removePlane"), callsign); + } + + void CXBusTrafficProxy::removeAllPlanes() + { + m_dbusInterface->callDBus(QLatin1String("removeAllPlanes")); + } + + void CXBusTrafficProxy::setPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading) + { + m_dbusInterface->callDBus(QLatin1String("setPlanePosition"), callsign, latitude, longitude, altitude, pitch, roll, heading); + } + + void CXBusTrafficProxy::setPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust, + double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern) + { + m_dbusInterface->callDBus(QLatin1String("setPlaneSurfaces"), callsign, gear, flap, spoiler, speedBrake, slat, wingSweep, thrust, elevator, rudder, aileron, + landLight, beaconLight, strobeLight, navLight, lightPattern); + } + + void CXBusTrafficProxy::setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident) + { + m_dbusInterface->callDBus(QLatin1String("setPlaneTransponder"), callsign, code, modeC, ident); + } + + } +} \ No newline at end of file diff --git a/src/plugins/simulator/xplane/xbus_traffic_proxy.h b/src/plugins/simulator/xplane/xbus_traffic_proxy.h new file mode 100644 index 000000000..4f06f6c58 --- /dev/null +++ b/src/plugins/simulator/xplane/xbus_traffic_proxy.h @@ -0,0 +1,98 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BLACKSIMPLUGIN_XBUS_TRAFFIC_PROXY_H +#define BLACKSIMPLUGIN_XBUS_TRAFFIC_PROXY_H + +//! \file + +#include "blackmisc/genericdbusinterface.h" + +//! \cond PRIVATE +#define XBUS_TRAFFIC_INTERFACENAME "net.vatsim.xbus.traffic" +#define XBUS_TRAFFIC_OBJECTPATH "/xbus/traffic" +//! \endcond + +namespace BlackSimPlugin +{ + namespace XPlane + { + + /*! + * Proxy object connected to a real XBus::CTraffic object via DBus + */ + class CXBusTrafficProxy : public QObject + { + Q_OBJECT + + public: + //! Service name + static const QString &InterfaceName() + { + static QString s(XBUS_TRAFFIC_INTERFACENAME); + return s; + } + + //! Service path + static const QString &ObjectPath() + { + static QString s(XBUS_TRAFFIC_OBJECTPATH); + return s; + } + + //! Constructor + CXBusTrafficProxy(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; + + void relaySignals(); + + public slots: + //! \copydoc XBus::CTraffic::initialize + bool initialize(); + + //! \copydoc XBus::CTraffic::cleanup + void cleanup(); + + //! \copydoc XBus::CTraffic::loadPlanesPackage + bool loadPlanesPackage(const QString &path); + + //! \copydoc XBus::CTraffic::setDefaultIcao + void setDefaultIcao(const QString &defaultIcao); + + //! \copydoc XBus::CTraffic::setDrawingLabels + void setDrawingLabels(bool drawing); + + //! \copydoc XBus::CTraffic::isDrawingLabels + bool isDrawingLabels() const; + + //! \copydoc XBus::CTraffic::addPlane + void addPlane(const QString &callsign, const QString &aircraftIcao, const QString &airlineIcao, const QString &livery); + + //! \copydoc XBus::CTraffic::removePlane + void removePlane(const QString &callsign); + + //! \copydoc XBus::CTraffic::removeAllPlanes + void removeAllPlanes(); + + //! \copydoc XBus::CTraffic::setPlanePosition + void setPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading); + + //! \copydoc XBus::CTraffic::setPlaneSurfaces + void setPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust, + double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern); + + //! \copydoc XBus::CTraffic::setPlaneTransponder + void setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident); + }; + + } +} + +#endif // guard