diff --git a/samples/blackmiscsim/samplesfscommon.cpp b/samples/blackmiscsim/samplesfscommon.cpp index 98db9a1a6..b603527bd 100644 --- a/samples/blackmiscsim/samplesfscommon.cpp +++ b/samples/blackmiscsim/samplesfscommon.cpp @@ -10,8 +10,8 @@ #include "samplesfscommon.h" #include "blackmisc/sampleutils.h" #include "blackmisc/simulation/fscommon/aircraftcfgentrieslist.h" -#include "blackmisc/simulation/fscommon/aircraftmatcher.h" #include "blackmisc/simulation/fscommon/aircraftcfgparser.h" +#include "blackmisc/simulation/aircraftmatcher.h" #include #include diff --git a/samples/blackmiscsim/samplesmodelmapping.cpp b/samples/blackmiscsim/samplesmodelmapping.cpp index 0dd01d6cb..54cedb167 100644 --- a/samples/blackmiscsim/samplesmodelmapping.cpp +++ b/samples/blackmiscsim/samplesmodelmapping.cpp @@ -12,7 +12,7 @@ #include "blackmisc/sampleutils.h" #include "blackmisc/simulation/fscommon/aircraftcfgparser.h" #include "blackmisc/simulation/fscommon/modelmappingsprovidervpilot.h" -#include "blackmisc/simulation/fscommon/aircraftmatcher.h" +#include "blackmisc/simulation/aircraftmatcher.h" #include #include diff --git a/src/blackmisc/simulation/aircraftmatcher.cpp b/src/blackmisc/simulation/aircraftmatcher.cpp new file mode 100644 index 000000000..ce03e5a45 --- /dev/null +++ b/src/blackmisc/simulation/aircraftmatcher.cpp @@ -0,0 +1,256 @@ +/* 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 "aircraftmatcher.h" +#include "blackmisc/logmessage.h" +#include "blackmisc/worker.h" +#include +#include + +using namespace BlackMisc; +using namespace BlackMisc::Simulation; +using namespace BlackMisc::Network; +using namespace BlackMisc::Aviation; + +namespace BlackMisc +{ + namespace Simulation + { + + CAircraftMatcher::CAircraftMatcher(MatchingMode matchingMode, QObject *parent) : + QObject(parent), + m_matchingMode(matchingMode) + { } + + CAircraftMatcher::~CAircraftMatcher() + { + cancelInit(); + if (this->m_initWorker) { this->m_initWorker->waitForFinished(); } + } + + void CAircraftMatcher::init() + { + if (m_initState != NotInitialized) { return; } + m_initWorker = BlackMisc::CWorker::fromTask(this, "CAircraftMatcher::initImpl", [this]() + { + initImpl(); + }); + } + + bool CAircraftMatcher::isInitialized() const + { + return m_initState == InitFinished; + } + + void CAircraftMatcher::setModelMappingProvider(std::unique_ptr mappings) + { + m_mappingsProvider = std::move(mappings); + if (m_matchingMode.testFlag(ModelMapping)) { initMappings(); } + } + + void CAircraftMatcher::setMatchingModes(MatchingMode matchingModes) + { + m_matchingMode = matchingModes; + if (m_matchingMode.testFlag(ModelMapping) && m_modelMappings.isEmpty()) initMappings(); + } + + CAircraftModel CAircraftMatcher::getClosestMatch(const CSimulatedAircraft &remoteAircraft) + { + CAircraftModel aircraftModel(remoteAircraft); // set defaults + + // Manually set string? + if (remoteAircraft.getModel().hasManuallySetString()) + { + // manual set model, maybe update missing parts + aircraftModel.updateMissingParts(remoteAircraft.getModel()); + aircraftModel.setCallsign(remoteAircraft.getCallsign()); + reverseLookupIcaoData(aircraftModel); + return aircraftModel; + } + + // mapper ready? + if (!isInitialized()) + { + // will be removed later, just for experimental version + aircraftModel = getDefaultModel(); + aircraftModel.setCallsign(remoteAircraft.getCallsign()); + CLogMessage(static_cast(nullptr)).warning("Matcher not initialized, set to default model"); + return aircraftModel; + } + + aircraftModel = matchByExactModelName(remoteAircraft); + + if (!aircraftModel.hasModelString()) + { + aircraftModel = matchByMapping(remoteAircraft); + } + + if (!aircraftModel.hasModelString()) + { + aircraftModel = matchByAlgorithm(remoteAircraft); + } + + if (!aircraftModel.hasModelString()) + { + aircraftModel = getDefaultModel(); + } + aircraftModel.setCallsign(remoteAircraft.getCallsign()); + + Q_ASSERT(!aircraftModel.getCallsign().isEmpty()); + Q_ASSERT(aircraftModel.hasModelString()); + Q_ASSERT(aircraftModel.getModelType() != CAircraftModel::TypeUnknown); + + return aircraftModel; + } + + CAircraftIcaoData CAircraftMatcher::getIcaoForModelString(const QString &modelString) const + { + if (modelString.isEmpty() || !isInitialized()) { return CAircraftIcaoData(); } + CAircraftMappingList mappings = m_mappingsProvider->getMappingList().findByModelString(modelString); + if (mappings.isEmpty()) { return CAircraftIcaoData(); } + return mappings.front().getIcao(); + } + + int CAircraftMatcher::synchronize() + { + return synchronizeWithExistingModels(m_installedModels.getSortedModelStrings()); + } + + void CAircraftMatcher::cancelInit() + { + // when running, force re-init + this->m_initState = NotInitialized; + } + + const CAircraftModel &CAircraftMatcher::getDefaultModel() + { + return m_defaultModel; + } + + void CAircraftMatcher::setDefaultModel(const BlackMisc::Simulation::CAircraftModel &defaultModel) + { + m_defaultModel = defaultModel; + } + + void CAircraftMatcher::ps_setModelMappingRules(const CAircraftMappingList &mappings) + { + m_modelMappings = mappings; + } + + void CAircraftMatcher::initImpl() + { + InitState e = NotInitialized; + InitState d = InitInProgress; + if (!m_initState.compare_exchange_strong(e, d)) { return; } + + // sync + this->synchronize(); + CLogMessage(this).debug() << "Mapping definitions after sync" << m_modelMappings.size(); + + // finish + CLogMessage(this).info("Mapping system: %1 definitions for %2 installed models") << m_modelMappings.size() + << m_installedModels.size(); + m_initState = InitFinished; + emit initializationFinished(); + } + + void CAircraftMatcher::initMappings() + { + Q_ASSERT(m_mappingsProvider); + int mappingsSize = m_mappingsProvider->getMappingList().size(); + if (mappingsSize < 1) + { + m_mappingsProvider->read(); + m_modelMappings = m_mappingsProvider->getMappingList(); + mappingsSize = m_modelMappings.size(); + if (mappingsSize < 1) + { + CLogMessage(this).error("Reading mapping rules failed or empty!"); + // Turn off the model mapping mode + m_matchingMode &= ~ModelMapping; + return; + } + } + m_modelMappings = m_mappingsProvider->getMappingList(); + CLogMessage(this).debug() << "Mapping definitions" << mappingsSize; + } + + CAircraftModel CAircraftMatcher::matchByExactModelName(const CSimulatedAircraft &remoteAircraft) + { + CAircraftModel aircraftModel(remoteAircraft); + // Model by queried string + const CClient remoteClient = remoteAircraft.getClient(); + if (remoteClient.getAircraftModel().hasQueriedModelString()) + { + QString directModelString = remoteClient.getAircraftModel().getModelString(); + if (!directModelString.isEmpty() && m_installedModels.containsModelString(directModelString)) + { + aircraftModel = m_installedModels.findFirstByModelString(directModelString); + aircraftModel.setModelType(CAircraftModel::TypeQueriedFromNetwork); + } + } + + return aircraftModel; + } + + CAircraftModel CAircraftMatcher::matchByMapping(const CSimulatedAircraft &remoteAircraft) + { + CAircraftModel aircraftModel; + CAircraftIcaoData icao = remoteAircraft.getIcaoInfo(); + BlackMisc::Network::CAircraftMappingList mappingList = m_modelMappings.findByIcaoAircraftAndAirlineDesignator(icao, true); + if (!mappingList.isEmpty()) + { + CAircraftModel modelFromMappings = mappingList.front().getModel(); + // now turn the model from the mapping rules into a model from the simulator which has more metadata + aircraftModel = m_installedModels.findFirstByModelString(modelFromMappings.getModelString()); + Q_ASSERT(aircraftModel.getModelString() == modelFromMappings.getModelString()); + aircraftModel.updateMissingParts(modelFromMappings); // update ICAO + aircraftModel.setModelType(CAircraftModel::TypeModelMatching); + } + + return aircraftModel; + } + + CAircraftModel CAircraftMatcher::matchByAlgorithm(const CSimulatedAircraft & /** remoteAircraft **/) + { + // Use an algorithm to find the best match + return CAircraftModel(); + } + + int CAircraftMatcher::synchronizeWithExistingModels(const QStringList &modelNames, Qt::CaseSensitivity cs) + { + if (modelNames.isEmpty() || m_modelMappings.isEmpty()) { return 0; } + CAircraftMappingList newList; + for (const CAircraftMapping &mapping : m_modelMappings) + { + if (this->m_initState != InitInProgress) { return 0; } // canceled + QString modelString = mapping.getModel().getModelString(); + if (modelString.isEmpty()) { continue; } + if (modelNames.contains(modelString, cs)) + { + newList.push_back(mapping); + } + } + this->m_modelMappings = newList; + return this->m_modelMappings.size(); + } + + void CAircraftMatcher::reverseLookupIcaoData(CAircraftModel &model) + { + if (isInitialized()) + { + // reverse lookup of ICAO + CAircraftIcaoData icao = getIcaoForModelString(model.getModelString()); + icao.updateMissingParts(icao); + model.setIcao(icao); + } + } + + } +} // namespace diff --git a/src/blackmisc/simulation/aircraftmatcher.h b/src/blackmisc/simulation/aircraftmatcher.h new file mode 100644 index 000000000..d071a37d9 --- /dev/null +++ b/src/blackmisc/simulation/aircraftmatcher.h @@ -0,0 +1,148 @@ +/* Copyright (C) 2015 + * 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_AIRCRAFTMATCHER_H +#define BLACKMISC_SIMULATION_AIRCRAFTMATCHER_H + +#include "blackmisc/blackmiscexport.h" +#include "blackmisc/simulation/modelmappingsprovider.h" +#include "blackmisc/simulation/simulatedaircraft.h" +#include "blackmisc/simulation/aircraftmodellist.h" +#include "blackmisc/worker.h" +#include +#include +#include +#include + +namespace BlackMisc +{ + namespace Simulation + { + + /*! Matcher for all models + * \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. + */ + class BLACKMISC_EXPORT CAircraftMatcher : public QObject + { + Q_OBJECT + + signals: + //! Full init completed + void initializationFinished(); + + public: + //! Enabled matching mode flags + enum MatchingModeFlag + { + ExactMatch = 1 << 0, + ModelMapping = 1 << 1, + ModelMatching = 1 << 2, + AllModes = ExactMatch | ModelMapping | ModelMatching + }; + Q_DECLARE_FLAGS(MatchingMode, MatchingModeFlag) + + //! Constructor + CAircraftMatcher(MatchingMode matchingMode = ModelMatching, QObject *parent = nullptr); + + //! Destructor + ~CAircraftMatcher(); + + //! Initialize + void init(); + + //! Init completed? + bool isInitialized() const; + + //! Get all models + const CAircraftModelList &getInstalledModelsList() const { return m_installedModels; } + + //! Set the list of installed models + void setInstalledModels(const CAircraftModelList &models) { m_installedModels = models; } + + //! Number of models + int countInstalledModels() const { return m_installedModels.size(); } + + //! Set the model mapping provider. The CAircraftMatcher will move the object and take over ownership + void setModelMappingProvider(std::unique_ptr mappings); + + //! Set the enabled matching modes + void setMatchingModes(MatchingMode matchingModes); + + //! Get the closest matching aircraft model. + //! Result depends on enabled modes. + //! \sa MatchingModeFlag + CAircraftModel getClosestMatch(const CSimulatedAircraft &remoteAircraft); + + //! Get all mappings + const BlackMisc::Network::CAircraftMappingList &getAircraftMappingList() const { return m_mappingsProvider->getMappingList(); } + + //! Inverse lookup + BlackMisc::Aviation::CAircraftIcaoData getIcaoForModelString(const QString &modelString) const; + + //! Number of mapping definitions + int countMappingRules() const { return m_modelMappings.size(); } + + //! Synchronize models and mappings + //! \remarks after this step, we only have mappings for which we have models + int synchronize(); + + //! Shutdown + void cancelInit(); + + //! default model + const BlackMisc::Simulation::CAircraftModel &getDefaultModel(); + + //! Set default model + void setDefaultModel(const BlackMisc::Simulation::CAircraftModel &defaultModel); + + private slots: + //! Set the mapping rules + void ps_setModelMappingRules(const BlackMisc::Network::CAircraftMappingList &mappings); + + private: + //! Init state + enum InitState + { + NotInitialized, + InitInProgress, + InitFinished + }; + + void initImpl(); + void initMappings(); + + CAircraftModel matchByExactModelName(const CSimulatedAircraft &remoteAircraft); + CAircraftModel matchByMapping(const CSimulatedAircraft &remoteAircraft); + CAircraftModel matchByAlgorithm(const CSimulatedAircraft &remoteAircraft); + + //! Synchronize with existing model names, remove unneeded models + int synchronizeWithExistingModels(const QStringList &modelNames, Qt::CaseSensitivity cs = Qt::CaseInsensitive); + + //! Reverse lookup + void reverseLookupIcaoData(BlackMisc::Simulation::CAircraftModel &model); + + std::unique_ptr m_mappingsProvider; //!< Provides all mapping definitions + std::atomic m_initState { NotInitialized }; + QPointer m_initWorker; + MatchingMode m_matchingMode = ModelMatching; + CAircraftModelList m_installedModels; + BlackMisc::Network::CAircraftMappingList m_modelMappings; + BlackMisc::Simulation::CAircraftModel m_defaultModel; + }; + + } +} // namespace + +Q_DECLARE_OPERATORS_FOR_FLAGS(BlackMisc::Simulation::CAircraftMatcher::MatchingMode) + +#endif // guard diff --git a/src/blackmisc/simulation/fscommon/aircraftmatcher.cpp b/src/blackmisc/simulation/fscommon/aircraftmatcher.cpp deleted file mode 100644 index 21d59f681..000000000 --- a/src/blackmisc/simulation/fscommon/aircraftmatcher.cpp +++ /dev/null @@ -1,259 +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 "aircraftmatcher.h" -#include "blackmisc/logmessage.h" -#include "blackmisc/worker.h" -#include -#include - -using namespace BlackMisc; -using namespace BlackMisc::Simulation; -using namespace BlackMisc::Network; -using namespace BlackMisc::Aviation; - -namespace BlackMisc -{ - namespace Simulation - { - namespace FsCommon - { - - CAircraftMatcher::CAircraftMatcher(MatchingMode matchingMode, QObject *parent) : - QObject(parent), - m_matchingMode(matchingMode) - { } - - CAircraftMatcher::~CAircraftMatcher() - { - cancelInit(); - if (this->m_initWorker) { this->m_initWorker->waitForFinished(); } - } - - void CAircraftMatcher::init() - { - if (m_initState != NotInitialized) { return; } - m_initWorker = BlackMisc::CWorker::fromTask(this, "CAircraftMatcher::initImpl", [this]() - { - initImpl(); - }); - } - - bool CAircraftMatcher::isInitialized() const - { - return m_initState == InitFinished; - } - - void CAircraftMatcher::setModelMappingProvider(std::unique_ptr mappings) - { - m_mappingsProvider = std::move(mappings); - if (m_matchingMode.testFlag(ModelMapping)) { initMappings(); } - } - - void CAircraftMatcher::setMatchingModes(MatchingMode matchingModes) - { - m_matchingMode = matchingModes; - if (m_matchingMode.testFlag(ModelMapping) && m_modelMappings.isEmpty()) initMappings(); - } - - CAircraftModel CAircraftMatcher::getClosestMatch(const CSimulatedAircraft &remoteAircraft) - { - CAircraftModel aircraftModel(remoteAircraft); // set defaults - - // Manually set string? - if (remoteAircraft.getModel().hasManuallySetString()) - { - // manual set model, maybe update missing parts - aircraftModel.updateMissingParts(remoteAircraft.getModel()); - aircraftModel.setCallsign(remoteAircraft.getCallsign()); - reverseLookupIcaoData(aircraftModel); - return aircraftModel; - } - - // mapper ready? - if (!isInitialized()) - { - // will be removed later, just for experimental version - aircraftModel = getDefaultModel(); - aircraftModel.setCallsign(remoteAircraft.getCallsign()); - CLogMessage(static_cast(nullptr)).warning("Matcher not initialized, set to default model"); - return aircraftModel; - } - - aircraftModel = matchByExactModelName(remoteAircraft); - - if (!aircraftModel.hasModelString()) - { - aircraftModel = matchByMapping(remoteAircraft); - } - - if (!aircraftModel.hasModelString()) - { - aircraftModel = matchByAlgorithm(remoteAircraft); - } - - if (!aircraftModel.hasModelString()) - { - aircraftModel = getDefaultModel(); - } - aircraftModel.setCallsign(remoteAircraft.getCallsign()); - - Q_ASSERT(!aircraftModel.getCallsign().isEmpty()); - Q_ASSERT(aircraftModel.hasModelString()); - Q_ASSERT(aircraftModel.getModelType() != CAircraftModel::TypeUnknown); - - return aircraftModel; - } - - CAircraftIcaoData CAircraftMatcher::getIcaoForModelString(const QString &modelString) const - { - if (modelString.isEmpty() || !isInitialized()) { return CAircraftIcaoData(); } - CAircraftMappingList mappings = m_mappingsProvider->getMappingList().findByModelString(modelString); - if (mappings.isEmpty()) { return CAircraftIcaoData(); } - return mappings.front().getIcao(); - } - - int CAircraftMatcher::synchronize() - { - return synchronizeWithExistingModels(m_installedModels.getSortedModelStrings()); - } - - void CAircraftMatcher::cancelInit() - { - // when running, force re-init - this->m_initState = NotInitialized; - } - - const CAircraftModel &CAircraftMatcher::getDefaultModel() - { - return m_defaultModel; - } - - void CAircraftMatcher::setDefaultModel(const BlackMisc::Simulation::CAircraftModel &defaultModel) - { - m_defaultModel = defaultModel; - } - - void CAircraftMatcher::ps_setModelMappingRules(const CAircraftMappingList &mappings) - { - m_modelMappings = mappings; - } - - void CAircraftMatcher::initImpl() - { - InitState e = NotInitialized; - InitState d = InitInProgress; - if (!m_initState.compare_exchange_strong(e, d)) { return; } - - // sync - this->synchronize(); - CLogMessage(this).debug() << "Mapping definitions after sync" << m_modelMappings.size(); - - // finish - CLogMessage(this).info("Mapping system: %1 definitions for %2 installed models") << m_modelMappings.size() - << m_installedModels.size(); - m_initState = InitFinished; - emit initializationFinished(); - } - - void CAircraftMatcher::initMappings() - { - Q_ASSERT(m_mappingsProvider); - int mappingsSize = m_mappingsProvider->getMappingList().size(); - if (mappingsSize < 1) - { - m_mappingsProvider->read(); - m_modelMappings = m_mappingsProvider->getMappingList(); - mappingsSize = m_modelMappings.size(); - if (mappingsSize < 1) - { - CLogMessage(this).error("Reading mapping rules failed or empty!"); - // Turn off the model mapping mode - m_matchingMode &= ~ModelMapping; - return; - } - } - m_modelMappings = m_mappingsProvider->getMappingList(); - CLogMessage(this).debug() << "Mapping definitions" << mappingsSize; - } - - CAircraftModel CAircraftMatcher::matchByExactModelName(const CSimulatedAircraft &remoteAircraft) - { - CAircraftModel aircraftModel(remoteAircraft); - // Model by queried string - const CClient remoteClient = remoteAircraft.getClient(); - if (remoteClient.getAircraftModel().hasQueriedModelString()) - { - QString directModelString = remoteClient.getAircraftModel().getModelString(); - if (!directModelString.isEmpty() && m_installedModels.containsModelString(directModelString)) - { - aircraftModel = m_installedModels.findFirstByModelString(directModelString); - aircraftModel.setModelType(CAircraftModel::TypeQueriedFromNetwork); - } - } - - return aircraftModel; - } - - CAircraftModel CAircraftMatcher::matchByMapping(const CSimulatedAircraft &remoteAircraft) - { - CAircraftModel aircraftModel; - CAircraftIcaoData icao = remoteAircraft.getIcaoInfo(); - BlackMisc::Network::CAircraftMappingList mappingList = m_modelMappings.findByIcaoAircraftAndAirlineDesignator(icao, true); - if (!mappingList.isEmpty()) - { - CAircraftModel modelFromMappings = mappingList.front().getModel(); - // now turn the model from the mapping rules into a model from the simulator which has more metadata - aircraftModel = m_installedModels.findFirstByModelString(modelFromMappings.getModelString()); - Q_ASSERT(aircraftModel.getModelString() == modelFromMappings.getModelString()); - aircraftModel.updateMissingParts(modelFromMappings); // update ICAO - aircraftModel.setModelType(CAircraftModel::TypeModelMatching); - } - - return aircraftModel; - } - - CAircraftModel CAircraftMatcher::matchByAlgorithm(const CSimulatedAircraft & /** remoteAircraft **/) - { - // Use an algorithm to find the best match - return CAircraftModel(); - } - - int CAircraftMatcher::synchronizeWithExistingModels(const QStringList &modelNames, Qt::CaseSensitivity cs) - { - if (modelNames.isEmpty() || m_modelMappings.isEmpty()) { return 0; } - CAircraftMappingList newList; - for (const CAircraftMapping &mapping : m_modelMappings) - { - if (this->m_initState != InitInProgress) { return 0; } // canceled - QString modelString = mapping.getModel().getModelString(); - if (modelString.isEmpty()) { continue; } - if (modelNames.contains(modelString, cs)) - { - newList.push_back(mapping); - } - } - this->m_modelMappings = newList; - return this->m_modelMappings.size(); - } - - void CAircraftMatcher::reverseLookupIcaoData(CAircraftModel &model) - { - if (isInitialized()) - { - // reverse lookup of ICAO - CAircraftIcaoData icao = getIcaoForModelString(model.getModelString()); - icao.updateMissingParts(icao); - model.setIcao(icao); - } - } - - } // namespace - } // namespace -} // namespace diff --git a/src/blackmisc/simulation/fscommon/aircraftmatcher.h b/src/blackmisc/simulation/fscommon/aircraftmatcher.h deleted file mode 100644 index ca327e106..000000000 --- a/src/blackmisc/simulation/fscommon/aircraftmatcher.h +++ /dev/null @@ -1,153 +0,0 @@ -/* Copyright (C) 2015 - * 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_AIRCRAFTMATCHER_H -#define BLACKMISC_SIMULATION_FSCOMMON_AIRCRAFTMATCHER_H - -#include "aircraftcfgentrieslist.h" -#include "blackmisc/blackmiscexport.h" -#include "blackmisc/simulation/modelmappingsprovider.h" -#include "blackmisc/simulation/simulatedaircraft.h" -#include "blackmisc/worker.h" -#include -#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 CAircraftMatcher : public QObject - { - Q_OBJECT - - signals: - //! Full init completed - void initializationFinished(); - - public: - //! Enabled matching mode flags - enum MatchingModeFlag - { - ExactMatch = 1 << 0, - ModelMapping = 1 << 1, - ModelMatching = 1 << 2, - AllModes = ExactMatch | ModelMapping | ModelMatching - }; - Q_DECLARE_FLAGS(MatchingMode, MatchingModeFlag) - - //! Constructor - CAircraftMatcher(MatchingMode matchingMode = ModelMatching, QObject *parent = nullptr); - - //! Destructor - ~CAircraftMatcher(); - - //! Initialize - void init(); - - //! Init completed? - bool isInitialized() const; - - //! Get all models - const CAircraftModelList &getInstalledModelsList() const { return m_installedModels; } - - //! Set the list of installed models - void setInstalledModels(const CAircraftModelList &models) { m_installedModels = models; } - - //! Number of models - int countInstalledModels() const { return m_installedModels.size(); } - - //! Set the model mapping provider. The CAircraftMatcher will move the object and take over ownership - void setModelMappingProvider(std::unique_ptr mappings); - - //! Set the enabled matching modes - void setMatchingModes(MatchingMode matchingModes); - - //! Get the closest matching aircraft model. - //! Result depends on enabled modes. - //! \sa MatchingModeFlag - CAircraftModel getClosestMatch(const CSimulatedAircraft &remoteAircraft); - - //! Get all mappings - const BlackMisc::Network::CAircraftMappingList &getAircraftMappingList() const { return m_mappingsProvider->getMappingList(); } - - //! Inverse lookup - BlackMisc::Aviation::CAircraftIcaoData getIcaoForModelString(const QString &modelString) const; - - //! Number of mapping definitions - int countMappingRules() const { return m_modelMappings.size(); } - - //! Synchronize models and mappings - //! \remarks after this step, we only have mappings for which we have models - int synchronize(); - - //! Shutdown - void cancelInit(); - - //! default model - const BlackMisc::Simulation::CAircraftModel &getDefaultModel(); - - //! Set default model - void setDefaultModel(const BlackMisc::Simulation::CAircraftModel &defaultModel); - - private slots: - //! Set the mapping rules - void ps_setModelMappingRules(const BlackMisc::Network::CAircraftMappingList &mappings); - - private: - //! Init state - enum InitState - { - NotInitialized, - InitInProgress, - InitFinished - }; - - void initImpl(); - void initMappings(); - - CAircraftModel matchByExactModelName(const CSimulatedAircraft &remoteAircraft); - CAircraftModel matchByMapping(const CSimulatedAircraft &remoteAircraft); - CAircraftModel matchByAlgorithm(const CSimulatedAircraft &remoteAircraft); - - //! Synchronize with existing model names, remove unneeded models - int synchronizeWithExistingModels(const QStringList &modelNames, Qt::CaseSensitivity cs = Qt::CaseInsensitive); - - //! Reverse lookup - void reverseLookupIcaoData(BlackMisc::Simulation::CAircraftModel &model); - - std::unique_ptr m_mappingsProvider; //!< Provides all mapping definitions - std::atomic m_initState { NotInitialized }; - QPointer m_initWorker; - MatchingMode m_matchingMode = ModelMatching; - CAircraftModelList m_installedModels; - BlackMisc::Network::CAircraftMappingList m_modelMappings; - BlackMisc::Simulation::CAircraftModel m_defaultModel; - }; - } // namespace - } // namespace -} // namespace - -Q_DECLARE_OPERATORS_FOR_FLAGS(BlackMisc::Simulation::FsCommon::CAircraftMatcher::MatchingMode) - -#endif // guard diff --git a/src/plugins/simulator/fscommon/simulator_fscommon.h b/src/plugins/simulator/fscommon/simulator_fscommon.h index 1d0a648c5..9bf2b9b73 100644 --- a/src/plugins/simulator/fscommon/simulator_fscommon.h +++ b/src/plugins/simulator/fscommon/simulator_fscommon.h @@ -14,7 +14,7 @@ #include "blackcore/simulator_common.h" #include "blackcore/interpolator.h" -#include "blackmisc/simulation/fscommon/aircraftmatcher.h" +#include "blackmisc/simulation/aircraftmatcher.h" #include "blackmisc/simulation/fscommon/aircraftcfgparser.h" #include "fsuipc.h" @@ -104,7 +104,7 @@ namespace BlackSimPlugin // parser / matcher BlackMisc::Simulation::FsCommon::CAircraftCfgParser m_aircraftCfgParser; //!< aircraft.cfg parser - BlackMisc::Simulation::FsCommon::CAircraftMatcher m_modelMatcher; //!< Model matcher + BlackMisc::Simulation::CAircraftMatcher m_modelMatcher; //!< Model matcher //! Set own model void setOwnAircraftModel(const BlackMisc::Simulation::CAircraftModel &model);