mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-18 03:15:34 +08:00
refs #395, moved thread safe aircraft parts / situations (from interpolator) to airspace
* access via provider, access now possible also beyond the scope of interpolator * will be used in (to be written airpace analyzer) * renamed some member functions as required * fixed some asserts / Doxygen comments * adjusted unit tests * added vtolAircraft flag for interpolator, not fully used everywhere remarks: update signals for parts / situation still only needed in XP driver
This commit is contained in:
committed by
Mathew Sutcliffe
parent
32e65669a3
commit
48188dd28d
@@ -77,53 +77,53 @@ namespace BlackCore
|
|||||||
return m_aircraftInRange;
|
return m_aircraftInRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CAircraftSituationList &CAirspaceMonitor::remoteAircraftSituations() const
|
CAircraftSituationList CAirspaceMonitor::remoteAircraftSituations(const CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
// not thread safe, check
|
QReadLocker l(&m_lockSituations);
|
||||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
static const CAircraftSituationList empty;
|
||||||
return m_aircraftSituations;
|
if (!m_situationsByCallsign.contains(callsign)) { return empty; }
|
||||||
|
return m_situationsByCallsign[callsign];
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftSituationList &CAirspaceMonitor::remoteAircraftSituations()
|
int CAirspaceMonitor::remoteAircraftSituationsCount(const CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
// not thread safe, check
|
QReadLocker l(&m_lockSituations);
|
||||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
if (!m_situationsByCallsign.contains(callsign)) { return -1; }
|
||||||
return m_aircraftSituations;
|
return m_situationsByCallsign[callsign].size();
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftSituationList CAirspaceMonitor::getRenderedAircraftSituations() const
|
CAircraftPartsList CAirspaceMonitor::remoteAircraftParts(const CCallsign &callsign, qint64 cutoffTimeValuesBefore) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
QReadLocker l(&m_lockParts);
|
||||||
return this->m_aircraftSituations;
|
static const CAircraftPartsList empty;
|
||||||
|
if (!m_partsByCallsign.contains(callsign)) { return empty; }
|
||||||
|
if (cutoffTimeValuesBefore < 0)
|
||||||
|
{
|
||||||
|
return m_partsByCallsign[callsign];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return m_partsByCallsign[callsign].findBefore(cutoffTimeValuesBefore);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const CAircraftPartsList &CAirspaceMonitor::remoteAircraftParts() const
|
bool CAirspaceMonitor::isRemoteAircraftSupportingParts(const CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
// not thread safe, check
|
QReadLocker l(&m_lockParts);
|
||||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
return m_aircraftSupportingParts.contains(callsign);
|
||||||
return m_aircraftParts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftPartsList &CAirspaceMonitor::remoteAircraftParts()
|
CCallsignSet CAirspaceMonitor::remoteAircraftSupportingParts() const
|
||||||
{
|
{
|
||||||
// not thread safe, check
|
QReadLocker l(&m_lockParts);
|
||||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
return m_aircraftSupportingParts;
|
||||||
return m_aircraftParts;
|
|
||||||
}
|
|
||||||
|
|
||||||
CAircraftPartsList CAirspaceMonitor::getRenderedAircraftParts() const
|
|
||||||
{
|
|
||||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
|
||||||
return this->m_aircraftParts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAirspaceMonitor::connectRemoteAircraftProviderSignals(
|
bool CAirspaceMonitor::connectRemoteAircraftProviderSignals(
|
||||||
std::function<void(const CAircraftSituation &)> situationSlot,
|
std::function<void(const CAircraftSituation &)> situationSlot,
|
||||||
std::function<void(const CAircraftParts &)> partsSlot,
|
std::function<void(const CAircraftParts &)> partsSlot,
|
||||||
std::function<void(const CCallsign &)> removedAircraftSlot
|
std::function<void(const CCallsign &)> removedAircraftSlot)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
// bool s1 = connect(this, &CAirspaceMonitor::addedRemoteAircraftSituation, situationSlot);
|
|
||||||
bool s1 = connect(this->m_network, &INetwork::aircraftPositionUpdate, situationSlot);
|
bool s1 = connect(this->m_network, &INetwork::aircraftPositionUpdate, situationSlot);
|
||||||
Q_ASSERT(s1);
|
Q_ASSERT(s1);
|
||||||
bool s2 = connect(this, &CAirspaceMonitor::addedRemoteAircraftParts, partsSlot);
|
bool s2 = connect(this, &CAirspaceMonitor::addedRemoteAircraftParts, partsSlot);
|
||||||
@@ -516,8 +516,16 @@ namespace BlackCore
|
|||||||
const CCallsign cs(aircraft.getCallsign());
|
const CCallsign cs(aircraft.getCallsign());
|
||||||
emit removedRemoteAircraft(cs);
|
emit removedRemoteAircraft(cs);
|
||||||
}
|
}
|
||||||
m_aircraftSituations.clear();
|
|
||||||
m_aircraftParts.clear();
|
// block for lock scope
|
||||||
|
{
|
||||||
|
QWriteLocker l1(&m_lockParts);
|
||||||
|
QWriteLocker l2(&m_lockSituations);
|
||||||
|
m_situationsByCallsign.clear();
|
||||||
|
m_partsByCallsign.clear();
|
||||||
|
m_aircraftSupportingParts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
m_aircraftInRange.clear();
|
m_aircraftInRange.clear();
|
||||||
m_flightPlanCache.clear();
|
m_flightPlanCache.clear();
|
||||||
m_icaoCodeCache.clear();
|
m_icaoCodeCache.clear();
|
||||||
@@ -769,8 +777,7 @@ namespace BlackCore
|
|||||||
Q_ASSERT_X(!callsign.isEmpty(), "ps_aircraftUpdateReceived", "Empty callsign");
|
Q_ASSERT_X(!callsign.isEmpty(), "ps_aircraftUpdateReceived", "Empty callsign");
|
||||||
|
|
||||||
// store situation history
|
// store situation history
|
||||||
this->m_aircraftSituations.push_front(situation);
|
this->storeAircraftSituation(situation);
|
||||||
this->m_aircraftSituations.removeOlderThanNowMinusOffset(AircraftSituationsRemovedOffsetMs);
|
|
||||||
emit this->addedRemoteAircraftSituation(situation);
|
emit this->addedRemoteAircraftSituation(situation);
|
||||||
|
|
||||||
bool exists = this->m_aircraftInRange.containsCallsign(callsign);
|
bool exists = this->m_aircraftInRange.containsCallsign(callsign);
|
||||||
@@ -892,15 +899,22 @@ namespace BlackCore
|
|||||||
void CAirspaceMonitor::ps_pilotDisconnected(const CCallsign &callsign)
|
void CAirspaceMonitor::ps_pilotDisconnected(const CCallsign &callsign)
|
||||||
{
|
{
|
||||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||||
bool contains = this->m_aircraftInRange.containsCallsign(callsign);
|
|
||||||
|
|
||||||
// if with contains false remove here, in case of inconsistencies
|
// in case of inconsistencies I always remove here
|
||||||
this->m_aircraftWatchdog.removeCallsign(callsign);
|
this->m_aircraftWatchdog.removeCallsign(callsign);
|
||||||
this->m_otherClients.removeByCallsign(callsign);
|
this->m_otherClients.removeByCallsign(callsign);
|
||||||
this->m_aircraftSituations.removeByCallsign(callsign);
|
|
||||||
this->m_aircraftParts.removeByCallsign(callsign);
|
|
||||||
this->removeFromAircraftCaches(callsign);
|
this->removeFromAircraftCaches(callsign);
|
||||||
|
|
||||||
|
// block for lock scope
|
||||||
|
{
|
||||||
|
QWriteLocker l1(&m_lockParts);
|
||||||
|
QWriteLocker l2(&m_lockSituations);
|
||||||
|
m_situationsByCallsign.remove(callsign);
|
||||||
|
m_partsByCallsign.remove(callsign);
|
||||||
|
m_aircraftSupportingParts.remove(callsign);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains = this->m_aircraftInRange.containsCallsign(callsign);
|
||||||
if (contains)
|
if (contains)
|
||||||
{
|
{
|
||||||
this->m_aircraftInRange.removeByCallsign(callsign);
|
this->m_aircraftInRange.removeByCallsign(callsign);
|
||||||
@@ -938,7 +952,7 @@ namespace BlackCore
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// incremental update
|
// incremental update
|
||||||
parts = m_aircraftParts.findFirstByCallsign(callsign);
|
parts = this->remoteAircraftParts(callsign).findFirstByCallsign(callsign);
|
||||||
QJsonObject config = applyIncrementalObject(parts.toJson(), jsonObject);
|
QJsonObject config = applyIncrementalObject(parts.toJson(), jsonObject);
|
||||||
parts.convertFromJson(config);
|
parts.convertFromJson(config);
|
||||||
}
|
}
|
||||||
@@ -947,9 +961,8 @@ namespace BlackCore
|
|||||||
parts.setCurrentUtcTime();
|
parts.setCurrentUtcTime();
|
||||||
parts.setCallsign(callsign);
|
parts.setCallsign(callsign);
|
||||||
|
|
||||||
// store part history
|
// store part history (parts always absolute)
|
||||||
this->m_aircraftParts.push_front(parts);
|
this->storeAircraftParts(parts);
|
||||||
this->m_aircraftParts.removeOlderThanNowMinusOffset(AircraftPartsRemoveOffsetMs);
|
|
||||||
emit this->addedRemoteAircraftParts(parts);
|
emit this->addedRemoteAircraftParts(parts);
|
||||||
|
|
||||||
// here I expect always a changed value
|
// here I expect always a changed value
|
||||||
@@ -963,6 +976,40 @@ namespace BlackCore
|
|||||||
if (!this->m_connected || !m_sendInterimPositions) { return; }
|
if (!this->m_connected || !m_sendInterimPositions) { return; }
|
||||||
CSimulatedAircraftList aircrafts = m_aircraftInRange.findBy(&CSimulatedAircraft::fastPositionUpdates, true);
|
CSimulatedAircraftList aircrafts = m_aircraftInRange.findBy(&CSimulatedAircraft::fastPositionUpdates, true);
|
||||||
m_network->sendInterimPosition(aircrafts.getCallsigns());
|
m_network->sendInterimPosition(aircrafts.getCallsigns());
|
||||||
|
|
||||||
|
void CAirspaceMonitor::storeAircraftSituation(const CAircraftSituation &situation)
|
||||||
|
{
|
||||||
|
QWriteLocker lock(&m_lockSituations);
|
||||||
|
const CCallsign callsign(situation.getCallsign());
|
||||||
|
Q_ASSERT_X(!callsign.isEmpty(), "storeAircraftSituation", "empty callsign");
|
||||||
|
if (callsign.isEmpty()) { return; }
|
||||||
|
|
||||||
|
// list from new to old
|
||||||
|
CAircraftSituationList &l = this->m_situationsByCallsign[callsign];
|
||||||
|
l.push_frontMaxElements(situation, MaxSituationsPerCallsign);
|
||||||
|
|
||||||
|
// check sort order
|
||||||
|
Q_ASSERT_X(l.size() < 2 || l[0].getMSecsSinceEpoch() >= l[1].getMSecsSinceEpoch(), "storeAircraftSituation", "wrong sort order");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAirspaceMonitor::storeAircraftParts(const CAircraftParts &parts)
|
||||||
|
{
|
||||||
|
QWriteLocker lock(&m_lockParts);
|
||||||
|
const CCallsign callsign(parts.getCallsign());
|
||||||
|
Q_ASSERT_X(!callsign.isEmpty(), "storeAircraftParts", "empty callsign");
|
||||||
|
if (callsign.isEmpty()) { return; }
|
||||||
|
|
||||||
|
// list sorted from new to old
|
||||||
|
CAircraftPartsList &l = this->m_partsByCallsign[callsign];
|
||||||
|
l.push_frontMaxElements(parts, MaxPartsPerCallsign);
|
||||||
|
|
||||||
|
if (!m_aircraftSupportingParts.contains(callsign))
|
||||||
|
{
|
||||||
|
m_aircraftSupportingParts.push_back(callsign); // mark as callsign which supports parts
|
||||||
|
}
|
||||||
|
|
||||||
|
// check sort order
|
||||||
|
Q_ASSERT_X(l.size() < 2 || l[0].getMSecsSinceEpoch() >= l[1].getMSecsSinceEpoch(), "storeAircraftParts", "wrong sort order");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -43,25 +43,28 @@ namespace BlackCore
|
|||||||
//! Constructor
|
//! Constructor
|
||||||
CAirspaceMonitor(QObject *parent, const BlackMisc::Simulation::IOwnAircraftProviderReadOnly *ownAircraft, INetwork *network, CVatsimBookingReader *bookings, CVatsimDataFileReader *dataFile);
|
CAirspaceMonitor(QObject *parent, const BlackMisc::Simulation::IOwnAircraftProviderReadOnly *ownAircraft, INetwork *network, CVatsimBookingReader *bookings, CVatsimDataFileReader *dataFile);
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraft
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraft
|
||||||
virtual const BlackMisc::Simulation::CSimulatedAircraftList &remoteAircraft() const override;
|
virtual const BlackMisc::Simulation::CSimulatedAircraftList &remoteAircraft() const override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProvider::renderedAircraft
|
//! \copydoc IRemoteAircraftProvider::remoteAircraft
|
||||||
virtual BlackMisc::Simulation::CSimulatedAircraftList &remoteAircraft() override;
|
virtual BlackMisc::Simulation::CSimulatedAircraftList &remoteAircraft() override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProvider::remoteAircraftSituations
|
//! \copydoc IRemoteAircraftProvider::remoteAircraftSituations
|
||||||
virtual const BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() const override;
|
virtual BlackMisc::Aviation::CAircraftSituationList remoteAircraftSituations(const BlackMisc::Aviation::CCallsign &callsign) const override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProvider::remoteAircraftSituations
|
//! \copydoc IRemoteAircraftProvider::remoteAircraftSituationsCount
|
||||||
virtual BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() override;
|
virtual int remoteAircraftSituationsCount(const BlackMisc::Aviation::CCallsign &callsign) const override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProvider::remoteAircraftParts
|
//! \copydoc IRemoteAircraftProvider::remoteAircraftParts
|
||||||
virtual const BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() const override;
|
virtual BlackMisc::Aviation::CAircraftPartsList remoteAircraftParts(const BlackMisc::Aviation::CCallsign &callsign, qint64 cutoffTimeValuesBefore = -1) const override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProvider::remoteAircraftParts
|
//! \copydoc IRemoteAircraftProviderReadOnly::isRemoteAircraftSupportingParts
|
||||||
virtual BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() override;
|
virtual bool isRemoteAircraftSupportingParts(const BlackMisc::Aviation::CCallsign &callsign) const override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProvider::remoteAircraftParts
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSupportingParts
|
||||||
|
virtual BlackMisc::Aviation::CCallsignSet remoteAircraftSupportingParts() const override;
|
||||||
|
|
||||||
|
//! \copydoc IRemoteAircraftProvider::updateAircraftEnabled
|
||||||
virtual bool updateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator) override;
|
virtual bool updateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator) override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProvider::updateAircraftModel
|
//! \copydoc IRemoteAircraftProvider::updateAircraftModel
|
||||||
@@ -116,12 +119,6 @@ namespace BlackCore
|
|||||||
//! Test injected aircraft parts
|
//! Test injected aircraft parts
|
||||||
void testAddAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts, bool incremental);
|
void testAddAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts, bool incremental);
|
||||||
|
|
||||||
//! Aircraft situations
|
|
||||||
virtual BlackMisc::Aviation::CAircraftSituationList getRenderedAircraftSituations() const;
|
|
||||||
|
|
||||||
//! Aircraft parts
|
|
||||||
virtual BlackMisc::Aviation::CAircraftPartsList getRenderedAircraftParts() const;
|
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::connectSignals
|
//! \copydoc IRemoteAircraftProviderReadOnly::connectSignals
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::connectSignals
|
//! \copydoc IRemoteAircraftProviderReadOnly::connectSignals
|
||||||
virtual bool connectRemoteAircraftProviderSignals(
|
virtual bool connectRemoteAircraftProviderSignals(
|
||||||
@@ -143,7 +140,7 @@ namespace BlackCore
|
|||||||
|
|
||||||
//--- signals for the provider, work locally only (not in DBus)
|
//--- signals for the provider, work locally only (not in DBus)
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftSituation
|
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftPart
|
||||||
void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
|
void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftPart
|
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftPart
|
||||||
@@ -152,6 +149,8 @@ namespace BlackCore
|
|||||||
//! \copydoc IRemoteAircraftProviderReadOnly::removedAircraft
|
//! \copydoc IRemoteAircraftProviderReadOnly::removedAircraft
|
||||||
void removedRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign);
|
void removedRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign);
|
||||||
|
|
||||||
|
//--- DBus / local signals
|
||||||
|
|
||||||
//! Online ATC stations were changed
|
//! Online ATC stations were changed
|
||||||
void changedAtcStationsOnline();
|
void changedAtcStationsOnline();
|
||||||
|
|
||||||
@@ -175,8 +174,11 @@ namespace BlackCore
|
|||||||
BlackMisc::Aviation::CAtcStationList m_atcStationsBooked;
|
BlackMisc::Aviation::CAtcStationList m_atcStationsBooked;
|
||||||
BlackMisc::Network::CClientList m_otherClients;
|
BlackMisc::Network::CClientList m_otherClients;
|
||||||
BlackMisc::Simulation::CSimulatedAircraftList m_aircraftInRange;
|
BlackMisc::Simulation::CSimulatedAircraftList m_aircraftInRange;
|
||||||
BlackMisc::Aviation::CAircraftSituationList m_aircraftSituations;
|
|
||||||
BlackMisc::Aviation::CAircraftPartsList m_aircraftParts;
|
// hashs, because not sorted by key but keeping order
|
||||||
|
CSituationsPerCallsign m_situationsByCallsign; //!< situations, for performance reasons per callsign
|
||||||
|
CPartsPerCallsign m_partsByCallsign; //!< parts, for performance reasons per callsign
|
||||||
|
BlackMisc::Aviation::CCallsignSet m_aircraftSupportingParts; //!< aircraft supporting parts
|
||||||
|
|
||||||
QMap<BlackMisc::Aviation::CAirportIcao, BlackMisc::Aviation::CInformationMessage> m_metarCache;
|
QMap<BlackMisc::Aviation::CAirportIcao, BlackMisc::Aviation::CInformationMessage> m_metarCache;
|
||||||
QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CFlightPlan> m_flightPlanCache;
|
QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CFlightPlan> m_flightPlanCache;
|
||||||
@@ -190,9 +192,18 @@ namespace BlackCore
|
|||||||
bool m_serverSupportsNameQuery = false; //!< not all servers support name query
|
bool m_serverSupportsNameQuery = false; //!< not all servers support name query
|
||||||
bool m_connected = false; //!< retrieve data
|
bool m_connected = false; //!< retrieve data
|
||||||
bool m_sendInterimPositions = false;
|
bool m_sendInterimPositions = false;
|
||||||
|
|
||||||
QTimer m_interimPositionUpdateTimer;
|
QTimer m_interimPositionUpdateTimer;
|
||||||
|
|
||||||
|
// locks
|
||||||
|
mutable QReadWriteLock m_lockSituations; //!< lock for situations
|
||||||
|
mutable QReadWriteLock m_lockParts; //!< lock for parts
|
||||||
|
|
||||||
|
|
||||||
|
// TODO FIXME (MS) should be in INetwork
|
||||||
|
void sendFsipiCustomPacket(const BlackMisc::Aviation::CCallsign &recipientCallsign) const;
|
||||||
|
void sendFsipirCustomPacket(const BlackMisc::Aviation::CCallsign &recipientCallsign) const;
|
||||||
|
QStringList createFsipiCustomPacketData() const;
|
||||||
|
|
||||||
//! Remove ATC online stations
|
//! Remove ATC online stations
|
||||||
void removeAllOnlineAtcStations();
|
void removeAllOnlineAtcStations();
|
||||||
|
|
||||||
@@ -208,6 +219,14 @@ namespace BlackCore
|
|||||||
//! Schedule a ready for model matching
|
//! Schedule a ready for model matching
|
||||||
void fireDelayedReadyForModelMatching(const BlackMisc::Aviation::CCallsign &callsign, int trial = 1, int delayMs = 2500);
|
void fireDelayedReadyForModelMatching(const BlackMisc::Aviation::CCallsign &callsign, int trial = 1, int delayMs = 2500);
|
||||||
|
|
||||||
|
//! Store an aircraft situation
|
||||||
|
//! \threadsafe
|
||||||
|
void storeAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
|
||||||
|
|
||||||
|
//! Store an aircraft part
|
||||||
|
//! \threadsafe
|
||||||
|
void storeAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
//! Create aircraft in range, this is the only place where a new aircraft should be added
|
//! Create aircraft in range, this is the only place where a new aircraft should be added
|
||||||
void ps_aircraftUpdateReceived(const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Aviation::CTransponder &transponder);
|
void ps_aircraftUpdateReceived(const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Aviation::CTransponder &transponder);
|
||||||
|
|||||||
@@ -78,12 +78,13 @@ namespace BlackCore
|
|||||||
connect(this->m_airspace, &CAirspaceMonitor::changedAtcStationsBooked, this, &CContextNetwork::changedAtcStationsBooked);
|
connect(this->m_airspace, &CAirspaceMonitor::changedAtcStationsBooked, this, &CContextNetwork::changedAtcStationsBooked);
|
||||||
connect(this->m_airspace, &CAirspaceMonitor::changedAtcStationOnlineConnectionStatus, this, &CContextNetwork::changedAtcStationOnlineConnectionStatus);
|
connect(this->m_airspace, &CAirspaceMonitor::changedAtcStationOnlineConnectionStatus, this, &CContextNetwork::changedAtcStationOnlineConnectionStatus);
|
||||||
connect(this->m_airspace, &CAirspaceMonitor::changedAircraftInRange, this, &CContextNetwork::changedAircraftInRange);
|
connect(this->m_airspace, &CAirspaceMonitor::changedAircraftInRange, this, &CContextNetwork::changedAircraftInRange);
|
||||||
connect(this->m_airspace, &CAirspaceMonitor::removedRemoteAircraft, this, &IContextNetwork::removedAircraft);
|
connect(this->m_airspace, &CAirspaceMonitor::removedRemoteAircraft, this, &IContextNetwork::removedAircraft); // DBus
|
||||||
connect(this->m_airspace, &CAirspaceMonitor::removedRemoteAircraft, this, &CContextNetwork::removedRemoteAircraft);
|
|
||||||
connect(this->m_airspace, &CAirspaceMonitor::readyForModelMatching, this, &CContextNetwork::readyForModelMatching);
|
connect(this->m_airspace, &CAirspaceMonitor::readyForModelMatching, this, &CContextNetwork::readyForModelMatching);
|
||||||
connect(this->m_airspace, &CAirspaceMonitor::addedRemoteAircraftParts, this, &CContextNetwork::addedRemoteAircraftParts);
|
|
||||||
connect(this->m_airspace, &CAirspaceMonitor::addedRemoteAircraftSituation, this, &CContextNetwork::addedRemoteAircraftSituation);
|
|
||||||
connect(this->m_airspace, &CAirspaceMonitor::addedAircraft, this, &CContextNetwork::addedAircraft);
|
connect(this->m_airspace, &CAirspaceMonitor::addedAircraft, this, &CContextNetwork::addedAircraft);
|
||||||
|
|
||||||
|
// remote provider, local only
|
||||||
|
connect(this->m_airspace, &CAirspaceMonitor::removedRemoteAircraft, this, &CContextNetwork::removedRemoteAircraft); // Local
|
||||||
|
connect(this->m_airspace, &CAirspaceMonitor::addedRemoteAircraftParts, this, &CContextNetwork::addedRemoteAircraftParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
CContextNetwork::~CContextNetwork()
|
CContextNetwork::~CContextNetwork()
|
||||||
@@ -103,28 +104,34 @@ namespace BlackCore
|
|||||||
return m_airspace->remoteAircraft();
|
return m_airspace->remoteAircraft();
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftSituationList &CContextNetwork::remoteAircraftSituations()
|
CAircraftSituationList CContextNetwork::remoteAircraftSituations(const CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(this->m_airspace);
|
Q_ASSERT(this->m_airspace);
|
||||||
return m_airspace->remoteAircraftSituations();
|
return m_airspace->remoteAircraftSituations(callsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CAircraftSituationList &CContextNetwork::remoteAircraftSituations() const
|
CAircraftPartsList CContextNetwork::remoteAircraftParts(const CCallsign &callsign, qint64 cutoffTimeBefore) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(this->m_airspace);
|
Q_ASSERT(this->m_airspace);
|
||||||
return m_airspace->remoteAircraftSituations();
|
return m_airspace->remoteAircraftParts(callsign, cutoffTimeBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CAircraftPartsList &CContextNetwork::remoteAircraftParts() const
|
int CContextNetwork::remoteAircraftSituationsCount(const CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(this->m_airspace);
|
Q_ASSERT(this->m_airspace);
|
||||||
return m_airspace->remoteAircraftParts();
|
return m_airspace->remoteAircraftSituationsCount(callsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftPartsList &CContextNetwork::remoteAircraftParts()
|
bool CContextNetwork::isRemoteAircraftSupportingParts(const CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(this->m_airspace);
|
Q_ASSERT(this->m_airspace);
|
||||||
return m_airspace->remoteAircraftParts();
|
return m_airspace->isRemoteAircraftSupportingParts(callsign);
|
||||||
|
}
|
||||||
|
|
||||||
|
CCallsignSet CContextNetwork::remoteAircraftSupportingParts() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(this->m_airspace);
|
||||||
|
return m_airspace->remoteAircraftSupportingParts();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CContextNetwork::connectRemoteAircraftProviderSignals(
|
bool CContextNetwork::connectRemoteAircraftProviderSignals(
|
||||||
|
|||||||
@@ -51,23 +51,26 @@ namespace BlackCore
|
|||||||
//! Destructor
|
//! Destructor
|
||||||
virtual ~CContextNetwork();
|
virtual ~CContextNetwork();
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraft
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraft
|
||||||
virtual const BlackMisc::Simulation::CSimulatedAircraftList &remoteAircraft() const override;
|
virtual const BlackMisc::Simulation::CSimulatedAircraftList &remoteAircraft() const override;
|
||||||
|
|
||||||
//! \copydoc IRenderedAircraftProvider::renderedAircraft
|
//! \copydoc IRenderedAircraftProvider::remoteAircraft
|
||||||
virtual BlackMisc::Simulation::CSimulatedAircraftList &remoteAircraft() override;
|
virtual BlackMisc::Simulation::CSimulatedAircraftList &remoteAircraft() override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraftSituations
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSituations
|
||||||
virtual const BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() const override;
|
virtual BlackMisc::Aviation::CAircraftSituationList remoteAircraftSituations(const BlackMisc::Aviation::CCallsign &callsign) const override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraftSituations
|
//! \copydoc IRemoteAircraftProvider::remoteAircraftSituationsCount
|
||||||
virtual BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() override;
|
virtual int remoteAircraftSituationsCount(const BlackMisc::Aviation::CCallsign &callsign) const override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraftParts
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftParts
|
||||||
virtual const BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() const override;
|
virtual BlackMisc::Aviation::CAircraftPartsList remoteAircraftParts(const BlackMisc::Aviation::CCallsign &callsign, qint64 cutoffTimeBefore = -1) const override;
|
||||||
|
|
||||||
//! \copydoc IRenderedAircraftProvider::renderedAircraftParts
|
//! \copydoc IRemoteAircraftProviderReadOnly::isRemoteAircraftSupportingParts
|
||||||
virtual BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() override;
|
virtual bool isRemoteAircraftSupportingParts(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||||
|
|
||||||
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSupportingParts
|
||||||
|
virtual BlackMisc::Aviation::CCallsignSet remoteAircraftSupportingParts() const override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::connectSignals
|
//! \copydoc IRemoteAircraftProviderReadOnly::connectSignals
|
||||||
virtual bool connectRemoteAircraftProviderSignals(
|
virtual bool connectRemoteAircraftProviderSignals(
|
||||||
@@ -77,9 +80,6 @@ namespace BlackCore
|
|||||||
) override;
|
) override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftSituation
|
|
||||||
void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
|
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftPart
|
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftPart
|
||||||
void addedRemoteAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts);
|
void addedRemoteAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts);
|
||||||
|
|
||||||
|
|||||||
@@ -23,101 +23,18 @@ namespace BlackCore
|
|||||||
CContinuousWorker(parent, workerName),
|
CContinuousWorker(parent, workerName),
|
||||||
CRemoteAircraftAwareReadOnly(provider)
|
CRemoteAircraftAwareReadOnly(provider)
|
||||||
{
|
{
|
||||||
Q_ASSERT(provider);
|
Q_ASSERT_X(provider, Q_FUNC_INFO, "missing provider");
|
||||||
this->m_situationsByCallsign = this->remoteAircraftSituations().splitPerCallsign();
|
|
||||||
this->m_partsByCallsign = this->remoteAircraftParts().splitPerCallsign();
|
|
||||||
bool c = provider->connectRemoteAircraftProviderSignals(
|
|
||||||
std::bind(&IInterpolator::ps_onAddedAircraftSituation, this, std::placeholders::_1),
|
|
||||||
std::bind(&IInterpolator::ps_onAddedAircraftParts, this, std::placeholders::_1),
|
|
||||||
std::bind(&IInterpolator::ps_onRemovedAircraft, this, std::placeholders::_1)
|
|
||||||
);
|
|
||||||
Q_ASSERT(c);
|
|
||||||
Q_UNUSED(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftSituationList IInterpolator::getInterpolatedSituations(qint64 currentTimeMsSinceEpoch)
|
CAircraftPartsList IInterpolator::getPartsBeforeTime(const CCallsign &callsign, qint64 cutoffTime, BlackCore::IInterpolator::PartsStatus &partsStatus)
|
||||||
{
|
|
||||||
QReadLocker l(&m_lockSituations);
|
|
||||||
const CSituationsPerCallsign situationsCopy(m_situationsByCallsign);
|
|
||||||
l.unlock();
|
|
||||||
|
|
||||||
CAircraftSituationList latestInterpolations;
|
|
||||||
if (currentTimeMsSinceEpoch < 0) { currentTimeMsSinceEpoch = QDateTime::currentMSecsSinceEpoch(); }
|
|
||||||
for (const CCallsign &cs : situationsCopy.keys())
|
|
||||||
{
|
|
||||||
InterpolationStatus status;
|
|
||||||
CAircraftSituation situation = getInterpolatedSituation(cs, currentTimeMsSinceEpoch, status, &situationsCopy);
|
|
||||||
if (status.allTrue())
|
|
||||||
{
|
|
||||||
latestInterpolations.push_back(situation);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// not OK can mean not enough situations
|
|
||||||
// further logging could go here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return latestInterpolations;
|
|
||||||
}
|
|
||||||
|
|
||||||
IInterpolator::CSituationsPerCallsign IInterpolator::getSituationsByCallsign() const
|
|
||||||
{
|
|
||||||
QReadLocker l(&m_lockSituations);
|
|
||||||
return m_situationsByCallsign;
|
|
||||||
}
|
|
||||||
|
|
||||||
CAircraftPartsList IInterpolator::getAndRemovePartsBeforeTime(const CCallsign &callsign, qint64 cutoffTime, BlackCore::IInterpolator::PartsStatus &partsStatus)
|
|
||||||
{
|
{
|
||||||
static const CAircraftPartsList empty;
|
static const CAircraftPartsList empty;
|
||||||
Q_ASSERT_X(!callsign.isEmpty(), "getAndRemovePartsBeforeTime", "empty callsign");
|
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "empty callsign");
|
||||||
partsStatus.reset();
|
partsStatus.reset();
|
||||||
QWriteLocker l(&m_lockParts);
|
|
||||||
if (this->m_partsByCallsign.contains(callsign))
|
|
||||||
{
|
|
||||||
partsStatus.supportsParts = true;
|
|
||||||
if (cutoffTime < 0) { return this->m_partsByCallsign[callsign]; }
|
|
||||||
return this->m_partsByCallsign[callsign].findBeforeAndRemove(cutoffTime);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// did we ever have parts for this callsign
|
|
||||||
partsStatus.supportsParts = m_aircraftSupportingParts.contains(callsign);
|
|
||||||
return empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void IInterpolator::clear()
|
partsStatus.supportsParts = this->isRemoteAircraftSupportingParts(callsign);
|
||||||
{
|
if (!partsStatus.supportsParts) { return empty; }
|
||||||
QWriteLocker s(&m_lockSituations);
|
return this->remoteAircraftParts(callsign, cutoffTime);
|
||||||
QWriteLocker p(&m_lockParts);
|
|
||||||
m_situationsByCallsign.clear();
|
|
||||||
m_partsByCallsign.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IInterpolator::hasDataForCallsign(const CCallsign &callsign) const
|
|
||||||
{
|
|
||||||
if (callsign.isEmpty()) { return false; }
|
|
||||||
QReadLocker s(&m_lockSituations);
|
|
||||||
if (m_situationsByCallsign.contains(callsign)) { return true; }
|
|
||||||
|
|
||||||
QReadLocker p(&m_lockParts);
|
|
||||||
return m_partsByCallsign.contains(callsign);
|
|
||||||
}
|
|
||||||
|
|
||||||
CAircraftSituationList IInterpolator::getSituationsForCallsign(const CCallsign &callsign) const
|
|
||||||
{
|
|
||||||
QReadLocker l(&m_lockSituations);
|
|
||||||
static const CAircraftSituationList empty;
|
|
||||||
if (!m_situationsByCallsign.contains(callsign)) { return empty; }
|
|
||||||
return m_situationsByCallsign[callsign];
|
|
||||||
}
|
|
||||||
|
|
||||||
CAircraftPartsList IInterpolator::getPartsForCallsign(const CCallsign &callsign) const
|
|
||||||
{
|
|
||||||
QReadLocker l(&m_lockParts);
|
|
||||||
static const CAircraftPartsList empty;
|
|
||||||
if (!m_partsByCallsign.contains(callsign)) { return empty; }
|
|
||||||
return m_partsByCallsign[callsign];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IInterpolator::enableDebugMessages(bool enabled)
|
void IInterpolator::enableDebugMessages(bool enabled)
|
||||||
@@ -125,61 +42,6 @@ namespace BlackCore
|
|||||||
this->m_withDebugMsg = enabled;
|
this->m_withDebugMsg = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IInterpolator::forceSortingOfAddedValues(bool sort)
|
|
||||||
{
|
|
||||||
this->m_forceSortWhenAddingValues = sort;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IInterpolator::ps_onAddedAircraftSituation(const CAircraftSituation &situation)
|
|
||||||
{
|
|
||||||
QWriteLocker lock(&m_lockSituations);
|
|
||||||
const CCallsign callsign(situation.getCallsign());
|
|
||||||
Q_ASSERT_X(!callsign.isEmpty(), "ps_onAddedAircraftSituation", "empty callsign");
|
|
||||||
if (callsign.isEmpty()) { return; }
|
|
||||||
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << situation.getCallsign() << situation.getMSecsSinceEpoch(); }
|
|
||||||
|
|
||||||
// list from new to old
|
|
||||||
CAircraftSituationList &l = this->m_situationsByCallsign[callsign];
|
|
||||||
l.push_frontMaxElements(situation, MaxSituationsPerCallsign);
|
|
||||||
if (this->m_forceSortWhenAddingValues) { l.sortLatestFirst(); }
|
|
||||||
|
|
||||||
// check sort order
|
|
||||||
Q_ASSERT(l.size() < 2 || l[0].getMSecsSinceEpoch() >= l[1].getMSecsSinceEpoch());
|
|
||||||
}
|
|
||||||
|
|
||||||
void IInterpolator::ps_onAddedAircraftParts(const CAircraftParts &parts)
|
|
||||||
{
|
|
||||||
QWriteLocker lock(&m_lockParts);
|
|
||||||
const CCallsign callsign(parts.getCallsign());
|
|
||||||
Q_ASSERT_X(!callsign.isEmpty(), "ps_onAddedAircraftParts", "empty callsign");
|
|
||||||
if (callsign.isEmpty()) { return; }
|
|
||||||
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << parts.getCallsign() << parts.getMSecsSinceEpoch(); }
|
|
||||||
|
|
||||||
// list sorted from new to old
|
|
||||||
CAircraftPartsList &l = this->m_partsByCallsign[callsign];
|
|
||||||
l.push_frontMaxElements(parts, MaxPartsPerCallsign);
|
|
||||||
if (this->m_forceSortWhenAddingValues) { l.sortLatestFirst(); }
|
|
||||||
|
|
||||||
if (m_aircraftSupportingParts.contains(callsign)) { return; }
|
|
||||||
m_aircraftSupportingParts.push_back(callsign); // mark as callsign which supports parts
|
|
||||||
|
|
||||||
// check sort order
|
|
||||||
Q_ASSERT(l.size() < 2 || l[0].getMSecsSinceEpoch() >= l[1].getMSecsSinceEpoch());
|
|
||||||
}
|
|
||||||
|
|
||||||
void IInterpolator::ps_onRemovedAircraft(const CCallsign &callsign)
|
|
||||||
{
|
|
||||||
QWriteLocker ls(&m_lockSituations);
|
|
||||||
QWriteLocker lp(&m_lockParts);
|
|
||||||
Q_ASSERT(!callsign.isEmpty());
|
|
||||||
if (callsign.isEmpty()) { return; }
|
|
||||||
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign; }
|
|
||||||
|
|
||||||
this->m_partsByCallsign.remove(callsign);
|
|
||||||
this->m_situationsByCallsign.remove(callsign);
|
|
||||||
this->m_aircraftSupportingParts.remove(callsign);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IInterpolator::InterpolationStatus::allTrue() const
|
bool IInterpolator::InterpolationStatus::allTrue() const
|
||||||
{
|
{
|
||||||
return interpolationSucceeded && changedPosition;
|
return interpolationSucceeded && changedPosition;
|
||||||
|
|||||||
@@ -29,12 +29,6 @@ namespace BlackCore
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Situations per callsign
|
|
||||||
typedef QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> CSituationsPerCallsign;
|
|
||||||
|
|
||||||
//! Parts per callsign
|
|
||||||
typedef QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftPartsList> CPartsPerCallsign;
|
|
||||||
|
|
||||||
//! Virtual destructor
|
//! Virtual destructor
|
||||||
virtual ~IInterpolator() {}
|
virtual ~IInterpolator() {}
|
||||||
|
|
||||||
@@ -70,79 +64,22 @@ namespace BlackCore
|
|||||||
//! Current interpolated situation
|
//! Current interpolated situation
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
virtual BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation(
|
virtual BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation(
|
||||||
const BlackMisc::Aviation::CCallsign &callsign, qint64 currentTimeSinceEpoc,
|
const BlackMisc::Aviation::CCallsign &callsign, qint64 currentTimeSinceEpoc, bool isVtolAircraft, InterpolationStatus &status) const = 0;
|
||||||
InterpolationStatus &status, const CSituationsPerCallsign *situationsPerCallsign = nullptr) const = 0;
|
|
||||||
|
|
||||||
//! Do a complete calculation for all know callsigns.
|
|
||||||
//! \param currentTimeMsSinceEpoch if no value is passed current time is used
|
|
||||||
//! \threadsafe
|
|
||||||
//!
|
|
||||||
virtual BlackMisc::Aviation::CAircraftSituationList getInterpolatedSituations(qint64 currentTimeMsSinceEpoch = -1);
|
|
||||||
|
|
||||||
//! All situations for all callsigns (in map as per callsign)
|
|
||||||
//! \threadsafe
|
|
||||||
CSituationsPerCallsign getSituationsByCallsign() const;
|
|
||||||
|
|
||||||
//! Parts before given offset time (aka pending parts)
|
//! Parts before given offset time (aka pending parts)
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
virtual BlackMisc::Aviation::CAircraftPartsList getAndRemovePartsBeforeTime(const BlackMisc::Aviation::CCallsign &callsign, qint64 cutoffTime, PartsStatus &partsStatus);
|
virtual BlackMisc::Aviation::CAircraftPartsList getPartsBeforeTime(const BlackMisc::Aviation::CCallsign &callsign, qint64 cutoffTime, PartsStatus &partsStatus);
|
||||||
|
|
||||||
//! Clear all data
|
|
||||||
//! \threadsafe
|
|
||||||
virtual void clear();
|
|
||||||
|
|
||||||
//! Does know callsign?
|
|
||||||
//! \threadsafe
|
|
||||||
virtual bool hasDataForCallsign(const BlackMisc::Aviation::CCallsign &callsign) const;
|
|
||||||
|
|
||||||
//! All situations for given callsign
|
|
||||||
//! \threadsafe
|
|
||||||
BlackMisc::Aviation::CAircraftSituationList getSituationsForCallsign(const BlackMisc::Aviation::CCallsign &callsign) const;
|
|
||||||
|
|
||||||
//! All parts for given callsign
|
|
||||||
//! \threadsafe
|
|
||||||
BlackMisc::Aviation::CAircraftPartsList getPartsForCallsign(const BlackMisc::Aviation::CCallsign &callsign) const;
|
|
||||||
|
|
||||||
//! Enable debug messages
|
//! Enable debug messages
|
||||||
void enableDebugMessages(bool enabled);
|
void enableDebugMessages(bool enabled);
|
||||||
|
|
||||||
//! Force sorting (latest first), not required if order can be guaranteed
|
|
||||||
void forceSortingOfAddedValues(bool sort);
|
|
||||||
|
|
||||||
static const qint64 TimeOffsetMs = 6000; //!< offset for interpolation
|
static const qint64 TimeOffsetMs = 6000; //!< offset for interpolation
|
||||||
static const int MaxSituationsPerCallsign = 6; //!< How many situations per callsign
|
|
||||||
static const int MaxPartsPerCallsign = 3; //!< How many parts per callsign
|
|
||||||
static const int MaxKeptInterpolationRequests = 3; //!< How many requests are stored
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
//! New situation got added
|
|
||||||
//! \threadsafe
|
|
||||||
void ps_onAddedAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
|
|
||||||
|
|
||||||
//! Added aircraft parts
|
|
||||||
//! \threadsafe
|
|
||||||
void ps_onAddedAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts);
|
|
||||||
|
|
||||||
//! Removed aircraft
|
|
||||||
//! \threadsafe
|
|
||||||
void ps_onRemovedAircraft(const BlackMisc::Aviation::CCallsign &callsign);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
IInterpolator(BlackMisc::Simulation::IRemoteAircraftProviderReadOnly *provider, const QString &workerName, QObject *parent = nullptr);
|
IInterpolator(BlackMisc::Simulation::IRemoteAircraftProviderReadOnly *provider, const QString &workerName, QObject *parent = nullptr);
|
||||||
|
|
||||||
bool m_withDebugMsg = false; //!< allows to disable debug messages
|
bool m_withDebugMsg = false; //!< allows to disable debug messages
|
||||||
bool m_forceSortWhenAddingValues = false; //!< force sorting (latest first) when adding values
|
|
||||||
BlackMisc::Aviation::CCallsignSet m_aircraftSupportingParts; //!< aircraft supporting parts
|
|
||||||
|
|
||||||
// hashs, because not sorted by key but keeping order
|
|
||||||
CSituationsPerCallsign m_situationsByCallsign; //!< situations
|
|
||||||
CPartsPerCallsign m_partsByCallsign; //!< parts
|
|
||||||
|
|
||||||
// locks
|
|
||||||
mutable QReadWriteLock m_lockSituations; //!< lock for situations
|
|
||||||
mutable QReadWriteLock m_lockParts; //!< lock for parts
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -20,30 +20,20 @@ using namespace BlackMisc::Aviation;
|
|||||||
|
|
||||||
namespace BlackCore
|
namespace BlackCore
|
||||||
{
|
{
|
||||||
CAircraftSituation CInterpolatorLinear::getInterpolatedSituation(const CCallsign &callsign, qint64 currentTimeMsSinceEpoc, InterpolationStatus &status, const CSituationsPerCallsign *situationsPerCallsign) const
|
CAircraftSituation CInterpolatorLinear::getInterpolatedSituation(const CCallsign &callsign, qint64 currentTimeMsSinceEpoc, bool vtolAiracraft, InterpolationStatus &status) const
|
||||||
{
|
{
|
||||||
const static CAircraftSituation empty;
|
static const CAircraftSituation empty;
|
||||||
status.reset();
|
status.reset();
|
||||||
QList<CAircraftSituationList> splitSituations;
|
|
||||||
|
// any data at all?
|
||||||
|
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "empty callsign");
|
||||||
|
if (this->remoteAircraftSituationsCount(callsign) < 1) { return empty; }
|
||||||
|
|
||||||
|
// data, split situations by time
|
||||||
if (currentTimeMsSinceEpoc < 0) { currentTimeMsSinceEpoc = QDateTime::currentMSecsSinceEpoch(); }
|
if (currentTimeMsSinceEpoc < 0) { currentTimeMsSinceEpoc = QDateTime::currentMSecsSinceEpoch(); }
|
||||||
qint64 splitTimeMsSinceEpoch = currentTimeMsSinceEpoc - TimeOffsetMs;
|
qint64 splitTimeMsSinceEpoch = currentTimeMsSinceEpoc - TimeOffsetMs;
|
||||||
|
|
||||||
if (situationsPerCallsign)
|
QList<CAircraftSituationList> splitSituations(remoteAircraftSituations(callsign).splitByTime(splitTimeMsSinceEpoch, true));
|
||||||
{
|
|
||||||
// lock free, expected that situationsPerCallsign is a copy
|
|
||||||
if (!situationsPerCallsign->contains(callsign)) { return empty; }
|
|
||||||
if ((*situationsPerCallsign)[callsign].isEmpty()) { return empty; }
|
|
||||||
splitSituations = (*situationsPerCallsign)[callsign].splitByTime(splitTimeMsSinceEpoch);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// only part where it is locked
|
|
||||||
QReadLocker lock(&m_lockSituations);
|
|
||||||
if (!m_situationsByCallsign.contains(callsign)) { return empty; }
|
|
||||||
if (m_situationsByCallsign[callsign].isEmpty()) { return empty; }
|
|
||||||
splitSituations = m_situationsByCallsign[callsign].splitByTime(splitTimeMsSinceEpoch, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
CAircraftSituationList &situationsNewer = splitSituations[0]; // newer part
|
CAircraftSituationList &situationsNewer = splitSituations[0]; // newer part
|
||||||
CAircraftSituationList &situationsOlder = splitSituations[1]; // older part
|
CAircraftSituationList &situationsOlder = splitSituations[1]; // older part
|
||||||
|
|
||||||
@@ -123,16 +113,15 @@ namespace BlackCore
|
|||||||
// Interpolate altitude: Alt = (AltB - AltA) * t + AltA
|
// Interpolate altitude: Alt = (AltB - AltA) * t + AltA
|
||||||
const CAltitude oldAlt(oldSituation.getAltitude());
|
const CAltitude oldAlt(oldSituation.getAltitude());
|
||||||
const CAltitude newAlt(newSituation.getAltitude());
|
const CAltitude newAlt(newSituation.getAltitude());
|
||||||
Q_ASSERT(oldAlt.getReferenceDatum() == newAlt.getReferenceDatum()); // otherwise no calculation is possible
|
Q_ASSERT_X(oldAlt.getReferenceDatum() == newAlt.getReferenceDatum(), Q_FUNC_INFO, "mismatch in reference"); // otherwise no calculation is possible
|
||||||
currentSituation.setAltitude(CAltitude((newAlt - oldAlt)
|
currentSituation.setAltitude(CAltitude((newAlt - oldAlt)
|
||||||
* simulationTimeFraction
|
* simulationTimeFraction
|
||||||
+ oldAlt,
|
+ oldAlt,
|
||||||
oldAlt.getReferenceDatum()));
|
oldAlt.getReferenceDatum()));
|
||||||
|
|
||||||
if (newLat == oldLat && newLng == oldLng && oldAlt == newAlt)
|
if (!vtolAiracraft && newLat == oldLat && newLng == oldLng && oldAlt == newAlt)
|
||||||
{
|
{
|
||||||
// stop interpolation here
|
// stop interpolation here, does not work for VTOL aircraft. We need a flag for VTOL aircraft
|
||||||
//! \todo Does not work for VTOL aircraft. We need a flag for VTOL aircraft
|
|
||||||
return currentSituation;
|
return currentSituation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +168,7 @@ namespace BlackCore
|
|||||||
* simulationTimeFraction
|
* simulationTimeFraction
|
||||||
+ oldSituation.getGroundSpeed());
|
+ oldSituation.getGroundSpeed());
|
||||||
status.changedPosition = true;
|
status.changedPosition = true;
|
||||||
Q_ASSERT(currentSituation.getCallsign() == callsign);
|
Q_ASSERT_X(currentSituation.getCallsign() == callsign, Q_FUNC_INFO, "mismatching callsigns");
|
||||||
return currentSituation;
|
return currentSituation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace BlackCore
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
//! \copydoc IInterpolator::getCurrentInterpolatedSituation
|
//! \copydoc IInterpolator::getCurrentInterpolatedSituation
|
||||||
virtual BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation(const BlackMisc::Aviation::CCallsign &callsign, qint64 currentTimeSinceEpoc, InterpolationStatus &status, const CSituationsPerCallsign *situationsPerCallsign = nullptr) const override;
|
virtual BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation(const BlackMisc::Aviation::CCallsign &callsign, qint64 currentTimeSinceEpoc, bool vtolAiracraft, InterpolationStatus &status) const override;
|
||||||
|
|
||||||
//! Log category
|
//! Log category
|
||||||
static QString getMessageCategory() { return "swift.interpolatorlinear"; }
|
static QString getMessageCategory() { return "swift.interpolatorlinear"; }
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace BlackCore
|
|||||||
CRemoteAircraftAware(remoteAircraftProvider),
|
CRemoteAircraftAware(remoteAircraftProvider),
|
||||||
m_simulatorPluginInfo(info)
|
m_simulatorPluginInfo(info)
|
||||||
{
|
{
|
||||||
this->setObjectName("CSimulatorCommon");
|
this->setObjectName(info.getIdentifier());
|
||||||
m_oneSecondTimer = new QTimer(this);
|
m_oneSecondTimer = new QTimer(this);
|
||||||
m_oneSecondTimer->setObjectName(this->objectName().append(":OneSecondTimer"));
|
m_oneSecondTimer->setObjectName(this->objectName().append(":OneSecondTimer"));
|
||||||
connect(this->m_oneSecondTimer, &QTimer::timeout, this, &CSimulatorCommon::ps_oneSecondTimer);
|
connect(this->m_oneSecondTimer, &QTimer::timeout, this, &CSimulatorCommon::ps_oneSecondTimer);
|
||||||
@@ -129,13 +129,13 @@ namespace BlackCore
|
|||||||
if (!this->m_interpolator) { return; }
|
if (!this->m_interpolator) { return; }
|
||||||
|
|
||||||
const CCallsign callsign(aircraft.getCallsign());
|
const CCallsign callsign(aircraft.getCallsign());
|
||||||
if (!this->m_interpolator->hasDataForCallsign(callsign)) { return; }
|
if (!(this->remoteAircraftSituationsCount(callsign) < 1)) { return; }
|
||||||
|
|
||||||
// with an interpolator the interpolated situation is used
|
// with an interpolator the interpolated situation is used
|
||||||
// to avoid position jittering
|
// to avoid position jittering
|
||||||
qint64 time = QDateTime::currentMSecsSinceEpoch();
|
qint64 time = QDateTime::currentMSecsSinceEpoch();
|
||||||
IInterpolator::InterpolationStatus is;
|
IInterpolator::InterpolationStatus is;
|
||||||
CAircraftSituation as(m_interpolator->getInterpolatedSituation(callsign, time, is));
|
CAircraftSituation as(m_interpolator->getInterpolatedSituation(callsign, time, aircraft.isVtol(), is));
|
||||||
if (is.interpolationSucceeded) { aircraft.setSituation(as); }
|
if (is.interpolationSucceeded) { aircraft.setSituation(as); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,67 +18,91 @@ namespace BlackMisc
|
|||||||
|
|
||||||
const CSimulatedAircraftList &CRemoteAircraftAwareReadOnly::remoteAircraft() const
|
const CSimulatedAircraftList &CRemoteAircraftAwareReadOnly::remoteAircraft() const
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraft", "No object available");
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
return this->m_remoteAircraftProvider->remoteAircraft();
|
return this->m_remoteAircraftProvider->remoteAircraft();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Aviation::CAircraftSituationList &CRemoteAircraftAwareReadOnly::remoteAircraftSituations() const
|
Aviation::CAircraftSituationList CRemoteAircraftAwareReadOnly::remoteAircraftSituations(const BlackMisc::Aviation::CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraftSituations", "No object available");
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
return this->m_remoteAircraftProvider->remoteAircraftSituations();
|
return this->m_remoteAircraftProvider->remoteAircraftSituations(callsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Aviation::CAircraftPartsList &CRemoteAircraftAwareReadOnly::remoteAircraftParts() const
|
int CRemoteAircraftAwareReadOnly::remoteAircraftSituationsCount(const CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraftParts", "No object available");
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
return this->m_remoteAircraftProvider->remoteAircraftParts();
|
return this->m_remoteAircraftProvider->remoteAircraftSituationsCount(callsign);
|
||||||
|
}
|
||||||
|
|
||||||
|
CAircraftPartsList CRemoteAircraftAwareReadOnly::remoteAircraftParts(const BlackMisc::Aviation::CCallsign &callsign, qint64 cutoffTimeBefore) const
|
||||||
|
{
|
||||||
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
|
return this->m_remoteAircraftProvider->remoteAircraftParts(callsign, cutoffTimeBefore);
|
||||||
|
}
|
||||||
|
|
||||||
|
CCallsignSet CRemoteAircraftAwareReadOnly::remoteAircraftSupportingParts() const
|
||||||
|
{
|
||||||
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
|
return this->m_remoteAircraftProvider->remoteAircraftSupportingParts();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CRemoteAircraftAwareReadOnly::isRemoteAircraftSupportingParts(const CCallsign &callsign) const
|
||||||
|
{
|
||||||
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
|
return this->m_remoteAircraftProvider->isRemoteAircraftSupportingParts(callsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CSimulatedAircraftList &CRemoteAircraftAware::remoteAircraft() const
|
const CSimulatedAircraftList &CRemoteAircraftAware::remoteAircraft() const
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraft", "No object available");
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
return this->m_remoteAircraftProvider->remoteAircraft();
|
return this->m_remoteAircraftProvider->remoteAircraft();
|
||||||
}
|
}
|
||||||
|
|
||||||
CSimulatedAircraftList &CRemoteAircraftAware::remoteAircraft()
|
CSimulatedAircraftList &CRemoteAircraftAware::remoteAircraft()
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraft", "No object available");
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
return this->m_remoteAircraftProvider->remoteAircraft();
|
return this->m_remoteAircraftProvider->remoteAircraft();
|
||||||
}
|
}
|
||||||
|
|
||||||
const CAircraftSituationList &CRemoteAircraftAware::remoteAircraftSituations() const
|
CAircraftSituationList CRemoteAircraftAware::remoteAircraftSituations(const BlackMisc::Aviation::CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraftSituations", "No object available");
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
return this->m_remoteAircraftProvider->remoteAircraftSituations();
|
return this->m_remoteAircraftProvider->remoteAircraftSituations(callsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftSituationList &CRemoteAircraftAware::remoteAircraftSituations()
|
CAircraftPartsList CRemoteAircraftAware::remoteAircraftParts(const BlackMisc::Aviation::CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraftSituations", "No object available");
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
return this->m_remoteAircraftProvider->remoteAircraftSituations();
|
return this->m_remoteAircraftProvider->remoteAircraftParts(callsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CAircraftPartsList &CRemoteAircraftAware::remoteAircraftParts() const
|
CCallsignSet CRemoteAircraftAware::remoteAircraftSupportingParts() const
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraftParts", "No object available");
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
return this->m_remoteAircraftProvider->remoteAircraftParts();
|
return this->m_remoteAircraftProvider->remoteAircraftSupportingParts();
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftPartsList &CRemoteAircraftAware::remoteAircraftParts()
|
int CRemoteAircraftAware::remoteAircraftSituationsCount(const CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraftParts", "No object available");
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
return this->m_remoteAircraftProvider->remoteAircraftParts();
|
return this->m_remoteAircraftProvider->remoteAircraftSituationsCount(callsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CRemoteAircraftAware::providerUpdateAircraftModel(const Aviation::CCallsign &callsign, const CAircraftModel &model, const QString &originator)
|
bool CRemoteAircraftAware::providerUpdateAircraftModel(const Aviation::CCallsign &callsign, const CAircraftModel &model, const QString &originator)
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "providerUpdateAircraftModel", "No object available");
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
return this->m_remoteAircraftProvider->updateAircraftModel(callsign, model, originator);
|
return this->m_remoteAircraftProvider->updateAircraftModel(callsign, model, originator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CRemoteAircraftAware::isRemoteAircraftSupportingParts(const CCallsign &callsign) const
|
||||||
|
{
|
||||||
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
|
return this->m_remoteAircraftProvider->isRemoteAircraftSupportingParts(callsign);
|
||||||
|
}
|
||||||
|
|
||||||
bool CRemoteAircraftAware::providerUpdateAircraftEnabled(const Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator)
|
bool CRemoteAircraftAware::providerUpdateAircraftEnabled(const Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator)
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "providerUpdateAircraftEnabled", "No object available");
|
Q_ASSERT_X(this->m_remoteAircraftProvider, Q_FUNC_INFO, "No object available");
|
||||||
return this->m_remoteAircraftProvider->updateAircraftEnabled(callsign, enabledForRedering, originator);
|
return this->m_remoteAircraftProvider->updateAircraftEnabled(callsign, enabledForRedering, originator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,14 +28,34 @@ namespace BlackMisc
|
|||||||
class BLACKMISC_EXPORT IRemoteAircraftProviderReadOnly
|
class BLACKMISC_EXPORT IRemoteAircraftProviderReadOnly
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
//! Situations per callsign
|
||||||
|
typedef QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> CSituationsPerCallsign;
|
||||||
|
|
||||||
|
//! Parts per callsign
|
||||||
|
typedef QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftPartsList> CPartsPerCallsign;
|
||||||
|
|
||||||
//! All rendered aircraft
|
//! All rendered aircraft
|
||||||
virtual const CSimulatedAircraftList &remoteAircraft() const = 0;
|
virtual const CSimulatedAircraftList &remoteAircraft() const = 0;
|
||||||
|
|
||||||
//! All situation (per callsign, time history)
|
//! Rendered aircraft situations (per callsign, time history)
|
||||||
virtual const BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() const = 0;
|
//! \threadsafe
|
||||||
|
virtual BlackMisc::Aviation::CAircraftSituationList remoteAircraftSituations(const BlackMisc::Aviation::CCallsign &callsign) const = 0;
|
||||||
|
|
||||||
|
//! Number of remote aircraft situations for callsign
|
||||||
|
//! \threadsafe
|
||||||
|
virtual int remoteAircraftSituationsCount(const BlackMisc::Aviation::CCallsign &callsign) const = 0;
|
||||||
|
|
||||||
//! All parts (per callsign, time history)
|
//! All parts (per callsign, time history)
|
||||||
virtual const BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() const = 0;
|
//! \threadsafe
|
||||||
|
virtual BlackMisc::Aviation::CAircraftPartsList remoteAircraftParts(const BlackMisc::Aviation::CCallsign &callsign, qint64 cutoffTimeBefore = -1) const = 0;
|
||||||
|
|
||||||
|
//! Is remote aircraft supporting parts?
|
||||||
|
//! \threadsafe
|
||||||
|
virtual bool isRemoteAircraftSupportingParts(const BlackMisc::Aviation::CCallsign &callsign) const = 0;
|
||||||
|
|
||||||
|
//! Remote aircraft supporting parts.
|
||||||
|
//! \threadsafe
|
||||||
|
virtual BlackMisc::Aviation::CCallsignSet remoteAircraftSupportingParts() const = 0;
|
||||||
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
virtual ~IRemoteAircraftProviderReadOnly() {}
|
virtual ~IRemoteAircraftProviderReadOnly() {}
|
||||||
@@ -47,11 +67,11 @@ namespace BlackMisc
|
|||||||
std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot
|
std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
|
static const int MaxSituationsPerCallsign = 6; //!< How many situations per callsign
|
||||||
|
static const int MaxPartsPerCallsign = 3; //!< How many parts per callsign
|
||||||
|
|
||||||
// those signals have to be implemented by classes using the interface.
|
// those signals have to be implemented by classes using the interface.
|
||||||
signals:
|
signals:
|
||||||
//! A new situation got added
|
|
||||||
void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
|
|
||||||
|
|
||||||
//! New parts got added
|
//! New parts got added
|
||||||
void addedRemoteAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts);
|
void addedRemoteAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts);
|
||||||
|
|
||||||
@@ -65,21 +85,13 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
//! The read only /sa IRemoteAircraftProviderReadOnly::remoteAircraft
|
||||||
using IRemoteAircraftProviderReadOnly::remoteAircraft;
|
using IRemoteAircraftProviderReadOnly::remoteAircraft;
|
||||||
using IRemoteAircraftProviderReadOnly::remoteAircraftParts;
|
|
||||||
using IRemoteAircraftProviderReadOnly::remoteAircraftSituations;
|
|
||||||
|
|
||||||
//! All rendered aircraft
|
//! All rendered aircraft
|
||||||
//! \note in memory reference, not thread safe
|
//! \note in memory reference, not thread safe
|
||||||
virtual CSimulatedAircraftList &remoteAircraft() = 0;
|
virtual CSimulatedAircraftList &remoteAircraft() = 0;
|
||||||
|
|
||||||
//! Rendered aircraft situations (history)
|
|
||||||
virtual BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() = 0;
|
|
||||||
|
|
||||||
//! All parts (per callsign, time history)
|
|
||||||
//! \note in memory reference, not thread safe
|
|
||||||
virtual BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() = 0;
|
|
||||||
|
|
||||||
//! Enable/disable rendering
|
//! Enable/disable rendering
|
||||||
virtual bool updateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRendering, const QString &originator) = 0;
|
virtual bool updateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRendering, const QString &originator) = 0;
|
||||||
|
|
||||||
@@ -97,11 +109,20 @@ namespace BlackMisc
|
|||||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraft
|
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraft
|
||||||
virtual const CSimulatedAircraftList &remoteAircraft() const;
|
virtual const CSimulatedAircraftList &remoteAircraft() const;
|
||||||
|
|
||||||
//!\copydoc IRemoteAircraftProviderReadOnly::renderedAircraftSituations
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSituations
|
||||||
virtual const BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() const;
|
virtual BlackMisc::Aviation::CAircraftSituationList remoteAircraftSituations(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||||
|
|
||||||
//!\copydoc IRemoteAircraftProviderReadOnly::renderedAircraftParts
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSituationsCount
|
||||||
virtual const BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() const;
|
virtual int remoteAircraftSituationsCount(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||||
|
|
||||||
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftParts
|
||||||
|
virtual BlackMisc::Aviation::CAircraftPartsList remoteAircraftParts(const BlackMisc::Aviation::CCallsign &callsign, qint64 cutoffTimeBefore = -1) const;
|
||||||
|
|
||||||
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSupportingParts
|
||||||
|
virtual BlackMisc::Aviation::CCallsignSet remoteAircraftSupportingParts() const;
|
||||||
|
|
||||||
|
//! \copydoc IRemoteAircraftProviderReadOnly::isRemoteAircraftSupportingParts
|
||||||
|
virtual bool isRemoteAircraftSupportingParts(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||||
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
virtual ~CRemoteAircraftAwareReadOnly() {}
|
virtual ~CRemoteAircraftAwareReadOnly() {}
|
||||||
@@ -116,23 +137,23 @@ namespace BlackMisc
|
|||||||
class BLACKMISC_EXPORT CRemoteAircraftAware
|
class BLACKMISC_EXPORT CRemoteAircraftAware
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraft
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraft
|
||||||
virtual const CSimulatedAircraftList &remoteAircraft() const;
|
virtual const CSimulatedAircraftList &remoteAircraft() const;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProvider::renderedAircraft
|
//! \copydoc IRemoteAircraftProvider::remoteAircraft
|
||||||
virtual CSimulatedAircraftList &remoteAircraft();
|
virtual CSimulatedAircraftList &remoteAircraft();
|
||||||
|
|
||||||
//!\copydoc IRemoteAircraftProviderReadOnly::renderedAircraftSituations
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSituations
|
||||||
virtual const BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() const;
|
virtual BlackMisc::Aviation::CAircraftSituationList remoteAircraftSituations(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||||
|
|
||||||
//!\copydoc IRemoteAircraftProvider::remoteAircraftSituations
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftParts
|
||||||
virtual BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations();
|
virtual BlackMisc::Aviation::CAircraftPartsList remoteAircraftParts(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||||
|
|
||||||
//!\copydoc IRemoteAircraftProviderReadOnly::renderedAircraftParts
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSupportingParts
|
||||||
virtual const BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() const;
|
virtual BlackMisc::Aviation::CCallsignSet remoteAircraftSupportingParts() const;
|
||||||
|
|
||||||
//!\copydoc IRemoteAircraftProvider::remoteAircraftParts
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSituationsCount
|
||||||
virtual BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts();
|
virtual int remoteAircraftSituationsCount(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProvider::updateAircraftEnabled
|
//! \copydoc IRemoteAircraftProvider::updateAircraftEnabled
|
||||||
virtual bool providerUpdateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator);
|
virtual bool providerUpdateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator);
|
||||||
@@ -140,6 +161,9 @@ namespace BlackMisc
|
|||||||
//! \copydoc IRemoteAircraftProvider::updateAircraftModel
|
//! \copydoc IRemoteAircraftProvider::updateAircraftModel
|
||||||
virtual bool providerUpdateAircraftModel(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Simulation::CAircraftModel &model, const QString &originator);
|
virtual bool providerUpdateAircraftModel(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Simulation::CAircraftModel &model, const QString &originator);
|
||||||
|
|
||||||
|
//! \copydoc IRemoteAircraftProviderReadOnly::isRemoteAircraftSupportingParts
|
||||||
|
virtual bool isRemoteAircraftSupportingParts(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||||
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
virtual ~CRemoteAircraftAware() {}
|
virtual ~CRemoteAircraftAware() {}
|
||||||
|
|
||||||
|
|||||||
@@ -29,24 +29,30 @@ namespace BlackMisc
|
|||||||
return m_aircraft;
|
return m_aircraft;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CAircraftPartsList &CRemoteAircraftProviderDummy::remoteAircraftParts() const
|
CAircraftPartsList CRemoteAircraftProviderDummy::remoteAircraftParts(const BlackMisc::Aviation::CCallsign &callsign, qint64 cutoffTimeBefore) const
|
||||||
{
|
{
|
||||||
return m_parts;
|
if (cutoffTimeBefore < 0) { return m_parts.findByCallsign(callsign); }
|
||||||
|
return m_parts.findByCallsign(callsign).findBefore(cutoffTimeBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftPartsList &CRemoteAircraftProviderDummy::remoteAircraftParts()
|
CAircraftSituationList CRemoteAircraftProviderDummy::remoteAircraftSituations(const BlackMisc::Aviation::CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
return m_parts;
|
return m_situations.findByCallsign(callsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CAircraftSituationList &CRemoteAircraftProviderDummy::remoteAircraftSituations() const
|
int CRemoteAircraftProviderDummy::remoteAircraftSituationsCount(const CCallsign &callsign) const
|
||||||
{
|
{
|
||||||
return m_situations;
|
return remoteAircraftSituations(callsign).size();
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftSituationList &CRemoteAircraftProviderDummy::remoteAircraftSituations()
|
CCallsignSet CRemoteAircraftProviderDummy::remoteAircraftSupportingParts() const
|
||||||
{
|
{
|
||||||
return m_situations;
|
return m_parts.getCallsigns();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CRemoteAircraftProviderDummy::isRemoteAircraftSupportingParts(const CCallsign &callsign) const
|
||||||
|
{
|
||||||
|
return remoteAircraftParts(callsign).size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CRemoteAircraftProviderDummy::connectRemoteAircraftProviderSignals(std::function<void (const CAircraftSituation &)> situationSlot, std::function<void (const CAircraftParts &)> partsSlot, std::function<void (const CCallsign &)> removedAircraftSlot)
|
bool CRemoteAircraftProviderDummy::connectRemoteAircraftProviderSignals(std::function<void (const CAircraftSituation &)> situationSlot, std::function<void (const CAircraftParts &)> partsSlot, std::function<void (const CCallsign &)> removedAircraftSlot)
|
||||||
@@ -83,14 +89,14 @@ namespace BlackMisc
|
|||||||
|
|
||||||
void CRemoteAircraftProviderDummy::insertNewSituation(const CAircraftSituation &situation)
|
void CRemoteAircraftProviderDummy::insertNewSituation(const CAircraftSituation &situation)
|
||||||
{
|
{
|
||||||
this->m_situations.push_frontMaxElements(situation, 20);
|
this->m_situations.push_front(situation);
|
||||||
this->m_situations.sortLatestFirst(); // like in real world, latest should be first
|
this->m_situations.sortLatestFirst(); // like in real world, latest should be first
|
||||||
emit addedRemoteAircraftSituation(situation);
|
emit addedRemoteAircraftSituation(situation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRemoteAircraftProviderDummy::insertNewAircraftParts(const CAircraftParts &parts)
|
void CRemoteAircraftProviderDummy::insertNewAircraftParts(const CAircraftParts &parts)
|
||||||
{
|
{
|
||||||
this->m_parts.push_frontMaxElements(parts, 20);
|
this->m_parts.push_front(parts);
|
||||||
this->m_parts.sortLatestFirst(); // like in real world, latest should be first
|
this->m_parts.sortLatestFirst(); // like in real world, latest should be first
|
||||||
emit addedRemoteAircraftParts(parts);
|
emit addedRemoteAircraftParts(parts);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,16 +39,19 @@ namespace BlackMisc
|
|||||||
virtual CSimulatedAircraftList &remoteAircraft() override;
|
virtual CSimulatedAircraftList &remoteAircraft() override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftParts
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftParts
|
||||||
virtual const BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() const override;
|
virtual BlackMisc::Aviation::CAircraftPartsList remoteAircraftParts(const Aviation::CCallsign &callsign, qint64 cutoffTimeBefore = -1) const override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProvider::remoteAircraftParts
|
|
||||||
virtual BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() override;
|
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSituations
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSituations
|
||||||
virtual const BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() const override;
|
virtual BlackMisc::Aviation::CAircraftSituationList remoteAircraftSituations(const Aviation::CCallsign &callsign) const override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProvider::remoteAircraftSituations
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSituationsCount
|
||||||
virtual BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() override;
|
virtual int remoteAircraftSituationsCount(const Aviation::CCallsign &callsign) const override;
|
||||||
|
|
||||||
|
//! \copydoc IRemoteAircraftProviderReadOnly::remoteAircraftSupportingParts
|
||||||
|
virtual BlackMisc::Aviation::CCallsignSet remoteAircraftSupportingParts() const override;
|
||||||
|
|
||||||
|
//! \copydoc IRemoteAircraftProviderReadOnly::isRemoteAircraftSupportingParts
|
||||||
|
virtual bool isRemoteAircraftSupportingParts(const Aviation::CCallsign &callsign) const override;
|
||||||
|
|
||||||
//! \copydoc IRemoteAircraftProviderReadOnly::connectRemoteAircraftProviderSignals
|
//! \copydoc IRemoteAircraftProviderReadOnly::connectRemoteAircraftProviderSignals
|
||||||
virtual bool connectRemoteAircraftProviderSignals(
|
virtual bool connectRemoteAircraftProviderSignals(
|
||||||
|
|||||||
@@ -76,13 +76,13 @@ namespace BlackSimPlugin
|
|||||||
void CFs9Client::timerEvent(QTimerEvent *event)
|
void CFs9Client::timerEvent(QTimerEvent *event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event);
|
Q_UNUSED(event);
|
||||||
Q_ASSERT(m_interpolator);
|
Q_ASSERT_X(m_interpolator, Q_FUNC_INFO, "Missing interpolator");
|
||||||
|
|
||||||
if (m_clientStatus == Disconnected) { return; }
|
if (m_clientStatus == Disconnected) { return; }
|
||||||
|
|
||||||
|
|
||||||
IInterpolator::InterpolationStatus status;
|
IInterpolator::InterpolationStatus status;
|
||||||
CAircraftSituation situation = this->m_interpolator->getInterpolatedSituation(m_callsign, -1, status);
|
bool vtolAircraft(false);
|
||||||
|
CAircraftSituation situation = this->m_interpolator->getInterpolatedSituation(m_callsign, -1, vtolAircraft, status);
|
||||||
|
|
||||||
// Test only for successful interpolation. FS9 requires constant positions
|
// Test only for successful interpolation. FS9 requires constant positions
|
||||||
if (!status.interpolationSucceeded) { return; }
|
if (!status.interpolationSucceeded) { return; }
|
||||||
|
|||||||
@@ -151,8 +151,8 @@ namespace BlackSimPlugin
|
|||||||
CLogMessage(this).warning("Have to remove aircraft %1 before I can add it") << callsign;
|
CLogMessage(this).warning("Have to remove aircraft %1 before I can add it") << callsign;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSimulatedAircraft newRemoteAircraftCopy(newRemoteAircraft);
|
CSimulatedAircraft newRemoteAircraftCopy(newRemoteAircraft); // copy which can be modified
|
||||||
this->setInitialAircraftSituationAndParts(newRemoteAircraftCopy);
|
this->setInitialAircraftSituationAndParts(newRemoteAircraftCopy); // set interpolated data/parts if available
|
||||||
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(newRemoteAircraftCopy.getSituation());
|
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(newRemoteAircraftCopy.getSituation());
|
||||||
|
|
||||||
CSimConnectObject simObj;
|
CSimConnectObject simObj;
|
||||||
@@ -611,7 +611,7 @@ namespace BlackSimPlugin
|
|||||||
{
|
{
|
||||||
static_assert(sizeof(DataDefinitionRemoteAircraftParts) == 120, "DataDefinitionRemoteAircraftParts has an incorrect size.");
|
static_assert(sizeof(DataDefinitionRemoteAircraftParts) == 120, "DataDefinitionRemoteAircraftParts has an incorrect size.");
|
||||||
Q_ASSERT(this->m_interpolator);
|
Q_ASSERT(this->m_interpolator);
|
||||||
Q_ASSERT_X(this->m_interpolator->thread() != this->thread(), "updateOtherAircraft", "interpolator should run in its own thread");
|
Q_ASSERT_X(this->m_interpolator->thread() != this->thread(), Q_FUNC_INFO, "interpolator should run in its own thread");
|
||||||
|
|
||||||
// nothing to do, reset request id and exit
|
// nothing to do, reset request id and exit
|
||||||
if (this->isPaused()) { return; } // no interpolation while paused
|
if (this->isPaused()) { return; } // no interpolation while paused
|
||||||
@@ -623,19 +623,29 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
// values used for position and parts
|
// values used for position and parts
|
||||||
bool isOnGround = false;
|
bool isOnGround = false;
|
||||||
|
bool isVtolAircraft = false; //! \todo determine VTOL aircraft in interpolator
|
||||||
|
|
||||||
qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch();
|
qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch();
|
||||||
|
CCallsignSet aircraftWithParts(this->remoteAircraftSupportingParts()); // optimization, fetch all parts supporting aircraft in one step (one lock)
|
||||||
|
|
||||||
for (const CSimConnectObject &simObj : m_simConnectObjects)
|
for (const CSimConnectObject &simObj : m_simConnectObjects)
|
||||||
{
|
{
|
||||||
|
if (simObj.getObjectId() < 1) { continue; }
|
||||||
|
|
||||||
const CCallsign callsign(simObj.getCallsign());
|
const CCallsign callsign(simObj.getCallsign());
|
||||||
|
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "missing callsign");
|
||||||
IInterpolator::InterpolationStatus interpolatorStatus;
|
IInterpolator::InterpolationStatus interpolatorStatus;
|
||||||
if (simObj.getObjectId() == 0) { continue; }
|
CAircraftSituation interpolatedSituation = this->m_interpolator->getInterpolatedSituation(callsign, currentTimestamp, isVtolAircraft, interpolatorStatus);
|
||||||
CAircraftSituation interpolatedSituation = this->m_interpolator->getInterpolatedSituation(callsign, currentTimestamp, interpolatorStatus);
|
|
||||||
|
|
||||||
// having the onGround flag in parts forces me to obtain parts here
|
// having the onGround flag in parts forces me to obtain parts here
|
||||||
// which is not the smartest thing regarding performance
|
// which is not the smartest thing regarding performance
|
||||||
IInterpolator::PartsStatus partsStatus;
|
IInterpolator::PartsStatus partsStatus;
|
||||||
CAircraftPartsList parts = this->m_interpolator->getAndRemovePartsBeforeTime(callsign, currentTimestamp - IInterpolator::TimeOffsetMs, partsStatus);
|
partsStatus.supportsParts = aircraftWithParts.contains(callsign);
|
||||||
|
CAircraftPartsList parts;
|
||||||
|
if (partsStatus.supportsParts)
|
||||||
|
{
|
||||||
|
this->m_interpolator->getPartsBeforeTime(callsign, currentTimestamp - IInterpolator::TimeOffsetMs, partsStatus);
|
||||||
|
}
|
||||||
|
|
||||||
if (interpolatorStatus.allTrue())
|
if (interpolatorStatus.allTrue())
|
||||||
{
|
{
|
||||||
@@ -643,6 +653,7 @@ namespace BlackSimPlugin
|
|||||||
SIMCONNECT_DATA_INITPOSITION position = aircraftSituationToFsxInitPosition(interpolatedSituation);
|
SIMCONNECT_DATA_INITPOSITION position = aircraftSituationToFsxInitPosition(interpolatedSituation);
|
||||||
|
|
||||||
//! \todo The onGround in parts is nuts, as already mentioned in the discussion
|
//! \todo The onGround in parts is nuts, as already mentioned in the discussion
|
||||||
|
// Currently ignored here, only guessing which is faster as aircraft without parts can just be
|
||||||
// a) I am forced to read parts even if i just want to update position
|
// a) I am forced to read parts even if i just want to update position
|
||||||
// b) Unlike the other values it is not a fire and forget value, as I need it again in the next cycle
|
// b) Unlike the other values it is not a fire and forget value, as I need it again in the next cycle
|
||||||
if (partsStatus.supportsParts && !parts.isEmpty())
|
if (partsStatus.supportsParts && !parts.isEmpty())
|
||||||
@@ -662,8 +673,6 @@ namespace BlackSimPlugin
|
|||||||
sizeof(SIMCONNECT_DATA_INITPOSITION), &position);
|
sizeof(SIMCONNECT_DATA_INITPOSITION), &position);
|
||||||
if (hr != S_OK) { CLogMessage(this).warning("Failed so set position on SimObject %1 callsign: %2") << simObj.getObjectId() << callsign; }
|
if (hr != S_OK) { CLogMessage(this).warning("Failed so set position on SimObject %1 callsign: %2") << simObj.getObjectId() << callsign; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // interpolation data
|
} // interpolation data
|
||||||
|
|
||||||
if (interpolatorStatus.interpolationSucceeded)
|
if (interpolatorStatus.interpolationSucceeded)
|
||||||
|
|||||||
@@ -47,10 +47,13 @@ namespace BlackSimPlugin
|
|||||||
m_watcher = new QDBusServiceWatcher(this);
|
m_watcher = new QDBusServiceWatcher(this);
|
||||||
m_watcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
|
m_watcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
|
||||||
m_watcher->addWatchedService(xbusServiceName());
|
m_watcher->addWatchedService(xbusServiceName());
|
||||||
|
m_watcher->setObjectName("QDBusServiceWatcher");
|
||||||
connect(m_watcher, &QDBusServiceWatcher::serviceUnregistered, this, &CSimulatorXPlane::ps_serviceUnregistered);
|
connect(m_watcher, &QDBusServiceWatcher::serviceUnregistered, this, &CSimulatorXPlane::ps_serviceUnregistered);
|
||||||
|
|
||||||
m_fastTimer = new QTimer(this);
|
m_fastTimer = new QTimer(this);
|
||||||
m_slowTimer = new QTimer(this);
|
m_slowTimer = new QTimer(this);
|
||||||
|
m_fastTimer->setObjectName(this->objectName().append(":m_fastTimer"));
|
||||||
|
m_slowTimer->setObjectName(this->objectName().append(":m_slowTimer"));
|
||||||
connect(m_fastTimer, &QTimer::timeout, this, &CSimulatorXPlane::ps_fastTimerTimeout);
|
connect(m_fastTimer, &QTimer::timeout, this, &CSimulatorXPlane::ps_fastTimerTimeout);
|
||||||
connect(m_slowTimer, &QTimer::timeout, this, &CSimulatorXPlane::ps_slowTimerTimeout);
|
connect(m_slowTimer, &QTimer::timeout, this, &CSimulatorXPlane::ps_slowTimerTimeout);
|
||||||
m_fastTimer->start(100);
|
m_fastTimer->start(100);
|
||||||
|
|||||||
@@ -25,13 +25,12 @@ namespace BlackCoreTest
|
|||||||
{
|
{
|
||||||
QScopedPointer<CRemoteAircraftProviderDummy> provider(new CRemoteAircraftProviderDummy());
|
QScopedPointer<CRemoteAircraftProviderDummy> provider(new CRemoteAircraftProviderDummy());
|
||||||
CInterpolatorLinear interpolator(provider.data());
|
CInterpolatorLinear interpolator(provider.data());
|
||||||
interpolator.forceSortingOfAddedValues(true);
|
|
||||||
|
|
||||||
// fixed time so everything can be debugged
|
// fixed time so everything can be debugged
|
||||||
const qint64 ts = 1425000000000; // QDateTime::currentMSecsSinceEpoch();
|
const qint64 ts = 1425000000000; // QDateTime::currentMSecsSinceEpoch();
|
||||||
const qint64 deltaT = 5000; // ms
|
const qint64 deltaT = 5000; // ms
|
||||||
CCallsign cs("SWIFT");
|
CCallsign cs("SWIFT");
|
||||||
for (int i = 0; i < IInterpolator::MaxSituationsPerCallsign; i++)
|
for (int i = 0; i < IRemoteAircraftProviderReadOnly::MaxSituationsPerCallsign; i++)
|
||||||
{
|
{
|
||||||
CAircraftSituation s(getTestSituation(cs, i, ts, deltaT));
|
CAircraftSituation s(getTestSituation(cs, i, ts, deltaT));
|
||||||
|
|
||||||
@@ -41,30 +40,30 @@ namespace BlackCoreTest
|
|||||||
provider->insertNewSituation(s);
|
provider->insertNewSituation(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < IInterpolator::MaxPartsPerCallsign; i++)
|
for (int i = 0; i < IRemoteAircraftProviderReadOnly::MaxPartsPerCallsign; i++)
|
||||||
{
|
{
|
||||||
CAircraftParts p(getTestParts(cs, i, ts, deltaT));
|
CAircraftParts p(getTestParts(cs, i, ts, deltaT));
|
||||||
provider->insertNewAircraftParts(p);
|
provider->insertNewAircraftParts(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure signals are processed
|
// make sure signals are processed, if the interpolator depends on those signals
|
||||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
|
QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
|
||||||
|
|
||||||
// check if all situations / parts have been received
|
// check if all situations / parts have been received
|
||||||
QVERIFY2(interpolator.getSituationsForCallsign(cs).size() == IInterpolator::MaxSituationsPerCallsign, "Missing situations");
|
QVERIFY2(provider->remoteAircraftSituations(cs).size() == IRemoteAircraftProviderReadOnly::MaxSituationsPerCallsign, "Missing situations");
|
||||||
QVERIFY2(interpolator.getPartsForCallsign(cs).size() == IInterpolator::MaxPartsPerCallsign, "Missing parts");
|
QVERIFY2(provider->remoteAircraftParts(cs).size() == IRemoteAircraftProviderReadOnly::MaxPartsPerCallsign, "Missing parts");
|
||||||
|
|
||||||
// interpolation
|
// interpolation functional check
|
||||||
IInterpolator::InterpolationStatus status;
|
IInterpolator::InterpolationStatus status;
|
||||||
double latOld = 360.0;
|
double latOld = 360.0;
|
||||||
double lngOld = 360.0;
|
double lngOld = 360.0;
|
||||||
for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += 250)
|
for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += (deltaT / 20))
|
||||||
{
|
{
|
||||||
// This will use time range
|
// This will use time range
|
||||||
// from: ts - 2* deltaT - IInterpolator::TimeOffsetMs
|
// from: ts - 2* deltaT - IInterpolator::TimeOffsetMs
|
||||||
// to: ts - IInterpolator::TimeOffsetMs
|
// to: ts - IInterpolator::TimeOffsetMs
|
||||||
CAircraftSituation currentSituation(interpolator.getInterpolatedSituation
|
CAircraftSituation currentSituation(interpolator.getInterpolatedSituation
|
||||||
(cs, currentTime, status)
|
(cs, currentTime, false, status)
|
||||||
);
|
);
|
||||||
QVERIFY2(status.interpolationSucceeded, "Interpolation was not succesful");
|
QVERIFY2(status.interpolationSucceeded, "Interpolation was not succesful");
|
||||||
QVERIFY2(status.changedPosition, "Interpolation did not changed");
|
QVERIFY2(status.changedPosition, "Interpolation did not changed");
|
||||||
@@ -80,15 +79,21 @@ namespace BlackCoreTest
|
|||||||
int interpolationNo = 0;
|
int interpolationNo = 0;
|
||||||
qint64 startTimeMsSinceEpoch = ts - 2 * deltaT;
|
qint64 startTimeMsSinceEpoch = ts - 2 * deltaT;
|
||||||
|
|
||||||
for (int callsigns = 0; callsigns < 20; callsigns++)
|
|
||||||
|
// Pseudo performance test:
|
||||||
|
// Those make not completely sense, as the performance depends on the implementation of
|
||||||
|
// the dummy provider, which is different from the real provider
|
||||||
|
// With one callsign in the lists (of dummy provider) it is somehow expected to be roughly the same performance
|
||||||
|
|
||||||
|
for (int loops = 0; loops < 20; loops++)
|
||||||
{
|
{
|
||||||
for (qint64 currentTime = startTimeMsSinceEpoch; currentTime < ts; currentTime += 250)
|
for (qint64 currentTime = startTimeMsSinceEpoch; currentTime < ts; currentTime += (deltaT / 20))
|
||||||
{
|
{
|
||||||
// This will use range
|
// This will use range
|
||||||
// from: ts - 2* deltaT - IInterpolator::TimeOffsetMs
|
// from: ts - 2* deltaT - IInterpolator::TimeOffsetMs
|
||||||
// to: ts - IInterpolator::TimeOffsetMs
|
// to: ts - IInterpolator::TimeOffsetMs
|
||||||
CAircraftSituation currentSituation(interpolator.getInterpolatedSituation
|
CAircraftSituation currentSituation(interpolator.getInterpolatedSituation
|
||||||
(cs, currentTime, status)
|
(cs, currentTime, false, status)
|
||||||
);
|
);
|
||||||
QVERIFY2(status.allTrue(), "Failed interpolation");
|
QVERIFY2(status.allTrue(), "Failed interpolation");
|
||||||
QVERIFY2(currentSituation.getCallsign() == cs, "Wrong callsign");
|
QVERIFY2(currentSituation.getCallsign() == cs, "Wrong callsign");
|
||||||
@@ -101,105 +106,20 @@ namespace BlackCoreTest
|
|||||||
}
|
}
|
||||||
int timeMs = timer.elapsed();
|
int timeMs = timer.elapsed();
|
||||||
QVERIFY2(timeMs < interpolationNo, "Interpolation > 1ms");
|
QVERIFY2(timeMs < interpolationNo, "Interpolation > 1ms");
|
||||||
qDebug() << timeMs << "ms" << "for" << interpolationNo;
|
qDebug() << timeMs << "ms" << "for" << interpolationNo << "interpolations";
|
||||||
|
|
||||||
CAircraftSituationList interpolations(interpolator.getInterpolatedSituations(startTimeMsSinceEpoch));
|
|
||||||
QVERIFY(interpolations.size() == 1);
|
|
||||||
QVERIFY(interpolations.containsCallsign(cs));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Single interpolation vs. all interpolations at once
|
|
||||||
//
|
|
||||||
|
|
||||||
// Create data in provider
|
|
||||||
provider->clear();
|
|
||||||
interpolator.clear();
|
|
||||||
QVERIFY(interpolator.getSituationsByCallsign().size() == 0);
|
|
||||||
const int callsignsInProvider = 20;
|
|
||||||
for (int callsignNo = 0; callsignNo < callsignsInProvider; callsignNo++)
|
|
||||||
{
|
|
||||||
cs = CCallsign("SWIFT" + QString::number(callsignNo));
|
|
||||||
int i = 0;
|
|
||||||
for (int t = 0; t < IInterpolator::MaxSituationsPerCallsign; t++)
|
|
||||||
{
|
|
||||||
qint64 currentTime = ts - t * deltaT;
|
|
||||||
CAircraftSituation s(getTestSituation(cs, i, currentTime, 0));
|
|
||||||
provider->insertNewSituation(s);
|
|
||||||
|
|
||||||
CAircraftParts p(getTestParts(cs, i, currentTime, 0));
|
|
||||||
provider->insertNewAircraftParts(p);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<CCallsign> csKeys = interpolator.getSituationsByCallsign().keys();
|
|
||||||
CCallsignSet callsigns(csKeys);
|
|
||||||
QVERIFY(callsigns.size() == callsignsInProvider);
|
|
||||||
QVERIFY(interpolator.getSituationsForCallsign("SWIFT0").size() == IInterpolator::MaxSituationsPerCallsign);
|
|
||||||
QVERIFY(interpolator.getPartsForCallsign("SWIFT0").size() == IInterpolator::MaxPartsPerCallsign);
|
|
||||||
|
|
||||||
// interpolation for time, then for each callsign
|
|
||||||
int doneInterpolations = 0;
|
|
||||||
timer.start();
|
|
||||||
for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += 250)
|
|
||||||
{
|
|
||||||
// This will use range
|
|
||||||
// from: ts - 2* deltaT - IInterpolator::TimeOffsetMs
|
|
||||||
// to: ts - IInterpolator::TimeOffsetMs
|
|
||||||
|
|
||||||
for (const CCallsign &cs : callsigns)
|
|
||||||
{
|
|
||||||
CAircraftSituation currentSituation(interpolator.getInterpolatedSituation
|
|
||||||
(cs, currentTime, status)
|
|
||||||
);
|
|
||||||
QVERIFY2(status.interpolationSucceeded, "Interpolation was not succesful");
|
|
||||||
QVERIFY2(status.changedPosition, "Interpolation did not changed");
|
|
||||||
double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5);
|
|
||||||
double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5);
|
|
||||||
Q_UNUSED(latDeg);
|
|
||||||
Q_UNUSED(lngDeg);
|
|
||||||
doneInterpolations++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
timeMs = timer.elapsed();
|
|
||||||
qDebug() << "Per callsign" << doneInterpolations << "interpolations in" << timeMs << "ms";
|
|
||||||
|
|
||||||
doneInterpolations = 0;
|
|
||||||
timer.start();
|
|
||||||
for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += 250)
|
|
||||||
{
|
|
||||||
// This will use range
|
|
||||||
// from: ts - 2* deltaT - IInterpolator::TimeOffsetMs
|
|
||||||
// to: ts - IInterpolator::TimeOffsetMs
|
|
||||||
|
|
||||||
CAircraftSituationList currentSituations(interpolator.getInterpolatedSituations(currentTime));
|
|
||||||
QVERIFY2(currentSituations.size() == callsignsInProvider, "Interpolation was not succesful");
|
|
||||||
for (const CAircraftSituation ¤tSituation : currentSituations)
|
|
||||||
{
|
|
||||||
double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5);
|
|
||||||
double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5);
|
|
||||||
doneInterpolations++;
|
|
||||||
Q_UNUSED(latDeg);
|
|
||||||
Q_UNUSED(lngDeg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
timeMs = timer.elapsed();
|
|
||||||
qDebug() << "All callsigns" << doneInterpolations << "interpolations in" << timeMs << "ms";
|
|
||||||
|
|
||||||
int fetchedParts = 0;
|
int fetchedParts = 0;
|
||||||
timer.start();
|
timer.start();
|
||||||
for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += 250)
|
for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += 250)
|
||||||
{
|
|
||||||
for (const CCallsign &callsign : callsigns)
|
|
||||||
{
|
{
|
||||||
IInterpolator::PartsStatus status;
|
IInterpolator::PartsStatus status;
|
||||||
CAircraftPartsList pl = interpolator.getAndRemovePartsBeforeTime(callsign, ts, status);
|
CAircraftPartsList pl(interpolator.getPartsBeforeTime(cs, ts, status));
|
||||||
fetchedParts++;
|
fetchedParts++;
|
||||||
Q_UNUSED(pl);
|
QVERIFY2(status.supportsParts, "Parts not supported");
|
||||||
}
|
QVERIFY2(!pl.isEmpty(), "Parts empty");
|
||||||
}
|
}
|
||||||
timeMs = timer.elapsed();
|
timeMs = timer.elapsed();
|
||||||
qDebug() << "Per callsign" << fetchedParts << "fetched parts in" << timeMs << "ms";
|
qDebug() << timeMs << "ms" << "for" << fetchedParts << "fetched parts";
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftSituation CTestInterpolator::getTestSituation(const CCallsign &callsign, int number, qint64 ts, qint64 deltaT)
|
CAircraftSituation CTestInterpolator::getTestSituation(const CCallsign &callsign, int number, qint64 ts, qint64 deltaT)
|
||||||
|
|||||||
Reference in New Issue
Block a user