From 5953bbe4c6ec3eb13ea5f854052cdf93cd91c517 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sun, 22 Jul 2018 18:01:58 +0200 Subject: [PATCH] Ref T292, model loader improvements * CMultiAircraftModelLoaderProvider keeping all model loaders in memory (alzy init) * using CCentralMultiSimulatorModelCachesProvider * adjusted to changes such as "ModelsFor" renaming * parent QObject for model loaders --- .../simulation/aircraftmodelloader.cpp | 297 ++++++------------ .../simulation/aircraftmodelloader.h | 185 +++++------ 2 files changed, 172 insertions(+), 310 deletions(-) diff --git a/src/blackmisc/simulation/aircraftmodelloader.cpp b/src/blackmisc/simulation/aircraftmodelloader.cpp index fb2f5b8cc..7c1eead95 100644 --- a/src/blackmisc/simulation/aircraftmodelloader.cpp +++ b/src/blackmisc/simulation/aircraftmodelloader.cpp @@ -30,16 +30,10 @@ namespace BlackMisc { namespace Simulation { - IAircraftModelLoader::IAircraftModelLoader(const CSimulatorInfo &simulator) + const CLogCategoryList &IAircraftModelLoader::getLogCategories() { - Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "Only one simulator per loader"); - m_caches.setCurrentSimulator(simulator); - this->setObjectInfo(simulator); - - // first connect is an internal connection to log info about load status - connect(this, &IAircraftModelLoader::loadingFinished, this, &IAircraftModelLoader::onLoadingFinished, Qt::QueuedConnection); - connect(&m_caches, &IMultiSimulatorModelCaches::cacheChanged, this, &IAircraftModelLoader::onCacheChanged); - connect(&m_settings, &CMultiSimulatorSettings::settingsChanged, this, &IAircraftModelLoader::onSettingsChanged); + static const CLogCategoryList cats({ CLogCategory::modelLoader() }); + return cats; } const QString &IAircraftModelLoader::enumToString(IAircraftModelLoader::LoadFinishedInfo info) @@ -100,152 +94,33 @@ namespace BlackMisc return mode.testFlag(CacheFirst) || mode.testFlag(CacheOnly); } - IAircraftModelLoader::~IAircraftModelLoader() + IAircraftModelLoader::IAircraftModelLoader(const CSimulatorInfo &simulator, QObject *parent) : + CCentralMultiSimulatorModelCachesProvider(parent), + m_simulator(simulator) { - this->gracefulShutdown(); + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "Only one simulator per loader"); + connect(this, &IAircraftModelLoader::loadingFinished, this, &IAircraftModelLoader::onLoadingFinished, Qt::QueuedConnection); } - const CLogCategoryList &IAircraftModelLoader::getLogCategories() - { - static const CLogCategoryList cats({ CLogCategory::modelLoader() }); - return cats; - } + IAircraftModelLoader::~IAircraftModelLoader() { } - CStatusMessage IAircraftModelLoader::setCachedModels(const CAircraftModelList &models, const CSimulatorInfo &simulator) - { - const CSimulatorInfo usedSimulator = simulator.isSingleSimulator() ? simulator : this->getSimulator(); // support default value - this->setObjectInfo(usedSimulator); - return m_caches.setCachedModels(models, usedSimulator); - } - - CStatusMessage IAircraftModelLoader::replaceOrAddCachedModels(const CAircraftModelList &models, const CSimulatorInfo &simulator) - { - if (models.isEmpty()) { return CStatusMessage(this, CStatusMessage::SeverityInfo, "No data"); } - const CSimulatorInfo sim = simulator.isSingleSimulator() ? simulator : this->getSimulator(); // support default values - this->setObjectInfo(sim); - CAircraftModelList allModels(m_caches.getSynchronizedCachedModels(sim)); - const int c = allModels.replaceOrAddModelsWithString(models, Qt::CaseInsensitive); - if (c > 0) - { - return this->setCachedModels(allModels, sim); - } - else - { - return CStatusMessage(this, CStatusMessage::SeverityInfo, "No data changed"); - } - } - - void IAircraftModelLoader::onLoadingFinished(const CStatusMessageList &statusMsgs, const CSimulatorInfo &simulator, LoadFinishedInfo info) - { - Q_UNUSED(info); - this->setObjectInfo(simulator); - - // remark: in the past status used to be bool, now it is CStatusMessage - // so there is some redundancy here between status and m_loadingMessages - m_loadingInProgress = false; - - const QMap counts = statusMsgs.countSeverities(); - const int errors = counts.value(SeverityError); - const int warnings = counts.value(SeverityWarning); - - if (statusMsgs.hasWarningOrErrorMessages()) - { - CLogMessage(this).log(m_loadingMessages.worstSeverity(), - "Message loading produced %1 error and %2 warning messages") << errors << warnings; - } - else - { - CLogMessage(this).info("Loading finished, success for '%1'") << simulator.toQString(); - } - } - - void IAircraftModelLoader::onCacheChanged(const CSimulatorInfo &simInfo) - { - // this detects a loaded cache elsewhere - Q_UNUSED(simInfo); - } - - void IAircraftModelLoader::onSettingsChanged(const CSimulatorInfo &simInfo) - { - // this detects changed settings elsewhere - Q_UNUSED(simInfo); - } - - QStringList IAircraftModelLoader::getInitializedModelDirectories(const QStringList &modelDirectories, const CSimulatorInfo &simulator) const - { - QStringList modelDirs = modelDirectories.isEmpty() ? m_settings.getModelDirectoriesOrDefault(simulator) : modelDirectories; - modelDirs = CFileUtils::fixWindowsUncPaths(modelDirs); - return CDirectoryUtils::getExistingUnemptyDirectories(modelDirs); - } - - void IAircraftModelLoader::setObjectInfo(const CSimulatorInfo &simulatorInfo) - { - this->setObjectName("Model loader for: '" + simulatorInfo.toQString(true) + "'"); - } - - QStringList IAircraftModelLoader::getModelDirectoriesOrDefault() const - { - const QStringList mdirs = m_settings.getModelDirectoriesOrDefault(this->getSimulator()); - return mdirs; - } - - QString IAircraftModelLoader::getFirstModelDirectoryOrDefault() const - { - const QString md = m_settings.getFirstModelDirectoryOrDefault(this->getSimulator()); - return md; - } - - QStringList IAircraftModelLoader::getModelExcludeDirectoryPatterns() const - { - return m_settings.getModelExcludeDirectoryPatternsOrDefault(this->getSimulator()); - } - - CAircraftModelList IAircraftModelLoader::getAircraftModels() const - { - return m_caches.getCurrentCachedModels(); - } - - CAircraftModelList IAircraftModelLoader::getCachedAircraftModels(const CSimulatorInfo &simulator) const - { - return m_caches.getCachedModels(simulator); - } - - QDateTime IAircraftModelLoader::getCacheTimestamp() const - { - return m_caches.getCurrentCacheTimestamp(); - } - - bool IAircraftModelLoader::hasCachedData() const - { - return !m_caches.getCurrentCachedModels().isEmpty(); - } - - CStatusMessage IAircraftModelLoader::clearCache() - { - return m_caches.clearCachedModels(m_caches.getCurrentSimulator()); - } - - CStatusMessage IAircraftModelLoader::clearCache(const CSimulatorInfo &simulator) - { - return m_caches.clearCachedModels(simulator); - } - - void IAircraftModelLoader::startLoading(LoadMode mode, const ModelConsolidationCallback &modelConsolidation, const QStringList &modelDirectories) + void IAircraftModelLoader::startLoading(LoadMode mode, const IAircraftModelLoader::ModelConsolidationCallback &modelConsolidation, const QStringList &modelDirectories) { if (m_loadingInProgress) { return; } + if (mode == NotSet) { return; } m_loadingInProgress = true; m_loadingMessages.clear(); const CSimulatorInfo simulator = this->getSimulator(); const bool needsCacheSynced = IAircraftModelLoader::needsCacheSynchronized(mode); - if (needsCacheSynced) { m_caches.synchronizeCache(simulator); } + if (needsCacheSynced) { this->synchronizeCache(simulator); } const bool useCachedData = !mode.testFlag(CacheSkipped) && this->hasCachedData(); if (useCachedData && (mode.testFlag(CacheFirst) || mode.testFlag(CacheOnly))) { // we just just cache data static const CStatusMessage status(this, CStatusMessage::SeverityInfo, "Using cached data"); - emit loadingFinished(status, this->getSimulator(), CacheLoaded); + emit this->loadingFinished(status, simulator, CacheLoaded); return; } if (mode.testFlag(CacheOnly)) @@ -273,83 +148,113 @@ namespace BlackMisc this->startLoadingFromDisk(mode, modelConsolidation, modelDirs); } - const CSimulatorInfo IAircraftModelLoader::getSimulator() const + QString IAircraftModelLoader::getFirstModelDirectoryOrDefault() const { - return m_caches.getCurrentSimulator(); + const QString md = m_settings.getFirstModelDirectoryOrDefault(m_simulator); + return md; } - QString IAircraftModelLoader::getSimulatorAsString() const + void IAircraftModelLoader::setModels(const CAircraftModelList &models) { - return this->getSimulator().toQString(); + this->setModelsForSimulator(models, m_simulator); } - bool IAircraftModelLoader::supportsSimulator(const CSimulatorInfo &simulator) + int IAircraftModelLoader::updateModels(const CAircraftModelList &models) { - return getSimulator().matchesAny(simulator); + return this->updateModelsForSimulator(models, m_simulator); } - void IAircraftModelLoader::cancelLoading() - { - if (!m_loadingInProgress) { return; } - m_cancelLoading = true; - } - - void IAircraftModelLoader::gracefulShutdown() - { - this->cancelLoading(); - m_loadingInProgress = true; // avoids further startups - } - - QString IAircraftModelLoader::getModelCacheInfoString() const - { - return m_caches.getInfoString(); - } - - QString IAircraftModelLoader::getModelCacheInfoStringFsFamily() const - { - return m_caches.getInfoStringFsFamily(); - } - - QString IAircraftModelLoader::getModelCacheCountAndTimestamp() const - { - return m_caches.getCacheCountAndTimestamp(this->getSimulator()); - } - - QString IAircraftModelLoader::getModelCacheCountAndTimestamp(const CSimulatorInfo &simulator) const - { - return m_caches.getCacheCountAndTimestamp(simulator); - } - - CSpecializedSimulatorSettings IAircraftModelLoader::getCurrentSimulatorSettings() const - { - return m_settings.getSpecializedSettings(this->getSimulator()); - } - - void IAircraftModelLoader::synchronizeModelCache(const CSimulatorInfo &simulator) - { - m_caches.synchronizeCache(simulator); - } - - std::unique_ptr IAircraftModelLoader::createModelLoader(const CSimulatorInfo &simulator) + IAircraftModelLoader *IAircraftModelLoader::createModelLoader(const CSimulatorInfo &simulator, QObject *parent) { Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "Single simulator"); - std::unique_ptr loader; - if (simulator.isXPlane()) + if (simulator.isXPlane()) { return new CAircraftModelLoaderXPlane(parent); } + return CAircraftCfgParser::createModelLoader(simulator, parent); + } + + QStringList IAircraftModelLoader::getInitializedModelDirectories(const QStringList &modelDirectories, const CSimulatorInfo &simulator) const + { + QStringList modelDirs = modelDirectories.isEmpty() ? m_settings.getModelDirectoriesOrDefault(simulator) : modelDirectories; + modelDirs = CFileUtils::fixWindowsUncPaths(modelDirs); + return CDirectoryUtils::getExistingUnemptyDirectories(modelDirs); + } + + bool IAircraftModelLoader::hasCachedData() const + { + return !this->getCachedModels(m_simulator).isEmpty(); + } + + void IAircraftModelLoader::setObjectInfo(const CSimulatorInfo &simulatorInfo) + { + this->setObjectName("Model loader for: '" + simulatorInfo.toQString(true) + "'"); + } + + void IAircraftModelLoader::onLoadingFinished(const CStatusMessageList &statusMsgs, const CSimulatorInfo &simulator, IAircraftModelLoader::LoadFinishedInfo info) + { + Q_UNUSED(info); + if (!this->supportsSimulator(simulator)) { return; } // none of my business + this->setObjectInfo(simulator); + + // remark: in the past status used to be bool, now it is CStatusMessage + // so there is some redundancy here between status and m_loadingMessages + m_loadingInProgress = false; + + const QMap counts = statusMsgs.countSeverities(); + const int errors = counts.value(SeverityError); + const int warnings = counts.value(SeverityWarning); + + if (statusMsgs.hasWarningOrErrorMessages()) { - loader = std::make_unique(); + CLogMessage(this).log(m_loadingMessages.worstSeverity(), + "Message loading produced %1 error and %2 warning messages") << errors << warnings; } else { - loader = CAircraftCfgParser::createModelLoader(simulator); + CLogMessage(this).info("Loading finished, success for '%1'") << simulator.toQString(); } + } - if (!loader) { return loader; } - - // make sure the cache is really available, normally this happens in the constructor - if (loader->getSimulator() != simulator) + IAircraftModelLoader *CMultiAircraftModelLoaderProvider::loaderInstance(const CSimulatorInfo &simulator) + { + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + switch (simulator.getSimulator()) { - loader->m_caches.setCurrentSimulator(simulator); // mark current simulator and sync caches + case CSimulatorInfo::FSX: + { + if (!m_loaderFsx) { m_loaderFsx = this->initLoader(CSimulatorInfo::fsx()); } + return m_loaderFsx; + } + case CSimulatorInfo::P3D: + { + if (!m_loaderP3D) { m_loaderP3D = this->initLoader(CSimulatorInfo::p3d()); } + return m_loaderP3D; + } + case CSimulatorInfo::XPLANE: + { + if (!m_loaderXP) { m_loaderXP = this->initLoader(CSimulatorInfo::xplane()); } + return m_loaderXP; + } + case CSimulatorInfo::FS9: + { + if (!m_loaderFS9) { m_loaderFS9 = this->initLoader(CSimulatorInfo::fs9()); } + return m_loaderFS9; + } + default: + Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong simulator"); + break; } + return nullptr; + } + + CMultiAircraftModelLoaderProvider &CMultiAircraftModelLoaderProvider::multiModelLoaderInstance() + { + static CMultiAircraftModelLoaderProvider loader; + return loader; + } + + IAircraftModelLoader *CMultiAircraftModelLoaderProvider::initLoader(const CSimulatorInfo &simulator) + { + IAircraftModelLoader *loader = IAircraftModelLoader::createModelLoader(simulator, this); + connect(loader, &IAircraftModelLoader::loadingFinished, this, &CMultiAircraftModelLoaderProvider::loadingFinished); return loader; } } // ns diff --git a/src/blackmisc/simulation/aircraftmodelloader.h b/src/blackmisc/simulation/aircraftmodelloader.h index d7c33253f..6a6211dab 100644 --- a/src/blackmisc/simulation/aircraftmodelloader.h +++ b/src/blackmisc/simulation/aircraftmodelloader.h @@ -12,13 +12,13 @@ #ifndef BLACKMISC_SIMULATION_IAIRCRAFTMODELLOADER_H #define BLACKMISC_SIMULATION_IAIRCRAFTMODELLOADER_H -#include "blackmisc/blackmiscexport.h" #include "blackmisc/simulation/aircraftmodelinterfaces.h" #include "blackmisc/simulation/aircraftmodellist.h" #include "blackmisc/simulation/data/modelcaches.h" #include "blackmisc/simulation/settings/simulatorsettings.h" #include "blackmisc/simulation/simulatorinfo.h" #include "blackmisc/statusmessagelist.h" +#include "blackmisc/blackmiscexport.h" #include #include @@ -36,23 +36,22 @@ namespace BlackMisc { /*! * Load the aircraft for a simulator + * \remark all model loaders share the same model caches of Data::CCentralMultiSimulatorModelCachesProvider */ class BLACKMISC_EXPORT IAircraftModelLoader : - public QObject, + public Data::CCentralMultiSimulatorModelCachesProvider, public IModelsSetable, - public IModelsUpdatable, - public IModelsPerSimulatorSetable, - public IModelsPerSimulatorUpdatable + public IModelsUpdatable { Q_OBJECT Q_INTERFACES(BlackMisc::Simulation::IModelsSetable) Q_INTERFACES(BlackMisc::Simulation::IModelsUpdatable) - Q_INTERFACES(BlackMisc::Simulation::IModelsPerSimulatorSetable) - Q_INTERFACES(BlackMisc::Simulation::IModelsPerSimulatorUpdatable) + Q_INTERFACES(BlackMisc::Simulation::IModelsForSimulatorSetable) + Q_INTERFACES(BlackMisc::Simulation::IModelsForSimulatorUpdatable) public: //! Log categories - static const BlackMisc::CLogCategoryList &getLogCategories(); + static const CLogCategoryList &getLogCategories(); //! Parser mode enum LoadModeFlag @@ -88,50 +87,24 @@ namespace BlackMisc //! Is that mode needing caches synchronized? static bool needsCacheSynchronized(LoadMode mode); - //! Destructor - virtual ~IAircraftModelLoader(); - //! Callback to consolidate data, normally with DB data //! \remark this has to be a abstarct, as DB handling is subject of BlackCore using ModelConsolidationCallback = std::function; + //! Destructor + virtual ~IAircraftModelLoader(); + + //! Loading finished? + virtual bool isLoadingFinished() const = 0; + //! Start the loading process from disk. //! Optional DB models can be passed and used for data consolidation. void startLoading(LoadMode mode = InBackgroundWithCache, const ModelConsolidationCallback &modelConsolidation = {}, const QStringList &modelDirectories = {}); - //! Loading finished? - virtual bool isLoadingFinished() const = 0; - //! Loading in progress //! \threadsafe bool isLoadingInProgress() const { return m_loadingInProgress; } - //! Get the loaded models - //! \threadsafe - BlackMisc::Simulation::CAircraftModelList getAircraftModels() const; - - //! Get the cached models - //! \threadsafe - BlackMisc::Simulation::CAircraftModelList getCachedAircraftModels(const CSimulatorInfo &simulator) const; - - //! Count of loaded models - //! \threadsafe - int getAircraftModelsCount() const { return getAircraftModels().size(); } - - //! Skip the loading of empty (model) directories - //! \remark loading of empty directories might erase the cache and is normally disable - //! \threadsafe - void setSkipLoadingOfEmptyDirectories(bool skip); - - //! Which simulator is supported by that very loader - const CSimulatorInfo getSimulator() const; - - //! Supported simulators as string - QString getSimulatorAsString() const; - - //! Is the given simulator supported? - bool supportsSimulator(const BlackMisc::Simulation::CSimulatorInfo &info); - //! Model directories QStringList getModelDirectoriesOrDefault() const; @@ -141,62 +114,19 @@ namespace BlackMisc //! Exclude directories QStringList getModelExcludeDirectoryPatterns() const; - //! Cancel loading - void cancelLoading(); + //! Simulator + const CSimulatorInfo &getSimulator() const { return m_simulator; } - //! Shutdown - void gracefulShutdown(); + //! Supported simulator + bool supportsSimulator(const CSimulatorInfo &simulator) const { return m_simulator == simulator; } - //! \copydoc BlackMisc::Simulation::Data::CModelCaches::getInfoString - QString getModelCacheInfoString() const; - - //! \copydoc BlackMisc::Simulation::Data::CModelCaches::getInfoStringFsFamily - QString getModelCacheInfoStringFsFamily() const; - - //! \copydoc BlackMisc::Simulation::Data::CModelCaches::getCacheCountAndTimestamp - QString getModelCacheCountAndTimestamp() const; - - //! \copydoc BlackMisc::Simulation::Data::CModelCaches::getCacheCountAndTimestamp - QString getModelCacheCountAndTimestamp(const CSimulatorInfo &simulator) const; - - //! \copydoc BlackMisc::Simulation::Data::IMultiSimulatorModelCaches::synchronizeCache - void synchronizeModelCache(const CSimulatorInfo &simulator); - - //! \copydoc BlackMisc::Simulation::Data::IMultiSimulatorModelCaches::clearCache - BlackMisc::CStatusMessage clearCache(); - - //! \copydoc BlackMisc::Simulation::Data::IMultiSimulatorModelCaches::clearCache - BlackMisc::CStatusMessage clearCache(const CSimulatorInfo &simulator); - - //! \copydoc Settings::CMultiSimulatorSettings::getSpecializedSettings - Settings::CSpecializedSimulatorSettings getCurrentSimulatorSettings() const; - - //! Access to multi simulator settings - const Settings::CMultiSimulatorSettings &multiSimulatorSettings() const { return m_settings; } - - //! Access to multi simulator settings - Settings::CMultiSimulatorSettings &multiSimulatorSettings() { return m_settings; } - - //! \name Implementations of the model interfaces (allows to set models modified in utility functions) - //! @{ - virtual void setModels(const CAircraftModelList &models) override { this->setCachedModels(models, this->getSimulator()); } - virtual void updateModels(const CAircraftModelList &models) override { this->replaceOrAddCachedModels(models, this->getSimulator()); } - virtual void setModels(const CAircraftModelList &models, const CSimulatorInfo &simulator) override { this->setCachedModels(models, simulator); } - virtual void updateModels(const CAircraftModelList &models, const CSimulatorInfo &simulator) override { this->replaceOrAddCachedModels(models, simulator); } + //! Interface implementations @{ + virtual void setModels(const CAircraftModelList &models) override; + virtual int updateModels(const CAircraftModelList &models) override; //! @} - //! Set cache from outside, this should only be used in special cases. - //! But it allows to modify data elsewhere and update the cache with manipulated data. - //! Normally used to consoidate data with DB data and write them back - BlackMisc::CStatusMessage setCachedModels(const CAircraftModelList &models, const CSimulatorInfo &simulator = CSimulatorInfo()); - - //! Set cache from outside, this should only be used in special cases. - //! But it allows to modify data elsewhere and update the cache with manipulated data. - //! Normally used to consoidate data with DB data and write them back - BlackMisc::CStatusMessage replaceOrAddCachedModels(const CAircraftModelList &models, const CSimulatorInfo &simulator = CSimulatorInfo()); - //! Create a loader and synchronize caches - static std::unique_ptr createModelLoader(const BlackMisc::Simulation::CSimulatorInfo &simulator); + static IAircraftModelLoader *createModelLoader(const CSimulatorInfo &simulator, QObject *parent = nullptr); signals: //! Parsing is finished or cache has been loaded @@ -205,38 +135,65 @@ namespace BlackMisc protected: //! Constructor - IAircraftModelLoader(const CSimulatorInfo &simulator); - - //! Cache timestamp - QDateTime getCacheTimestamp() const; - - //! Any cached data? - bool hasCachedData() const; + IAircraftModelLoader(const CSimulatorInfo &simulator, QObject *parent = nullptr); //! Start the loading process from disk virtual void startLoadingFromDisk(LoadMode mode, const ModelConsolidationCallback &modelConsolidation, const QStringList &modelDirectories) = 0; - //! Loading finished, also logs messages - void onLoadingFinished(const CStatusMessageList &statusMsgs, const CSimulatorInfo &simulator, LoadFinishedInfo info); - - //! A cache has been changed - void onCacheChanged(const CSimulatorInfo &simInfo); - - //! A setting has been changed - void onSettingsChanged(const CSimulatorInfo &simInfo); - //! Get model directories from settings if empty, otherwise checked and UNC path fixed QStringList getInitializedModelDirectories(const QStringList &modelDirectories, const CSimulatorInfo &simulator) const; - std::atomic m_cancelLoading { false }; //!< flag, requesting to cancel loading - std::atomic m_loadingInProgress { false }; //!< loading in progress - std::atomic m_skipLoadingEmptyModelDir { true }; //!< loading empty model dirs might erase the cache, so normally we skip it - CStatusMessageList m_loadingMessages; //!< loading messages - Data::CModelCaches m_caches { false, this }; //!< caches used with this loader - Settings::CMultiSimulatorSettings m_settings { this }; //!< settings + //! Any cached data? + bool hasCachedData() const; + + const CSimulatorInfo m_simulator; //!< related simulator + std::atomic m_loadingInProgress { false }; //!< loading in progress + std::atomic m_cancelLoading { false }; //!< flag, requesting to cancel loading + std::atomic m_skipLoadingEmptyModelDir { true }; //!< loading empty model dirs might erase the cache, so normally we skip it + CStatusMessageList m_loadingMessages; //!< loading messages + Settings::CMultiSimulatorSettings m_settings { this }; //!< settings private: - void setObjectInfo(const BlackMisc::Simulation::CSimulatorInfo &simulatorInfo); + //! Descriptive name for loader + void setObjectInfo(const CSimulatorInfo &simulatorInfo); + + //! Loading completed + void onLoadingFinished(const CStatusMessageList &statusMsgs, const CSimulatorInfo &simulator, LoadFinishedInfo info); + }; + + /*! + * Single instances of all model loaders (lazy init) + */ + class BLACKMISC_EXPORT CMultiAircraftModelLoaderProvider : public QObject + { + Q_OBJECT + + public: + //! Loader instance + IAircraftModelLoader *loaderInstance(const CSimulatorInfo &simulator); + + //! Singleton + static CMultiAircraftModelLoaderProvider &multiModelLoaderInstance(); + + //! Simulator specific loaders @{ + IAircraftModelLoader *modelLoaderFsx() const { return m_loaderFsx; } + IAircraftModelLoader *modelLoaderP3D() const { return m_loaderP3D; } + IAircraftModelLoader *modelLoaderXP() const { return m_loaderXP; } + IAircraftModelLoader *modelLoaderFS9() const { return m_loaderFS9; } + //! @} + + signals: + //! \copydoc IAircraftModelLoader::loadingFinished + void loadingFinished(const CStatusMessageList &status, const CSimulatorInfo &simulator, IAircraftModelLoader::LoadFinishedInfo info); + + private: + IAircraftModelLoader *m_loaderFsx = nullptr; + IAircraftModelLoader *m_loaderP3D = nullptr; + IAircraftModelLoader *m_loaderXP = nullptr; + IAircraftModelLoader *m_loaderFS9 = nullptr; + + //! Init the loader + IAircraftModelLoader *initLoader(const CSimulatorInfo &simulator); }; } // ns } // ns