refs #452, adjusted aircraft/aviation classes

* support for loading from datastore
* improved timestamp handling
* new color and country classes
* new attributes
* updates for missing parts in CUser
This commit is contained in:
Klaus Basan
2015-09-23 03:20:36 +02:00
committed by Mathew Sutcliffe
parent c5f7179588
commit ae24700299
45 changed files with 2762 additions and 401 deletions

View File

@@ -11,6 +11,8 @@
#include "distributor.h"
#include "blackmisc/datastoreutility.h"
#include <QString>
#include <QJsonDocument>
#include <QJsonObject>
using namespace BlackMisc::Aviation;
@@ -19,15 +21,15 @@ namespace BlackMisc
namespace Simulation
{
CAircraftModel::CAircraftModel(const QString &model, CAircraftModel::ModelType type) :
m_modelString(model), m_modelType(type)
m_modelString(model.trimmed().toUpper()), m_modelType(type)
{}
CAircraftModel::CAircraftModel(const QString &model, CAircraftModel::ModelType type, const QString &description, const Aviation::CAircraftIcaoData &icao, const Aviation::CLivery &livery) :
m_icao(icao), m_livery(livery), m_modelString(model), m_description(description), m_modelType(type)
CAircraftModel::CAircraftModel(const QString &model, CAircraftModel::ModelType type, const QString &description, const CAircraftIcaoCode &icao, const Aviation::CLivery &livery) :
m_aircraftIcao(icao), m_livery(livery), m_modelString(model.trimmed().toUpper()), m_description(description.trimmed()), m_modelType(type)
{}
CAircraftModel::CAircraftModel(const Aviation::CAircraft &aircraft) :
m_callsign(aircraft.getCallsign()), m_icao(aircraft.getIcaoInfo()), m_livery(aircraft.getLivery())
CAircraftModel::CAircraftModel(const QString &model, CAircraftModel::ModelType type, CSimulatorInfo &simulator, const QString &name, const QString &description, const CAircraftIcaoCode &icao, const CLivery &livery) :
m_aircraftIcao(icao), m_livery(livery), m_simulator(simulator), m_modelString(model.trimmed().toUpper()), m_modelName(name.trimmed()), m_description(description.trimmed()), m_modelType(type)
{ }
QString CAircraftModel::convertToQString(bool i18n) const
@@ -36,7 +38,7 @@ namespace BlackMisc
if (!s.isEmpty()) { s += ' '; }
s += this->getModelTypeAsString();
s += ' ';
s += this->m_icao.toQString(i18n);
s += this->m_aircraftIcao.toQString(i18n);
if (!this->m_fileName.isEmpty())
{
s += ' ';
@@ -48,6 +50,7 @@ namespace BlackMisc
CVariant CAircraftModel::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
if (index.isMyself()) { return CVariant::from(*this); }
if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::propertyByIndex(index); }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
@@ -59,12 +62,24 @@ namespace BlackMisc
return CVariant::fromValue(static_cast<int>(this->m_modelType));
case IndexModelTypeAsString:
return CVariant(this->getModelTypeAsString());
case IndexModelMode:
return CVariant::fromValue(static_cast<int>(this->m_modelMode));
case IndexModelModeAsString:
return CVariant(this->getModelModeAsString());
case IndexDistributor:
return m_distributor.propertyByIndex(index.copyFrontRemoved());
case IndexSimulatorInfo:
return m_simulator.propertyByIndex(index.copyFrontRemoved());
case IndexSimulatorInfoAsString:
return CVariant(m_simulator.toQString());
case IndexDescription:
return CVariant(this->m_description);
case IndexName:
return CVariant(this->m_modelName);
case IndexFileName:
return CVariant(this->m_fileName);
case IndexIcao:
return m_icao.propertyByIndex(index.copyFrontRemoved());
case IndexAircraftIcaoCode:
return m_aircraftIcao.propertyByIndex(index.copyFrontRemoved());
case IndexLivery:
return m_livery.propertyByIndex(index.copyFrontRemoved());
case IndexCallsign:
@@ -83,15 +98,24 @@ namespace BlackMisc
case IndexModelString:
this->m_modelString = variant.toQString();
break;
case IndexIcao:
this->m_icao.setPropertyByIndex(variant, index.copyFrontRemoved());
case IndexAircraftIcaoCode:
this->m_aircraftIcao.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexLivery:
this->m_livery.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexDistributor:
this->m_distributor.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexDescription:
this->m_description = variant.toQString();
break;
case IndexSimulatorInfo:
this->m_simulator.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexName:
this->m_modelName = variant.toQString();
break;
case IndexCallsign:
this->m_callsign.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
@@ -101,30 +125,67 @@ namespace BlackMisc
case IndexModelType:
this->m_modelType = static_cast<ModelType>(variant.toInt());
break;
case IndexModelMode:
this->m_modelMode = static_cast<ModelMode>(variant.toInt());
break;
default:
CValueObject::setPropertyByIndex(variant, index);
break;
}
}
const CAircraftIcaoCode &CAircraftModel::getAircraftIcaoCode() const
bool CAircraftModel::setAircraftIcaoCode(const CAircraftIcaoCode &aircraftIcaoCode)
{
return m_icao.getAircraftIcaoCode();
if (this->m_aircraftIcao == aircraftIcaoCode) { return false; }
this->m_aircraftIcao = aircraftIcaoCode;
return true;
}
const CAirlineIcaoCode &CAircraftModel::getAirlineIcaoCode() const
void CAircraftModel::setAircraftIcaoDesignator(const QString &designator)
{
return m_icao.getAirlineIcaoCode();
this->m_aircraftIcao.setDesignator(designator);
}
void CAircraftModel::setAircraftIcaoCodes(const CAircraftIcaoCode &aircraftIcaoCode, const CAirlineIcaoCode &airlineIcaoCode)
{
m_aircraftIcao = aircraftIcaoCode;
m_livery.setAirlineIcaoCode(airlineIcaoCode);
}
bool CAircraftModel::hasAircraftAndAirlineDesignator() const
{
return this->m_aircraftIcao.hasDesignator() && this->m_livery.hasValidAirlineDesignator();
}
bool CAircraftModel::hasAircraftDesignator() const
{
return this->m_aircraftIcao.hasDesignator();
}
bool CAircraftModel::hasAirlineDesignator() const
{
return this->m_livery.hasValidAirlineDesignator();
}
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(); }
if (this->m_modelString.isEmpty()) { this->setModelString(model.getModelString()); }
if (this->m_description.isEmpty()) { this->setDescription(model.getDescription()); }
if (this->m_fileName.isEmpty()) { this->setFileName(model.getFileName()); }
if (this->m_callsign.isEmpty()) { this->setCallsign(model.getCallsign()); }
if (this->m_modelType == static_cast<int>(TypeUnknown)) { this->m_modelType = model.getModelType(); }
this->m_icao.updateMissingParts(model.getIcao());
if (this->m_simulator.isUnspecified())
{
this->setSimulatorInfo(model.getSimulatorInfo());
}
else
{
this->m_simulator.add(model.getSimulatorInfo());
}
this->m_livery.updateMissingParts(model.getLivery());
this->m_aircraftIcao.updateMissingParts(model.getAircraftIcaoCode());
this->m_distributor.updateMissingParts(model.getDistributor());
}
bool CAircraftModel::hasQueriedModelString() const
@@ -137,6 +198,11 @@ namespace BlackMisc
return this->m_modelType == TypeManuallySet && this->hasModelString();
}
bool CAircraftModel::hasValidSimulator() const
{
return m_simulator.isAnySimulator();
}
bool CAircraftModel::matchesModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const
{
if (sensitivity == Qt::CaseSensitive)
@@ -150,13 +216,29 @@ namespace BlackMisc
}
}
CStatusMessageList CAircraftModel::validate(bool withNestedObjects) const
{
static const CLogCategoryList cats( { CLogCategory(this->getClassName()), CLogCategory::validation()});
CStatusMessageList msgs;
if (!hasModelString()) { msgs.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Model: missing model string (aka key)")); }
if (!hasValidSimulator()) {msgs.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Model: no simulator set")); }
if (!hasDescription()) {msgs.push_back(CStatusMessage(cats, CStatusMessage::SeverityWarning, "Model: no description")); }
if (withNestedObjects)
{
msgs.push_back(m_aircraftIcao.validate());
msgs.push_back(m_livery.validate());
msgs.push_back(m_distributor.validate());
}
return msgs;
}
QString CAircraftModel::modelTypeToString(CAircraftModel::ModelType type)
{
switch (type)
{
case TypeQueriedFromNetwork: return "queried";
case TypeModelMatching: return "matching";
case TypeModelMapping: return "mapping";
case TypeDatabaseEntry: return "database";
case TypeModelMatchingDefaultModel: return "map. default";
case TypeOwnSimulatorModel: return "own simulator";
case TypeManuallySet: return "set";
@@ -165,38 +247,49 @@ namespace BlackMisc
}
}
CAircraftModel CAircraftModel::fromDatabaseJson(const QJsonObject &json)
CAircraftModel::ModelMode CAircraftModel::modelModeFromString(const QString &mode)
{
QJsonArray inner = json["cell"].toArray();
Q_ASSERT_X(!inner.isEmpty(), Q_FUNC_INFO, "Missing JSON");
if (inner.isEmpty()) { return CAircraftModel(); }
// int i = 0;
int i = 0;
int dbKey(inner.at(i++).toInt(-1));
QString modelString(inner.at(i++).toString());
QString distributorKey(inner.at(i++).toString());
QString liveryDescription(inner.at(i++).toString());
QString modelDescription;
CAircraftIcaoData aircraftIcao;
CAirlineIcaoCode airlineIcao;
CLivery livery;
CDistributor distributor(distributorKey, "", "", "");
bool fsx = CDatastoreUtility::dbBoolStringToBool(inner.at(i++).toString());
bool fs9 = CDatastoreUtility::dbBoolStringToBool(inner.at(i++).toString());
bool xp = CDatastoreUtility::dbBoolStringToBool(inner.at(i++).toString());
CSimulatorInfo simInfo(fsx, fs9, xp);
CAircraftModel model(
modelString, CAircraftModel::TypeModelMapping, modelDescription, aircraftIcao, livery
);
model.setDbKey(dbKey);
model.setSimulatorInfo(simInfo);
return model;
if (mode.isEmpty() || mode.startsWith('I', Qt::CaseInsensitive)) { return Include;}
if (mode.startsWith('E', Qt::CaseInsensitive)) { return Exclude; }
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong mode");
return Include; // default
}
QString CAircraftModel::modelModeToString(CAircraftModel::ModelMode mode)
{
switch (mode)
{
case Include: return "Include";
case Exclude: return "Exclude";
default: Q_ASSERT_X(false, Q_FUNC_INFO, "wrong mode");
}
return "Include";
}
CAircraftModel CAircraftModel::fromDatabaseJson(const QJsonObject &json, const QString prefix)
{
QString modelString(json.value(prefix + "simkey").toString());
QString modelDescription(json.value(prefix + "description").toString());
QString modelName(json.value(prefix + "name").toString());
QString modelMode(json.value(prefix + "mode").toString());
bool fsx = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "simfsx").toString());
bool fs9 = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "simfs9").toString());
bool xp = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "simxplane").toString());
bool p3d = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "simp3d").toString());
CAircraftIcaoCode aircraftIcao(CAircraftIcaoCode::fromDatabaseJson(json, "ac_"));
CLivery livery(CLivery::fromDatabaseJson(json, "liv_"));
CDistributor distributor(CDistributor::fromDatabaseJson(json, "dist_"));
CSimulatorInfo simInfo(fsx, fs9, xp, p3d);
CAircraftModel model(
modelString, CAircraftModel::TypeDatabaseEntry, simInfo, modelName, modelDescription, aircraftIcao, livery
);
model.setDistributor(distributor);
model.setModelMode(modelModeFromString(modelMode));
model.setKeyAndTimestampFromDatabaseJson(json, prefix);
return model;
}
} // namespace
} // namespace

View File

@@ -14,11 +14,12 @@
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/simulation/simulatorinfo.h"
#include "blackmisc/aviation/aircraft.h"
#include "blackmisc/aviation/aircrafticaodata.h"
#include "blackmisc/simulation/distributor.h"
#include "blackmisc/aviation/livery.h"
#include "blackmisc/aviation/aircrafticaocode.h"
#include "blackmisc/network/user.h"
#include "blackmisc/propertyindex.h"
#include <QUrlQuery>
namespace BlackMisc
{
@@ -36,11 +37,20 @@ namespace BlackMisc
{
TypeUnknown,
TypeQueriedFromNetwork, //!< model was queried by network protocol
TypeFsdData, //!< model based on FSD ICAO data
TypeModelMatching, //!< model is result of model matching
TypeModelMatchingDefaultModel, //!< a default model assigned by model matching
TypeModelMapping, //!< used along with mapping definition
TypeDatabaseEntry, //!< used along with mapping definition
TypeManuallySet, //!< manually set, e.g. from GUI
TypeOwnSimulatorModel //!< represents own simulator model
TypeOwnSimulatorModel, //!< represents own simulator model
TypeVPilotRuleBased //!< based on a vPilot rule
};
//! Mode
enum ModelMode
{
Include,
Exclude
};
//! Indexes
@@ -48,12 +58,18 @@ namespace BlackMisc
{
IndexModelString = BlackMisc::CPropertyIndex::GlobalIndexCAircraftModel,
IndexCallsign,
IndexName,
IndexDescription,
IndexIcao,
IndexSimulatorInfo,
IndexSimulatorInfoAsString,
IndexAircraftIcaoCode,
IndexLivery,
IndexDistributor,
IndexFileName,
IndexModelType,
IndexModelTypeAsString,
IndexModelMode,
IndexModelModeAsString,
IndexHasQueriedModelString
};
@@ -64,10 +80,10 @@ namespace BlackMisc
CAircraftModel(const QString &model, ModelType type);
//! Constructor.
CAircraftModel(const QString &model, ModelType type, const QString &description, const BlackMisc::Aviation::CAircraftIcaoData &icao, const BlackMisc::Aviation::CLivery &livery = BlackMisc::Aviation::CLivery());
CAircraftModel(const QString &model, ModelType type, const QString &description, const BlackMisc::Aviation::CAircraftIcaoCode &icao, const BlackMisc::Aviation::CLivery &livery = BlackMisc::Aviation::CLivery());
//! Constructor
CAircraftModel(const BlackMisc::Aviation::CAircraft &aircraft);
//! Constructor.
CAircraftModel(const QString &model, ModelType type, CSimulatorInfo &simulator, const QString &name, const QString &description, const BlackMisc::Aviation::CAircraftIcaoCode &icao, const BlackMisc::Aviation::CLivery &livery = BlackMisc::Aviation::CLivery());
//! \copydoc CValueObject::propertyByIndex
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
@@ -88,7 +104,7 @@ namespace BlackMisc
const QString &getModelString() const { return this->m_modelString; }
//! Model string
void setModelString(const QString &modelString) { this->m_modelString = modelString; }
void setModelString(const QString &modelString) { this->m_modelString = modelString.trimmed().toUpper(); }
//! Descriptive text
const QString &getDescription() const { return this->m_description; }
@@ -99,23 +115,35 @@ namespace BlackMisc
//! Set queried model string
void setQueriedModelString(const QString &model) { this->m_modelString = model; this->m_modelType = TypeQueriedFromNetwork; }
//! ICAO code
BlackMisc::Aviation::CAircraftIcaoData getIcao() const { return this->m_icao; }
//! Set ICAO info
void setIcao(const BlackMisc::Aviation::CAircraftIcaoData &icao) { this->m_icao = icao; }
//! \copydoc CAircraftIcaoData::hasAircraftAndAirlineDesignator
bool hasAircraftAndAirlineDesignator() const { return this->m_icao.hasAircraftAndAirlineDesignator(); }
//! \copydoc CAircraftIcaoData::hasAircraftDesignator
bool hasAircraftDesignator() const { return this->m_icao.hasAircraftDesignator(); }
//! Aircraft ICAO code
const BlackMisc::Aviation::CAircraftIcaoCode &getAircraftIcaoCode() const;
const BlackMisc::Aviation::CAircraftIcaoCode &getAircraftIcaoCode() const { return this->m_aircraftIcao; }
//! Aircraft ICAO code designator
const QString &getAircraftIcaoCodeDesignator() const { return this->m_aircraftIcao.getDesignator(); }
//! Airline ICAO code
const BlackMisc::Aviation::CAirlineIcaoCode &getAirlineIcaoCode() const;
const BlackMisc::Aviation::CAirlineIcaoCode &getAirlineIcaoCode() const { return this->m_livery.getAirlineIcaoCode(); }
//! Airline ICAO code designator
const QString &getAirlineIcaoCodeDesignator() const { return this->m_livery.getAirlineIcaoCode().getDesignator(); }
//! Set aircraft ICAO code
bool setAircraftIcaoCode(const BlackMisc::Aviation::CAircraftIcaoCode &aircraftIcaoCode);
//! Set aircraft ICAO code designator
void setAircraftIcaoDesignator(const QString &designator);
//! Set ICAO codes
void setAircraftIcaoCodes(const BlackMisc::Aviation::CAircraftIcaoCode &aircraftIcaoCode, const BlackMisc::Aviation::CAirlineIcaoCode &airlineIcaoCode);
//! Airline and aircraft designator?
bool hasAircraftAndAirlineDesignator() const;
//! Has aircraft designator?
bool hasAircraftDesignator() const;
//! Airline designator?
bool hasAirlineDesignator() const;
//! Get livery
const BlackMisc::Aviation::CLivery &getLivery() const { return m_livery; }
@@ -126,6 +154,18 @@ namespace BlackMisc
//! Livery available?
bool hasLivery() const { return m_livery.hasCompleteData();}
//! Get distributor
const CDistributor &getDistributor() const { return m_distributor; }
//! Set distributor
void setDistributor(const CDistributor &distributor) { m_distributor = distributor; }
//! Name
const QString &getName() const { return this->m_modelName; }
//! Name
void setName(const QString &name) { this->m_modelName = name.trimmed(); }
//! Model type
ModelType getModelType() const { return m_modelType; }
@@ -135,6 +175,15 @@ namespace BlackMisc
//! Set type
void setModelType(ModelType type) { this->m_modelType = type; }
//! Model mode
ModelMode getModelMode() const { return m_modelMode; }
//! Model mode as string
QString getModelModeAsString() const { return modelModeToString(getModelMode()); }
//! Set model mode
void setModelMode(ModelMode mode) { m_modelMode = mode; }
//! Simulator info
CSimulatorInfo getSimulatorInfo() const { return this->m_simulator; }
@@ -162,41 +211,65 @@ namespace BlackMisc
//! Non empty model string
bool hasModelString() const { return !m_modelString.isEmpty(); }
//! Description
bool hasDescription() const { return !m_description.isEmpty(); }
//! Valid simulator
bool hasValidSimulator() const;
//! Matches model string?
bool matchesModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const;
//! Validate
BlackMisc::CStatusMessageList validate(bool withNestedObjects) const;
//! \copydoc CValueObject::convertToQString
QString convertToQString(bool i18n = false) const;
//! Model type
static QString modelTypeToString(ModelType type);
//! Model mode
static ModelMode modelModeFromString(const QString &mode);
//! Model mode
static QString modelModeToString(ModelMode mode);
//! From swift DB JSON
static CAircraftModel fromDatabaseJson(const QJsonObject &json);
static CAircraftModel fromDatabaseJson(const QJsonObject &json, const QString prefix = QString("mod_"));
private:
BLACK_ENABLE_TUPLE_CONVERSION(CAircraftModel)
BlackMisc::Aviation::CCallsign m_callsign; //!< aircraft's callsign if any
BlackMisc::Aviation::CAircraftIcaoData m_icao; //!< ICAO data if available
BlackMisc::Aviation::CLivery m_livery; //!< livery information
CSimulatorInfo m_simulator; //!< model for given simulator
QString m_modelString; //!< Simulator model string
QString m_description; //!< descriptive text
QString m_fileName; //!< file name
ModelType m_modelType = TypeUnknown; //!< model string is coming from ...?
BlackMisc::Aviation::CCallsign m_callsign; //!< aircraft's callsign if any
BlackMisc::Aviation::CAircraftIcaoCode m_aircraftIcao; //!< ICAO code if available
BlackMisc::Aviation::CLivery m_livery; //!< livery information
CSimulatorInfo m_simulator; //!< model for given simulator
CDistributor m_distributor; //!< who designed or distributed the model
QString m_modelString; //!< Simulator model string
QString m_modelName; //!< Model name
QString m_description; //!< descriptive text
QString m_fileName; //!< file name
ModelType m_modelType = TypeUnknown; //!< model string is coming representing ...?
ModelMode m_modelMode = Include; //!< model mode (include / exclude)
};
} // namespace
} // namespace
BLACK_DECLARE_TUPLE_CONVERSION(
BlackMisc::Simulation::CAircraftModel, (
attr(o.m_dbKey),
attr(o.m_timestampMSecsSinceEpoch),
attr(o.m_callsign),
attr(o.m_icao),
attr(o.m_aircraftIcao),
attr(o.m_livery),
attr(o.m_simulator),
attr(o.m_distributor),
attr(o.m_modelString, flags<CaseInsensitiveComparison>()),
attr(o.m_modelName),
attr(o.m_description, flags<DisabledForComparison>()),
attr(o.m_fileName, flags <DisabledForComparison> ()),
attr(o.m_modelType)
attr(o.m_modelType),
attr(o.m_modelMode)
))
Q_DECLARE_METATYPE(BlackMisc::Simulation::CAircraftModel)

View File

@@ -38,8 +38,70 @@ namespace BlackMisc
CAircraftModel CAircraftModelList::findFirstByModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const
{
CAircraftModelList ml = findByModelString(modelString, sensitivity);
return ml.frontOrDefault();
return this->findFirstBy([ = ](const CAircraftModel & model)
{
return model.matchesModelString(modelString, sensitivity);
});
}
CAircraftModelList CAircraftModelList::findByIcaoDesignators(const CAircraftIcaoCode &aircraftIcaoCode, const CAirlineIcaoCode &airlineIcaoCode) const
{
const QString aircraft(aircraftIcaoCode.getDesignator());
const QString airline(airlineIcaoCode.getDesignator());
if (airline.isEmpty())
{
return this->findBy([ = ](const CAircraftModel & model)
{
return model.getAircraftIcaoCode().getDesignator() == aircraft;
});
}
if (aircraft.isEmpty())
{
return this->findBy([ = ](const CAircraftModel & model)
{
return model.getAirlineIcaoCode().getDesignator() == airline;
});
}
return this->findBy([ = ](const CAircraftModel & model)
{
return model.getAirlineIcaoCode().getDesignator() == airline &&
model.getAircraftIcaoCode().getDesignator() == aircraft;
});
}
CAircraftModelList CAircraftModelList::findByAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode) const
{
if (aircraftDesignator.isEmpty()) { return CAircraftModelList(); }
return this->findBy([ = ](const CAircraftModel & model)
{
if (!model.getAircraftIcaoCode().matchesDesignator(aircraftDesignator)) { return false; }
return model.getLivery().matchesCombinedCode(combinedCode);
});
}
void CAircraftModelList::setSimulatorInfo(const CSimulatorInfo &info)
{
for (CAircraftModel &model : (*this))
{
model.setSimulatorInfo(info);
}
}
int CAircraftModelList::keepModelsWithString(const QStringList &modelStrings, Qt::CaseSensitivity sensitivity)
{
int cs = this->size();
(*this) = (findByModelStrings(modelStrings, sensitivity));
int d = cs - this->size();
return d;
}
int CAircraftModelList::removeModelsWithString(const QStringList &modelStrings, Qt::CaseSensitivity sensitivity)
{
int cs = this->size();
(*this) = (findByNotInModelStrings(modelStrings, sensitivity));
int d = cs - this->size();
return d;
}
CAircraftModelList CAircraftModelList::findModelsStartingWith(const QString &modelString, Qt::CaseSensitivity sensitivity) const
@@ -50,6 +112,22 @@ namespace BlackMisc
});
}
CAircraftModelList CAircraftModelList::findByModelStrings(const QStringList &modelStrings, Qt::CaseSensitivity sensitivity) const
{
return this->findBy([ = ](const CAircraftModel & model)
{
return modelStrings.contains(model.getModelString(), sensitivity);
});
}
CAircraftModelList CAircraftModelList::findByNotInModelStrings(const QStringList &modelStrings, Qt::CaseSensitivity sensitivity) const
{
return this->findBy([ = ](const CAircraftModel & model)
{
return !modelStrings.contains(model.getModelString(), sensitivity);
});
}
QStringList CAircraftModelList::getSortedModelStrings() const
{
QStringList ms;

View File

@@ -49,6 +49,29 @@ namespace BlackMisc
//! Find models starting with
CAircraftModelList findModelsStartingWith(const QString &modelString, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive) const;
//! Find by a given list of models by strings
CAircraftModelList findByModelStrings(const QStringList &modelStrings, Qt::CaseSensitivity sensitivity) const;
//! Find by a given list of models trings
CAircraftModelList findByNotInModelStrings(const QStringList &modelStrings, Qt::CaseSensitivity sensitivity) const;
//! Find by model string
CAircraftModelList findByIcaoDesignators(const BlackMisc::Aviation::CAircraftIcaoCode &aircraftIcaoCode, const BlackMisc::Aviation::CAirlineIcaoCode &airlineIcaoCode) const;
//! Find by model string
CAircraftModelList findByAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode) const;
//! Set simulator for all elements
void setSimulatorInfo(const BlackMisc::Simulation::CSimulatorInfo &info);
//! Keep only those models with given model strings
//! \return number of elements removed
int keepModelsWithString(const QStringList &modelStrings, Qt::CaseSensitivity sensitivity);
//! Remove those models with given model strings
//! \return number of elements removed
int removeModelsWithString(const QStringList &modelStrings, Qt::CaseSensitivity sensitivity);
//! Model strings
QStringList getSortedModelStrings() const;
};

View File

@@ -23,8 +23,13 @@ namespace BlackMisc
init();
}
CSimulatedAircraft::CSimulatedAircraft(const CAircraft &aircraft, const CAircraftModel &model, const CClient &client) :
CValueObject(aircraft), m_model(model), m_client(client)
CSimulatedAircraft::CSimulatedAircraft(const CAircraftModel &model) : m_model(model)
{
init();
}
CSimulatedAircraft::CSimulatedAircraft(const CCallsign &callsign, const CUser &user, const CAircraftSituation &situation) :
m_callsign(callsign), m_pilot(user), m_situation(situation)
{
init();
}
@@ -34,10 +39,209 @@ namespace BlackMisc
// sync some values, order here is crucial
// set get/set thing here updates the redundant data (e.g. livery / model.livery)
this->setCallsign(this->getCallsign());
this->setIcaoInfo(this->getIcaoInfo());
this->setIcaoCodes(this->getAircraftIcaoCode(), this->getAirlineIcaoCode());
this->setLivery(this->getLivery());
this->setModel(this->getModel());
this->setPilot(this->hasValidRealName() ? this->getPilot() : this->getClient().getUser());
}
void CSimulatedAircraft::setCockpit(const CComSystem &com1, const CComSystem &com2, const CTransponder &transponder)
{
this->setCom1System(com1);
this->setCom2System(com2);
this->setTransponder(transponder);
}
void CSimulatedAircraft::setCockpit(const CComSystem &com1, const CComSystem &com2, int transponderCode, CTransponder::TransponderMode transponderMode)
{
this->setCom1System(com1);
this->setCom2System(com2);
this->m_transponder.setTransponderCode(transponderCode);
this->m_transponder.setTransponderMode(transponderMode);
}
bool CSimulatedAircraft::hasChangedCockpitData(const CComSystem &com1, const CComSystem &com2, const CTransponder &transponder) const
{
return this->getCom1System() != com1 || this->getCom2System() != com2 || this->getTransponder() != transponder;
}
bool CSimulatedAircraft::hasSameComData(const CComSystem &com1, const CComSystem &com2, const CTransponder &transponder)
{
return this->getCom1System() == com1 && this->getCom2System() == com2 && this->getTransponder() == transponder;
}
bool CSimulatedAircraft::isValidForLogin() const
{
if (this->m_callsign.asString().isEmpty()) { return false; }
if (!this->m_pilot.isValid()) { return false; }
return true;
}
void CSimulatedAircraft::setSituation(const CAircraftSituation &situation)
{
m_situation = situation;
m_situation.setCallsign(this->getCallsign());
}
const CAircraftIcaoCode &CSimulatedAircraft::getAircraftIcaoCode() const
{
return m_model.getAircraftIcaoCode();
}
void CSimulatedAircraft::setPilot(const Network::CUser &user)
{
m_pilot = user;
this->m_pilot.setCallsign(this->m_callsign);
}
const QString &CSimulatedAircraft::getAircraftIcaoCodeDesignator() const
{
return getAircraftIcaoCode().getDesignator();
}
const QString &CSimulatedAircraft::getAircraftIcaoCombinedType() const
{
return getAircraftIcaoCode().getCombinedType();
}
bool CSimulatedAircraft::setIcaoCodes(const CAircraftIcaoCode &aircraftIcaoCode, const CAirlineIcaoCode &airlineIcaoCode)
{
bool c = this->m_model.setAircraftIcaoCode(aircraftIcaoCode);
return m_livery.setAirlineIcaoCode(airlineIcaoCode) || c;
}
const CAirlineIcaoCode &CSimulatedAircraft::getAirlineIcaoCode() const
{
return m_livery.getAirlineIcaoCode();
}
const QString &CSimulatedAircraft::getAirlineIcaoCodeDesignator() const
{
return getAircraftIcaoCode().getDesignator();
}
void CSimulatedAircraft::setAircraftIcaoDesignator(const QString &designator)
{
this->m_model.setAircraftIcaoDesignator(designator);
}
bool CSimulatedAircraft::hasAircraftDesignator() const
{
return this->getAircraftIcaoCode().hasDesignator();
}
bool CSimulatedAircraft::hasAircraftAndAirlineDesignator() const
{
return this->getAircraftIcaoCode().hasDesignator() && m_livery.hasValidAirlineDesignator();
}
const CComSystem CSimulatedAircraft::getComSystem(CComSystem::ComUnit unit) const
{
switch (unit)
{
case CComSystem::Com1: return this->getCom1System();
case CComSystem::Com2: return this->getCom2System();
default: break;
}
Q_ASSERT(false);
return CComSystem(); // avoid warning
}
void CSimulatedAircraft::setComSystem(const CComSystem &com, CComSystem::ComUnit unit)
{
switch (unit)
{
case CComSystem::Com1: this->setCom1System(com); break;
case CComSystem::Com2: this->setCom2System(com); break;
}
}
bool CSimulatedAircraft::setCom1ActiveFrequency(const CFrequency &frequency)
{
if (!CComSystem::isValidComFrequency(frequency)) { return false; }
this->m_com1system.setFrequencyActive(frequency);
return true;
}
bool CSimulatedAircraft::setCom2ActiveFrequency(const CFrequency &frequency)
{
if (!CComSystem::isValidComFrequency(frequency)) { return false; }
this->m_com2system.setFrequencyActive(frequency);
return true;
}
bool CSimulatedAircraft::setComActiveFrequency(const CFrequency &frequency, CComSystem::ComUnit unit)
{
if (!CComSystem::isValidComFrequency(frequency)) { return false; }
switch (unit)
{
case CComSystem::Com1: return this->setCom1ActiveFrequency(frequency);
case CComSystem::Com2: return this->setCom2ActiveFrequency(frequency);
}
return false;
}
void CSimulatedAircraft::initComSystems()
{
CComSystem com1("COM1", CPhysicalQuantitiesConstants::FrequencyUnicom(), CPhysicalQuantitiesConstants::FrequencyUnicom());
CComSystem com2("COM2", CPhysicalQuantitiesConstants::FrequencyUnicom(), CPhysicalQuantitiesConstants::FrequencyUnicom());
this->setCom1System(com1);
this->setCom2System(com2);
}
void CSimulatedAircraft::initTransponder()
{
CTransponder xpdr(7000, CTransponder::StateStandby);
this->setTransponder(xpdr);
}
CAircraftLights CSimulatedAircraft::getLights() const
{
return m_parts.getLights();
}
void CSimulatedAircraft::setParts(const CAircraftParts &parts)
{
m_parts = parts;
m_parts.setCallsign(this->getCallsign());
}
void CSimulatedAircraft::setLights(CAircraftLights &lights)
{
m_parts.setLights(lights);
}
void CSimulatedAircraft::setAllLightsOn()
{
m_parts.setAllLightsOn();
}
void CSimulatedAircraft::setAllLightsOff()
{
m_parts.setAllLightsOff();
}
bool CSimulatedAircraft::isVtol() const
{
return getAircraftIcaoCode().isVtol();
}
QString CSimulatedAircraft::getCombinedIcaoLiveryString() const
{
if (this->hasAircraftAndAirlineDesignator())
{
QString s("%1 (%2)");
return s.arg(getAircraftIcaoCodeDesignator()).arg(getAirlineIcaoCodeDesignator());
}
if (!this->hasAircraftDesignator())
{
return getLivery().getCombinedCode();
}
else
{
QString s("%1 (%2)");
return s.arg(getAircraftIcaoCodeDesignator()).arg(getLivery().getCombinedCode());
}
}
CVariant CSimulatedAircraft::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
@@ -48,8 +252,6 @@ namespace BlackMisc
{
case IndexModel:
return this->m_model.propertyByIndex(index.copyFrontRemoved());
case IndexClient:
return this->m_client.propertyByIndex(index.copyFrontRemoved());
case IndexEnabled:
return CVariant::fromValue(this->isEnabled());
case IndexRendered:
@@ -58,8 +260,34 @@ namespace BlackMisc
return CVariant::fromValue(this->isPartsSynchronized());
case IndexFastPositionUpdates:
return CVariant::fromValue(this->fastPositionUpdates());
case IndexCallsign:
return this->m_callsign.propertyByIndex(index.copyFrontRemoved());
case IndexPilot:
return this->m_pilot.propertyByIndex(index.copyFrontRemoved());
case IndexDistanceToOwnAircraft:
return this->m_distanceToOwnAircraft.propertyByIndex(index.copyFrontRemoved());
case IndexCom1System:
return this->m_com1system.propertyByIndex(index.copyFrontRemoved());
case IndexCom2System:
return this->m_com2system.propertyByIndex(index.copyFrontRemoved());
case IndexTransponder:
return this->m_transponder.propertyByIndex(index.copyFrontRemoved());
case IndexSituation:
return this->m_situation.propertyByIndex(index.copyFrontRemoved());
case IndexAircraftIcaoCode:
return this->getAircraftIcaoCode().propertyByIndex(index.copyFrontRemoved());
case IndexLivery:
return this->m_livery.propertyByIndex(index.copyFrontRemoved());
case IndexParts:
return this->m_parts.propertyByIndex(index.copyFrontRemoved());
case IndexIsVtol:
return CVariant::fromValue(this->isVtol());
case IndexCombinedIcaoLiveryString:
return CVariant::fromValue(this->getCombinedIcaoLiveryString());
default:
return CAircraft::propertyByIndex(index);
return (ICoordinateGeodetic::canHandleIndex(index)) ?
ICoordinateGeodetic::propertyByIndex(index) :
CValueObject::propertyByIndex(index);
}
}
@@ -69,13 +297,40 @@ namespace BlackMisc
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexCallsign:
this->m_callsign.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexPilot:
this->m_pilot.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexDistanceToOwnAircraft:
this->m_distanceToOwnAircraft.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexCom1System:
this->m_com1system.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexCom2System:
this->m_com2system.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexTransponder:
this->m_transponder.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexAircraftIcaoCode:
this->m_livery.setPropertyByIndex(variant, index); // intentionally not removing front, delegating
break;
case IndexLivery:
this->m_livery.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexSituation:
this->m_situation.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexParts:
this->m_parts.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexModel:
this->m_model.setPropertyByIndex(variant, index.copyFrontRemoved());
this->setModel(this->m_model); // sync some values
break;
case IndexClient:
this->m_client.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexEnabled:
this->m_enabled = variant.toBool();
break;
@@ -89,7 +344,7 @@ namespace BlackMisc
this->m_fastPositionUpdates = variant.toBool();
break;
default:
CAircraft::setPropertyByIndex(variant, index);
CValueObject::setPropertyByIndex(variant, index);
break;
}
}
@@ -99,7 +354,7 @@ namespace BlackMisc
// sync the callsigns
this->m_model = model;
this->setCallsign(this->hasValidCallsign() ? this->getCallsign() : model.getCallsign());
this->setIcaoInfo(model.getIcao());
this->setIcaoCodes(model.getAircraftIcaoCode(), model.getAirlineIcaoCode());
}
void CSimulatedAircraft::setModelString(const QString &modelString)
@@ -109,54 +364,35 @@ namespace BlackMisc
void CSimulatedAircraft::setCallsign(const CCallsign &callsign)
{
CAircraft::setCallsign(callsign); // also sets correct hint
this->m_model.setCallsign(getCallsign());
this->m_client.setUserCallsign(getCallsign());
this->m_callsign = callsign;
this->m_model.setCallsign(callsign);
}
void CSimulatedAircraft::setIcaoInfo(const CAircraftIcaoData &icao)
bool CSimulatedAircraft::isActiveFrequencyWithin8_33kHzChannel(const CFrequency &comFrequency) const
{
// snyc ICAO info
CAircraftIcaoData newIcao(icao);
newIcao.updateMissingParts(this->getIcaoInfo());
newIcao.updateMissingParts(this->getModel().getIcao());
// now we have a superset of ICAO data
this->m_model.setIcao(newIcao);
CAircraft::setIcaoInfo(newIcao);
return this->m_com1system.isActiveFrequencyWithin8_33kHzChannel(comFrequency) ||
this->m_com2system.isActiveFrequencyWithin8_33kHzChannel(comFrequency);
}
void CSimulatedAircraft::setLivery(const CLivery &livery)
bool CSimulatedAircraft::isActiveFrequencyWithin25kHzChannel(const CFrequency &comFrequency) const
{
this->m_model.setLivery(livery);
CAircraft::setLivery(livery);
}
void CSimulatedAircraft::setPilot(const CUser &user)
{
this->m_client.setUser(user);
CAircraft::setPilot(user);
}
void CSimulatedAircraft::setClient(const CClient &client)
{
Q_ASSERT(client.getCallsign() == this->getCallsign());
m_client = client;
}
//! \todo Smarter way to do this?
void CSimulatedAircraft::setAircraft(const CAircraft &aircraft)
{
static_cast<CAircraft &>(*this) = aircraft;
this->m_model.setCallsign(aircraft.getCallsign());
this->m_client.setAircraftModel(this->getModel());
this->m_client.setUser(aircraft.getPilot());
this->m_client.setUserCallsign(aircraft.getCallsign());
return this->m_com1system.isActiveFrequencyWithin25kHzChannel(comFrequency) ||
this->m_com2system.isActiveFrequencyWithin25kHzChannel(comFrequency);
}
QString CSimulatedAircraft::convertToQString(bool i18n) const
{
QString s = CAircraft::convertToQString(i18n);
QString s(this->m_callsign.toQString(i18n));
s += " ";
s += this->m_pilot.toQString(i18n);
s += " ";
s += this->m_situation.toQString(i18n);
s += " ";
s += this->m_com1system.toQString(i18n);
s += " ";
s += this->m_com2system.toQString(i18n);
s += " ";
s += this->m_transponder.toQString(i18n);
s += " enabled: ";
s += BlackMisc::boolToYesNo(this->isEnabled());
s += " ";
@@ -164,8 +400,6 @@ namespace BlackMisc
s += BlackMisc::boolToYesNo(this->isRendered());
s += " ";
s += this->m_model.toQString(i18n);
s += " ";
s += this->m_client.toQString(i18n);
return s;
}

View File

@@ -13,24 +13,48 @@
#define BLACKMISC_SIMULATION_SIMULATEDAIRCRAFT_H
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/aviation/aircraft.h"
#include "aircraftmodel.h"
#include "blackmisc/aviation/aircraftsituation.h"
#include "blackmisc/aviation/aircrafticaocode.h"
#include "blackmisc/aviation/callsign.h"
#include "blackmisc/aviation/selcal.h"
#include "blackmisc/aviation/transponder.h"
#include "blackmisc/aviation/comsystem.h"
#include "blackmisc/aviation/aircraftparts.h"
#include "blackmisc/aviation/livery.h"
#include "blackmisc/valueobject.h"
#include "blackmisc/namevariantpairlist.h"
#include "blackmisc/propertyindex.h"
#include "blackmisc/network/client.h"
#include "blackmisc/network/user.h"
#include "blackmisc/blackmiscfreefunctions.h"
namespace BlackMisc
{
namespace Simulation
{
//! Comprehensive information of an aircraft
//! \sa CAircraft
class BLACKMISC_EXPORT CSimulatedAircraft : public CValueObject<CSimulatedAircraft, BlackMisc::Aviation::CAircraft>
class BLACKMISC_EXPORT CSimulatedAircraft :
public CValueObject<CSimulatedAircraft>,
public BlackMisc::Geo::ICoordinateWithRelativePosition
{
public:
//! Properties by index
enum ColumnIndex
{
IndexModel = BlackMisc::CPropertyIndex::GlobalIndexCSimulatedAircraft,
IndexClient,
IndexCallsign = BlackMisc::CPropertyIndex::GlobalIndexCSimulatedAircraft,
IndexPilot,
IndexDistanceToOwnAircraft,
IndexCom1System,
IndexCom2System,
IndexTransponder,
IndexSituation,
IndexAircraftIcaoCode,
IndexLivery,
IndexParts,
IndexIsVtol,
IndexCombinedIcaoLiveryString,
IndexModel,
IndexEnabled,
IndexRendered,
IndexPartsSynchronized,
@@ -41,9 +65,235 @@ namespace BlackMisc
CSimulatedAircraft();
//! Constructor.
CSimulatedAircraft(const BlackMisc::Aviation::CAircraft &aircraft,
const BlackMisc::Simulation::CAircraftModel &model = {},
const BlackMisc::Network::CClient &client = {});
CSimulatedAircraft(const BlackMisc::Simulation::CAircraftModel &model);
//! Constructor.
CSimulatedAircraft(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Network::CUser &user, const BlackMisc::Aviation::CAircraftSituation &situation);
//! \copydoc CValueObject::toIcon()
BlackMisc::CIcon toIcon() const { return this->m_callsign.toIcon(); }
//! Get callsign.
const BlackMisc::Aviation::CCallsign &getCallsign() const { return m_callsign; }
//! Get callsign.
QString getCallsignAsString() const { return m_callsign.asString(); }
//! Get situation.
const BlackMisc::Aviation::CAircraftSituation &getSituation() const { return m_situation; }
//! Set situation.
void setSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
//! Get user
const BlackMisc::Network::CUser &getPilot() const { return m_pilot; }
//! Get user's real name
QString getPilotRealname() const { return m_pilot.getRealName(); }
//! Get user's real id
QString getPilotId() { return m_pilot.getId(); }
//! Get aircraft ICAO info
const BlackMisc::Aviation::CAircraftIcaoCode &getAircraftIcaoCode() const;
//! Aircraft ICAO code designator
const QString &getAircraftIcaoCodeDesignator() const;
//! Aircraft ICAO combined code
const QString &getAircraftIcaoCombinedType() const;
//! Set aicraft ICAO code
bool setAircraftIcaoCode(const BlackMisc::Aviation::CAircraftIcaoCode &aircraftIcaoCode) { return m_model.setAircraftIcaoCode(aircraftIcaoCode);}
//! Set ICAO info
bool setIcaoCodes(const BlackMisc::Aviation::CAircraftIcaoCode &aircraftIcaoCode, const BlackMisc::Aviation::CAirlineIcaoCode &airlineIcaoCode);
//! Get livery
const BlackMisc::Aviation::CLivery &getLivery() const { return m_livery; }
//! Airline ICAO code if any
const BlackMisc::Aviation::CAirlineIcaoCode &getAirlineIcaoCode() const;
//! Airline ICAO code designator
const QString &getAirlineIcaoCodeDesignator() const;
//! Livery
virtual void setLivery(const BlackMisc::Aviation::CLivery &livery) { this->m_livery = livery; }
//! Set aircraft ICAO designator
virtual void setAircraftIcaoDesignator(const QString &designator);
//! Has valid realname?
bool hasValidRealName() const { return this->m_pilot.hasValidRealName(); }
//! Has valid id?
bool hasValidId() const { return this->m_pilot.hasValidId(); }
//! Valid designator?
bool hasAircraftDesignator() const;
//! Valid airline designator
bool hasAirlineDesignator() const { return this->m_livery.hasValidAirlineDesignator(); }
//! Valid designators?
bool hasAircraftAndAirlineDesignator() const;
//! Valid callsign
bool hasValidCallsign() const { return BlackMisc::Aviation::CCallsign::isValidCallsign(this->getCallsign().asString()); }
//! Get position
BlackMisc::Geo::CCoordinateGeodetic getPosition() const { return this->m_situation.getPosition(); }
//! Set position
void setPosition(const BlackMisc::Geo::CCoordinateGeodetic &position) { this->m_situation.setPosition(position); }
//! Get altitude
const BlackMisc::Aviation::CAltitude &getAltitude() const { return this->m_situation.getAltitude(); }
//! Set altitude
void setAltitude(const BlackMisc::Aviation::CAltitude &altitude) { this->m_situation.setAltitude(altitude); }
//! Get groundspeed
const BlackMisc::PhysicalQuantities::CSpeed &getGroundSpeed() const { return this->m_situation.getGroundSpeed(); }
//! \copydoc ICoordinateGeodetic::latitude
virtual const BlackMisc::Geo::CLatitude &latitude() const override { return this->m_situation.latitude(); }
//! \copydoc ICoordinateGeodetic::longitude
virtual const BlackMisc::Geo::CLongitude &longitude() const override { return this->m_situation.longitude(); }
//! \copydoc ICoordinateGeodetic::geodeticHeight
//! \remarks this should be used for elevation as depicted here: http://en.wikipedia.org/wiki/Altitude#mediaviewer/File:Vertical_distances.svg
const BlackMisc::PhysicalQuantities::CLength &geodeticHeight() const override { return this->m_situation.geodeticHeight(); }
//! Elevation
//! \sa geodeticHeight
const BlackMisc::PhysicalQuantities::CLength getElevation() const { return this->geodeticHeight(); }
//! Elevation
//! \sa setGeodeticHeight
void setElevation(const BlackMisc::PhysicalQuantities::CLength &elevation) { return this->m_situation.setElevation(elevation); }
//! Get heading
const BlackMisc::Aviation::CHeading &getHeading() const { return this->m_situation.getHeading(); }
//! Get pitch
const BlackMisc::PhysicalQuantities::CAngle &getPitch() const { return this->m_situation.getPitch(); }
//! Get bank
const BlackMisc::PhysicalQuantities::CAngle &getBank() const { return this->m_situation.getBank(); }
//! Get COM1 system
const BlackMisc::Aviation::CComSystem &getCom1System() const { return this->m_com1system; }
//! Get COM2 system
const BlackMisc::Aviation::CComSystem &getCom2System() const { return this->m_com2system; }
//! Get COM unit
const BlackMisc::Aviation::CComSystem getComSystem(BlackMisc::Aviation::CComSystem::ComUnit unit) const;
//! Set COM unit
void setComSystem(const BlackMisc::Aviation::CComSystem &com, BlackMisc::Aviation::CComSystem::ComUnit unit);
//! Set COM1 system
void setCom1System(const BlackMisc::Aviation::CComSystem &comSystem) { this->m_com1system = comSystem; }
//! Set COM2 system
void setCom2System(const BlackMisc::Aviation::CComSystem &comSystem) { this->m_com2system = comSystem; }
//! Set COM1 frequency
bool setCom1ActiveFrequency(const BlackMisc::PhysicalQuantities::CFrequency &frequency);
//! Set COM2 frequency
bool setCom2ActiveFrequency(const BlackMisc::PhysicalQuantities::CFrequency &frequency);
//! Set COM frequency
bool setComActiveFrequency(const BlackMisc::PhysicalQuantities::CFrequency &frequency, BlackMisc::Aviation::CComSystem::ComUnit unit);
//! Given SELCAL selected?
bool isSelcalSelected(const BlackMisc::Aviation::CSelcal &selcal) const { return this->m_selcal == selcal; }
//! Valid SELCAL?
bool hasValidSelcal() const { return this->m_selcal.isValid(); }
//! SELCAL
const BlackMisc::Aviation::CSelcal getSelcal() const { return m_selcal; }
//! Cockpit data
void setCockpit(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, const BlackMisc::Aviation::CTransponder &transponder);
//! Cockpit data
void setCockpit(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, int transponderCode, BlackMisc::Aviation::CTransponder::TransponderMode mode);
//! Own SELCAL code
void setSelcal(const BlackMisc::Aviation::CSelcal &selcal) { this->m_selcal = selcal; }
//! Changed cockpit data?
bool hasChangedCockpitData(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, const BlackMisc::Aviation::CTransponder &transponder) const;
//! Identical COM system?
bool hasSameComData(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, const BlackMisc::Aviation::CTransponder &transponder);
//! Is any (COM1/2) active frequency within 8.3383kHz channel?
bool isActiveFrequencyWithin8_33kHzChannel(const BlackMisc::PhysicalQuantities::CFrequency &comFrequency) const;
//! Is any (COM1/2) active frequency within 25kHz channel?
bool isActiveFrequencyWithin25kHzChannel(const BlackMisc::PhysicalQuantities::CFrequency &comFrequency) const;
//! Get transponder
const BlackMisc::Aviation::CTransponder &getTransponder() const { return this->m_transponder; }
//! Set transponder
void setTransponder(const BlackMisc::Aviation::CTransponder &transponder) { this->m_transponder = transponder; }
//! Set transponder mode
void setTransponderMode(BlackMisc::Aviation::CTransponder::TransponderMode mode) { this->m_transponder.setTransponderMode(mode); }
//! Set transponder code
void setTransponderCode(int code) { this->m_transponder.setTransponderCode(code); }
//! Get transponder code
QString getTransponderCodeFormatted() const { return this->m_transponder.getTransponderCodeFormatted(); }
//! Get transponder code
qint32 getTransponderCode() const { return this->m_transponder.getTransponderCode(); }
//! Get transponder mode
BlackMisc::Aviation::CTransponder::TransponderMode getTransponderMode() const { return this->m_transponder.getTransponderMode(); }
//! Is valid for login?
bool isValidForLogin() const;
//! Meaningful default settings for COM Systems
void initComSystems();
//! Meaningful default settings for Transponder
void initTransponder();
//! Get aircraft parts
const BlackMisc::Aviation::CAircraftParts &getParts() const { return m_parts; }
//! Get aircraft parts
BlackMisc::Aviation::CAircraftLights getLights() const;
//! Set aircraft parts
void setParts(const BlackMisc::Aviation::CAircraftParts &parts);
//! Set aircraft lights
void setLights(BlackMisc::Aviation::CAircraftLights &lights);
//! Set aircraft lights on
void setAllLightsOn();
//! Set aircraft lights off
void setAllLightsOff();
//! VTOL aircraft?
bool isVtol() const;
//! Combined ICAO / color string
QString getCombinedIcaoLiveryString() const;
//! \copydoc CValueObject::propertyByIndex
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
@@ -63,23 +313,11 @@ namespace BlackMisc
//! Set model string
void setModelString(const QString &modelString);
//! \copydoc CAircraft::setCallsign
virtual void setCallsign(const BlackMisc::Aviation::CCallsign &callsign) override;
//! Set callsign
void setCallsign(const BlackMisc::Aviation::CCallsign &callsign);
//! \copydoc CAircraft::setIcaoInfo
virtual void setIcaoInfo(const BlackMisc::Aviation::CAircraftIcaoData &icao) override;
//! \copydoc CAircraft::setLivery
virtual void setLivery(const BlackMisc::Aviation::CLivery &livery) override;
//! \copydoc CAircraft::setPilot
virtual void setPilot(const BlackMisc::Network::CUser &user) override;
//! Get client
const BlackMisc::Network::CClient &getClient() const { return m_client; }
//! Set client
void setClient(const BlackMisc::Network::CClient &client);
//! Set pilot
void setPilot(const BlackMisc::Network::CUser &user);
//! Enabled?
bool isEnabled() const { return m_enabled; }
@@ -99,9 +337,6 @@ namespace BlackMisc
//! Rendered?
void setRendered(bool rendered) { m_rendered = rendered; }
//! Update from aviation aircraft
void setAircraft(const BlackMisc::Aviation::CAircraft &aircraft);
//! Have parts been synchronized with a remote client?
bool isPartsSynchronized() const { return m_partsSynchronized; }
@@ -113,8 +348,16 @@ namespace BlackMisc
private:
BLACK_ENABLE_TUPLE_CONVERSION(CSimulatedAircraft)
BlackMisc::Simulation::CAircraftModel m_model;
BlackMisc::Network::CClient m_client;
BlackMisc::Aviation::CCallsign m_callsign;
BlackMisc::Network::CUser m_pilot;
BlackMisc::Aviation::CAircraftSituation m_situation;
BlackMisc::Aviation::CComSystem m_com1system;
BlackMisc::Aviation::CComSystem m_com2system;
BlackMisc::Aviation::CTransponder m_transponder;
BlackMisc::Aviation::CAircraftParts m_parts;
BlackMisc::Aviation::CSelcal m_selcal;
BlackMisc::Aviation::CLivery m_livery;
BlackMisc::Simulation::CAircraftModel m_model;
bool m_enabled = true; //!< to be displayed in sim
bool m_rendered = false; //!< really shown in simulator
bool m_partsSynchronized = false; //!< sync.parts
@@ -128,8 +371,17 @@ namespace BlackMisc
} // namespace
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Simulation::CSimulatedAircraft, (
attr(o.m_callsign),
attr(o.m_pilot),
attr(o.m_situation),
attr(o.m_com1system),
attr(o.m_com2system),
attr(o.m_transponder),
attr(o.m_parts),
attr(o.m_livery),
attr(o.m_distanceToOwnAircraft),
attr(o.m_bearingToOwnAircraft),
attr(o.m_model),
attr(o.m_client),
attr(o.m_enabled),
attr(o.m_rendered),
attr(o.m_partsSynchronized),

View File

@@ -21,7 +21,6 @@ namespace BlackMisc
{
namespace Simulation
{
CSimulatedAircraftList::CSimulatedAircraftList() { }
CSimulatedAircraftList::CSimulatedAircraftList(const CSequence<CSimulatedAircraft> &other) :
@@ -59,6 +58,26 @@ namespace BlackMisc
return csl;
}
bool CSimulatedAircraftList::updateWithVatsimDataFileData(CSimulatedAircraft &aircraftToBeUpdated) const
{
if (this->isEmpty()) return false;
if (aircraftToBeUpdated.hasValidRealName() && aircraftToBeUpdated.hasValidId() && aircraftToBeUpdated.hasAircraftAndAirlineDesignator()) { return false; }
CSimulatedAircraft currentDataFileAircraft = this->findFirstByCallsign(aircraftToBeUpdated.getCallsign());
if (currentDataFileAircraft.getCallsign().isEmpty()) return false;
CUser user = aircraftToBeUpdated.getPilot();
user.updateMissingParts(currentDataFileAircraft.getPilot());
aircraftToBeUpdated.setPilot(user);
CAircraftIcaoCode aircraftIcao = aircraftToBeUpdated.getAircraftIcaoCode();
CAirlineIcaoCode airlineIcao = aircraftToBeUpdated.getAirlineIcaoCode();
aircraftIcao.updateMissingParts(currentDataFileAircraft.getAircraftIcaoCode());
airlineIcao.updateMissingParts(currentDataFileAircraft.getAirlineIcaoCode());
aircraftToBeUpdated.setIcaoCodes(aircraftIcao, airlineIcao);
return true;
}
void CSimulatedAircraftList::markAllAsNotRendered()
{
for (CSimulatedAircraft &aircraft : (*this))
@@ -80,6 +99,18 @@ namespace BlackMisc
return c;
}
int CSimulatedAircraftList::setAircraftModel(const CCallsign &callsign, const CAircraftModel &model)
{
int c = 0;
for (CSimulatedAircraft &aircraft : (*this))
{
if (aircraft.getCallsign() != callsign) { continue; }
aircraft.setModel(model);
c++;
}
return c;
}
int CSimulatedAircraftList::setAircraftParts(const CCallsign &callsign, const CAircraftParts &parts)
{
int c = 0;
@@ -113,15 +144,5 @@ namespace BlackMisc
return false;
}
CAircraftList CSimulatedAircraftList::toAircraftList() const
{
CAircraftList al;
for (const CSimulatedAircraft &aircraft : (*this))
{
al.push_back(aircraft);
}
return al;
}
} // namespace
} // namespace

View File

@@ -15,7 +15,6 @@
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/simulation/simulatedaircraft.h"
#include "blackmisc/aviation/callsignobjectlist.h"
#include "blackmisc/aviation/aircraftlist.h"
#include "blackmisc/geo/geoobjectlist.h"
#include "blackmisc/network/userlist.h"
#include "blackmisc/collection.h"
@@ -59,12 +58,19 @@ namespace BlackMisc
//! Callsigns of aircraft with synchronized parts
BlackMisc::Aviation::CCallsignSet getCallsignsWithSyncronizedParts() const;
//! Update aircraft with data from VATSIM data file
//! \remarks The list used ("this") needs to contain the VATSIM data file objects
bool updateWithVatsimDataFileData(CSimulatedAircraft &aircraftToBeUpdated) const;
//! Mark all aircraft as unrendered
void markAllAsNotRendered();
//! Mark given callsign as rendered
int setRendered(const BlackMisc::Aviation::CCallsign &callsign, bool rendered);
//! Set model
int setAircraftModel(const BlackMisc::Aviation::CCallsign &callsign, const CAircraftModel &model);
//! Set aircraft parts
int setAircraftParts(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftParts &parts);
@@ -74,9 +80,6 @@ namespace BlackMisc
//! Rendered?
bool isRendered(const BlackMisc::Aviation::CCallsign &callsign) const;
//! To aircraft list
BlackMisc::Aviation::CAircraftList toAircraftList() const;
};
} //namespace