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:
Klaus Basan
2016-03-11 04:13:56 +01:00
parent eda68329f3
commit 4087d63d9c
13 changed files with 354 additions and 151 deletions

View File

@@ -39,6 +39,7 @@ HEADERS += *.h \
$$PWD/simulation/fscommon/*.h \
$$PWD/simulation/fsx/*.h \
$$PWD/simulation/xplane/*.h \
$$PWD/simulation/data/*.h \
$$PWD/weather/*.h
SOURCES += *.cpp \
@@ -54,6 +55,7 @@ SOURCES += *.cpp \
$$PWD/simulation/fscommon/*.cpp \
$$PWD/simulation/fsx/*.cpp \
$$PWD/simulation/xplane/*.cpp \
# $$PWD/simulation/data/*.cpp \
$$PWD/weather/*.cpp
win32 {

View File

@@ -19,15 +19,67 @@ namespace BlackMisc
{
namespace Simulation
{
IAircraftModelLoader::IAircraftModelLoader(const CSimulatorInfo &info) :
m_simulatorInfo(info)
{ }
IAircraftModelLoader::IAircraftModelLoader(const CSimulatorInfo &info, const QString &rootDirectory, const QStringList &excludeDirs) :
m_simulatorInfo(info), m_rootDirectory(rootDirectory), m_excludedDirectories(excludeDirs)
{
connect(this, &IAircraftModelLoader::loadingFinished, this, &IAircraftModelLoader::ps_loadFinished);
}
IAircraftModelLoader::~IAircraftModelLoader()
{
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
{
return m_simulatorInfo;
@@ -45,7 +97,8 @@ namespace BlackMisc
void IAircraftModelLoader::cancelLoading()
{
m_cancelLoading = true;
this->m_cancelLoading = true;
this->m_loadingInProgress = true;
}
void IAircraftModelLoader::gracefulShutdown()

View File

@@ -15,6 +15,7 @@
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/simulation/aircraftmodellist.h"
#include "blackmisc/simulation/simulatorinfo.h"
#include "blackmisc/simulation/data/modelcaches.h"
#include "blackmisc/pixmap.h"
#include <QObject>
#include <atomic>
@@ -33,23 +34,45 @@ namespace BlackMisc
public:
//! Parser mode
enum LoadMode
enum LoadModeFlag
{
ModeBlocking,
ModeBackground
NotSet = 0,
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
virtual ~IAircraftModelLoader();
//! Start the loading process
virtual void startLoading(LoadMode mode = ModeBackground) = 0;
//! Start the loading process from disk
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?
virtual bool isLoadingFinished() const = 0;
//! The models loaded
virtual BlackMisc::Simulation::CAircraftModelList getAircraftModels() const = 0;
//! The loaded models
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
virtual BlackMisc::CPixmap iconForModel(const QString &modelName, BlackMisc::CStatusMessage &statusMessage) const = 0;
@@ -78,13 +101,30 @@ namespace BlackMisc
protected:
//! 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
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
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

View 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

View File

@@ -9,6 +9,7 @@
#include "aircraftcfgparser.h"
#include "blackmisc/simulation/fscommon/fscommonutil.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/predicates.h"
#include "blackmisc/logmessage.h"
@@ -23,12 +24,8 @@ namespace BlackMisc
{
namespace FsCommon
{
CAircraftCfgParser::CAircraftCfgParser() { }
CAircraftCfgParser::CAircraftCfgParser(const CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &exludes) :
IAircraftModelLoader(simInfo),
m_rootDirectory(rootDirectory),
m_excludedDirectories(exludes)
CAircraftCfgParser::CAircraftCfgParser(const CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &excludeDirs) :
IAircraftModelLoader(simInfo, rootDirectory, excludeDirs)
{ }
std::unique_ptr<CAircraftCfgParser> CAircraftCfgParser::createModelLoader(const CSimulatorInfo &simInfo)
@@ -64,15 +61,6 @@ namespace BlackMisc
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
{
static const CPixmap empty {};
@@ -101,13 +89,13 @@ namespace BlackMisc
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; }
auto rootDirectory = m_rootDirectory;
auto excludedDirectories = m_excludedDirectories;
const QString rootDirectory(m_rootDirectory); // copy
const QStringList excludedDirectories(m_excludedDirectories); // copy
m_parserWorker = BlackMisc::CWorker::fromTask(this, "CAircraftCfgParser::changeDirectory",
[this, rootDirectory, excludedDirectories]()
{
@@ -117,13 +105,18 @@ namespace BlackMisc
});
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;
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);
}
}
@@ -133,11 +126,68 @@ namespace BlackMisc
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)
{
@@ -145,6 +195,24 @@ namespace BlackMisc
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)
{
//
@@ -205,7 +273,7 @@ namespace BlackMisc
// 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
QString fileName = file.absoluteFilePath();
const QString fileName = file.absoluteFilePath();
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text))
{
@@ -335,14 +403,6 @@ namespace BlackMisc
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)
{
return fixedStringContent(settings.value(key));

View File

@@ -15,8 +15,10 @@
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/worker.h"
#include "blackmisc/pixmap.h"
#include "blackmisc/datacache.h"
#include "blackmisc/simulation/aircraftmodelloader.h"
#include "blackmisc/simulation/fscommon/aircraftcfgentrieslist.h"
#include "blackmisc/simulation/data/modelcaches.h"
#include <QPointer>
@@ -32,35 +34,24 @@ namespace BlackMisc
Q_OBJECT
public:
//! Destructor
CAircraftCfgParser();
//! Constructor
CAircraftCfgParser(const BlackMisc::Simulation::CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &exludes = {});
//! Virtual destructor
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
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;
//! \copydoc IAircraftModelLoader::startLoading
virtual void startLoading(LoadMode mode = ModeBackground) override;
//! \copydoc IAircraftModelLoader::isLoadingFinished
virtual bool isLoadingFinished() const override;
//! \copydoc IAircraftModelLoader::getAircraftModels
virtual BlackMisc::Simulation::CAircraftModelList getAircraftModels() const override;
virtual bool areModelFilesUpdated() const override;
virtual bool hasCachedData() const override;
virtual QDateTime getCacheTimestamp() const override;
virtual const BlackMisc::Simulation::CAircraftModelList &getAircraftModels() const override;
//! @}
//! Create an parser object for given simulator
static std::unique_ptr<CAircraftCfgParser> createModelLoader(const BlackMisc::Simulation::CSimulatorInfo &simInfo);
@@ -69,6 +60,15 @@ namespace BlackMisc
//! Parsed or injected entires
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:
//! Section within file
enum FileSection
@@ -78,9 +78,6 @@ namespace BlackMisc
Unknown
};
//! Does the directory exist?
bool existsDir(const QString &directory = "") const;
//! Perform the parsing
//! \threadsafe
CAircraftCfgEntriesList performParsing(const QString &directory, const QStringList &excludeDirectories, bool *ok);
@@ -94,10 +91,13 @@ namespace BlackMisc
//! Content after "="
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
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

View File

@@ -11,6 +11,7 @@
#include "xplaneutil.h"
#include "blackmisc/predicates.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/fileutils.h"
#include <QDirIterator>
#include <QTextStream>
@@ -43,13 +44,8 @@ namespace BlackMisc
}
}
CAircraftModelLoaderXPlane::CAircraftModelLoaderXPlane()
{ }
CAircraftModelLoaderXPlane::CAircraftModelLoaderXPlane(const CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &exludes) :
IAircraftModelLoader(simInfo),
m_rootDirectory(rootDirectory),
m_excludedDirectories(exludes)
CAircraftModelLoaderXPlane::CAircraftModelLoaderXPlane(const CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &excludeDirs) :
IAircraftModelLoader(simInfo, rootDirectory, excludeDirs)
{ }
CAircraftModelLoaderXPlane::~CAircraftModelLoaderXPlane()
@@ -58,15 +54,6 @@ namespace BlackMisc
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
{
// X-Plane does not have previews. Maybe we can just use the textures?
@@ -75,7 +62,7 @@ namespace BlackMisc
return {};
}
void CAircraftModelLoaderXPlane::startLoading(LoadMode mode)
void CAircraftModelLoaderXPlane::startLoadingFromDisk(LoadMode mode)
{
m_installedModels.clear();
if (m_rootDirectory.isEmpty())
@@ -84,7 +71,7 @@ namespace BlackMisc
return;
}
if (mode == ModeBackground)
if (mode.testFlag(LoadInBackground))
{
if (m_parserWorker && !m_parserWorker->isFinished()) { return; }
auto rootDirectory = m_rootDirectory;
@@ -100,7 +87,7 @@ namespace BlackMisc
this->updateInstalledModels(models);
});
}
else if (mode == ModeBlocking)
else if (mode.testFlag(LoadDirectly))
{
m_installedModels = performParsing(m_rootDirectory, m_excludedDirectories);
emit loadingFinished(true);
@@ -112,7 +99,27 @@ namespace BlackMisc
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;
}
@@ -146,7 +153,7 @@ namespace BlackMisc
{
if (models.containsModelString(model.getModelString()))
{
CLogMessage(static_cast<CAircraftModelLoaderXPlane*>(nullptr)).warning("Model %1 exists already! Potential model string conflict! Ignoring it.") << model.getModelString();
CLogMessage(static_cast<CAircraftModelLoaderXPlane *>(nullptr)).warning("Model %1 exists already! Potential model string conflict! Ignoring it.") << model.getModelString();
}
models.push_back(model);
}
@@ -216,7 +223,6 @@ namespace BlackMisc
m_cslPackages.clear();
QDir searchPath(rootDirectory, "xsb_aircraft.txt");
QDirIterator it(searchPath, QDirIterator::Subdirectories);
while (it.hasNext())
@@ -282,14 +288,6 @@ namespace BlackMisc
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)
{
for (auto i = m_cslPackages.begin(); i != m_cslPackages.end(); ++i)
@@ -353,7 +351,7 @@ namespace BlackMisc
{
line = stream.readLine();
}
while(line.isEmpty() && !stream.atEnd());
while (line.isEmpty() && !stream.atEnd());
return line;
}
@@ -376,7 +374,7 @@ namespace BlackMisc
// Get obj header
QFile objFile(fullPath);
if(!objFile.open(QIODevice::ReadOnly | QIODevice::Text))
if (!objFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
CLogMessage(this).warning("Object %1 does not exist.") << fullPath;
return false;

View File

@@ -35,37 +35,32 @@ namespace BlackMisc
Q_OBJECT
public:
//! Constructor
CAircraftModelLoaderXPlane();
//! Constructor
CAircraftModelLoaderXPlane(const BlackMisc::Simulation::CSimulatorInfo &simInfo, const QString &rootDirectory, const QStringList &exludes = {});
//! Virtual destructor
virtual ~CAircraftModelLoaderXPlane();
//! Change the directory
bool changeRootDirectory(const QString &directory);
//! Current root directory
QString getRootDirectory() const { return this->m_rootDirectory; }
//! \copydoc IAircraftModelLoader::iconForModel
//! \name Interface functions
//! @{
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;
//! \copydoc IAircraftModelLoader::getAircraftModels
virtual BlackMisc::Simulation::CAircraftModelList getAircraftModels() const override;
virtual bool areModelFilesUpdated() const override;
virtual bool hasCachedData() const override;
virtual QDateTime getCacheTimestamp() const override;
virtual const BlackMisc::Simulation::CAircraftModelList &getAircraftModels() const override;
//! @}
public slots:
//! Parsed or injected models
void updateInstalledModels(const BlackMisc::Simulation::CAircraftModelList &models);
protected:
//! \name Interface functions
//! @{
virtual void startLoadingFromDisk(LoadMode mode) override;
//! @}
private:
struct CSLPlane
{
@@ -98,8 +93,6 @@ namespace BlackMisc
BlackMisc::Simulation::CAircraftModelList parseFlyableAirplanes(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 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);
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
QVector<CSLPackage> m_cslPackages; //!< Parsed Packages. No lock required since accessed only from one thread
BlackMisc::Simulation::CAircraftModelList m_installedModels;