diff --git a/src/blackcore/airspacemonitor.cpp b/src/blackcore/airspacemonitor.cpp index d28e6147a..762eae1b8 100644 --- a/src/blackcore/airspacemonitor.cpp +++ b/src/blackcore/airspacemonitor.cpp @@ -105,7 +105,7 @@ namespace BlackCore if (this->supportsVatsimDataFile()) { - connect(sApp->getWebDataServices()->getVatsimDataFileReader(), &CVatsimDataFileReader::dataFileRead, this, &CAirspaceMonitor::onReceivedDataFile); + connect(sApp->getWebDataServices()->getVatsimDataFileReader(), &CVatsimDataFileReader::dataFileRead, this, &CAirspaceMonitor::onReceivedVatsimDataFile); } // Force snapshot in the main event loop @@ -400,24 +400,6 @@ namespace BlackCore return users; } - CClientList CAirspaceMonitor::getOtherClientsForCallsigns(const CCallsignSet &callsigns) const - { - CClientList clients; - if (callsigns.isEmpty()) { return clients; } - clients.push_back(this->getOtherClients().findByCallsigns(callsigns)); - return clients; - } - - CClient CAirspaceMonitor::getOtherClientOrDefaultForCallsign(const CCallsign &callsign) const - { - return this->getOtherClients().findFirstByCallsign(callsign); - } - - bool CAirspaceMonitor::hasClientInfo(const CCallsign &callsign) const - { - return this->getOtherClients().containsCallsign(callsign); - } - bool CAirspaceMonitor::isAircraftInRange(const CCallsign &callsign) const { if (callsign.isEmpty()) { return false; } @@ -425,12 +407,6 @@ namespace BlackCore return m_aircraftInRange.containsCallsign(callsign); } - CClientList CAirspaceMonitor::getOtherClients() const - { - QReadLocker l(&m_lockClient); - return m_otherClients; - } - CAtcStation CAirspaceMonitor::getAtcStationForComUnit(const CComSystem &comSystem) { CAtcStation station; @@ -532,7 +508,7 @@ namespace BlackCore m_tempFsInnPackets.clear(); this->removeAllOnlineAtcStations(); this->removeAllAircraft(); - this->removeAllOtherClients(); + this->clearClients(); } void CAirspaceMonitor::gracefulShutdown() @@ -568,7 +544,7 @@ namespace BlackCore this->updateOrAddClient(callsign, vm, false); } - void CAirspaceMonitor::onCapabilitiesReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, quint32 flags) + void CAirspaceMonitor::onCapabilitiesReplyReceived(const CCallsign &callsign, quint32 flags) { if (!this->isConnected() || callsign.isEmpty()) { return; } CPropertyIndexVariantMap capabilities; @@ -623,12 +599,6 @@ namespace BlackCore m_flightPlanCache.clear(); } - void CAirspaceMonitor::removeAllOtherClients() - { - QWriteLocker l1(&m_lockClient); - m_otherClients.clear(); - } - void CAirspaceMonitor::removeFromAircraftCachesAndLogs(const CCallsign &callsign) { if (callsign.isEmpty()) { return; } @@ -666,10 +636,10 @@ namespace BlackCore emit this->changedAtcStationsBooked(); // treat as stations were changed } - void CAirspaceMonitor::onReceivedDataFile() + void CAirspaceMonitor::onReceivedVatsimDataFile() { Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this)); - CClientList clients(this->getOtherClients()); // copy + CClientList clients(this->getClients()); // copy bool changed = false; for (auto client = clients.begin(); client != clients.end(); ++client) { @@ -680,8 +650,7 @@ namespace BlackCore client->setVoiceCapabilities(vc); } if (!changed) { return; } - QWriteLocker l(&m_lockClient); - m_otherClients = clients; + this->setClients(clients); } void CAirspaceMonitor::sendReadyForModelMatching(const CCallsign &callsign, int trial) @@ -769,8 +738,7 @@ namespace BlackCore void CAirspaceMonitor::onAtcControllerDisconnected(const CCallsign &callsign) { Q_ASSERT(CThreadUtils::isCurrentThreadObjectThread(this)); - - m_otherClients.removeByCallsign(callsign); + this->removeClient(callsign); if (m_atcStationsOnline.containsCallsign(callsign)) { const CAtcStation removedStation = m_atcStationsOnline.findFirstByCallsign(callsign); @@ -889,7 +857,7 @@ namespace BlackCore arg(aircraftIcaoDesignator, airlineIcaoDesignator, livery), getLogCategories()); - const CClient client = this->getOtherClientOrDefaultForCallsign(callsign); + const CClient client = this->getClientOrDefaultForCallsign(callsign); this->addOrUpdateAircraftInRange(callsign, aircraftIcaoDesignator, airlineIcaoDesignator, livery, client.getQueriedModelString(), CAircraftModel::TypeQueriedFromNetwork, pReverseLookupMessages); this->addReverseLookupMessages(callsign, reverseLookupMessages); this->sendReadyForModelMatching(callsign); // ICAO codes received @@ -1024,34 +992,6 @@ namespace BlackCore return c; } - bool CAirspaceMonitor::addNewClient(const CClient &client) - { - const CCallsign callsign = client.getCallsign(); - Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "invalid callsign"); - if (this->hasClientInfo(callsign)) { return false; } - QWriteLocker l(&m_lockClient); - m_otherClients.push_back(client); - return true; - } - - int CAirspaceMonitor::updateOrAddClient(const CCallsign &callsign, const CPropertyIndexVariantMap &vm, bool skipEqualValues) - { - Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "Missing callsign"); - int c = 0; - if (!this->hasClientInfo(callsign)) - { - CClient client(callsign); - c = client.apply(vm).size(); - this->addNewClient(client); - } - else - { - QWriteLocker l(&m_lockClient); - c = m_otherClients.applyIfCallsign(callsign, vm, skipEqualValues); - } - return c; - } - int CAirspaceMonitor::updateOnlineStation(const CCallsign &callsign, const CPropertyIndexVariantMap &vm, bool skipEqualValues, bool sendSignal) { const int c = m_atcStationsOnline.applyIfCallsign(callsign, vm, skipEqualValues); @@ -1213,8 +1153,8 @@ namespace BlackCore { QWriteLocker l1(&m_lockParts); m_partsByCallsign.remove(callsign); m_aircraftSupportingParts.remove(callsign); } { QWriteLocker l2(&m_lockSituations); m_situationsByCallsign.remove(callsign); } - { QWriteLocker l3(&m_lockClient); m_otherClients.removeByCallsign(callsign); } { QWriteLocker l4(&m_lockPartsHistory); m_aircraftPartsHistory.remove(callsign); } + this->removeClient(callsign); bool removedCallsign = false; { diff --git a/src/blackcore/airspacemonitor.h b/src/blackcore/airspacemonitor.h index 24a73c6dc..771ce5c99 100644 --- a/src/blackcore/airspacemonitor.h +++ b/src/blackcore/airspacemonitor.h @@ -39,14 +39,14 @@ #include "blackmisc/aviation/callsign.h" #include "blackmisc/aviation/callsignset.h" #include "blackmisc/aviation/flightplan.h" -#include "blackmisc/geo/coordinategeodetic.h" -#include "blackmisc/identifiable.h" -#include "blackmisc/identifier.h" -#include "blackmisc/network/clientlist.h" +#include "blackmisc/network/clientprovider.h" #include "blackmisc/network/userlist.h" +#include "blackmisc/geo/coordinategeodetic.h" #include "blackmisc/pq/frequency.h" #include "blackmisc/pq/length.h" #include "blackmisc/pq/angle.h" +#include "blackmisc/identifiable.h" +#include "blackmisc/identifier.h" namespace BlackMisc { @@ -69,12 +69,14 @@ namespace BlackCore //! Central instance of data for \sa IRemoteAircraftProvider. class BLACKCORE_EXPORT CAirspaceMonitor : public QObject, + public BlackMisc::Network::IClientProvider, // those data will be provided from the class CAirspaceMonitor public BlackMisc::Simulation::IRemoteAircraftProvider, // those data will be provided from the class CAirspaceMonitor public BlackMisc::Simulation::COwnAircraftAware, // used to obtain in memory information about own aircraft public BlackMisc::Simulation::CSimulationEnvironmentAware, // elevation info etc. public BlackMisc::CIdentifiable { Q_OBJECT + Q_INTERFACES(BlackMisc::Network::IClientProvider) Q_INTERFACES(BlackMisc::Simulation::IRemoteAircraftProvider) public: @@ -135,22 +137,6 @@ namespace BlackCore //! \threadsafe BlackMisc::Aviation::CFlightPlanRemarks tryToGetFlightPlanRemarks(const BlackMisc::Aviation::CCallsign &callsign) const; - //! Returns this list of other clients we know about - //! \threadsafe - BlackMisc::Network::CClientList getOtherClients() const; - - //! Returns a list of other clients corresponding to the given callsigns - //! \threadsafe - BlackMisc::Network::CClientList getOtherClientsForCallsigns(const BlackMisc::Aviation::CCallsignSet &callsigns) const; - - //! Other client for the given callsigns - //! \threadsafe - BlackMisc::Network::CClient getOtherClientOrDefaultForCallsign(const BlackMisc::Aviation::CCallsign &callsign) const; - - //! Client info for given callsign? - //! \threadsafe - bool hasClientInfo(const BlackMisc::Aviation::CCallsign &callsign) const; - //! Returns the current online ATC stations (consolidated with booked stations) BlackMisc::Aviation::CAtcStationList getAtcStationsOnline() const { return m_atcStationsOnline; } @@ -245,7 +231,6 @@ namespace BlackCore BlackMisc::Aviation::CAtcStationList m_atcStationsOnline; //!< online ATC stations BlackMisc::Aviation::CAtcStationList m_atcStationsBooked; //!< booked ATC stations - BlackMisc::Network::CClientList m_otherClients; //!< client informatiom, thread safe access required BlackMisc::Simulation::CSimulatedAircraftList m_aircraftInRange; //!< aircraft, thread safe access required QMap m_reverseLookupMessages; QMap m_aircraftPartsHistory; @@ -268,7 +253,6 @@ namespace BlackCore mutable QReadWriteLock m_lockSituations; //!< lock for situations: m_situationsByCallsign mutable QReadWriteLock m_lockParts; //!< lock for parts: m_partsByCallsign, m_aircraftSupportingParts mutable QReadWriteLock m_lockAircraft; //!< lock aircraft: m_aircraftInRange - mutable QReadWriteLock m_lockClient; //!< lock clients: m_otherClients mutable QReadWriteLock m_lockMessages; //!< lock for messages mutable QReadWriteLock m_lockPartsHistory; //!< lock for aircraft parts @@ -279,10 +263,6 @@ namespace BlackCore //! \threadsafe void removeAllAircraft(); - //! Remove all other clients - //! \threadsafe - void removeAllOtherClients(); - //! Remove data from caches and logs //! \threadsafe void removeFromAircraftCachesAndLogs(const BlackMisc::Aviation::CCallsign &callsign); @@ -333,14 +313,6 @@ namespace BlackCore //! \threadsafe int updateAircraftInRange(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::CPropertyIndexVariantMap &vm, bool skipEqualValues = true); - //! Add new client if not yet existing - //! \threadsafe - bool addNewClient(const BlackMisc::Network::CClient &client); - - //! Update client by callsign - //! \threadsafe - int updateOrAddClient(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::CPropertyIndexVariantMap &vm, bool skipEqualValues = true); - //! Update online stations by callsign int updateOnlineStation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::CPropertyIndexVariantMap &vm, bool skipEqualValues = true, bool sendSignal = true); @@ -397,7 +369,7 @@ namespace BlackCore void onFrequencyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &frequency); void onReceivedAtcBookings(const BlackMisc::Aviation::CAtcStationList &bookedStations); void onReadUnchangedAtcBookings(); - void onReceivedDataFile(); + void onReceivedVatsimDataFile(); void onAircraftConfigReceived(const BlackMisc::Aviation::CCallsign &callsign, const QJsonObject &jsonObject, int currentOffset); void onAircraftInterimUpdateReceived(const BlackMisc::Aviation::CAircraftSituation &situation); void onConnectionStatusChanged(BlackCore::INetwork::ConnectionStatus oldStatus, BlackCore::INetwork::ConnectionStatus newStatus); diff --git a/src/blackcore/context/contextnetworkimpl.cpp b/src/blackcore/context/contextnetworkimpl.cpp index 5b454acc1..41dc689d3 100644 --- a/src/blackcore/context/contextnetworkimpl.cpp +++ b/src/blackcore/context/contextnetworkimpl.cpp @@ -373,13 +373,13 @@ namespace BlackCore CClientList CContextNetwork::getOtherClients() const { if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - return m_airspace->getOtherClients(); + return m_airspace->getClients(); } CClientList CContextNetwork::getOtherClientsForCallsigns(const CCallsignSet &callsigns) const { if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - return m_airspace->getOtherClientsForCallsigns(callsigns); + return m_airspace->getClientsForCallsigns(callsigns); } CServerList CContextNetwork::getVatsimFsdServers() const diff --git a/src/blackmisc/network/clientprovider.cpp b/src/blackmisc/network/clientprovider.cpp new file mode 100644 index 000000000..784292be0 --- /dev/null +++ b/src/blackmisc/network/clientprovider.cpp @@ -0,0 +1,123 @@ +/* Copyright (C) 2018 + * 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 "clientprovider.h" + +using namespace BlackMisc::Aviation; + +namespace BlackMisc +{ + namespace Network + { + CClientList IClientProvider::getClients() const + { + QReadLocker l(&m_lockClient); + return m_clients; + } + + void IClientProvider::setClients(const CClientList &clients) + { + QWriteLocker l(&m_lockClient); + m_clients = clients; + } + + void IClientProvider::clearClients() + { + QWriteLocker l(&m_lockClient); + m_clients.clear(); + } + + CClientList IClientProvider::getClientsForCallsigns(const CCallsignSet &callsigns) const + { + return this->getClients().findByCallsigns(callsigns); + } + + CClient IClientProvider::getClientOrDefaultForCallsign(const CCallsign &callsign) const + { + const CClientList clients(this->getClients()); + return clients.findFirstByCallsign(callsign); + } + + bool IClientProvider::hasClientInfo(const CCallsign &callsign) const + { + return this->getClients().containsCallsign(callsign); + } + + bool IClientProvider::addNewClient(const CClient &client) + { + const CCallsign callsign = client.getCallsign(); + Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "invalid callsign"); + if (this->hasClientInfo(callsign)) { return false; } + QWriteLocker l(&m_lockClient); + m_clients.push_back(client); + return true; + } + + int IClientProvider::updateOrAddClient(const CCallsign &callsign, const CPropertyIndexVariantMap &vm, bool skipEqualValues) + { + Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "Missing callsign"); + int c = 0; + if (!this->hasClientInfo(callsign)) + { + CClient client(callsign); + c = client.apply(vm).size(); + this->addNewClient(client); + } + else + { + QWriteLocker l(&m_lockClient); + c = m_clients.applyIfCallsign(callsign, vm, skipEqualValues); + } + return c; + } + + int IClientProvider::removeClient(const CCallsign &callsign) + { + QWriteLocker l(&m_lockClient); + return m_clients.removeByCallsign(callsign); + } + + CClientList CClientAware::getClients() const + { + if (m_clientProvider) { return m_clientProvider->getClients(); } + return CClientList(); + } + + CClient CClientAware::getClientOrDefaultForCallsign(const Aviation::CCallsign &callsign) const + { + if (m_clientProvider) { return m_clientProvider->getClientOrDefaultForCallsign(callsign); } + return CClient(); + } + + bool CClientAware::hasClientInfo(const CCallsign &callsign) const + { + if (m_clientProvider) { return m_clientProvider->hasClientInfo(callsign); } + return false; + } + + bool CClientAware::addNewClient(const CClient &client) + { + if (m_clientProvider) { return m_clientProvider->addNewClient(client); } + return false; + } + + int CClientAware::updateOrAddClient(const CCallsign &callsign, const CPropertyIndexVariantMap &vm, bool skipEqualValues) + { + if (m_clientProvider) { return m_clientProvider->updateOrAddClient(callsign, vm, skipEqualValues); } + return 0; + } + + int CClientAware::removeClient(const CCallsign &callsign) + { + if (m_clientProvider) { return m_clientProvider->removeClient(callsign); } + return 0; + } + } + // namespace +} // namespace diff --git a/src/blackmisc/network/clientprovider.h b/src/blackmisc/network/clientprovider.h new file mode 100644 index 000000000..ce9a61aa9 --- /dev/null +++ b/src/blackmisc/network/clientprovider.h @@ -0,0 +1,116 @@ +/* Copyright (C) 2018 + * 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_NETWORK_CLIENTPROVIDER_H +#define BLACKMISC_NETWORK_CLIENTPROVIDER_H + +#include "clientlist.h" +#include "blackmisc/aviation/callsignset.h" +#include "blackmisc/provider.h" +#include + +namespace BlackMisc +{ + namespace Network + { + //! Direct in memory access to client (network client) data + class BLACKMISC_EXPORT IClientProvider : public IProvider + { + public: + //! Get other clients + //! \threadsafe + CClientList getClients() const; + + //! Set other clients + //! \threadsafe + void setClients(const CClientList &clients); + + //! Set other clients + //! \threadsafe + void clearClients(); + + //! Returns a list of other clients corresponding to the given callsigns + //! \threadsafe + BlackMisc::Network::CClientList getClientsForCallsigns(const Aviation::CCallsignSet &callsigns) const; + + //! Other client for the given callsigns + //! \threadsafe + BlackMisc::Network::CClient getClientOrDefaultForCallsign(const Aviation::CCallsign &callsign) const; + + //! Client info for given callsign? + //! \threadsafe + bool hasClientInfo(const Aviation::CCallsign &callsign) const; + + //! Add a new client, if existing nothing will be added + //! \threadsafe + bool addNewClient(const CClient &client); + + //! Update or add a client + //! \threadsafe + int updateOrAddClient(const Aviation::CCallsign &callsign, const CPropertyIndexVariantMap &vm, bool skipEqualValues = true); + + //! Remove client + //! \threadsafe + int removeClient(const Aviation::CCallsign &callsign); + + private: + CClientList m_clients; + mutable QReadWriteLock m_lockClient; //!< lock clients: m_clients + }; + + //! Class which can be directly used to access an \sa IClientProvider object + class BLACKMISC_EXPORT CClientAware : public IProviderAware + { + public: + //! \copydoc IClientProvider::getClients + CClientList getClients() const; + + //! \copydoc IClientProvider::setClients + void setClients(const CClientList &clients); + + //! \copydoc IClientProvider::clearClients + void clearClients(); + + //! \copydoc IClientProvider::getClientsForCallsigns + BlackMisc::Network::CClientList getClientsForCallsigns(const Aviation::CCallsignSet &callsigns) const; + + //! \copydoc IClientProvider::getClientOrDefaultForCallsign + BlackMisc::Network::CClient getClientOrDefaultForCallsign(const Aviation::CCallsign &callsign) const; + + //! \copydoc IClientProvider::hasClientInfo + bool hasClientInfo(const Aviation::CCallsign &callsign) const; + + //! \copydoc IClientProvider::addNewClient + bool addNewClient(const CClient &client); + + //! \copydoc IClientProvider::updateOrAddClient + int updateOrAddClient(const Aviation::CCallsign &callsign, const CPropertyIndexVariantMap &vm, bool skipEqualValues); + + //! \copydoc IClientProvider::removeClient + int removeClient(const Aviation::CCallsign &callsign); + + //! Provider + void setClientProvider(IClientProvider *provider) { this->setProvider(provider); } + + protected: + //! Default constructor + CClientAware() {} + + //! Constructor + CClientAware(IClientProvider *clientProvider) : m_clientProvider(clientProvider) { Q_ASSERT(clientProvider); } + IClientProvider *m_clientProvider = nullptr; //!< access to object + }; + } // namespace +} // namespace + +Q_DECLARE_INTERFACE(BlackMisc::Network::IClientProvider, "BlackMisc::Network::IClientProvider") + +#endif // guard