From 27a5b3aae8a26493f13fef99141a4d653acacaa2 Mon Sep 17 00:00:00 2001 From: Lars Toenning Date: Sun, 16 Nov 2025 23:44:59 +0100 Subject: [PATCH 1/5] refactor: Use lambda to combine common logic --- src/gui/views/atcstationtreeview.cpp | 15 ++++----------- src/gui/views/atcstationtreeview.h | 3 +-- src/gui/views/atcstationview.cpp | 23 ++++++++--------------- src/gui/views/atcstationview.h | 3 +-- 4 files changed, 14 insertions(+), 30 deletions(-) diff --git a/src/gui/views/atcstationtreeview.cpp b/src/gui/views/atcstationtreeview.cpp index 0954491d2..78aa98afb 100644 --- a/src/gui/views/atcstationtreeview.cpp +++ b/src/gui/views/atcstationtreeview.cpp @@ -123,8 +123,8 @@ namespace swift::gui::views 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); }); + connect(com2, &QAction::triggered, this, [this]() { tuneInAtc(CComSystem::Com2); }); connect(text, &QAction::triggered, this, &CAtcStationTreeView::requestTextMessage); connect(resize, &QAction::triggered, this, &CAtcStationTreeView::fullResizeToContentsImpl); @@ -160,18 +160,11 @@ namespace swift::gui::views } } - void CAtcStationTreeView::tuneInAtcCom1() + void CAtcStationTreeView::tuneInAtc(const misc::aviation::CComSystem::ComUnit unit) { 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); } void CAtcStationTreeView::requestTextMessage() diff --git a/src/gui/views/atcstationtreeview.h b/src/gui/views/atcstationtreeview.h index 1041fa425..80e146a53 100644 --- a/src/gui/views/atcstationtreeview.h +++ b/src/gui/views/atcstationtreeview.h @@ -107,8 +107,7 @@ namespace swift::gui //! @{ //! Tune in/invoke - void tuneInAtcCom1(); - void tuneInAtcCom2(); + void tuneInAtc(misc::aviation::CComSystem::ComUnit unit); void requestTextMessage(); //! @} diff --git a/src/gui/views/atcstationview.cpp b/src/gui/views/atcstationview.cpp index bdd44f82c..1f9032672 100644 --- a/src/gui/views/atcstationview.cpp +++ b/src/gui/views/atcstationview.cpp @@ -59,12 +59,12 @@ namespace swift::gui::views { if (m_actions.isEmpty()) { m_actions = QList({ 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[0] = menuActions.addAction(m_actions[0], CIcons::appCockpit16(), "Tune in COM1", + CMenuAction::pathClientCom(), + { this, [this]() { tuneInAtc(CComSystem::Com1); } }); + m_actions[1] = menuActions.addAction(m_actions[1], CIcons::appCockpit16(), "Tune in COM2", + CMenuAction::pathClientCom(), + { this, [this]() { tuneInAtc(CComSystem::Com2); } }); m_actions[2] = menuActions.addAction(m_actions[2], CIcons::appTextMessages16(), "Show text messages", CMenuAction::pathClientCom(), { this, &CAtcStationView::requestTextMessage }); @@ -72,18 +72,11 @@ namespace swift::gui::views CViewBase::customMenu(menuActions); } - void CAtcStationView::tuneInAtcCom1() + void CAtcStationView::tuneInAtc(const misc::aviation::CComSystem::ComUnit unit) { 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); } void CAtcStationView::requestTextMessage() diff --git a/src/gui/views/atcstationview.h b/src/gui/views/atcstationview.h index 8bb522e12..8c06f69d7 100644 --- a/src/gui/views/atcstationview.h +++ b/src/gui/views/atcstationview.h @@ -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); void requestTextMessage(); QList m_actions; //!< real actions From c830b862bed17fe4109023404dbc375603114407 Mon Sep 17 00:00:00 2001 From: Lars Toenning Date: Sun, 16 Nov 2025 23:39:49 +0100 Subject: [PATCH 2/5] feat: Allow to tune STBY frequency from context menu Fixes #274 --- src/core/context/contextownaircraft.h | 7 +++++- src/core/context/contextownaircraftempty.h | 12 ++++++++++ src/core/context/contextownaircraftimpl.cpp | 20 ++++++++++++++++ src/core/context/contextownaircraftimpl.h | 5 ++++ src/core/context/contextownaircraftproxy.cpp | 8 +++++++ src/core/context/contextownaircraftproxy.h | 5 ++++ src/gui/components/atcstationcomponent.cpp | 5 ++-- src/gui/components/atcstationcomponent.h | 2 +- src/gui/views/atcstationtreeview.cpp | 18 ++++++++++----- src/gui/views/atcstationtreeview.h | 4 ++-- src/gui/views/atcstationview.cpp | 24 ++++++++++++-------- src/gui/views/atcstationview.h | 4 ++-- 12 files changed, 91 insertions(+), 23 deletions(-) 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/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 78aa98afb..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, [this]() { tuneInAtc(CComSystem::Com1); }); - connect(com2, &QAction::triggered, this, [this]() { tuneInAtc(CComSystem::Com2); }); + 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,11 +166,11 @@ namespace swift::gui::views } } - void CAtcStationTreeView::tuneInAtc(const misc::aviation::CComSystem::ComUnit unit) + 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(), unit); + 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 80e146a53..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,7 +107,7 @@ namespace swift::gui //! @{ //! Tune in/invoke - void tuneInAtc(misc::aviation::CComSystem::ComUnit unit); + 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 1f9032672..8947f0b05 100644 --- a/src/gui/views/atcstationview.cpp +++ b/src/gui/views/atcstationview.cpp @@ -57,26 +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", + m_actions[0] = menuActions.addAction(m_actions[0], CIcons::appCockpit16(), "Tune in COM1 (active)", CMenuAction::pathClientCom(), - { this, [this]() { tuneInAtc(CComSystem::Com1); } }); - m_actions[1] = menuActions.addAction(m_actions[1], CIcons::appCockpit16(), "Tune in COM2", + { 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); } }); - m_actions[2] = - menuActions.addAction(m_actions[2], CIcons::appTextMessages16(), "Show text messages", + { 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::tuneInAtc(const misc::aviation::CComSystem::ComUnit unit) + 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(), unit); + 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 8c06f69d7..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,7 +64,7 @@ namespace swift::gui private: void emitTestRequest1kAtcOnlineDummies() { emit this->testRequestDummyAtcOnlineStations(1000); } void emitTestRequest3kAtcOnlineDummies() { emit this->testRequestDummyAtcOnlineStations(3000); } - void tuneInAtc(misc::aviation::CComSystem::ComUnit unit); + void tuneInAtc(misc::aviation::CComSystem::ComUnit unit, bool active); void requestTextMessage(); QList m_actions; //!< real actions From ae8807e543bdbfb41c6ef1c670b664c79ce5f4c5 Mon Sep 17 00:00:00 2001 From: Lars Toenning Date: Sat, 29 Nov 2025 12:26:08 +0100 Subject: [PATCH 3/5] fix: Remove outdated signal connection This was removed with edbabe34b --- src/plugins/simulator/flightgear/fgswiftbusserviceproxy.cpp | 6 ------ src/plugins/simulator/xplane/xswiftbusserviceproxy.cpp | 5 ----- 2 files changed, 11 deletions(-) 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/xswiftbusserviceproxy.cpp b/src/plugins/simulator/xplane/xswiftbusserviceproxy.cpp index 3e17f5bbf..8a8e4d7b7 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); From a71b8e349196e3a242e19f0324d3fa40907f1931 Mon Sep 17 00:00:00 2001 From: Lars Toenning Date: Sun, 17 Nov 2024 14:44:34 +0100 Subject: [PATCH 4/5] feat: Add custom X-Plane dataref for connection state Fixes #304 --- .../simulator/xplane/simulatorxplane.cpp | 1 + .../xplane/xswiftbusserviceproxy.cpp | 5 ++ .../simulator/xplane/xswiftbusserviceproxy.h | 3 ++ src/xswiftbus/CMakeLists.txt | 1 + src/xswiftbus/custom_datarefs.h | 24 +++++++++ src/xswiftbus/datarefs.h | 52 +++++++++++++++++++ .../org.swift_project.xswiftbus.service.xml | 3 ++ src/xswiftbus/service.cpp | 11 ++++ src/xswiftbus/service.h | 5 ++ 9 files changed, 105 insertions(+) create mode 100644 src/xswiftbus/custom_datarefs.h diff --git a/src/plugins/simulator/xplane/simulatorxplane.cpp b/src/plugins/simulator/xplane/simulatorxplane.cpp index 3c6baf324..8eff69211 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.cpp +++ b/src/plugins/simulator/xplane/simulatorxplane.cpp @@ -215,6 +215,7 @@ namespace swift::simplugin::xplane void CSimulatorXPlane::setFlightNetworkConnected(bool connected) { if (connected && !this->isShuttingDownOrDisconnected()) { m_serviceProxy->resetFrameTotals(); } + m_serviceProxy->setFlightNetworkConnected(connected); CSimulatorPluginCommon::setFlightNetworkConnected(connected); } diff --git a/src/plugins/simulator/xplane/xswiftbusserviceproxy.cpp b/src/plugins/simulator/xplane/xswiftbusserviceproxy.cpp index 8a8e4d7b7..8c8040107 100644 --- a/src/plugins/simulator/xplane/xswiftbusserviceproxy.cpp +++ b/src/plugins/simulator/xplane/xswiftbusserviceproxy.cpp @@ -358,6 +358,11 @@ namespace swift::simplugin::xplane void CXSwiftBusServiceProxy::resetFrameTotals() { m_dbusInterface->callDBus(QLatin1String("resetFrameTotals")); } + void CXSwiftBusServiceProxy::setFlightNetworkConnected(bool connected) + { + m_dbusInterface->callDBus(QLatin1String("setFlightNetworkConnected"), connected); + } + 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..943735ed1 100644 --- a/src/plugins/simulator/xplane/xswiftbusserviceproxy.h +++ b/src/plugins/simulator/xplane/xswiftbusserviceproxy.h @@ -212,6 +212,9 @@ namespace swift::simplugin::xplane //! \copydoc XSwiftBus::CService::resetFrameTotals void resetFrameTotals(); + //! \copydoc XSwiftBus::CService::setFlightNetworkConnected + void setFlightNetworkConnected(bool connected); + //! @{ //! \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..626c93310 --- /dev/null +++ b/src/xswiftbus/custom_datarefs.h @@ -0,0 +1,24 @@ +// 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"; } + //! Can be written to? + static constexpr bool writable = false; + //! Dataref type + using type = int; + //! Not an array dataref + static constexpr bool is_array = false; + }; + +} // namespace XSwiftBus + +#endif // SWIFT_SIM_XSWIFTBUS_CUSTOM_DATAREFS_H diff --git a/src/xswiftbus/datarefs.h b/src/xswiftbus/datarefs.h index 23741ce45..c64861b04 100644 --- a/src/xswiftbus/datarefs.h +++ b/src/xswiftbus/datarefs.h @@ -223,6 +223,58 @@ namespace XSwiftBus XPLMDataRef m_ref; }; + /*! + * Class providing a custom variable + dataref + * \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, read, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, this, NULL); + } + else { XPLMDebugString("Unsupported custom dataref type\n"); } + 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 read(void *refcon) + { + return reinterpret_cast(refcon)->get(); + } + + //! 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 + 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..28de2e282 100644 --- a/src/xswiftbus/org.swift_project.xswiftbus.service.xml +++ b/src/xswiftbus/org.swift_project.xswiftbus.service.xml @@ -113,6 +113,9 @@ R"XML( + + + diff --git a/src/xswiftbus/service.cpp b/src/xswiftbus/service.cpp index f3f0ea152..4f1a467d3 100644 --- a/src/xswiftbus/service.cpp +++ b/src/xswiftbus/service.cpp @@ -93,6 +93,7 @@ namespace XSwiftBus { this->updateMessageBoxFromSettings(); m_framePeriodSampler->show(); + m_swiftNetworkConnected.set(0); } // Explicitly in cpp file to allow use of forward declaration @@ -136,6 +137,8 @@ namespace XSwiftBus } } + void CService::setFlightNetworkConnected(bool connected) { m_swiftNetworkConnected.set(connected); } + void CService::addTextMessage(const std::string &text, double red, double green, double blue) { if (text.empty()) { return; } @@ -509,6 +512,14 @@ 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() == "getLatitudeDeg") { queueDBusCall([=]() { sendDBusReply(sender, serial, getLatitudeDeg()); }); diff --git a/src/xswiftbus/service.h b/src/xswiftbus/service.h index be7b0bf3c..c4f2936d2 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,9 @@ 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); + //! Get aircraft latitude in degrees double getLatitudeDeg() const { return m_latitude.get(); } @@ -349,6 +353,7 @@ namespace XSwiftBus DataRef m_sceneryIsLoading; int m_sceneryWasLoading = 0; + CustomDataRef m_swiftNetworkConnected; StringDataRef m_liveryPath; StringDataRef m_icao; StringDataRef m_descrip; From 2cb18c5b90d96c007994462a6a8c471989bc5c31 Mon Sep 17 00:00:00 2001 From: Lars Toenning Date: Fri, 12 Dec 2025 20:28:04 +0100 Subject: [PATCH 5/5] feat(xswiftbus): Expose callsign as dataref Fixes #379 --- src/core/context/contextsimulatorimpl.cpp | 4 ++ src/core/simulator.cpp | 6 +++ src/core/simulator.h | 3 ++ .../simulator/xplane/simulatorxplane.cpp | 6 +++ .../simulator/xplane/simulatorxplane.h | 1 + .../xplane/xswiftbusserviceproxy.cpp | 5 +++ .../simulator/xplane/xswiftbusserviceproxy.h | 3 ++ src/xswiftbus/custom_datarefs.h | 13 ++++-- src/xswiftbus/datarefs.h | 40 ++++++++++++++++--- .../org.swift_project.xswiftbus.service.xml | 3 ++ src/xswiftbus/service.cpp | 11 +++++ src/xswiftbus/service.h | 4 ++ 12 files changed, 90 insertions(+), 9 deletions(-) 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/plugins/simulator/xplane/simulatorxplane.cpp b/src/plugins/simulator/xplane/simulatorxplane.cpp index 8eff69211..3c76ea07f 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.cpp +++ b/src/plugins/simulator/xplane/simulatorxplane.cpp @@ -219,6 +219,12 @@ namespace swift::simplugin::xplane 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 8c8040107..fa0e37c2a 100644 --- a/src/plugins/simulator/xplane/xswiftbusserviceproxy.cpp +++ b/src/plugins/simulator/xplane/xswiftbusserviceproxy.cpp @@ -363,6 +363,11 @@ namespace swift::simplugin::xplane 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 943735ed1..374a35e49 100644 --- a/src/plugins/simulator/xplane/xswiftbusserviceproxy.h +++ b/src/plugins/simulator/xplane/xswiftbusserviceproxy.h @@ -215,6 +215,9 @@ namespace swift::simplugin::xplane //! \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/custom_datarefs.h b/src/xswiftbus/custom_datarefs.h index 626c93310..2f8fcd174 100644 --- a/src/xswiftbus/custom_datarefs.h +++ b/src/xswiftbus/custom_datarefs.h @@ -11,12 +11,17 @@ namespace XSwiftBus { //! Dataref name static constexpr const char *name() { return "org/swift-project/xswiftbus/connected"; } - //! Can be written to? - static constexpr bool writable = false; //! Dataref type using type = int; - //! Not an array dataref - static constexpr bool is_array = false; + }; + + //! 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 diff --git a/src/xswiftbus/datarefs.h b/src/xswiftbus/datarefs.h index c64861b04..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,8 +225,13 @@ 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 @@ -236,10 +243,17 @@ namespace XSwiftBus { if constexpr (std::is_same_v) { - m_ref = XPLMRegisterDataAccessor(DataRefTraits::name(), xplmType_Int, 0, read, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, this, NULL); + 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 { XPLMDebugString("Unsupported custom dataref type\n"); } + else { static_assert(dependent_false, "Unsupported custom dataref type"); } if (!m_ref) { XPLMDebugString("Missing dataref:"); @@ -257,11 +271,27 @@ namespace XSwiftBus if (m_ref) { XPLMUnregisterDataAccessor(m_ref); } } - static typename DataRefTraits::type read(void *refcon) + 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; } @@ -269,7 +299,7 @@ namespace XSwiftBus void set(typename DataRefTraits::type val) { m_datarefVal = val; } //! Get the value - typename DataRefTraits::type get() const { return m_datarefVal; } + const typename DataRefTraits::type &get() const { return m_datarefVal; } XPLMDataRef m_ref; typename DataRefTraits::type m_datarefVal; diff --git a/src/xswiftbus/org.swift_project.xswiftbus.service.xml b/src/xswiftbus/org.swift_project.xswiftbus.service.xml index 28de2e282..be2aec5fa 100644 --- a/src/xswiftbus/org.swift_project.xswiftbus.service.xml +++ b/src/xswiftbus/org.swift_project.xswiftbus.service.xml @@ -116,6 +116,9 @@ R"XML( + + + diff --git a/src/xswiftbus/service.cpp b/src/xswiftbus/service.cpp index 4f1a467d3..93f26d604 100644 --- a/src/xswiftbus/service.cpp +++ b/src/xswiftbus/service.cpp @@ -94,6 +94,7 @@ namespace XSwiftBus this->updateMessageBoxFromSettings(); m_framePeriodSampler->show(); m_swiftNetworkConnected.set(0); + m_swiftCallsign.set(""); } // Explicitly in cpp file to allow use of forward declaration @@ -139,6 +140,8 @@ 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; } @@ -520,6 +523,14 @@ namespace XSwiftBus 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 c4f2936d2..add910a0a 100644 --- a/src/xswiftbus/service.h +++ b/src/xswiftbus/service.h @@ -123,6 +123,9 @@ namespace XSwiftBus //! 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(); } @@ -354,6 +357,7 @@ namespace XSwiftBus int m_sceneryWasLoading = 0; CustomDataRef m_swiftNetworkConnected; + CustomDataRef m_swiftCallsign; StringDataRef m_liveryPath; StringDataRef m_icao; StringDataRef m_descrip;