mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-01 05:26:45 +08:00
177 lines
8.8 KiB
C++
177 lines
8.8 KiB
C++
/* Copyright (C) 2019
|
|
* 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. 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 "categorymatcher.h"
|
|
#include "simulatedaircraft.h"
|
|
#include "aircraftmatchersetup.h"
|
|
#include "matchingutils.h"
|
|
#include "blackmisc/statusmessagelist.h"
|
|
|
|
#include <QStringBuilder>
|
|
|
|
using namespace BlackMisc::Aviation;
|
|
|
|
namespace BlackMisc
|
|
{
|
|
namespace Simulation
|
|
{
|
|
const CLogCategoryList &CCategoryMatcher::getLogCategories()
|
|
{
|
|
static const CLogCategoryList cats { CLogCategory::matching() };
|
|
return cats;
|
|
}
|
|
|
|
void CCategoryMatcher::setCategories(const CAircraftCategoryList &categories)
|
|
{
|
|
m_all = categories;
|
|
m_all.sortByLevel();
|
|
|
|
CAircraftCategoryList gliders = categories.findByName("glider").findFirstLevels();
|
|
if (!gliders.isEmpty())
|
|
{
|
|
const int fl = gliders.front().getFirstLevel();
|
|
gliders = categories.findByFirstLevel(fl);
|
|
gliders.sortByLevel();
|
|
m_gliders = gliders;
|
|
}
|
|
|
|
CAircraftCategoryList militaryWing = categories.findByName("wing military").findFirstLevels();
|
|
if (!militaryWing.isEmpty())
|
|
{
|
|
const int fl = militaryWing.front().getFirstLevel();
|
|
militaryWing = categories.findByFirstLevel(fl);
|
|
militaryWing.sortByLevel();
|
|
m_militaryWingAircraft = militaryWing;
|
|
}
|
|
|
|
CAircraftCategoryList militaryRotor = categories.findByName("rotor military").findFirstLevels();
|
|
if (!militaryRotor.isEmpty())
|
|
{
|
|
const int fl = militaryRotor.front().getFirstLevel();
|
|
militaryRotor = categories.findByFirstLevel(fl);
|
|
militaryRotor.sortByLevel();
|
|
m_militaryRotorAircraft = militaryRotor;
|
|
}
|
|
}
|
|
|
|
CAircraftModelList CCategoryMatcher::reduceByCategories(const CAircraftModelList &alreadyMatchedModels, const CAircraftModelList &modelSet, const CAircraftMatcherSetup &setup, const CSimulatedAircraft &remoteAircraft, bool &reduced, bool shortLog, CStatusMessageList *log) const
|
|
{
|
|
Q_UNUSED(shortLog)
|
|
|
|
reduced = false;
|
|
if (!setup.useCategoryMatching())
|
|
{
|
|
if (log) { CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("Disabled category matching"), getLogCategories()); }
|
|
return alreadyMatchedModels;
|
|
}
|
|
if (m_all.isEmpty())
|
|
{
|
|
// no categories?
|
|
CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("Disabled category matching"), getLogCategories());
|
|
return alreadyMatchedModels;
|
|
}
|
|
if (!remoteAircraft.getAircraftIcaoCode().hasCategory())
|
|
{
|
|
CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("No category in remote aircraft"), getLogCategories());
|
|
return alreadyMatchedModels;
|
|
}
|
|
|
|
if (log) { CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("Remote aircraft has category '%1'").arg(remoteAircraft.getAircraftIcaoCode().getCategory().getNameDbKey()), getLogCategories()); }
|
|
if (!m_gliders.isEmpty() && setup.getMatchingMode().testFlag(CAircraftMatcherSetup::ByCategoryGlider) && this->isGlider(remoteAircraft.getAircraftIcaoCode()))
|
|
{
|
|
// we have a glider
|
|
// and we search in the whole set: this is a special case
|
|
const int firstLevel = this->gliderFirstLevel();
|
|
const CAircraftModelList gliders = modelSet.findByCategoryFirstLevel(firstLevel); // all gliders from model set
|
|
if (!gliders.isEmpty())
|
|
{
|
|
const CAircraftCategory category = remoteAircraft.getAircraftIcaoCode().getCategory();
|
|
reduced = true; // in any case reduced (to gliders)
|
|
|
|
// find same category
|
|
const CAircraftModelList sameGliders = gliders.findByCategory(category);
|
|
if (!sameGliders.isEmpty())
|
|
{
|
|
if (log) { CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("Reduced to %1 models by category: '%2'").arg(sameGliders.size()).arg(category.toQString(true)), getLogCategories()); }
|
|
return sameGliders;
|
|
}
|
|
|
|
// find parallel branch category
|
|
const CAircraftCategoryList otherBranches = m_gliders.findInParallelBranch(category);
|
|
if (!otherBranches.isEmpty())
|
|
{
|
|
const CAircraftModelList otherBranchGliders = gliders.findByCategories(otherBranches);
|
|
if (!otherBranchGliders.isEmpty())
|
|
{
|
|
if (log) { CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("Reduced to %1 parallel branch models of '%2' by categories: '%3'").arg(otherBranchGliders.size()).arg(category.getLevelAndName(), otherBranches.getLevelsString()), getLogCategories()); }
|
|
return otherBranchGliders;
|
|
}
|
|
}
|
|
|
|
const CAircraftCategoryList siblings = m_gliders.findSiblings(category);
|
|
if (!siblings.isEmpty())
|
|
{
|
|
const CAircraftModelList siblingGliders = modelSet.findByCategories(siblings);
|
|
if (!siblings.isEmpty() && !siblingGliders.isEmpty())
|
|
{
|
|
if (log) { CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("Reduced to %1 sibling models of '%2' by categories: '%3'").arg(siblingGliders.size()).arg(category.getLevelAndName(), siblings.getLevelsString()), getLogCategories()); }
|
|
return siblingGliders;
|
|
}
|
|
}
|
|
|
|
CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("Reduced to %1 models by 'GLIDER' category").arg(sameGliders.size()), getLogCategories());
|
|
return gliders;
|
|
}
|
|
else
|
|
{
|
|
if (log) { CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("No glider category '%1' in set").arg(m_gliders.front().getLevelAndName()), getLogCategories()); }
|
|
static const QStringList substituteIcaos({ "UHEL", "GLID", "ULAC" }); // maybe also GYRO
|
|
static const QString substituteIcaosStr = substituteIcaos.join(", ");
|
|
|
|
CAircraftModelList substitutes = alreadyMatchedModels.findByDesignatorsOrFamilyWithColorLivery(substituteIcaos);
|
|
if (substitutes.isEmpty())
|
|
{
|
|
substitutes = alreadyMatchedModels.findByCombinedType(QStringLiteral("L1P"));
|
|
if (!substitutes.isEmpty())
|
|
{
|
|
reduced = true;
|
|
if (log) { CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("No gliders, reduced to 'L1P' models: %1' (avoid absurd matchings)").arg(substitutes.size()), getLogCategories()); }
|
|
return substitutes;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
reduced = true;
|
|
if (log) { CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("Reduced to %1 models by '%2'").arg(substitutes.size()).arg(substituteIcaosStr), getLogCategories()); }
|
|
return substitutes;
|
|
}
|
|
}
|
|
}
|
|
|
|
return alreadyMatchedModels;
|
|
}
|
|
|
|
bool CCategoryMatcher::isGlider(const CAircraftIcaoCode &icao) const
|
|
{
|
|
if (icao.getDesignator() == CAircraftIcaoCode::getGliderDesignator()) { return true; }
|
|
const int glider1st = this->gliderFirstLevel();
|
|
if (glider1st >= 0 && icao.hasCategory())
|
|
{
|
|
return icao.getCategory().getFirstLevel() == glider1st;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int CCategoryMatcher::gliderFirstLevel() const
|
|
{
|
|
if (m_gliders.isEmpty()) { return -1; }
|
|
return m_gliders.front().getFirstLevel();
|
|
}
|
|
} // namespace
|
|
} // namespace
|