From 94e3b89479f74a31b998ddd2919d92631c197701 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Thu, 26 Jul 2018 02:27:48 +0200 Subject: [PATCH] Ref T292, Ref T285 model loader and cache improvements * multi caches also emit when values are set and synchronized * model loader detects cache changed * added CCentralMultiSimulatorModelCachesAware --- .../components/dbownmodelscomponent.cpp | 12 +++-- .../components/dbownmodelscomponent.h | 3 ++ .../simulation/aircraftmodelloader.cpp | 17 +++++-- .../simulation/aircraftmodelloader.h | 13 ++++- src/blackmisc/simulation/data/modelcaches.cpp | 28 +++++----- src/blackmisc/simulation/data/modelcaches.h | 51 +++++++++++++++++-- 6 files changed, 100 insertions(+), 24 deletions(-) diff --git a/src/blackgui/components/dbownmodelscomponent.cpp b/src/blackgui/components/dbownmodelscomponent.cpp index cf76f229d..932cd542d 100644 --- a/src/blackgui/components/dbownmodelscomponent.cpp +++ b/src/blackgui/components/dbownmodelscomponent.cpp @@ -53,6 +53,7 @@ namespace BlackGui connect(ui->comp_SimulatorSelector, &CSimulatorSelector::changed, this, &CDbOwnModelsComponent::onSimulatorSelectorChanged); connect(&CMultiAircraftModelLoaderProvider::multiModelLoaderInstance(), &CMultiAircraftModelLoaderProvider::loadingFinished, this, &CDbOwnModelsComponent::onOwnModelsLoadingFinished, Qt::QueuedConnection); connect(&CMultiAircraftModelLoaderProvider::multiModelLoaderInstance(), &CMultiAircraftModelLoaderProvider::diskLoadingStarted, this, &CDbOwnModelsComponent::onOwnModelsDiskLoadingStarted, Qt::QueuedConnection); + connect(&CMultiAircraftModelLoaderProvider::multiModelLoaderInstance(), &CMultiAircraftModelLoaderProvider::cacheChanged, this, &CDbOwnModelsComponent::onCacheChanged, Qt::QueuedConnection); // Last selection isPinned -> no sync needed ui->comp_SimulatorSelector->setRememberSelectionAndSetToLastSelection(); @@ -546,9 +547,14 @@ namespace BlackGui // cache loads may occur in background, do not adjust UI settings if (info == IAircraftModelLoader::CacheLoaded) { return; } - // parsed loads normally explicit - ui->le_Simulator->setText(simulator.toQString()); - ui->comp_SimulatorSelector->setValue(simulator); + // parsed loads normally explicit displaying this simulator + this->setSimulator(simulator); + } + + void CDbOwnModelsComponent::onCacheChanged(const CSimulatorInfo &simulator) + { + const CAircraftModelList models(m_modelLoader->getCachedModels(simulator)); + ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(models); } void CDbOwnModelsComponent::requestSimulatorModels(const CSimulatorInfo &simulator, IAircraftModelLoader::LoadMode mode, const QStringList &modelDirectories) diff --git a/src/blackgui/components/dbownmodelscomponent.h b/src/blackgui/components/dbownmodelscomponent.h index de6e61462..fc3f92893 100644 --- a/src/blackgui/components/dbownmodelscomponent.h +++ b/src/blackgui/components/dbownmodelscomponent.h @@ -142,6 +142,9 @@ namespace BlackGui //! Model loading finished void onOwnModelsLoadingFinished(const BlackMisc::CStatusMessageList &statusMessages, const BlackMisc::Simulation::CSimulatorInfo &simulator, BlackMisc::Simulation::IAircraftModelLoader::LoadFinishedInfo info); + //! Cache has been changed + void onCacheChanged(const BlackMisc::Simulation::CSimulatorInfo &simulator); + //! Request simulator models void requestSimulatorModels(const BlackMisc::Simulation::CSimulatorInfo &simulator, BlackMisc::Simulation::IAircraftModelLoader::LoadMode mode, const QStringList &modelDirectories = {}); diff --git a/src/blackmisc/simulation/aircraftmodelloader.cpp b/src/blackmisc/simulation/aircraftmodelloader.cpp index f58e26f38..d74933b3c 100644 --- a/src/blackmisc/simulation/aircraftmodelloader.cpp +++ b/src/blackmisc/simulation/aircraftmodelloader.cpp @@ -95,11 +95,15 @@ namespace BlackMisc } IAircraftModelLoader::IAircraftModelLoader(const CSimulatorInfo &simulator, QObject *parent) : - CCentralMultiSimulatorModelCachesProvider(parent), + QObject(parent), m_simulator(simulator) { Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "Only one simulator per loader"); connect(this, &IAircraftModelLoader::loadingFinished, this, &IAircraftModelLoader::onLoadingFinished, Qt::QueuedConnection); + + CCentralMultiSimulatorModelCachesProvider *centralCaches = &CCentralMultiSimulatorModelCachesProvider::modelCachesInstance(); + connect(centralCaches, &CCentralMultiSimulatorModelCachesProvider::cacheChanged, this, &IAircraftModelLoader::onCacheChanged, Qt::QueuedConnection); + this->setObjectInfo(simulator); } IAircraftModelLoader::~IAircraftModelLoader() { } @@ -190,7 +194,6 @@ namespace BlackMisc 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); @@ -209,10 +212,17 @@ namespace BlackMisc } else { - CLogMessage(this).info("Loading finished, success for '%1'") << simulator.toQString(); + CLogMessage(this).info("Loading '%1' finished, success for '%2'") << IAircraftModelLoader::enumToString(info) << simulator.toQString(); } } + void IAircraftModelLoader::onCacheChanged(const CSimulatorInfo &simulator) + { + if (m_loadingInProgress) { return; } // this change signal is redundant as it will be handled by onLoadingFinished + if (!this->supportsSimulator(simulator)) { return; } // none of my business + emit this->cacheChanged(simulator); + } + IAircraftModelLoader *CMultiAircraftModelLoaderProvider::loaderInstance(const CSimulatorInfo &simulator) { Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); @@ -256,6 +266,7 @@ namespace BlackMisc IAircraftModelLoader *loader = IAircraftModelLoader::createModelLoader(simulator, this); connect(loader, &IAircraftModelLoader::loadingFinished, this, &CMultiAircraftModelLoaderProvider::loadingFinished); connect(loader, &IAircraftModelLoader::diskLoadingStarted, this, &CMultiAircraftModelLoaderProvider::diskLoadingStarted); + connect(loader, &IAircraftModelLoader::cacheChanged, this, &CMultiAircraftModelLoaderProvider::cacheChanged); return loader; } } // ns diff --git a/src/blackmisc/simulation/aircraftmodelloader.h b/src/blackmisc/simulation/aircraftmodelloader.h index e2a12a81e..08c39d0b4 100644 --- a/src/blackmisc/simulation/aircraftmodelloader.h +++ b/src/blackmisc/simulation/aircraftmodelloader.h @@ -39,7 +39,8 @@ namespace BlackMisc * \remark all model loaders share the same model caches of Data::CCentralMultiSimulatorModelCachesProvider */ class BLACKMISC_EXPORT IAircraftModelLoader : - public Data::CCentralMultiSimulatorModelCachesProvider, + public QObject, + public Data::CCentralMultiSimulatorModelCachesAware, public IModelsSetable, public IModelsUpdatable { @@ -137,6 +138,10 @@ namespace BlackMisc //! \remark does to fire if the cache has been changed elsewhere and it has just been reloaded here! void loadingFinished(const CStatusMessageList &status, const CSimulatorInfo &simulator, LoadFinishedInfo info); + //! Relayed from centralized caches + //! \remark this can result from loading, the cache changed elsewhere or clearing data + void cacheChanged(const CSimulatorInfo &simulator); + protected: //! Constructor IAircraftModelLoader(const CSimulatorInfo &simulator, QObject *parent = nullptr); @@ -163,6 +168,9 @@ namespace BlackMisc //! Loading completed void onLoadingFinished(const CStatusMessageList &statusMsgs, const CSimulatorInfo &simulator, LoadFinishedInfo info); + + //! Cache has been changed + void onCacheChanged(const CSimulatorInfo &simulator); }; /*! @@ -193,6 +201,9 @@ namespace BlackMisc //! \copydoc IAircraftModelLoader::diskLoadingStarted void diskLoadingStarted(const CSimulatorInfo &simulator, IAircraftModelLoader::LoadMode mode); + //! \copydoc IAircraftModelLoader::cacheChanged + void cacheChanged(const CSimulatorInfo &simulator); + private: IAircraftModelLoader *m_loaderFsx = nullptr; IAircraftModelLoader *m_loaderP3D = nullptr; diff --git a/src/blackmisc/simulation/data/modelcaches.cpp b/src/blackmisc/simulation/data/modelcaches.cpp index 38badfe6e..52b84e61e 100644 --- a/src/blackmisc/simulation/data/modelcaches.cpp +++ b/src/blackmisc/simulation/data/modelcaches.cpp @@ -184,18 +184,19 @@ namespace BlackMisc CStatusMessage CModelCaches::setCachedModels(const CAircraftModelList &models, const CSimulatorInfo &simulator) { Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + CStatusMessage msg; switch (simulator.getSimulator()) { - case CSimulatorInfo::FS9: return m_modelCacheFs9.set(models); - case CSimulatorInfo::FSX: return m_modelCacheFsx.set(models); - case CSimulatorInfo::P3D: return m_modelCacheP3D.set(models); - case CSimulatorInfo::XPLANE: return m_modelCacheXP.set(models); + case CSimulatorInfo::FS9: msg = m_modelCacheFs9.set(models); break; + case CSimulatorInfo::FSX: msg = m_modelCacheFsx.set(models); break; + case CSimulatorInfo::P3D: msg = m_modelCacheP3D.set(models); break; + case CSimulatorInfo::XPLANE: msg = m_modelCacheXP.set(models); break; default: Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator"); return CStatusMessage(); } - - this->emitCacheChanged(simulator); + this->emitCacheChanged(simulator); // set + return msg; } CStatusMessage IMultiSimulatorModelCaches::clearCachedModels(const CSimulatorInfo &simulator) @@ -307,6 +308,7 @@ namespace BlackMisc Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator"); break; } + this->emitCacheChanged(simulator); // sync } void CModelCaches::admitCacheImpl(const CSimulatorInfo &simulator) @@ -375,18 +377,19 @@ namespace BlackMisc orderedModels.sortAscendingByOrder(); } + CStatusMessage msg; switch (simulator.getSimulator()) { - case CSimulatorInfo::FS9: return m_modelCacheFs9.set(orderedModels); - case CSimulatorInfo::FSX: return m_modelCacheFsx.set(orderedModels); - case CSimulatorInfo::P3D: return m_modelCacheP3D.set(orderedModels); - case CSimulatorInfo::XPLANE: return m_modelCacheXP.set(orderedModels); + case CSimulatorInfo::FS9: msg = m_modelCacheFs9.set(orderedModels); break; + case CSimulatorInfo::FSX: msg = m_modelCacheFsx.set(orderedModels); break; + case CSimulatorInfo::P3D: msg = m_modelCacheP3D.set(orderedModels); break; + case CSimulatorInfo::XPLANE: msg = m_modelCacheXP.set(orderedModels); break; default: Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator"); return CStatusMessage(); } - - this->emitCacheChanged(simulator); + this->emitCacheChanged(simulator); // set + return msg; } QDateTime CModelSetCaches::getCacheTimestamp(const CSimulatorInfo &simulator) const @@ -476,6 +479,7 @@ namespace BlackMisc Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong simulator"); break; } + this->emitCacheChanged(simulator); // sync } void CModelSetCaches::admitCacheImpl(const CSimulatorInfo &simulator) diff --git a/src/blackmisc/simulation/data/modelcaches.h b/src/blackmisc/simulation/data/modelcaches.h index 9b1d29ad7..06504290f 100644 --- a/src/blackmisc/simulation/data/modelcaches.h +++ b/src/blackmisc/simulation/data/modelcaches.h @@ -249,6 +249,7 @@ namespace BlackMisc signals: //! Cache has been changed + //! \note this detects caches changed elsewhere or set here (the normal caches detect only "elsewhere" void cacheChanged(const CSimulatorInfo &simulator); protected: @@ -367,7 +368,11 @@ namespace BlackMisc protected: //! Ctor - CCentralMultiSimulatorModelCachesProviderBase(QObject *parent = nullptr) : IMultiSimulatorModelCaches(parent) { } + CCentralMultiSimulatorModelCachesProviderBase(const QString &name, QObject *parent = nullptr) : IMultiSimulatorModelCaches(parent) + { + this->setObjectName(name); + connect(&m_caches, &IMultiSimulatorModelCaches::cacheChanged, this, &CCentralMultiSimulatorModelCachesProviderBase::cacheChanged); + } private: TCaches m_caches { false, this }; //!< used caches @@ -379,6 +384,7 @@ namespace BlackMisc const TCaches &instanceCaches() const { return this->isInstance() ? m_caches : Derived::modelCachesInstance().m_caches; } //! Is this object the central instance? + //! \remark would also allow do direct inherit this class bool isInstance() const { return this == &Derived::modelCachesInstance(); } }; @@ -393,13 +399,44 @@ namespace BlackMisc //! Central instance static CCentralMultiSimulatorModelCachesProvider &modelCachesInstance() { - static CCentralMultiSimulatorModelCachesProvider c; + static CCentralMultiSimulatorModelCachesProvider c("Central model caches provider"); return c; } protected: //! Ctor - CCentralMultiSimulatorModelCachesProvider(QObject *parent = nullptr) : CCentralMultiSimulatorModelCachesProviderBase(parent) {} + CCentralMultiSimulatorModelCachesProvider(const QString &name, QObject *parent = nullptr) : CCentralMultiSimulatorModelCachesProviderBase(name, parent) {} + }; + + //! Basically a QObject free (delegate based) version of CCentralMultiSimulatorModelCachesProvider + class BLACKMISC_EXPORT CCentralMultiSimulatorModelCachesAware: + public IModelsForSimulatorSetable, + public IModelsForSimulatorUpdatable + { + public: + //! \name Look like IMultiSimulatorModelCaches interface + //! @{ + CAircraftModelList getCachedModels(const CSimulatorInfo &simulator) const { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().getCachedModels(simulator); } + int getCachedModelsCount(const CSimulatorInfo &simulator) const { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().getCachedModelsCount(simulator); } + QString getCacheCountAndTimestamp(const CSimulatorInfo &simulator) const { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().getCacheCountAndTimestamp(simulator); } + CStatusMessage setCachedModels(const CAircraftModelList &models, const CSimulatorInfo &simulator) { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().setCachedModels(models, simulator); } + CStatusMessage clearCachedModels(const CSimulatorInfo &simulator) { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().clearCachedModels(simulator); } + QDateTime getCacheTimestamp(const CSimulatorInfo &simulator) const { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().getCacheTimestamp(simulator); } + CStatusMessage setCacheTimestamp(const QDateTime &ts, const CSimulatorInfo &simulator) { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().setCacheTimestamp(ts, simulator); } + void synchronizeCache(const CSimulatorInfo &simulator) { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().synchronizeCache(simulator); } + void admitCache(const CSimulatorInfo &simulator) { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().admitCache(simulator); } + QString getFilename(const CSimulatorInfo &simulator) const { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().getFilename(simulator); } + bool isSaved(const CSimulatorInfo &simulator) const { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().isSaved(simulator); } + QString getDescription() const { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().getDescription(); } + QString getInfoString() const { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().getInfoString(); } + QString getInfoStringFsFamily() const { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().getInfoStringFsFamily(); } + //! @} + + //! \copydoc IModelsForSimulatorSetable::setModelsForSimulator + virtual void setModelsForSimulator(const CAircraftModelList &models, const CSimulatorInfo &simulator) override { CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().setModelsForSimulator(models, simulator); } + + //! \copydoc IModelsForSimulatorUpdatable::updateModelsForSimulator + virtual int updateModelsForSimulator(const CAircraftModelList &models, const CSimulatorInfo &simulator) override { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().updateModelsForSimulator(models, simulator); } }; //! One central instance of the model set caches @@ -413,13 +450,13 @@ namespace BlackMisc //! Central instance static CCentralMultiSimulatorModelSetCachesProvider &modelCachesInstance() { - static CCentralMultiSimulatorModelSetCachesProvider c; + static CCentralMultiSimulatorModelSetCachesProvider c("Central model sets provider"); return c; } protected: //! Ctor - CCentralMultiSimulatorModelSetCachesProvider(QObject *parent = nullptr) : CCentralMultiSimulatorModelCachesProviderBase(parent) {} + CCentralMultiSimulatorModelSetCachesProvider(const QString &name, QObject *parent = nullptr) : CCentralMultiSimulatorModelCachesProviderBase(name, parent) {} }; //! Basically a QObject free (delegate based) version of CCentralMultiSimulatorModelSetCachesProvider @@ -432,7 +469,9 @@ namespace BlackMisc //! @{ CAircraftModelList getCachedModels(const CSimulatorInfo &simulator) const { return CCentralMultiSimulatorModelSetCachesProvider::modelCachesInstance().getCachedModels(simulator); } int getCachedModelsCount(const CSimulatorInfo &simulator) const { return CCentralMultiSimulatorModelSetCachesProvider::modelCachesInstance().getCachedModelsCount(simulator); } + QString getCacheCountAndTimestamp(const CSimulatorInfo &simulator) const { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().getCacheCountAndTimestamp(simulator); } CStatusMessage setCachedModels(const CAircraftModelList &models, const CSimulatorInfo &simulator) { return CCentralMultiSimulatorModelSetCachesProvider::modelCachesInstance().setCachedModels(models, simulator); } + CStatusMessage clearCachedModels(const CSimulatorInfo &simulator) { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().clearCachedModels(simulator); } QDateTime getCacheTimestamp(const CSimulatorInfo &simulator) const { return CCentralMultiSimulatorModelSetCachesProvider::modelCachesInstance().getCacheTimestamp(simulator); } CStatusMessage setCacheTimestamp(const QDateTime &ts, const CSimulatorInfo &simulator) { return CCentralMultiSimulatorModelSetCachesProvider::modelCachesInstance().setCacheTimestamp(ts, simulator); } void synchronizeCache(const CSimulatorInfo &simulator) { return CCentralMultiSimulatorModelSetCachesProvider::modelCachesInstance().synchronizeCache(simulator); } @@ -440,6 +479,8 @@ namespace BlackMisc QString getFilename(const CSimulatorInfo &simulator) const { return CCentralMultiSimulatorModelSetCachesProvider::modelCachesInstance().getFilename(simulator); } bool isSaved(const CSimulatorInfo &simulator) const { return CCentralMultiSimulatorModelSetCachesProvider::modelCachesInstance().isSaved(simulator); } QString getDescription() const { return CCentralMultiSimulatorModelSetCachesProvider::modelCachesInstance().getDescription(); } + QString getInfoString() const { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().getInfoString(); } + QString getInfoStringFsFamily() const { return CCentralMultiSimulatorModelCachesProvider::modelCachesInstance().getInfoStringFsFamily(); } //! @} //! \copydoc IModelsForSimulatorSetable::setModelsForSimulator