mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-05-01 22:55:41 +08:00
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
This commit is contained in:
committed by
Mathew Sutcliffe
parent
6ccc23fb32
commit
c760f1d424
@@ -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);
|
||||
|
||||
@@ -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<BlackMisc::Aviation::CAirportIcaoCode, BlackMisc::Aviation::CInformationMessage> m_metarCache;
|
||||
QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CFlightPlan> m_flightPlanCache;
|
||||
QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CFlightPlan> m_flightPlanCache;
|
||||
QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftIcaoData> 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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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<QMetaObject::Connection> 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
|
||||
|
||||
|
||||
@@ -96,8 +96,7 @@ namespace BlackCore
|
||||
this->m_ownAircraft.setIcaoInfo(
|
||||
CAircraftIcaoData(
|
||||
CAircraftIcaoCode("C172", "L1P"),
|
||||
CAirlineIcaoCode(),
|
||||
"0000ff")
|
||||
CAirlineIcaoCode())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
71
src/blackcore/databasereader.cpp
Normal file
71
src/blackcore/databasereader.cpp
Normal file
@@ -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
|
||||
45
src/blackcore/databasereader.h
Normal file
45
src/blackcore/databasereader.h
Normal file
@@ -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 <QNetworkReply>
|
||||
#include <QJsonArray>
|
||||
|
||||
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
|
||||
@@ -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<QNetworkReply, QScopedPointerDeleteLater> 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<QNetworkReply, QScopedPointerDeleteLater> 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
|
||||
|
||||
@@ -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 <QObject>
|
||||
#include <QTimer>
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
168
src/blackcore/modeldatareader.cpp
Normal file
168
src/blackcore/modeldatareader.cpp
Normal file
@@ -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 <QRegularExpression>
|
||||
|
||||
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<QNetworkReply, QScopedPointerDeleteLater> 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<QNetworkReply, QScopedPointerDeleteLater> 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<QNetworkReply, QScopedPointerDeleteLater> 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
|
||||
116
src/blackcore/modeldatareader.h
Normal file
116
src/blackcore/modeldatareader.h
Normal file
@@ -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 <QObject>
|
||||
#include <QTimer>
|
||||
#include <QNetworkReply>
|
||||
#include <QReadWriteLock>
|
||||
|
||||
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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
28
src/blackcore/reader_settings.cpp
Normal file
28
src/blackcore/reader_settings.cpp
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
69
src/blackcore/reader_settings.h
Normal file
69
src/blackcore/reader_settings.h
Normal file
@@ -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 <QStringList>
|
||||
#include <QObject>
|
||||
|
||||
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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Settings::Network::BookingService> m_serviceUrl { this };
|
||||
QString m_serviceUrl; //!< URL of the service
|
||||
QNetworkAccessManager *m_networkManager = nullptr;
|
||||
|
||||
signals:
|
||||
|
||||
260
src/blackcore/web_datareader.cpp
Normal file
260
src/blackcore/web_datareader.cpp
Normal file
@@ -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<QMetaObject::Connection> CWebDataReader::connectVatsimDataSignals(std::function<void(int)> bookingsRead, std::function<void(int)> dataFileRead)
|
||||
{
|
||||
// bind does not allow to define connection type
|
||||
// so anything in its own thread will be sent with this thread affinity
|
||||
QList<QMetaObject::Connection> 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<QMetaObject::Connection> CWebDataReader::connectSwiftDatabaseSignals(
|
||||
QObject *receiver,
|
||||
std::function<void(int)> aircraftIcaoCodeRead, std::function<void(int)> airlineIcaoCodeRead,
|
||||
std::function<void(int)> liveriesRead, std::function<void(int)> distributorsRead,
|
||||
std::function<void(int)> 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<QMetaObject::Connection> 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
|
||||
173
src/blackcore/web_datareader.h
Normal file
173
src/blackcore/web_datareader.h
Normal file
@@ -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 <QObject>
|
||||
|
||||
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<QMetaObject::Connection> connectVatsimDataSignals(std::function<void(int)> bookingsRead, std::function<void(int)> dataFileRead);
|
||||
|
||||
//! Relay signals for swift data
|
||||
QList<QMetaObject::Connection> connectSwiftDatabaseSignals(
|
||||
QObject *receiver,
|
||||
std::function<void(int)> aircraftIcaoCodeRead, std::function<void(int)> airlineIcaoCodeRead,
|
||||
std::function<void(int)> liveriesRead, std::function<void(int)> distributorsRead,
|
||||
std::function<void(int)> 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
|
||||
Reference in New Issue
Block a user