mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-17 19:05:31 +08:00
refs #619, change model loader to use caches (one per simulator)
* removed caching from GUI component * added caches in model loader * adjusted samples
This commit is contained in:
@@ -15,6 +15,8 @@
|
|||||||
#include "blackmisc/simulation/fscommon/aircraftcfgentrieslist.h"
|
#include "blackmisc/simulation/fscommon/aircraftcfgentrieslist.h"
|
||||||
#include "blackmisc/simulation/fscommon/aircraftcfgparser.h"
|
#include "blackmisc/simulation/fscommon/aircraftcfgparser.h"
|
||||||
#include "blackmisc/simulation/aircraftmatcher.h"
|
#include "blackmisc/simulation/aircraftmatcher.h"
|
||||||
|
#include "blackmisc/simulation/simulatorinfo.h"
|
||||||
|
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
@@ -24,16 +26,17 @@
|
|||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
|
||||||
using namespace BlackMisc;
|
using namespace BlackMisc;
|
||||||
|
using namespace BlackMisc::Simulation;
|
||||||
using namespace BlackMisc::Simulation::FsCommon;
|
using namespace BlackMisc::Simulation::FsCommon;
|
||||||
|
|
||||||
namespace BlackSample
|
namespace BlackSample
|
||||||
{
|
{
|
||||||
void CSamplesFsCommon::samples(QTextStream &streamOut, QTextStream &streamIn)
|
void CSamplesFsCommon::samples(QTextStream &streamOut, QTextStream &streamIn)
|
||||||
{
|
{
|
||||||
QString fsxDir = CSampleUtils::selectDirectory({"C:/Program Files (x86)/Microsoft Games/Microsoft Flight Simulator X/SimObjects",
|
const QString fsxDir = CSampleUtils::selectDirectory({"C:/Program Files (x86)/Microsoft Games/Microsoft Flight Simulator X/SimObjects",
|
||||||
"C:/Flight Simulator 9/Aircraft"}, streamOut, streamIn);
|
"C:/Flight Simulator 9/Aircraft"}, streamOut, streamIn);
|
||||||
|
|
||||||
CAircraftCfgParser parser;
|
CAircraftCfgParser parser(CSimulatorInfo(CSimulatorInfo::FSX), fsxDir);
|
||||||
parser.changeRootDirectory(fsxDir);
|
parser.changeRootDirectory(fsxDir);
|
||||||
|
|
||||||
streamOut << "start reading, press RETURN" << endl;
|
streamOut << "start reading, press RETURN" << endl;
|
||||||
|
|||||||
@@ -43,12 +43,12 @@ namespace BlackSample
|
|||||||
streamOut << "loaded: " << BlackMisc::boolToYesNo(s) << " size: " << cvm->getDatastoreModels().size() << endl;
|
streamOut << "loaded: " << BlackMisc::boolToYesNo(s) << " size: " << cvm->getDatastoreModels().size() << endl;
|
||||||
|
|
||||||
// mapper with rule set, handing over ownership
|
// mapper with rule set, handing over ownership
|
||||||
CAircraftCfgParser cfgParser;
|
|
||||||
QString fsxDir = CSampleUtils::selectDirectory({QStringLiteral("P:/FlightSimulatorX (MSI)/SimObjects"),
|
QString fsxDir = CSampleUtils::selectDirectory({QStringLiteral("P:/FlightSimulatorX (MSI)/SimObjects"),
|
||||||
QStringLiteral("P:/Temp/SimObjects"),
|
QStringLiteral("P:/Temp/SimObjects"),
|
||||||
QStringLiteral("C:/Flight Simulator 9/Aircraft")
|
QStringLiteral("C:/Flight Simulator 9/Aircraft")
|
||||||
}, streamOut, streamIn);
|
}, streamOut, streamIn);
|
||||||
|
|
||||||
|
CAircraftCfgParser cfgParser(CSimulatorInfo(CSimulatorInfo::FSX), fsxDir);
|
||||||
if (!cfgParser.changeRootDirectory(fsxDir))
|
if (!cfgParser.changeRootDirectory(fsxDir))
|
||||||
{
|
{
|
||||||
streamOut << "Wrong or empty directoy " << fsxDir << endl;
|
streamOut << "Wrong or empty directoy " << fsxDir << endl;
|
||||||
@@ -56,7 +56,7 @@ namespace BlackSample
|
|||||||
}
|
}
|
||||||
|
|
||||||
streamOut << "Start reading models" << endl;
|
streamOut << "Start reading models" << endl;
|
||||||
cfgParser.startLoading(CAircraftCfgParser::ModeBlocking);
|
cfgParser.startLoading(CAircraftCfgParser::CacheSkipped | CAircraftCfgParser::LoadDirectly);
|
||||||
streamOut << "Read models: " << cfgParser.getAircraftCfgEntriesList().size() << endl;
|
streamOut << "Read models: " << cfgParser.getAircraftCfgEntriesList().size() << endl;
|
||||||
streamOut << "Ambigious models: " << cfgParser.getAircraftCfgEntriesList().detectAmbiguousTitles().join(", ") << endl;
|
streamOut << "Ambigious models: " << cfgParser.getAircraftCfgEntriesList().detectAmbiguousTitles().join(", ") << endl;
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,10 @@ namespace BlackGui
|
|||||||
ui->tvp_OwnAircraftModels->setCustomMenu(new CShowSimulatorFile(this), false);
|
ui->tvp_OwnAircraftModels->setCustomMenu(new CShowSimulatorFile(this), false);
|
||||||
ui->tvp_OwnAircraftModels->setCustomMenu(new CMappingOwnSimulatorModelMenu(this));
|
ui->tvp_OwnAircraftModels->setCustomMenu(new CMappingOwnSimulatorModelMenu(this));
|
||||||
ui->tvp_OwnAircraftModels->setCustomMenu(new CModelStashTools(this, false));
|
ui->tvp_OwnAircraftModels->setCustomMenu(new CModelStashTools(this, false));
|
||||||
ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(this->m_cachedOwnModels.get());
|
if (this->m_modelLoader)
|
||||||
|
{
|
||||||
|
ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(this->m_modelLoader->getAircraftModels());
|
||||||
|
}
|
||||||
|
|
||||||
// how to display forms
|
// how to display forms
|
||||||
ui->editor_AircraftIcao->setSelectOnly();
|
ui->editor_AircraftIcao->setSelectOnly();
|
||||||
@@ -107,9 +110,9 @@ namespace BlackGui
|
|||||||
this->ui->tvp_AircraftModelsForVPilot->setCustomMenu(new CModelStashTools(this, false));
|
this->ui->tvp_AircraftModelsForVPilot->setCustomMenu(new CModelStashTools(this, false));
|
||||||
this->ui->tvp_AircraftModelsForVPilot->setDisplayAutomatically(true);
|
this->ui->tvp_AircraftModelsForVPilot->setDisplayAutomatically(true);
|
||||||
this->ui->tvp_AircraftModelsForVPilot->addFilterDialog();
|
this->ui->tvp_AircraftModelsForVPilot->addFilterDialog();
|
||||||
const CAircraftModelList cachedModels(m_cachedVPilotModels.get());
|
const CAircraftModelList vPilotModels(m_cachedVPilotModels.get());
|
||||||
this->ui->tvp_AircraftModelsForVPilot->updateContainerMaybeAsync(cachedModels);
|
this->ui->tvp_AircraftModelsForVPilot->updateContainerMaybeAsync(vPilotModels);
|
||||||
int noModels = cachedModels.size();
|
int noModels = vPilotModels.size();
|
||||||
CLogMessage(this).info("%1 cached vPilot models loaded") << noModels;
|
CLogMessage(this).info("%1 cached vPilot models loaded") << noModels;
|
||||||
}
|
}
|
||||||
this->m_vPilot1stInit = false;
|
this->m_vPilot1stInit = false;
|
||||||
@@ -264,7 +267,8 @@ namespace BlackGui
|
|||||||
|
|
||||||
CAircraftModel CDbMappingComponent::getOwnModelForModelString(const QString &modelString) const
|
CAircraftModel CDbMappingComponent::getOwnModelForModelString(const QString &modelString) const
|
||||||
{
|
{
|
||||||
return m_cachedOwnModels.get().findFirstByModelString(modelString);
|
if (!this->m_modelLoader) { return CAircraftModel(); }
|
||||||
|
return this->m_modelLoader->getAircraftModels().findFirstByModelString(modelString);
|
||||||
}
|
}
|
||||||
|
|
||||||
CDbMappingComponent::TabIndex CDbMappingComponent::currentTabIndex() const
|
CDbMappingComponent::TabIndex CDbMappingComponent::currentTabIndex() const
|
||||||
@@ -510,8 +514,9 @@ namespace BlackGui
|
|||||||
|
|
||||||
void CDbMappingComponent::ps_requestOwnModelsUpdate()
|
void CDbMappingComponent::ps_requestOwnModelsUpdate()
|
||||||
{
|
{
|
||||||
|
if (!this->m_modelLoader) { return; }
|
||||||
this->ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(
|
this->ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(
|
||||||
this->m_cachedOwnModels.get()
|
this->m_modelLoader->getAircraftModels()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -678,11 +683,7 @@ namespace BlackGui
|
|||||||
{
|
{
|
||||||
const CAircraftModelList models(this->m_modelLoader->getAircraftModels());
|
const CAircraftModelList models(this->m_modelLoader->getAircraftModels());
|
||||||
CLogMessage(this).info("Loading %1 of models completed") << models.size();
|
CLogMessage(this).info("Loading %1 of models completed") << models.size();
|
||||||
this->m_cachedOwnModels.set(models);
|
this->ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(models);
|
||||||
CLogMessage(this).info("Written %1 own models to cache") << models.size();
|
|
||||||
|
|
||||||
// when the cache writting is done the view vill be updated in the
|
|
||||||
// cache changed slot
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -692,14 +693,6 @@ namespace BlackGui
|
|||||||
this->ui->tvp_OwnAircraftModels->hideLoadIndicator();
|
this->ui->tvp_OwnAircraftModels->hideLoadIndicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDbMappingComponent::ps_ownModelsCacheChanged()
|
|
||||||
{
|
|
||||||
if (this->ui->tvp_OwnAircraftModels->displayAutomatically())
|
|
||||||
{
|
|
||||||
this->ui->tvp_OwnAircraftModels->updateContainer(this->m_cachedOwnModels.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CAircraftModel CDbMappingComponent::getEditorAircraftModel() const
|
CAircraftModel CDbMappingComponent::getEditorAircraftModel() const
|
||||||
{
|
{
|
||||||
CAircraftModel model(ui->editor_Model->getValue());
|
CAircraftModel model(ui->editor_Model->getValue());
|
||||||
|
|||||||
@@ -181,9 +181,6 @@ namespace BlackGui
|
|||||||
//! Model loading finished
|
//! Model loading finished
|
||||||
void ps_onOwnModelsLoadingFinished(bool success);
|
void ps_onOwnModelsLoadingFinished(bool success);
|
||||||
|
|
||||||
//! Own models cache changed
|
|
||||||
void ps_ownModelsCacheChanged();
|
|
||||||
|
|
||||||
//! Own model count changed
|
//! Own model count changed
|
||||||
void ps_onOwnModelsCountChanged(int count, bool withFilter);
|
void ps_onOwnModelsCountChanged(int count, bool withFilter);
|
||||||
|
|
||||||
@@ -221,7 +218,6 @@ namespace BlackGui
|
|||||||
BlackMisc::Simulation::FsCommon::CVPilotRulesReader m_vPilotReader; //!< read vPilot rules
|
BlackMisc::Simulation::FsCommon::CVPilotRulesReader m_vPilotReader; //!< read vPilot rules
|
||||||
std::unique_ptr<BlackMisc::Simulation::IAircraftModelLoader> m_modelLoader; //!< read own aircraft models
|
std::unique_ptr<BlackMisc::Simulation::IAircraftModelLoader> m_modelLoader; //!< read own aircraft models
|
||||||
BlackMisc::CData<BlackCore::Data::VPilotAircraftModels> m_cachedVPilotModels { this, &CDbMappingComponent::ps_onVPilotCacheChanged }; //!< cache for latest vPilot rules
|
BlackMisc::CData<BlackCore::Data::VPilotAircraftModels> m_cachedVPilotModels { this, &CDbMappingComponent::ps_onVPilotCacheChanged }; //!< cache for latest vPilot rules
|
||||||
BlackMisc::CData<BlackCore::Data::OwnSimulatorAircraftModels> m_cachedOwnModels { this, &CDbMappingComponent::ps_ownModelsCacheChanged }; //!< cache for own installed models
|
|
||||||
BlackMisc::CData<BlackCore::Data::AuthenticatedDbUser> m_swiftDbUser {this, &CDbMappingComponent::ps_userChanged};
|
BlackMisc::CData<BlackCore::Data::AuthenticatedDbUser> m_swiftDbUser {this, &CDbMappingComponent::ps_userChanged};
|
||||||
bool m_vPilot1stInit = true;
|
bool m_vPilot1stInit = true;
|
||||||
bool m_withVPilot = false;
|
bool m_withVPilot = false;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ HEADERS += *.h \
|
|||||||
$$PWD/simulation/fscommon/*.h \
|
$$PWD/simulation/fscommon/*.h \
|
||||||
$$PWD/simulation/fsx/*.h \
|
$$PWD/simulation/fsx/*.h \
|
||||||
$$PWD/simulation/xplane/*.h \
|
$$PWD/simulation/xplane/*.h \
|
||||||
|
$$PWD/simulation/data/*.h \
|
||||||
$$PWD/weather/*.h
|
$$PWD/weather/*.h
|
||||||
|
|
||||||
SOURCES += *.cpp \
|
SOURCES += *.cpp \
|
||||||
@@ -54,6 +55,7 @@ SOURCES += *.cpp \
|
|||||||
$$PWD/simulation/fscommon/*.cpp \
|
$$PWD/simulation/fscommon/*.cpp \
|
||||||
$$PWD/simulation/fsx/*.cpp \
|
$$PWD/simulation/fsx/*.cpp \
|
||||||
$$PWD/simulation/xplane/*.cpp \
|
$$PWD/simulation/xplane/*.cpp \
|
||||||
|
# $$PWD/simulation/data/*.cpp \
|
||||||
$$PWD/weather/*.cpp
|
$$PWD/weather/*.cpp
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
|
|||||||
@@ -19,15 +19,67 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
namespace Simulation
|
namespace Simulation
|
||||||
{
|
{
|
||||||
IAircraftModelLoader::IAircraftModelLoader(const CSimulatorInfo &info) :
|
IAircraftModelLoader::IAircraftModelLoader(const CSimulatorInfo &info, const QString &rootDirectory, const QStringList &excludeDirs) :
|
||||||
m_simulatorInfo(info)
|
m_simulatorInfo(info), m_rootDirectory(rootDirectory), m_excludedDirectories(excludeDirs)
|
||||||
{ }
|
{
|
||||||
|
connect(this, &IAircraftModelLoader::loadingFinished, this, &IAircraftModelLoader::ps_loadFinished);
|
||||||
|
}
|
||||||
|
|
||||||
IAircraftModelLoader::~IAircraftModelLoader()
|
IAircraftModelLoader::~IAircraftModelLoader()
|
||||||
{
|
{
|
||||||
this->gracefulShutdown();
|
this->gracefulShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IAircraftModelLoader::existsDir(const QString &directory) const
|
||||||
|
{
|
||||||
|
if (directory.isEmpty()) { return false; }
|
||||||
|
QDir dir(directory);
|
||||||
|
//! \todo not available network dir can make this hang here
|
||||||
|
return dir.exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IAircraftModelLoader::ps_loadFinished(bool success)
|
||||||
|
{
|
||||||
|
Q_UNUSED(success);
|
||||||
|
this->m_loadingInProgress = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IAircraftModelLoader::changeRootDirectory(const QString &directory)
|
||||||
|
{
|
||||||
|
if (m_rootDirectory == directory) { return false; }
|
||||||
|
if (directory.isEmpty() || !existsDir(directory)) { return false; }
|
||||||
|
|
||||||
|
m_rootDirectory = directory;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IAircraftModelLoader::startLoading(LoadMode mode)
|
||||||
|
{
|
||||||
|
if (this->m_loadingInProgress) { return; }
|
||||||
|
this->m_loadingInProgress = true;
|
||||||
|
const bool useCachedData = !mode.testFlag(CacheSkipped) && this->hasCachedData();
|
||||||
|
if (useCachedData && mode.testFlag(CacheFirst))
|
||||||
|
{
|
||||||
|
emit loadingFinished(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (useCachedData && mode.testFlag(CacheUntilNewer))
|
||||||
|
{
|
||||||
|
if (!this->areModelFilesUpdated())
|
||||||
|
{
|
||||||
|
emit loadingFinished(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mode.testFlag(CacheOnly))
|
||||||
|
{
|
||||||
|
// only cache, but we did not find any data
|
||||||
|
emit loadingFinished(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->startLoadingFromDisk(mode);
|
||||||
|
}
|
||||||
|
|
||||||
const CSimulatorInfo &IAircraftModelLoader::supportedSimulators() const
|
const CSimulatorInfo &IAircraftModelLoader::supportedSimulators() const
|
||||||
{
|
{
|
||||||
return m_simulatorInfo;
|
return m_simulatorInfo;
|
||||||
@@ -45,7 +97,8 @@ namespace BlackMisc
|
|||||||
|
|
||||||
void IAircraftModelLoader::cancelLoading()
|
void IAircraftModelLoader::cancelLoading()
|
||||||
{
|
{
|
||||||
m_cancelLoading = true;
|
this->m_cancelLoading = true;
|
||||||
|
this->m_loadingInProgress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IAircraftModelLoader::gracefulShutdown()
|
void IAircraftModelLoader::gracefulShutdown()
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "blackmisc/blackmiscexport.h"
|
#include "blackmisc/blackmiscexport.h"
|
||||||
#include "blackmisc/simulation/aircraftmodellist.h"
|
#include "blackmisc/simulation/aircraftmodellist.h"
|
||||||
#include "blackmisc/simulation/simulatorinfo.h"
|
#include "blackmisc/simulation/simulatorinfo.h"
|
||||||
|
#include "blackmisc/simulation/data/modelcaches.h"
|
||||||
#include "blackmisc/pixmap.h"
|
#include "blackmisc/pixmap.h"
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
@@ -33,23 +34,45 @@ namespace BlackMisc
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
//! Parser mode
|
//! Parser mode
|
||||||
enum LoadMode
|
enum LoadModeFlag
|
||||||
{
|
{
|
||||||
ModeBlocking,
|
NotSet = 0,
|
||||||
ModeBackground
|
LoadDirectly = 1 << 0, //!< load syncronously (blocking), normally for testing
|
||||||
|
LoadInBackground = 1 << 1, //!< load in background, asnycronously
|
||||||
|
CacheUntilNewer = 1 << 2, //!< use cache until newer data re available
|
||||||
|
CacheFirst = 1 << 3, //!< always use cache (if it has data)
|
||||||
|
CacheSkipped = 1 << 4, //!< ignore cache
|
||||||
|
CacheOnly = 1 << 5, //!< force ignoring the cache
|
||||||
|
Default = LoadInBackground | CacheFirst //!< default mode
|
||||||
};
|
};
|
||||||
|
Q_DECLARE_FLAGS(LoadMode, LoadModeFlag)
|
||||||
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
virtual ~IAircraftModelLoader();
|
virtual ~IAircraftModelLoader();
|
||||||
|
|
||||||
//! Start the loading process
|
//! Start the loading process from disk
|
||||||
virtual void startLoading(LoadMode mode = ModeBackground) = 0;
|
void startLoading(LoadMode mode = Default);
|
||||||
|
|
||||||
|
//! Change the directory
|
||||||
|
bool changeRootDirectory(const QString &directory);
|
||||||
|
|
||||||
|
//! Current root directory
|
||||||
|
QString getRootDirectory() const { return this->m_rootDirectory; }
|
||||||
|
|
||||||
//! Loading finished?
|
//! Loading finished?
|
||||||
virtual bool isLoadingFinished() const = 0;
|
virtual bool isLoadingFinished() const = 0;
|
||||||
|
|
||||||
//! The models loaded
|
//! The loaded models
|
||||||
virtual BlackMisc::Simulation::CAircraftModelList getAircraftModels() const = 0;
|
virtual const BlackMisc::Simulation::CAircraftModelList &getAircraftModels() const = 0;
|
||||||
|
|
||||||
|
//! Cache timestamp
|
||||||
|
virtual QDateTime getCacheTimestamp() const = 0;
|
||||||
|
|
||||||
|
//! Model files updated?
|
||||||
|
virtual bool areModelFilesUpdated() const = 0;
|
||||||
|
|
||||||
|
//! Any cached data
|
||||||
|
virtual bool hasCachedData() const = 0;
|
||||||
|
|
||||||
//! A representive pixmap for given model
|
//! A representive pixmap for given model
|
||||||
virtual BlackMisc::CPixmap iconForModel(const QString &modelName, BlackMisc::CStatusMessage &statusMessage) const = 0;
|
virtual BlackMisc::CPixmap iconForModel(const QString &modelName, BlackMisc::CStatusMessage &statusMessage) const = 0;
|
||||||
@@ -78,13 +101,30 @@ namespace BlackMisc
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
IAircraftModelLoader(const CSimulatorInfo &info = CSimulatorInfo());
|
IAircraftModelLoader(const CSimulatorInfo &info, const QString &rootDirectory, const QStringList &excludeDirs = {});
|
||||||
|
|
||||||
|
//! Check if directory exists
|
||||||
|
bool existsDir(const QString &directory) const;
|
||||||
|
|
||||||
|
//! Start the loading process from disk
|
||||||
|
virtual void startLoadingFromDisk(LoadMode mode) = 0;
|
||||||
|
|
||||||
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
|
||||||
|
std::atomic<bool> m_loadingInProgress { false }; //!< Loading in progress
|
||||||
|
QString m_rootDirectory; //!< root directory parsing aircraft.cfg files
|
||||||
|
QStringList m_excludedDirectories; //!< directories not to be parsed
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
//! Loading finished
|
||||||
|
void ps_loadFinished(bool success);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(BlackMisc::Simulation::IAircraftModelLoader::LoadMode)
|
||||||
|
Q_DECLARE_METATYPE(BlackMisc::Simulation::IAircraftModelLoader::LoadModeFlag)
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(BlackMisc::Simulation::IAircraftModelLoader::LoadMode)
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|||||||
67
src/blackmisc/simulation/data/modelcaches.h
Normal file
67
src/blackmisc/simulation/data/modelcaches.h
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/* Copyright (C) 2016
|
||||||
|
* swift project community / contributors
|
||||||
|
*
|
||||||
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||||
|
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||||
|
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||||
|
* contained in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \file
|
||||||
|
|
||||||
|
#ifndef BLACKMISC_SIMULATION_DATA_MODELCACHES
|
||||||
|
#define BLACKMISC_SIMULATION_DATA_MODELCACHES
|
||||||
|
|
||||||
|
#include "blackmisc/datacache.h"
|
||||||
|
#include "blackmisc/simulation/aircraftmodellist.h"
|
||||||
|
|
||||||
|
namespace BlackMisc
|
||||||
|
{
|
||||||
|
namespace Simulation
|
||||||
|
{
|
||||||
|
namespace Data
|
||||||
|
{
|
||||||
|
//! Trait for model cache
|
||||||
|
struct ModelCache : public BlackMisc::CDataTrait<BlackMisc::Simulation::CAircraftModelList>
|
||||||
|
{
|
||||||
|
//! Default value
|
||||||
|
static const BlackMisc::Simulation::CAircraftModelList &defaultValue()
|
||||||
|
{
|
||||||
|
static const BlackMisc::Simulation::CAircraftModelList ml;
|
||||||
|
return ml;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Trait for XP model cache
|
||||||
|
struct ModelCacheXP : public ModelCache
|
||||||
|
{
|
||||||
|
//! Key in data cache
|
||||||
|
static const char *key() { return "modelcachexp"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Trait for FSX model cache
|
||||||
|
struct ModelCacheFsx : public ModelCache
|
||||||
|
{
|
||||||
|
//! Key in data cache
|
||||||
|
static const char *key() { return "modelcachefsx"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Trait for FS9 model cache
|
||||||
|
struct ModelCacheFs9 : public ModelCache
|
||||||
|
{
|
||||||
|
//! Key in data cache
|
||||||
|
static const char *key() { return "modelcachefs9"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Trait for P3D model cache
|
||||||
|
struct ModelCacheP3D : public ModelCache
|
||||||
|
{
|
||||||
|
//! Key in data cache
|
||||||
|
static const char *key() { return "modelcachep3d"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // ns
|
||||||
|
} // ns
|
||||||
|
} // ns
|
||||||
|
|
||||||
|
#endif // guard
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "aircraftcfgparser.h"
|
#include "aircraftcfgparser.h"
|
||||||
#include "blackmisc/simulation/fscommon/fscommonutil.h"
|
#include "blackmisc/simulation/fscommon/fscommonutil.h"
|
||||||
|
#include "blackmisc/fileutils.h"
|
||||||
#include "blackmisc/predicates.h"
|
#include "blackmisc/predicates.h"
|
||||||
#include "blackmisc/logmessage.h"
|
#include "blackmisc/logmessage.h"
|
||||||
|
|
||||||
@@ -23,12 +24,8 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
namespace FsCommon
|
namespace FsCommon
|
||||||
{
|
{
|
||||||
CAircraftCfgParser::CAircraftCfgParser() { }
|
CAircraftCfgParser::CAircraftCfgParser(const CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &excludeDirs) :
|
||||||
|
IAircraftModelLoader(simInfo, rootDirectory, excludeDirs)
|
||||||
CAircraftCfgParser::CAircraftCfgParser(const CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &exludes) :
|
|
||||||
IAircraftModelLoader(simInfo),
|
|
||||||
m_rootDirectory(rootDirectory),
|
|
||||||
m_excludedDirectories(exludes)
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
std::unique_ptr<CAircraftCfgParser> CAircraftCfgParser::createModelLoader(const CSimulatorInfo &simInfo)
|
std::unique_ptr<CAircraftCfgParser> CAircraftCfgParser::createModelLoader(const CSimulatorInfo &simInfo)
|
||||||
@@ -64,15 +61,6 @@ namespace BlackMisc
|
|||||||
if (this->m_parserWorker) { this->m_parserWorker->waitForFinished(); }
|
if (this->m_parserWorker) { this->m_parserWorker->waitForFinished(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAircraftCfgParser::changeRootDirectory(const QString &directory)
|
|
||||||
{
|
|
||||||
if (m_rootDirectory == directory) { return false; }
|
|
||||||
if (directory.isEmpty() || !existsDir(directory)) { return false; }
|
|
||||||
|
|
||||||
m_rootDirectory = directory;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CPixmap CAircraftCfgParser::iconForModel(const QString &modelString, CStatusMessage &statusMessage) const
|
CPixmap CAircraftCfgParser::iconForModel(const QString &modelString, CStatusMessage &statusMessage) const
|
||||||
{
|
{
|
||||||
static const CPixmap empty {};
|
static const CPixmap empty {};
|
||||||
@@ -101,13 +89,13 @@ namespace BlackMisc
|
|||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAircraftCfgParser::startLoading(LoadMode mode)
|
void CAircraftCfgParser::startLoadingFromDisk(LoadMode mode)
|
||||||
{
|
{
|
||||||
if (mode == ModeBackground)
|
if (mode.testFlag(LoadInBackground))
|
||||||
{
|
{
|
||||||
if (m_parserWorker && !m_parserWorker->isFinished()) { return; }
|
if (m_parserWorker && !m_parserWorker->isFinished()) { return; }
|
||||||
auto rootDirectory = m_rootDirectory;
|
const QString rootDirectory(m_rootDirectory); // copy
|
||||||
auto excludedDirectories = m_excludedDirectories;
|
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]()
|
||||||
{
|
{
|
||||||
@@ -117,13 +105,18 @@ namespace BlackMisc
|
|||||||
});
|
});
|
||||||
m_parserWorker->thenWithResult<std::pair<CAircraftCfgEntriesList, bool>>(this, [this](const auto &pair)
|
m_parserWorker->thenWithResult<std::pair<CAircraftCfgEntriesList, bool>>(this, [this](const auto &pair)
|
||||||
{
|
{
|
||||||
if (pair.second) { this->updateCfgEntriesList(pair.first); }
|
if (pair.second)
|
||||||
|
{
|
||||||
|
this->updateCfgEntriesList(pair.first);
|
||||||
|
this->setModelsInCache(pair.first.toAircraftModelList());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (mode == ModeBlocking)
|
else if (mode == LoadDirectly)
|
||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
m_parsedCfgEntriesList = performParsing(m_rootDirectory, m_excludedDirectories, &ok);
|
this->m_parsedCfgEntriesList = performParsing(m_rootDirectory, m_excludedDirectories, &ok);
|
||||||
|
this->setModelsInCache(this->m_parsedCfgEntriesList.toAircraftModelList());
|
||||||
emit loadingFinished(ok);
|
emit loadingFinished(ok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,11 +126,68 @@ namespace BlackMisc
|
|||||||
return !m_parserWorker || m_parserWorker->isFinished();
|
return !m_parserWorker || m_parserWorker->isFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftModelList CAircraftCfgParser::getAircraftModels() const
|
QDateTime CAircraftCfgParser::getCacheTimestamp() const
|
||||||
{
|
{
|
||||||
return getAircraftCfgEntriesList().toAircraftModelList(this->m_simulatorInfo);
|
if (this->m_simulatorInfo.fsx())
|
||||||
|
{
|
||||||
|
return m_modelCacheFsx.getTimestamp();
|
||||||
|
}
|
||||||
|
else if (this->m_simulatorInfo.fs9())
|
||||||
|
{
|
||||||
|
return m_modelCacheFs9.getTimestamp();
|
||||||
|
}
|
||||||
|
else if (this->m_simulatorInfo.p3d())
|
||||||
|
{
|
||||||
|
return m_modelCacheP3D.getTimestamp();
|
||||||
|
}
|
||||||
|
Q_ASSERT_X(false, Q_FUNC_INFO, "Illegal simulator info");
|
||||||
|
return QDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CAircraftCfgParser::areModelFilesUpdated() const
|
||||||
|
{
|
||||||
|
const QDateTime cacheTs(getCacheTimestamp());
|
||||||
|
if (!cacheTs.isValid()) { return true; }
|
||||||
|
//! \todo KB we cannot use the exclude dirs, a minor disadvantege. Also wonder if it was better to parse a QStringList ofr wildcard
|
||||||
|
return CFileUtils::containsFileNewerThan(cacheTs, this->getRootDirectory(), true, "*.cfg");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAircraftCfgParser::hasCachedData() const
|
||||||
|
{
|
||||||
|
if (this->m_simulatorInfo.fsx())
|
||||||
|
{
|
||||||
|
return !m_modelCacheFsx.get().isEmpty();
|
||||||
|
}
|
||||||
|
else if (this->m_simulatorInfo.fs9())
|
||||||
|
{
|
||||||
|
return !m_modelCacheFs9.get().isEmpty();
|
||||||
|
}
|
||||||
|
else if (this->m_simulatorInfo.p3d())
|
||||||
|
{
|
||||||
|
return !m_modelCacheP3D.get().isEmpty();
|
||||||
|
}
|
||||||
|
Q_ASSERT_X(false, Q_FUNC_INFO, "Illegal simulator info");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CAircraftModelList &CAircraftCfgParser::getAircraftModels() const
|
||||||
|
{
|
||||||
|
static const CAircraftModelList empty;
|
||||||
|
if (this->m_simulatorInfo.fsx())
|
||||||
|
{
|
||||||
|
return m_modelCacheFsx.get();
|
||||||
|
}
|
||||||
|
else if (this->m_simulatorInfo.fs9())
|
||||||
|
{
|
||||||
|
return m_modelCacheFs9.get();
|
||||||
|
}
|
||||||
|
else if (this->m_simulatorInfo.p3d())
|
||||||
|
{
|
||||||
|
return m_modelCacheP3D.get();
|
||||||
|
}
|
||||||
|
Q_ASSERT_X(false, Q_FUNC_INFO, "Illegal simulator info");
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
void CAircraftCfgParser::updateCfgEntriesList(const CAircraftCfgEntriesList &cfgEntriesList)
|
void CAircraftCfgParser::updateCfgEntriesList(const CAircraftCfgEntriesList &cfgEntriesList)
|
||||||
{
|
{
|
||||||
@@ -145,6 +195,24 @@ namespace BlackMisc
|
|||||||
emit loadingFinished(true);
|
emit loadingFinished(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CStatusMessage CAircraftCfgParser::setModelsInCache(const CAircraftModelList &models)
|
||||||
|
{
|
||||||
|
if (this->m_simulatorInfo.fsx())
|
||||||
|
{
|
||||||
|
return m_modelCacheFsx.set(models);
|
||||||
|
}
|
||||||
|
else if (this->m_simulatorInfo.fs9())
|
||||||
|
{
|
||||||
|
return m_modelCacheFs9.set(models);
|
||||||
|
}
|
||||||
|
else if (this->m_simulatorInfo.p3d())
|
||||||
|
{
|
||||||
|
return m_modelCacheP3D.set(models);
|
||||||
|
}
|
||||||
|
Q_ASSERT_X(false, Q_FUNC_INFO, "Illegal simulator info");
|
||||||
|
return CStatusMessage(this, CStatusMessage::SeverityError, "Wrong simulator type");
|
||||||
|
}
|
||||||
|
|
||||||
CAircraftCfgEntriesList CAircraftCfgParser::performParsing(const QString &directory, const QStringList &excludeDirectories, bool *ok)
|
CAircraftCfgEntriesList CAircraftCfgParser::performParsing(const QString &directory, const QStringList &excludeDirectories, bool *ok)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@@ -205,7 +273,7 @@ namespace BlackMisc
|
|||||||
// remark: in a 1st version I have used QSettings to parse to file as ini file
|
// remark: in a 1st version I have used QSettings to parse to file as ini file
|
||||||
// unfortunately some files are malformed which could end up in wrong data
|
// unfortunately some files are malformed which could end up in wrong data
|
||||||
|
|
||||||
QString fileName = file.absoluteFilePath();
|
const QString fileName = file.absoluteFilePath();
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (!file.open(QFile::ReadOnly | QFile::Text))
|
if (!file.open(QFile::ReadOnly | QFile::Text))
|
||||||
{
|
{
|
||||||
@@ -335,14 +403,6 @@ namespace BlackMisc
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAircraftCfgParser::existsDir(const QString &directory) const
|
|
||||||
{
|
|
||||||
if (directory.isEmpty()) { return false; }
|
|
||||||
QDir dir(directory);
|
|
||||||
//! \todo not available network dir can make this hang here
|
|
||||||
return dir.exists();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CAircraftCfgParser::fixedStringContent(const QSettings &settings, const QString &key)
|
QString CAircraftCfgParser::fixedStringContent(const QSettings &settings, const QString &key)
|
||||||
{
|
{
|
||||||
return fixedStringContent(settings.value(key));
|
return fixedStringContent(settings.value(key));
|
||||||
|
|||||||
@@ -15,8 +15,10 @@
|
|||||||
#include "blackmisc/blackmiscexport.h"
|
#include "blackmisc/blackmiscexport.h"
|
||||||
#include "blackmisc/worker.h"
|
#include "blackmisc/worker.h"
|
||||||
#include "blackmisc/pixmap.h"
|
#include "blackmisc/pixmap.h"
|
||||||
|
#include "blackmisc/datacache.h"
|
||||||
#include "blackmisc/simulation/aircraftmodelloader.h"
|
#include "blackmisc/simulation/aircraftmodelloader.h"
|
||||||
#include "blackmisc/simulation/fscommon/aircraftcfgentrieslist.h"
|
#include "blackmisc/simulation/fscommon/aircraftcfgentrieslist.h"
|
||||||
|
#include "blackmisc/simulation/data/modelcaches.h"
|
||||||
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
|
||||||
@@ -32,35 +34,24 @@ namespace BlackMisc
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Destructor
|
|
||||||
CAircraftCfgParser();
|
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
CAircraftCfgParser(const BlackMisc::Simulation::CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &exludes = {});
|
CAircraftCfgParser(const BlackMisc::Simulation::CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &exludes = {});
|
||||||
|
|
||||||
//! Virtual destructor
|
//! Virtual destructor
|
||||||
virtual ~CAircraftCfgParser();
|
virtual ~CAircraftCfgParser();
|
||||||
|
|
||||||
//! Change the directory
|
|
||||||
bool changeRootDirectory(const QString &directory);
|
|
||||||
|
|
||||||
//! Current root directory
|
|
||||||
QString getRootDirectory() const { return this->m_rootDirectory; }
|
|
||||||
|
|
||||||
//! Get parsed aircraft cfg entries list
|
//! Get parsed aircraft cfg entries list
|
||||||
const CAircraftCfgEntriesList &getAircraftCfgEntriesList() const { return m_parsedCfgEntriesList; }
|
const CAircraftCfgEntriesList &getAircraftCfgEntriesList() const { return m_parsedCfgEntriesList; }
|
||||||
|
|
||||||
//! \copydoc IAircraftModelLoader::iconForModel
|
//! \name Interface functions
|
||||||
|
//! @{
|
||||||
virtual BlackMisc::CPixmap iconForModel(const QString &modelName, BlackMisc::CStatusMessage &statusMessage) const override;
|
virtual BlackMisc::CPixmap iconForModel(const QString &modelName, BlackMisc::CStatusMessage &statusMessage) const override;
|
||||||
|
|
||||||
//! \copydoc IAircraftModelLoader::startLoading
|
|
||||||
virtual void startLoading(LoadMode mode = ModeBackground) override;
|
|
||||||
|
|
||||||
//! \copydoc IAircraftModelLoader::isLoadingFinished
|
|
||||||
virtual bool isLoadingFinished() const override;
|
virtual bool isLoadingFinished() const override;
|
||||||
|
virtual bool areModelFilesUpdated() const override;
|
||||||
//! \copydoc IAircraftModelLoader::getAircraftModels
|
virtual bool hasCachedData() const override;
|
||||||
virtual BlackMisc::Simulation::CAircraftModelList getAircraftModels() const override;
|
virtual QDateTime getCacheTimestamp() const override;
|
||||||
|
virtual const BlackMisc::Simulation::CAircraftModelList &getAircraftModels() const override;
|
||||||
|
//! @}
|
||||||
|
|
||||||
//! Create an parser object for given simulator
|
//! Create an parser object for given simulator
|
||||||
static std::unique_ptr<CAircraftCfgParser> createModelLoader(const BlackMisc::Simulation::CSimulatorInfo &simInfo);
|
static std::unique_ptr<CAircraftCfgParser> createModelLoader(const BlackMisc::Simulation::CSimulatorInfo &simInfo);
|
||||||
@@ -69,6 +60,15 @@ namespace BlackMisc
|
|||||||
//! Parsed or injected entires
|
//! Parsed or injected entires
|
||||||
void updateCfgEntriesList(const BlackMisc::Simulation::FsCommon::CAircraftCfgEntriesList &cfgEntriesList);
|
void updateCfgEntriesList(const BlackMisc::Simulation::FsCommon::CAircraftCfgEntriesList &cfgEntriesList);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//! Set cached values
|
||||||
|
BlackMisc::CStatusMessage setModelsInCache(const BlackMisc::Simulation::CAircraftModelList &models);
|
||||||
|
|
||||||
|
//! \name Interface functions
|
||||||
|
//! @{
|
||||||
|
virtual void startLoadingFromDisk(LoadMode mode) override;
|
||||||
|
//! @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! Section within file
|
//! Section within file
|
||||||
enum FileSection
|
enum FileSection
|
||||||
@@ -78,9 +78,6 @@ namespace BlackMisc
|
|||||||
Unknown
|
Unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Does the directory exist?
|
|
||||||
bool existsDir(const QString &directory = "") const;
|
|
||||||
|
|
||||||
//! Perform the parsing
|
//! Perform the parsing
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
CAircraftCfgEntriesList performParsing(const QString &directory, const QStringList &excludeDirectories, bool *ok);
|
CAircraftCfgEntriesList performParsing(const QString &directory, const QStringList &excludeDirectories, bool *ok);
|
||||||
@@ -94,10 +91,13 @@ namespace BlackMisc
|
|||||||
//! Content after "="
|
//! Content after "="
|
||||||
static QString getFixedIniLineContent(const QString &line);
|
static QString getFixedIniLineContent(const QString &line);
|
||||||
|
|
||||||
QString m_rootDirectory; //!< root directory parsing aircraft.cfg files
|
|
||||||
QStringList m_excludedDirectories; //!< directories not to be parsed
|
|
||||||
CAircraftCfgEntriesList m_parsedCfgEntriesList; //!< parsed entries
|
CAircraftCfgEntriesList m_parsedCfgEntriesList; //!< parsed entries
|
||||||
QPointer<BlackMisc::CWorker> m_parserWorker; //!< worker will destroy itself, so weak pointer
|
QPointer<BlackMisc::CWorker> m_parserWorker; //!< worker will destroy itself, so weak pointer
|
||||||
|
|
||||||
|
//! \todo KB/MS Is there nothing better than having 3 cache members
|
||||||
|
BlackMisc::CData<BlackMisc::Simulation::Data::ModelCacheFsx> m_modelCacheFsx {this}; //!< FSX cache
|
||||||
|
BlackMisc::CData<BlackMisc::Simulation::Data::ModelCacheFs9> m_modelCacheFs9 {this}; //!< Fs9 cache
|
||||||
|
BlackMisc::CData<BlackMisc::Simulation::Data::ModelCacheP3D> m_modelCacheP3D {this}; //!< P3D cache
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "xplaneutil.h"
|
#include "xplaneutil.h"
|
||||||
#include "blackmisc/predicates.h"
|
#include "blackmisc/predicates.h"
|
||||||
#include "blackmisc/logmessage.h"
|
#include "blackmisc/logmessage.h"
|
||||||
|
#include "blackmisc/fileutils.h"
|
||||||
|
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
@@ -43,13 +44,8 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftModelLoaderXPlane::CAircraftModelLoaderXPlane()
|
CAircraftModelLoaderXPlane::CAircraftModelLoaderXPlane(const CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &excludeDirs) :
|
||||||
{ }
|
IAircraftModelLoader(simInfo, rootDirectory, excludeDirs)
|
||||||
|
|
||||||
CAircraftModelLoaderXPlane::CAircraftModelLoaderXPlane(const CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &exludes) :
|
|
||||||
IAircraftModelLoader(simInfo),
|
|
||||||
m_rootDirectory(rootDirectory),
|
|
||||||
m_excludedDirectories(exludes)
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
CAircraftModelLoaderXPlane::~CAircraftModelLoaderXPlane()
|
CAircraftModelLoaderXPlane::~CAircraftModelLoaderXPlane()
|
||||||
@@ -58,15 +54,6 @@ namespace BlackMisc
|
|||||||
if (this->m_parserWorker) { this->m_parserWorker->waitForFinished(); }
|
if (this->m_parserWorker) { this->m_parserWorker->waitForFinished(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAircraftModelLoaderXPlane::changeRootDirectory(const QString &directory)
|
|
||||||
{
|
|
||||||
if (m_rootDirectory == directory) { return false; }
|
|
||||||
if (directory.isEmpty() || !existsDir(directory)) { return false; }
|
|
||||||
|
|
||||||
m_rootDirectory = directory;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CPixmap CAircraftModelLoaderXPlane::iconForModel(const QString &modelString, CStatusMessage &statusMessage) const
|
CPixmap CAircraftModelLoaderXPlane::iconForModel(const QString &modelString, CStatusMessage &statusMessage) const
|
||||||
{
|
{
|
||||||
// X-Plane does not have previews. Maybe we can just use the textures?
|
// X-Plane does not have previews. Maybe we can just use the textures?
|
||||||
@@ -75,7 +62,7 @@ namespace BlackMisc
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAircraftModelLoaderXPlane::startLoading(LoadMode mode)
|
void CAircraftModelLoaderXPlane::startLoadingFromDisk(LoadMode mode)
|
||||||
{
|
{
|
||||||
m_installedModels.clear();
|
m_installedModels.clear();
|
||||||
if (m_rootDirectory.isEmpty())
|
if (m_rootDirectory.isEmpty())
|
||||||
@@ -84,7 +71,7 @@ namespace BlackMisc
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == ModeBackground)
|
if (mode.testFlag(LoadInBackground))
|
||||||
{
|
{
|
||||||
if (m_parserWorker && !m_parserWorker->isFinished()) { return; }
|
if (m_parserWorker && !m_parserWorker->isFinished()) { return; }
|
||||||
auto rootDirectory = m_rootDirectory;
|
auto rootDirectory = m_rootDirectory;
|
||||||
@@ -100,7 +87,7 @@ namespace BlackMisc
|
|||||||
this->updateInstalledModels(models);
|
this->updateInstalledModels(models);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (mode == ModeBlocking)
|
else if (mode.testFlag(LoadDirectly))
|
||||||
{
|
{
|
||||||
m_installedModels = performParsing(m_rootDirectory, m_excludedDirectories);
|
m_installedModels = performParsing(m_rootDirectory, m_excludedDirectories);
|
||||||
emit loadingFinished(true);
|
emit loadingFinished(true);
|
||||||
@@ -112,7 +99,27 @@ namespace BlackMisc
|
|||||||
return !m_parserWorker || m_parserWorker->isFinished();
|
return !m_parserWorker || m_parserWorker->isFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftModelList CAircraftModelLoaderXPlane::getAircraftModels() const
|
bool CAircraftModelLoaderXPlane::areModelFilesUpdated() const
|
||||||
|
{
|
||||||
|
const QDateTime cacheTs(getCacheTimestamp());
|
||||||
|
if (!cacheTs.isValid()) { return true; }
|
||||||
|
//! \todo KB we cannot use the exclude dirs, a minor disadvantege. Also wonder if it was better to parse a QStringList ofr wildcard
|
||||||
|
return CFileUtils::containsFileNewerThan(cacheTs, this->getRootDirectory(), true, "xsb_aircraft.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAircraftModelLoaderXPlane::hasCachedData() const
|
||||||
|
{
|
||||||
|
//! \todo KB
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime CAircraftModelLoaderXPlane::getCacheTimestamp() const
|
||||||
|
{
|
||||||
|
//! \todo KB add cache and report back
|
||||||
|
return QDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
const CAircraftModelList &CAircraftModelLoaderXPlane::getAircraftModels() const
|
||||||
{
|
{
|
||||||
return m_installedModels;
|
return m_installedModels;
|
||||||
}
|
}
|
||||||
@@ -216,7 +223,6 @@ namespace BlackMisc
|
|||||||
|
|
||||||
m_cslPackages.clear();
|
m_cslPackages.clear();
|
||||||
|
|
||||||
|
|
||||||
QDir searchPath(rootDirectory, "xsb_aircraft.txt");
|
QDir searchPath(rootDirectory, "xsb_aircraft.txt");
|
||||||
QDirIterator it(searchPath, QDirIterator::Subdirectories);
|
QDirIterator it(searchPath, QDirIterator::Subdirectories);
|
||||||
while (it.hasNext())
|
while (it.hasNext())
|
||||||
@@ -282,14 +288,6 @@ namespace BlackMisc
|
|||||||
return installedModels;
|
return installedModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAircraftModelLoaderXPlane::existsDir(const QString &directory) const
|
|
||||||
{
|
|
||||||
if (directory.isEmpty()) { return false; }
|
|
||||||
QDir dir(directory);
|
|
||||||
//! \todo not available network dir can make this hang here
|
|
||||||
return dir.exists();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CAircraftModelLoaderXPlane::doPackageSub(QString &ioPath)
|
bool CAircraftModelLoaderXPlane::doPackageSub(QString &ioPath)
|
||||||
{
|
{
|
||||||
for (auto i = m_cslPackages.begin(); i != m_cslPackages.end(); ++i)
|
for (auto i = m_cslPackages.begin(); i != m_cslPackages.end(); ++i)
|
||||||
|
|||||||
@@ -35,37 +35,32 @@ namespace BlackMisc
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Constructor
|
|
||||||
CAircraftModelLoaderXPlane();
|
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
CAircraftModelLoaderXPlane(const BlackMisc::Simulation::CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &exludes = {});
|
CAircraftModelLoaderXPlane(const BlackMisc::Simulation::CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &exludes = {});
|
||||||
|
|
||||||
//! Virtual destructor
|
//! Virtual destructor
|
||||||
virtual ~CAircraftModelLoaderXPlane();
|
virtual ~CAircraftModelLoaderXPlane();
|
||||||
|
|
||||||
//! Change the directory
|
//! \name Interface functions
|
||||||
bool changeRootDirectory(const QString &directory);
|
//! @{
|
||||||
|
|
||||||
//! Current root directory
|
|
||||||
QString getRootDirectory() const { return this->m_rootDirectory; }
|
|
||||||
|
|
||||||
//! \copydoc IAircraftModelLoader::iconForModel
|
|
||||||
virtual BlackMisc::CPixmap iconForModel(const QString &modelName, BlackMisc::CStatusMessage &statusMessage) const override;
|
virtual BlackMisc::CPixmap iconForModel(const QString &modelName, BlackMisc::CStatusMessage &statusMessage) const override;
|
||||||
|
|
||||||
//! \copydoc IAircraftModelLoader::startLoading
|
|
||||||
virtual void startLoading(LoadMode mode = ModeBackground) override;
|
|
||||||
|
|
||||||
//! \copydoc IAircraftModelLoader::isLoadingFinished
|
|
||||||
virtual bool isLoadingFinished() const override;
|
virtual bool isLoadingFinished() const override;
|
||||||
|
virtual bool areModelFilesUpdated() const override;
|
||||||
//! \copydoc IAircraftModelLoader::getAircraftModels
|
virtual bool hasCachedData() const override;
|
||||||
virtual BlackMisc::Simulation::CAircraftModelList getAircraftModels() const override;
|
virtual QDateTime getCacheTimestamp() const override;
|
||||||
|
virtual const BlackMisc::Simulation::CAircraftModelList &getAircraftModels() const override;
|
||||||
|
//! @}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
//! Parsed or injected models
|
//! Parsed or injected models
|
||||||
void updateInstalledModels(const BlackMisc::Simulation::CAircraftModelList &models);
|
void updateInstalledModels(const BlackMisc::Simulation::CAircraftModelList &models);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//! \name Interface functions
|
||||||
|
//! @{
|
||||||
|
virtual void startLoadingFromDisk(LoadMode mode) override;
|
||||||
|
//! @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct CSLPlane
|
struct CSLPlane
|
||||||
{
|
{
|
||||||
@@ -98,8 +93,6 @@ namespace BlackMisc
|
|||||||
BlackMisc::Simulation::CAircraftModelList parseFlyableAirplanes(const QString &rootDirectory, const QStringList &excludeDirectories);
|
BlackMisc::Simulation::CAircraftModelList parseFlyableAirplanes(const QString &rootDirectory, const QStringList &excludeDirectories);
|
||||||
BlackMisc::Simulation::CAircraftModelList parseCslPackages(const QString &rootDirectory, const QStringList &excludeDirectories);
|
BlackMisc::Simulation::CAircraftModelList parseCslPackages(const QString &rootDirectory, const QStringList &excludeDirectories);
|
||||||
|
|
||||||
//! Does the directory exist?
|
|
||||||
bool existsDir(const QString &directory = QString()) const;
|
|
||||||
bool doPackageSub(QString &ioPath);
|
bool doPackageSub(QString &ioPath);
|
||||||
|
|
||||||
bool parseExportCommand(const QStringList &tokens, CSLPackage &package, const QString &path, int lineNum);
|
bool parseExportCommand(const QStringList &tokens, CSLPackage &package, const QString &path, int lineNum);
|
||||||
@@ -118,8 +111,6 @@ namespace BlackMisc
|
|||||||
CSLPackage parsePackageHeader(const QString &path, const QString &content);
|
CSLPackage parsePackageHeader(const QString &path, const QString &content);
|
||||||
void parseFullPackage(const QString &content, CSLPackage &package);
|
void parseFullPackage(const QString &content, CSLPackage &package);
|
||||||
|
|
||||||
QString m_rootDirectory; //!< root directory parsing aircraft.cfg files
|
|
||||||
QStringList m_excludedDirectories; //!< directories not to be parsed
|
|
||||||
QPointer<BlackMisc::CWorker> m_parserWorker; //!< worker will destroy itself, so weak pointer
|
QPointer<BlackMisc::CWorker> m_parserWorker; //!< worker will destroy itself, so weak pointer
|
||||||
QVector<CSLPackage> m_cslPackages; //!< Parsed Packages. No lock required since accessed only from one thread
|
QVector<CSLPackage> m_cslPackages; //!< Parsed Packages. No lock required since accessed only from one thread
|
||||||
BlackMisc::Simulation::CAircraftModelList m_installedModels;
|
BlackMisc::Simulation::CAircraftModelList m_installedModels;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace BlackSimPlugin
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_aircraftCfgParser->startLoading(CAircraftCfgParser::ModeBackground);
|
m_aircraftCfgParser->startLoading(CAircraftCfgParser::LoadInBackground);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// reading from cache / settings would go here
|
// reading from cache / settings would go here
|
||||||
|
|||||||
Reference in New Issue
Block a user