diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.cpp b/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.cpp index aa2a1d537..11ad37b05 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.cpp +++ b/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.cpp @@ -24,34 +24,6 @@ namespace BlackMisc namespace FsCommon { - int CAircraftCfgEntriesList::read() - { - if (this->m_readForDirectory) { return this->size(); } - - // not read so far, read it - this->clear(); - this->m_readForDirectory = true; - return this->read(this->m_rootDirectory, excludeDirectories()); - } - - bool CAircraftCfgEntriesList::changeDirectory(const QString &directory) - { - if (this->m_rootDirectory != directory) - { - this->m_rootDirectory = directory; - this->m_readForDirectory = false; - } - return (!directory.isEmpty() && this->existsDir(directory)); - } - - bool CAircraftCfgEntriesList::existsDir(const QString &directory) const - { - QString d = directory.isEmpty() ? this->m_rootDirectory : directory; - if (d.isEmpty()) { return false; } - QDir dir(d); - //! \todo unavailable network dir can make this hang here - return dir.exists(); - } bool CAircraftCfgEntriesList::containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity) { @@ -104,196 +76,6 @@ namespace BlackMisc { return title.compare(entries.getTitle(), caseSensitivity) == 0; }); } - const QStringList &CAircraftCfgEntriesList::excludeDirectories() - { - static const QStringList exclude - { - // "SimObjects/Misc", - "SimObjects/Animals", - "SimObjects/GroundVehicles", - "SimObjects/Boats" - }; - return exclude; - } - - int CAircraftCfgEntriesList::read(const QString &directory, const QStringList &excludeDirectories) - { - if (m_cancelRead) { return -1; } - - // excluded? - for (const QString &excludeDir : excludeDirectories) - { - if (directory.contains(excludeDir, Qt::CaseInsensitive)) - { - CLogMessage(this).debug() << "Skipping directory " << directory; - return 0; - } - } - - // set directory with name filters, get aircraft.cfg and sub directories - QDir dir(directory, "aircraft.cfg", QDir::Name, QDir::Files | QDir::AllDirs); - - - if (!dir.exists()) return 0; // can happen if there are shortcuts or linked dirs not available - - int counter = 0; - QString currentDir = dir.absolutePath(); - - // Dirs last is crucial, since I will break recursion on ".cfg" level - // once I have found .cfg, I do not go any deeper - QFileInfoList files = dir.entryInfoList(QDir::Files | QDir::AllDirs, QDir::DirsLast); - for (const QFileInfo &file : files) - { - if (m_cancelRead) { return -1; } - if (file.isDir()) - { - QString nextDir = file.absoluteFilePath(); - if (currentDir.startsWith(nextDir, Qt::CaseInsensitive)) { continue; } // do not go up - if (dir == currentDir) { continue; } // do not recursively call same directory - counter += CAircraftCfgEntriesList::read(nextDir, excludeDirectories); - } - else - { - // due to the filter we expect only ".cfg" here - // 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(); - QFile file(fileName); - if (!file.open(QFile::ReadOnly | QFile::Text)) - { - CLogMessage(this).warning("Unable to read file %1") << fileName; - continue; - } - QTextStream in(&file); - QList tempEntries; - - // parse through the file - QString atcType; - QString atcModel; - QString fltSection("[FLTSIM.0]"); - int fltsimCounter = 0; - FileSection currentSection = Unknown; - bool isRotorcraftPath = fileName.toLower().contains("rotorcraft"); - - while (!in.atEnd()) - { - const QString lineFixed(in.readLine().trimmed()); - if (lineFixed.isEmpty()) { continue; } - if (lineFixed.startsWith("[")) - { - if (lineFixed.startsWith("[GENERAL]", Qt::CaseInsensitive)) { currentSection = General; continue; } - if (lineFixed.startsWith(fltSection, Qt::CaseInsensitive)) - { - CAircraftCfgEntries e(fileName, fltsimCounter); - if (isRotorcraftPath) - { - e.setRotorcraft(true); - } - tempEntries.append(e); - currentSection = Fltsim; - fltSection = QString("[FLTSIM.%1]").arg(++fltsimCounter); - continue; - } - currentSection = Unknown; - continue; - } - switch (currentSection) - { - case General: - { - if (lineFixed.startsWith("//")) { break; } - if (atcType.isEmpty() || atcModel.isEmpty()) - { - QString c = getFixedIniLineContent(lineFixed); - if (lineFixed.startsWith("atc_type", Qt::CaseInsensitive)) { atcType = c; } - else if (lineFixed.startsWith("atc_model", Qt::CaseInsensitive)) { atcModel = c; } - } - } - break; - case Fltsim: - { - if (lineFixed.startsWith("//")) { break; } - CAircraftCfgEntries &e = tempEntries[tempEntries.size() - 1]; - if (lineFixed.startsWith("atc_parking_codes", Qt::CaseInsensitive)) - { - e.setAtcParkingCode(getFixedIniLineContent(lineFixed)); - } - else if (lineFixed.startsWith("description", Qt::CaseInsensitive)) - { - e.setDescription(getFixedIniLineContent(lineFixed)); - } - else if (lineFixed.startsWith("ui_manufacturer", Qt::CaseInsensitive)) - { - e.setUiManufacturer(getFixedIniLineContent(lineFixed)); - } - else if (lineFixed.startsWith("ui_typerole", Qt::CaseInsensitive)) - { - bool r = getFixedIniLineContent(lineFixed).toLower().contains("rotor"); - e.setRotorcraft(r); - } - else if (lineFixed.startsWith("ui_type", Qt::CaseInsensitive)) - { - e.setUiType(getFixedIniLineContent(lineFixed)); - } - else if (lineFixed.startsWith("texture", Qt::CaseInsensitive)) - { - e.setTexture(getFixedIniLineContent(lineFixed)); - } - else if (lineFixed.startsWith("title", Qt::CaseInsensitive)) - { - e.setTitle(getFixedIniLineContent(lineFixed)); - } - } - break; - default: - case Unknown: break; - } - - } // all lines - file.close(); - - // store all entries - for (const CAircraftCfgEntries &e : tempEntries) - { - if (e.getTitle().isEmpty()) - { - CLogMessage(this).info("FSX model in %1, index %2 has no title") << fileName << e.getIndex(); - continue; - } - CAircraftCfgEntries newEntries(e); - newEntries.setAtcModel(atcModel); - newEntries.setAtcType(atcType); - this->push_back(newEntries); - counter++; - } - return counter; // do not go any deeper in file tree, we found aircraft.cfg - - } // file, no directory - } // files - return counter; - } - - QString CAircraftCfgEntriesList::getFixedIniLineContent(const QString &line) - { - if (line.isEmpty()) { return ""; } - int index = line.indexOf('='); - if (index < 0) { return ""; } - if (line.length() < index + 1) { return ""; } - - QString content(line.mid(index + 1).trimmed()); - - // fix "" strings, some are malformed and just contain " at beginning, not clsoing at end of line - if (content.endsWith('"')) { content.remove(content.size() - 1 , 1); } - if (content.startsWith('"')) { content.remove(0 , 1); } - - // fix C style linebreaks - content.replace("\\n", " "); - content.replace("\\t", " "); - - // return - return content; - } - } // namespace } // namespace } // namespace diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.h b/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.h index f69522908..7959111ee 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.h +++ b/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.h @@ -37,29 +37,11 @@ namespace BlackMisc BLACKMISC_DECLARE_USING_MIXIN_METATYPE(CAircraftCfgEntriesList) //! Constructor - CAircraftCfgEntriesList(const QString &rootDirectory = "") : m_rootDirectory(rootDirectory) {} - - //! Read all aircraft.cfg files starting from root directory - int read(); - - //! Change the directory - bool changeDirectory(const QString &directory); + CAircraftCfgEntriesList() {} //! Virtual destructor virtual ~CAircraftCfgEntriesList() {} - //! Does the directory exist? - bool existsDir(const QString &directory = "") const; - - //! Has current directory been read? - bool hasReadDirectory() const { return this->m_readForDirectory; } - - //! Cancel read - void cancelRead() { m_cancelRead = true; } - - //! Current root directory - QString getRootDirectory() const { return this->m_rootDirectory; } - //! Contains model with title? bool containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive); @@ -75,16 +57,7 @@ namespace BlackMisc //! Find by title CAircraftCfgEntriesList findByTitle(const QString &title, Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive) const; - //! Do not include the following directories for FS - static const QStringList &excludeDirectories(); - private: - QString m_rootDirectory; //!< root directory reading aircraft.cfg files - bool m_readForDirectory = false; //!< valid read for given directory - bool m_cancelRead = false; - - //! Read all entries in one directory - int read(const QString &directory, const QStringList &excludeDirectories = QStringList()); //! Section within file enum FileSection @@ -94,8 +67,6 @@ namespace BlackMisc Unknown }; - //! Content after "=" - static QString getFixedIniLineContent(const QString &line); }; } // namespace } // namespace diff --git a/src/blackmisc/simulation/fscommon/aircraftmapper.cpp b/src/blackmisc/simulation/fscommon/aircraftmapper.cpp deleted file mode 100644 index 36cf8e3c9..000000000 --- a/src/blackmisc/simulation/fscommon/aircraftmapper.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* Copyright (C) 2013 - * 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. - */ - -#include "aircraftmapper.h" -#include "blackmisc/logmessage.h" -#include "blackmisc/worker.h" -#include - -using namespace BlackMisc; -using namespace BlackMisc::Simulation; -using namespace BlackMisc::Network; -using namespace BlackMisc::Aviation; - -namespace BlackMisc -{ - namespace Simulation - { - namespace FsCommon - { - CAircraftMapper::CAircraftMapper(QObject *parent) : QObject(parent) { } - - CAircraftMapper::CAircraftMapper(std::unique_ptr mappings, QObject *parent) : - QObject(parent), m_mappings(mappings.release()) - { } - - CAircraftMapper::CAircraftMapper(std::unique_ptr mappings, const QString &simObjectsDir, QObject *parent) : - QObject(parent), m_mappings(mappings.release()) - { - this->m_entries.changeDirectory(simObjectsDir); - } - - CAircraftMapper::~CAircraftMapper() - { - this->gracefulShutdown(); - } - - int CAircraftMapper::readSimObjects(const QString &simObjectDir) - { - if (!simObjectDir.isEmpty()) { m_entries.changeDirectory(simObjectDir); } - int n = m_entries.read(); - emit entriesRead(n); - return n; - } - - void CAircraftMapper::initCompletelyInBackground(const QString &simObjectDir) - { - if (this->m_initWorker) { return; } - this->m_initWorker = BlackMisc::CWorker::fromTask(this, "CAircraftMapper::initCompletely", [this, simObjectDir]() - { - this->initCompletely(simObjectDir); - }); - } - - bool CAircraftMapper::isInitialized() const - { - return m_init; - } - - CAircraftIcaoData CAircraftMapper::getIcaoForModelString(const QString &modelString) const - { - if (modelString.isEmpty() || !this->isInitialized()) { return CAircraftIcaoData(); } - CAircraftMappingList mappings = this->m_mappings->getMappingList().findByModelString(modelString); - if (mappings.isEmpty()) { return CAircraftIcaoData(); } - return mappings.front().getIcao(); - } - - bool CAircraftMapper::containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity) - { - return this->m_entries.containsModelWithTitle(title, caseSensitivity); - } - - CAircraftModel CAircraftMapper::getModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity) const - { - CAircraftCfgEntriesList el = this->m_entries.findByTitle(title, caseSensitivity); - if (el.isEmpty()) { return CAircraftModel(); } - CAircraftModel model = el.front().toAircraftModel(); - CAircraftIcaoData icao = this->getIcaoForModelString(model.getModelString()); - model.setIcao(icao); - return model; - } - - int CAircraftMapper::synchronize() - { - Q_ASSERT(this->m_mappings); - if (!this->m_mappings) { return 0; } - return this->m_mappings->synchronizeWithExistingModels(this->m_entries.getTitles(true)); - } - - void CAircraftMapper::gracefulShutdown() - { - // when running, force re-init - this->m_entries.cancelRead(); - this->m_initInProgress = false; - this->m_init = false; - } - - void CAircraftMapper::markUninitialized() - { - this->m_init = false; - } - - const CAircraftModel &CAircraftMapper::getDefaultModel() - { - static const CAircraftModel aircraftModel( - "Boeing 737-800 Paint1", - CAircraftModel::TypeModelMatchingDefaultModel, - "B737-800 default model", - CAircraftIcaoData( - CAircraftIcaoCode("B738", "L2J"), CAirlineIcaoCode(), "FFFFFF" - ) - ); - return aircraftModel; - } - - bool CAircraftMapper::initCompletely(QString simObjectDir) - { - if (this->m_init) { return true; } - if (this->m_initInProgress) { return false; } - this->m_initInProgress = true; - if (!this->m_mappings) - { - CLogMessage(this).error("Missing mapping defintions"); - emit initCompleted(false); - this->m_initInProgress = false; - return false; - } - - if (!m_entries.existsDir(simObjectDir)) - { - CLogMessage(this).error("Mapping engine, cannot read Flight Simulator directory: %1") << simObjectDir; - emit initCompleted(false); - this->m_initInProgress = false; - return false; - } - - // read the defintions (if required) - int mappingSize = this->m_mappings->size(); - if (mappingSize < 1) - { - this->m_mappings->read(); - mappingSize = this->m_mappings->size(); - if (mappingSize < 1) - { - CLogMessage(this).error("Reading mapping rules failed or empty"); - emit initCompleted(false); - this->m_initInProgress = false; - return false; - } - } - CLogMessage(this).debug() << "Mapping definitions" << mappingSize; - - // read sim objects, can take a while - int simObjectsSize = this->m_entries.size(); - if (simObjectsSize < 1) - { - simObjectsSize = this->readSimObjects(simObjectDir); - if (simObjectsSize < 1) - { - CLogMessage(this).error("No SimObjects found in %1") << simObjectDir; - emit initCompleted(false); - this->m_initInProgress = false; - return false; - } - } - simObjectsSize = this->m_entries.size(); - CLogMessage(this).info("Read %1 SimObjects from %2") << simObjectsSize << m_entries.getRootDirectory(); - - // sync - this->synchronize(); - CLogMessage(this).debug() << "Mapping definitions after sync" << this->m_mappings->size(); - - // finish - CLogMessage(this).info("Mapping system: %1 definitions for %2 entries") << this->m_mappings->size() << this->m_entries.size(); - emit initCompleted(true); - this->m_initInProgress = false; - this->m_init = true; - return true; - } - - } // namespace - } // namespace -} // namespace diff --git a/src/blackmisc/simulation/fscommon/aircraftmapper.h b/src/blackmisc/simulation/fscommon/aircraftmapper.h deleted file mode 100644 index 63171f312..000000000 --- a/src/blackmisc/simulation/fscommon/aircraftmapper.h +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright (C) 2013 - * 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_FSCOMMON_AIRCRAFTMAPPER_H -#define BLACKMISC_SIMULATION_FSCOMMON_AIRCRAFTMAPPER_H - -#include "blackmisc/blackmiscexport.h" -#include "aircraftcfgentrieslist.h" -#include "blackmisc/simulation/modelmappingsprovider.h" -#include "blackmisc/worker.h" -#include -#include -#include -#include -#include -#include - -namespace BlackMisc -{ - namespace Simulation - { - namespace FsCommon - { - //! Mapper for all models (works for FS9/FSX). - //! \details Reads all the mapping rules and all the available flight simulator models. - //! Then all rules for models not existing are eliminated ( \sa synchronize ). - //! Thereafter all existing models and mappings can be obtained from here. - //! \sa CAircraftCfgEntries - //! \sa CAircraftCfgEntriesList - class BLACKMISC_EXPORT CAircraftMapper : public QObject - { - Q_OBJECT - - signals: - //! Number of entries read - void entriesRead(int number); - - //! Full init completed - void initCompleted(bool success); - - public: - //! Default constructor - CAircraftMapper(QObject *parent = nullptr); - - //! Constructor, handing over ownership or mappings object - CAircraftMapper(std::unique_ptr mappings, QObject *parent = nullptr); - - //! Constructor, handing over ownership or mappings object - CAircraftMapper(std::unique_ptr mappings, const QString &simObjectsDir, QObject *parent = nullptr); - - //! Destructor - ~CAircraftMapper(); - - //! Completely init - bool initCompletely(QString simObjectDir); - - //! Read for directory or re-read - int readSimObjects(const QString &simObjectDir = ""); - - //! Init in background - void initCompletelyInBackground(const QString &simObjectDir = ""); - - //! Init completed? - bool isInitialized() const; - - //! Get all aircraft entries (aka models available) - const CAircraftCfgEntriesList &getAircraftCfgEntriesList() const { return m_entries; } - - //! Get all mappings - const BlackMisc::Network::CAircraftMappingList &getAircraftMappingList() const { return m_mappings->getMappingList(); } - - //! Inverse lookup - BlackMisc::Aviation::CAircraftIcaoData getIcaoForModelString(const QString &modelString) const; - - //! Number of aircraft entries - int countAircraftCfgEntries() const { return m_entries.size(); } - - //! Number of mapping definitions - int countMappingRules() const { return m_mappings ? m_mappings->size() : 0; } - - //! Set the directory - bool changeCAircraftCfgEntriesDirectory(const QString &directory) { return this->m_entries.changeDirectory(directory); } - - //! Contains model with title? - bool containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive); - - //! Model with title - BlackMisc::Simulation::CAircraftModel getModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive) const; - - //! Synchronize models and mappings - //! \remarks after this step, we only have mappings for which we have models - int synchronize(); - - //! Shutdown - void gracefulShutdown(); - - //! To force reload - void markUninitialized(); - - //! default model - static const BlackMisc::Simulation::CAircraftModel &getDefaultModel(); - - private: - QScopedPointer m_mappings; //!< all mapping definitions - CAircraftCfgEntriesList m_entries; //!< all entries - bool m_init = false; - bool m_initInProgress = false; - BlackMisc::CWorker *m_initWorker = nullptr; - }; - } // namespace - } // namespace -} // namespace -#endif // guard diff --git a/src/blackmisc/simulation/modelmappingsprovider.cpp b/src/blackmisc/simulation/modelmappingsprovider.cpp index 05af56ea7..62a0c08cf 100644 --- a/src/blackmisc/simulation/modelmappingsprovider.cpp +++ b/src/blackmisc/simulation/modelmappingsprovider.cpp @@ -19,36 +19,10 @@ namespace BlackMisc IModelMappingsProvider::IModelMappingsProvider(QObject *parent) : QObject(parent) {} - int IModelMappingsProvider::size() const - { - return this->m_mappings.size(); - } - - bool IModelMappingsProvider::isEmpty() const - { - return this->m_mappings.isEmpty(); - } - const CAircraftMappingList &IModelMappingsProvider::getMappingList() const { return this->m_mappings; } - int IModelMappingsProvider::synchronizeWithExistingModels(const QStringList &modelNames, Qt::CaseSensitivity cs) - { - if (modelNames.isEmpty() || this->m_mappings.isEmpty()) { return this->m_mappings.size(); } - CAircraftMappingList newList; - for (const CAircraftMapping &mapping : this->m_mappings) - { - QString modelString = mapping.getModel().getModelString(); - if (modelString.isEmpty()) { continue; } - if (modelNames.contains(modelString, cs)) - { - newList.push_back(mapping); - } - } - this->m_mappings = newList; - return this->m_mappings.size(); - } } // namespace } // namespace diff --git a/src/blackmisc/simulation/modelmappingsprovider.h b/src/blackmisc/simulation/modelmappingsprovider.h index a7f49f11e..eb40effae 100644 --- a/src/blackmisc/simulation/modelmappingsprovider.h +++ b/src/blackmisc/simulation/modelmappingsprovider.h @@ -36,18 +36,9 @@ namespace BlackMisc //! Load data virtual bool read() = 0; - //! Empty - bool isEmpty() const; - - //! Size - int size() const; - //! Get list const BlackMisc::Network::CAircraftMappingList &getMappingList() const; - //! Synchronize with existing model names, remove unneeded models - int synchronizeWithExistingModels(const QStringList &modelNames, Qt::CaseSensitivity cs = Qt::CaseInsensitive); - protected: BlackMisc::Network::CAircraftMappingList m_mappings; //!< Mappings };