From c760f1d4242688c59010538b69da181121072657 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Fri, 10 Jul 2015 01:03:11 +0200 Subject: [PATCH] refs #445, encapsulated web service based reading in CWebDataReader * the reader will be used in context, but can also be used standalone (ie mapping GUI) GUI * adjustments in context/airspace as required ** for web reader ** livery * base class for database based reading (via JSON/web) * model data reader for models --- src/blackcore/airspace_monitor.cpp | 27 ++- src/blackcore/airspace_monitor.h | 10 +- src/blackcore/context.cpp | 6 + src/blackcore/context.h | 8 +- src/blackcore/context_network.h | 30 ++- src/blackcore/context_network_impl.cpp | 119 ++++------ src/blackcore/context_network_impl.h | 31 +-- src/blackcore/context_ownaircraft_impl.cpp | 3 +- src/blackcore/context_simulator_impl.cpp | 1 + src/blackcore/databasereader.cpp | 71 ++++++ src/blackcore/databasereader.h | 45 ++++ src/blackcore/icaodatareader.cpp | 71 +++--- src/blackcore/icaodatareader.h | 30 ++- src/blackcore/modeldatareader.cpp | 168 +++++++++++++ src/blackcore/modeldatareader.h | 116 +++++++++ src/blackcore/network_vatlib.cpp | 7 +- src/blackcore/reader_settings.cpp | 28 +++ src/blackcore/reader_settings.h | 69 ++++++ src/blackcore/simulator.h | 1 + src/blackcore/vatsimbookingreader.cpp | 7 +- src/blackcore/vatsimbookingreader.h | 5 +- src/blackcore/web_datareader.cpp | 260 +++++++++++++++++++++ src/blackcore/web_datareader.h | 173 ++++++++++++++ src/blackmisc/setnetwork.h | 113 +++++++++ 24 files changed, 1197 insertions(+), 202 deletions(-) create mode 100644 src/blackcore/databasereader.cpp create mode 100644 src/blackcore/databasereader.h create mode 100644 src/blackcore/modeldatareader.cpp create mode 100644 src/blackcore/modeldatareader.h create mode 100644 src/blackcore/reader_settings.cpp create mode 100644 src/blackcore/reader_settings.h create mode 100644 src/blackcore/web_datareader.cpp create mode 100644 src/blackcore/web_datareader.h create mode 100644 src/blackmisc/setnetwork.h diff --git a/src/blackcore/airspace_monitor.cpp b/src/blackcore/airspace_monitor.cpp index 24ebfad24..a5492c489 100644 --- a/src/blackcore/airspace_monitor.cpp +++ b/src/blackcore/airspace_monitor.cpp @@ -9,6 +9,9 @@ #include "airspace_monitor.h" #include "blackcore/blackcorefreefunctions.h" +#include "blackcore/web_datareader.h" +#include "blackcore/vatsimbookingreader.h" +#include "blackcore/vatsimdatafilereader.h" #include "blackmisc/project.h" #include "blackmisc/testing.h" #include "blackmisc/logmessage.h" @@ -26,10 +29,10 @@ using namespace BlackMisc::PhysicalQuantities; namespace BlackCore { - CAirspaceMonitor::CAirspaceMonitor(QObject *parent, BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider, INetwork *network, CVatsimBookingReader *bookings, CVatsimDataFileReader *dataFile) + CAirspaceMonitor::CAirspaceMonitor(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider, INetwork *network, CWebDataReader *webDataReader, QObject *parent) : QObject(parent), COwnAircraftAware(ownAircraftProvider), - m_network(network), m_vatsimBookingReader(bookings), m_vatsimDataFileReader(dataFile), + m_network(network), m_webDataReader(webDataReader), m_analyzer(new CAirspaceAnalyzer(ownAircraftProvider, this, network, this)) { this->setObjectName("CAirspaceMonitor"); @@ -55,8 +58,8 @@ namespace BlackCore this->connect(&m_interimPositionUpdateTimer, &QTimer::timeout, this, &CAirspaceMonitor::ps_sendInterimPositions); // AutoConnection: this should also avoid race conditions by updating the bookings - this->connect(this->m_vatsimBookingReader, &CVatsimBookingReader::dataRead, this, &CAirspaceMonitor::ps_receivedBookings); - this->connect(this->m_vatsimDataFileReader, &CVatsimDataFileReader::dataRead, this, &CAirspaceMonitor::ps_receivedDataFile); + this->connect(this->m_webDataReader->getBookingReader(), &CVatsimBookingReader::dataRead, this, &CAirspaceMonitor::ps_receivedBookings); + this->connect(this->m_webDataReader->getDataFileReader(), &CVatsimDataFileReader::dataRead, this, &CAirspaceMonitor::ps_receivedDataFile); // Force snapshot in the main event loop this->connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, this, &CAirspaceMonitor::airspaceAircraftSnapshot, Qt::QueuedConnection); @@ -287,7 +290,7 @@ namespace BlackCore // those are the ones not in range for (const CCallsign &callsign : searchList) { - CUserList usersByCallsign = this->m_vatsimDataFileReader->getUsersForCallsign(callsign); + CUserList usersByCallsign = this->m_webDataReader->getDataFileReader()->getUsersForCallsign(callsign); if (usersByCallsign.isEmpty()) { CUser user; @@ -438,13 +441,13 @@ namespace BlackCore void CAirspaceMonitor::ps_realNameReplyReceived(const CCallsign &callsign, const QString &realname) { - Q_ASSERT(this->m_vatsimDataFileReader); + Q_ASSERT(this->m_webDataReader->getDataFileReader()); if (!this->m_connected || realname.isEmpty()) { return; } CPropertyIndexVariantMap vm({CAtcStation::IndexController, CUser::IndexRealName}, realname); this->m_atcStationsOnline.applyIf(&CAtcStation::getCallsign, callsign, vm); this->m_atcStationsBooked.applyIf(&CAtcStation::getCallsign, callsign, vm); - CVoiceCapabilities caps = this->m_vatsimDataFileReader->getVoiceCapabilityForCallsign(callsign); + CVoiceCapabilities caps = this->m_webDataReader->getDataFileReader()->getVoiceCapabilityForCallsign(callsign); vm = CPropertyIndexVariantMap({CAircraft::IndexPilot, CUser::IndexRealName}, realname); vm.addValue({ CSimulatedAircraft::IndexClient, CClient::IndexUser, CUser::IndexRealName }, realname); vm.addValue({ CSimulatedAircraft::IndexClient, CClient::IndexVoiceCapabilities }, caps); @@ -472,7 +475,7 @@ namespace BlackCore capabilities.addValue(CClient::FsdWithAircraftConfig, (flags & INetwork::SupportsAircraftConfigs)); CPropertyIndexVariantMap vm(CClient::IndexCapabilities, CVariant::from(capabilities)); - CVoiceCapabilities caps = m_vatsimDataFileReader->getVoiceCapabilityForCallsign(callsign); + CVoiceCapabilities caps = m_webDataReader->getDataFileReader()->getVoiceCapabilityForCallsign(callsign); vm.addValue({CClient::IndexVoiceCapabilities}, caps); if (!this->m_otherClients.containsCallsign(callsign)) { this->m_otherClients.push_back(CClient(callsign)); } this->m_otherClients.applyIf(&CClient::getCallsign, callsign, vm); @@ -634,7 +637,7 @@ namespace BlackCore for (auto client = this->m_otherClients.begin(); client != this->m_otherClients.end(); ++client) { if (client->hasSpecifiedVoiceCapabilities()) { continue; } // we already have voice caps - CVoiceCapabilities vc = this->m_vatsimDataFileReader->getVoiceCapabilityForCallsign(client->getCallsign()); + CVoiceCapabilities vc = this->m_webDataReader->getDataFileReader()->getVoiceCapabilityForCallsign(client->getCallsign()); if (vc.isUnknown()) { continue; } client->setVoiceCapabilities(vc); } @@ -683,7 +686,7 @@ namespace BlackCore if (stationsWithCallsign.isEmpty()) { // new station, init with data from data file - CAtcStation station(this->m_vatsimDataFileReader->getAtcStationsForCallsign(callsign).frontOrDefault()); + CAtcStation station(this->m_webDataReader->getDataFileReader()->getAtcStationsForCallsign(callsign).frontOrDefault()); station.setCallsign(callsign); station.setRange(range); station.setFrequency(frequency); @@ -819,7 +822,7 @@ namespace BlackCore { // empty so far, try to fetch from data file CLogMessage(this).warning("Empty ICAO info for %1 %2") << callsign.toQString() << icaoData.toQString(); - CAircraftIcaoData icaoDataFromDataFile = this->m_vatsimDataFileReader->getIcaoInfo(callsign); + CAircraftIcaoData icaoDataFromDataFile = this->m_webDataReader->getDataFileReader()->getIcaoInfo(callsign); if (!icaoDataFromDataFile.hasAircraftDesignator()) { return; } // give up! vm = CPropertyIndexVariantMap(CAircraft::IndexIcao, CVariant::from(icaoDataFromDataFile)); } @@ -873,7 +876,7 @@ namespace BlackCore setIcao = true; } - this->m_vatsimDataFileReader->updateWithVatsimDataFileData(aircraft); + this->m_webDataReader->getDataFileReader()->updateWithVatsimDataFileData(aircraft); // only place where aircraft is added this->m_aircraftInRange.push_back(aircraft); diff --git a/src/blackcore/airspace_monitor.h b/src/blackcore/airspace_monitor.h index 2ca68dd10..e4163d048 100644 --- a/src/blackcore/airspace_monitor.h +++ b/src/blackcore/airspace_monitor.h @@ -14,8 +14,6 @@ #include "blackcore/blackcoreexport.h" #include "blackcore/network.h" -#include "blackcore/vatsimbookingreader.h" -#include "blackcore/vatsimdatafilereader.h" #include "airspace_analyzer.h" #include "blackmisc/simulation/simulatedaircraftlist.h" #include "blackmisc/simulation/ownaircraftprovider.h" @@ -29,6 +27,7 @@ namespace BlackCore { + class CWebDataReader; //! Keeps track of other entities in the airspace: aircraft, ATC stations, etc. //! Central instance of data for \sa IRemoteAircraftProvider. @@ -42,7 +41,7 @@ namespace BlackCore public: //! Constructor - CAirspaceMonitor(QObject *parent, BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, INetwork *network, CVatsimBookingReader *bookings, CVatsimDataFileReader *dataFile); + CAirspaceMonitor(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, INetwork *network, CWebDataReader *webDataReader, QObject *parent); //! \copydoc IRemoteAircraftProvider::getAircraftInRange //! \ingroup remoteaircraftprovider @@ -212,12 +211,11 @@ namespace BlackCore BlackMisc::Aviation::CCallsignSet m_aircraftSupportingParts; //!< aircraft supporting parts QMap m_metarCache; - QMap m_flightPlanCache; + QMap m_flightPlanCache; QMap m_icaoCodeCache; INetwork *m_network = nullptr; - CVatsimBookingReader *m_vatsimBookingReader = nullptr; - CVatsimDataFileReader *m_vatsimDataFileReader = nullptr; + CWebDataReader *m_webDataReader = nullptr; CAirspaceAnalyzer *m_analyzer = nullptr; //!< owned analyzer bool m_serverSupportsNameQuery = false; //!< not all servers support name query bool m_connected = false; //!< retrieve data diff --git a/src/blackcore/context.cpp b/src/blackcore/context.cpp index 28616eec8..47330cb82 100644 --- a/src/blackcore/context.cpp +++ b/src/blackcore/context.cpp @@ -15,6 +15,12 @@ using namespace BlackMisc; namespace BlackCore { + const CLogCategoryList &CContext::getLogCategories() + { + static const BlackMisc::CLogCategoryList cats { BlackMisc::CLogCategory::context() }; + return cats; + } + IContextNetwork *CContext::getIContextNetwork() { return this->getRuntime()->getIContextNetwork(); diff --git a/src/blackcore/context.h b/src/blackcore/context.h index 219575b8f..682ee6b9c 100644 --- a/src/blackcore/context.h +++ b/src/blackcore/context.h @@ -28,12 +28,8 @@ namespace BlackCore //! Destructor ~CContext() {} - //! Log category - static const BlackMisc::CLogCategoryList &getLogCategories() - { - static const BlackMisc::CLogCategoryList cats { BlackMisc::CLogCategory::context() }; - return cats; - } + //! Log categories + static const BlackMisc::CLogCategoryList &getLogCategories(); //! Using local implementing object? bool isUsingImplementingObject() const diff --git a/src/blackcore/context_network.h b/src/blackcore/context_network.h index c8c53e210..225b5fbfb 100644 --- a/src/blackcore/context_network.h +++ b/src/blackcore/context_network.h @@ -116,12 +116,6 @@ namespace BlackCore //! Terminated connection void connectionTerminated(); - //! VATSIM data file was read - void vatsimDataFileRead(); - - //! Bookings read - void vatsimBookingsRead(); - //! Connection status changed //! \param from old status //! \param to new status @@ -138,8 +132,30 @@ namespace BlackCore //! Text message sent (by me) void textMessageSent(const BlackMisc::Network::CTextMessage &sentMessage); - public slots: + // --------------------------- data readers ------------------------------- + //! Data file read + void vatsimDataFileRead(int lines); + + //! Bookings read + void vatsimBookingsRead(int number); + + //! ICAO codes read + void aircraftIcaoCodeRead(int number); + + //! ICAO codes read + void airlineIcaoCodeRead(int number); + + //! Liveries read + void liveriesRead(int number); + + //! Distributors read + void distributorsRead(int number); + + //! Number of models read + void modelsRead(int number); + + public slots: //! Reload bookings from booking service virtual void readAtcBookingsFromSource() const = 0; diff --git a/src/blackcore/context_network_impl.cpp b/src/blackcore/context_network_impl.cpp index f3abd27a5..30f9b11fa 100644 --- a/src/blackcore/context_network_impl.cpp +++ b/src/blackcore/context_network_impl.cpp @@ -14,10 +14,8 @@ #include "context_simulator.h" #include "context_ownaircraft_impl.h" #include "network_vatlib.h" -#include "vatsimbookingreader.h" -#include "vatsimdatafilereader.h" -#include "icaodatareader.h" #include "airspace_monitor.h" +#include "web_datareader.h" #include "blackmisc/networkutils.h" #include "blackmisc/aviation/atcstationlist.h" #include "blackmisc/logmessage.h" @@ -41,6 +39,7 @@ namespace BlackCore IContextNetwork(mode, runtime) { Q_ASSERT(this->getRuntime()); + Q_ASSERT(this->getIContextSettings()); Q_ASSERT(this->getIContextOwnAircraft()); Q_ASSERT(this->getIContextOwnAircraft()->isUsingImplementingObject()); @@ -51,38 +50,31 @@ namespace BlackCore connect(this->m_network, &INetwork::textMessagesReceived, this, &CContextNetwork::ps_checkForSupervisiorTextMessage); connect(this->m_network, &INetwork::textMessageSent, this, &CContextNetwork::textMessageSent); - // 2. VATSIM bookings - this->m_vatsimBookingReader = new CVatsimBookingReader(this); - connect(this->m_vatsimBookingReader, &CVatsimBookingReader::dataRead, this, &CContextNetwork::ps_receivedBookings); - this->m_vatsimBookingReader->start(); - this->m_vatsimBookingReader->setInterval(180 * 1000); - this->m_vatsimBookingReader->readInBackgroundThread(); // first read - - // 3. VATSIM data file - const QStringList dataFileUrls = { "http://info.vroute.net/vatsim-data.txt" }; - this->m_vatsimDataFileReader = new CVatsimDataFileReader(this, dataFileUrls); - connect(this->m_vatsimDataFileReader, &CVatsimDataFileReader::dataRead, this, &CContextNetwork::ps_dataFileRead); - this->m_vatsimDataFileReader->start(); - this->m_vatsimDataFileReader->readInBackgroundThread(); // first read - this->m_vatsimDataFileReader->setInterval(90 * 1000); - - // 4. ICAO data reader - this->m_icaoDataReader = new CIcaoDataReader(this, - "http://vatrep.vatsim-germany.org/service/allaircrafticao.php?rows=20000&sord=asc", - "http://vatrep.vatsim-germany.org/service/allairlineicao.php?rows=20000&sord=asc"); - connect(this->m_icaoDataReader, &CIcaoDataReader::readAircraftIcaoCodes, this, &CContextNetwork::ps_readAircraftIcaoCodes); - connect(this->m_icaoDataReader, &CIcaoDataReader::readAirlinesIcaoCodes, this, &CContextNetwork::ps_readAirlinesIcaoCodes); - this->m_icaoDataReader->start(); - this->m_icaoDataReader->readInBackgroundThread(); - - // 5. Update timer for data (network data such as frequency) + // 2. Update timer for data (network data such as frequency) this->m_dataUpdateTimer = new QTimer(this); connect(this->m_dataUpdateTimer, &QTimer::timeout, this, &CContextNetwork::requestDataUpdates); this->m_dataUpdateTimer->start(30 * 1000); - // 6. Airspace contents + // 3. data reader + this->m_webDataReader = new CWebDataReader(CWebDataReader::AllReaders, this); + this->m_webReaderSignalConnections = this->m_webDataReader->connectVatsimDataSignals( + std::bind(&CContextNetwork::vatsimBookingsRead, this, std::placeholders::_1), + std::bind(&CContextNetwork::vatsimDataFileRead, this, std::placeholders::_1)); + this->m_webReaderSignalConnections.append( + this->m_webDataReader->connectSwiftDatabaseSignals( + this, // the object here must be the same as in the bind + std::bind(&CContextNetwork::aircraftIcaoCodeRead, this, std::placeholders::_1), + std::bind(&CContextNetwork::airlineIcaoCodeRead, this, std::placeholders::_1), + std::bind(&CContextNetwork::liveriesRead, this, std::placeholders::_1), + std::bind(&CContextNetwork::distributorsRead, this, std::placeholders::_1), + std::bind(&CContextNetwork::modelsRead, this, std::placeholders::_1) + )); + this->m_webDataReader->readAllInBackground(1000); + + // 4. Airspace contents Q_ASSERT_X(this->getRuntime()->getCContextOwnAircraft(), Q_FUNC_INFO, "this and own aircraft context must be local"); - this->m_airspace = new CAirspaceMonitor(this, this->getRuntime()->getCContextOwnAircraft(), this->m_network, this->m_vatsimBookingReader, this->m_vatsimDataFileReader); + Q_ASSERT_X(this->m_webDataReader, Q_FUNC_INFO, "Missing reader"); + this->m_airspace = new CAirspaceMonitor(this->getRuntime()->getCContextOwnAircraft(), this->m_network, this->m_webDataReader, this); connect(this->m_airspace, &CAirspaceMonitor::changedAtcStationsOnline, this, &CContextNetwork::changedAtcStationsOnline); connect(this->m_airspace, &CAirspaceMonitor::changedAtcStationsBooked, this, &CContextNetwork::changedAtcStationsBooked); connect(this->m_airspace, &CAirspaceMonitor::changedAtcStationOnlineConnectionStatus, this, &CContextNetwork::changedAtcStationOnlineConnectionStatus); @@ -147,8 +139,9 @@ namespace BlackCore void CContextNetwork::gracefulShutdown() { this->disconnect(); // all signals - if (this->m_vatsimBookingReader) { this->m_vatsimBookingReader->requestStop(); this->m_vatsimBookingReader->quit(); } - if (this->m_vatsimDataFileReader) { this->m_vatsimDataFileReader->requestStop(); this->m_vatsimDataFileReader->quit(); } + this->m_webReaderSignalConnections.clear(); // disconnect + this->m_webDataReader->gracefulShutdown(); + if (this->isConnected()) { this->disconnectFromNetwork(); } if (this->m_airspace) { this->m_airspace->gracefulShutdown(); } } @@ -203,14 +196,9 @@ namespace BlackCore CServer CContextNetwork::getConnectedServer() const { - if (this->isConnected()) - { - return this->m_network->getPresetServer(); - } - else - { - return CServer(); - } + return this->isConnected() ? + this->m_network->getPresetServer() : + CServer(); } CStatusMessage CContextNetwork::disconnectFromNetwork() @@ -392,19 +380,16 @@ namespace BlackCore CServerList CContextNetwork::getVatsimFsdServers() const { + Q_ASSERT_X(this->m_webDataReader, Q_FUNC_INFO, "Missing data reader"); if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - Q_ASSERT(this->m_vatsimDataFileReader); - if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; - return this->m_vatsimDataFileReader->getFsdServers(); + return this->m_webDataReader->getVatsimFsdServers(); } CServerList CContextNetwork::getVatsimVoiceServers() const { + Q_ASSERT_X(this->m_webDataReader, Q_FUNC_INFO, "Missing data reader"); if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - Q_ASSERT(this->m_vatsimDataFileReader); - CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; - return this->m_vatsimDataFileReader->getVoiceServers(); + return this->m_webDataReader->getVatsimVoiceServers(); } void CContextNetwork::ps_fsdConnectionStatusChanged(INetwork::ConnectionStatus from, INetwork::ConnectionStatus to) @@ -455,25 +440,6 @@ namespace BlackCore m_airspace->analyzer()->setSimulatorRenderRestrictionsChanged(restricted, enabled, maxAircraft, maxRenderedDistance, maxRenderedBoundary); } - void CContextNetwork::ps_dataFileRead(int lines) - { - if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - CLogMessage(this).info("Read VATSIM data file, %1 lines") << lines; - emit vatsimDataFileRead(); - } - - void CContextNetwork::ps_readAircraftIcaoCodes(int number) - { - if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - CLogMessage(this).info("Read %1 aircraft ICAO codes") << number; - } - - void CContextNetwork::ps_readAirlinesIcaoCodes(int number) - { - if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - CLogMessage(this).info("Read %1 airline ICAO codes") << number; - } - void CContextNetwork::ps_checkForSupervisiorTextMessage(const CTextMessageList &messages) { if (messages.containsPrivateMessages()) @@ -493,13 +459,6 @@ namespace BlackCore return this->getRuntime()->getCContextOwnAircraft()->getOwnAircraft(); } - void CContextNetwork::readAtcBookingsFromSource() const - { - Q_ASSERT(this->m_vatsimBookingReader); - CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; - this->m_vatsimBookingReader->readInBackgroundThread(); - } - CAtcStationList CContextNetwork::getAtcStationsOnline() const { if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } @@ -536,13 +495,6 @@ namespace BlackCore return this->m_airspace->getAtcStationsOnline().findFirstByCallsign(callsign); } - void CContextNetwork::ps_receivedBookings(const CAtcStationList &) - { - if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - CLogMessage(this).info("Read bookings from network"); - emit vatsimBookingsRead(); - } - void CContextNetwork::requestDataUpdates() { Q_ASSERT(this->m_network); @@ -599,6 +551,13 @@ namespace BlackCore return c; } + void CContextNetwork::readAtcBookingsFromSource() const + { + if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } + Q_ASSERT_X(this->m_webDataReader, Q_FUNC_INFO, "missing reader"); + this->m_webDataReader->readAtcBookingsInBackground(); + } + bool CContextNetwork::updateAircraftRendered(const CCallsign &callsign, bool rendered, const CIdentifier &originator) { if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << rendered << originator; } diff --git a/src/blackcore/context_network_impl.h b/src/blackcore/context_network_impl.h index daf85f859..232455f43 100644 --- a/src/blackcore/context_network_impl.h +++ b/src/blackcore/context_network_impl.h @@ -21,6 +21,7 @@ #include "blackmisc/simulation/remoteaircraftprovider.h" #include "blackmisc/aviation/atcstationlist.h" #include "blackmisc/aviation/aircraftsituationlist.h" +#include "blackmisc/setnetwork.h" #include "blackmisc/network/clientlist.h" #include "blackmisc/digestsignal.h" #include "blackmisc/logmessage.h" @@ -31,9 +32,7 @@ namespace BlackCore { class CAirspaceMonitor; - class CVatsimBookingReader; - class CVatsimDataFileReader; - class CIcaoDataReader; + class CWebDataReader; //! Network context implementation class BLACKCORE_EXPORT CContextNetwork : @@ -232,37 +231,22 @@ namespace BlackCore CContextNetwork *registerWithDBus(CDBusServer *server); private: - CAirspaceMonitor *m_airspace = nullptr; - BlackCore::INetwork *m_network = nullptr; + CAirspaceMonitor *m_airspace = nullptr; + INetwork *m_network = nullptr; + CWebDataReader *m_webDataReader = nullptr; //!< web service readers + QList m_webReaderSignalConnections; INetwork::ConnectionStatus m_currentStatus = INetwork::Disconnected; //!< used to detect pending connections + QTimer *m_dataUpdateTimer = nullptr; //!< general updates such as ATIS, frequencies, see requestDataUpdates() // Digest signals, only sending after some time BlackMisc::CDigestSignal m_dsAtcStationsBookedChanged { this, &IContextNetwork::changedAtcStationsBooked, &IContextNetwork::changedAtcStationsBookedDigest, 750, 2 }; BlackMisc::CDigestSignal m_dsAtcStationsOnlineChanged { this, &IContextNetwork::changedAtcStationsOnline, &IContextNetwork::changedAtcStationsOnlineDigest, 750, 4 }; BlackMisc::CDigestSignal m_dsAircraftsInRangeChanged { this, &IContextNetwork::changedAircraftInRange, &IContextNetwork::changedAircraftInRangeDigest, 750, 4 }; - // for reading XML and VATSIM data files - CVatsimBookingReader *m_vatsimBookingReader = nullptr; - CVatsimDataFileReader *m_vatsimDataFileReader = nullptr; - CIcaoDataReader *m_icaoDataReader = nullptr; - QTimer *m_dataUpdateTimer = nullptr; //!< general updates such as ATIS, frequencies, see requestDataUpdates() - //! Own aircraft from \sa CContextOwnAircraft const BlackMisc::Simulation::CSimulatedAircraft ownAircraft() const; private slots: - //! ATC bookings received - void ps_receivedBookings(const BlackMisc::Aviation::CAtcStationList &bookedStations); - - //! Data file has been read - void ps_dataFileRead(int lines); - - //! Read ICAO codes - void ps_readAircraftIcaoCodes(int number); - - //! Read ICAO codes - void ps_readAirlinesIcaoCodes(int number); - //! Check if a supervisor message was received void ps_checkForSupervisiorTextMessage(const BlackMisc::Network::CTextMessageList &messages); @@ -272,7 +256,6 @@ namespace BlackCore //! Render restrictions have been changed, used with analyzer //! \sa CAirspaceAnalyzer void ps_simulatorRenderRestrictionsChanged(bool restricted, bool enabled, int maxAircraft, const BlackMisc::PhysicalQuantities::CLength &maxRenderedDistance, const BlackMisc::PhysicalQuantities::CLength &maxRenderedBoundary); - }; } // ns diff --git a/src/blackcore/context_ownaircraft_impl.cpp b/src/blackcore/context_ownaircraft_impl.cpp index fef06f76f..2edb87c9b 100644 --- a/src/blackcore/context_ownaircraft_impl.cpp +++ b/src/blackcore/context_ownaircraft_impl.cpp @@ -96,8 +96,7 @@ namespace BlackCore this->m_ownAircraft.setIcaoInfo( CAircraftIcaoData( CAircraftIcaoCode("C172", "L1P"), - CAirlineIcaoCode(), - "0000ff") + CAirlineIcaoCode()) ); } diff --git a/src/blackcore/context_simulator_impl.cpp b/src/blackcore/context_simulator_impl.cpp index cd7dbdfb7..1ddc3ef09 100644 --- a/src/blackcore/context_simulator_impl.cpp +++ b/src/blackcore/context_simulator_impl.cpp @@ -418,6 +418,7 @@ namespace BlackCore } Q_ASSERT_X(!listener->parent(), Q_FUNC_INFO, "Objects with parent cannot be moved to thread"); + listener->setProperty("isInitialized", true); listener->moveToThread(&m_listenersThread); } diff --git a/src/blackcore/databasereader.cpp b/src/blackcore/databasereader.cpp new file mode 100644 index 000000000..bbe9c094e --- /dev/null +++ b/src/blackcore/databasereader.cpp @@ -0,0 +1,71 @@ +/* Copyright (C) 2015 + * 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 "databasereader.h" +#include "blackmisc/logmessage.h" + +using namespace BlackMisc; + +namespace BlackCore +{ + CDatabaseReader::CDatabaseReader(QObject *owner, const QString &name) : + BlackMisc::CThreadedReader(owner, name) + { } + + void CDatabaseReader::readInBackgroundThread() + { + bool s = QMetaObject::invokeMethod(this, "ps_read"); + Q_ASSERT_X(s, Q_FUNC_INFO, "Invoke failed"); + Q_UNUSED(s); + } + + QJsonArray CDatabaseReader::transformReplyIntoJsonArray(QNetworkReply *nwReply) const + { + this->threadAssertCheck(); + QJsonArray array; + if (this->isFinished()) + { + CLogMessage(this).debug() << Q_FUNC_INFO; + CLogMessage(this).info("Terminated data parsing process"); // for users + return array; // stop, terminate straight away, ending thread + } + + if (nwReply->error() == QNetworkReply::NoError) + { + const QString dataFileData = nwReply->readAll(); + nwReply->close(); // close asap + if (dataFileData.isEmpty()) { return array; } + + QJsonDocument jsonResponse = QJsonDocument::fromJson(dataFileData.toUtf8()); + QJsonObject jsonObject = jsonResponse.object(); + QJsonArray jsonArray = jsonObject["rows"].toArray(); + return jsonArray; + } + CLogMessage(this).warning("Reading data failed %1 %2") << nwReply->errorString() << nwReply->url().toString(); + nwReply->abort(); + return array; + } + + QString CDatabaseReader::buildUrl(const QString &protocol, const QString &server, const QString &baseUrl, const QString &serviceUrl) + { + Q_ASSERT_X(protocol.length() > 3, Q_FUNC_INFO, "worng protocol"); + Q_ASSERT_X(!server.isEmpty(), Q_FUNC_INFO, "missing server"); + Q_ASSERT_X(!serviceUrl.isEmpty(), Q_FUNC_INFO, "missing service URL"); + + QString url(server); + if (!baseUrl.isEmpty()) + { + url.append("/").append(baseUrl); + } + url.append("/").append(serviceUrl); + url.replace("//", "/"); + return protocol + "://" + url; + } + +} // namespace diff --git a/src/blackcore/databasereader.h b/src/blackcore/databasereader.h new file mode 100644 index 000000000..be36620b3 --- /dev/null +++ b/src/blackcore/databasereader.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2015 + * 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. + */ + +#ifndef BLACKCORE_DATABASE_READER_H +#define BLACKCORE_DATABASE_READER_H + +//! \file + +#include "blackcore/blackcoreexport.h" +#include "blackmisc/threadedreader.h" +#include +#include + +namespace BlackCore +{ + //! Support for threaded based reading and parsing tasks such + //! as data files via http, or file system and parsing (such as FSX models) + class BLACKCORE_EXPORT CDatabaseReader : public BlackMisc::CThreadedReader + { + Q_OBJECT + + public: + //! Start reading in own thread + void readInBackgroundThread(); + + protected: + //! Constructor + CDatabaseReader(QObject *owner, const QString &name); + + //! Check if terminated or error, otherwise split into array of objects + QJsonArray transformReplyIntoJsonArray(QNetworkReply *nwReply) const; + + //! Build service URL + static QString buildUrl(const QString &protocol, const QString &server, const QString &baseUrl, const QString &serviceUrl); + + }; +} // namespace + +#endif // guard diff --git a/src/blackcore/icaodatareader.cpp b/src/blackcore/icaodatareader.cpp index 19b595a46..d1fc3f862 100644 --- a/src/blackcore/icaodatareader.cpp +++ b/src/blackcore/icaodatareader.cpp @@ -18,9 +18,9 @@ using namespace BlackMisc::Aviation; namespace BlackCore { - CIcaoDataReader::CIcaoDataReader(QObject *owner, const QString &aircraftIcaoUrl, const QString &airlineIcaoUrl) : - CThreadedReader(owner, "CIcaoDataReader"), - m_urlAircraftIcao(aircraftIcaoUrl), m_urlAirlineIcao(airlineIcaoUrl) + CIcaoDataReader::CIcaoDataReader(QObject *owner, const QString &protocol, const QString &server, const QString &baseUrl) : + CDatabaseReader(owner, "CIcaoDataReader"), + m_urlAircraftIcao(getAircraftIcaoUrl(protocol, server, baseUrl)), m_urlAirlineIcao(getAirlineIcaoUrl(protocol, server, baseUrl)) { this->m_networkManagerAircraft = new QNetworkAccessManager(this); this->m_networkManagerAirlines = new QNetworkAccessManager(this); @@ -41,11 +41,26 @@ namespace BlackCore return m_airlineIcaos; } - void CIcaoDataReader::readInBackgroundThread() + int CIcaoDataReader::getAircraftIcaoCodesCount() const { - bool s = QMetaObject::invokeMethod(this, "ps_read"); - Q_ASSERT_X(s, Q_FUNC_INFO, "Invoke failed"); - Q_UNUSED(s); + QReadLocker l(&m_lockAircraft); + return m_aircraftIcaos.size(); + } + + int CIcaoDataReader::getAirlineIcaoCodesCount() const + { + QReadLocker l(&m_lockAirline); + return m_airlineIcaos.size(); + } + + QString CIcaoDataReader::getAircraftIcaoUrl(const QString &protocol, const QString &server, const QString &baseUrl) + { + return buildUrl(protocol, server, baseUrl, "service/allaircrafticao.php?rows=20000&sord=asc"); + } + + QString CIcaoDataReader::getAirlineIcaoUrl(const QString &protocol, const QString &server, const QString &baseUrl) + { + return buildUrl(protocol, server, baseUrl, "service/allairlineicao.php?rows=20000&sord=asc"); } void CIcaoDataReader::ps_read() @@ -61,47 +76,12 @@ namespace BlackCore this->m_networkManagerAirlines->get(requestAirline); } - QJsonArray CIcaoDataReader::splitReplyIntoArray(QNetworkReply *nwReply) const - { - this->threadAssertCheck(); - QJsonArray array; - if (this->isFinished()) - { - CLogMessage(this).debug() << Q_FUNC_INFO; - CLogMessage(this).info("Terminated ICAO data parsing process"); // for users - return array; // stop, terminate straight away, ending thread - } - - if (nwReply->error() == QNetworkReply::NoError) - { - const QString dataFileData = nwReply->readAll(); - nwReply->close(); // close asap - if (dataFileData.isEmpty()) { return array; } - - QJsonDocument jsonResponse = QJsonDocument::fromJson(dataFileData.toUtf8()); - QJsonObject jsonObject = jsonResponse.object(); - QJsonArray jsonArray = jsonObject["rows"].toArray(); - return jsonArray; - } - CLogMessage(this).warning("Reading data failed %1 %2") << nwReply->errorString() << nwReply->url().toString(); - nwReply->abort(); - return array; - } - - bool BlackCore::CIcaoDataReader::checkIfFinished() const - { - if (!this->isFinished()) { return false; } - CLogMessage(this).debug() << Q_FUNC_INFO; - CLogMessage(this).info("Terminated ICAO data parsing process"); // for users - return true; - } - void CIcaoDataReader::ps_parseAircraftIcaoData(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); - QJsonArray array = this->splitReplyIntoArray(nwReply.data()); + QJsonArray array = this->transformReplyIntoJsonArray(nwReply.data()); if (array.isEmpty()) { return; } CAircraftIcaoCodeList codes = CAircraftIcaoCodeList::fromDatabaseJson(array); @@ -113,12 +93,13 @@ namespace BlackCore n = codes.size(); } emit readAircraftIcaoCodes(n); + if (this->getAirlineIcaoCodesCount() > 0) { emit readAll(); } } void CIcaoDataReader::ps_parseAirlineIcaoData(QNetworkReply *nwReplyPtr) { QScopedPointer nwReply(nwReplyPtr); - QJsonArray array = this->splitReplyIntoArray(nwReply.data()); + QJsonArray array = this->transformReplyIntoJsonArray(nwReply.data()); if (array.isEmpty()) { return; } CAirlineIcaoCodeList codes = CAirlineIcaoCodeList::fromDatabaseJson(array); @@ -130,6 +111,6 @@ namespace BlackCore n = codes.size(); } emit readAirlinesIcaoCodes(n); + if (this->getAircraftIcaoCodesCount() > 0) { emit readAll(); } } - } // namespace diff --git a/src/blackcore/icaodatareader.h b/src/blackcore/icaodatareader.h index 6cbffa327..f30d6a5b1 100644 --- a/src/blackcore/icaodatareader.h +++ b/src/blackcore/icaodatareader.h @@ -12,10 +12,10 @@ #ifndef BLACKCORE_ICAODATAREADER_H #define BLACKCORE_ICAODATAREADER_H -#include "blackcoreexport.h" +#include "blackcore/blackcoreexport.h" +#include "blackcore/databasereader.h" #include "blackmisc/aviation/aircrafticaocodelist.h" #include "blackmisc/aviation/airlineicaocodelist.h" -#include "blackmisc/threadedreader.h" #include #include @@ -24,14 +24,14 @@ namespace BlackCore { - //! Read bookings from VATSIM - class BLACKCORE_EXPORT CIcaoDataReader : public BlackMisc::CThreadedReader + //! Read ICAO data from Database + class BLACKCORE_EXPORT CIcaoDataReader : public CDatabaseReader { Q_OBJECT public: //! Constructor - explicit CIcaoDataReader(QObject *owner, const QString &aircraftIcaoUrl, const QString &airlineIcaoUrl); + explicit CIcaoDataReader(QObject *owner, const QString &protocol, const QString &server, const QString &baseUrl); //! Get aircraft ICAO information //! \threadsafe @@ -41,8 +41,13 @@ namespace BlackCore //! \threadsafe BlackMisc::Aviation::CAirlineIcaoCodeList getAirlineIcaoCodes() const; - //! Start reading in own thread - void readInBackgroundThread(); + //! Get aircraft ICAO information count + //! \threadsafe + int getAircraftIcaoCodesCount() const; + + //! Get airline ICAO information count + //! \threadsafe + int getAirlineIcaoCodesCount() const; signals: //! Codes have been read @@ -51,6 +56,9 @@ namespace BlackCore //! Codes have been read void readAirlinesIcaoCodes(int number); + //! Everything has been read + void readAll(); + private slots: //! Aircraft have been read void ps_parseAircraftIcaoData(QNetworkReply *nwReply); @@ -72,11 +80,11 @@ namespace BlackCore mutable QReadWriteLock m_lockAirline; mutable QReadWriteLock m_lockAircraft; - //! Check if terminated or error, otherwise split into array of objects - QJsonArray splitReplyIntoArray(QNetworkReply *nwReply) const; + //! URL + static QString getAircraftIcaoUrl(const QString &protocol, const QString &server, const QString &baseUrl); - //! Check if thread has been finished - bool checkIfFinished() const; + //! URL + static QString getAirlineIcaoUrl(const QString &protocol, const QString &server, const QString &baseUrl); }; } diff --git a/src/blackcore/modeldatareader.cpp b/src/blackcore/modeldatareader.cpp new file mode 100644 index 000000000..38318b89d --- /dev/null +++ b/src/blackcore/modeldatareader.cpp @@ -0,0 +1,168 @@ +/* Copyright (C) 2015 + * 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 "blackmisc/sequence.h" +#include "blackmisc/logmessage.h" +#include "modeldatareader.h" + +#include + +using namespace BlackMisc; +using namespace BlackMisc::Aviation; +using namespace BlackMisc::Simulation; + +namespace BlackCore +{ + CModelDataReader::CModelDataReader(QObject *owner, const QString &protocol, const QString &server, const QString &baseUrl) : + CDatabaseReader(owner, "CModelDataReader"), + m_urlLiveries(getLiveryUrl(protocol, server, baseUrl)), + m_urlDistributors(getDistributorUrl(protocol, server, baseUrl)), + m_urlModels(getModelUrl(protocol, server, baseUrl)) + { + this->m_networkManagerLivery = new QNetworkAccessManager(this); + this->m_networkManagerDistributor = new QNetworkAccessManager(this); + this->m_networkManagerModel = new QNetworkAccessManager(this); + + this->connect(this->m_networkManagerLivery, &QNetworkAccessManager::finished, this, &CModelDataReader::ps_parseLiveryData); + this->connect(this->m_networkManagerDistributor, &QNetworkAccessManager::finished, this, &CModelDataReader::ps_parseDistributorData); + this->connect(this->m_networkManagerModel, &QNetworkAccessManager::finished, this, &CModelDataReader::ps_parseModelData); + } + + CLiveryList CModelDataReader::getLiveries() const + { + QReadLocker l(&m_lockLivery); + return m_liveries; + } + + CDistributorList CModelDataReader::getDistributors() const + { + QReadLocker l(&m_lockDistributor); + return m_distributors; + } + + CAircraftModelList CModelDataReader::getModels() const + { + QReadLocker l(&m_lockModels); + return m_models; + } + + int CModelDataReader::getLiveriesCount() const + { + QReadLocker l(&m_lockLivery); + return m_liveries.size(); + } + + int CModelDataReader::getDistributorsCount() const + { + QReadLocker l(&m_lockDistributor); + return m_distributors.size(); + } + + int CModelDataReader::getModelsCount() const + { + QReadLocker l(&m_lockModels); + return m_models.size(); + } + + bool CModelDataReader::allRead() const + { + return + getLiveriesCount() > 0 && + getModelsCount() > 0 && + getDistributorsCount(); + } + + void CModelDataReader::ps_read() + { + this->threadAssertCheck(); + Q_ASSERT(this->m_networkManagerLivery); + Q_ASSERT(this->m_networkManagerDistributor); + Q_ASSERT(this->m_networkManagerModel); + Q_ASSERT(!m_urlLiveries.isEmpty()); + Q_ASSERT(!m_urlDistributors.isEmpty()); + QNetworkRequest requestLivery(m_urlLiveries); + QNetworkRequest requestDistributor(m_urlDistributors); + QNetworkRequest requestModel(m_urlModels); + this->m_networkManagerLivery->get(requestLivery); + this->m_networkManagerDistributor->get(requestDistributor); + this->m_networkManagerModel->get(requestModel); + } + + QString CModelDataReader::getLiveryUrl(const QString &protocol, const QString &server, const QString &baseUrl) + { + return buildUrl(protocol, server, baseUrl, "service/alllivery.php?rows=20000&sord=asc"); + } + + QString CModelDataReader::getDistributorUrl(const QString &protocol, const QString &server, const QString &baseUrl) + { + return buildUrl(protocol, server, baseUrl, "service/alldistributor.php?rows=20000&sord=asc"); + } + + QString CModelDataReader::getModelUrl(const QString &protocol, const QString &server, const QString &baseUrl) + { + return buildUrl(protocol, server, baseUrl, "service/allaircraftmodel.php?rows=20000&sord=asc"); + } + + void CModelDataReader::ps_parseLiveryData(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); + QJsonArray array = this->transformReplyIntoJsonArray(nwReply.data()); + if (array.isEmpty()) { return; } + CLiveryList liveries = CLiveryList::fromDatabaseJson(array); + + // this part needs to be synchronized + int n; + { + QWriteLocker wl(&this->m_lockLivery); + this->m_liveries = liveries; + n = liveries.size(); + } + emit readLiveries(n); + if (allRead()) { emit readAll(); } + } + + void CModelDataReader::ps_parseDistributorData(QNetworkReply *nwReplyPtr) + { + QScopedPointer nwReply(nwReplyPtr); + QJsonArray array = this->transformReplyIntoJsonArray(nwReply.data()); + if (array.isEmpty()) { return; } + CDistributorList distributors = CDistributorList::fromDatabaseJson(array); + + // this part needs to be synchronized + int n; + { + QWriteLocker wl(&this->m_lockDistributor); + this->m_distributors = distributors; + n = distributors.size(); + } + emit readDistributors(n); + if (allRead()) { emit readAll(); } + } + + void CModelDataReader::ps_parseModelData(QNetworkReply *nwReplyPtr) + { + QScopedPointer nwReply(nwReplyPtr); + QJsonArray array = this->transformReplyIntoJsonArray(nwReply.data()); + if (array.isEmpty()) { return; } + CAircraftModelList models = CAircraftModelList::fromDatabaseJson(array); + + // this part needs to be synchronized + int n; + { + QWriteLocker wl(&this->m_lockModels); + this->m_models = models; + n = models.size(); + } + emit readModels(n); + if (allRead()) { emit readAll(); } + } + +} // namespace diff --git a/src/blackcore/modeldatareader.h b/src/blackcore/modeldatareader.h new file mode 100644 index 000000000..01ec1a0df --- /dev/null +++ b/src/blackcore/modeldatareader.h @@ -0,0 +1,116 @@ +/* Copyright (C) 2015 + * 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 BLACKCORE_MODELDATAREADER_H +#define BLACKCORE_MODELDATAREADER_H + +#include "blackcore/blackcoreexport.h" +#include "blackcore/databasereader.h" +#include "blackmisc/aviation/liverylist.h" +#include "blackmisc/simulation/distributorlist.h" +#include "blackmisc/simulation/aircraftmodellist.h" + +#include +#include +#include +#include + +namespace BlackCore +{ + //! Read model related data from Database + class BLACKCORE_EXPORT CModelDataReader : public CDatabaseReader + { + Q_OBJECT + + public: + //! Constructor + explicit CModelDataReader(QObject *owner, const QString &protocol, const QString &server, const QString &baseUrl); + + //! Get aircraft liveries + //! \threadsafe + BlackMisc::Aviation::CLiveryList getLiveries() const; + + //! Get distributors (of models) + //! \threadsafe + BlackMisc::Simulation::CDistributorList getDistributors() const; + + //! Get models + //! \threadsafe + BlackMisc::Simulation::CAircraftModelList getModels() const; + + //! Get aircraft liveries count + //! \threadsafe + int getLiveriesCount() const; + + //! Get model distributors count + //! \threadsafe + int getDistributorsCount() const; + + //! Get models count + //! \threadsafe + int getModelsCount() const; + + //! All data read + bool allRead() const; + + signals: + //! Liveries have been read + void readLiveries(int number); + + //! Distributors have been read + void readDistributors(int number); + + //! Models have been read + void readModels(int number); + + //! All data read + void readAll(); + + private slots: + //! Liveries have been read + void ps_parseLiveryData(QNetworkReply *nwReply); + + //! Distributors have been read + void ps_parseDistributorData(QNetworkReply *nwReply); + + //! Models have been read + void ps_parseModelData(QNetworkReply *nwReply); + + //! Read / re-read data file + void ps_read(); + + private: + QNetworkAccessManager *m_networkManagerLivery = nullptr; + QNetworkAccessManager *m_networkManagerDistributor = nullptr; + QNetworkAccessManager *m_networkManagerModel = nullptr; + BlackMisc::Aviation::CLiveryList m_liveries; + BlackMisc::Simulation::CDistributorList m_distributors; + BlackMisc::Simulation::CAircraftModelList m_models; + QString m_urlLiveries; + QString m_urlDistributors; + QString m_urlModels; + + mutable QReadWriteLock m_lockDistributor; + mutable QReadWriteLock m_lockLivery; + mutable QReadWriteLock m_lockModels; + + //! URL livery web service + static QString getLiveryUrl(const QString &protocol, const QString &server, const QString &baseUrl); + + //! URL distributor web service + static QString getDistributorUrl(const QString &protocol, const QString &server, const QString &baseUrl); + + //! URL model web service + static QString getModelUrl(const QString &protocol, const QString &server, const QString &baseUrl); + }; +} // ns + +#endif // guard diff --git a/src/blackcore/network_vatlib.cpp b/src/blackcore/network_vatlib.cpp index 69d53e23d..93b95c65c 100644 --- a/src/blackcore/network_vatlib.cpp +++ b/src/blackcore/network_vatlib.cpp @@ -69,7 +69,7 @@ namespace BlackCore clientCapabilities |= vatCapsStealth; } - m_net.reset(Vat_CreateNetworkSession(vatServerLegacyFsd, CProject::systemNameAndVersionChar(), + m_net.reset(Vat_CreateNetworkSession(vatServerLegacyFsd, CProject::swiftVersionChar(), CProject::versionMajor(), CProject::versionMinor(), "None", CLIENT_PUBLIC_ID, CLIENT_PRIVATE_KEY, clientCapabilities)); @@ -553,7 +553,7 @@ namespace BlackCore { const QByteArray acTypeICAObytes = toFSD(m_icaoCode.getAircraftDesignator()); const QByteArray airlineICAObytes = toFSD(m_icaoCode.getAirlineDesignator()); - const QByteArray liverybytes = toFSD(m_icaoCode.getLivery()); + const QByteArray liverybytes; //! \todo VATLIB: send livery VatAircraftInfo aircraftInfo {acTypeICAObytes, airlineICAObytes, liverybytes}; Vat_SendModernPlaneInfo(m_net.data(), toFSD(callsign), &aircraftInfo); @@ -1024,7 +1024,8 @@ namespace BlackCore BlackMisc::Aviation::CAircraftIcaoData icao; icao.setAircraftDesignator(aircraftInfo->aircraftType); icao.setAirlineDesignator(aircraftInfo->airline); - icao.setLivery(aircraftInfo->livery); + + //! \todo use livery: aircraftInfo->livery; emit cbvar_cast(cbvar)->icaoCodesReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), icao); } diff --git a/src/blackcore/reader_settings.cpp b/src/blackcore/reader_settings.cpp new file mode 100644 index 000000000..0923d5231 --- /dev/null +++ b/src/blackcore/reader_settings.cpp @@ -0,0 +1,28 @@ +/* Copyright (C) 2015 + * 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 "reader_settings.h" + +namespace BlackCore +{ + CReaderSettings::CReaderSettings() : + // m_protocolIcaoReader("http"), m_serverIcaoReader("vatrep.vatsim-germany.org"), + // m_protocolModelReader("http"), m_serverModelReader("vatrep.vatsim-germany.org"), + m_protocolIcaoReader("http"), m_serverIcaoReader("ubuntu12"), m_baseUrlIcaoReader("vatrep/public"), + m_protocolModelReader("http"), m_serverModelReader("ubuntu12"), m_baseUrlModelReader("vatrep/public"), + m_bookingsUrl("http://vatbook.euroutepro.com/xml2.php"), + m_vatsimDataFileUrls({ "http://info.vroute.net/vatsim-data.txt" }) + { } + + const CReaderSettings &CReaderSettings::instance() + { + static const CReaderSettings rs; + return rs; + } +} diff --git a/src/blackcore/reader_settings.h b/src/blackcore/reader_settings.h new file mode 100644 index 000000000..937dd5ed6 --- /dev/null +++ b/src/blackcore/reader_settings.h @@ -0,0 +1,69 @@ +/* Copyright (C) 2015 + * 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. + */ + +#ifndef BLACKCORE_READERSETTINGS_H +#define BLACKCORE_READERSETTINGS_H + +#include "blackcoreexport.h" +#include +#include + +namespace BlackCore +{ + //! Settings for readers + class BLACKCORE_EXPORT CReaderSettings : public QObject + { + Q_OBJECT + + public: + //! ICAO Reader protocol + const QString &protocolIcaoReader() const { return m_protocolIcaoReader; } + + //! ICAO Reader server + const QString &serverIcaoReader() const { return m_serverIcaoReader; } + + //! ICAO Reader base URL + const QString &baseUrlIcaoReader() const { return m_baseUrlIcaoReader; } + + //! Model Reader protocol + const QString &protocolModelReader() const { return m_protocolModelReader; } + + //! Model Reader server + const QString &serverModelReader() const { return m_serverModelReader; } + + //! Model Reader server + const QString &baseUrlModelReader() const { return m_baseUrlModelReader; } + + //! URL to read bookings + const QString &bookingsUrl() const { return m_bookingsUrl; } + + //! VATSIM data file URLs + const QStringList &vatsimDataFileUrls() const { return m_vatsimDataFileUrls; } + + //! Singleton + static const CReaderSettings &instance(); + + private: + //! Default constructor + CReaderSettings(); + + //! Destructor. + ~CReaderSettings() {} + + QString m_protocolIcaoReader; + QString m_serverIcaoReader; + QString m_baseUrlIcaoReader; + QString m_protocolModelReader; + QString m_serverModelReader; + QString m_baseUrlModelReader; + QString m_bookingsUrl; + QStringList m_vatsimDataFileUrls; + }; +} +#endif // guard diff --git a/src/blackcore/simulator.h b/src/blackcore/simulator.h index 06d48bf01..617860cb7 100644 --- a/src/blackcore/simulator.h +++ b/src/blackcore/simulator.h @@ -295,5 +295,6 @@ namespace BlackCore Q_DECLARE_INTERFACE(BlackCore::ISimulatorFactory, "org.swift-project.blackcore.simulatorinterface") Q_DECLARE_OPERATORS_FOR_FLAGS(BlackCore::ISimulator::SimulatorStatus) +Q_DECLARE_INTERFACE(BlackCore::ISimulatorListener, "org.swift-project.blackcore.simulatorlistener") #endif // guard diff --git a/src/blackcore/vatsimbookingreader.cpp b/src/blackcore/vatsimbookingreader.cpp index 575e5ade3..4a9bc3591 100644 --- a/src/blackcore/vatsimbookingreader.cpp +++ b/src/blackcore/vatsimbookingreader.cpp @@ -21,8 +21,9 @@ using namespace BlackMisc::Network; namespace BlackCore { - CVatsimBookingReader::CVatsimBookingReader(QObject *owner) : - CThreadedReader(owner, "CVatsimBookingReader") + CVatsimBookingReader::CVatsimBookingReader(QObject *owner, const QString &url) : + CThreadedReader(owner, "CVatsimBookingReader"), + m_serviceUrl(url) { this->m_networkManager = new QNetworkAccessManager(this); this->connect(this->m_networkManager, &QNetworkAccessManager::finished, this, &CVatsimBookingReader::ps_parseBookings); @@ -39,7 +40,7 @@ namespace BlackCore void CVatsimBookingReader::ps_read() { this->threadAssertCheck(); - QUrl url(this->m_serviceUrl.get()); + QUrl url(this->m_serviceUrl); if (url.isEmpty()) return; Q_ASSERT(this->m_networkManager); QNetworkRequest request(url); diff --git a/src/blackcore/vatsimbookingreader.h b/src/blackcore/vatsimbookingreader.h index dd3099777..2f3339559 100644 --- a/src/blackcore/vatsimbookingreader.h +++ b/src/blackcore/vatsimbookingreader.h @@ -13,7 +13,6 @@ #define BLACKCORE_VATSIMBOOKINGREADER_H #include "blackcoreexport.h" -#include "blackcore/settings/network.h" #include "blackmisc/threadedreader.h" #include "blackmisc/aviation/atcstationlist.h" @@ -31,7 +30,7 @@ namespace BlackCore public: //! Constructor - explicit CVatsimBookingReader(QObject *owner); + explicit CVatsimBookingReader(QObject *owner, const QString &url); //! Read / re-read bookings void readInBackgroundThread(); @@ -45,7 +44,7 @@ namespace BlackCore void ps_read(); private: - CSetting m_serviceUrl { this }; + QString m_serviceUrl; //!< URL of the service QNetworkAccessManager *m_networkManager = nullptr; signals: diff --git a/src/blackcore/web_datareader.cpp b/src/blackcore/web_datareader.cpp new file mode 100644 index 000000000..7f3defed3 --- /dev/null +++ b/src/blackcore/web_datareader.cpp @@ -0,0 +1,260 @@ +/* Copyright (C) 2015 + * 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 "blackcore/web_datareader.h" +#include "vatsimbookingreader.h" +#include "vatsimdatafilereader.h" +#include "icaodatareader.h" +#include "modeldatareader.h" +#include "reader_settings.h" +#include "blackmisc/logmessage.h" +#include "blackmisc/worker.h" + +using namespace BlackMisc; +using namespace BlackMisc::Simulation; +using namespace BlackMisc::Network; +using namespace BlackMisc::Aviation; +using namespace BlackMisc::PhysicalQuantities; + +namespace BlackCore +{ + + CWebDataReader::CWebDataReader(WebReader readerFlags, QObject *parent) : + QObject(parent), m_readerFlags(readerFlags) + { + this->setObjectName("CWebDataReader"); + this->initReaders(readerFlags); + } + + QList CWebDataReader::connectVatsimDataSignals(std::function bookingsRead, std::function dataFileRead) + { + // bind does not allow to define connection type + // so anything in its own thread will be sent with this thread affinity + QList cl; + + if (m_readerFlags.testFlag(VatsimBookingReader)) + { + QMetaObject::Connection c1 = connect(this, &CWebDataReader::vatsimBookingsRead, bookingsRead); + Q_ASSERT_X(c1, Q_FUNC_INFO, "connect failed"); + cl.append(c1); + } + + if (m_readerFlags.testFlag(VatsimDataReader)) + { + QMetaObject::Connection c2 = connect(this, &CWebDataReader::vatsimDataFileRead, dataFileRead); + Q_ASSERT_X(c2, Q_FUNC_INFO, "connect failed"); + cl.append(c2); + } + return cl; + } + + QList CWebDataReader::connectSwiftDatabaseSignals( + QObject *receiver, + std::function aircraftIcaoCodeRead, std::function airlineIcaoCodeRead, + std::function liveriesRead, std::function distributorsRead, + std::function modelsRead) + { + Q_ASSERT_X(receiver, Q_FUNC_INFO, "Missing receiver"); + + // bind does not allow to define connection type + // so anything in its own thread will be sent with this thread affinity + QList cl; + + if (m_readerFlags.testFlag(IcaoDataReader)) + { + QMetaObject::Connection c1 = connect(this, &CWebDataReader::aircraftIcaoCodeRead, receiver, aircraftIcaoCodeRead); + Q_ASSERT_X(c1, Q_FUNC_INFO, "connect failed"); + cl.append(c1); + QMetaObject::Connection c2 = connect(this, &CWebDataReader::airlineIcaoCodeRead, receiver, airlineIcaoCodeRead); + Q_ASSERT_X(c2, Q_FUNC_INFO, "connect failed"); + cl.append(c2); + } + + if (m_readerFlags.testFlag(ModelReader)) + { + QMetaObject::Connection c1 = connect(this, &CWebDataReader::liveriesRead, receiver, liveriesRead); + Q_ASSERT_X(c1, Q_FUNC_INFO, "connect failed"); + cl.append(c1); + QMetaObject::Connection c2 = connect(this, &CWebDataReader::distributorsRead, receiver, distributorsRead); + Q_ASSERT_X(c2, Q_FUNC_INFO, "connect failed"); + cl.append(c2); + QMetaObject::Connection c3 = connect(this, &CWebDataReader::modelsRead, receiver, modelsRead); + Q_ASSERT_X(c3, Q_FUNC_INFO, "connect failed"); + cl.append(c3); + } + return cl; + } + + CServerList CWebDataReader::getVatsimFsdServers() const + { + if (m_vatsimDataFileReader) { return m_vatsimDataFileReader->getFsdServers(); } + return CServerList(); + } + + CServerList CWebDataReader::getVatsimVoiceServers() const + { + if (m_vatsimDataFileReader) { return m_vatsimDataFileReader->getVoiceServers(); } + return CServerList(); + } + + CDistributorList CWebDataReader::getDistributors() const + { + if (m_modelDataReader) { return m_modelDataReader->getDistributors(); } + return CDistributorList(); + } + + CLiveryList CWebDataReader::getLiveries() const + { + if (m_modelDataReader) { return m_modelDataReader->getLiveries(); } + return CLiveryList(); + } + + CAircraftModelList CWebDataReader::getModels() const + { + if (m_modelDataReader) { return m_modelDataReader->getModels(); } + return CAircraftModelList(); + } + + CAircraftIcaoCodeList CWebDataReader::getAircraftIcaoCodes() const + { + if (m_icaoDataReader) { return m_icaoDataReader->getAircraftIcaoCodes(); } + return CAircraftIcaoCodeList(); + } + + CAirlineIcaoCodeList CWebDataReader::getAirlineIcaoCodes() const + { + if (m_icaoDataReader) { return m_icaoDataReader->getAirlineIcaoCodes(); } + return CAirlineIcaoCodeList(); + } + + void CWebDataReader::gracefulShutdown() + { + this->disconnect(); // all signals + if (this->m_vatsimBookingReader) { this->m_vatsimBookingReader->requestStop(); this->m_vatsimBookingReader->quit(); } + if (this->m_vatsimDataFileReader) { this->m_vatsimDataFileReader->requestStop(); this->m_vatsimDataFileReader->quit(); } + } + + const CLogCategoryList &CWebDataReader::getLogCategories() + { + static const BlackMisc::CLogCategoryList cats { CLogCategory("swift.datareader") }; + return cats; + } + + void CWebDataReader::initReaders(WebReader flags) + { + // 1. VATSIM bookings + if (flags.testFlag(VatsimBookingReader)) + { + this->m_vatsimBookingReader = new CVatsimBookingReader(this, CReaderSettings::instance().bookingsUrl()); + connect(this->m_vatsimBookingReader, &CVatsimBookingReader::dataRead, this, &CWebDataReader::ps_receivedBookings); + this->m_vatsimBookingReader->start(); + this->m_vatsimBookingReader->setInterval(3 * 60 * 1000); + } + + // 2. VATSIM data file + if (flags.testFlag(VatsimDataReader)) + { + this->m_vatsimDataFileReader = new CVatsimDataFileReader(this, CReaderSettings::instance().vatsimDataFileUrls()); + connect(this->m_vatsimDataFileReader, &CVatsimDataFileReader::dataRead, this, &CWebDataReader::ps_dataFileRead); + this->m_vatsimDataFileReader->start(); + this->m_vatsimDataFileReader->setInterval(90 * 1000); + } + + // 3. ICAO data reader + if (flags.testFlag(IcaoDataReader)) + { + this->m_icaoDataReader = new CIcaoDataReader(this, CReaderSettings::instance().protocolIcaoReader(), CReaderSettings::instance().serverIcaoReader(), CReaderSettings::instance().baseUrlIcaoReader()); + connect(this->m_icaoDataReader, &CIcaoDataReader::readAircraftIcaoCodes, this, &CWebDataReader::ps_readAircraftIcaoCodes); + connect(this->m_icaoDataReader, &CIcaoDataReader::readAirlinesIcaoCodes, this, &CWebDataReader::ps_readAirlinesIcaoCodes); + this->m_icaoDataReader->start(); + } + + // 4. Model reader + if (flags.testFlag(ModelReader)) + { + this->m_modelDataReader = new CModelDataReader(this, CReaderSettings::instance().protocolModelReader(), CReaderSettings::instance().serverModelReader(), CReaderSettings::instance().baseUrlModelReader()); + connect(this->m_modelDataReader, &CModelDataReader::readLiveries, this, &CWebDataReader::ps_readLiveries); + connect(this->m_modelDataReader, &CModelDataReader::readDistributors, this, &CWebDataReader::ps_readDistributors); + connect(this->m_modelDataReader, &CModelDataReader::readModels, this, &CWebDataReader::ps_readModels); + this->m_modelDataReader->start(); + } + } + + void CWebDataReader::ps_receivedBookings(const CAtcStationList &stations) + { + CLogMessage(this).info("Read bookings from network"); + emit vatsimBookingsRead(stations.size()); + } + + void CWebDataReader::ps_dataFileRead(int lines) + { + CLogMessage(this).info("Read VATSIM data file, %1 lines") << lines; + emit vatsimDataFileRead(lines); + } + + void CWebDataReader::ps_readAircraftIcaoCodes(int number) + { + CLogMessage(this).info("Read %1 aircraft ICAO codes") << number; + emit aircraftIcaoCodeRead(number); + } + + void CWebDataReader::ps_readAirlinesIcaoCodes(int number) + { + CLogMessage(this).info("Read %1 airline ICAO codes") << number; + emit airlineIcaoCodeRead(number); + } + + void CWebDataReader::ps_readLiveries(int number) + { + CLogMessage(this).info("Read %1 liveries") << number; + emit liveriesRead(number); + } + + void CWebDataReader::ps_readDistributors(int number) + { + CLogMessage(this).info("Read %1 distributors") << number; + emit distributorsRead(number); + } + + void CWebDataReader::ps_readModels(int number) + { + CLogMessage(this).info("Read %1 models") << number; + emit modelsRead(number); + } + + void CWebDataReader::readAllInBackground(int delayMs) + { + if (delayMs > 100) + { + BlackMisc::singleShot(delayMs, QThread::currentThread(), [ = ]() + { + this->readAllInBackground(0); + }); + return; + } + + if (this->m_vatsimBookingReader) {this->m_vatsimBookingReader->readInBackgroundThread(); } + if (this->m_vatsimDataFileReader) this->m_vatsimDataFileReader->readInBackgroundThread(); + if (this->m_icaoDataReader) { this->m_icaoDataReader->readInBackgroundThread(); } + if (this->m_modelDataReader) { this->m_modelDataReader->readInBackgroundThread(); } + } + + void CWebDataReader::readAtcBookingsInBackground() const + { + if (!this->m_vatsimBookingReader) { return; } + this->m_vatsimBookingReader->readInBackgroundThread(); + } + + void CWebDataReader::readModelDataInBackground() const + { + if (!this->m_modelDataReader) { return; } + this->m_modelDataReader->readInBackgroundThread(); + } + +} // ns diff --git a/src/blackcore/web_datareader.h b/src/blackcore/web_datareader.h new file mode 100644 index 000000000..81ee3a017 --- /dev/null +++ b/src/blackcore/web_datareader.h @@ -0,0 +1,173 @@ +/* Copyright (C) 2015 + * 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 BLACKCORE_WEB_DATAREADER_H +#define BLACKCORE_WEB_DATAREADER_H + +#include "blackcore/blackcoreexport.h" +#include "blackmisc/logcategorylist.h" +#include "blackmisc/aviation/atcstationlist.h" +#include "blackmisc/aviation/liverylist.h" +#include "blackmisc/aviation/airlineicaocodelist.h" +#include "blackmisc/aviation/aircrafticaocodelist.h" +#include "blackmisc/network/serverlist.h" +#include "blackmisc/simulation/distributorlist.h" +#include + +namespace BlackCore +{ + class CVatsimBookingReader; + class CVatsimDataFileReader; + class CIcaoDataReader; + class CModelDataReader; + + /** + * Encapsulates reading data from web sources + */ + class BLACKCORE_EXPORT CWebDataReader : public QObject + { + Q_OBJECT + + public: + //! \todo Qt5.5: Make use of QFlags + enum WebReaderFlags + { + None = 0, + VatsimBookingReader = 1 << 0, + VatsimDataReader = 1 << 1, + IcaoDataReader = 1 << 2, + ModelReader = 1 << 3, + AllVatsimReaders = VatsimBookingReader | VatsimDataReader, + AllSwiftDbReaders = IcaoDataReader | ModelReader, + AllReaders = 0xFFFF + }; + Q_DECLARE_FLAGS(WebReader, WebReaderFlags) + + //! Constructor + CWebDataReader(WebReader readerFlags, QObject *parent = nullptr); + + //! Shutdown + void gracefulShutdown(); + + //! Relay signals for VATSIM data + QList connectVatsimDataSignals(std::function bookingsRead, std::function dataFileRead); + + //! Relay signals for swift data + QList connectSwiftDatabaseSignals( + QObject *receiver, + std::function aircraftIcaoCodeRead, std::function airlineIcaoCodeRead, + std::function liveriesRead, std::function distributorsRead, + std::function modelsRead); + + //! \copydoc CVatsimDataFileReader::getVatsimFsdServers + BlackMisc::Network::CServerList getVatsimFsdServers() const; + + //! \copydoc CVatsimDataFileReader::getVatsimVoiceServers + BlackMisc::Network::CServerList getVatsimVoiceServers() const; + + //! \copydoc CModelDataReader::getDistributors + BlackMisc::Simulation::CDistributorList getDistributors() const; + + //! \copydoc CModelDataReader::getLiveries + BlackMisc::Aviation::CLiveryList getLiveries() const; + + //! \copydoc CModelDataReader::getModels + BlackMisc::Simulation::CAircraftModelList getModels() const; + + //! \copydoc CIcaoDataReader::getAircraftIcaoCodes + BlackMisc::Aviation::CAircraftIcaoCodeList getAircraftIcaoCodes() const; + + //! \copydoc CIcaoDataReader::getAirlineIcaoCodes + BlackMisc::Aviation::CAirlineIcaoCodeList getAirlineIcaoCodes() const; + + //! Read ATC bookings + void readAtcBookingsInBackground() const; + + //! Read liveries + void readModelDataInBackground() const; + + //! Booking reader + CVatsimBookingReader *getBookingReader() const { return m_vatsimBookingReader; } + + //! Data file reader + CVatsimDataFileReader *getDataFileReader() const { return m_vatsimDataFileReader; } + + //! Reader flags + WebReader getReaderFlags() const { return m_readerFlags; } + + //! Log categories + static const BlackMisc::CLogCategoryList &getLogCategories(); + + public slots: + //! First read (allows to immediately read in background) + void readAllInBackground(int delayMs); + + signals: + //! Data file read + void vatsimDataFileRead(int lines); + + //! Bookings read + void vatsimBookingsRead(int number); + + //! ICAO codes read + void aircraftIcaoCodeRead(int number); + + //! ICAO codes read + void airlineIcaoCodeRead(int number); + + //! Liveries read + void liveriesRead(int number); + + //! Distributors read + void distributorsRead(int number); + + //! Models read + void modelsRead(int number); + + private slots: + //! ATC bookings received + void ps_receivedBookings(const BlackMisc::Aviation::CAtcStationList &bookedStations); + + //! Data file has been read + void ps_dataFileRead(int lines); + + //! Read ICAO codes + void ps_readAircraftIcaoCodes(int number); + + //! Read ICAO codes + void ps_readAirlinesIcaoCodes(int number); + + //! Read liveries + void ps_readLiveries(int number); + + //! Read distributors + void ps_readDistributors(int number); + + //! Read models + void ps_readModels(int number); + + private: + //! Init the readers + void initReaders(WebReader flags); + + WebReader m_readerFlags = None; //!< which readers are available + + // for reading XML and VATSIM data files + CVatsimBookingReader *m_vatsimBookingReader = nullptr; + CVatsimDataFileReader *m_vatsimDataFileReader = nullptr; + CIcaoDataReader *m_icaoDataReader = nullptr; + CModelDataReader *m_modelDataReader = nullptr; + }; +} // namespace + +Q_DECLARE_OPERATORS_FOR_FLAGS(BlackCore::CWebDataReader::WebReader) + +#endif diff --git a/src/blackmisc/setnetwork.h b/src/blackmisc/setnetwork.h new file mode 100644 index 000000000..3a51208b7 --- /dev/null +++ b/src/blackmisc/setnetwork.h @@ -0,0 +1,113 @@ +/* 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_SETTINGS_NETWORK_H +#define BLACKMISC_SETTINGS_NETWORK_H + +#include "blackmiscexport.h" +#include "network/serverlist.h" +#include "valueobject.h" +#include "statusmessagelist.h" +#include "settingutilities.h" +#include + +namespace BlackMisc +{ + class CVariant; + + namespace Settings + { + //! Value object encapsulating information of network related settings. + //! \remarks Not only traffic network settings, but also URLs, DBus address, ... + class BLACKMISC_EXPORT CSettingsNetwork : public CValueObject + { + public: + //! Default constructor. + CSettingsNetwork(); + + //! Destructor. + virtual ~CSettingsNetwork() {} + + //! Current server + //! \deprecated shall not be used anymore + static const QString &CmdSetCurrentServer() + { + static const QString cmd("currenttrafficserver"); + return cmd; + } + + //! Path + static const QString &ValueTrafficServers() + { + static const QString value("trafficservers"); + return value; + } + + //! Path + static const QString &ValueBookingServiceUrl() + { + static const QString value("bookingserviceurl"); + return value; + } + + //! Path + static const QString &ValueDBusServerAddress() + { + static const QString value("dbuserveraddress"); + return value; + } + + //! Denotes a session DBus server + static const QString &sessionDBusServer() + { + static QString session("session"); + return session; + } + + //! Value object, traffic network server objects + BlackMisc::Network::CServerList getTrafficNetworkServers() const { return m_trafficNetworkServers; } + + //! Selected traffic network server + //! \deprecated Shall not be used anymore + BlackMisc::Network::CServer getCurrentTrafficNetworkServer() const { return m_trafficNetworkServerCurrent; } + + //! Address for DBus Server + QString getDBusServerAddress() const { return m_dbusServerAddress; } + + //! Selected traffic network server + bool setCurrentNetworkServer(const BlackMisc::Network::CServer ¤tServer); + + //! Traffic network server objects + void addTrafficNetworkServer(const BlackMisc::Network::CServer &server) { m_trafficNetworkServers.push_back(server); } + + //! \copydoc BlackCore::IContextSettings::value + BlackMisc::CStatusMessage value(const QString &path, const QString &command, const CVariant &value, bool &changedFlag); + + //! Init with meaningful default values + void initDefaultValues(); + + //! \copydoc CValueObject::convertToQString + QString convertToQString(bool i18n = false) const; + + private: + BLACK_ENABLE_TUPLE_CONVERSION(CSettingsNetwork) + BlackMisc::Network::CServerList m_trafficNetworkServers; + BlackMisc::Network::CServer m_trafficNetworkServerCurrent; + QString m_dbusServerAddress; + }; + + } // namespace +} // namespace + +Q_DECLARE_METATYPE(BlackMisc::Settings::CSettingsNetwork) +BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Settings::CSettingsNetwork, (o.m_trafficNetworkServers, o.m_trafficNetworkServerCurrent, o.m_dbusServerAddress)) + +#endif // guard