mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-27 11:05:44 +08:00
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
This commit is contained in:
@@ -542,9 +542,9 @@ namespace BlackGui
|
|||||||
|
|
||||||
void CDbMappingComponent::ps_onStashedModelsChanged()
|
void CDbMappingComponent::ps_onStashedModelsChanged()
|
||||||
{
|
{
|
||||||
bool hlvp = this->ui->tvp_AircraftModelsForVPilot->derivedModel()->highlightModelStrings();
|
const bool hlvp = this->ui->tvp_AircraftModelsForVPilot->derivedModel()->highlightModelStrings();
|
||||||
bool hlom = this->ui->tvp_OwnAircraftModels->derivedModel()->highlightModelStrings();
|
const bool hlom = this->ui->tvp_OwnAircraftModels->derivedModel()->highlightModelStrings();
|
||||||
bool highlight = hlom || hlvp;
|
const bool highlight = hlom || hlvp;
|
||||||
if (!highlight) { return; }
|
if (!highlight) { return; }
|
||||||
const QStringList stashedModels(this->ui->comp_StashAircraft->getStashedModelStrings());
|
const QStringList stashedModels(this->ui->comp_StashAircraft->getStashedModelStrings());
|
||||||
if (hlvp)
|
if (hlvp)
|
||||||
@@ -602,13 +602,9 @@ namespace BlackGui
|
|||||||
this->ui->tw_ModelsToBeMapped->setTabText(i, o);
|
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<QAction *>(QObject::sender());
|
this->ps_loadInstalledModels(simInfo, mode);
|
||||||
if (!a) { return; }
|
|
||||||
int f = a->data().toInt();
|
|
||||||
CSimulatorInfo sim(f);
|
|
||||||
this->ps_loadInstalledModels(sim);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDbMappingComponent::ps_userChanged()
|
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))
|
if (!this->initModelLoader(simInfo))
|
||||||
{
|
{
|
||||||
@@ -694,7 +690,8 @@ namespace BlackGui
|
|||||||
|
|
||||||
CLogMessage(this).info("Starting loading for %1") << simInfo.toQString();
|
CLogMessage(this).info("Starting loading for %1") << simInfo.toQString();
|
||||||
this->ui->tvp_OwnAircraftModels->showLoadIndicator();
|
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)
|
void CDbMappingComponent::ps_onOwnModelsLoadingFinished(bool success, const CSimulatorInfo &simInfo)
|
||||||
@@ -702,9 +699,10 @@ namespace BlackGui
|
|||||||
if (success && this->m_modelLoader)
|
if (success && this->m_modelLoader)
|
||||||
{
|
{
|
||||||
const CAircraftModelList models(this->m_modelLoader->getAircraftModels());
|
const CAircraftModelList models(this->m_modelLoader->getAircraftModels());
|
||||||
|
const int modelsLoaded = models.size();
|
||||||
this->ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(models);
|
this->ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(models);
|
||||||
CLogMessage(this).info("Loading %1 of models completed") << models.size();
|
if (modelsLoaded > 0)
|
||||||
|
{
|
||||||
// store for later
|
// store for later
|
||||||
Data::CDbMappingComponent mc(this->m_lastInteractions.get());
|
Data::CDbMappingComponent mc(this->m_lastInteractions.get());
|
||||||
if (simInfo.isSingleSimulator() && mc.getLastSimulatorSelection() != simInfo)
|
if (simInfo.isSingleSimulator() && mc.getLastSimulatorSelection() != simInfo)
|
||||||
@@ -714,6 +712,12 @@ namespace BlackGui
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// loading ok, but no data
|
||||||
|
CLogMessage(this).warning("Loading completed, but no models");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
this->ui->tvp_OwnAircraftModels->hideLoadIndicator();
|
this->ui->tvp_OwnAircraftModels->hideLoadIndicator();
|
||||||
CLogMessage(this).error("Loading of models failed, simulator %1") << simInfo.toQString();
|
CLogMessage(this).error("Loading of models failed, simulator %1") << simInfo.toQString();
|
||||||
@@ -758,29 +762,69 @@ namespace BlackGui
|
|||||||
{
|
{
|
||||||
this->addSeparator(menu);
|
this->addSeparator(menu);
|
||||||
QMenu *load = menu.addMenu(CIcons::appModels16(), "Load installed models");
|
QMenu *load = menu.addMenu(CIcons::appModels16(), "Load installed models");
|
||||||
QAction *a = nullptr;
|
|
||||||
CDbMappingComponent *mapComp = qobject_cast<CDbMappingComponent *>(this->parent());
|
CDbMappingComponent *mapComp = qobject_cast<CDbMappingComponent *>(this->parent());
|
||||||
Q_ASSERT_X(mapComp, Q_FUNC_INFO, "Cannot access parent");
|
Q_ASSERT_X(mapComp, Q_FUNC_INFO, "Cannot access parent");
|
||||||
|
|
||||||
if (sims.fs9())
|
if (sims.fs9())
|
||||||
{
|
{
|
||||||
a = load->addAction(CIcons::appModels16(), "FS9 models", mapComp, SLOT(ps_requestSimulatorModels()));
|
load->addAction(CIcons::appModels16(), "FS9 models", mapComp, [mapComp]()
|
||||||
a->setData(QVariant(static_cast<int>(CSimulatorInfo::FS9)));
|
{
|
||||||
|
mapComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::FSX), IAircraftModelLoader::InBackgroundWithCache);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (sims.fsx())
|
if (sims.fsx())
|
||||||
{
|
{
|
||||||
a = load->addAction(CIcons::appModels16(), "FSX models", mapComp, SLOT(ps_requestSimulatorModels()));
|
load->addAction(CIcons::appModels16(), "P3D models", mapComp, [mapComp]()
|
||||||
a->setData(QVariant(static_cast<int>(CSimulatorInfo::FSX)));
|
{
|
||||||
|
mapComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::P3D), IAircraftModelLoader::InBackgroundWithCache);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (sims.p3d())
|
if (sims.p3d())
|
||||||
{
|
{
|
||||||
a = load->addAction(CIcons::appModels16(), "P3D models", mapComp, SLOT(ps_requestSimulatorModels()));
|
load->addAction(CIcons::appModels16(), "FS9 models", mapComp, [mapComp]()
|
||||||
a->setData(QVariant(static_cast<int>(CSimulatorInfo::P3D)));
|
{
|
||||||
|
mapComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::FS9), IAircraftModelLoader::InBackgroundWithCache);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (sims.xplane())
|
if (sims.xplane())
|
||||||
{
|
{
|
||||||
a = load->addAction(CIcons::appModels16(), "XPlane models", mapComp, SLOT(ps_requestSimulatorModels()));
|
load->addAction(CIcons::appModels16(), "XP models", mapComp, [mapComp]()
|
||||||
a->setData(QVariant(static_cast<int>(CSimulatorInfo::XPLANE)));
|
{
|
||||||
|
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);
|
this->nestedCustomMenu(menu);
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ namespace BlackGui
|
|||||||
void ps_onModelRowSelected(const QModelIndex &index);
|
void ps_onModelRowSelected(const QModelIndex &index);
|
||||||
|
|
||||||
//! Load the models
|
//! 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
|
//! Model loading finished
|
||||||
void ps_onOwnModelsLoadingFinished(bool success, const BlackMisc::Simulation::CSimulatorInfo &simInfo);
|
void ps_onOwnModelsLoadingFinished(bool success, const BlackMisc::Simulation::CSimulatorInfo &simInfo);
|
||||||
@@ -186,7 +186,7 @@ namespace BlackGui
|
|||||||
void ps_onOwnModelsCountChanged(int count, bool withFilter);
|
void ps_onOwnModelsCountChanged(int count, bool withFilter);
|
||||||
|
|
||||||
//! Request simulator models
|
//! Request simulator models
|
||||||
void ps_requestSimulatorModels();
|
void ps_requestSimulatorModels(const BlackMisc::Simulation::CSimulatorInfo &simInfo, BlackMisc::Simulation::IAircraftModelLoader::LoadMode mode);
|
||||||
|
|
||||||
//! User object changed
|
//! User object changed
|
||||||
void ps_userChanged();
|
void ps_userChanged();
|
||||||
|
|||||||
@@ -266,6 +266,11 @@ namespace BlackMisc
|
|||||||
return this->m_aircraftIcao.hasDesignator();
|
return this->m_aircraftIcao.hasDesignator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CAircraftModel::hasKnownAircraftDesignator() const
|
||||||
|
{
|
||||||
|
return this->m_aircraftIcao.hasKnownDesignator();
|
||||||
|
}
|
||||||
|
|
||||||
bool CAircraftModel::hasAirlineDesignator() const
|
bool CAircraftModel::hasAirlineDesignator() const
|
||||||
{
|
{
|
||||||
return this->m_livery.hasValidAirlineDesignator();
|
return this->m_livery.hasValidAirlineDesignator();
|
||||||
@@ -291,9 +296,9 @@ namespace BlackMisc
|
|||||||
this->setModelMode(CAircraftModel::modelModeFromString(mode));
|
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
|
// 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
|
// so we change roles. We take the DB object as base, and update our parts
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ namespace BlackMisc
|
|||||||
//! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex
|
//! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex
|
||||||
void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index);
|
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;
|
int comparePropertyByIndex(const CAircraftModel &compareValue, const CPropertyIndex &index) const;
|
||||||
|
|
||||||
//! Can be initialized from FSD
|
//! Can be initialized from FSD
|
||||||
@@ -153,6 +153,9 @@ namespace BlackMisc
|
|||||||
//! Has aircraft designator?
|
//! Has aircraft designator?
|
||||||
bool hasAircraftDesignator() const;
|
bool hasAircraftDesignator() const;
|
||||||
|
|
||||||
|
//! Has known aircraft designator?
|
||||||
|
bool hasKnownAircraftDesignator() const;
|
||||||
|
|
||||||
//! Airline designator?
|
//! Airline designator?
|
||||||
bool hasAirlineDesignator() const;
|
bool hasAirlineDesignator() const;
|
||||||
|
|
||||||
@@ -217,7 +220,7 @@ namespace BlackMisc
|
|||||||
void setFileName(const QString &fileName) { m_fileName = fileName; }
|
void setFileName(const QString &fileName) { m_fileName = fileName; }
|
||||||
|
|
||||||
//! Update missing parts from another model
|
//! Update missing parts from another model
|
||||||
void updateMissingParts(const CAircraftModel &otherModel);
|
void updateMissingParts(const CAircraftModel &otherModel, bool dbModelPriority = true);
|
||||||
|
|
||||||
//! Queried model string?
|
//! Queried model string?
|
||||||
bool hasQueriedModelString() const;
|
bool hasQueriedModelString() const;
|
||||||
|
|||||||
@@ -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)
|
void CAircraftModelList::setSimulatorInfo(const CSimulatorInfo &info)
|
||||||
{
|
{
|
||||||
for (CAircraftModel &model : (*this))
|
for (CAircraftModel &model : (*this))
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ namespace BlackMisc
|
|||||||
bool containsModelStringOrId(const BlackMisc::Simulation::CAircraftModel &model, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive) const;
|
bool containsModelStringOrId(const BlackMisc::Simulation::CAircraftModel &model, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive) const;
|
||||||
|
|
||||||
//! Find by model string
|
//! Find by model string
|
||||||
|
//! \remark normally CAircraftModelList::findFirstByModelString would be used
|
||||||
CAircraftModelList findByModelString(const QString &modelString, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive) const;
|
CAircraftModelList findByModelString(const QString &modelString, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive) const;
|
||||||
|
|
||||||
//! Find first by model string
|
//! Find first by model string
|
||||||
@@ -67,6 +68,18 @@ namespace BlackMisc
|
|||||||
//! With file name
|
//! With file name
|
||||||
CAircraftModelList findWithFileName() const;
|
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
|
//! Set simulator for all elements
|
||||||
void setSimulatorInfo(const BlackMisc::Simulation::CSimulatorInfo &info);
|
void setSimulatorInfo(const BlackMisc::Simulation::CSimulatorInfo &info);
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,23 @@ namespace BlackMisc
|
|||||||
return dir.exists();
|
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)
|
void IAircraftModelLoader::ps_loadFinished(bool success)
|
||||||
{
|
{
|
||||||
Q_UNUSED(success);
|
Q_UNUSED(success);
|
||||||
@@ -53,7 +70,7 @@ namespace BlackMisc
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IAircraftModelLoader::startLoading(LoadMode mode)
|
void IAircraftModelLoader::startLoading(LoadMode mode, const CAircraftModelList &dbModels)
|
||||||
{
|
{
|
||||||
if (this->m_loadingInProgress) { return; }
|
if (this->m_loadingInProgress) { return; }
|
||||||
this->m_loadingInProgress = true;
|
this->m_loadingInProgress = true;
|
||||||
@@ -65,6 +82,7 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
else if (useCachedData && mode.testFlag(CacheUntilNewer))
|
else if (useCachedData && mode.testFlag(CacheUntilNewer))
|
||||||
{
|
{
|
||||||
|
//! \todo currently too slow, does not make sense with that overhead
|
||||||
if (!this->areModelFilesUpdated())
|
if (!this->areModelFilesUpdated())
|
||||||
{
|
{
|
||||||
emit loadingFinished(true, this->m_simulatorInfo);
|
emit loadingFinished(true, this->m_simulatorInfo);
|
||||||
@@ -77,7 +95,7 @@ namespace BlackMisc
|
|||||||
emit loadingFinished(false, this->m_simulatorInfo);
|
emit loadingFinished(false, this->m_simulatorInfo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->startLoadingFromDisk(mode);
|
this->startLoadingFromDisk(mode, dbModels);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CSimulatorInfo &IAircraftModelLoader::supportedSimulators() const
|
const CSimulatorInfo &IAircraftModelLoader::supportedSimulators() const
|
||||||
|
|||||||
@@ -43,15 +43,17 @@ namespace BlackMisc
|
|||||||
CacheFirst = 1 << 3, //!< always use cache (if it has data)
|
CacheFirst = 1 << 3, //!< always use cache (if it has data)
|
||||||
CacheSkipped = 1 << 4, //!< ignore cache
|
CacheSkipped = 1 << 4, //!< ignore cache
|
||||||
CacheOnly = 1 << 5, //!< only read cache, never load from disk
|
CacheOnly = 1 << 5, //!< only read cache, never load from disk
|
||||||
Default = LoadInBackground | CacheFirst //!< default mode
|
InBackgroundWithCache = LoadInBackground | CacheFirst, //!< Background, cached
|
||||||
|
InBackgroundNoCache = LoadInBackground | CacheSkipped //!< Background, not cached
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(LoadMode, LoadModeFlag)
|
Q_DECLARE_FLAGS(LoadMode, LoadModeFlag)
|
||||||
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
virtual ~IAircraftModelLoader();
|
virtual ~IAircraftModelLoader();
|
||||||
|
|
||||||
//! Start the loading process from disk
|
//! Start the loading process from disk.
|
||||||
void startLoading(LoadMode mode = Default);
|
//! Optional DB models can be passed and used for data consolidation.
|
||||||
|
void startLoading(LoadMode mode = InBackgroundWithCache, const CAircraftModelList &dbModels = {});
|
||||||
|
|
||||||
//! Change the directory
|
//! Change the directory
|
||||||
bool changeRootDirectory(const QString &directory);
|
bool changeRootDirectory(const QString &directory);
|
||||||
@@ -65,6 +67,9 @@ namespace BlackMisc
|
|||||||
//! The loaded models
|
//! The loaded models
|
||||||
virtual const BlackMisc::Simulation::CAircraftModelList &getAircraftModels() const = 0;
|
virtual const BlackMisc::Simulation::CAircraftModelList &getAircraftModels() const = 0;
|
||||||
|
|
||||||
|
//! Count of loaded models
|
||||||
|
const int getAircraftModelsCount() const { return getAircraftModels().size(); }
|
||||||
|
|
||||||
//! Cache timestamp
|
//! Cache timestamp
|
||||||
virtual QDateTime getCacheTimestamp() const = 0;
|
virtual QDateTime getCacheTimestamp() const = 0;
|
||||||
|
|
||||||
@@ -107,7 +112,10 @@ namespace BlackMisc
|
|||||||
bool existsDir(const QString &directory) const;
|
bool existsDir(const QString &directory) const;
|
||||||
|
|
||||||
//! Start the loading process from disk
|
//! 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
|
BlackMisc::Simulation::CSimulatorInfo m_simulatorInfo; //!< Corresponding simulator
|
||||||
std::atomic<bool> m_cancelLoading { false }; //!< flag
|
std::atomic<bool> m_cancelLoading { false }; //!< flag
|
||||||
|
|||||||
@@ -19,10 +19,8 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
namespace Simulation
|
namespace Simulation
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace FsCommon
|
namespace FsCommon
|
||||||
{
|
{
|
||||||
|
|
||||||
bool CAircraftCfgEntriesList::containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity)
|
bool CAircraftCfgEntriesList::containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity)
|
||||||
{
|
{
|
||||||
if (title.isEmpty()) { return false; }
|
if (title.isEmpty()) { return false; }
|
||||||
@@ -61,9 +59,9 @@ namespace BlackMisc
|
|||||||
CAircraftModelList CAircraftCfgEntriesList::toAircraftModelList() const
|
CAircraftModelList CAircraftCfgEntriesList::toAircraftModelList() const
|
||||||
{
|
{
|
||||||
CAircraftModelList ml;
|
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;
|
return ml;
|
||||||
}
|
}
|
||||||
@@ -71,9 +69,9 @@ namespace BlackMisc
|
|||||||
CAircraftModelList CAircraftCfgEntriesList::toAircraftModelList(const CSimulatorInfo &simInfo) const
|
CAircraftModelList CAircraftCfgEntriesList::toAircraftModelList(const CSimulatorInfo &simInfo) const
|
||||||
{
|
{
|
||||||
CAircraftModelList ml;
|
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);
|
m.setSimulatorInfo(simInfo);
|
||||||
ml.push_back(m);
|
ml.push_back(m);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
#include "blackmisc/predicates.h"
|
#include "blackmisc/predicates.h"
|
||||||
#include "blackmisc/logmessage.h"
|
#include "blackmisc/logmessage.h"
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
using namespace BlackMisc;
|
using namespace BlackMisc;
|
||||||
using namespace BlackMisc::Simulation;
|
using namespace BlackMisc::Simulation;
|
||||||
using namespace BlackMisc::Simulation::FsCommon;
|
using namespace BlackMisc::Simulation::FsCommon;
|
||||||
@@ -24,6 +26,9 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
namespace FsCommon
|
namespace FsCommon
|
||||||
{
|
{
|
||||||
|
// response for async. loading
|
||||||
|
using LoaderResponse = std::tuple<CAircraftCfgEntriesList, CAircraftModelList, bool>;
|
||||||
|
|
||||||
CAircraftCfgParser::CAircraftCfgParser(const CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &excludeDirs) :
|
CAircraftCfgParser::CAircraftCfgParser(const CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &excludeDirs) :
|
||||||
IAircraftModelLoader(simInfo, rootDirectory, excludeDirs)
|
IAircraftModelLoader(simInfo, rootDirectory, excludeDirs)
|
||||||
{ }
|
{ }
|
||||||
@@ -89,7 +94,7 @@ namespace BlackMisc
|
|||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAircraftCfgParser::startLoadingFromDisk(LoadMode mode)
|
void CAircraftCfgParser::startLoadingFromDisk(LoadMode mode, const CAircraftModelList &dbModels)
|
||||||
{
|
{
|
||||||
if (mode.testFlag(LoadInBackground))
|
if (mode.testFlag(LoadInBackground))
|
||||||
{
|
{
|
||||||
@@ -97,19 +102,36 @@ namespace BlackMisc
|
|||||||
const QString rootDirectory(m_rootDirectory); // copy
|
const QString rootDirectory(m_rootDirectory); // copy
|
||||||
const QStringList excludedDirectories(m_excludedDirectories); // copy
|
const QStringList excludedDirectories(m_excludedDirectories); // copy
|
||||||
m_parserWorker = BlackMisc::CWorker::fromTask(this, "CAircraftCfgParser::changeDirectory",
|
m_parserWorker = BlackMisc::CWorker::fromTask(this, "CAircraftCfgParser::changeDirectory",
|
||||||
[this, rootDirectory, excludedDirectories]()
|
[this, rootDirectory, excludedDirectories, dbModels]()
|
||||||
{
|
{
|
||||||
bool ok;
|
bool ok = false;
|
||||||
auto aircraftCfgEntriesList = this->performParsing(rootDirectory, excludedDirectories, &ok);
|
const auto aircraftCfgEntriesList = this->performParsing(rootDirectory, excludedDirectories, &ok);
|
||||||
return std::make_pair(aircraftCfgEntriesList, ok);
|
CAircraftModelList models;
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
models = (aircraftCfgEntriesList.toAircraftModelList(this->supportedSimulators()));
|
||||||
|
this->mergeWithDbData(models, dbModels);
|
||||||
|
}
|
||||||
|
return std::make_tuple(aircraftCfgEntriesList, models, ok);
|
||||||
});
|
});
|
||||||
m_parserWorker->thenWithResult<std::pair<CAircraftCfgEntriesList, bool>>(this, [this](const auto &pair)
|
m_parserWorker->thenWithResult<LoaderResponse>(this, [this](const LoaderResponse & tuple)
|
||||||
{
|
{
|
||||||
if (pair.second)
|
const bool ok = std::get<2>(tuple);
|
||||||
|
if (ok)
|
||||||
{
|
{
|
||||||
this->m_parsedCfgEntriesList = pair.first;
|
this->m_parsedCfgEntriesList = std::get<0>(tuple);
|
||||||
this->setModelsInCache(pair.first.toAircraftModelList());
|
const CAircraftModelList models(std::get<1>(tuple));
|
||||||
emit loadingFinished(true, this->m_simulatorInfo);
|
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;
|
bool ok;
|
||||||
this->m_parsedCfgEntriesList = performParsing(m_rootDirectory, m_excludedDirectories, &ok);
|
this->m_parsedCfgEntriesList = performParsing(m_rootDirectory, m_excludedDirectories, &ok);
|
||||||
this->setModelsInCache(this->m_parsedCfgEntriesList.toAircraftModelList());
|
CAircraftModelList models(this->m_parsedCfgEntriesList.toAircraftModelList(this->supportedSimulators()));
|
||||||
emit loadingFinished(ok, this->m_simulatorInfo);
|
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 (m_cancelLoading) { return CAircraftCfgEntriesList(); }
|
||||||
if (file.isDir())
|
if (file.isDir())
|
||||||
{
|
{
|
||||||
QString nextDir = file.absoluteFilePath();
|
const QString nextDir = file.absoluteFilePath();
|
||||||
if (currentDir.startsWith(nextDir, Qt::CaseInsensitive)) { continue; } // do not go up
|
if (currentDir.startsWith(nextDir, Qt::CaseInsensitive)) { continue; } // do not go up
|
||||||
if (dir == currentDir) { continue; } // do not recursively call same directory
|
if (dir == currentDir) { continue; } // do not recursively call same directory
|
||||||
|
|
||||||
@@ -414,7 +443,7 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
else if (static_cast<QMetaType::Type>(qv.type()) == QMetaType::QStringList)
|
else if (static_cast<QMetaType::Type>(qv.type()) == QMetaType::QStringList)
|
||||||
{
|
{
|
||||||
QStringList l = qv.toStringList();
|
const QStringList l = qv.toStringList();
|
||||||
return l.join(",").trimmed();
|
return l.join(",").trimmed();
|
||||||
}
|
}
|
||||||
else if (static_cast<QMetaType::Type>(qv.type()) == QMetaType::QString)
|
else if (static_cast<QMetaType::Type>(qv.type()) == QMetaType::QString)
|
||||||
@@ -453,3 +482,5 @@ namespace BlackMisc
|
|||||||
} // namespace
|
} // namespace
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(BlackMisc::Simulation::FsCommon::LoaderResponse)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace BlackMisc
|
|||||||
|
|
||||||
//! \name Interface functions
|
//! \name Interface functions
|
||||||
//! @{
|
//! @{
|
||||||
virtual void startLoadingFromDisk(LoadMode mode) override;
|
virtual void startLoadingFromDisk(LoadMode mode, const BlackMisc::Simulation::CAircraftModelList &dbModels) override;
|
||||||
//! @}
|
//! @}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace BlackMisc
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAircraftModelLoaderXPlane::startLoadingFromDisk(LoadMode mode)
|
void CAircraftModelLoaderXPlane::startLoadingFromDisk(LoadMode mode, const CAircraftModelList &dbModels)
|
||||||
{
|
{
|
||||||
m_installedModels.clear();
|
m_installedModels.clear();
|
||||||
if (m_rootDirectory.isEmpty())
|
if (m_rootDirectory.isEmpty())
|
||||||
@@ -77,9 +77,10 @@ namespace BlackMisc
|
|||||||
auto rootDirectory = m_rootDirectory;
|
auto rootDirectory = m_rootDirectory;
|
||||||
auto excludedDirectories = m_excludedDirectories;
|
auto excludedDirectories = m_excludedDirectories;
|
||||||
m_parserWorker = BlackMisc::CWorker::fromTask(this, "CAircraftModelLoaderXPlane::performParsing",
|
m_parserWorker = BlackMisc::CWorker::fromTask(this, "CAircraftModelLoaderXPlane::performParsing",
|
||||||
[this, rootDirectory, excludedDirectories]()
|
[this, rootDirectory, excludedDirectories, dbModels]()
|
||||||
{
|
{
|
||||||
auto models = performParsing(rootDirectory, excludedDirectories);
|
auto models = performParsing(rootDirectory, excludedDirectories);
|
||||||
|
mergeWithDbData(models, dbModels);
|
||||||
return models;
|
return models;
|
||||||
});
|
});
|
||||||
m_parserWorker->thenWithResult<CAircraftModelList>(this, [this](const auto & models)
|
m_parserWorker->thenWithResult<CAircraftModelList>(this, [this](const auto & models)
|
||||||
@@ -90,6 +91,7 @@ namespace BlackMisc
|
|||||||
else if (mode.testFlag(LoadDirectly))
|
else if (mode.testFlag(LoadDirectly))
|
||||||
{
|
{
|
||||||
m_installedModels = performParsing(m_rootDirectory, m_excludedDirectories);
|
m_installedModels = performParsing(m_rootDirectory, m_excludedDirectories);
|
||||||
|
mergeWithDbData(m_installedModels, dbModels);
|
||||||
emit loadingFinished(true, this->m_simulatorInfo);
|
emit loadingFinished(true, this->m_simulatorInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace BlackMisc
|
|||||||
protected:
|
protected:
|
||||||
//! \name Interface functions
|
//! \name Interface functions
|
||||||
//! @{
|
//! @{
|
||||||
virtual void startLoadingFromDisk(LoadMode mode) override;
|
virtual void startLoadingFromDisk(LoadMode mode, const BlackMisc::Simulation::CAircraftModelList &dbModels) override;
|
||||||
//! @}
|
//! @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user