diff --git a/src/core/context/contextownaircraft.h b/src/core/context/contextownaircraft.h index 121a94c14..36afaf3cd 100644 --- a/src/core/context/contextownaircraft.h +++ b/src/core/context/contextownaircraft.h @@ -135,11 +135,16 @@ namespace swift::core::context //! Set XPDR mode virtual bool setTransponderMode(swift::misc::aviation::CTransponder::TransponderMode mode) = 0; - //! Tune in a COM frequency + //! Tune in a COM frequency (active) virtual bool updateActiveComFrequency(const swift::misc::physical_quantities::CFrequency &frequency, swift::misc::aviation::CComSystem::ComUnit comUnit, const swift::misc::CIdentifier &originator) = 0; + //! Tune in a COM frequency (standby) + virtual bool updateStandbyComFrequency(const swift::misc::physical_quantities::CFrequency &frequency, + swift::misc::aviation::CComSystem::ComUnit comUnit, + const swift::misc::CIdentifier &originator) = 0; + //! Set current pilot virtual bool updateOwnAircraftPilot(const swift::misc::network::CUser &pilot) = 0; diff --git a/src/core/context/contextownaircraftempty.h b/src/core/context/contextownaircraftempty.h index 4b0f6c219..18ca8ed32 100644 --- a/src/core/context/contextownaircraftempty.h +++ b/src/core/context/contextownaircraftempty.h @@ -100,6 +100,18 @@ namespace swift::core::context return false; } + //! \copydoc IContextOwnAircraft::updateStandbyComFrequency + bool updateStandbyComFrequency(const swift::misc::physical_quantities::CFrequency &frequency, + swift::misc::aviation::CComSystem::ComUnit comUnit, + const swift::misc::CIdentifier &originator) override + { + Q_UNUSED(frequency); + Q_UNUSED(comUnit); + Q_UNUSED(originator); + logEmptyContextWarning(Q_FUNC_INFO); + return false; + } + //! \copydoc IContextOwnAircraft::updateOwnAircraftPilot bool updateOwnAircraftPilot(const swift::misc::network::CUser &pilot) override { diff --git a/src/core/context/contextownaircraftimpl.cpp b/src/core/context/contextownaircraftimpl.cpp index 4dff42282..68bb2b7d1 100644 --- a/src/core/context/contextownaircraftimpl.cpp +++ b/src/core/context/contextownaircraftimpl.cpp @@ -330,6 +330,26 @@ namespace swift::core::context return changed; } + bool CContextOwnAircraft::updateStandbyComFrequency(const CFrequency &frequency, CComSystem::ComUnit unit, + const CIdentifier &originator) + { + if (unit != CComSystem::Com1 && unit != CComSystem::Com2) { return false; } + if (!CComSystem::isValidComFrequency(frequency)) { return false; } + CComSystem com1, com2; + CTransponder xpdr; + { + QReadLocker l(&m_lockAircraft); + com1 = m_ownAircraft.getCom1System(); + com2 = m_ownAircraft.getCom2System(); + xpdr = m_ownAircraft.getTransponder(); + } + if (unit == CComSystem::Com1) { com1.setFrequencyStandby(frequency); } + else { com2.setFrequencyStandby(frequency); } + + const bool changed = this->updateCockpit(com1, com2, xpdr, originator); + return changed; + } + bool CContextOwnAircraft::updateOwnAircraftPilot(const CUser &pilot) { { diff --git a/src/core/context/contextownaircraftimpl.h b/src/core/context/contextownaircraftimpl.h index dcc5bb849..bb760560f 100644 --- a/src/core/context/contextownaircraftimpl.h +++ b/src/core/context/contextownaircraftimpl.h @@ -175,6 +175,11 @@ namespace swift::core swift::misc::aviation::CComSystem::ComUnit comUnit, const swift::misc::CIdentifier &originator) override; + //! \copydoc IContextOwnAircraft::updateStandbyComFrequency + bool updateStandbyComFrequency(const swift::misc::physical_quantities::CFrequency &frequency, + swift::misc::aviation::CComSystem::ComUnit comUnit, + const swift::misc::CIdentifier &originator) override; + //! \copydoc IContextOwnAircraft::updateOwnAircraftPilot bool updateOwnAircraftPilot(const swift::misc::network::CUser &pilot) override; diff --git a/src/core/context/contextownaircraftproxy.cpp b/src/core/context/contextownaircraftproxy.cpp index 02bc2e5bf..264644561 100644 --- a/src/core/context/contextownaircraftproxy.cpp +++ b/src/core/context/contextownaircraftproxy.cpp @@ -111,6 +111,14 @@ namespace swift::core::context originator); } + bool CContextOwnAircraftProxy::updateStandbyComFrequency(const physical_quantities::CFrequency &frequency, + swift::misc::aviation::CComSystem::ComUnit comUnit, + const CIdentifier &originator) + { + return m_dBusInterface->callDBusRet(QLatin1String("updateStandbyComFrequency"), frequency, comUnit, + originator); + } + bool CContextOwnAircraftProxy::updateOwnAircraftPilot(const swift::misc::network::CUser &pilot) { return m_dBusInterface->callDBusRet(QLatin1String("updateOwnAircraftPilot"), pilot); diff --git a/src/core/context/contextownaircraftproxy.h b/src/core/context/contextownaircraftproxy.h index f318b281b..329c267d9 100644 --- a/src/core/context/contextownaircraftproxy.h +++ b/src/core/context/contextownaircraftproxy.h @@ -89,6 +89,11 @@ namespace swift::core swift::misc::aviation::CComSystem::ComUnit comUnit, const swift::misc::CIdentifier &originator) override; + //! \copydoc swift::core::context::IContextOwnAircraft::updateStandbyComFrequency + bool updateStandbyComFrequency(const swift::misc::physical_quantities::CFrequency &frequency, + swift::misc::aviation::CComSystem::ComUnit comUnit, + const swift::misc::CIdentifier &originator) override; + //! \copydoc swift::core::context::IContextOwnAircraft::updateOwnAircraftPilot bool updateOwnAircraftPilot(const swift::misc::network::CUser &pilot) override; diff --git a/src/core/context/contextsimulatorimpl.cpp b/src/core/context/contextsimulatorimpl.cpp index 4b5506656..f2fc105c0 100644 --- a/src/core/context/contextsimulatorimpl.cpp +++ b/src/core/context/contextsimulatorimpl.cpp @@ -802,12 +802,15 @@ namespace swift::core::context { Q_UNUSED(from) SWIFT_VERIFY_X(this->getIContextNetwork(), Q_FUNC_INFO, "Missing network context"); + SWIFT_VERIFY_X(this->getIContextOwnAircraft(), Q_FUNC_INFO, "Missing own aircraft context"); if (to.isConnected() && this->getIContextNetwork()) { m_networkSessionId = this->getIContextNetwork()->getConnectedServer().getServerSessionId(false); if (m_simulatorPlugin.second) // check in case the plugin has been unloaded { m_simulatorPlugin.second->setFlightNetworkConnected(true); + m_simulatorPlugin.second->setOwnCallsign( + this->getIContextOwnAircraft()->getOwnAircraft().getCallsign()); } } else if (to.isDisconnected()) @@ -821,6 +824,7 @@ namespace swift::core::context { m_simulatorPlugin.second->removeAllRemoteAircraft(); // also removes aircraft m_simulatorPlugin.second->setFlightNetworkConnected(false); + m_simulatorPlugin.second->setOwnCallsign({}); } } } diff --git a/src/core/simulator.cpp b/src/core/simulator.cpp index 202d184b5..93f7f9292 100644 --- a/src/core/simulator.cpp +++ b/src/core/simulator.cpp @@ -119,6 +119,12 @@ namespace swift::core void ISimulator::setFlightNetworkConnected(bool connected) { m_networkConnected = connected; } + void ISimulator::setOwnCallsign(const CCallsign &callsign) + { + Q_UNUSED(callsign) + // void + } + void ISimulator::clearAllRemoteAircraftData() { // rendering related stuff diff --git a/src/core/simulator.h b/src/core/simulator.h index 5d6ab99fd..50a52266a 100644 --- a/src/core/simulator.h +++ b/src/core/simulator.h @@ -152,6 +152,9 @@ namespace swift::core //! \sa ISimulator::isFlightNetworkConnected virtual void setFlightNetworkConnected(bool connected); + //! Own callsign has changed + virtual void setOwnCallsign(const swift::misc::aviation::CCallsign &callsign); + //! Is the flight network connected bool isFlightNetworkConnected() const { return m_networkConnected; } diff --git a/src/gui/components/atcstationcomponent.cpp b/src/gui/components/atcstationcomponent.cpp index cf18baaf8..9c27d777e 100644 --- a/src/gui/components/atcstationcomponent.cpp +++ b/src/gui/components/atcstationcomponent.cpp @@ -330,11 +330,12 @@ namespace swift::gui::components } void CAtcStationComponent::setComFrequency(const physical_quantities::CFrequency &frequency, - CComSystem::ComUnit unit) + CComSystem::ComUnit unit, bool active) { if (unit != CComSystem::Com1 && unit != CComSystem::Com2) { return; } if (!CComSystem::isValidComFrequency(frequency)) { return; } - sGui->getIContextOwnAircraft()->updateActiveComFrequency(frequency, unit, identifier()); + if (active) { sGui->getIContextOwnAircraft()->updateActiveComFrequency(frequency, unit, identifier()); } + else { sGui->getIContextOwnAircraft()->updateStandbyComFrequency(frequency, unit, identifier()); } } void CAtcStationComponent::settingsChanged() diff --git a/src/gui/components/atcstationcomponent.h b/src/gui/components/atcstationcomponent.h index 3e36c6b3e..2608141f9 100644 --- a/src/gui/components/atcstationcomponent.h +++ b/src/gui/components/atcstationcomponent.h @@ -122,7 +122,7 @@ namespace swift::gui //! Set COM frequency void setComFrequency(const swift::misc::physical_quantities::CFrequency &frequency, - swift::misc::aviation::CComSystem::ComUnit unit); + swift::misc::aviation::CComSystem::ComUnit unit, bool active); //! Airports read from web readers void airportsRead(); diff --git a/src/gui/views/atcstationtreeview.cpp b/src/gui/views/atcstationtreeview.cpp index 0954491d2..ee6f57332 100644 --- a/src/gui/views/atcstationtreeview.cpp +++ b/src/gui/views/atcstationtreeview.cpp @@ -118,18 +118,24 @@ namespace swift::gui::views auto *menu = new QMenu(this); // menu - auto *com1 = new QAction(CIcons::appCockpit16(), "Tune in COM1", this); - auto *com2 = new QAction(CIcons::appCockpit16(), "Tune in COM2", this); + auto *com1 = new QAction(CIcons::appCockpit16(), "Tune in COM1 (active)", this); + auto *com2 = new QAction(CIcons::appCockpit16(), "Tune in COM2 (active)", this); + auto *com1_stby = new QAction(CIcons::appCockpit16(), "Tune in COM1 (standby)", this); + auto *com2_stby = new QAction(CIcons::appCockpit16(), "Tune in COM2 (standby)", this); auto *text = new QAction(CIcons::appTextMessages16(), "Show text messages", this); auto *resize = new QAction(CIcons::resize16(), "Resize", this); - connect(com1, &QAction::triggered, this, &CAtcStationTreeView::tuneInAtcCom1); - connect(com2, &QAction::triggered, this, &CAtcStationTreeView::tuneInAtcCom2); + connect(com1, &QAction::triggered, this, [this]() { tuneInAtc(CComSystem::Com1, true); }); + connect(com2, &QAction::triggered, this, [this]() { tuneInAtc(CComSystem::Com2, true); }); + connect(com1_stby, &QAction::triggered, this, [this]() { tuneInAtc(CComSystem::Com1, false); }); + connect(com2_stby, &QAction::triggered, this, [this]() { tuneInAtc(CComSystem::Com2, false); }); connect(text, &QAction::triggered, this, &CAtcStationTreeView::requestTextMessage); connect(resize, &QAction::triggered, this, &CAtcStationTreeView::fullResizeToContentsImpl); menu->addAction(com1); menu->addAction(com2); + menu->addAction(com1_stby); + menu->addAction(com2_stby); menu->addAction(text); menu->addSeparator(); menu->addAction(resize); @@ -160,18 +166,11 @@ namespace swift::gui::views } } - void CAtcStationTreeView::tuneInAtcCom1() + void CAtcStationTreeView::tuneInAtc(const misc::aviation::CComSystem::ComUnit unit, const bool active) { const CAtcStation s(this->selectedObject()); if (s.getCallsign().isEmpty()) { return; } - emit this->requestComFrequency(s.getFrequency(), CComSystem::Com1); - } - - void CAtcStationTreeView::tuneInAtcCom2() - { - const CAtcStation s(this->selectedObject()); - if (s.getCallsign().isEmpty()) { return; } - emit this->requestComFrequency(s.getFrequency(), CComSystem::Com2); + emit this->requestComFrequency(s.getFrequency(), unit, active); } void CAtcStationTreeView::requestTextMessage() diff --git a/src/gui/views/atcstationtreeview.h b/src/gui/views/atcstationtreeview.h index 1041fa425..c37be5b32 100644 --- a/src/gui/views/atcstationtreeview.h +++ b/src/gui/views/atcstationtreeview.h @@ -63,7 +63,7 @@ namespace swift::gui //! Request COM frequency void requestComFrequency(const swift::misc::physical_quantities::CFrequency &frequency, - swift::misc::aviation::CComSystem::ComUnit unit); + swift::misc::aviation::CComSystem::ComUnit unit, bool active); //! Request a text message to void requestTextMessageWidget(const swift::misc::aviation::CCallsign &callsign); @@ -107,8 +107,7 @@ namespace swift::gui //! @{ //! Tune in/invoke - void tuneInAtcCom1(); - void tuneInAtcCom2(); + void tuneInAtc(misc::aviation::CComSystem::ComUnit unit, bool active); void requestTextMessage(); //! @} diff --git a/src/gui/views/atcstationview.cpp b/src/gui/views/atcstationview.cpp index bdd44f82c..8947f0b05 100644 --- a/src/gui/views/atcstationview.cpp +++ b/src/gui/views/atcstationview.cpp @@ -57,33 +57,32 @@ namespace swift::gui::views if (this->hasSelection()) { - if (m_actions.isEmpty()) { m_actions = QList({ nullptr, nullptr, nullptr }); } + if (m_actions.isEmpty()) { m_actions = QList({ nullptr, nullptr, nullptr, nullptr, nullptr }); } - m_actions[0] = - menuActions.addAction(m_actions[0], CIcons::appCockpit16(), "Tune in COM1", - CMenuAction::pathClientCom(), { this, &CAtcStationView::tuneInAtcCom1 }); - m_actions[1] = - menuActions.addAction(m_actions[1], CIcons::appCockpit16(), "Tune in COM2", - CMenuAction::pathClientCom(), { this, &CAtcStationView::tuneInAtcCom2 }); - m_actions[2] = - menuActions.addAction(m_actions[2], CIcons::appTextMessages16(), "Show text messages", + m_actions[0] = menuActions.addAction(m_actions[0], CIcons::appCockpit16(), "Tune in COM1 (active)", + CMenuAction::pathClientCom(), + { this, [this]() { tuneInAtc(CComSystem::Com1, true); } }); + m_actions[1] = menuActions.addAction(m_actions[1], CIcons::appCockpit16(), "Tune in COM2 (active)", + CMenuAction::pathClientCom(), + { this, [this]() { tuneInAtc(CComSystem::Com2, true); } }); + m_actions[2] = menuActions.addAction(m_actions[2], CIcons::appCockpit16(), "Tune in COM1 (standby)", + CMenuAction::pathClientCom(), + { this, [this]() { tuneInAtc(CComSystem::Com1, false); } }); + m_actions[3] = menuActions.addAction(m_actions[3], CIcons::appCockpit16(), "Tune in COM2 (standby)", + CMenuAction::pathClientCom(), + { this, [this]() { tuneInAtc(CComSystem::Com2, false); } }); + m_actions[4] = + menuActions.addAction(m_actions[4], CIcons::appTextMessages16(), "Show text messages", CMenuAction::pathClientCom(), { this, &CAtcStationView::requestTextMessage }); } CViewBase::customMenu(menuActions); } - void CAtcStationView::tuneInAtcCom1() + void CAtcStationView::tuneInAtc(const misc::aviation::CComSystem::ComUnit unit, const bool active) { const CAtcStation s(this->selectedObject()); if (s.getCallsign().isEmpty()) { return; } - emit this->requestComFrequency(s.getFrequency(), CComSystem::Com1); - } - - void CAtcStationView::tuneInAtcCom2() - { - const CAtcStation s(this->selectedObject()); - if (s.getCallsign().isEmpty()) { return; } - emit this->requestComFrequency(s.getFrequency(), CComSystem::Com2); + emit this->requestComFrequency(s.getFrequency(), unit, active); } void CAtcStationView::requestTextMessage() diff --git a/src/gui/views/atcstationview.h b/src/gui/views/atcstationview.h index 8bb522e12..b9e3936b7 100644 --- a/src/gui/views/atcstationview.h +++ b/src/gui/views/atcstationview.h @@ -52,7 +52,7 @@ namespace swift::gui //! Request COM frequency void requestComFrequency(const swift::misc::physical_quantities::CFrequency &frequency, - swift::misc::aviation::CComSystem::ComUnit unit); + swift::misc::aviation::CComSystem::ComUnit unit, bool active); //! Request a text message to void requestTextMessageWidget(const swift::misc::aviation::CCallsign &callsign); @@ -64,8 +64,7 @@ namespace swift::gui private: void emitTestRequest1kAtcOnlineDummies() { emit this->testRequestDummyAtcOnlineStations(1000); } void emitTestRequest3kAtcOnlineDummies() { emit this->testRequestDummyAtcOnlineStations(3000); } - void tuneInAtcCom1(); - void tuneInAtcCom2(); + void tuneInAtc(misc::aviation::CComSystem::ComUnit unit, bool active); void requestTextMessage(); QList m_actions; //!< real actions diff --git a/src/plugins/simulator/flightgear/fgswiftbusserviceproxy.cpp b/src/plugins/simulator/flightgear/fgswiftbusserviceproxy.cpp index dd991a105..31ad3a852 100644 --- a/src/plugins/simulator/flightgear/fgswiftbusserviceproxy.cpp +++ b/src/plugins/simulator/flightgear/fgswiftbusserviceproxy.cpp @@ -26,12 +26,6 @@ namespace swift::simplugin::flightgear QString(), "/fgswiftbus/service", "org.swift_project.fgswiftbus.service", "aircraftModelChanged", this, SIGNAL(aircraftModelChanged(QString, QString, QString, QString, QString, QString, QString))); Q_ASSERT(s); - - s = connection.connect( - QString(), "/fgswiftbus/service", "org.swift_project.fgswiftbus.service", "airportsInRangeUpdated", - this, - SIGNAL(airportsInRangeUpdated(QStringList, QStringList, QList, QList, QList))); - Q_ASSERT(s); } } diff --git a/src/plugins/simulator/xplane/simulatorxplane.cpp b/src/plugins/simulator/xplane/simulatorxplane.cpp index 3c6baf324..3c76ea07f 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.cpp +++ b/src/plugins/simulator/xplane/simulatorxplane.cpp @@ -215,9 +215,16 @@ namespace swift::simplugin::xplane void CSimulatorXPlane::setFlightNetworkConnected(bool connected) { if (connected && !this->isShuttingDownOrDisconnected()) { m_serviceProxy->resetFrameTotals(); } + m_serviceProxy->setFlightNetworkConnected(connected); CSimulatorPluginCommon::setFlightNetworkConnected(connected); } + void CSimulatorXPlane::setOwnCallsign(const CCallsign &callsign) + { + m_serviceProxy->setOwnCallsign(callsign.asString()); + CSimulatorPluginCommon::setOwnCallsign(callsign); + } + bool CSimulatorXPlane::isSuspiciousTerrainValue(const CElevationPlane &elevation) { if (!elevation.hasMSLGeodeticHeight()) { return true; } diff --git a/src/plugins/simulator/xplane/simulatorxplane.h b/src/plugins/simulator/xplane/simulatorxplane.h index 4403c33c1..a73c37b69 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.h +++ b/src/plugins/simulator/xplane/simulatorxplane.h @@ -150,6 +150,7 @@ namespace swift::simplugin::xplane const swift::misc::aviation::CCallsign &callsign, bool isWater) override; void setFlightNetworkConnected(bool connected) override; + void setOwnCallsign(const swift::misc::aviation::CCallsign &callsign) override; //! @} //! \copydoc swift::misc::simulation::ISimulationEnvironmentProvider::requestElevation diff --git a/src/plugins/simulator/xplane/xswiftbusserviceproxy.cpp b/src/plugins/simulator/xplane/xswiftbusserviceproxy.cpp index 3e17f5bbf..fa0e37c2a 100644 --- a/src/plugins/simulator/xplane/xswiftbusserviceproxy.cpp +++ b/src/plugins/simulator/xplane/xswiftbusserviceproxy.cpp @@ -27,11 +27,6 @@ namespace swift::simplugin::xplane SIGNAL(aircraftModelChanged(QString, QString, QString, QString, QString, QString, QString))); Q_ASSERT(s); - s = connection.connect( - QString(), "/xswiftbus/service", "org.swift_project.xswiftbus.service", "airportsInRangeUpdated", this, - SIGNAL(airportsInRangeUpdated(QStringList, QStringList, QList, QList, QList))); - Q_ASSERT(s); - s = connection.connect(QString(), "/xswiftbus/service", "org.swift_project.xswiftbus.service", "sceneryLoaded", this, SIGNAL(sceneryLoaded())); Q_ASSERT(s); @@ -363,6 +358,16 @@ namespace swift::simplugin::xplane void CXSwiftBusServiceProxy::resetFrameTotals() { m_dbusInterface->callDBus(QLatin1String("resetFrameTotals")); } + void CXSwiftBusServiceProxy::setFlightNetworkConnected(bool connected) + { + m_dbusInterface->callDBus(QLatin1String("setFlightNetworkConnected"), connected); + } + + void CXSwiftBusServiceProxy::setOwnCallsign(const QString &callsign) + { + m_dbusInterface->callDBus(QLatin1String("setOwnCallsign"), callsign); + } + double CXSwiftBusServiceProxy::getLatitudeDeg() const { return m_dbusInterface->callDBusRet(QLatin1String("getLatitudeDeg")); diff --git a/src/plugins/simulator/xplane/xswiftbusserviceproxy.h b/src/plugins/simulator/xplane/xswiftbusserviceproxy.h index bd4b8ab61..374a35e49 100644 --- a/src/plugins/simulator/xplane/xswiftbusserviceproxy.h +++ b/src/plugins/simulator/xplane/xswiftbusserviceproxy.h @@ -212,6 +212,12 @@ namespace swift::simplugin::xplane //! \copydoc XSwiftBus::CService::resetFrameTotals void resetFrameTotals(); + //! \copydoc XSwiftBus::CService::setFlightNetworkConnected + void setFlightNetworkConnected(bool connected); + + //! \copydoc XSwiftBus::CService::setOwnCallsign + void setOwnCallsign(const QString &callsign); + //! @{ //! \copydoc XSwiftBus::CService::getLatitudeDeg double getLatitudeDeg() const; diff --git a/src/xswiftbus/CMakeLists.txt b/src/xswiftbus/CMakeLists.txt index 53701274b..120d9ae7e 100644 --- a/src/xswiftbus/CMakeLists.txt +++ b/src/xswiftbus/CMakeLists.txt @@ -12,6 +12,7 @@ add_library(xswiftbus SHARED command.h config.cpp config.h + custom_datarefs.h datarefs.h dbuscallbacks.h dbusconnection.cpp diff --git a/src/xswiftbus/custom_datarefs.h b/src/xswiftbus/custom_datarefs.h new file mode 100644 index 000000000..2f8fcd174 --- /dev/null +++ b/src/xswiftbus/custom_datarefs.h @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1 + +#ifndef SWIFT_SIM_XSWIFTBUS_CUSTOM_DATAREFS_H +#define SWIFT_SIM_XSWIFTBUS_CUSTOM_DATAREFS_H + +namespace XSwiftBus +{ + //! Is swift connected to a network? + struct TSwiftNetworkConnected + { + //! Dataref name + static constexpr const char *name() { return "org/swift-project/xswiftbus/connected"; } + //! Dataref type + using type = int; + }; + + //! Current callsign + struct TSwiftCallsign + { + //! Dataref name + static constexpr const char *name() { return "org/swift-project/xswiftbus/callsign"; } + //! Dataref type + using type = std::string; + }; + +} // namespace XSwiftBus + +#endif // SWIFT_SIM_XSWIFTBUS_CUSTOM_DATAREFS_H diff --git a/src/xswiftbus/datarefs.h b/src/xswiftbus/datarefs.h index 23741ce45..4bc2fe4a4 100644 --- a/src/xswiftbus/datarefs.h +++ b/src/xswiftbus/datarefs.h @@ -9,8 +9,10 @@ #include #include +#include #include #include +#include #include // Avoid checking large auto-generated header with cppcheck @@ -223,6 +225,86 @@ namespace XSwiftBus XPLMDataRef m_ref; }; + /* Helper to conditionally fail compilation if no matching constexpr if case is found */ + template + constexpr bool dependent_false = false; + + /*! + * Class providing a custom variable + dataref + * \hint Currently only readable int and std::string datarefs are supported + * \tparam DataRefTraits The trait class representing the dataref. + */ + template + class CustomDataRef + { + public: + //! Constructor + CustomDataRef() + { + if constexpr (std::is_same_v) + { + m_ref = XPLMRegisterDataAccessor(DataRefTraits::name(), xplmType_Int, 0, readInt, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, this, nullptr); + } + else if constexpr (std::is_same_v) + { + m_ref = XPLMRegisterDataAccessor(DataRefTraits::name(), xplmType_Data, 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + readData, nullptr, this, nullptr); + } + else { static_assert(dependent_false, "Unsupported custom dataref type"); } + if (!m_ref) + { + XPLMDebugString("Missing dataref:"); + XPLMDebugString(DataRefTraits::name()); + XPLMDebugString("\n"); + } + } + + CustomDataRef(const CustomDataRef &) = delete; + CustomDataRef &operator=(const CustomDataRef &) = delete; + CustomDataRef(CustomDataRef &&other) = delete; + CustomDataRef &operator=(CustomDataRef &&other) = delete; + ~CustomDataRef() + { + if (m_ref) { XPLMUnregisterDataAccessor(m_ref); } + } + + static typename DataRefTraits::type readInt(void *refcon) + { + return reinterpret_cast(refcon)->get(); + } + + static int readData(void *refcon, void *out, int offset, int max_length) + { + if constexpr (std::is_same_v) + { + std::string_view sv(reinterpret_cast(refcon)->get()); + const size_t start = std::clamp(offset, 0, sv.size()); + const size_t remaining_length = sv.size() - start; + const auto len = std::min(static_cast(max_length), remaining_length); + sv = sv.substr(start, len); + std::memcpy(out, sv.data(), len); + return static_cast(len); + } + + return -1; // should never be reached + } + + //! True if the dataref exists + bool isValid() const { return m_ref != nullptr; } + + //! Set the value + void set(typename DataRefTraits::type val) { m_datarefVal = val; } + + //! Get the value + const typename DataRefTraits::type &get() const { return m_datarefVal; } + + XPLMDataRef m_ref; + typename DataRefTraits::type m_datarefVal; + }; + template <> inline void DataRefImpl::implSet(int d) { diff --git a/src/xswiftbus/org.swift_project.xswiftbus.service.xml b/src/xswiftbus/org.swift_project.xswiftbus.service.xml index e1df2070f..be2aec5fa 100644 --- a/src/xswiftbus/org.swift_project.xswiftbus.service.xml +++ b/src/xswiftbus/org.swift_project.xswiftbus.service.xml @@ -113,6 +113,12 @@ R"XML( + + + + + + diff --git a/src/xswiftbus/service.cpp b/src/xswiftbus/service.cpp index f3f0ea152..93f26d604 100644 --- a/src/xswiftbus/service.cpp +++ b/src/xswiftbus/service.cpp @@ -93,6 +93,8 @@ namespace XSwiftBus { this->updateMessageBoxFromSettings(); m_framePeriodSampler->show(); + m_swiftNetworkConnected.set(0); + m_swiftCallsign.set(""); } // Explicitly in cpp file to allow use of forward declaration @@ -136,6 +138,10 @@ namespace XSwiftBus } } + void CService::setFlightNetworkConnected(bool connected) { m_swiftNetworkConnected.set(connected); } + + void CService::setOwnCallsign(const std::string &callsign) { m_swiftCallsign.set(callsign); } + void CService::addTextMessage(const std::string &text, double red, double green, double blue) { if (text.empty()) { return; } @@ -509,6 +515,22 @@ namespace XSwiftBus maybeSendEmptyDBusReply(wantsReply, sender, serial); queueDBusCall([=]() { resetFrameTotals(); }); } + else if (message.getMethodName() == "setFlightNetworkConnected") + { + maybeSendEmptyDBusReply(wantsReply, sender, serial); + bool connected = false; + message.beginArgumentRead(); + message.getArgument(connected); + queueDBusCall([=]() { setFlightNetworkConnected(connected); }); + } + else if (message.getMethodName() == "setOwnCallsign") + { + maybeSendEmptyDBusReply(wantsReply, sender, serial); + std::string callsign; + message.beginArgumentRead(); + message.getArgument(callsign); + queueDBusCall([=]() { setOwnCallsign(callsign); }); + } else if (message.getMethodName() == "getLatitudeDeg") { queueDBusCall([=]() { sendDBusReply(sender, serial, getLatitudeDeg()); }); diff --git a/src/xswiftbus/service.h b/src/xswiftbus/service.h index be7b0bf3c..add910a0a 100644 --- a/src/xswiftbus/service.h +++ b/src/xswiftbus/service.h @@ -15,6 +15,7 @@ #include "datarefs.h" #include "messages.h" #include "terrainprobe.h" +#include "custom_datarefs.h" #include #include #include @@ -119,6 +120,12 @@ namespace XSwiftBus //! Reset the monitoring of total miles and minutes lost due to low frame rate. void resetFrameTotals(); + //! Set the current connection state + void setFlightNetworkConnected(bool connected); + + //! Set the current own callsign + void setOwnCallsign(const std::string &callsign); + //! Get aircraft latitude in degrees double getLatitudeDeg() const { return m_latitude.get(); } @@ -349,6 +356,8 @@ namespace XSwiftBus DataRef m_sceneryIsLoading; int m_sceneryWasLoading = 0; + CustomDataRef m_swiftNetworkConnected; + CustomDataRef m_swiftCallsign; StringDataRef m_liveryPath; StringDataRef m_icao; StringDataRef m_descrip;