diff --git a/src/blackmisc/orderablelist.cpp b/src/blackmisc/orderablelist.cpp index a2908f7d2..45cffd7e5 100644 --- a/src/blackmisc/orderablelist.cpp +++ b/src/blackmisc/orderablelist.cpp @@ -45,7 +45,7 @@ namespace BlackMisc template void IOrderableList::sortAscendingByOrder() { - IOrderableList::container().sort(BlackMisc::Predicates::MemberLess(&OBJ::getOrder)); + IOrderableList::container().sort(Predicates::MemberLess(&OBJ::getOrder)); } template @@ -140,6 +140,38 @@ namespace BlackMisc } } + template + OBJ IOrderableList::minOrderOrDefault() const + { + if (container().isEmpty()) { return OBJ(); } + OBJ min = container().front(); + for (const OBJ &obj : container()) + { + if (!obj.hasValidOrder()) { continue; } + if (obj.getOrder() < min.getOrder()) + { + min = obj; + } + } + return min; + } + + template + OBJ IOrderableList::maxOrderOrDefault() const + { + if (container().isEmpty()) { return OBJ(); } + OBJ max = container().front(); + for (const OBJ &obj : container()) + { + if (!obj.hasValidOrder()) { continue; } + if (obj.getOrder() > max.getOrder()) + { + max = obj; + } + } + return max; + } + //! \cond PRIVATE template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IOrderableList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IOrderableList; diff --git a/src/blackmisc/orderablelist.h b/src/blackmisc/orderablelist.h index a48187116..871fffa46 100644 --- a/src/blackmisc/orderablelist.h +++ b/src/blackmisc/orderablelist.h @@ -51,6 +51,12 @@ namespace BlackMisc //! Current order of list will be new order values void freezeOrder(); + //! Object with min.order or default + OBJ minOrderOrDefault() const; + + //! Object with max.order or default + OBJ maxOrderOrDefault() const; + protected: //! Constructor IOrderableList(); diff --git a/src/blackmisc/range.h b/src/blackmisc/range.h index 2147a72f4..c08c102a2 100644 --- a/src/blackmisc/range.h +++ b/src/blackmisc/range.h @@ -127,6 +127,13 @@ namespace BlackMisc return equalsBy(other, BlackMisc::Predicates::EqualsByMembers(k0, keys...)); } + //! Pick one random element + template + T randomElement() const + { + return this->randomElements(1).front(); + } + //! Copy n elements from the container at random. Derived randomElements(int n) const { diff --git a/src/blackmisc/simulation/aircraftmatchersetup.cpp b/src/blackmisc/simulation/aircraftmatchersetup.cpp index 852160ea3..961d3f152 100644 --- a/src/blackmisc/simulation/aircraftmatchersetup.cpp +++ b/src/blackmisc/simulation/aircraftmatchersetup.cpp @@ -14,17 +14,44 @@ namespace BlackMisc { namespace Simulation { - CAircraftMatcherSetup::CAircraftMatcherSetup(CAircraftMatcherSetup::MatchingAlgorithm algorithm, MatchingMode mode) + CAircraftMatcherSetup::CAircraftMatcherSetup() { - this->setMatchingAlgorithm(algorithm); + this->reset(MatchingScoreBased); + } + + CAircraftMatcherSetup::CAircraftMatcherSetup(CAircraftMatcherSetup::MatchingAlgorithm algorithm) + { + this->reset(algorithm); + } + + CAircraftMatcherSetup::CAircraftMatcherSetup(CAircraftMatcherSetup::MatchingAlgorithm algorithm, MatchingMode mode, PickSimilarStrategy pickStrategy) + { + this->setPickStrategy(pickStrategy); + this->setMatchingAlgorithm(algorithm, false); this->setMatchingMode(mode); } + bool CAircraftMatcherSetup::setMatchingAlgorithm(CAircraftMatcherSetup::MatchingAlgorithm algorithm, bool reset) + { + if (this->getMatchingAlgorithm() == algorithm) { return false; } + if (reset) + { + this->reset(algorithm); + } + else + { + m_algorithm = static_cast(algorithm); + } + return true; + } + QString CAircraftMatcherSetup::convertToQString(bool i18n) const { Q_UNUSED(i18n); return QStringLiteral("algorithm: '") % this->getMatchingAlgorithmAsString() % - QStringLiteral("' mode: ") % this->getMatchingModeAsString(); + QStringLiteral("' mode: '") % this->getMatchingModeAsString() % + QStringLiteral("' strategy: ") % this->getPickStrategyAsString() % + QStringLiteral("'"); } CVariant CAircraftMatcherSetup::propertyByIndex(const CPropertyIndex &index) const @@ -35,6 +62,7 @@ namespace BlackMisc { case IndexMatchingAlgorithm: return CVariant::fromValue(m_algorithm); case IndexMatchingMode: return CVariant::fromValue(m_mode); + case IndexPickStrategy: return CVariant::fromValue(m_strategy); default: break; } return CValueObject::propertyByIndex(index); @@ -48,11 +76,30 @@ namespace BlackMisc { case IndexMatchingAlgorithm: m_algorithm = variant.toInt(); break; case IndexMatchingMode: m_mode = variant.toInt(); break; + case IndexPickStrategy: m_strategy = variant.toInt(); break; default: break; } CValueObject::setPropertyByIndex(index, variant); } + void CAircraftMatcherSetup::reset(CAircraftMatcherSetup::MatchingAlgorithm algorithm) + { + m_algorithm = static_cast(algorithm); + MatchingMode mode = ModeNone; + switch (algorithm) + { + case MatchingStepwiseReduce: + mode = ModeDefaultReduce; + break; + case MatchingScoreBased: + default: + mode = ModeDefaultScore; + break; + } + this->setMatchingMode(mode); + this->setPickStrategy(PickByOrder); + } + const QString &CAircraftMatcherSetup::algorithmToString(CAircraftMatcherSetup::MatchingAlgorithm algorithm) { static const QString s("score based"); @@ -111,6 +158,24 @@ namespace BlackMisc return modes.join(", "); } + const QString &CAircraftMatcherSetup::strategyToString(CAircraftMatcherSetup::PickSimilarStrategy strategy) + { + static const QString f("first"); + static const QString o("order"); + static const QString r("random"); + + switch (strategy) + { + case PickFirst: return f; + case PickByOrder: return o; + case PickRandom: return r; + default: break; + } + + static const QString unknown("unknown"); + return unknown; + } + CAircraftMatcherSetup::MatchingMode CAircraftMatcherSetup::matchingMode( bool byModelString, bool byIcaoDataAircraft1st, bool byIcaoDataAirline1st, bool byFamily, bool byLivery, bool byCombinedType, bool scoreIgnoreZeros, bool scorePreferColorLiveries) diff --git a/src/blackmisc/simulation/aircraftmatchersetup.h b/src/blackmisc/simulation/aircraftmatchersetup.h index 0ce91930f..fbb2cfc63 100644 --- a/src/blackmisc/simulation/aircraftmatchersetup.h +++ b/src/blackmisc/simulation/aircraftmatchersetup.h @@ -45,24 +45,37 @@ namespace BlackMisc ScoreIgnoreZeros = 1 << 7, //!< zero scores are ignored ScorePreferColorLiveries = 1 << 8, //!< prefer color liveries // --- others --- - ModeNone = 0, - ModeScoreDefault = ScoreIgnoreZeros | ScorePreferColorLiveries, - ModeDefault = ByModelString | ByFamily | ByLivery | ByCombinedType | ByIcaoOrderAircraftFirst | ModeScoreDefault + ModeNone = 0, + ModeScoreDefault = ScoreIgnoreZeros | ScorePreferColorLiveries, + ModeDefaultScore = ByIcaoOrderAircraftFirst | ByModelString | ByCombinedType | ModeScoreDefault, + ModeDefaultReduce = ByModelString | ByFamily | ByLivery | ByCombinedType | ByIcaoOrderAircraftFirst }; Q_DECLARE_FLAGS(MatchingMode, MatchingModeFlag) + //! How to pick among similar candiates + enum PickSimilarStrategy + { + PickFirst, + PickRandom, + PickByOrder + }; + //! Properties by index enum ColumnIndex { IndexMatchingAlgorithm = CPropertyIndex::GlobalIndexCAircraftMatcherSetup, - IndexMatchingMode + IndexMatchingMode, + IndexPickStrategy }; //! Constructor - CAircraftMatcherSetup() {} + CAircraftMatcherSetup(); //! Constructor - CAircraftMatcherSetup(MatchingAlgorithm algorithm, MatchingMode mode); + CAircraftMatcherSetup(MatchingAlgorithm algorithm); + + //! Constructor + CAircraftMatcherSetup(MatchingAlgorithm algorithm, MatchingMode mode, PickSimilarStrategy pickStrategy); //! Algorithm MatchingAlgorithm getMatchingAlgorithm() const { return static_cast(m_algorithm); } @@ -71,7 +84,7 @@ namespace BlackMisc const QString &getMatchingAlgorithmAsString() const { return algorithmToString(this->getMatchingAlgorithm()); } //! Algorithm - void setMatchingAlgorithm(MatchingAlgorithm algorithm) { m_algorithm = static_cast(algorithm); } + bool setMatchingAlgorithm(MatchingAlgorithm algorithm, bool reset = true); //! Matching mode MatchingMode getMatchingMode() const { return static_cast(m_mode); } @@ -82,6 +95,15 @@ namespace BlackMisc //! Dynamic offset values? void setMatchingMode(MatchingMode mode) { m_mode = static_cast(mode); } + //! Strategy among equally suitable models + PickSimilarStrategy getPickStrategy() const { return static_cast(m_strategy); } + + //! Strategy as string + const QString &getPickStrategyAsString() const { return strategyToString(this->getPickStrategy()); } + + //! Set the strategy + void setPickStrategy(PickSimilarStrategy strategy) { m_strategy = static_cast(strategy); } + //! \copydoc BlackMisc::Mixin::String::toQString QString convertToQString(bool i18n = false) const; @@ -91,6 +113,9 @@ namespace BlackMisc //! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex void setPropertyByIndex(const BlackMisc::CPropertyIndex &index, const BlackMisc::CVariant &variant); + //! Reset + void reset(MatchingAlgorithm algorithm); + //! Algorithm to string static const QString &algorithmToString(MatchingAlgorithm algorithm); @@ -100,6 +125,9 @@ namespace BlackMisc //! Enumeration as string static QString modeToString(MatchingMode mode); + //! Strategy to string + static const QString &strategyToString(PickSimilarStrategy strategy); + //! Mode by flags static MatchingMode matchingMode( bool byModelString, bool byIcaoDataAircraft1st, bool byIcaoDataAirline1st, bool byFamily, bool byLivery, bool byCombinedType, @@ -107,12 +135,14 @@ namespace BlackMisc private: int m_algorithm = static_cast(MatchingScoreBased); - int m_mode = static_cast(ModeDefault); + int m_mode = static_cast(ModeDefaultScore); + int m_strategy = static_cast(PickByOrder); BLACK_METACLASS( CAircraftMatcherSetup, BLACK_METAMEMBER(algorithm), - BLACK_METAMEMBER(mode) + BLACK_METAMEMBER(mode), + BLACK_METAMEMBER(strategy) ); }; } // ns @@ -122,6 +152,7 @@ Q_DECLARE_METATYPE(BlackMisc::Simulation::CAircraftMatcherSetup) Q_DECLARE_METATYPE(BlackMisc::Simulation::CAircraftMatcherSetup::MatchingAlgorithm) Q_DECLARE_METATYPE(BlackMisc::Simulation::CAircraftMatcherSetup::MatchingMode) Q_DECLARE_METATYPE(BlackMisc::Simulation::CAircraftMatcherSetup::MatchingModeFlag) +Q_DECLARE_METATYPE(BlackMisc::Simulation::CAircraftMatcherSetup::PickSimilarStrategy) Q_DECLARE_OPERATORS_FOR_FLAGS(BlackMisc::Simulation::CAircraftMatcherSetup::MatchingMode) #endif // guard diff --git a/src/blackmisc/simulation/registermetadatasimulation.cpp b/src/blackmisc/simulation/registermetadatasimulation.cpp index 6fde927b3..9ed270a8a 100644 --- a/src/blackmisc/simulation/registermetadatasimulation.cpp +++ b/src/blackmisc/simulation/registermetadatasimulation.cpp @@ -52,8 +52,10 @@ namespace BlackMisc qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); + qDBusRegisterMetaType(); CAircraftMatcherSetup::registerMetadata(); } } // ns