1
0
Fork 0

Expose performance/ICAO planning data to QML

This commit is contained in:
James Turner 2018-07-26 15:36:09 +01:00
parent 401a0dd22d
commit 78a3e8d979
4 changed files with 148 additions and 52 deletions

View file

@ -49,6 +49,7 @@ protected:
void installProgress(InstallRef aInstall, unsigned int bytes, unsigned int total) override void installProgress(InstallRef aInstall, unsigned int bytes, unsigned int total) override
{ {
Q_UNUSED(total)
if (aInstall->package() == p->packageRef()) { if (aInstall->package() == p->packageRef()) {
p->setDownloadBytes(bytes); p->setDownloadBytes(bytes);
} }
@ -58,6 +59,7 @@ protected:
{ {
Q_UNUSED(aReason); Q_UNUSED(aReason);
if (aInstall->package() == p->packageRef()) { if (aInstall->package() == p->packageRef()) {
p->_cachedProps.reset();
p->checkForStates(); p->checkForStates();
p->infoChanged(); p->infoChanged();
} }
@ -135,19 +137,6 @@ static AircraftStateVec readAircraftStates(const SGPath& setXMLPath)
return result; return result;
} }
static SGPropertyNode_ptr readAircraftAuthors(const SGPath& setXMLPath)
{
SGPropertyNode_ptr root(new SGPropertyNode);
try {
readProperties(setXMLPath, root);
} catch (sg_exception&) {
return {}; // malformed include or XML, just bail
}
const auto authors = root->getNode("sim/authors");
return authors;
}
QString humanNameFromStateTag(const std::string& tag) QString humanNameFromStateTag(const std::string& tag)
{ {
if (tag == "approach") return QObject::tr("On approach"); if (tag == "approach") return QObject::tr("On approach");
@ -214,12 +203,12 @@ public:
if (it == _data.end()) if (it == _data.end())
return -1; return -1;
return std::distance(_data.begin(), it); return static_cast<int>(std::distance(_data.begin(), it));
} }
int rowCount(const QModelIndex &parent) const override int rowCount(const QModelIndex &) const override
{ {
return _data.size(); return static_cast<int>(_data.size());
} }
QVariant data(const QModelIndex &index, int role) const override QVariant data(const QModelIndex &index, int role) const override
@ -320,7 +309,7 @@ int QmlAircraftInfo::numVariants() const
return _item->variants.size() + 1; return _item->variants.size() + 1;
} else if (_package) { } else if (_package) {
// whereas for packaged aircraft we do // whereas for packaged aircraft we do
return _package->variants().size(); return static_cast<int>(_package->variants().size());
} }
return 0; return 0;
@ -353,8 +342,10 @@ QString QmlAircraftInfo::authors() const
{ {
SGPropertyNode_ptr structuredAuthors; SGPropertyNode_ptr structuredAuthors;
if (_item) { if (_item) {
std::string path = pathOnDisk().toUtf8().toStdString(); validateLocalProps();
structuredAuthors = readAircraftAuthors(SGPath::fromUtf8(path)); if (_cachedProps)
structuredAuthors = _cachedProps->getNode("sim/authors");
if (!structuredAuthors) if (!structuredAuthors)
return resolveItem()->authors; return resolveItem()->authors;
} else if (_package) { } else if (_package) {
@ -531,7 +522,7 @@ QString QmlAircraftInfo::packageId() const
int QmlAircraftInfo::packageSize() const int QmlAircraftInfo::packageSize() const
{ {
if (_package) { if (_package) {
return _package->fileSizeBytes(); return static_cast<int>(_package->fileSizeBytes());
} }
return 0; return 0;
@ -596,6 +587,31 @@ void QmlAircraftInfo::checkForStates()
emit infoChanged(); emit infoChanged();
} }
void QmlAircraftInfo::validateLocalProps() const
{
if (!_cachedProps) {
SGPath path;
if (_item) {
path = resolveItem()->path.toUtf8().toStdString();
} else if (_package) {
auto install = _package->existingInstall();
if (!install.valid())
return;
path = install->path();
}
if (!path.exists())
return;
_cachedProps = new SGPropertyNode;
try {
readProperties(path, _cachedProps);
} catch (sg_exception&) {
_cachedProps.reset();
}
}
}
void QmlAircraftInfo::setUri(QUrl u) void QmlAircraftInfo::setUri(QUrl u)
{ {
if (uri() == u) if (uri() == u)
@ -604,6 +620,7 @@ void QmlAircraftInfo::setUri(QUrl u)
_item.clear(); _item.clear();
_package.clear(); _package.clear();
_statesModel.reset(new StatesModel); _statesModel.reset(new StatesModel);
_cachedProps.clear();
if (u.isLocalFile()) { if (u.isLocalFile()) {
_item = LocalAircraftCache::instance()->findItemWithUri(u); _item = LocalAircraftCache::instance()->findItemWithUri(u);
@ -651,27 +668,14 @@ void QmlAircraftInfo::setVariant(int variant)
return; return;
_variant = variant; _variant = variant;
_cachedProps.clear();
checkForStates(); checkForStates();
emit infoChanged(); emit infoChanged();
emit variantChanged(_variant); emit variantChanged(_variant);
} }
void QmlAircraftInfo::requestInstallUpdate()
{
}
void QmlAircraftInfo::requestUninstall()
{
}
void QmlAircraftInfo::requestInstallCancel()
{
}
QVariant QmlAircraftInfo::packageAircraftStatus(simgear::pkg::PackageRef p) QVariant QmlAircraftInfo::packageAircraftStatus(simgear::pkg::PackageRef p)
{ {
if (p->hasTag("needs-maintenance")) { if (p->hasTag("needs-maintenance")) {
@ -774,5 +778,75 @@ StatesModel *QmlAircraftInfo::statesModel()
return _statesModel.data(); return _statesModel.data();
} }
QuantityValue QmlAircraftInfo::cruiseSpeed() const
{
validateLocalProps();
if (!_cachedProps) {
return {};
}
if (_cachedProps->hasValue("aircraft/performance/cruise/mach")) {
return QuantityValue{Units::Mach, _cachedProps->getDoubleValue("aircraft/performance/cruise/mach")};
}
if (_cachedProps->hasValue("aircraft/performance/cruise/airpseed-knots")) {
return QuantityValue{Units::Knots, _cachedProps->getIntValue("aircraft/performance/cruise/airpseed-knots")};
}
return {};
}
QuantityValue QmlAircraftInfo::approachSpeed() const
{
validateLocalProps();
if (!_cachedProps) {
return {};
}
if (_cachedProps->hasValue("aircraft/performance/approach/airpseed-knots")) {
return QuantityValue{Units::Knots, _cachedProps->getIntValue("aircraft/performance/approach/airpseed-knots")};
}
return {};
}
QuantityValue QmlAircraftInfo::cruiseAltitude() const
{
validateLocalProps();
if (!_cachedProps) {
return {};
}
if (_cachedProps->hasValue("aircraft/performance/cruise/flight-level")) {
return QuantityValue{Units::FlightLevel, _cachedProps->getIntValue("aircraft/performance/cruise/flight-level")};
}
if (_cachedProps->hasValue("aircraft/performance/cruise/airpseed-knots")) {
return QuantityValue{Units::FeetMSL, _cachedProps->getIntValue("aircraft/performance/cruise/altitude-ft")};
}
return {};
}
QString QmlAircraftInfo::icaoType() const
{
validateLocalProps();
if (!_cachedProps) {
return {};
}
return QString::fromStdString(_cachedProps->getStringValue("aircraft/icao/type"));
}
bool QmlAircraftInfo::isSpeedBelowLimits(QuantityValue speed) const
{
return true;
}
bool QmlAircraftInfo::isAltitudeBelowLimits(QuantityValue speed) const
{
return true;
}
#include "QmlAircraftInfo.moc" #include "QmlAircraftInfo.moc"

View file

@ -11,6 +11,8 @@
#include <simgear/package/Catalog.hxx> #include <simgear/package/Catalog.hxx>
#include <simgear/package/Package.hxx> #include <simgear/package/Package.hxx>
#include "UnitsModel.hxx"
struct AircraftItem; struct AircraftItem;
typedef QSharedPointer<AircraftItem> AircraftItemPtr; typedef QSharedPointer<AircraftItem> AircraftItemPtr;
@ -25,20 +27,19 @@ class QmlAircraftInfo : public QObject
Q_PROPERTY(QVariantList previews READ previews NOTIFY infoChanged) Q_PROPERTY(QVariantList previews READ previews NOTIFY infoChanged)
Q_PROPERTY(int numVariants READ numVariants NOTIFY infoChanged) Q_PROPERTY(int numVariants READ numVariants NOTIFY infoChanged)
Q_PROPERTY(QStringList variantNames READ variantNames NOTIFY infoChanged)
Q_PROPERTY(QString name READ name NOTIFY infoChanged) Q_PROPERTY(QString name READ name NOTIFY infoChanged)
Q_PROPERTY(QString description READ description NOTIFY infoChanged) Q_PROPERTY(QString description READ description NOTIFY infoChanged)
Q_PROPERTY(QString authors READ authors NOTIFY infoChanged) Q_PROPERTY(QString authors READ authors NOTIFY infoChanged)
Q_PROPERTY(QUrl thumbnail READ thumbnail NOTIFY infoChanged) Q_PROPERTY(QUrl thumbnail READ thumbnail NOTIFY infoChanged)
Q_PROPERTY(QVariantList ratings READ ratings NOTIFY infoChanged)
Q_PROPERTY(QString pathOnDisk READ pathOnDisk NOTIFY infoChanged) Q_PROPERTY(QString pathOnDisk READ pathOnDisk NOTIFY infoChanged)
Q_PROPERTY(QString packageId READ packageId NOTIFY infoChanged) Q_PROPERTY(QString packageId READ packageId NOTIFY infoChanged)
Q_PROPERTY(int packageSize READ packageSize NOTIFY infoChanged) Q_PROPERTY(int packageSize READ packageSize NOTIFY infoChanged)
Q_PROPERTY(int downloadedBytes READ downloadedBytes NOTIFY downloadChanged) Q_PROPERTY(int downloadedBytes READ downloadedBytes NOTIFY downloadChanged)
Q_PROPERTY(bool isPackaged READ isPackaged NOTIFY infoChanged)
Q_PROPERTY(QVariant status READ status NOTIFY infoChanged) Q_PROPERTY(QVariant status READ status NOTIFY infoChanged)
Q_PROPERTY(QVariant installStatus READ installStatus NOTIFY downloadChanged) Q_PROPERTY(QVariant installStatus READ installStatus NOTIFY downloadChanged)
@ -49,21 +50,13 @@ class QmlAircraftInfo : public QObject
Q_PROPERTY(QUrl supportUrl READ supportUrl NOTIFY infoChanged) Q_PROPERTY(QUrl supportUrl READ supportUrl NOTIFY infoChanged)
Q_PROPERTY(QUrl wikipediaUrl READ wikipediaUrl NOTIFY infoChanged) Q_PROPERTY(QUrl wikipediaUrl READ wikipediaUrl NOTIFY infoChanged)
Q_PROPERTY(QuantityValue cruiseSpeed READ cruiseSpeed NOTIFY infoChanged)
Q_PROPERTY(QuantityValue cruiseAltitude READ cruiseAltitude NOTIFY infoChanged)
Q_PROPERTY(QuantityValue approachSpeed READ approachSpeed NOTIFY infoChanged)
Q_INVOKABLE void requestInstallUpdate(); Q_PROPERTY(QString icaoType READ icaoType NOTIFY infoChanged)
Q_INVOKABLE void requestUninstall();
Q_INVOKABLE void requestInstallCancel();
Q_PROPERTY(QVariantList ratings READ ratings NOTIFY infoChanged)
Q_PROPERTY(QStringList variantNames READ variantNames NOTIFY infoChanged)
Q_PROPERTY(bool isPackaged READ isPackaged NOTIFY infoChanged)
Q_PROPERTY(bool hasStates READ hasStates NOTIFY infoChanged) Q_PROPERTY(bool hasStates READ hasStates NOTIFY infoChanged)
Q_PROPERTY(StatesModel* statesModel READ statesModel NOTIFY infoChanged) Q_PROPERTY(StatesModel* statesModel READ statesModel NOTIFY infoChanged)
public: public:
@ -123,6 +116,16 @@ public:
static const int StateExplicitRole; static const int StateExplicitRole;
StatesModel* statesModel(); StatesModel* statesModel();
QuantityValue cruiseSpeed() const;
QuantityValue approachSpeed() const;
QuantityValue cruiseAltitude() const;
QString icaoType() const;
Q_INVOKABLE bool isSpeedBelowLimits(QuantityValue speed) const;
Q_INVOKABLE bool isAltitudeBelowLimits(QuantityValue speed) const;
signals: signals:
void uriChanged(); void uriChanged();
void infoChanged(); void infoChanged();
@ -139,14 +142,20 @@ private:
AircraftItemPtr resolveItem() const; AircraftItemPtr resolveItem() const;
void checkForStates(); void checkForStates();
void validateLocalProps() const;
class Delegate; class Delegate;
std::unique_ptr<Delegate> _delegate; std::unique_ptr<Delegate> _delegate;
simgear::pkg::PackageRef _package; simgear::pkg::PackageRef _package;
AircraftItemPtr _item; AircraftItemPtr _item;
int _variant = 0; quint32 _variant = 0;
int _downloadBytes = 0; int _downloadBytes = 0;
QScopedPointer<StatesModel> _statesModel; QScopedPointer<StatesModel> _statesModel;
/// if the aircraft is locally installed, this is the cached
/// parsed contents of the -set.xml.
mutable SGPropertyNode_ptr _cachedProps;
}; };
#endif // QMLAIRCRAFTINFO_HXX #endif // QMLAIRCRAFTINFO_HXX

View file

@ -287,6 +287,14 @@ QuantityValue::QuantityValue(Units::Type u, double v) :
{ {
} }
QuantityValue::QuantityValue(Units::Type u, int v) :
value(static_cast<double>(v)),
unit(u)
{
assert(static_unitData.at(u).decimals == 0);
}
QuantityValue QuantityValue::convertToUnit(Units::Type u) const QuantityValue QuantityValue::convertToUnit(Units::Type u) const
{ {
// special case a no-change // special case a no-change
@ -331,6 +339,7 @@ QuantityValue QuantityValue::convertToUnit(Units::Type u) const
// use the value at sea level for now // use the value at sea level for now
return {u, value / 667.0}; return {u, value / 667.0};
} }
break;
} }
case Units::Knots: case Units::Knots:
@ -340,6 +349,7 @@ QuantityValue QuantityValue::convertToUnit(Units::Type u) const
// use the value at sea level for now // use the value at sea level for now
return {u, value * 667.0}; return {u, value * 667.0};
} }
break;
} }
case Units::DegreesMagnetic: case Units::DegreesMagnetic:
@ -350,6 +360,7 @@ QuantityValue QuantityValue::convertToUnit(Units::Type u) const
if ((unit == Units::DegreesMagnetic) || (unit == Units::DegreesTrue)) { if ((unit == Units::DegreesMagnetic) || (unit == Units::DegreesTrue)) {
return {u, value}; return {u, value};
} }
break;
} }
case Units::FlightLevel: case Units::FlightLevel:

View file

@ -86,6 +86,8 @@ public:
QuantityValue(Units::Type u, double v); QuantityValue(Units::Type u, double v);
QuantityValue(Units::Type u, int v);
QuantityValue convertToUnit(Units::Type u) const; QuantityValue convertToUnit(Units::Type u) const;
Q_INVOKABLE QuantityValue convertToUnit(int u) const; Q_INVOKABLE QuantityValue convertToUnit(int u) const;