From fc84673bb98f603ae100d8f972dae2cbf277ebd9 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sun, 31 Aug 2014 15:54:19 +0200 Subject: [PATCH] Handled performance issues and bugs noticed during testing of refs #319 / refs #322 * discussion: https://dev.vatsim-germany.org/boards/22/topics/2027?r=2040#message-2040 * fixed bug with ATC station component, wrong signals for booked stations * booked stations loading to frequently (for each minor change such as online), changed to timestamp based concept * update booked stations with receiving ATIS/voiceroom to online * CDigestSignal class: new class and methods for collecting signals, avoiding too many signals - one of the cures for the performance issues * fixed bug found during testing, missing start for timers when connecting to network --- src/blackcore/airspace_monitor.cpp | 32 ++++++---- src/blackcore/context_network.h | 13 +++- src/blackcore/context_network_impl.h | 11 +++- src/blackcore/context_network_proxy.cpp | 12 ++++ .../components/atcstationcomponent.cpp | 62 +++++++++++-------- src/blackgui/components/atcstationcomponent.h | 23 +++---- src/blackgui/components/timerbasedcomponent.h | 8 +++ src/blackmisc/digestsignal.cpp | 36 +++++++++++ src/blackmisc/digestsignal.h | 58 +++++++++++++++++ src/swiftgui_standard/mainwindow.cpp | 3 +- src/swiftgui_standard/mainwindow.h | 4 +- src/swiftgui_standard/mainwindow_init.cpp | 10 +-- 12 files changed, 209 insertions(+), 63 deletions(-) create mode 100644 src/blackmisc/digestsignal.cpp create mode 100644 src/blackmisc/digestsignal.h diff --git a/src/blackcore/airspace_monitor.cpp b/src/blackcore/airspace_monitor.cpp index fbfdcfe83..2a526f50e 100644 --- a/src/blackcore/airspace_monitor.cpp +++ b/src/blackcore/airspace_monitor.cpp @@ -248,7 +248,7 @@ namespace BlackCore if (callsign.isEmpty() || model.isEmpty()) return; // Request of other client, I can get the other's model from that - CIndexVariantMap vm( { CClient::IndexModel, CAircraftModel::IndexModelString }, QVariant(model)); + CIndexVariantMap vm({ CClient::IndexModel, CAircraftModel::IndexModelString }, QVariant(model)); vm.addValue({ CClient::IndexModel, CAircraftModel::IndexIsQueriedModelString }, QVariant(true)); if (!this->m_otherClients.contains(&CClient::getCallsign, callsign)) { @@ -280,8 +280,8 @@ namespace BlackCore this->m_atcStationsOnline.applyIf(&CAtcStation::getCallsign, callsignTower, vm); this->m_atcStationsBooked.applyIf(&CAtcStation::getCallsign, callsignTower, vm); this->m_metarCache.insert(icaoCode, metar); - if (this->m_atcStationsOnline.contains(&CAtcStation::getCallsign, callsignTower)) emit this->changedAtcStationsOnline(); - if (this->m_atcStationsBooked.contains(&CAtcStation::getCallsign, callsignTower)) emit this->changedAtcStationsBooked(); + if (this->m_atcStationsOnline.contains(&CAtcStation::getCallsign, callsignTower)) { emit this->changedAtcStationsOnline(); } + if (this->m_atcStationsBooked.contains(&CAtcStation::getCallsign, callsignTower)) { emit this->changedAtcStationsBooked(); } } void CAirspaceMonitor::ps_flightplanReceived(const CCallsign &callsign, const CFlightPlan &flightPlan) @@ -322,6 +322,7 @@ namespace BlackCore // into list this->m_atcStationsBooked.push_back(bookedStation); } + emit this->changedAtcStationsBooked(); // all booked stations reloaded } void CAirspaceMonitor::ps_atcPositionUpdate(const CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &frequency, const CCoordinateGeodetic &position, const BlackMisc::PhysicalQuantities::CLength &range) @@ -385,9 +386,12 @@ namespace BlackCore if (callsign.isEmpty()) return; CIndexVariantMap vm(CAtcStation::IndexAtis, atisMessage.toQVariant()); this->m_atcStationsOnline.applyIf(&CAtcStation::getCallsign, callsign, vm); + + // receiving an ATIS means station is online, update in bookings + vm.addValue(CAtcStation::IndexIsOnline, true); this->m_atcStationsBooked.applyIf(&CAtcStation::getCallsign, callsign, vm); - if (this->m_atcStationsOnline.contains(&CAtcStation::getCallsign, callsign)) emit this->changedAtcStationsBooked(); - if (this->m_atcStationsBooked.contains(&CAtcStation::getCallsign, callsign)) emit this->changedAtcStationsBooked(); + if (this->m_atcStationsOnline.contains(&CAtcStation::getCallsign, callsign)) { emit this->changedAtcStationsOnline(); } + if (this->m_atcStationsBooked.contains(&CAtcStation::getCallsign, callsign)) { emit this->changedAtcStationsBooked(); } } void CAirspaceMonitor::ps_atisVoiceRoomReceived(const CCallsign &callsign, const QString &url) @@ -395,18 +399,20 @@ namespace BlackCore Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this)); QString trimmedUrl = url.trimmed(); CIndexVariantMap vm({ CAtcStation::IndexVoiceRoom, CVoiceRoom::IndexUrl }, trimmedUrl); - if (this->m_atcStationsBooked.contains(&CAtcStation::getCallsign, callsign)) - { - this->m_atcStationsBooked.applyIf(&CAtcStation::getCallsign, callsign, vm); - emit this->changedAtcStationsBooked(); - } if (this->m_atcStationsOnline.contains(&CAtcStation::getCallsign, callsign)) { this->m_atcStationsOnline.applyIf(&CAtcStation::getCallsign, callsign, vm); CAtcStation station = this->m_atcStationsOnline.findFirstByCallsign(callsign); - emit this->changedAtcStationsBooked(); + emit this->changedAtcStationsOnline(); // single ATIS received emit this->changedAtcStationOnlineConnectionStatus(station, true); } + if (this->m_atcStationsBooked.contains(&CAtcStation::getCallsign, callsign)) + { + // receiving a voice room means station is online, update in bookings + vm.addValue(CAtcStation::IndexIsOnline, true); + this->m_atcStationsBooked.applyIf(&CAtcStation::getCallsign, callsign, vm); + emit this->changedAtcStationsBooked(); // single ATIS received + } vm = CIndexVariantMap(CClient::IndexVoiceCapabilities, CVoiceCapabilities(CVoiceCapabilities::Voice).toQVariant()); this->m_otherClients.applyIf(&CClient::getCallsign, callsign, vm); } @@ -427,8 +433,8 @@ namespace BlackCore CIndexVariantMap vm(CAtcStation::IndexBookedUntil, logoffDateTime); this->m_atcStationsOnline.applyIf(&CAtcStation::getCallsign, callsign, vm); this->m_atcStationsBooked.applyIf(&CAtcStation::getCallsign, callsign, vm); - if (this->m_atcStationsOnline.contains(&CAtcStation::getCallsign, callsign)) emit this->changedAtcStationsBooked(); - if (this->m_atcStationsBooked.contains(&CAtcStation::getCallsign, callsign)) emit this->changedAtcStationsBooked(); + if (this->m_atcStationsOnline.contains(&CAtcStation::getCallsign, callsign)) { emit this->changedAtcStationsOnline(); } + if (this->m_atcStationsBooked.contains(&CAtcStation::getCallsign, callsign)) { emit this->changedAtcStationsBooked(); } } } diff --git a/src/blackcore/context_network.h b/src/blackcore/context_network.h index 7850b7229..61256719d 100644 --- a/src/blackcore/context_network.h +++ b/src/blackcore/context_network.h @@ -66,18 +66,27 @@ namespace BlackCore //! ATC station (online) list has been changed void changedAtcStationsOnline(); + //! Digest signal changedAtcStationsOnline() + void changedAtcStationsOnlineDigest(); + //! ATC station (booked) list has been changed void changedAtcStationsBooked(); - //! Connection status changed for online station - void changedAtcStationOnlineConnectionStatus(const BlackMisc::Aviation::CAtcStation &atcStation, bool connected); + //! Digest signal changedAtcStationsBooked() + void changedAtcStationsBookedDigest(); //! Aircraft list has been changed void changedAircraftsInRange(); + //! Digest signal changedAircraftsInRange() + void changedAircraftsInRangeDigest(); + //! Aircraft situation update void changedAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situation); + //! Connection status changed for online station + void changedAtcStationOnlineConnectionStatus(const BlackMisc::Aviation::CAtcStation &atcStation, bool connected); + //! Terminated connection void connectionTerminated(); diff --git a/src/blackcore/context_network_impl.h b/src/blackcore/context_network_impl.h index f68bf7a51..e72dee31c 100644 --- a/src/blackcore/context_network_impl.h +++ b/src/blackcore/context_network_impl.h @@ -21,6 +21,7 @@ #include "blackmisc/avatcstationlist.h" #include "blackmisc/setnetwork.h" #include "blackmisc/nwclientlist.h" +#include "blackmisc/digestsignal.h" #include @@ -46,7 +47,7 @@ namespace BlackCore //! Airspace monitor accessible to other contexts CAirspaceMonitor *getAirspaceMonitor() const { return m_airspace; } - public slots: // IContextNetwork overrides + public slots: //! \copydoc IContextNetwork::readAtcBookingsFromSource() virtual void readAtcBookingsFromSource() const override; @@ -145,12 +146,16 @@ namespace BlackCore private: static const auto c_logContext = CRuntime::LogForNetwork; - CAirspaceMonitor *m_airspace; + CAirspaceMonitor *m_airspace; BlackCore::INetwork *m_network; INetwork::ConnectionStatus m_currentStatus; //!< used to detect pending connections + BlackMisc::CDigestSignal m_dsAtcStationsBookedChanged { this, &IContextNetwork::changedAtcStationsBooked, &IContextNetwork::changedAtcStationsBookedDigest, 750, 2 }; + BlackMisc::CDigestSignal m_dsAtcStationsOnlineChanged { this, &IContextNetwork::changedAtcStationsOnline, &IContextNetwork::changedAtcStationsOnlineDigest, 750, 2 }; + BlackMisc::CDigestSignal m_dsAircraftsInRangeChanged { this, &IContextNetwork::changedAircraftsInRange, &IContextNetwork::changedAircraftsInRangeDigest, 750, 2 }; + // for reading XML and VATSIM data files - CVatsimBookingReader *m_vatsimBookingReader; + CVatsimBookingReader *m_vatsimBookingReader; CVatsimDataFileReader *m_vatsimDataFileReader; QTimer *m_dataUpdateTimer; //!< general updates such as ATIS, frequencies, see requestDataUpdates() diff --git a/src/blackcore/context_network_proxy.cpp b/src/blackcore/context_network_proxy.cpp index 6c7394dbf..e14346404 100644 --- a/src/blackcore/context_network_proxy.cpp +++ b/src/blackcore/context_network_proxy.cpp @@ -37,9 +37,21 @@ namespace BlackCore s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), "changedAtcStationsOnline", this, SIGNAL(changedAtcStationsOnline())); Q_ASSERT(s); + s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), + "changedAtcStationsBookedDigest", this, SIGNAL(changedAtcStationsBookedDigest())); + Q_ASSERT(s); + s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), + "changedAtcStationsOnlineDigest", this, SIGNAL(changedAtcStationsOnlineDigest())); + Q_ASSERT(s); + s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), + "changedAircraftsInRange", this, SIGNAL(changedAircraftsInRange())); + Q_ASSERT(s); s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), "changedAtcStationOnlineConnectionStatus", this, SIGNAL(changedAtcStationOnlineConnectionStatus(BlackMisc::Aviation::CAtcStation, bool))); Q_ASSERT(s); + s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), + "changedAircraftsInRangeDigest", this, SIGNAL(changedAircraftsInRangeDigest())); + Q_ASSERT(s); s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), "connectionTerminated", this, SIGNAL(connectionTerminated())); Q_ASSERT(s); diff --git a/src/blackgui/components/atcstationcomponent.cpp b/src/blackgui/components/atcstationcomponent.cpp index c753fd4fc..637eb38f4 100644 --- a/src/blackgui/components/atcstationcomponent.cpp +++ b/src/blackgui/components/atcstationcomponent.cpp @@ -26,6 +26,9 @@ namespace BlackGui { ui->setupUi(this); this->m_timerComponent = new CTimerBasedComponent(SLOT(update()), this); + + // set station mode + this->ui->tvp_AtcStationsOnline->setStationMode(CAtcStationListModel::StationsOnline); this->ui->tvp_AtcStationsBooked->setStationMode(CAtcStationListModel::StationsBooked); // Signal / Slots @@ -33,10 +36,10 @@ namespace BlackGui Q_ASSERT(connected); connected = this->connect(this->ui->pb_AtcStationsLoadMetar, SIGNAL(clicked()), this, SLOT(getMetar())); Q_ASSERT(connected); - this->connect(this, &QTabWidget::currentChanged, this, &CAtcStationComponent::atcStationsTabChanged); - this->connect(this->ui->tvp_AtcStationsOnline, &QTableView::clicked, this, &CAtcStationComponent::onlineAtcStationSelected); - this->connect(this->ui->pb_AtcStationsAtisReload, &QPushButton::clicked, this, &CAtcStationComponent::requestAtis); - this->connect(this->ui->pb_ReloadAtcStationsBooked, &QPushButton::clicked, this, &CAtcStationComponent::reloadAtcStationsBooked); + this->connect(this, &QTabWidget::currentChanged, this, &CAtcStationComponent::ps_atcStationsTabChanged); + this->connect(this->ui->tvp_AtcStationsOnline, &QTableView::clicked, this, &CAtcStationComponent::ps_onlineAtcStationSelected); + this->connect(this->ui->pb_AtcStationsAtisReload, &QPushButton::clicked, this, &CAtcStationComponent::ps_requestAtis); + this->connect(this->ui->pb_ReloadAtcStationsBooked, &QPushButton::clicked, this, &CAtcStationComponent::ps_reloadAtcStationsBooked); } CAtcStationComponent::~CAtcStationComponent() @@ -50,10 +53,10 @@ namespace BlackGui Q_ASSERT(this->getIContextNetwork()); if (this->getIContextNetwork()) { - this->connect(this->getIContextNetwork(), &IContextNetwork::changedAtcStationsOnline, this, &CAtcStationComponent::changedAtcStationsOnline); - this->connect(this->getIContextNetwork(), &IContextNetwork::changedAtcStationsBooked, this, &CAtcStationComponent::changedAtcStationsBooked); + this->connect(this->getIContextNetwork(), &IContextNetwork::changedAtcStationsOnlineDigest, this, &CAtcStationComponent::ps_changedAtcStationsOnline); + this->connect(this->getIContextNetwork(), &IContextNetwork::changedAtcStationsBookedDigest, this, &CAtcStationComponent::ps_changedAtcStationsBooked); this->connect(this->getIContextNetwork(), &IContextNetwork::changedAtcStationOnlineConnectionStatus, this, &CAtcStationComponent::changedAtcStationOnlineConnectionStatus); - this->connect(this->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this, &CAtcStationComponent::connectionStatusChanged); + this->connect(this->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this, &CAtcStationComponent::ps_connectionStatusChanged); } } @@ -63,14 +66,17 @@ namespace BlackGui Q_ASSERT(this->ui->tvp_AtcStationsOnline); Q_ASSERT(this->getIContextNetwork()); - // initial read for bookings - if (this->ui->tvp_AtcStationsBooked->isEmpty()) this->reloadAtcStationsBooked(); + // bookings + if (this->m_timestampBookedStationsChanged > this->m_timestampLastReadBookedStations) + { + this->ps_reloadAtcStationsBooked(); + } + // online stations, only when connected if (this->getIContextNetwork()->isConnected()) { // update - if (this->m_timestampOnlineStationsChanged.isNull() || this->m_timestampLastReadOnlineStations.isNull() || - (this->m_timestampOnlineStationsChanged > this->m_timestampLastReadOnlineStations)) + if (this->m_timestampOnlineStationsChanged > this->m_timestampLastReadOnlineStations) { this->ui->tvp_AtcStationsOnline->updateContainer(this->getIContextNetwork()->getAtcStationsOnline()); this->m_timestampLastReadOnlineStations = QDateTime::currentDateTimeUtc(); @@ -84,7 +90,7 @@ namespace BlackGui } } - void CAtcStationComponent::reloadAtcStationsBooked() + void CAtcStationComponent::ps_reloadAtcStationsBooked() { Q_ASSERT(this->ui->tvp_AtcStationsBooked); Q_ASSERT(this->getIContextNetwork()); @@ -92,8 +98,8 @@ namespace BlackGui QObject *sender = QObject::sender(); if (sender == this->ui->pb_ReloadAtcStationsBooked && this->getIContextNetwork()) { - this->getIContextNetwork()->readAtcBookingsFromSource(); // trigger new read - QTimer::singleShot(7500, this, SLOT(reloadAtcStationsBooked())); // deferred loading + // trigger new read, which takes some time. A signal will be received when this is done + this->getIContextNetwork()->readAtcBookingsFromSource(); } else { @@ -102,14 +108,23 @@ namespace BlackGui } } - void CAtcStationComponent::changedAtcStationsOnline() + void CAtcStationComponent::ps_changedAtcStationsOnline() { - // just update timestamp, data will be pulled by time + // just update timestamp, data will be pulled by timer // the timestamp will tell if there are any newer data this->m_timestampOnlineStationsChanged = QDateTime::currentDateTimeUtc(); } - void CAtcStationComponent::connectionStatusChanged(uint from, uint to, const QString &message) + void CAtcStationComponent::ps_changedAtcStationsBooked() + { + // a change can mean a complete change of the bookings, or + // a single value is updated (e.g. online status) + // just update timestamp, data will be pulled by timer + // the timestamp will tell if there are any newer data + this->m_timestampBookedStationsChanged = QDateTime::currentDateTimeUtc(); + } + + void CAtcStationComponent::ps_connectionStatusChanged(uint from, uint to, const QString &message) { INetwork::ConnectionStatus fromStatus = static_cast(from); INetwork::ConnectionStatus toStatus = static_cast(to); @@ -127,11 +142,6 @@ namespace BlackGui this->ui->tvp_AtcStationsOnline->changedAtcStationConnectionStatus(station, added); } - void CAtcStationComponent::changedAtcStationsBooked() - { - this->reloadAtcStationsBooked(); - } - void CAtcStationComponent::getMetar(const QString &airportIcaoCode) { if (!this->getIContextNetwork()->isConnected()) @@ -154,7 +164,7 @@ namespace BlackGui } } - void CAtcStationComponent::onlineAtcStationSelected(QModelIndex index) + void CAtcStationComponent::ps_onlineAtcStationSelected(QModelIndex index) { this->ui->te_AtcStationsOnlineInfo->setText(""); // reset const CAtcStation stationClicked = this->ui->tvp_AtcStationsOnline->derivedModel()->at(index); @@ -172,16 +182,16 @@ namespace BlackGui this->ui->te_AtcStationsOnlineInfo->setText(infoMessage); } - void CAtcStationComponent::atcStationsTabChanged() + void CAtcStationComponent::ps_atcStationsTabChanged() { if (this->currentWidget() == this->ui->tb_AtcStationsOnline) { if (this->m_timestampLastReadBookedStations.isNull()) - this->reloadAtcStationsBooked(); + this->ps_reloadAtcStationsBooked(); } } - void CAtcStationComponent::requestAtis() + void CAtcStationComponent::ps_requestAtis() { if (!this->getIContextNetwork()->isConnected()) return; this->getIContextNetwork()->requestAtisUpdates(); diff --git a/src/blackgui/components/atcstationcomponent.h b/src/blackgui/components/atcstationcomponent.h index 47d89b4f9..d5994b9ff 100644 --- a/src/blackgui/components/atcstationcomponent.h +++ b/src/blackgui/components/atcstationcomponent.h @@ -68,32 +68,33 @@ namespace BlackGui private slots: //! Request new ATIS - void requestAtis(); + void ps_requestAtis(); //! Online ATC station selected - void onlineAtcStationSelected(QModelIndex index); + void ps_onlineAtcStationSelected(QModelIndex index); //! Tab changed - void atcStationsTabChanged(); + void ps_atcStationsTabChanged(); - //! Booked stations - void reloadAtcStationsBooked(); + //! Booked stations reloading + void ps_reloadAtcStationsBooked(); //! Booked stations changed - void changedAtcStationsBooked(); + void ps_changedAtcStationsBooked(); //! Online stations changed - void changedAtcStationsOnline(); + void ps_changedAtcStationsOnline(); //! Connection status has been changed - void connectionStatusChanged(uint from, uint to, const QString &message); + void ps_connectionStatusChanged(uint from, uint to, const QString &message); private: Ui::CAtcStationComponent *ui; CTimerBasedComponent *m_timerComponent; - QDateTime m_timestampLastReadOnlineStations; - QDateTime m_timestampOnlineStationsChanged; - QDateTime m_timestampLastReadBookedStations; + QDateTime m_timestampLastReadOnlineStations = CTimerBasedComponent::epoch(); //!< stations read + QDateTime m_timestampOnlineStationsChanged = CTimerBasedComponent::epoch(); //!< stations marked as changed + QDateTime m_timestampLastReadBookedStations = CTimerBasedComponent::epoch(); //!< stations read + QDateTime m_timestampBookedStationsChanged = CTimerBasedComponent::epoch(); //!< stations marked as changed }; } } diff --git a/src/blackgui/components/timerbasedcomponent.h b/src/blackgui/components/timerbasedcomponent.h index d64608aac..f2499ea3b 100644 --- a/src/blackgui/components/timerbasedcomponent.h +++ b/src/blackgui/components/timerbasedcomponent.h @@ -13,6 +13,7 @@ #define BLACKGUI_TIMERBASEDCOMPONENT_H #include +#include namespace BlackGui { @@ -28,6 +29,13 @@ namespace BlackGui //! Destructor ~CTimerBasedComponent(); + //! Date/time of 1/1/1970, used to init timestamp values as "outdated" + static const QDateTime &epoch() + { + static const QDateTime e = QDateTime::fromMSecsSinceEpoch(0); + return e; + } + public slots: //! Update time, time < 100 stops updates void setUpdateInterval(int milliSeconds); diff --git a/src/blackmisc/digestsignal.cpp b/src/blackmisc/digestsignal.cpp new file mode 100644 index 000000000..6f0ccaf0e --- /dev/null +++ b/src/blackmisc/digestsignal.cpp @@ -0,0 +1,36 @@ +/* Copyright (C) 2013 + * 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 "digestsignal.h" + +namespace BlackMisc +{ + + void CDigestSignal::ps_inputSignal() + { + if (m_timer.isActive()) + { + m_timer.start(); + } + + m_inputsCount++; + if (m_inputsCount >= m_maxInputsPerDigest) + { + ps_timeout(); + } + } + + void CDigestSignal::ps_timeout() + { + m_timer.stop(); + m_inputsCount = 0; + emit digestSignal(); + } + +} // namespace diff --git a/src/blackmisc/digestsignal.h b/src/blackmisc/digestsignal.h new file mode 100644 index 000000000..2ee34fb69 --- /dev/null +++ b/src/blackmisc/digestsignal.h @@ -0,0 +1,58 @@ +/* Copyright (C) 2013 + * 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. + */ + +//! \file + +#ifndef BLACKMISC_DIGESTSIGNAL_H +#define BLACKMISC_DIGESTSIGNAL_H + +#include +#include + +namespace BlackMisc +{ + + //! Receive 1..n signal, collect them over time, and resend afer n milliseconds + class CDigestSignal : public QObject + { + Q_OBJECT + + public: + //! Constructor + template + CDigestSignal(T *sender, F1 inputSignal, F2 digestSignal, int maxDelayMs = 500, int maxInputsPerDigest = 3) + : m_maxInputsPerDigest(maxInputsPerDigest) + { + QObject::connect(sender, inputSignal, this, &CDigestSignal::ps_inputSignal); + QObject::connect(this, &CDigestSignal::digestSignal, sender, digestSignal); + + QObject::connect(&m_timer, &QTimer::timeout, this, &CDigestSignal::ps_timeout); + m_timer.setSingleShot(true); + m_timer.setInterval(maxDelayMs); + } + + signals: + //! Send digest signal + void digestSignal(); + + private slots: + //! Received input signal + void ps_inputSignal(); + + //! Timer timed out + void ps_timeout(); + + private: + QTimer m_timer; + const int m_maxInputsPerDigest = 3; + int m_inputsCount = 0; + }; +} + +#endif diff --git a/src/swiftgui_standard/mainwindow.cpp b/src/swiftgui_standard/mainwindow.cpp index 801789024..ea8a6d0e4 100644 --- a/src/swiftgui_standard/mainwindow.cpp +++ b/src/swiftgui_standard/mainwindow.cpp @@ -259,11 +259,12 @@ void MainWindow::ps_toggleNetworkConnection() this->ps_displayStatusMessageInGui(CStatusMessage::getInfoMessage("login in observer mode")); } msgs = this->getIContextNetwork()->connectToNetwork(static_cast(mode)); + this->startUpdateTimersWhenConnected(); } else { // disconnect from network - this->stopUpdateTimers(); // stop update timers, to avoid updates during disconnecting (a short time frame) + this->stopUpdateTimersWhenDisconnected(); // stop update timers, to avoid updates during disconnecting (a short time frame) if (this->m_contextAudioAvailable) this->getIContextAudio()->leaveAllVoiceRooms(); msgs = this->getIContextNetwork()->disconnectFromNetwork(); } diff --git a/src/swiftgui_standard/mainwindow.h b/src/swiftgui_standard/mainwindow.h index df622869f..a26121a64 100644 --- a/src/swiftgui_standard/mainwindow.h +++ b/src/swiftgui_standard/mainwindow.h @@ -145,10 +145,10 @@ private: bool isMainPageSelected(MainPageIndex mainPage) const; //! Start all update timers - void startUpdateTimers(); + void startUpdateTimersWhenConnected(); //! Stop all update timers - void stopUpdateTimers(); + void stopUpdateTimersWhenDisconnected(); /*! * \brief Stop all timers diff --git a/src/swiftgui_standard/mainwindow_init.cpp b/src/swiftgui_standard/mainwindow_init.cpp index 6adde5566..870dab70c 100644 --- a/src/swiftgui_standard/mainwindow_init.cpp +++ b/src/swiftgui_standard/mainwindow_init.cpp @@ -144,7 +144,7 @@ void MainWindow::init(const CRuntimeConfig &runtimeConfig) this->ps_registerHotkeyFunctions(); // update timers - this->startUpdateTimers(); + this->startUpdateTimersWhenConnected(); // do this as last statement, so it can be used as flag // whether init has been completed @@ -246,17 +246,17 @@ void MainWindow::initialDataReads() /* * Start update timers */ -void MainWindow::startUpdateTimers() +void MainWindow::startUpdateTimersWhenConnected() { - this->ui->comp_MainInfoArea->getAircraftComponent()->setUpdateIntervalSeconds(this->ui->comp_MainInfoArea->getSettingsComponent()->getAircraftUpdateIntervalSeconds()); this->ui->comp_MainInfoArea->getAtcStationComponent()->setUpdateIntervalSeconds(this->ui->comp_MainInfoArea->getSettingsComponent()->getAtcUpdateIntervalSeconds()); + this->ui->comp_MainInfoArea->getAircraftComponent()->setUpdateIntervalSeconds(this->ui->comp_MainInfoArea->getSettingsComponent()->getAircraftUpdateIntervalSeconds()); this->ui->comp_MainInfoArea->getUserComponent()->setUpdateIntervalSeconds(this->ui->comp_MainInfoArea->getSettingsComponent()->getUsersUpdateIntervalSeconds()); } /* * Stop udate timers */ -void MainWindow::stopUpdateTimers() +void MainWindow::stopUpdateTimersWhenDisconnected() { this->ui->comp_MainInfoArea->getAtcStationComponent()->stopTimer(); this->ui->comp_MainInfoArea->getAircraftComponent()->stopTimer(); @@ -271,7 +271,7 @@ void MainWindow::stopAllTimers(bool disconnect) this->m_timerStatusBar->stop(); this->m_timerContextWatchdog->stop(); this->m_timerSimulator->stop(); - this->stopUpdateTimers(); + this->stopUpdateTimersWhenDisconnected(); if (!disconnect) return; this->disconnect(this->m_timerStatusBar); this->disconnect(this->m_timerContextWatchdog);