refs #391, allow to send aircraft parts from GUI

* GUI component for aircraft parts
* remote aircraft selector component
* Adjusted GUI for internals component
* Enable / disable debug messages from GUI
* Allow to init engines directly
* Removed unused async sort in sequence

In same step fixed found issues in interpolator
* allow to set max rendered aircraft
This commit is contained in:
Klaus Basan
2015-03-07 03:34:17 +01:00
parent f31445e873
commit 5ed95aee3d
63 changed files with 1575 additions and 165 deletions

View File

@@ -156,6 +156,11 @@ namespace BlackMisc
m_parts.setCallsign(this->getCallsign());
}
bool CAircraft::isVtol() const
{
return m_icao.isVtol();
}
CVariant CAircraft::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
if (index.isMyself()) { return this->toCVariant(); }
@@ -180,6 +185,8 @@ namespace BlackMisc
return this->m_icao.propertyByIndex(index.copyFrontRemoved());
case IndexParts:
return this->m_parts.propertyByIndex(index.copyFrontRemoved());
case IndexIsVtol:
return CVariant::fromValue(this->isVtol());
default:
return (ICoordinateGeodetic::canHandleIndex(index)) ?
ICoordinateGeodetic::propertyByIndex(index) :

View File

@@ -30,7 +30,9 @@ namespace BlackMisc
namespace Aviation
{
//! Value object encapsulating information of an aircraft
class CAircraft : public CValueObjectStdTuple<CAircraft>, public BlackMisc::Geo::ICoordinateWithRelativePosition
class CAircraft :
public CValueObjectStdTuple<CAircraft>,
public BlackMisc::Geo::ICoordinateWithRelativePosition
{
public:
//! Properties by index
@@ -44,7 +46,8 @@ namespace BlackMisc
IndexTransponder,
IndexSituation,
IndexIcao,
IndexParts
IndexParts,
IndexIsVtol
};
//! Default constructor.
@@ -75,7 +78,7 @@ namespace BlackMisc
const BlackMisc::Network::CUser &getPilot() const { return m_pilot; }
//! Get user's real name
QString getPilotRealname() { return m_pilot.getRealName(); }
QString getPilotRealname() const { return m_pilot.getRealName(); }
//! Get user's real id
QString getPilotId() { return m_pilot.getId(); }
@@ -247,6 +250,9 @@ namespace BlackMisc
//! Set aircraft parts
void setParts(const BlackMisc::Aviation::CAircraftParts &parts);
//! VTOL aircraft?
bool isVtol() const;
//! \copydoc CValueObject::propertyByIndex
virtual CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const override;
@@ -282,7 +288,7 @@ BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Aviation::CAircraft, (
o.m_parts,
o.m_icao,
o.m_distanceToOwnAircraft,
o.m_bearingToOwnAircraft))
o.m_bearingToOwnAircraft))
Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraft)

View File

@@ -77,6 +77,27 @@ namespace BlackMisc
return true;
}
bool CAircraftIcao::isVtol() const
{
// special designators
if (
this->m_aircraftDesignator == "BALL" ||
this->m_aircraftDesignator == "SHIP" ||
this->m_aircraftDesignator == "GYRO" ||
this->m_aircraftDesignator == "UHEL"
) { return true; }
if (!m_aircraftCombinedType.isEmpty())
{
if (
this->m_aircraftCombinedType.startsWith('G') || // gyrocopter
this->m_aircraftCombinedType.startsWith('H') || // helicopter
this->m_aircraftCombinedType.startsWith('T') // tilt wing
) { return true; }
}
return false;
}
CVariant CAircraftIcao::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
if (index.isMyself()) { return this->toCVariant(); }
@@ -93,6 +114,8 @@ namespace BlackMisc
return CVariant::fromValue(this->m_aircraftColor);
case IndexAsString:
return CVariant::fromValue(this->asString());
case IndexIsVtol:
return CVariant::fromValue(this->isVtol());
default:
return CValueObject::propertyByIndex(index);
}

View File

@@ -32,7 +32,8 @@ namespace BlackMisc
IndexCombinedAircraftType,
IndexAirlineDesignator,
IndexAircraftColor,
IndexAsString
IndexAsString,
IndexIsVtol
};
//! Default constructor.
@@ -135,6 +136,9 @@ namespace BlackMisc
//! Matches wildcard icao object
bool matchesWildcardIcao(const CAircraftIcao &otherIcao) const;
//! Is VTOL aircraft
bool isVtol() const;
//! \copydoc CValueObject::propertyByIndex
virtual CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const override;

View File

@@ -31,7 +31,7 @@ namespace BlackMisc
class CAircraftList :
public CSequence<CAircraft>,
public ICallsignObjectList<CAircraft, CAircraftList>,
public BlackMisc::Geo::IGeoObjectList<CAircraft, CAircraftList>
public BlackMisc::Geo::IGeoObjectWithRelativePositionList<CAircraft, CAircraftList>
{
public:
//! Default constructor.

View File

@@ -118,12 +118,12 @@ namespace BlackMisc
if (onlineAtcStation.hasValidDistance())
{
bookedAtcStation.setDistanceToOwnAircraft(onlineAtcStation.getDistanceToOwnAircraft());
bookedAtcStation.setBearingToOwnAircraft(onlineAtcStation.getBearingToOwnAIrcraft());
bookedAtcStation.setBearingToOwnAircraft(onlineAtcStation.getBearingToOwnAircraft());
}
else if (bookedAtcStation.hasValidDistance())
{
onlineAtcStation.setDistanceToOwnAircraft(bookedAtcStation.getDistanceToOwnAircraft());
onlineAtcStation.setBearingToOwnAircraft(bookedAtcStation.getBearingToOwnAIrcraft());
onlineAtcStation.setBearingToOwnAircraft(bookedAtcStation.getBearingToOwnAircraft());
}
// update

View File

@@ -85,6 +85,15 @@ namespace BlackMisc
return atcAlikeCallsignSuffixes().contains(this->getSuffix(), Qt::CaseInsensitive);
}
/*
* OBS callsign?
*/
bool CCallsign::isObserverCallsign() const
{
return m_callsignAsSet.endsWith("_OBS", Qt::CaseInsensitive);
}
/*
* Callsign as Observer
*/

View File

@@ -57,6 +57,9 @@ namespace BlackMisc
//! \sa atcAlikeCallsignSuffixes()
bool isAtcAlikeCallsign() const;
//! Observer callsign?
bool isObserverCallsign() const;
//! Get callsign.
const QString &asString() const { return this->m_callsign; }

View File

@@ -36,6 +36,17 @@ namespace BlackMisc
return this->container().applyIf(&OBJ::getCallsign, callsign, variantMap);
}
template <class OBJ, class CONTAINER>
CCallsignList ICallsignObjectList<OBJ, CONTAINER>::getCallsigns() const
{
CCallsignList cs;
for (const OBJ &obj : this->container())
{
cs.push_back(obj.getCallsign());
}
return cs;
}
template <class OBJ, class CONTAINER>
CONTAINER ICallsignObjectList<OBJ, CONTAINER>::findByCallsign(const CCallsign &callsign) const
{
@@ -51,13 +62,22 @@ namespace BlackMisc
template <class OBJ, class CONTAINER>
OBJ ICallsignObjectList<OBJ, CONTAINER>::findFirstByCallsign(const CCallsign &callsign, const OBJ &ifNotFound) const
{
return this->findByCallsign(callsign).frontOrDefault(ifNotFound);
for (const OBJ &callsignObj : this->container())
{
if (callsignObj.getCallsign() == callsign) { return callsignObj; }
}
return ifNotFound;
}
template <class OBJ, class CONTAINER>
OBJ ICallsignObjectList<OBJ, CONTAINER>::findBackByCallsign(const CCallsign &callsign, const OBJ &ifNotFound) const
OBJ ICallsignObjectList<OBJ, CONTAINER>::findLastByCallsign(const CCallsign &callsign, const OBJ &ifNotFound) const
{
return this->findByCallsign(callsign).backOrDefault(ifNotFound);
for (auto current = container().end(); current != container().begin() ; /* Do nothing */)
{
--current;
if (current->getCallsign() == callsign) { return *current; }
}
return ifNotFound;
}
template <class OBJ, class CONTAINER>
@@ -73,6 +93,16 @@ namespace BlackMisc
return r;
}
template <class OBJ, class CONTAINER>
int ICallsignObjectList<OBJ, CONTAINER>::firstIndexOfCallsign(const CCallsign &callsign)
{
for (int i = 0; i < this->container().size(); i++)
{
if (this->container()[i].getCallsign() == callsign) { return i; }
}
return -1;
}
template <class OBJ, class CONTAINER>
int ICallsignObjectList<OBJ, CONTAINER>::removeByCallsign(const CCallsign &callsign)
{

View File

@@ -36,6 +36,9 @@ namespace BlackMisc
//! Apply for given callsign
int applyIfCallsign(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::CPropertyIndexVariantMap &variantMap);
//! All callsigns
BlackMisc::Aviation::CCallsignList getCallsigns() const;
//! Find 0..n stations by callsign
CONTAINER findByCallsign(const CCallsign &callsign) const;
@@ -46,11 +49,14 @@ namespace BlackMisc
OBJ findFirstByCallsign(const CCallsign &callsign, const OBJ &ifNotFound = {}) const;
//! Find the back object by callsign, if none return given one
OBJ findBackByCallsign(const CCallsign &callsign, const OBJ &ifNotFound = {}) const;
OBJ findLastByCallsign(const CCallsign &callsign, const OBJ &ifNotFound = {}) const;
//! All with given suffix, empty suffixes ignored
CONTAINER findBySuffix(const QString &suffix) const;
//! First found index of callsign, otherwise -1
int firstIndexOfCallsign(const BlackMisc::Aviation::CCallsign &callsign);
//! Remove all objects with callsign
int removeByCallsign(const CCallsign &callsign);

View File

@@ -13,8 +13,20 @@ namespace BlackMisc
{
namespace Aviation
{
QString CAircraftEngine::convertToQString(bool /** i18n */) const
CAircraftEngine::CAircraftEngine(int number, bool on) : m_number(number), m_on(on)
{
Q_ASSERT_X(number > 0, "CAircraftEngine", "Engine number have to be > 1");
}
void CAircraftEngine::setNumber(int number)
{
Q_ASSERT_X(number > 0, "setNumber", "Engine number have to be > 1");
m_number = number;
}
QString CAircraftEngine::convertToQString(bool i18n) const
{
Q_UNUSED(i18n);
QString s(m_number);
s += m_on;
return s;

View File

@@ -27,13 +27,13 @@ namespace BlackMisc
CAircraftEngine() = default;
//! Constructor
CAircraftEngine(int number, bool on) : m_number(number), m_on(on) {}
CAircraftEngine(int number, bool on);
//! Get engine number
int getNumber() const { return m_number; }
//! Set engine number
void setNumber (int number) { m_number = number; }
void setNumber (int number);
//! Is on/off?
bool isOn() const { return m_on; }
@@ -61,4 +61,4 @@ BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Aviation::CAircraftEngine, (
Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftEngine)
#endif // BLACKMISC_AIRCRAFTENGINES_H
#endif // guard

View File

@@ -13,10 +13,57 @@ namespace BlackMisc
{
namespace Aviation
{
CAircraftEngineList::CAircraftEngineList(std::initializer_list<bool> enginesOnOff)
{
int no = 1; // engines 1 based
for (auto it = enginesOnOff.begin(); it != enginesOnOff.end(); ++it)
{
CAircraftEngine engine(no++, *it);
this->push_back(engine);
}
}
CAircraftEngineList::CAircraftEngineList(const CSequence<CAircraftEngine> &other) :
CSequence<CAircraftEngine>(other)
{ }
CAircraftEngine CAircraftEngineList::getEngine(int engineNumber) const
{
Q_ASSERT(engineNumber >= 0);
return this->findBy(&CAircraftEngine::getNumber, engineNumber).frontOrDefault();
}
bool CAircraftEngineList::isEngineOn(int engineNumber) const
{
return getEngine(engineNumber).isOn();
}
QJsonObject CAircraftEngineList::toJson() const
{
QJsonObject map;
for (const auto &e : *this)
{
QJsonObject value = e.toJson();
map.insert(QString::number(e.getNumber()), value);
}
return map;
}
void CAircraftEngineList::convertFromJson(const QJsonObject &json)
{
clear();
for (const auto &e : json.keys())
{
CAircraftEngine engine;
int number = e.toInt();
engine.convertFromJson(json.value(e).toObject());
engine.setNumber(number);
push_back(engine);
}
}
void CAircraftEngineList::registerMetadata()
{
qRegisterMetaType<BlackMisc::CSequence<CAircraftEngine>>();

View File

@@ -15,6 +15,7 @@
#include "aircraftengine.h"
#include "blackmisc/collection.h"
#include "blackmisc/sequence.h"
#include <initializer_list>
namespace BlackMisc
{
@@ -27,41 +28,29 @@ namespace BlackMisc
//! Default constructor.
CAircraftEngineList() = default;
//! Construct by bool values for engines 1,2 ...
CAircraftEngineList(std::initializer_list<bool> enginesOnOff);
//! Construct from a base class object.
CAircraftEngineList(const CSequence<CAircraftEngine> &other);
//! Get engine 1..n
CAircraftEngine getEngine(int engineNumber) const;
//! Engine number 1..x on?
bool isEngineOn(int engineNumber) const;
//! \copydoc CValueObject::toQVariant
virtual QVariant toQVariant() const override { return QVariant::fromValue(*this); }
//! \copydoc CValueObject::convertFromQVariant
virtual void convertFromQVariant(const QVariant &variant) override { BlackMisc::setFromQVariant(this, variant); }
virtual QJsonObject toJson() const override
{
QJsonObject map;
for (const auto &e : *this)
{
QJsonObject value = e.toJson();
map.insert(QString::number(e.getNumber()), value);
}
return map;
}
//! \copydoc CValueObject::toJson
virtual QJsonObject toJson() const override;
//! \copydoc CValueObject::convertFromJson
virtual void convertFromJson(const QJsonObject &json) override
{
clear();
for (const auto &e : json.keys())
{
CAircraftEngine engine;
int number = e.toInt();
engine.convertFromJson(json.value(e).toObject());
engine.setNumber(number);
push_back(engine);
}
}
virtual void convertFromJson(const QJsonObject &json) override;
//! Register metadata
static void registerMetadata();

View File

@@ -100,12 +100,12 @@ namespace BlackMisc
CAircraftEngine CAircraftParts::getEngine(int number) const
{
return this->m_engines.findBy(&CAircraftEngine::getNumber, number).frontOrDefault();
return this->m_engines.getEngine(number);
}
bool CAircraftParts::isEngineOn(int number) const
{
return this->getEngine(number).isOn();
return this->m_engines.isEngineOn(number);
}
} // namespace

View File

@@ -94,7 +94,7 @@ namespace BlackMisc
//! Engine with number
CAircraftEngine getEngine(int number) const;
//! Is engine with number on?
//! Is engine with number 1..n on?
bool isEngineOn(int number) const;
//! Set engines

View File

@@ -25,11 +25,11 @@ TRANSLATIONS += translations/blackmisc_i18n_de.ts \
HEADERS += *.h \
$$PWD/simulation/*.h \
$$PWD/aviation/*.h \
$$PWD/aviation/*.h
SOURCES += *.cpp \
$$PWD/simulation/*.cpp \
$$PWD/aviation/*.cpp \
$$PWD/aviation/*.cpp
DESTDIR = ../../lib
OTHER_FILES += $$TRANSLATIONS readme.txt

View File

@@ -100,7 +100,7 @@ namespace BlackMisc
void setDistanceToOwnAircraft(const BlackMisc::PhysicalQuantities::CLength &distance) { this->m_distanceToOwnAircraft = distance; }
//! Get the bearing to own plane
const BlackMisc::PhysicalQuantities::CAngle &getBearingToOwnAIrcraft() const { return m_bearingToOwnAircraft; }
const BlackMisc::PhysicalQuantities::CAngle &getBearingToOwnAircraft() const { return m_bearingToOwnAircraft; }
//! Set bearing to own plane
void setBearingToOwnAircraft(const BlackMisc::PhysicalQuantities::CAngle &angle) { this->m_bearingToOwnAircraft = angle; }

View File

@@ -38,7 +38,7 @@ namespace BlackMisc
}
template <class OBJ, class CONTAINER>
void IGeoObjectWithRelativePositionList<OBJ, CONTAINER>::calculcateDistanceAndBearingToPlane(const ICoordinateGeodetic &position)
void IGeoObjectWithRelativePositionList<OBJ, CONTAINER>::calculcateDistanceAndBearingToPosition(const ICoordinateGeodetic &position)
{
for (OBJ &geoObj : this->container())
{
@@ -60,11 +60,16 @@ namespace BlackMisc
{
if (updateValues)
{
this->calculcateDistanceAndBearingToPlane(position);
this->calculcateDistanceAndBearingToPosition(position);
}
this->container().sort([ & ](const OBJ & a, const OBJ & b) { return a.getDistanceToOwnAircraft() < b.getDistanceToOwnAircraft(); });
}
template <class OBJ, class CONTAINER>
void IGeoObjectWithRelativePositionList<OBJ, CONTAINER>::sortByDistanceToOwnAircraft()
{
this->container().sort([ & ](const OBJ & a, const OBJ & b) { return a.getDistanceToOwnAircraft() < b.getDistanceToOwnAircraft(); });
}
// see here for the reason of thess forward instantiations
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html

View File

@@ -53,11 +53,14 @@ namespace BlackMisc
//! Calculate distances, then sort by range
void sortByRange(const BlackMisc::Geo::ICoordinateGeodetic &position, bool updateValues);
//! If distance is already set, just sort
void sortByDistanceToOwnAircraft();
//! Calculate distances, remove if outside range
void removeIfOutsideRange(const BlackMisc::Geo::ICoordinateGeodetic &position, const BlackMisc::PhysicalQuantities::CLength &maxDistance, bool updateValues);
//! Calculate distances
void calculcateDistanceAndBearingToPlane(const BlackMisc::Geo::ICoordinateGeodetic &position);
void calculcateDistanceAndBearingToPosition(const BlackMisc::Geo::ICoordinateGeodetic &position);
protected:
//! Constructor

View File

@@ -503,22 +503,6 @@ namespace BlackMisc
return result;
}
/*!
* \brief Return a copy as derived container sorted by a given comparator predicate.
* \remarks Sorts in background.
*/
template <class TargetContainer, class Predicate>
QFuture<TargetContainer> sortedAsync(Predicate p) const
{
TargetContainer result = *this;
QFuture<TargetContainer> f = QtConcurrent::run([ = ]()
{
result.sort(p);
return result;
});
return f;
}
/*!
* \brief Return a copy sorted by some particular key(s).
* \param key1 A pointer to a member function of T.

View File

@@ -31,7 +31,7 @@ namespace BlackMisc
class CSimulatedAircraftList :
public BlackMisc::CSequence<CSimulatedAircraft>,
public BlackMisc::Aviation::ICallsignObjectList<CSimulatedAircraft, CSimulatedAircraftList>,
public BlackMisc::Geo::IGeoObjectList<CSimulatedAircraft, CSimulatedAircraftList>
public BlackMisc::Geo::IGeoObjectWithRelativePositionList<CSimulatedAircraft, CSimulatedAircraftList>
{
public:
//! Default constructor.

View File

@@ -119,7 +119,7 @@ namespace BlackMisc
}
template <class OBJ, class CONTAINER>
void ITimestampObjectList<OBJ, CONTAINER>::removeOlderThanNowMinusOffset(int offsetMs)
void ITimestampObjectList<OBJ, CONTAINER>::removeOlderThanNowMinusOffset(qint64 offsetMs)
{
const qint64 epoch = QDateTime::currentMSecsSinceEpoch() - offsetMs;
this->container().removeIf([&](const OBJ & obj)

View File

@@ -61,7 +61,7 @@ namespace BlackMisc
void removeBefore(qint64 msSinceEpoch);
//! Remove objects older than seconds
void removeOlderThanNowMinusOffset(int offsetMs);
void removeOlderThanNowMinusOffset(qint64 offsetMs);
//! Sort by timestamp
void sortLatestFirst();