diff --git a/src/blackcore/context/contextownaircraftimpl.cpp b/src/blackcore/context/contextownaircraftimpl.cpp index cf5d51681..f670ef99a 100644 --- a/src/blackcore/context/contextownaircraftimpl.cpp +++ b/src/blackcore/context/contextownaircraftimpl.cpp @@ -11,6 +11,8 @@ #include "blackcore/context/contextaudio.h" #include "blackcore/context/contextnetwork.h" #include "blackcore/context/contextownaircraftimpl.h" +#include "blackcore/application.h" +#include "blackcore/webdataservices.h" #include "blackmisc/audio/voiceroom.h" #include "blackmisc/audio/voiceroomlist.h" #include "blackmisc/aviation/aircrafticaocode.h" @@ -42,6 +44,7 @@ using namespace BlackMisc::Network; using namespace BlackMisc::Geo; using namespace BlackMisc::Audio; using namespace BlackMisc::Simulation; +using namespace BlackCore; namespace BlackCore { @@ -54,6 +57,11 @@ namespace BlackCore Q_ASSERT(this->getRuntime()); this->setObjectName("CContextOwnAircraft"); + if (sApp && sApp->getWebDataServices()) + { + connect(sApp->getWebDataServices(), &CWebDataServices::allSwiftDbDataRead, this, &CContextOwnAircraft::ps_allSwiftWebDataRead); + } + // Init own aircraft this->initOwnAircraft(); } @@ -100,30 +108,51 @@ namespace BlackCore void CContextOwnAircraft::initOwnAircraft() { Q_ASSERT(this->getRuntime()); + CSimulatedAircraft ownAircraft; { - QWriteLocker l(&m_lockAircraft); - this->m_ownAircraft.initComSystems(); - this->m_ownAircraft.initTransponder(); - CAircraftSituation situation( - CCoordinateGeodetic( - CLatitude::fromWgs84("N 049° 18' 17"), - CLongitude::fromWgs84("E 008° 27' 05"), - CLength(0, CLengthUnit::m())), - CAltitude(312, CAltitude::MeanSeaLevel, CLengthUnit::ft()) - ); - this->m_ownAircraft.setSituation(situation); - this->m_ownAircraft.setPilot(this->m_currentNetworkServer.getThreadLocal().getUser()); + // use copy to minimize lock time + QReadLocker rl(&m_lockAircraft); + ownAircraft = this->m_ownAircraft; + } - // from simulator, if available - this->m_ownAircraft.setCallsign(CCallsign("SWIFT")); // would come from settings + ownAircraft.initComSystems(); + ownAircraft.initTransponder(); + CAircraftSituation situation( + CCoordinateGeodetic( + CLatitude::fromWgs84("N 049° 18' 17"), + CLongitude::fromWgs84("E 008° 27' 05"), + CLength(0, CLengthUnit::m())), + CAltitude(312, CAltitude::MeanSeaLevel, CLengthUnit::ft()) + ); + ownAircraft.setSituation(situation); + ownAircraft.setPilot(this->m_currentNetworkServer.getThreadLocal().getUser()); - //! \todo Own aircraft ICAO default data, this would need to come from somewhere (mappings) -> Own callsign, plane ICAO status, model used - this->m_ownAircraft.setIcaoCodes( + // reverse lookup if possible + if (!ownAircraft.getModel().isLoadedFromDb() && !ownAircraft.getModelString().isEmpty()) + { + ownAircraft.setModel(reverseLookupModel(ownAircraft.getModelString())); + } + + // override empty values + if (!ownAircraft.hasValidCallsign()) + { + ownAircraft.setCallsign(CCallsign("SWIFT")); + } + + if (!ownAircraft.getAircraftIcaoCode().hasValidDesignator()) + { + ownAircraft.setIcaoCodes( CAircraftIcaoCode("C172", "L1P"), CAirlineIcaoCode() ); } + // update object + { + QWriteLocker l(&m_lockAircraft); + m_ownAircraft = ownAircraft; + } + // voice rooms, if network is already available if (this->getIContextNetwork()) { @@ -154,12 +183,37 @@ namespace BlackCore emit this->getIContextApplication()->fakedSetComVoiceRoom(rooms); } + CAircraftModel CContextOwnAircraft::reverseLookupModel(const QString &modelString) + { + if (modelString.isEmpty()) { return CAircraftModel(); } + if (!sApp || !sApp->hasWebDataServices()) { return CAircraftModel(); } + const CAircraftModel reverseLookupModel = sApp->getWebDataServices()->getModelForModelString(modelString); + return reverseLookupModel; + } + bool CContextOwnAircraft::updateOwnModel(const CAircraftModel &model) { + // reverse lookup if not yet from DB: + // this is the central place where we keep our own model, so we use best effort + // to make that model as accuarate as we can + CAircraftModel updateModel(model); + if (!updateModel.isLoadedFromDb()) + { + CAircraftModel reverseModel = reverseLookupModel(model.getModelString()); + if (reverseModel.isLoadedFromDb()) + { + // special case here, as we have some specific values for a local model + updateModel = reverseModel; + updateModel.updateMissingParts(model); + updateModel.setFileName(model.getFileName()); + } + } + QWriteLocker l(&m_lockAircraft); - bool changed = (this->m_ownAircraft.getModel() != model); + const bool changed = (this->m_ownAircraft.getModel() != updateModel); if (!changed) { return false; } - this->m_ownAircraft.setModel(model); + updateModel.setModelType(CAircraftModel::TypeOwnSimulatorModel); + this->m_ownAircraft.setModel(updateModel); return true; } @@ -292,11 +346,18 @@ namespace BlackCore this->resolveVoiceRooms(); } - void CContextOwnAircraft::ps_changedSimulatorModel(const CSimulatedAircraft &ownAircraft) + void CContextOwnAircraft::ps_changedSimulatorModel(const CAircraftModel &model) { - CAircraftModel model(ownAircraft.getModel()); - QWriteLocker l(&m_lockAircraft); - this->m_ownAircraft.setModel(model); + this->updateOwnModel(model); + } + + void CContextOwnAircraft::ps_allSwiftWebDataRead() + { + const CAircraftModel model = this->getOwnAircraftModel(); + if (model.isLoadedFromDb()) { return; } + + // a reverse lookup of the model could make sense + this->updateOwnModel(model); // force reverse lookup } void CContextOwnAircraft::setAudioVoiceRoomOverrideUrls(const QString &voiceRoom1Url, const QString &voiceRoom2Url) diff --git a/src/blackcore/context/contextownaircraftimpl.h b/src/blackcore/context/contextownaircraftimpl.h index 342ead209..22921a66a 100644 --- a/src/blackcore/context/contextownaircraftimpl.h +++ b/src/blackcore/context/contextownaircraftimpl.h @@ -89,6 +89,7 @@ namespace BlackCore //! \copydoc BlackMisc::Simulation::IOwnAircraftProvider::updateOwnModel //! \ingroup ownaircraftprovider + //! \remark perform reverse lookup if possible virtual bool updateOwnModel(const BlackMisc::Simulation::CAircraftModel &model) override; //! \copydoc BlackMisc::Simulation::IOwnAircraftProvider::updateOwnSituation @@ -161,7 +162,10 @@ namespace BlackCore //! Simulator model has been changed //! \note Connected in runtime - void ps_changedSimulatorModel(const BlackMisc::Simulation::CSimulatedAircraft &ownAircraft); + void ps_changedSimulatorModel(const BlackMisc::Simulation::CAircraftModel &model); + + //! Web data loaded + void ps_allSwiftWebDataRead(); private: BlackMisc::Simulation::CSimulatedAircraft m_ownAircraft; //!< my aircraft @@ -177,6 +181,9 @@ namespace BlackCore //! Resolve voice rooms void resolveVoiceRooms(); + + //! Reverse lookup of the model + static BlackMisc::Simulation::CAircraftModel reverseLookupModel(const QString &modelString); }; } // ns } // ns diff --git a/src/blackcore/context/contextsimulator.h b/src/blackcore/context/contextsimulator.h index 51b5a8aa7..76ca96712 100644 --- a/src/blackcore/context/contextsimulator.h +++ b/src/blackcore/context/contextsimulator.h @@ -100,7 +100,7 @@ namespace BlackCore void aircraftRenderingChanged(const BlackMisc::Simulation::CSimulatedAircraft &aircraft); //! Emitted when own aircraft model changes - void ownAircraftModelChanged(const BlackMisc::Simulation::CSimulatedAircraft &aircraft); + void ownAircraftModelChanged(const BlackMisc::Simulation::CAircraftModel &model); //! An airspace snapshot was handled void airspaceSnapshotHandled(); diff --git a/src/blackcore/context/contextsimulatorproxy.cpp b/src/blackcore/context/contextsimulatorproxy.cpp index f8c1089ac..3b8c95cfd 100644 --- a/src/blackcore/context/contextsimulatorproxy.cpp +++ b/src/blackcore/context/contextsimulatorproxy.cpp @@ -45,7 +45,7 @@ namespace BlackCore "installedAircraftModelsChanged", this, SIGNAL(installedAircraftModelsChanged())); Q_ASSERT(s); s = connection.connect(serviceName, IContextSimulator::ObjectPath(), IContextSimulator::InterfaceName(), - "ownAircraftModelChanged", this, SIGNAL(ownAircraftModelChanged(BlackMisc::Simulation::CSimulatedAircraft))); + "ownAircraftModelChanged", this, SIGNAL(ownAircraftModelChanged(BlackMisc::Simulation::CAircraftModel))); Q_ASSERT(s); s = connection.connect(serviceName, IContextSimulator::ObjectPath(), IContextSimulator::InterfaceName(), "modelMatchingCompleted", this, SIGNAL(modelMatchingCompleted(BlackMisc::Simulation::CSimulatedAircraft))); diff --git a/src/blackcore/db/databaseutils.cpp b/src/blackcore/db/databaseutils.cpp index fc7fe418e..2b388025f 100644 --- a/src/blackcore/db/databaseutils.cpp +++ b/src/blackcore/db/databaseutils.cpp @@ -33,10 +33,11 @@ namespace BlackCore const int distributorOrder = model.getDistributorOrder(); // later restore that order CAircraftModel dbModel(sApp->getWebDataServices()->getModelForModelString(model.getModelString())); - if (dbModel.hasValidDbKey()) + if (dbModel.isLoadedFromDb()) { + // take the db model as original if (modified) { *modified = true; } - dbModel.updateByLocalFileNames(model); + dbModel.updateMissingParts(model); dbModel.setDistributorOrder(distributorOrder); return dbModel; } @@ -70,7 +71,7 @@ namespace BlackCore if (modified) { *modified = true; } consolidatedModel.setDistributor(dbDistributor); } - consolidatedModel.updateByLocalFileNames(model); + consolidatedModel.updateLocalFileNames(model); consolidatedModel.setDistributorOrder(distributorOrder); return consolidatedModel; } diff --git a/src/blackcore/simulator.h b/src/blackcore/simulator.h index 7c74fe7b0..b420dded4 100644 --- a/src/blackcore/simulator.h +++ b/src/blackcore/simulator.h @@ -188,13 +188,13 @@ namespace BlackCore void simulatorStatusChanged(int status); //! Emitted when own aircraft model has changed - void ownAircraftModelChanged(BlackMisc::Simulation::CSimulatedAircraft aircraft); + void ownAircraftModelChanged(const BlackMisc::Simulation::CAircraftModel &model); //! Render restrictions have been changed void renderRestrictionsChanged(bool restricted, bool enabled, int maxAircraft, const BlackMisc::PhysicalQuantities::CLength &maxRenderedDistance, const BlackMisc::PhysicalQuantities::CLength &maxRenderedBoundary); //! Aircraft rendering changed - void aircraftRenderingChanged(BlackMisc::Simulation::CSimulatedAircraft aircraft); + void aircraftRenderingChanged(const BlackMisc::Simulation::CSimulatedAircraft &aircraft); //! Installed aircraft models ready or changed void installedAircraftModelsChanged(); diff --git a/src/blackmisc/simulation/aircraftmodel.cpp b/src/blackmisc/simulation/aircraftmodel.cpp index de68ab2c3..9f57249ff 100644 --- a/src/blackmisc/simulation/aircraftmodel.cpp +++ b/src/blackmisc/simulation/aircraftmodel.cpp @@ -101,7 +101,7 @@ namespace BlackMisc QString CAircraftModel::toDatabaseJsonString(QJsonDocument::JsonFormat format) const { - return QJsonDocument(toDatabaseJson()).toJson(format); + return QJsonDocument(this->toDatabaseJson()).toJson(format); } bool CAircraftModel::canInitializeFromFsd() const @@ -453,12 +453,13 @@ namespace BlackMisc return; } - this->updateByLocalFileNames(otherModel); + this->updateLocalFileNames(otherModel); if (this->m_callsign.isEmpty()) { this->setCallsign(otherModel.getCallsign()); } if (this->m_modelString.isEmpty()) { this->setModelString(otherModel.getModelString()); } - if (this->m_description.isEmpty() || this->m_description.startsWith(CAircraftModel::autoGenerated(), Qt::CaseInsensitive)) { this->setDescription(otherModel.getDescription()); } + if (this->m_name.isEmpty()) { this->setName(otherModel.getName()); } if (this->m_modelType == TypeUnknown) { this->m_modelType = otherModel.getModelType(); } if (this->m_modelMode == Undefined) { this->m_modelType = otherModel.getModelType(); } + if (this->m_description.isEmpty() || this->m_description.startsWith(CAircraftModel::autoGenerated(), Qt::CaseInsensitive)) { this->setDescription(otherModel.getDescription()); } if (this->m_simulator.isUnspecified()) { this->setSimulator(otherModel.getSimulator()); @@ -517,7 +518,7 @@ namespace BlackMisc this->m_fileName = CAircraftModel::normalizeFileNameForDb(this->m_fileName); } - void CAircraftModel::updateByLocalFileNames(const CAircraftModel &model) + void CAircraftModel::updateLocalFileNames(const CAircraftModel &model) { if (this->getModelType() == CAircraftModel::TypeOwnSimulatorModel) { diff --git a/src/blackmisc/simulation/aircraftmodel.h b/src/blackmisc/simulation/aircraftmodel.h index 42fc0dab3..415ec36db 100644 --- a/src/blackmisc/simulation/aircraftmodel.h +++ b/src/blackmisc/simulation/aircraftmodel.h @@ -61,7 +61,7 @@ namespace BlackMisc { TypeUnknown, TypeQueriedFromNetwork, //!< model was queried by network protocol - TypeFSInnData, //!< model based on FSD ICAO data + TypeFSInnData, //!< model based on FSD ICAO data TypeModelMatching, //!< model is result of model matching TypeModelMatchingDefaultModel, //!< a default model assigned by model matching TypeDatabaseEntry, //!< used along with mapping definition @@ -326,7 +326,7 @@ namespace BlackMisc void normalizeFileNameForDb(); //! If we have local file names, we use those - void updateByLocalFileNames(const CAircraftModel &model); + void updateLocalFileNames(const CAircraftModel &model); //! Matches model string? bool matchesModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const; diff --git a/src/plugins/simulator/fscommon/simulatorfscommon.cpp b/src/plugins/simulator/fscommon/simulatorfscommon.cpp index 414d084a5..be5b7b963 100644 --- a/src/plugins/simulator/fscommon/simulatorfscommon.cpp +++ b/src/plugins/simulator/fscommon/simulatorfscommon.cpp @@ -81,7 +81,7 @@ namespace BlackSimPlugin CAircraftModel newModel(model); newModel.setModelType(CAircraftModel::TypeOwnSimulatorModel); updateOwnModel(newModel); - emit ownAircraftModelChanged(getOwnAircraft()); + emit ownAircraftModelChanged(newModel); } } diff --git a/src/plugins/simulator/xplane/simulatorxplane.cpp b/src/plugins/simulator/xplane/simulatorxplane.cpp index 252788771..8134e028f 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.cpp +++ b/src/plugins/simulator/xplane/simulatorxplane.cpp @@ -102,7 +102,8 @@ namespace BlackSimPlugin m_fastTimer->start(100); m_slowTimer->start(1000); - m_defaultModel = { + m_defaultModel = + { "Jets A320_a A320_a_Austrian_Airlines A320_a_Austrian_Airlines", CAircraftModel::TypeModelMatchingDefaultModel, "A320 AUA", @@ -309,10 +310,9 @@ namespace BlackSimPlugin model.setFileName(path + "/" + filename); model.setLivery(CLivery("XPLANE." + livery, airlineIcaoCode, "XP livery", "", "", false)); - // updates - updateOwnIcaoCodes(model.getAircraftIcaoCode(), airlineIcaoCode); - updateOwnModel(model); - emit ownAircraftModelChanged(getOwnAircraft()); + // updated model. + // Hint: will update in own model context by using reverse lookup + emit ownAircraftModelChanged(model); } void CSimulatorXPlane::displayStatusMessage(const BlackMisc::CStatusMessage &message) const