refs #849, matching statistics entry and container class

This commit is contained in:
Klaus Basan
2017-01-05 02:16:27 +01:00
committed by Mathew Sutcliffe
parent dcfaca431c
commit ad0ef16ba5
7 changed files with 494 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
/* Copyright (C) 2017
* 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 "matchingstatistics.h"
namespace BlackMisc
{
namespace Simulation
{
CMatchingStatistics::CMatchingStatistics()
{ }
CMatchingStatistics::CMatchingStatistics(const CSequence<CMatchingStatisticsEntry> &other) :
CSequence<CMatchingStatisticsEntry>(other)
{ }
CMatchingStatistics CMatchingStatistics::findBySessionId(const QString &sessionId) const
{
return this->findBy(&CMatchingStatisticsEntry::getSessionId, sessionId);
}
CMatchingStatistics CMatchingStatistics::findMissingOnly() const
{
return this->findBy(&CMatchingStatisticsEntry::isMissing, true);
}
bool CMatchingStatistics::containsSessionId(const QString &sessionId) const
{
return this->contains(&CMatchingStatisticsEntry::getSessionId, sessionId);
}
bool CMatchingStatistics::containsAircraftAirlineCombination(const QString &aircraftDesignator, const QString &airlineDesignator) const
{
return aircraftDesignator.isEmpty() ?
this->contains(&CMatchingStatisticsEntry::getAircraftDesignator, aircraftDesignator) :
this->contains(&CMatchingStatisticsEntry::getAircraftDesignator, aircraftDesignator, &CMatchingStatisticsEntry::getAirlineDesignator, airlineDesignator);
}
bool CMatchingStatistics::containsAircraftAirlineCombination(const QString &sessionId, const QString &aircraftDesignator, const QString &airlineDesignator) const
{
return aircraftDesignator.isEmpty() ?
this->contains(&CMatchingStatisticsEntry::getSessionId, sessionId, &CMatchingStatisticsEntry::getAircraftDesignator, aircraftDesignator) :
this->contains(&CMatchingStatisticsEntry::getSessionId, sessionId, &CMatchingStatisticsEntry::getAircraftDesignator, aircraftDesignator, &CMatchingStatisticsEntry::getAirlineDesignator, airlineDesignator);
}
bool CMatchingStatistics::increaseCountIfFound(CMatchingStatisticsEntry::EntryType type, const QString &sessionId, const QString &aircraftDesignator, const QString &airlineDesignator)
{
bool found = false;
for (CMatchingStatisticsEntry &entry : *this)
{
if (entry.matches(type, sessionId, aircraftDesignator, airlineDesignator))
{
entry.increaseCount();
found = true;
}
}
return found;
}
void CMatchingStatistics::addAircraft(CMatchingStatisticsEntry::EntryType type, const QString &sessionId, const QString &modelSetId, const QString &description, const QString &aircraftDesignator, bool avoidDuplicates)
{
if (avoidDuplicates)
{
const bool didIncrease = this->increaseCountIfFound(type, sessionId, aircraftDesignator);
if (didIncrease) { return; }
}
this->push_back(CMatchingStatisticsEntry(type, sessionId, modelSetId, description, aircraftDesignator));
}
void CMatchingStatistics::addAircraftAirlineCombination(CMatchingStatisticsEntry::EntryType type, const QString &sessionId, const QString &modelSetId, const QString &description, const QString &aircraftDesignator, const QString &airlineDesignator, bool avoidDuplicates)
{
if (avoidDuplicates)
{
const bool didIncrease = this->increaseCountIfFound(type, sessionId, aircraftDesignator, airlineDesignator);
if (didIncrease) { return; }
}
this->push_back(CMatchingStatisticsEntry(type, sessionId, modelSetId, description, aircraftDesignator, airlineDesignator));
}
} // namespace
} // namespace

View File

@@ -0,0 +1,70 @@
/* Copyright (C) 2017
* 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_MATCHINGSTATISTICS_H
#define BLACKMISC_SIMULATION_MATCHINGSTATISTICS_H
#include "matchingstatisticsentry.h"
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/timestampobjectlist.h"
#include "blackmisc/collection.h"
namespace BlackMisc
{
namespace Simulation
{
//! Value object for matching statistics.
class BLACKMISC_EXPORT CMatchingStatistics :
public BlackMisc::CSequence<CMatchingStatisticsEntry>,
public BlackMisc::ITimestampObjectList<CMatchingStatisticsEntry, CMatchingStatistics>,
public BlackMisc::Mixin::MetaType<CMatchingStatistics>
{
public:
BLACKMISC_DECLARE_USING_MIXIN_METATYPE(CMatchingStatistics)
//! Default constructor.
CMatchingStatistics();
//! Construct from a base class object.
CMatchingStatistics(const CSequence<CMatchingStatisticsEntry> &other);
//! Find by session id
CMatchingStatistics findBySessionId(const QString &sessionId) const;
//! Find entires denoting missing entries only
CMatchingStatistics findMissingOnly() const;
//! Contains session id
bool containsSessionId(const QString &sessionId) const;
//! Contains given aircraft / airline combination
bool containsAircraftAirlineCombination(const QString &aircraftDesignator, const QString &airlineDesignator) const;
//! Contains given aircraft / airline combination
bool containsAircraftAirlineCombination(const QString &sessionId, const QString &aircraftDesignator, const QString &airlineDesignator) const;
//! Increase count if found
bool increaseCountIfFound(CMatchingStatisticsEntry::EntryType type, const QString &sessionId, const QString &aircraftDesignator, const QString &airlineDesignator = {});
//! Add a combination, normally with no duplicates (in that case count is increased
void addAircraft(CMatchingStatisticsEntry::EntryType type, const QString &sessionId, const QString &modelSetId, const QString &description, const QString &aircraftDesignator, bool avoidDuplicates = true);
//! Add a combination, normally with no duplicates (in that case count is increased
void addAircraftAirlineCombination(CMatchingStatisticsEntry::EntryType type, const QString &sessionId, const QString &modelSetId, const QString &description, const QString &aircraftDesignator, const QString &airlineDesignator, bool avoidDuplicates = true);
};
} // namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Simulation::CMatchingStatistics)
Q_DECLARE_METATYPE(BlackMisc::CCollection<BlackMisc::Simulation::CMatchingStatisticsEntry>)
Q_DECLARE_METATYPE(BlackMisc::CSequence<BlackMisc::Simulation::CMatchingStatisticsEntry>)
#endif // guard

View File

@@ -0,0 +1,181 @@
/* Copyright (C) 2017
* 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 "matchingstatisticsentry.h"
#include "blackmisc/comparefunctions.h"
#include "blackmisc/icon.h"
namespace BlackMisc
{
namespace Simulation
{
CMatchingStatisticsEntry::CMatchingStatisticsEntry() { }
CMatchingStatisticsEntry::CMatchingStatisticsEntry(EntryType type, const QString &sessionId, const QString &modelSetId, const QString &description, const QString &aircraftDesignator, const QString &airlineDesignator) :
m_sessionId(sessionId.trimmed()), m_modelSetId(modelSetId.trimmed()),
m_description(description),
m_aircraftDesignator(aircraftDesignator.trimmed().toUpper()),
m_airlineDesignator(airlineDesignator.trimmed().toUpper()),
m_entryType(type)
{
this->setCurrentUtcTime();
}
CMatchingStatisticsEntry::EntryType CMatchingStatisticsEntry::getEntryType() const
{
return static_cast<CMatchingStatisticsEntry::EntryType>(m_entryType);
}
bool CMatchingStatisticsEntry::isMissing() const
{
return this->getEntryType() == Missing;
}
void CMatchingStatisticsEntry::setEntryType(CMatchingStatisticsEntry::EntryType type)
{
m_entryType = static_cast<int>(type);
}
int CMatchingStatisticsEntry::getCount() const
{
return m_count;
}
void CMatchingStatisticsEntry::increaseCount()
{
m_count++;
}
bool CMatchingStatisticsEntry::matches(CMatchingStatisticsEntry::EntryType type, const QString &sessionId, const QString &aircraftDesignator, const QString &airlineDesignator) const
{
return this->getEntryType() == type && sessionId == this->getSessionId() && aircraftDesignator == this->getAircraftDesignator() && airlineDesignator == this->getAirlineDesignator();
}
bool CMatchingStatisticsEntry::hasAircraftAirlineCombination() const
{
return !m_aircraftDesignator.isEmpty() && !m_airlineDesignator.isEmpty();
}
const CIcon &CMatchingStatisticsEntry::entryTypeToIcon(CMatchingStatisticsEntry::EntryType type)
{
switch (type)
{
case Found: return CIcon::iconByIndex(CIcons::StandardIconTick16);
case Missing: return CIcon::iconByIndex(CIcons::StandardIconCross16);
default:
qFatal("Wrong Type");
return CIcon::iconByIndex(CIcons::StandardIconUnknown16);
}
}
const QString &CMatchingStatisticsEntry::entryTypeToString(CMatchingStatisticsEntry::EntryType type)
{
static const QString f("found");
static const QString m("missing");
static const QString x("ups");
switch (type)
{
case Found: return f;
case Missing: return m;
default:
qFatal("Wrong Type");
return x;
}
}
CVariant CMatchingStatisticsEntry::propertyByIndex(const CPropertyIndex &index) const
{
if (index.isMyself()) { return CVariant::from(*this); }
if (ITimestampBased::canHandleIndex(index)) { return ITimestampBased::propertyByIndex(index); }
const ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexSessionId: return CVariant::from(this->m_sessionId);
case IndexModelSetId: return CVariant::from(this->m_modelSetId);
case IndexCount: return CVariant::from(this->m_count);
case IndexEntryType: return CVariant::from(this->m_entryType);
case IndexEntryTypeAsString: return CVariant::from(entryTypeToString(this->getEntryType()));
case IndexEntryTypeAsIcon: return CVariant::from(entryTypeToIcon(this->getEntryType()));
case IndexAircraftDesignator: return CVariant::from(this->m_aircraftDesignator);
case IndexAirlineDesignator: return CVariant::from(this->m_airlineDesignator);
case IndexDescription: return CVariant::from(this->m_description);
case IndexHasAircraftAirlineCombination: return CVariant::from(this->hasAircraftAirlineCombination());
default:
return CValueObject::propertyByIndex(index);
}
}
void CMatchingStatisticsEntry::setPropertyByIndex(const CPropertyIndex &index, const CVariant &variant)
{
if (index.isMyself()) { (*this) = variant.to<CMatchingStatisticsEntry>(); return; }
if (ITimestampBased::canHandleIndex(index)) { ITimestampBased::setPropertyByIndex(index, variant); return; }
const ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexSessionId:
this->setSessionId(variant.value<QString>());
break;
case IndexModelSetId:
this->setModelSetId(variant.value<QString>());
break;
case IndexAircraftDesignator:
this->m_aircraftDesignator = variant.value<QString>();
break;
case IndexEntryType:
this->setEntryType(static_cast<EntryType>(variant.toInt()));
break;
case IndexCount:
this->m_count = variant.toInt();
break;
case IndexAirlineDesignator:
this->m_airlineDesignator = variant.value<QString>();
break;
case IndexDescription:
this->m_description = variant.value<QString>();
break;
default:
CValueObject::setPropertyByIndex(index, variant);
break;
}
}
int CMatchingStatisticsEntry::comparePropertyByIndex(const CPropertyIndex &index, const CMatchingStatisticsEntry &compareValue) const
{
if (ITimestampBased::canHandleIndex(index)) { return ITimestampBased::comparePropertyByIndex(index, compareValue); }
const ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexSessionId: return this->m_sessionId.compare(compareValue.m_sessionId, Qt::CaseInsensitive);
case IndexModelSetId: return this->m_modelSetId.compare(compareValue.getModelSetId(), Qt::CaseInsensitive);
case IndexEntryTypeAsIcon:
case IndexEntryTypeAsString:
case IndexEntryType: return Compare::compare(this->m_entryType, compareValue.m_entryType);
case IndexCount: return Compare::compare(this->m_count, compareValue.m_count);
case IndexAircraftDesignator: return this->m_aircraftDesignator.compare(compareValue.m_aircraftDesignator, Qt::CaseInsensitive);
case IndexAirlineDesignator: return this->m_airlineDesignator.compare(compareValue.m_airlineDesignator, Qt::CaseInsensitive);
case IndexHasAircraftAirlineCombination: return Compare::compare(this->hasAircraftAirlineCombination(), compareValue.hasAircraftAirlineCombination());
default:
break;
}
Q_ASSERT_X(false, Q_FUNC_INFO, "Compare failed");
return 0;
}
QString CMatchingStatisticsEntry::convertToQString(bool i18n) const
{
Q_UNUSED(i18n);
const QString s = QString("%1 Session: '%2' model set: '%3' aircraft: '%4' airline: '%5' description: '%6'")
.arg(entryTypeToString(getEntryType()), m_sessionId, m_modelSetId, m_aircraftDesignator, m_airlineDesignator, m_description);
return s;
}
} // namespace
} // namespace

View File

@@ -0,0 +1,153 @@
/* Copyright (C) 2017
* 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_MATCHINGSTATISTICSENTRY_H
#define BLACKMISC_SIMULATION_MATCHINGSTATISTICSENTRY_H
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/valueobject.h"
#include "blackmisc/timestampbased.h"
#include "blackmisc/variant.h"
namespace BlackMisc
{
namespace Simulation
{
//! Value object for a matching statistics entry.
class BLACKMISC_EXPORT CMatchingStatisticsEntry :
public BlackMisc::CValueObject<CMatchingStatisticsEntry>,
public BlackMisc::ITimestampBased
{
public:
//! Property indexes
enum ColumnIndex
{
IndexSessionId = CPropertyIndex::GlobalIndexCMatchingStatisticsEntry,
IndexModelSetId,
IndexEntryType,
IndexEntryTypeAsString,
IndexEntryTypeAsIcon,
IndexCount,
IndexDescription,
IndexAircraftDesignator,
IndexAirlineDesignator,
IndexHasAircraftAirlineCombination
};
//! Represents type of entry
enum EntryType
{
Found,
Missing
};
//! Default constructor.
CMatchingStatisticsEntry();
//! Constructor
CMatchingStatisticsEntry(EntryType type, const QString &sessionId, const QString &modelSetId, const QString &description, const QString &aircraftDesignator, const QString &airlineDesignator = {});
//! Session id
const QString &getSessionId() const { return m_sessionId; }
//! Set session id
void setSessionId(const QString &sessionId) { m_sessionId = sessionId.trimmed(); }
//! Get model set id
const QString &getModelSetId() const { return m_modelSetId; }
//! Set model set id
void setModelSetId(const QString &modelSetId) { m_modelSetId = modelSetId.trimmed(); }
//! Get missing aircraft designator
const QString &getAircraftDesignator() const { return m_aircraftDesignator;}
//! Set missing aircraft designator
void setAircraftDesignator(const QString &designator) { m_aircraftDesignator = designator.trimmed().toUpper(); }
//! Get missing airline designator
const QString &getAirlineDesignator() const { return m_airlineDesignator;}
//! Set missing airline designator
void setAirlineDesignator(const QString &designator) { m_airlineDesignator = designator.trimmed().toUpper(); }
//! Type of entry
EntryType getEntryType() const;
//! Missing entry?
bool isMissing() const;
//! Set the entry type
void setEntryType(EntryType type);
//! Get description
const QString &getDescription() const { return m_description;}
//! Set a description
void setDescription(const QString &description) { m_description = description; }
//! Current count
int getCount() const;
//! Count increased by one
void increaseCount();
//! Matches given value?
bool matches(EntryType type, const QString &sessionId, const QString &aircraftDesignator, const QString &airlineDesignator) const;
//! \copydoc BlackMisc::Mixin::Index::propertyByIndex
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
//! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex
void setPropertyByIndex(const BlackMisc::CPropertyIndex &index, const CVariant &variant);
//! Compare by index
int comparePropertyByIndex(const CPropertyIndex &index, const CMatchingStatisticsEntry &compareValue) const;
//! \copydoc BlackMisc::Mixin::String::toQString
QString convertToQString(bool i18n = false) const;
//! Missing aircraft/airline combination?
bool hasAircraftAirlineCombination() const;
//! Convert entry type
static const QString &entryTypeToString(EntryType type);
//! Convert entry type
static const BlackMisc::CIcon &entryTypeToIcon(EntryType type);
private:
QString m_sessionId; //!< Created in session
QString m_modelSetId; //!< represents model set
QString m_description; //!< Arbitrary description
QString m_aircraftDesignator; //!< missing aircraft designator
QString m_airlineDesignator; //!< missing airline designator
int m_entryType = Missing; //!< type
int m_count = 1; //!< quantity
BLACK_METACLASS(
CMatchingStatisticsEntry,
BLACK_METAMEMBER(sessionId),
BLACK_METAMEMBER(modelSetId),
BLACK_METAMEMBER(aircraftDesignator),
BLACK_METAMEMBER(airlineDesignator),
BLACK_METAMEMBER(description),
BLACK_METAMEMBER(entryType),
BLACK_METAMEMBER(count)
);
};
} // namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Simulation::CMatchingStatisticsEntry)
Q_DECLARE_METATYPE(BlackMisc::Simulation::CMatchingStatisticsEntry::EntryType)
#endif // guard

View File

@@ -30,6 +30,8 @@ namespace BlackMisc
CDistributorListPreferences::registerMetadata();
CInterpolationAndRenderingSetup::registerMetadata();
CInterpolationHints::registerMetadata();
CMatchingStatisticsEntry::registerMetadata();
CMatchingStatistics::registerMetadata();
CModelSettings::registerMetadata();
CSimConnectUtilities::registerMetadata();
CSimulatedAircraft::registerMetadata();

View File

@@ -21,6 +21,7 @@
#include "blackmisc/simulation/distributorlistpreferences.h"
#include "blackmisc/simulation/interpolationhints.h"
#include "blackmisc/simulation/interpolationrenderingsetup.h"
#include "blackmisc/simulation/matchingstatistics.h"
#include "blackmisc/simulation/modelsettings.h"
#include "blackmisc/simulation/simulatedaircraft.h"
#include "blackmisc/simulation/simulatedaircraftlist.h"