refs #358, consolidated mapping and model classes

* removed redundant classes in blacksim
* more detailed attributes for mapping
* more finder functions in mapping list
* aircraft model extended as simulator independent description for models
This commit is contained in:
Klaus Basan
2014-12-15 00:26:19 +01:00
parent def17124db
commit bdcb031591
15 changed files with 269 additions and 504 deletions

View File

@@ -52,6 +52,15 @@ namespace BlackMisc
return s;
}
void CAircraftIcao::updateMissingParts(const CAircraftIcao &icao)
{
if (this->m_aircraftDesignator.isEmpty()) { this->setAircraftDesignator(icao.getAircraftDesignator()); }
if (this->m_airlineDesignator.isEmpty()) { this->setAirlineDesignator(icao.getAirlineDesignator()); }
if (this->m_aircraftCombinedType.isEmpty()) { this->setAircraftCombinedType(icao.getAircraftCombinedType()); }
if (this->m_aircraftColor.isEmpty()) { this->setAircraftColor(icao.getAircraftColor()); }
if (this->m_livery.isEmpty()) { this->setLivery(icao.getLivery()); }
}
bool CAircraftIcao::matchesWildcardIcao(const CAircraftIcao &otherIcao) const
{
if ((*this) == otherIcao) return true;

View File

@@ -126,6 +126,9 @@ namespace BlackMisc
//! Set type
void setAircraftCombinedType(const QString &type) { this->m_aircraftCombinedType = type.trimmed().toUpper(); }
//! Missing parts from another ICAO object
void updateMissingParts(const CAircraftIcao &icao);
//! Matches wildcard icao object
bool matchesWildcardIcao(const CAircraftIcao &otherIcao) const;

View File

@@ -27,6 +27,7 @@ void BlackMisc::Network::registerMetadata()
CClient::registerMetadata();
CClientList::registerMetadata();
CAircraftModel::registerMetadata();
CAircraftModelList::registerMetadata();
CVoiceCapabilities::registerMetadata();
CAircraftMapping::registerMetadata();
CAircraftMappingList::registerMetadata();

View File

@@ -12,8 +12,9 @@
#include "blackmisc/nwtextmessagelist.h"
#include "blackmisc/nwclient.h"
#include "blackmisc/nwclientlist.h"
#include "blackmisc/nwaircraftmodel.h"
#include "blackmisc/nwvoicecapabilities.h"
#include "blackmisc/nwaircraftmodel.h"
#include "blackmisc/nwaircraftmodellist.h"
#include "blackmisc/nwaircraftmapping.h"
#include "blackmisc/nwaircraftmappinglist.h"

View File

@@ -22,8 +22,8 @@ namespace BlackMisc
/*
* Constructor
*/
CAircraftMapping::CAircraftMapping(const QString &aircraftDesignator, const QString &airlineDesignator, const QString &model) :
m_icao(CAircraftIcao(aircraftDesignator, airlineDesignator)), m_model(CAircraftModel(model, false))
CAircraftMapping::CAircraftMapping(const QString &source, const QString &packageName, const QString &aircraftDesignator, const QString &airlineDesignator, const QString &model) :
m_source(source.trimmed()), m_packageName(packageName.trimmed()), m_icao(CAircraftIcao(aircraftDesignator, airlineDesignator)), m_model(CAircraftModel(model, CAircraftModel::TypeModelMapping))
{ }
/*
@@ -54,16 +54,15 @@ namespace BlackMisc
{
case IndexModel:
return this->m_model.propertyByIndex(index.copyFrontRemoved());
break;
case IndexIcaoCode:
case IndexIcao:
return this->m_model.propertyByIndex(index.copyFrontRemoved());
break;
case IndexPackageName:
return QVariant::fromValue(this->m_packageName);
case IndexSource:
return QVariant::fromValue(this->m_source);
default:
break;
return CValueObject::propertyByIndex(index);
}
Q_ASSERT_X(false, "CAircraftMapping", "index unknown");
QString m = QString("no property, index ").append(index.toQString());
return CVariant::fromValue(m);
}
/*
@@ -82,11 +81,17 @@ namespace BlackMisc
case IndexModel:
this->m_model.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexIcaoCode:
case IndexIcao:
this->m_icao.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexPackageName:
this->m_packageName = variant.toQString();
break;
case IndexSource:
this->m_source = variant.toQString();
break;
default:
Q_ASSERT_X(false, "CAircraftMapping", "index unknown");
CValueObject::setPropertyByIndex(variant, index);
break;
}
}

View File

@@ -20,15 +20,9 @@ namespace BlackMisc
{
namespace Network
{
/*!
* Mapping
*/
//! Mapping
class CAircraftMapping : public CValueObjectStdTuple<CAircraftMapping>
{
private:
BLACK_ENABLE_TUPLE_CONVERSION(CAircraftMapping)
BlackMisc::Aviation::CAircraftIcao m_icao; //!< ICAO code
BlackMisc::Network::CAircraftModel m_model; //!< aircraft model
protected:
//! \copydoc CValueObject::convertToQString
@@ -39,14 +33,16 @@ namespace BlackMisc
enum ColumnIndex
{
IndexModel,
IndexIcaoCode
IndexIcao,
IndexPackageName,
IndexSource
};
//! Default constructor
CAircraftMapping() = default;
//! Constructor
CAircraftMapping(const QString &aircraftDesignator, const QString &airlineDesignator, const QString &model);
CAircraftMapping(const QString &source, const QString &packageName, const QString &aircraftDesignator, const QString &airlineDesignator, const QString &model);
//! \copydoc CValueObject::propertyByIndex
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const override;
@@ -71,6 +67,16 @@ namespace BlackMisc
//! Matches wildcard icao object
bool matchesWildcardIcao(const BlackMisc::Aviation::CAircraftIcao &otherIcao) const { return m_icao.matchesWildcardIcao(otherIcao); }
private:
BLACK_ENABLE_TUPLE_CONVERSION(CAircraftMapping)
QString m_source; //!< source, e.g. database, vPilot
QString m_packageName; //!< something like WoA, ..
BlackMisc::Aviation::CAircraftIcao m_icao; //!< ICAO code
BlackMisc::Network::CAircraftModel m_model; //!< aircraft model
// BlackSim::CSimulatorInfo m_simulatorInfo; //!< Mapping is for simulator
};
}
}

View File

@@ -31,12 +31,42 @@ namespace BlackMisc
CAircraftMappingList CAircraftMappingList::findByIcaoCodeWildcard(const CAircraftIcao &searchIcao) const
{
return this->findBy([ = ](const CAircraftMapping &mapping)
return this->findBy([ = ](const CAircraftMapping & mapping)
{
return mapping.matchesWildcardIcao(searchIcao);
});
}
CAircraftMappingList CAircraftMappingList::findByIcaoAircraftDesignator(const CAircraftIcao &searchIcao) const
{
const QString aircraftIcao = searchIcao.getAircraftDesignator();
if (aircraftIcao.isEmpty()) { return CAircraftMappingList(); }
return this->findBy([ = ](const CAircraftMapping & mapping)
{
return mapping.getIcao().getAircraftDesignator() == aircraftIcao;
});
}
CAircraftMappingList CAircraftMappingList::findByIcaoAirlineDesignator(const CAircraftIcao &searchIcao) const
{
const QString airlineIcao = searchIcao.getAircraftDesignator();
if (airlineIcao.isEmpty()) { return CAircraftMappingList(); }
return this->findBy([ = ](const CAircraftMapping & mapping)
{
return mapping.getIcao().getAirlineDesignator() == airlineIcao;
});
}
CAircraftMappingList CAircraftMappingList::findByIcaoAircraftAndAirlineDesignator(const CAircraftIcao &searchIcao, bool allowRelaxedAirline) const
{
CAircraftMappingList aircraftSearch = findByIcaoAircraftDesignator(searchIcao);
if (aircraftSearch.isEmpty()) { return aircraftSearch; }
CAircraftMappingList aircraftAndAirlineSearch = aircraftSearch.findByIcaoAirlineDesignator(searchIcao);
if (!aircraftAndAirlineSearch.isEmpty()) { return aircraftAndAirlineSearch; }
return allowRelaxedAirline ? aircraftSearch : aircraftAndAirlineSearch;
}
CAircraftMappingList CAircraftMappingList::findByIcaoCodeExact(const CAircraftIcao &searchIcao) const
{
return this->findBy(&CAircraftMapping::getIcao, searchIcao);
@@ -44,7 +74,7 @@ namespace BlackMisc
CAircraftMappingList CAircraftMappingList::findByModelString(const QString modelString, Qt::CaseSensitivity sensitivity) const
{
return this->findBy([ = ](const CAircraftMapping &mapping)
return this->findBy([ = ](const CAircraftMapping & mapping)
{
return mapping.matchesModelString(modelString, sensitivity);
});

View File

@@ -23,9 +23,7 @@ namespace BlackMisc
{
namespace Network
{
/*!
* Value object encapsulating a list of aircraft mappings
*/
//! Value object encapsulating a list of aircraft mappings
class CAircraftMappingList : public CSequence<CAircraftMapping>
{
public:
@@ -38,6 +36,15 @@ namespace BlackMisc
//! Find by ICAO code, empty fields treated as wildcards
CAircraftMappingList findByIcaoCodeWildcard(const BlackMisc::Aviation::CAircraftIcao &searchIcao) const;
//! Find by ICAO aircraft designator
CAircraftMappingList findByIcaoAircraftDesignator(const BlackMisc::Aviation::CAircraftIcao &searchIcao) const;
//! Find by ICAO airline designator
CAircraftMappingList findByIcaoAirlineDesignator(const BlackMisc::Aviation::CAircraftIcao &searchIcao) const;
//! Find by ICAO aircraft and airline designator
CAircraftMappingList findByIcaoAircraftAndAirlineDesignator(const BlackMisc::Aviation::CAircraftIcao &searchIcao, bool allowRelaxedAirline) const;
//! Find by ICAO code, empty fields treated literally
CAircraftMappingList findByIcaoCodeExact(const BlackMisc::Aviation::CAircraftIcao &searchIcao) const;

View File

@@ -8,21 +8,34 @@
*/
#include "nwaircraftmodel.h"
#include "variant.h"
#include <QString>
namespace BlackMisc
{
namespace Network
{
/*
* Constructor
*/
CAircraftModel::CAircraftModel(const Aviation::CAircraft &aircraft) :
m_callsign(aircraft.getCallsign()), m_icao(aircraft.getIcaoInfo())
{ }
/*
* Convert to string
*/
QString CAircraftModel::convertToQString(bool /** i18n **/) const
QString CAircraftModel::convertToQString(bool i18n) const
{
QString s = this->m_modelString;
if (!s.isEmpty()) s.append(' ');
s.append(this->m_queriedModelStringFlag ? "queried" : "mapped");
if (!s.isEmpty()) { s += ' '; }
s += this->getModelTypeAsString();
s += ' ';
s += this->m_icao.toQString(i18n);
if (!this->m_fileName.isEmpty())
{
s += ' ';
s += m_fileName;
}
return s;
}
@@ -31,19 +44,28 @@ namespace BlackMisc
*/
CVariant CAircraftModel::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
if (index.isMyself()) { return this->toCVariant(); }
if (index.isMyself()) { return this->toQVariant(); }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexModelString:
return CVariant::from(this->m_modelString);
break;
case IndexIsQueriedModelString:
return CVariant::from(this->m_queriedModelStringFlag);
break;
return CVariant(this->m_modelString);
case IndexHasQueriedModelString:
return CVariant::fromValue(this->hasQueriedModelString());
case IndexModelType:
return CVariant::fromValue(this->m_modelType);
case IndexModelTypeAsString:
return CVariant(this->getModelTypeAsString());
case IndexDescription:
return CVariant(this->m_description);
case IndexFileName:
return CVariant(this->m_fileName);
case IndexIcao:
return m_icao.propertyByIndex(index.copyFrontRemoved());
case IndexCallsign:
return m_callsign.propertyByIndex(index.copyFrontRemoved());
default:
return CValueObject::propertyByIndex(index);
break;
}
}
@@ -63,8 +85,20 @@ namespace BlackMisc
case IndexModelString:
this->m_modelString = variant.toQString();
break;
case IndexIsQueriedModelString:
this->m_queriedModelStringFlag = variant.toBool();
case IndexIcao:
this->m_icao.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexDescription:
this->m_description = variant.toQString();
break;
case IndexCallsign:
this->m_callsign.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexFileName:
this->m_fileName = variant.toQString();
break;
case IndexModelType:
this->m_modelType = variant.toInt();
break;
default:
CValueObject::setPropertyByIndex(variant, index);
@@ -72,15 +106,44 @@ namespace BlackMisc
}
}
/*
* Update missing parts
*/
void CAircraftModel::updateMissingParts(const CAircraftModel &model)
{
if (this->m_modelString.isEmpty()) { this->m_modelString = model.getModelString(); }
if (this->m_description.isEmpty()) { this->m_description = model.getDescription(); }
if (this->m_fileName.isEmpty()) { this->m_fileName = model.getFileName(); }
if (this->m_callsign.isEmpty()) { this->m_callsign = model.getCallsign(); }
this->m_icao.updateMissingParts(model.getIcao());
}
/*
* Matches string?
*/
bool CAircraftModel::matchesModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const
{
if (sensitivity == Qt::CaseSensitive)
{
return modelString == this->m_modelString;
}
else
{
return this->m_modelString.indexOf(modelString) == 0;
}
}
QString CAircraftModel::modelTypeToString(CAircraftModel::ModelType type)
{
switch (type)
{
case TypeQueriedFromNetwork: return "queried";
case TypeModelMatching: return "matching";
case TypeModelMapping: return "mapping";
case TypeOwnSimulatorModel: return "own simulator";
case TypeUnknown:
default: return "unknown";
}
}
} // namespace

View File

@@ -12,31 +12,52 @@
#ifndef BLACKMISC_AIRCRAFTMODEL_H
#define BLACKMISC_AIRCRAFTMODEL_H
#include "avaircraft.h"
#include "avaircrafticao.h"
#include "nwuser.h"
#include "propertyindex.h"
namespace BlackMisc
{
namespace Network
{
/*!
* Another pilot's aircraft model
*/
//! Aircraft model (other pilot, my models on disk)
//! \remarks Simulator independent class, supposed to be common denominator
class CAircraftModel : public CValueObjectStdTuple<CAircraftModel>
{
public:
//! Model type
enum ModelType
{
TypeUnknown,
TypeQueriedFromNetwork, //!< model was queried by network protocol
TypeModelMatching, //!< model is result of model matching
TypeModelMapping, //!< used along with mapping definition
TypeOwnSimulatorModel //!< represents own simulator model
};
//! Indexes
enum ColumnIndex
{
IndexModelString = BlackMisc::CPropertyIndex::GlobalIndexCAircraftModel,
IndexIsQueriedModelString
IndexCallsign,
IndexDescription,
IndexIcao,
IndexFileName,
IndexModelType,
IndexModelTypeAsString,
IndexHasQueriedModelString
};
//! Default constructor.
CAircraftModel() : m_queriedModelStringFlag(false) {}
CAircraftModel() {}
//! Constructor.
CAircraftModel(const QString &model, bool isQueriedString) : m_modelString(model), m_queriedModelStringFlag(isQueriedString) {}
CAircraftModel(const QString &model, ModelType type) : m_modelString(model), m_modelType(type) {}
//! Constructor
CAircraftModel(const BlackMisc::Aviation::CAircraft &aircraft);
//! \copydoc CValueObject::propertyByIndex
virtual CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const override;
@@ -44,34 +65,97 @@ namespace BlackMisc
//! \copydoc CValueObject::setPropertyByIndex
virtual void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index) override;
//! Corresponding callsign if applicable
const BlackMisc::Aviation::CCallsign &getCallsign() const { return this->m_callsign; }
//! Corresponding callsign if applicable
void setCallsign(const BlackMisc::Aviation::CCallsign &callsign) { this->m_callsign = callsign; }
//! Callsign empty
bool isCallsignEmpty() const { return this->m_callsign.isEmpty(); }
//! Queried model string
const QString &getModelString() const { return this->m_modelString; }
//! Queried model string
//! Model string
void setModelString(const QString &modelString) { this->m_modelString = modelString; }
//! Descriptive text
const QString &getDescription() const { return this->m_description; }
//! Descriptive text
void setDescription(const QString &description) { this->m_description = description; }
//! Set queried model string
void setQueriedModelString(const QString &model) { this->m_modelString = model; }
void setQueriedModelString(const QString &model) { this->m_modelString = model; this->m_modelType = TypeQueriedFromNetwork; }
//! ICAO code
BlackMisc::Aviation::CAircraftIcao getIcao() const { return this->m_icao; }
//! Set ICAO info
void setIcao(const BlackMisc::Aviation::CAircraftIcao &icao) { this->m_icao = icao; }
//! \copydoc CAircraftIcao::hasAircraftAndAirlineDesignator
bool hasAircraftAndAirlineDesignator() const { return this->m_icao.hasAircraftAndAirlineDesignator(); }
//! \copydoc CAircraftIcao::hasAircraftDesignator
bool hasAircraftDesignator() const { return this->m_icao.hasAircraftDesignator(); }
//! Model type
ModelType getModelType() const { return static_cast<ModelType>(m_modelType); }
//! Model type
QString getModelTypeAsString() const { return modelTypeToString(getModelType()); }
//! Set type
void setModelType(ModelType type) { this->m_modelType = static_cast<int>(type); }
//! File name
QString getFileName() const { return m_fileName; }
//! File name
void setFileName(const QString &fileName) { m_fileName = fileName; }
//! Update missing parts from another model
void updateMissingParts(const CAircraftModel &model);
//! Queried model string?
bool hasQueriedModelString() const { return this->m_queriedModelStringFlag && !this->m_modelString.isEmpty(); }
bool hasQueriedModelString() const { return this->m_modelType == TypeQueriedFromNetwork && this->hasModelString(); }
//! Non empty model string
bool hasModelString() const { return !m_modelString.isEmpty(); }
//! Matches model string?
bool matchesModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const;
//! Model type
static QString modelTypeToString(ModelType type);
protected:
//! \copydoc CValueObject::convertToQString
virtual QString convertToQString(bool i18n = false) const override;
private:
BLACK_ENABLE_TUPLE_CONVERSION(CAircraftModel)
QString m_modelString;
bool m_queriedModelStringFlag; //!< model string is queried from network?
BlackMisc::Aviation::CCallsign m_callsign; //!< aircraft's callsign
BlackMisc::Aviation::CAircraftIcao m_icao; //!< ICAO data if available
QString m_modelString; //!< Simulator model string
QString m_description; //!< descriptive text
QString m_fileName; //!< file name
int m_modelType = static_cast<int>(TypeUnknown); //!< model string is queried from network?
};
} // namespace
} // namespace
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Network::CAircraftModel, (o.m_modelString, o.m_queriedModelStringFlag))
BLACK_DECLARE_TUPLE_CONVERSION(
BlackMisc::Network::CAircraftModel, (
attr(o.m_callsign),
attr(o.m_icao),
attr(o.m_modelString, flags<CaseInsensitiveComparison>()),
attr(o.m_description, flags<DisabledForComparison>()),
attr(o.m_fileName, flags <DisabledForComparison> ()),
attr(o.m_modelType)
))
Q_DECLARE_METATYPE(BlackMisc::Network::CAircraftModel)
#endif // guard