diff --git a/src/blackcore/vatsim/vatsimbookingreader.cpp b/src/blackcore/vatsim/vatsimbookingreader.cpp index 1722559e7..842de2aed 100644 --- a/src/blackcore/vatsim/vatsimbookingreader.cpp +++ b/src/blackcore/vatsim/vatsimbookingreader.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include using namespace BlackMisc; @@ -43,41 +44,47 @@ namespace BlackCore namespace Vatsim { CVatsimBookingReader::CVatsimBookingReader(QObject *owner) : - CThreadedReader(owner, "CVatsimBookingReader") + CThreadedReader(owner, "CVatsimBookingReader"), + CEcosystemAware(CEcosystemAware::providerIfPossible(owner)) { settingsChanged(); } void CVatsimBookingReader::readInBackgroundThread() { - bool s = QMetaObject::invokeMethod(this, "ps_read"); - Q_ASSERT(s); - Q_UNUSED(s); + QPointer myself(this); + QTimer::singleShot(0, this, [ = ] + { + if (!myself) { return; } + myself->read(); + }); } void CVatsimBookingReader::doWorkImpl() { - ps_read(); + this->read(); } - void CVatsimBookingReader::ps_read() + void CVatsimBookingReader::read() { this->threadAssertCheck(); if (!this->doWorkCheck()) { return; } if (!this->isInternetAccessible("No network/internet access, cannot read VATSIM bookings")) { return; } + if (this->isNotVATSIMEcosystem()) { return; } Q_ASSERT_X(sApp, Q_FUNC_INFO, "No application"); const QUrl url(sApp->getGlobalSetup().getVatsimBookingsUrl()); if (url.isEmpty()) { return; } - this->getFromNetworkAndLog(url, { this, &CVatsimBookingReader::ps_parseBookings}); + this->getFromNetworkAndLog(url, { this, &CVatsimBookingReader::parseBookings}); } - void CVatsimBookingReader::ps_parseBookings(QNetworkReply *nwReplyPtr) + void CVatsimBookingReader::parseBookings(QNetworkReply *nwReplyPtr) { // wrap pointer, make sure any exit cleans up reply // required to use delete later as object is created in a different thread QScopedPointer nwReply(nwReplyPtr); this->threadAssertCheck(); + if (this->isNotVATSIMEcosystem()) { return; } // Worker thread, make sure to write no members here od do it threadsafe if (!this->doWorkCheck()) @@ -119,8 +126,8 @@ namespace BlackCore } } - QDomNode atc = doc.elementsByTagName("atcs").at(0); - QDomNodeList bookingNodes = atc.toElement().elementsByTagName("booking"); + const QDomNode atc = doc.elementsByTagName("atcs").at(0); + const QDomNodeList bookingNodes = atc.toElement().elementsByTagName("booking"); int size = bookingNodes.size(); CAtcStationList bookedStations; for (int i = 0; i < size; i++) @@ -132,8 +139,8 @@ namespace BlackCore } // pase nodes - QDomNode bookingNode = bookingNodes.at(i); - QDomNodeList bookingNodeValues = bookingNode.childNodes(); + const QDomNode bookingNode = bookingNodes.at(i); + const QDomNodeList bookingNodeValues = bookingNode.childNodes(); CAtcStation bookedStation; CUser user; for (int v = 0; v < bookingNodeValues.size(); v++) diff --git a/src/blackcore/vatsim/vatsimbookingreader.h b/src/blackcore/vatsim/vatsimbookingreader.h index b289b5f84..df8fa7da0 100644 --- a/src/blackcore/vatsim/vatsimbookingreader.h +++ b/src/blackcore/vatsim/vatsimbookingreader.h @@ -14,6 +14,7 @@ #include "blackcore/blackcoreexport.h" #include "blackmisc/aviation/atcstationlist.h" +#include "blackmisc/network/ecosystemprovider.h" #include "blackmisc/network/entityflags.h" #include "blackcore/threadedreader.h" @@ -26,7 +27,9 @@ namespace BlackCore namespace Vatsim { //! Read bookings from VATSIM - class BLACKCORE_EXPORT CVatsimBookingReader : public BlackCore::CThreadedReader + class BLACKCORE_EXPORT CVatsimBookingReader : + public BlackCore::CThreadedReader, + public BlackMisc::Network::CEcosystemAware { Q_OBJECT @@ -53,15 +56,14 @@ namespace BlackCore virtual void doWorkImpl() override; //! @} - private slots: + private: //! Bookings have been read //! \threadsafe - void ps_parseBookings(QNetworkReply *nwReply); + void parseBookings(QNetworkReply *nwReply); //! Do reading - void ps_read(); + void read(); - private: //! Settings changed void settingsChanged(); diff --git a/src/blackcore/vatsim/vatsimdatafilereader.cpp b/src/blackcore/vatsim/vatsimdatafilereader.cpp index 0110e8a34..2e8c547a2 100644 --- a/src/blackcore/vatsim/vatsimdatafilereader.cpp +++ b/src/blackcore/vatsim/vatsimdatafilereader.cpp @@ -43,6 +43,7 @@ #include #include #include +#include using namespace BlackMisc; using namespace BlackMisc::Aviation; @@ -57,7 +58,8 @@ namespace BlackCore namespace Vatsim { CVatsimDataFileReader::CVatsimDataFileReader(QObject *owner) : - CThreadedReader(owner, "CVatsimDataFileReader") + CThreadedReader(owner, "CVatsimDataFileReader"), + CEcosystemAware(CEcosystemAware::providerIfPossible(owner)) { this->reloadSettings(); } @@ -168,21 +170,25 @@ namespace BlackCore void CVatsimDataFileReader::readInBackgroundThread() { - const bool s = QMetaObject::invokeMethod(this, "ps_read"); - Q_ASSERT_X(s, Q_FUNC_INFO, "Invoke failed"); - Q_UNUSED(s); + QPointer myself(this); + QTimer::singleShot(0, this, [ = ] + { + if (!myself) { return; } + myself->read(); + }); } void CVatsimDataFileReader::doWorkImpl() { - this->ps_read(); + this->read(); } - void CVatsimDataFileReader::ps_read() + void CVatsimDataFileReader::read() { this->threadAssertCheck(); if (!this->doWorkCheck()) { return; } if (!this->isInternetAccessible("No network/internet access, cannot read VATSIM data file")) { return; } + if (this->isNotVATSIMEcosystem()) { return; } // round robin for load balancing // remark: Don't use QThread to run network operations in the background @@ -191,15 +197,16 @@ namespace BlackCore CFailoverUrlList urls(sApp->getVatsimDataFileUrls()); const QUrl url(urls.obtainNextWorkingUrl(true)); if (url.isEmpty()) { return; } - this->getFromNetworkAndLog(url, { this, &CVatsimDataFileReader::ps_parseVatsimFile}); + this->getFromNetworkAndLog(url, { this, &CVatsimDataFileReader::parseVatsimFile}); } - void CVatsimDataFileReader::ps_parseVatsimFile(QNetworkReply *nwReplyPtr) + void CVatsimDataFileReader::parseVatsimFile(QNetworkReply *nwReplyPtr) { // wrap pointer, make sure any exit cleans up reply // required to use delete later as object is created in a different thread QScopedPointer nwReply(nwReplyPtr); this->threadAssertCheck(); + if (this->isNotVATSIMEcosystem()) { return; } // Worker thread, make sure to write only synced here! if (!this->doWorkCheck()) diff --git a/src/blackcore/vatsim/vatsimdatafilereader.h b/src/blackcore/vatsim/vatsimdatafilereader.h index e8847dc3b..b17a382a9 100644 --- a/src/blackcore/vatsim/vatsimdatafilereader.h +++ b/src/blackcore/vatsim/vatsimdatafilereader.h @@ -20,6 +20,7 @@ #include "blackmisc/aviation/callsignset.h" #include "blackmisc/aviation/flightplan.h" #include "blackmisc/network/entityflags.h" +#include "blackmisc/network/ecosystemprovider.h" #include "blackmisc/network/serverlist.h" #include "blackmisc/network/userlist.h" #include "blackmisc/network/voicecapabilities.h" @@ -41,7 +42,9 @@ namespace BlackCore { //! Read vatsim data file //! \sa http://info.vroute.net/vatsim-data.txt - class BLACKCORE_EXPORT CVatsimDataFileReader : public CThreadedReader + class BLACKCORE_EXPORT CVatsimDataFileReader : + public CThreadedReader, + public BlackMisc::Network::CEcosystemAware { Q_OBJECT @@ -133,13 +136,6 @@ namespace BlackCore virtual void doWorkImpl() override; //! @} - private slots: - //! Data have been read, parse VATSIM file - void ps_parseVatsimFile(QNetworkReply *nwReply); - - //! Read / re-read data file - void ps_read(); - private: //! Section in file enum Section @@ -157,6 +153,12 @@ namespace BlackCore BlackMisc::CSettingReadOnly m_settings { this, &CVatsimDataFileReader::reloadSettings }; QMap m_flightPlanRemarks; //!< cache for flight plan remarks + //! Data have been read, parse VATSIM file + void parseVatsimFile(QNetworkReply *nwReply); + + //! Read / re-read data file + void read(); + //! Reload the reader settings void reloadSettings(); diff --git a/src/blackcore/vatsim/vatsimmetarreader.cpp b/src/blackcore/vatsim/vatsimmetarreader.cpp index 3c0fd9227..7f504d4fb 100644 --- a/src/blackcore/vatsim/vatsimmetarreader.cpp +++ b/src/blackcore/vatsim/vatsimmetarreader.cpp @@ -39,7 +39,8 @@ namespace BlackCore namespace Vatsim { CVatsimMetarReader::CVatsimMetarReader(QObject *owner) : - CThreadedReader(owner, "CVatsimMetarReader") + CThreadedReader(owner, "CVatsimMetarReader"), + CEcosystemAware(CEcosystemAware::providerIfPossible(owner)) { reloadSettings(); } @@ -77,6 +78,7 @@ namespace BlackCore this->threadAssertCheck(); if (!this->doWorkCheck()) { return; } if (!this->isInternetAccessible("No network/internet access, cannot read METARs")) { return; } + if (this->isNotVATSIMEcosystem()) { return; } CFailoverUrlList urls(sApp->getVatsimMetarUrls()); const CUrl url(urls.obtainNextWorkingUrl(true)); @@ -93,6 +95,8 @@ namespace BlackCore // Worker thread, make sure to write thread safe! this->threadAssertCheck(); + if (this->isNotVATSIMEcosystem()) { return; } + if (!this->doWorkCheck()) { CLogMessage(this).info("Terminated METAR decoding process"); // for users diff --git a/src/blackcore/vatsim/vatsimmetarreader.h b/src/blackcore/vatsim/vatsimmetarreader.h index d5b4f5e45..443e1928c 100644 --- a/src/blackcore/vatsim/vatsimmetarreader.h +++ b/src/blackcore/vatsim/vatsimmetarreader.h @@ -13,12 +13,13 @@ #define BLACKCORE_VATSIM_VATSIMMETARREADER_H #include "blackcore/blackcoreexport.h" -#include "blackmisc/aviation/airporticaocode.h" -#include "blackmisc/network/entityflags.h" -#include "blackcore/threadedreader.h" #include "blackmisc/weather/metar.h" #include "blackmisc/weather/metardecoder.h" #include "blackmisc/weather/metarlist.h" +#include "blackmisc/network/ecosystemprovider.h" +#include "blackmisc/network/entityflags.h" +#include "blackmisc/aviation/airporticaocode.h" +#include "blackcore/threadedreader.h" #include @@ -29,7 +30,9 @@ namespace BlackCore namespace Vatsim { //! Read bookings from VATSIM - class BLACKCORE_EXPORT CVatsimMetarReader : public BlackCore::CThreadedReader + class BLACKCORE_EXPORT CVatsimMetarReader : + public BlackCore::CThreadedReader, + public BlackMisc::Network::CEcosystemAware { Q_OBJECT diff --git a/src/blackcore/vatsim/vatsimstatusfilereader.cpp b/src/blackcore/vatsim/vatsimstatusfilereader.cpp index feac2ab9b..6cc1ce62f 100644 --- a/src/blackcore/vatsim/vatsimstatusfilereader.cpp +++ b/src/blackcore/vatsim/vatsimstatusfilereader.cpp @@ -72,10 +72,10 @@ namespace BlackCore CFailoverUrlList urls(sApp->getGlobalSetup().getVatsimStatusFileUrls()); const CUrl url(urls.obtainNextWorkingUrl(true)); // random working URL if (url.isEmpty()) { return; } - this->getFromNetworkAndLog(url, { this, &CVatsimStatusFileReader::ps_parseVatsimFile}); + this->getFromNetworkAndLog(url, { this, &CVatsimStatusFileReader::parseVatsimFile}); } - void CVatsimStatusFileReader::ps_parseVatsimFile(QNetworkReply *nwReplyPtr) + void CVatsimStatusFileReader::parseVatsimFile(QNetworkReply *nwReplyPtr) { // wrap pointer, make sure any exit cleans up reply // required to use delete later as object is created in a different thread diff --git a/src/blackcore/vatsim/vatsimstatusfilereader.h b/src/blackcore/vatsim/vatsimstatusfilereader.h index 26a06907c..14e912698 100644 --- a/src/blackcore/vatsim/vatsimstatusfilereader.h +++ b/src/blackcore/vatsim/vatsimstatusfilereader.h @@ -57,13 +57,13 @@ namespace BlackCore void dataRead(BlackMisc::Network::CEntityFlags::Entity entity, BlackMisc::Network::CEntityFlags::ReadState state, int number); private slots: - //! Data have been read, parse VATSIM file - void ps_parseVatsimFile(QNetworkReply *nwReply); - //! Read / re-read data file void ps_read(); private: + //! Data have been read, parse VATSIM file + void parseVatsimFile(QNetworkReply *nwReply); + BlackMisc::CData m_lastGoodSetup { this }; }; } // ns diff --git a/src/blackcore/webdataservices.cpp b/src/blackcore/webdataservices.cpp index f0eb02aa9..38943e8af 100644 --- a/src/blackcore/webdataservices.cpp +++ b/src/blackcore/webdataservices.cpp @@ -1454,7 +1454,9 @@ namespace BlackCore void CWebDataServices::onConnectedNetworkServerChanged(const CServer &server) { - Q_UNUSED(server); + const CEcosystem es(server.getEcosystem()); + this->setCurrentEcosystem(es); + CLogMessage(this).info("Changed data service ecosystem to '%1'") << es.toQString(true); } bool CWebDataServices::writeDbDataToDisk(const QString &dir) const diff --git a/src/blackcore/webdataservices.h b/src/blackcore/webdataservices.h index 8b9647e2b..d769de789 100644 --- a/src/blackcore/webdataservices.h +++ b/src/blackcore/webdataservices.h @@ -22,10 +22,11 @@ #include "blackmisc/aviation/atcstationlist.h" #include "blackmisc/aviation/liverylist.h" #include "blackmisc/countrylist.h" -#include "blackmisc/network/entityflags.h" +#include "blackmisc/network/ecosystemprovider.h" #include "blackmisc/network/serverlist.h" #include "blackmisc/network/urllist.h" #include "blackmisc/network/userlist.h" +#include "blackmisc/network/entityflags.h" #include "blackmisc/network/voicecapabilities.h" #include "blackmisc/restricted.h" #include "blackmisc/simulation/aircraftmodel.h" @@ -78,9 +79,12 @@ namespace BlackCore /*! * Encapsulates reading data from web sources */ - class BLACKCORE_EXPORT CWebDataServices : public QObject + class BLACKCORE_EXPORT CWebDataServices : + public QObject, + public BlackMisc::Network::IEcosystemProvider { Q_OBJECT + Q_INTERFACES(BlackMisc::Network::IEcosystemProvider) public: //! Log categories @@ -581,6 +585,7 @@ namespace BlackCore void onCoreFacadeStarted(); //! \copydoc BlackCore::Context::IContextNetwork::connectedServerChanged + //! \remark sets the ecosystem void onConnectedNetworkServerChanged(const BlackMisc::Network::CServer &server); CWebReaderFlags::WebReader m_readers = CWebReaderFlags::WebReaderFlag::None; //!< which readers are available diff --git a/src/blackmisc/network/ecosystemprovider.cpp b/src/blackmisc/network/ecosystemprovider.cpp index d9f6aa5c5..d76aa876c 100644 --- a/src/blackmisc/network/ecosystemprovider.cpp +++ b/src/blackmisc/network/ecosystemprovider.cpp @@ -31,6 +31,11 @@ namespace BlackMisc return this->getCurrentEcosystem() == system; } + bool IEcosystemProvider::isCurrentEcosystemVATSIM() const + { + return this->isCurrentEcosystem(CEcosystem::vatsim()); + } + bool IEcosystemProvider::isLastEcosystem(const CEcosystem &system) const { return this->getLastEcosystem() == system; @@ -70,10 +75,29 @@ namespace BlackMisc return this->provider()->isCurrentEcosystem(system); } + bool CEcosystemAware::isCurrentEcosystemVATSIM() const + { + return this->isCurrentEcosystem(CEcosystem::vatsim()); + } + + bool CEcosystemAware::isNotVATSIMEcosystem() const + { + if (!this->hasProvider()) { return false; } + if (this->isCurrentEcosystemVATSIM()) { return false; } + if (this->isCurrentEcosystem(CEcosystem::swiftTest())) { return false; } // our test server is supposed to be I VATSIM system + return !this->getCurrentEcosystem().isUnspecified(); // other know system which is specified + } + bool CEcosystemAware::isLastEcosystem(const CEcosystem &system) const { if (!this->hasProvider()) { return this->getLastEcosystem() == system; } return this->provider()->isLastEcosystem(system); } + + IEcosystemProvider *CEcosystemAware::providerIfPossible(QObject *object) + { + IEcosystemProvider *p = qobject_cast(object); + return p; + } } // namespace } // namespace diff --git a/src/blackmisc/network/ecosystemprovider.h b/src/blackmisc/network/ecosystemprovider.h index c12c94e1f..247428eb2 100644 --- a/src/blackmisc/network/ecosystemprovider.h +++ b/src/blackmisc/network/ecosystemprovider.h @@ -37,6 +37,10 @@ namespace BlackMisc //! \threadsafe bool isCurrentEcosystem(const CEcosystem &system) const; + //! Current ecosystem VATSIM? + //! \threadsafe + bool isCurrentEcosystemVATSIM() const; + //! Last known ecosystem? //! \threadsafe bool isLastEcosystem(const CEcosystem &system) const; @@ -72,9 +76,19 @@ namespace BlackMisc //! \copydoc IEcosystemProvider::isCurrentEcosystem bool isCurrentEcosystem(const CEcosystem &system) const; + //! \copydoc IEcosystemProvider::isCurrentEcosystemVATSIM + bool isCurrentEcosystemVATSIM() const; + + //! Connected with other system than VATSIM? + //! \remark use this function to skip VATSIM specific provider tasks etc. + bool isNotVATSIMEcosystem() const; + //! \copydoc IEcosystemProvider::isLastEcosystem bool isLastEcosystem(const CEcosystem &system) const; + //! Cast as provider if possible + static IEcosystemProvider *providerIfPossible(QObject *object); + protected: //! Constructor CEcosystemAware(IEcosystemProvider *EcosystemProvider) : IProviderAware(EcosystemProvider) { Q_ASSERT(EcosystemProvider); }