From 93176b5bd49a6044c3c518a4f282fbcef0b24d69 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sun, 13 Mar 2016 19:30:26 +0100 Subject: [PATCH] refs #619, enhance local model data with DB data (if possible) * use new slot syntax on menu actions * allow reload from disk and reload from cache * added utility functions for model/modellist --- .../components/dbmappingcomponent.cpp | 100 +++++++++++++----- src/blackgui/components/dbmappingcomponent.h | 4 +- src/blackmisc/simulation/aircraftmodel.cpp | 9 +- src/blackmisc/simulation/aircraftmodel.h | 7 +- .../simulation/aircraftmodellist.cpp | 34 ++++++ src/blackmisc/simulation/aircraftmodellist.h | 13 +++ .../simulation/aircraftmodelloader.cpp | 22 +++- .../simulation/aircraftmodelloader.h | 30 ++++-- .../fscommon/aircraftcfgentrieslist.cpp | 10 +- .../simulation/fscommon/aircraftcfgparser.cpp | 63 ++++++++--- .../simulation/fscommon/aircraftcfgparser.h | 2 +- .../xplane/aircraftmodelloaderxplane.cpp | 6 +- .../xplane/aircraftmodelloaderxplane.h | 2 +- 13 files changed, 229 insertions(+), 73 deletions(-) diff --git a/src/blackgui/components/dbmappingcomponent.cpp b/src/blackgui/components/dbmappingcomponent.cpp index a76be3dec..8016323fd 100644 --- a/src/blackgui/components/dbmappingcomponent.cpp +++ b/src/blackgui/components/dbmappingcomponent.cpp @@ -542,9 +542,9 @@ namespace BlackGui void CDbMappingComponent::ps_onStashedModelsChanged() { - bool hlvp = this->ui->tvp_AircraftModelsForVPilot->derivedModel()->highlightModelStrings(); - bool hlom = this->ui->tvp_OwnAircraftModels->derivedModel()->highlightModelStrings(); - bool highlight = hlom || hlvp; + const bool hlvp = this->ui->tvp_AircraftModelsForVPilot->derivedModel()->highlightModelStrings(); + const bool hlom = this->ui->tvp_OwnAircraftModels->derivedModel()->highlightModelStrings(); + const bool highlight = hlom || hlvp; if (!highlight) { return; } const QStringList stashedModels(this->ui->comp_StashAircraft->getStashedModelStrings()); if (hlvp) @@ -602,13 +602,9 @@ namespace BlackGui this->ui->tw_ModelsToBeMapped->setTabText(i, o); } - void CDbMappingComponent::ps_requestSimulatorModels() + void CDbMappingComponent::ps_requestSimulatorModels(const CSimulatorInfo &simInfo, IAircraftModelLoader::LoadMode mode) { - QAction *a = qobject_cast(QObject::sender()); - if (!a) { return; } - int f = a->data().toInt(); - CSimulatorInfo sim(f); - this->ps_loadInstalledModels(sim); + this->ps_loadInstalledModels(simInfo, mode); } void CDbMappingComponent::ps_userChanged() @@ -678,7 +674,7 @@ namespace BlackGui } } - void CDbMappingComponent::ps_loadInstalledModels(const CSimulatorInfo &simInfo) + void CDbMappingComponent::ps_loadInstalledModels(const CSimulatorInfo &simInfo, IAircraftModelLoader::LoadMode mode) { if (!this->initModelLoader(simInfo)) { @@ -694,7 +690,8 @@ namespace BlackGui CLogMessage(this).info("Starting loading for %1") << simInfo.toQString(); this->ui->tvp_OwnAircraftModels->showLoadIndicator(); - this->m_modelLoader->startLoading(); + Q_ASSERT_X(sGui && sGui->getWebDataServices(), Q_FUNC_INFO, "missing web data services"); + this->m_modelLoader->startLoading(mode, sGui->getWebDataServices()->getModels()); } void CDbMappingComponent::ps_onOwnModelsLoadingFinished(bool success, const CSimulatorInfo &simInfo) @@ -702,15 +699,22 @@ namespace BlackGui if (success && this->m_modelLoader) { const CAircraftModelList models(this->m_modelLoader->getAircraftModels()); + const int modelsLoaded = models.size(); this->ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(models); - CLogMessage(this).info("Loading %1 of models completed") << models.size(); - - // store for later - Data::CDbMappingComponent mc(this->m_lastInteractions.get()); - if (simInfo.isSingleSimulator() && mc.getLastSimulatorSelection() != simInfo) + if (modelsLoaded > 0) { - mc.setLastSimulatorSelection(simInfo); - this->m_lastInteractions.set(mc); + // store for later + Data::CDbMappingComponent mc(this->m_lastInteractions.get()); + if (simInfo.isSingleSimulator() && mc.getLastSimulatorSelection() != simInfo) + { + mc.setLastSimulatorSelection(simInfo); + this->m_lastInteractions.set(mc); + } + } + else + { + // loading ok, but no data + CLogMessage(this).warning("Loading completed, but no models"); } } else @@ -758,29 +762,69 @@ namespace BlackGui { this->addSeparator(menu); QMenu *load = menu.addMenu(CIcons::appModels16(), "Load installed models"); - QAction *a = nullptr; CDbMappingComponent *mapComp = qobject_cast(this->parent()); Q_ASSERT_X(mapComp, Q_FUNC_INFO, "Cannot access parent"); - if (sims.fs9()) { - a = load->addAction(CIcons::appModels16(), "FS9 models", mapComp, SLOT(ps_requestSimulatorModels())); - a->setData(QVariant(static_cast(CSimulatorInfo::FS9))); + load->addAction(CIcons::appModels16(), "FS9 models", mapComp, [mapComp]() + { + mapComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::FSX), IAircraftModelLoader::InBackgroundWithCache); + }); } if (sims.fsx()) { - a = load->addAction(CIcons::appModels16(), "FSX models", mapComp, SLOT(ps_requestSimulatorModels())); - a->setData(QVariant(static_cast(CSimulatorInfo::FSX))); + load->addAction(CIcons::appModels16(), "P3D models", mapComp, [mapComp]() + { + mapComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::P3D), IAircraftModelLoader::InBackgroundWithCache); + }); } if (sims.p3d()) { - a = load->addAction(CIcons::appModels16(), "P3D models", mapComp, SLOT(ps_requestSimulatorModels())); - a->setData(QVariant(static_cast(CSimulatorInfo::P3D))); + load->addAction(CIcons::appModels16(), "FS9 models", mapComp, [mapComp]() + { + mapComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::FS9), IAircraftModelLoader::InBackgroundWithCache); + }); } if (sims.xplane()) { - a = load->addAction(CIcons::appModels16(), "XPlane models", mapComp, SLOT(ps_requestSimulatorModels())); - a->setData(QVariant(static_cast(CSimulatorInfo::XPLANE))); + load->addAction(CIcons::appModels16(), "XP models", mapComp, [mapComp]() + { + mapComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::XPLANE), IAircraftModelLoader::InBackgroundWithCache); + }); + } + + // with models loaded I allow a refresh reload + if (sGui->getWebDataServices() && sGui->getWebDataServices()->getModelsCount() > 0) + { + QMenu *reloadMenu = load->addMenu("Force reload"); + if (sims.fs9()) + { + reloadMenu->addAction(CIcons::appModels16(), "FS9 models", mapComp, [mapComp]() + { + mapComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::FSX), IAircraftModelLoader::InBackgroundNoCache); + }); + } + if (sims.fsx()) + { + reloadMenu->addAction(CIcons::appModels16(), "P3D models", mapComp, [mapComp]() + { + mapComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::P3D), IAircraftModelLoader::InBackgroundNoCache); + }); + } + if (sims.p3d()) + { + reloadMenu->addAction(CIcons::appModels16(), "FS9 models", mapComp, [mapComp]() + { + mapComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::FS9), IAircraftModelLoader::InBackgroundNoCache); + }); + } + if (sims.xplane()) + { + reloadMenu->addAction(CIcons::appModels16(), "XP models", mapComp, [mapComp]() + { + mapComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::XPLANE), IAircraftModelLoader::InBackgroundNoCache); + }); + } } } this->nestedCustomMenu(menu); diff --git a/src/blackgui/components/dbmappingcomponent.h b/src/blackgui/components/dbmappingcomponent.h index 7b61a597e..f0c3f17d5 100644 --- a/src/blackgui/components/dbmappingcomponent.h +++ b/src/blackgui/components/dbmappingcomponent.h @@ -177,7 +177,7 @@ namespace BlackGui void ps_onModelRowSelected(const QModelIndex &index); //! Load the models - void ps_loadInstalledModels(const BlackMisc::Simulation::CSimulatorInfo &simInfo); + void ps_loadInstalledModels(const BlackMisc::Simulation::CSimulatorInfo &simInfo, BlackMisc::Simulation::IAircraftModelLoader::LoadMode mode); //! Model loading finished void ps_onOwnModelsLoadingFinished(bool success, const BlackMisc::Simulation::CSimulatorInfo &simInfo); @@ -186,7 +186,7 @@ namespace BlackGui void ps_onOwnModelsCountChanged(int count, bool withFilter); //! Request simulator models - void ps_requestSimulatorModels(); + void ps_requestSimulatorModels(const BlackMisc::Simulation::CSimulatorInfo &simInfo, BlackMisc::Simulation::IAircraftModelLoader::LoadMode mode); //! User object changed void ps_userChanged(); diff --git a/src/blackmisc/simulation/aircraftmodel.cpp b/src/blackmisc/simulation/aircraftmodel.cpp index 3b9c8bcfd..ee8c2c013 100644 --- a/src/blackmisc/simulation/aircraftmodel.cpp +++ b/src/blackmisc/simulation/aircraftmodel.cpp @@ -266,6 +266,11 @@ namespace BlackMisc return this->m_aircraftIcao.hasDesignator(); } + bool CAircraftModel::hasKnownAircraftDesignator() const + { + return this->m_aircraftIcao.hasKnownDesignator(); + } + bool CAircraftModel::hasAirlineDesignator() const { return this->m_livery.hasValidAirlineDesignator(); @@ -291,9 +296,9 @@ namespace BlackMisc this->setModelMode(CAircraftModel::modelModeFromString(mode)); } - void CAircraftModel::updateMissingParts(const CAircraftModel &otherModel) + void CAircraftModel::updateMissingParts(const CAircraftModel &otherModel, bool dbModelPriority) { - if (!this->hasValidDbKey() && otherModel.hasValidDbKey()) + if (dbModelPriority && !this->hasValidDbKey() && otherModel.hasValidDbKey()) { // we have no DB data, but the other one has // so we change roles. We take the DB object as base, and update our parts diff --git a/src/blackmisc/simulation/aircraftmodel.h b/src/blackmisc/simulation/aircraftmodel.h index e3993ba51..6ac9f6642 100644 --- a/src/blackmisc/simulation/aircraftmodel.h +++ b/src/blackmisc/simulation/aircraftmodel.h @@ -96,7 +96,7 @@ namespace BlackMisc //! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); - //! \copydoc BlackMisc::Mixin::Index::comparePropertyByIndex() + //! Compare by index int comparePropertyByIndex(const CAircraftModel &compareValue, const CPropertyIndex &index) const; //! Can be initialized from FSD @@ -153,6 +153,9 @@ namespace BlackMisc //! Has aircraft designator? bool hasAircraftDesignator() const; + //! Has known aircraft designator? + bool hasKnownAircraftDesignator() const; + //! Airline designator? bool hasAirlineDesignator() const; @@ -217,7 +220,7 @@ namespace BlackMisc void setFileName(const QString &fileName) { m_fileName = fileName; } //! Update missing parts from another model - void updateMissingParts(const CAircraftModel &otherModel); + void updateMissingParts(const CAircraftModel &otherModel, bool dbModelPriority = true); //! Queried model string? bool hasQueriedModelString() const; diff --git a/src/blackmisc/simulation/aircraftmodellist.cpp b/src/blackmisc/simulation/aircraftmodellist.cpp index 82d835b1a..4fe81be8e 100644 --- a/src/blackmisc/simulation/aircraftmodellist.cpp +++ b/src/blackmisc/simulation/aircraftmodellist.cpp @@ -102,6 +102,40 @@ namespace BlackMisc }); } + CAircraftModelList CAircraftModelList::withAircraftDesignator() const + { + return this->findBy([ = ](const CAircraftModel & model) + { + return model.hasAircraftDesignator(); + }); + } + + CAircraftModelList CAircraftModelList::withAircraftDesignator(const QStringList &designators) const + { + if (designators.isEmpty()) { return CAircraftModelList(); } + return this->findBy([ = ](const CAircraftModel & model) + { + return designators.contains(model.getAircraftIcaoCodeDesignator()); + }); + } + + CAircraftModelList CAircraftModelList::withKnownAircraftDesignator() const + { + return this->findBy([ = ](const CAircraftModel & model) + { + return model.hasKnownAircraftDesignator(); + }); + } + + CAircraftModelList CAircraftModelList::byDistributor(const CDistributorList &distributors) const + { + if (distributors.isEmpty()) { return CAircraftModelList(); } + return this->findBy([ = ](const CAircraftModel & model) + { + return model.matchesAnyDistributor(distributors); + }); + } + void CAircraftModelList::setSimulatorInfo(const CSimulatorInfo &info) { for (CAircraftModel &model : (*this)) diff --git a/src/blackmisc/simulation/aircraftmodellist.h b/src/blackmisc/simulation/aircraftmodellist.h index 4b8525f9c..8de39bc36 100644 --- a/src/blackmisc/simulation/aircraftmodellist.h +++ b/src/blackmisc/simulation/aircraftmodellist.h @@ -44,6 +44,7 @@ namespace BlackMisc bool containsModelStringOrId(const BlackMisc::Simulation::CAircraftModel &model, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive) const; //! Find by model string + //! \remark normally CAircraftModelList::findFirstByModelString would be used CAircraftModelList findByModelString(const QString &modelString, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive) const; //! Find first by model string @@ -67,6 +68,18 @@ namespace BlackMisc //! With file name CAircraftModelList findWithFileName() const; + //! Models with aircraft ICAO code set + CAircraftModelList withAircraftDesignator() const; + + //! Models with aircraft ICAO code from list + CAircraftModelList withAircraftDesignator(const QStringList &designators) const; + + //! Models with a known aircraft ICAO code set + CAircraftModelList withKnownAircraftDesignator() const; + + //! All models from given distributors + CAircraftModelList byDistributor(const CDistributorList &distributors) const; + //! Set simulator for all elements void setSimulatorInfo(const BlackMisc::Simulation::CSimulatorInfo &info); diff --git a/src/blackmisc/simulation/aircraftmodelloader.cpp b/src/blackmisc/simulation/aircraftmodelloader.cpp index 4651dfa05..b58dcef5d 100644 --- a/src/blackmisc/simulation/aircraftmodelloader.cpp +++ b/src/blackmisc/simulation/aircraftmodelloader.cpp @@ -38,6 +38,23 @@ namespace BlackMisc return dir.exists(); } + bool IAircraftModelLoader::mergeWithDbData(CAircraftModelList &modelsFromSimulator, const CAircraftModelList &dbModels) + { + if (dbModels.isEmpty() || modelsFromSimulator.isEmpty()) { return false; } + for (CAircraftModel &simModel : modelsFromSimulator) + { + if (simModel.hasValidDbKey()) { continue; } // already done + CAircraftModel dbModel(dbModels.findFirstByModelString(simModel.getModelString())); + if (!dbModel.hasValidDbKey()) + { + continue; // not found + } + dbModel.updateMissingParts(simModel, false); + simModel = dbModel; + } + return true; + } + void IAircraftModelLoader::ps_loadFinished(bool success) { Q_UNUSED(success); @@ -53,7 +70,7 @@ namespace BlackMisc return true; } - void IAircraftModelLoader::startLoading(LoadMode mode) + void IAircraftModelLoader::startLoading(LoadMode mode, const CAircraftModelList &dbModels) { if (this->m_loadingInProgress) { return; } this->m_loadingInProgress = true; @@ -65,6 +82,7 @@ namespace BlackMisc } else if (useCachedData && mode.testFlag(CacheUntilNewer)) { + //! \todo currently too slow, does not make sense with that overhead if (!this->areModelFilesUpdated()) { emit loadingFinished(true, this->m_simulatorInfo); @@ -77,7 +95,7 @@ namespace BlackMisc emit loadingFinished(false, this->m_simulatorInfo); return; } - this->startLoadingFromDisk(mode); + this->startLoadingFromDisk(mode, dbModels); } const CSimulatorInfo &IAircraftModelLoader::supportedSimulators() const diff --git a/src/blackmisc/simulation/aircraftmodelloader.h b/src/blackmisc/simulation/aircraftmodelloader.h index 18089dcda..73b514845 100644 --- a/src/blackmisc/simulation/aircraftmodelloader.h +++ b/src/blackmisc/simulation/aircraftmodelloader.h @@ -36,22 +36,24 @@ namespace BlackMisc //! Parser mode enum LoadModeFlag { - NotSet = 0, - LoadDirectly = 1 << 0, //!< load syncronously (blocking), normally for testing - LoadInBackground = 1 << 1, //!< load in background, asnycronously - CacheUntilNewer = 1 << 2, //!< use cache until newer data re available - CacheFirst = 1 << 3, //!< always use cache (if it has data) - CacheSkipped = 1 << 4, //!< ignore cache - CacheOnly = 1 << 5, //!< only read cache, never load from disk - Default = LoadInBackground | CacheFirst //!< default mode + NotSet = 0, + LoadDirectly = 1 << 0, //!< load syncronously (blocking), normally for testing + LoadInBackground = 1 << 1, //!< load in background, asnycronously + CacheUntilNewer = 1 << 2, //!< use cache until newer data re available + CacheFirst = 1 << 3, //!< always use cache (if it has data) + CacheSkipped = 1 << 4, //!< ignore cache + CacheOnly = 1 << 5, //!< only read cache, never load from disk + InBackgroundWithCache = LoadInBackground | CacheFirst, //!< Background, cached + InBackgroundNoCache = LoadInBackground | CacheSkipped //!< Background, not cached }; Q_DECLARE_FLAGS(LoadMode, LoadModeFlag) //! Destructor virtual ~IAircraftModelLoader(); - //! Start the loading process from disk - void startLoading(LoadMode mode = Default); + //! Start the loading process from disk. + //! Optional DB models can be passed and used for data consolidation. + void startLoading(LoadMode mode = InBackgroundWithCache, const CAircraftModelList &dbModels = {}); //! Change the directory bool changeRootDirectory(const QString &directory); @@ -65,6 +67,9 @@ namespace BlackMisc //! The loaded models virtual const BlackMisc::Simulation::CAircraftModelList &getAircraftModels() const = 0; + //! Count of loaded models + const int getAircraftModelsCount() const { return getAircraftModels().size(); } + //! Cache timestamp virtual QDateTime getCacheTimestamp() const = 0; @@ -107,7 +112,10 @@ namespace BlackMisc bool existsDir(const QString &directory) const; //! Start the loading process from disk - virtual void startLoadingFromDisk(LoadMode mode) = 0; + virtual void startLoadingFromDisk(LoadMode mode, const BlackMisc::Simulation::CAircraftModelList &dbModels) = 0; + + //! Merge with DB data if possible + virtual bool mergeWithDbData(BlackMisc::Simulation::CAircraftModelList &modelsFromSimulator, const BlackMisc::Simulation::CAircraftModelList &dbModels); BlackMisc::Simulation::CSimulatorInfo m_simulatorInfo; //!< Corresponding simulator std::atomic m_cancelLoading { false }; //!< flag diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.cpp b/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.cpp index c5e23acfc..ae16478b4 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.cpp +++ b/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.cpp @@ -19,10 +19,8 @@ namespace BlackMisc { namespace Simulation { - namespace FsCommon { - bool CAircraftCfgEntriesList::containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity) { if (title.isEmpty()) { return false; } @@ -61,9 +59,9 @@ namespace BlackMisc CAircraftModelList CAircraftCfgEntriesList::toAircraftModelList() const { CAircraftModelList ml; - for (auto it = this->begin() ; it != this->end(); ++it) + for (const CAircraftCfgEntries &entries : (*this)) { - ml.push_back(it->toAircraftModel()); + ml.push_back(entries.toAircraftModel()); } return ml; } @@ -71,9 +69,9 @@ namespace BlackMisc CAircraftModelList CAircraftCfgEntriesList::toAircraftModelList(const CSimulatorInfo &simInfo) const { CAircraftModelList ml; - for (auto it = this->begin() ; it != this->end(); ++it) + for (const CAircraftCfgEntries &entries : (*this)) { - CAircraftModel m(it->toAircraftModel()); + CAircraftModel m(entries.toAircraftModel()); m.setSimulatorInfo(simInfo); ml.push_back(m); } diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgparser.cpp b/src/blackmisc/simulation/fscommon/aircraftcfgparser.cpp index b09e7d066..e4f73a08a 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgparser.cpp +++ b/src/blackmisc/simulation/fscommon/aircraftcfgparser.cpp @@ -13,6 +13,8 @@ #include "blackmisc/predicates.h" #include "blackmisc/logmessage.h" +#include + using namespace BlackMisc; using namespace BlackMisc::Simulation; using namespace BlackMisc::Simulation::FsCommon; @@ -24,6 +26,9 @@ namespace BlackMisc { namespace FsCommon { + // response for async. loading + using LoaderResponse = std::tuple; + CAircraftCfgParser::CAircraftCfgParser(const CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &excludeDirs) : IAircraftModelLoader(simInfo, rootDirectory, excludeDirs) { } @@ -89,7 +94,7 @@ namespace BlackMisc return empty; } - void CAircraftCfgParser::startLoadingFromDisk(LoadMode mode) + void CAircraftCfgParser::startLoadingFromDisk(LoadMode mode, const CAircraftModelList &dbModels) { if (mode.testFlag(LoadInBackground)) { @@ -97,19 +102,36 @@ namespace BlackMisc const QString rootDirectory(m_rootDirectory); // copy const QStringList excludedDirectories(m_excludedDirectories); // copy m_parserWorker = BlackMisc::CWorker::fromTask(this, "CAircraftCfgParser::changeDirectory", - [this, rootDirectory, excludedDirectories]() + [this, rootDirectory, excludedDirectories, dbModels]() { - bool ok; - auto aircraftCfgEntriesList = this->performParsing(rootDirectory, excludedDirectories, &ok); - return std::make_pair(aircraftCfgEntriesList, ok); - }); - m_parserWorker->thenWithResult>(this, [this](const auto &pair) - { - if (pair.second) + bool ok = false; + const auto aircraftCfgEntriesList = this->performParsing(rootDirectory, excludedDirectories, &ok); + CAircraftModelList models; + if (ok) { - this->m_parsedCfgEntriesList = pair.first; - this->setModelsInCache(pair.first.toAircraftModelList()); - emit loadingFinished(true, this->m_simulatorInfo); + models = (aircraftCfgEntriesList.toAircraftModelList(this->supportedSimulators())); + this->mergeWithDbData(models, dbModels); + } + return std::make_tuple(aircraftCfgEntriesList, models, ok); + }); + m_parserWorker->thenWithResult(this, [this](const LoaderResponse & tuple) + { + const bool ok = std::get<2>(tuple); + if (ok) + { + this->m_parsedCfgEntriesList = std::get<0>(tuple); + const CAircraftModelList models(std::get<1>(tuple)); + const bool hasData = !models.isEmpty(); + if (hasData) + { + this->setModelsInCache(models); // not thread safe + } + // currently I treat no data as error + emit this->loadingFinished(hasData, this->m_simulatorInfo); + } + else + { + emit this->loadingFinished(false, this->m_simulatorInfo); } }); } @@ -117,8 +139,15 @@ namespace BlackMisc { bool ok; this->m_parsedCfgEntriesList = performParsing(m_rootDirectory, m_excludedDirectories, &ok); - this->setModelsInCache(this->m_parsedCfgEntriesList.toAircraftModelList()); - emit loadingFinished(ok, this->m_simulatorInfo); + CAircraftModelList models(this->m_parsedCfgEntriesList.toAircraftModelList(this->supportedSimulators())); + this->mergeWithDbData(models, dbModels); + const bool hasData = !models.isEmpty(); + if (hasData) + { + this->setModelsInCache(models); // not thread safe + } + // currently I treat no data as error + emit this->loadingFinished(hasData, this->m_simulatorInfo); } } @@ -250,7 +279,7 @@ namespace BlackMisc if (m_cancelLoading) { return CAircraftCfgEntriesList(); } if (file.isDir()) { - QString nextDir = file.absoluteFilePath(); + const QString nextDir = file.absoluteFilePath(); if (currentDir.startsWith(nextDir, Qt::CaseInsensitive)) { continue; } // do not go up if (dir == currentDir) { continue; } // do not recursively call same directory @@ -414,7 +443,7 @@ namespace BlackMisc } else if (static_cast(qv.type()) == QMetaType::QStringList) { - QStringList l = qv.toStringList(); + const QStringList l = qv.toStringList(); return l.join(",").trimmed(); } else if (static_cast(qv.type()) == QMetaType::QString) @@ -453,3 +482,5 @@ namespace BlackMisc } // namespace } // namespace } // namespace + +Q_DECLARE_METATYPE(BlackMisc::Simulation::FsCommon::LoaderResponse) diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgparser.h b/src/blackmisc/simulation/fscommon/aircraftcfgparser.h index 661e1ef5f..ecc52fc8a 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgparser.h +++ b/src/blackmisc/simulation/fscommon/aircraftcfgparser.h @@ -62,7 +62,7 @@ namespace BlackMisc //! \name Interface functions //! @{ - virtual void startLoadingFromDisk(LoadMode mode) override; + virtual void startLoadingFromDisk(LoadMode mode, const BlackMisc::Simulation::CAircraftModelList &dbModels) override; //! @} private slots: diff --git a/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.cpp b/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.cpp index d99ba06c0..434ebdbb2 100644 --- a/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.cpp +++ b/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.cpp @@ -62,7 +62,7 @@ namespace BlackMisc return {}; } - void CAircraftModelLoaderXPlane::startLoadingFromDisk(LoadMode mode) + void CAircraftModelLoaderXPlane::startLoadingFromDisk(LoadMode mode, const CAircraftModelList &dbModels) { m_installedModels.clear(); if (m_rootDirectory.isEmpty()) @@ -77,9 +77,10 @@ namespace BlackMisc auto rootDirectory = m_rootDirectory; auto excludedDirectories = m_excludedDirectories; m_parserWorker = BlackMisc::CWorker::fromTask(this, "CAircraftModelLoaderXPlane::performParsing", - [this, rootDirectory, excludedDirectories]() + [this, rootDirectory, excludedDirectories, dbModels]() { auto models = performParsing(rootDirectory, excludedDirectories); + mergeWithDbData(models, dbModels); return models; }); m_parserWorker->thenWithResult(this, [this](const auto & models) @@ -90,6 +91,7 @@ namespace BlackMisc else if (mode.testFlag(LoadDirectly)) { m_installedModels = performParsing(m_rootDirectory, m_excludedDirectories); + mergeWithDbData(m_installedModels, dbModels); emit loadingFinished(true, this->m_simulatorInfo); } } diff --git a/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.h b/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.h index 04b7a6e9c..41ed27e2e 100644 --- a/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.h +++ b/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.h @@ -58,7 +58,7 @@ namespace BlackMisc protected: //! \name Interface functions //! @{ - virtual void startLoadingFromDisk(LoadMode mode) override; + virtual void startLoadingFromDisk(LoadMode mode, const BlackMisc::Simulation::CAircraftModelList &dbModels) override; //! @} private: