From 2f0253b3eb5bfe1b3678191bfd71e08f4fa4ac0c Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Fri, 20 Oct 2017 00:23:18 +0200 Subject: [PATCH] Ref T118, support multiple model directories * this was recently discussed https://swift-project.slack.com/archives/C04J6J76N/p1508430536000065 * for config parser already implemented * for XP the loading from multiple dirs still needs to be implemented (see todo) --- .../components/dbownmodelscomponent.cpp | 16 +++++----- .../components/dbownmodelscomponent.h | 6 ++-- .../simulation/aircraftmodelloader.cpp | 12 ++++---- .../simulation/fscommon/aircraftcfgparser.cpp | 30 +++++++++++++------ .../simulation/fscommon/aircraftcfgparser.h | 10 +++++-- .../xplane/aircraftmodelloaderxplane.cpp | 15 ++++++---- .../xplane/aircraftmodelloaderxplane.h | 2 +- 7 files changed, 57 insertions(+), 34 deletions(-) diff --git a/src/blackgui/components/dbownmodelscomponent.cpp b/src/blackgui/components/dbownmodelscomponent.cpp index 437f02d2a..581f00b78 100644 --- a/src/blackgui/components/dbownmodelscomponent.cpp +++ b/src/blackgui/components/dbownmodelscomponent.cpp @@ -324,7 +324,7 @@ namespace BlackGui const QString dir = CDbOwnModelsComponent::directorySelector(sim); if (!dir.isEmpty()) { - ownModelsComp->ps_requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, dir); + ownModelsComp->ps_requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, QStringList(dir)); } }); } @@ -350,7 +350,7 @@ namespace BlackGui const QString dir = CDbOwnModelsComponent::directorySelector(sim); if (!dir.isEmpty()) { - ownModelsComp->ps_requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, dir); + ownModelsComp->ps_requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, QStringList(dir)); } }); } @@ -376,7 +376,7 @@ namespace BlackGui const QString dir = CDbOwnModelsComponent::directorySelector(sim); if (!dir.isEmpty()) { - ownModelsComp->ps_requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, dir); + ownModelsComp->ps_requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, QStringList(dir)); } }); } @@ -401,7 +401,7 @@ namespace BlackGui const QString dir = CDbOwnModelsComponent::directorySelector(sim); if (!dir.isEmpty()) { - ownModelsComp->ps_requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, dir); + ownModelsComp->ps_requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, QStringList(dir)); } }); } @@ -427,7 +427,7 @@ namespace BlackGui ); } - void CDbOwnModelsComponent::ps_loadInstalledModels(const CSimulatorInfo &simulator, IAircraftModelLoader::LoadMode mode, const QString &directory) + void CDbOwnModelsComponent::ps_loadInstalledModels(const CSimulatorInfo &simulator, IAircraftModelLoader::LoadMode mode, const QStringList &modelDirectories) { if (!this->initModelLoader(simulator)) { @@ -444,7 +444,7 @@ namespace BlackGui CLogMessage(this).info("Starting loading for '%1'") << simulator.toQString(); ui->tvp_OwnAircraftModels->showLoadIndicator(); Q_ASSERT_X(sGui && sGui->getWebDataServices(), Q_FUNC_INFO, "missing web data services"); - m_modelLoader->startLoading(mode, static_cast(&CDatabaseUtils::consolidateModelsWithDbData), directory); + m_modelLoader->startLoading(mode, static_cast(&CDatabaseUtils::consolidateModelsWithDbData), modelDirectories); } void CDbOwnModelsComponent::ps_onOwnModelsLoadingFinished(const CStatusMessage &status, const CSimulatorInfo &simulator, IAircraftModelLoader::LoadFinishedInfo info) @@ -475,9 +475,9 @@ namespace BlackGui ui->comp_SimulatorSelector->setValue(simulator); } - void CDbOwnModelsComponent::ps_requestSimulatorModels(const CSimulatorInfo &simulator, IAircraftModelLoader::LoadMode mode, const QString &directory) + void CDbOwnModelsComponent::ps_requestSimulatorModels(const CSimulatorInfo &simulator, IAircraftModelLoader::LoadMode mode, const QStringList &modelDirectories) { - this->ps_loadInstalledModels(simulator, mode, directory); + this->ps_loadInstalledModels(simulator, mode, modelDirectories); } void CDbOwnModelsComponent::ps_requestSimulatorModelsWithCacheInBackground(const CSimulatorInfo &simulator) diff --git a/src/blackgui/components/dbownmodelscomponent.h b/src/blackgui/components/dbownmodelscomponent.h index 3d816bf70..2ccf9dc16 100644 --- a/src/blackgui/components/dbownmodelscomponent.h +++ b/src/blackgui/components/dbownmodelscomponent.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include class QAction; @@ -121,13 +121,13 @@ namespace BlackGui void ps_requestOwnModelsUpdate(); //! Load the models - void ps_loadInstalledModels(const BlackMisc::Simulation::CSimulatorInfo &simulator, BlackMisc::Simulation::IAircraftModelLoader::LoadMode mode, const QString &directory = ""); + void ps_loadInstalledModels(const BlackMisc::Simulation::CSimulatorInfo &simulator, BlackMisc::Simulation::IAircraftModelLoader::LoadMode mode, const QStringList &modelDirectories = {}); //! Model loading finished void ps_onOwnModelsLoadingFinished(const BlackMisc::CStatusMessage &status, const BlackMisc::Simulation::CSimulatorInfo &simulator, BlackMisc::Simulation::IAircraftModelLoader::LoadFinishedInfo info); //! Request simulator models - void ps_requestSimulatorModels(const BlackMisc::Simulation::CSimulatorInfo &simulator, BlackMisc::Simulation::IAircraftModelLoader::LoadMode mode, const QString &directory = ""); + void ps_requestSimulatorModels(const BlackMisc::Simulation::CSimulatorInfo &simulator, BlackMisc::Simulation::IAircraftModelLoader::LoadMode mode, const QStringList &modelDirectories = {}); //! Request simulator models from cache void ps_requestSimulatorModelsWithCacheInBackground(const BlackMisc::Simulation::CSimulatorInfo &simulator); diff --git a/src/blackmisc/simulation/aircraftmodelloader.cpp b/src/blackmisc/simulation/aircraftmodelloader.cpp index c2aa08242..8f4f13cb6 100644 --- a/src/blackmisc/simulation/aircraftmodelloader.cpp +++ b/src/blackmisc/simulation/aircraftmodelloader.cpp @@ -182,7 +182,7 @@ namespace BlackMisc return this->setCachedModels(CAircraftModelList()); } - void IAircraftModelLoader::startLoading(LoadMode mode, const ModelConsolidation &modelConsolidation, const QString &directory) + void IAircraftModelLoader::startLoading(LoadMode mode, const ModelConsolidation &modelConsolidation, const QStringList &modelDirectories) { if (m_loadingInProgress) { return; } m_loadingInProgress = true; @@ -206,16 +206,18 @@ namespace BlackMisc } // really load from disk? - if (m_skipLoadingEmptyModelDir && !CDirectoryUtils::existsUnemptyDirectory(directory)) + const CSimulatorInfo simulator = this->getSimulator(); + const QStringList modelDirs = this->getInitializedModelDirectories(modelDirectories, simulator); + if (m_skipLoadingEmptyModelDir && modelDirs.isEmpty()) { const CStatusMessage status = CStatusMessage(this, CStatusMessage::SeverityWarning, "Empty or not existing %1 directory '%2', skipping read") - << this->getSimulator().toQString() << directory; + << simulator.toQString() << modelDirectories.join(", "); m_loadingMessages.push_back(status); - emit loadingFinished(status, this->getSimulator(), LoadingSkipped); + emit loadingFinished(status, simulator, LoadingSkipped); return; } - this->startLoadingFromDisk(mode, modelConsolidation, directory); + this->startLoadingFromDisk(mode, modelConsolidation, modelDirs); } const CSimulatorInfo IAircraftModelLoader::getSimulator() const diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgparser.cpp b/src/blackmisc/simulation/fscommon/aircraftcfgparser.cpp index 6a46ae06c..60fb26cbf 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgparser.cpp +++ b/src/blackmisc/simulation/fscommon/aircraftcfgparser.cpp @@ -63,26 +63,24 @@ namespace BlackMisc if (m_parserWorker) { m_parserWorker->waitForFinished(); } } - void CAircraftCfgParser::startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QString &directory) + void CAircraftCfgParser::startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QStringList &modelDirectories) { static const CStatusMessage statusLoadingOk(this, CStatusMessage::SeverityInfo, "Aircraft config parser loaded data"); static const CStatusMessage statusLoadingError(this, CStatusMessage::SeverityError, "Aircraft config parser did not load data"); const CSimulatorInfo simulator = this->getSimulator(); - const QString modelDirectory = CFileUtils::fixWindowsUncPath( - directory.isEmpty() ? m_settings.getFirstModelDirectoryOrDefault(simulator) : directory - ); // expect only one directory + const QStringList modelDirs = this->getInitializedModelDirectories(modelDirectories, simulator); const QStringList excludedDirectoryPatterns(m_settings.getModelExcludeDirectoryPatternsOrDefault(simulator)); // copy if (mode.testFlag(LoadInBackground)) { if (m_parserWorker && !m_parserWorker->isFinished()) { return; } m_parserWorker = BlackMisc::CWorker::fromTask(this, "CAircraftCfgParser::changeDirectory", - [this, modelDirectory, excludedDirectoryPatterns, simulator, modelConsolidation]() + [this, modelDirs, excludedDirectoryPatterns, simulator, modelConsolidation]() { bool ok = false; CStatusMessageList msgs; - const auto aircraftCfgEntriesList = this->performParsing(modelDirectory, excludedDirectoryPatterns, msgs, &ok); + const auto aircraftCfgEntriesList = this->performParsing(modelDirs, excludedDirectoryPatterns, msgs, &ok); CAircraftModelList models; if (ok) { @@ -119,13 +117,13 @@ namespace BlackMisc { bool ok; CStatusMessageList msgs; - m_parsedCfgEntriesList = performParsing(modelDirectory, excludedDirectoryPatterns, msgs, &ok); - CAircraftModelList models(m_parsedCfgEntriesList.toAircraftModelList(simulator, true, msgs)); + m_parsedCfgEntriesList = performParsing(modelDirs, excludedDirectoryPatterns, msgs, &ok); + const CAircraftModelList models(m_parsedCfgEntriesList.toAircraftModelList(simulator, true, msgs)); m_loadingMessages = msgs; const bool hasData = !models.isEmpty(); if (hasData) { - this->setCachedModels(models); // not thread safe + this->setCachedModels(models); } // currently I treat no data as error emit this->loadingFinished(hasData ? statusLoadingOk : statusLoadingError, simulator, ParsedData); @@ -137,6 +135,20 @@ namespace BlackMisc return !m_parserWorker || m_parserWorker->isFinished(); } + CAircraftCfgEntriesList CAircraftCfgParser::performParsing(const QStringList &directories, const QStringList &excludeDirectories, CStatusMessageList &messages, bool *ok) + { + CAircraftCfgEntriesList entries; + bool dirOk = false; + bool success = true; + for (const QString &dir : directories) + { + entries.push_back(performParsing(dir, excludeDirectories, messages, &dirOk)); + success &= dirOk; + } + *ok = success; + return entries; + } + CAircraftCfgEntriesList CAircraftCfgParser::performParsing(const QString &directory, const QStringList &excludeDirectories, CStatusMessageList &messages, bool *ok) { // diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgparser.h b/src/blackmisc/simulation/fscommon/aircraftcfgparser.h index 3eafeb699..3df09bbf1 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgparser.h +++ b/src/blackmisc/simulation/fscommon/aircraftcfgparser.h @@ -60,7 +60,7 @@ namespace BlackMisc protected: //! \name Interface functions //! @{ - virtual void startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QString &directory) override; + virtual void startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QStringList &modelDirectories) override; //! @} private: @@ -72,7 +72,13 @@ namespace BlackMisc Unknown }; - //! Perform the parsing + //! Perform the parsing for all directories + //! \threadsafe + CAircraftCfgEntriesList performParsing( + const QStringList &directories, const QStringList &excludeDirectories, + BlackMisc::CStatusMessageList &messages, bool *ok); + + //! Perform the parsing for one directory //! \threadsafe CAircraftCfgEntriesList performParsing( const QString &directory, const QStringList &excludeDirectories, diff --git a/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.cpp b/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.cpp index 6aa83bad6..db10ccc4b 100644 --- a/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.cpp +++ b/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.cpp @@ -11,6 +11,7 @@ #include "blackmisc/aviation/airlineicaocode.h" #include "blackmisc/aviation/livery.h" #include "blackmisc/fileutils.h" +#include "blackmisc/directoryutils.h" #include "blackmisc/logmessage.h" #include "blackmisc/simulation/aircraftmodel.h" #include "blackmisc/simulation/aircraftmodelutils.h" @@ -122,17 +123,16 @@ namespace BlackMisc if (m_parserWorker) { m_parserWorker->waitForFinished(); } } - void CAircraftModelLoaderXPlane::startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QString &directory) + void CAircraftModelLoaderXPlane::startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QStringList &modelDirectories) { - //! \todo KB/MS 2017-09 not high prio, but still needed: according to meeting XP needs to support multiple directories const CSimulatorInfo simulator = this->getSimulator(); - const QString modelDirectory(!directory.isEmpty() ? directory : this->getFirstModelDirectoryOrDefault()); // directory + const QStringList modelDirs = this->getInitializedModelDirectories(modelDirectories, simulator); const QStringList excludedDirectoryPatterns(m_settings.getModelExcludeDirectoryPatternsOrDefault(simulator)); // copy - if (modelDirectory.isEmpty()) + if (modelDirs.isEmpty()) { this->clearCache(); - emit loadingFinished(CStatusMessage(this, CStatusMessage::SeverityError, "Model directory '%1' is empty") << modelDirectory, simulator, ParsedData); + emit loadingFinished(CStatusMessage(this, CStatusMessage::SeverityError, "Model directories '%1' are empty") << modelDirectories.join(", "), simulator, ParsedData); return; } @@ -140,8 +140,11 @@ namespace BlackMisc { if (m_parserWorker && !m_parserWorker->isFinished()) { return; } m_parserWorker = BlackMisc::CWorker::fromTask(this, "CAircraftModelLoaderXPlane::performParsing", - [this, modelDirectory, excludedDirectoryPatterns, modelConsolidation]() + [this, modelDirs, excludedDirectoryPatterns, modelConsolidation]() { + //! \todo KB/MS 2017-09 not high prio, but still needed: according to meeting XP needs to support multiple directories + //! \todo KB with T118 now model directories are passed (changed signatures) but the code below needs to support multiple dirs + const QString modelDirectory = modelDirs.front(); auto models = performParsing(modelDirectory, excludedDirectoryPatterns); if (modelConsolidation) { modelConsolidation(models, true); } return models; diff --git a/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.h b/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.h index deb5fb55e..efea63788 100644 --- a/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.h +++ b/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.h @@ -61,7 +61,7 @@ namespace BlackMisc protected: //! \name Interface functions //! @{ - virtual void startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QString &directory) override; + virtual void startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QStringList &modelDirectories) override; //! @} private: