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
This commit is contained in:
Klaus Basan
2018-07-22 18:01:58 +02:00
parent b25e4ff3c0
commit 5953bbe4c6
2 changed files with 172 additions and 310 deletions

View File

@@ -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 <QDateTime>
#include <QFlags>
@@ -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<int (BlackMisc::Simulation::CAircraftModelList &, bool)>;
//! 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<IAircraftModelLoader> 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<bool> m_cancelLoading { false }; //!< flag, requesting to cancel loading
std::atomic<bool> m_loadingInProgress { false }; //!< loading in progress
std::atomic<bool> 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<bool> m_loadingInProgress { false }; //!< loading in progress
std::atomic<bool> m_cancelLoading { false }; //!< flag, requesting to cancel loading
std::atomic<bool> 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