From 1c3bb8d463da56c32f73a7c396605b300943fbd4 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Wed, 6 May 2015 02:45:17 +0200 Subject: [PATCH] refs #395, prepared for snapshot handling * logical / physical add/remote member functions in drivers, renamed functions * added access to snapshot * snapshot generation in analyzer * snapshot handling in driver * moved simulator base class in own files (.h/.cpp) * added functions as required to context --- src/blackcore/airspace_analyzer.cpp | 25 +++- src/blackcore/airspace_analyzer.h | 10 +- src/blackcore/airspace_monitor.h | 3 + src/blackcore/context_network_impl.cpp | 7 ++ src/blackcore/context_network_impl.h | 5 + src/blackcore/context_simulator.h | 25 ++-- src/blackcore/context_simulator_impl.cpp | 72 +++++------ src/blackcore/context_simulator_impl.h | 3 + src/blackcore/context_simulator_proxy.cpp | 13 +- src/blackcore/context_simulator_proxy.h | 3 + src/blackcore/simulator.h | 16 ++- src/blackcore/simulator_common.cpp | 116 +++++++++--------- src/blackcore/simulator_common.h | 11 +- .../simulation/airspaceaircraftsnapshot.cpp | 75 +++++++++-- .../simulation/airspaceaircraftsnapshot.h | 26 +++- src/plugins/simulator/fs9/simulator_fs9.cpp | 1 - .../simulator/fsx/simconnect_object.cpp | 5 + src/plugins/simulator/fsx/simconnect_object.h | 11 +- src/plugins/simulator/fsx/simulator_fsx.cpp | 27 ++-- 19 files changed, 314 insertions(+), 140 deletions(-) diff --git a/src/blackcore/airspace_analyzer.cpp b/src/blackcore/airspace_analyzer.cpp index 687dec991..3815e4e56 100644 --- a/src/blackcore/airspace_analyzer.cpp +++ b/src/blackcore/airspace_analyzer.cpp @@ -63,6 +63,15 @@ namespace BlackCore return m_latestAircraftSnapshot; } + void CAirspaceAnalyzer::setSimulatorRenderRestrictionsChanged(bool restricted, int maxAircraft, const CLength &maxRenderedDistance, const CLength &maxRenderedBoundary) + { + QWriteLocker l(&m_lockRestrictions); + this->m_simulatorRenderedAircraftRestricted = restricted; + this->m_simulatorMaxRenderedAircraft = maxAircraft; + this->m_simulatorMaxRenderedDistance = maxRenderedDistance; + this->m_simulatorMaxRenderedBoundary = maxRenderedBoundary; + } + void CAirspaceAnalyzer::ps_watchdogTouchAircraftCallsign(const CAircraftSituation &situation, const CTransponder &transponder) { Q_ASSERT_X(!situation.getCallsign().isEmpty(), Q_FUNC_INFO, "No callsign in situaton"); @@ -150,16 +159,28 @@ namespace BlackCore void CAirspaceAnalyzer::analyzeAirspace() { + bool restricted; + int maxAircraft; + CLength maxRenderedDistance, maxRenderedBoundary; + { + QReadLocker l(&m_lockRestrictions); + restricted = this->m_simulatorRenderedAircraftRestricted; + maxAircraft = this->m_simulatorMaxRenderedAircraft; + maxRenderedDistance = this->m_simulatorMaxRenderedDistance; + maxRenderedBoundary = this->m_simulatorMaxRenderedBoundary; + } + CAirspaceAircraftSnapshot snapshot( - getAircraftInRange() // thread safe copy + getAircraftInRange(), // thread safe copy + restricted, maxAircraft, maxRenderedDistance, maxRenderedBoundary ); // lock block { QWriteLocker l(&m_lockSnapshot); + snapshot.setRestrictionChanged(m_latestAircraftSnapshot); m_latestAircraftSnapshot = snapshot; } - emit airspaceAircraftSnapshot(snapshot); } diff --git a/src/blackcore/airspace_analyzer.h b/src/blackcore/airspace_analyzer.h index a1cd3c6a9..41a37559f 100644 --- a/src/blackcore/airspace_analyzer.h +++ b/src/blackcore/airspace_analyzer.h @@ -51,6 +51,9 @@ namespace BlackCore //! \threadsafe BlackMisc::Simulation::CAirspaceAircraftSnapshot getLatestAirspaceAircraftSnapshot() const; + //! Render restrictions in simulator + void setSimulatorRenderRestrictionsChanged(bool restricted, int maxAircraft, const BlackMisc::PhysicalQuantities::CLength &maxRenderedDistance, const BlackMisc::PhysicalQuantities::CLength &maxRenderedBoundary); + public slots: //! Clear void clear(); @@ -103,7 +106,12 @@ namespace BlackCore // snapshot BlackMisc::Simulation::CAirspaceAircraftSnapshot m_latestAircraftSnapshot; - mutable QReadWriteLock m_lockSnapshot; //!< lock snapshot + bool m_simulatorRenderedAircraftRestricted = false; + int m_simulatorMaxRenderedAircraft = -1; + BlackMisc::PhysicalQuantities::CLength m_simulatorMaxRenderedDistance { 0.0, BlackMisc::PhysicalQuantities::CLengthUnit::nullUnit() }; + BlackMisc::PhysicalQuantities::CLength m_simulatorMaxRenderedBoundary { 0.0, BlackMisc::PhysicalQuantities::CLengthUnit::nullUnit() }; + mutable QReadWriteLock m_lockSnapshot; //!< lock snapshot + mutable QReadWriteLock m_lockRestrictions; //!< lock simulator restrictions }; } // namespace diff --git a/src/blackcore/airspace_monitor.h b/src/blackcore/airspace_monitor.h index f67a8f9ed..9cb1d94f5 100644 --- a/src/blackcore/airspace_monitor.h +++ b/src/blackcore/airspace_monitor.h @@ -160,6 +160,9 @@ namespace BlackCore //! Enable interim position sending void enableFastPositionSending(bool enable); + //! Analyzer + CAirspaceAnalyzer *analyzer() const { return m_analyzer; } + static const qint64 AircraftSituationsRemovedOffsetMs = 30 * 1000; //!< situations older than now - offset will be removed static const qint64 AircraftPartsRemoveOffsetMs = 30 * 1000; //!< parts older than now - offset will be removed diff --git a/src/blackcore/context_network_impl.cpp b/src/blackcore/context_network_impl.cpp index 142d28856..cf38214f8 100644 --- a/src/blackcore/context_network_impl.cpp +++ b/src/blackcore/context_network_impl.cpp @@ -436,6 +436,13 @@ namespace BlackCore emit this->connectionStatusChanged(from, to); } + void CContextNetwork::ps_simulatorRenderRestrictionsChanged(bool restricted, int maxAircraft, const CLength &maxRenderedDistance, const CLength &maxRenderedBoundary) + { + if (!m_airspace) { return; } + if (!m_airspace->analyzer()) { return; } + m_airspace->analyzer()->setSimulatorRenderRestrictionsChanged(restricted, maxAircraft, maxRenderedDistance, maxRenderedBoundary); + } + void CContextNetwork::ps_dataFileRead() { if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } diff --git a/src/blackcore/context_network_impl.h b/src/blackcore/context_network_impl.h index 6d518b111..66523e1d0 100644 --- a/src/blackcore/context_network_impl.h +++ b/src/blackcore/context_network_impl.h @@ -269,6 +269,11 @@ namespace BlackCore //! Connection status changed void ps_fsdConnectionStatusChanged(INetwork::ConnectionStatus from, INetwork::ConnectionStatus to); + + //! Render restrictions have been changed, used with analyzer + //! \sa CAirspaceAnalyzer + void ps_simulatorRenderRestrictionsChanged(bool restricted, int maxAircraft, const BlackMisc::PhysicalQuantities::CLength &maxRenderedDistance, const BlackMisc::PhysicalQuantities::CLength &maxRenderedBoundary); + }; } diff --git a/src/blackcore/context_simulator.h b/src/blackcore/context_simulator.h index c9fe9b141..371b25e11 100644 --- a/src/blackcore/context_simulator.h +++ b/src/blackcore/context_simulator.h @@ -71,17 +71,23 @@ namespace BlackCore //! \sa ISimulator::SimulatorStatus void simulatorStatusChanged(int status); - //! Only a limited number of aircraft displayed - void restrictedRenderingChanged(bool restricted); + //! Simulator plugin loaded / unloaded (default info) + void simulatorPluginChanged(const BlackMisc::Simulation::CSimulatorPluginInfo &info); + + //! Render restrictions have been changed + void renderRestrictionsChanged(bool restricted, int maxAircraft, const BlackMisc::PhysicalQuantities::CLength &maxRenderedDistance, const BlackMisc::PhysicalQuantities::CLength &maxRenderedBoundary); //! Installed aircraft models ready or changed void installedAircraftModelsChanged(); //! A single model has been matched for given aircraft - void modelMatchingCompleted(BlackMisc::Simulation::CSimulatedAircraft aircraft); + void modelMatchingCompleted(const BlackMisc::Simulation::CSimulatedAircraft &aircraft); //! Emitted when own aircraft model changes - void ownAircraftModelChanged(BlackMisc::Simulation::CSimulatedAircraft aircraft); + void ownAircraftModelChanged(const BlackMisc::Simulation::CSimulatedAircraft &aircraft); + + //! An airspace snapshot was handled + void airspaceSnapshotHandled(); public slots: //! Return list of available simulator plugins @@ -153,9 +159,12 @@ namespace BlackCore //! Delete all restrictions (if any) -> unlimited number of aircraft virtual void deleteAllRenderingRestrictions() = 0; - //! Is number of aircraft restricted + //! Is number of aircraft restricted ormax distance set? virtual bool isRenderingRestricted() const = 0; + //! Rendering enabled at all + virtual bool isRenderingEnabled() const = 0; + //! Time synchronization offset virtual BlackMisc::PhysicalQuantities::CTime getTimeSynchronizationOffset() const = 0; @@ -164,13 +173,13 @@ namespace BlackCore //! Load specific simulator plugin as set in settings virtual bool loadSimulatorPluginFromSettings() = 0; - + //! Listen for the specific simulator to start, load plugin automatically virtual void listenForSimulator(const BlackMisc::Simulation::CSimulatorPluginInfo &simulatorInfo) = 0; - + //! Listen for all available simulators virtual void listenForAllSimulators() = 0; - + //! Listen for simulator as set in settings virtual void listenForSimulatorFromSettings() = 0; diff --git a/src/blackcore/context_simulator_impl.cpp b/src/blackcore/context_simulator_impl.cpp index e89d63ab1..be34d823f 100644 --- a/src/blackcore/context_simulator_impl.cpp +++ b/src/blackcore/context_simulator_impl.cpp @@ -126,10 +126,7 @@ namespace BlackCore BlackMisc::Simulation::CSimulatorPluginInfo CContextSimulator::getSimulatorPluginInfo() const { if (m_debugEnabled) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - if (!m_simulatorPlugin) - { - return BlackMisc::Simulation::CSimulatorPluginInfo(); - } + if (!m_simulatorPlugin) { return BlackMisc::Simulation::CSimulatorPluginInfo(); } Q_ASSERT(m_simulatorPlugin->simulator); return m_simulatorPlugin->info; @@ -208,10 +205,7 @@ namespace BlackCore CAircraftIcao CContextSimulator::getIcaoForModelString(const QString &modelString) const { if (m_debugEnabled) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << modelString; } - if (!m_simulatorPlugin) - { - return CAircraftIcao(); - } + if (!m_simulatorPlugin) { return CAircraftIcao(); } Q_ASSERT(m_simulatorPlugin->simulator); return m_simulatorPlugin->simulator->getIcaoForModelString(modelString); @@ -220,17 +214,11 @@ namespace BlackCore bool CContextSimulator::setTimeSynchronization(bool enable, CTime offset) { if (m_debugEnabled) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - if (!m_simulatorPlugin) - { - return false; - } + if (!m_simulatorPlugin) { return false; } Q_ASSERT(m_simulatorPlugin->simulator); bool c = m_simulatorPlugin->simulator->setTimeSynchronization(enable, offset); - if (!c) - { - return false; - } + if (!c) { return false; } CLogMessage(this).info(enable ? QStringLiteral("Set time syncronization to %1").arg(offset.toQString()) : QStringLiteral("Disabled time syncrhonization")); return true; @@ -239,10 +227,7 @@ namespace BlackCore bool CContextSimulator::isTimeSynchronized() const { if (m_debugEnabled) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - if (!m_simulatorPlugin) - { - return false; - } + if (!m_simulatorPlugin) { return false; } Q_ASSERT(m_simulatorPlugin->simulator); return m_simulatorPlugin->simulator->isTimeSynchronized(); @@ -336,21 +321,23 @@ namespace BlackCore bool CContextSimulator::isRenderingRestricted() const { if (m_debugEnabled) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - if (!m_simulatorPlugin) - { - return false; - } + if (!m_simulatorPlugin) { return false; } Q_ASSERT(m_simulatorPlugin->simulator); return this->m_simulatorPlugin->simulator->isRenderingRestricted(); } + bool CContextSimulator::isRenderingEnabled() const + { + if (m_debugEnabled) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } + if (!m_simulatorPlugin) { return false; } + Q_ASSERT(m_simulatorPlugin->simulator); + return this->m_simulatorPlugin->simulator->isRenderingEnabled(); + } + CTime CContextSimulator::getTimeSynchronizationOffset() const { if (m_debugEnabled) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } - if (!m_simulatorPlugin) - { - return CTime(0, CTimeUnit::hrmin()); - } + if (!m_simulatorPlugin) { return CTime(0, CTimeUnit::hrmin()); } Q_ASSERT(m_simulatorPlugin->simulator); return this->m_simulatorPlugin->simulator->getTimeSynchronizationOffset(); } @@ -386,15 +373,25 @@ namespace BlackCore plugin->simulator = newSimulator; m_simulatorPlugin = plugin; - connect(m_simulatorPlugin->simulator, &ISimulator::simulatorStatusChanged, this, &CContextSimulator::ps_onSimulatorStatusChanged); - connect(m_simulatorPlugin->simulator, &ISimulator::ownAircraftModelChanged, this, &IContextSimulator::ownAircraftModelChanged); - connect(m_simulatorPlugin->simulator, &ISimulator::modelMatchingCompleted, this, &IContextSimulator::modelMatchingCompleted); - connect(m_simulatorPlugin->simulator, &ISimulator::installedAircraftModelsChanged, this, &IContextSimulator::installedAircraftModelsChanged); - connect(m_simulatorPlugin->simulator, &ISimulator::restrictedRenderingChanged, this, &IContextSimulator::restrictedRenderingChanged); + bool c = connect(m_simulatorPlugin->simulator, &ISimulator::simulatorStatusChanged, this, &CContextSimulator::ps_onSimulatorStatusChanged); + Q_ASSERT(c); + c = connect(m_simulatorPlugin->simulator, &ISimulator::ownAircraftModelChanged, this, &IContextSimulator::ownAircraftModelChanged); + Q_ASSERT(c); + c = connect(m_simulatorPlugin->simulator, &ISimulator::modelMatchingCompleted, this, &IContextSimulator::modelMatchingCompleted); + Q_ASSERT(c); + c = connect(m_simulatorPlugin->simulator, &ISimulator::installedAircraftModelsChanged, this, &IContextSimulator::installedAircraftModelsChanged); + Q_ASSERT(c); + c = connect(m_simulatorPlugin->simulator, &ISimulator::renderRestrictionsChanged, this, &IContextSimulator::renderRestrictionsChanged); + Q_ASSERT(c); + c = connect(m_simulatorPlugin->simulator, &ISimulator::airspaceSnapshotHandled, this, &IContextSimulator::airspaceSnapshotHandled); + Q_ASSERT(c); // log from context to simulator - connect(CLogHandler::instance(), &CLogHandler::localMessageLogged, m_simulatorPlugin->simulator, &ISimulator::displayStatusMessage); - connect(CLogHandler::instance(), &CLogHandler::remoteMessageLogged, m_simulatorPlugin->simulator, &ISimulator::displayStatusMessage); + c = connect(CLogHandler::instance(), &CLogHandler::localMessageLogged, m_simulatorPlugin->simulator, &ISimulator::displayStatusMessage); + Q_ASSERT(c); + c = connect(CLogHandler::instance(), &CLogHandler::remoteMessageLogged, m_simulatorPlugin->simulator, &ISimulator::displayStatusMessage); + Q_ASSERT(c); + Q_UNUSED(c); // connect with network IContextNetwork *networkContext = this->getIContextNetwork(); @@ -414,6 +411,7 @@ namespace BlackCore m_simulatorPlugin->simulator->asyncConnectTo(); // info about what is going on + emit simulatorPluginChanged(this->m_simulatorPlugin->info); CLogMessage(this).info("Simulator plugin loaded: %1") << this->m_simulatorPlugin->info.toQString(true); return true; } @@ -532,6 +530,8 @@ namespace BlackCore if (m_simulatorPlugin) { // depending on shutdown order, network might already have been deleted + emit simulatorPluginChanged(CSimulatorPluginInfo()); + IContextNetwork *networkContext = this->getIContextNetwork(); Q_ASSERT(networkContext); Q_ASSERT(networkContext->isLocalObject()); @@ -543,7 +543,9 @@ namespace BlackCore this->disconnect(m_simulatorPlugin->simulator); if (m_simulatorPlugin->simulator->isConnected()) + { m_simulatorPlugin->simulator->disconnectFrom(); // disconnect from simulator + } m_simulatorPlugin->simulator->deleteLater(); m_simulatorPlugin->simulator = nullptr; diff --git a/src/blackcore/context_simulator_impl.h b/src/blackcore/context_simulator_impl.h index e61b0ad78..6de768c8c 100644 --- a/src/blackcore/context_simulator_impl.h +++ b/src/blackcore/context_simulator_impl.h @@ -118,6 +118,9 @@ namespace BlackCore //! \copydoc IContextSimulator::isRenderingRestricted virtual bool isRenderingRestricted() const override; + //! \copydoc IContextSimulator::isRenderingEnabled + virtual bool isRenderingEnabled() const override; + //! \copydoc IContextSimulator::getTimeSynchronizationOffset virtual BlackMisc::PhysicalQuantities::CTime getTimeSynchronizationOffset() const override; diff --git a/src/blackcore/context_simulator_proxy.cpp b/src/blackcore/context_simulator_proxy.cpp index c261ea6c2..c3f43badd 100644 --- a/src/blackcore/context_simulator_proxy.cpp +++ b/src/blackcore/context_simulator_proxy.cpp @@ -49,7 +49,13 @@ namespace BlackCore "modelMatchingCompleted", this, SIGNAL(modelMatchingCompleted(BlackMisc::Simulation::CSimulatedAircraft))); Q_ASSERT(s); s = connection.connect(serviceName, IContextSimulator::ObjectPath(), IContextSimulator::InterfaceName(), - "restrictedRenderingChanged", this, SIGNAL(restrictedRenderingChanged(bool))); + "renderRestrictionsChanged", this, SIGNAL(renderRestrictionsChanged(bool, int, BlackMisc::PhysicalQuantities::CLength, BlackMisc::PhysicalQuantities::CLength))); + Q_ASSERT(s); + s = connection.connect(serviceName, IContextSimulator::ObjectPath(), IContextSimulator::InterfaceName(), + "simulatorPluginChanged", this, SIGNAL(simulatorPluginChanged(BlackMisc::Simulation::CSimulatorPluginInfo &))); + Q_ASSERT(s); + s = connection.connect(serviceName, IContextSimulator::ObjectPath(), IContextSimulator::InterfaceName(), + "airspaceSnapshotHandled", this, SIGNAL(airspaceSnapshotHandled())); Q_ASSERT(s); Q_UNUSED(s); } @@ -144,6 +150,11 @@ namespace BlackCore return m_dBusInterface->callDBusRet(QLatin1Literal("isRenderingRestricted")); } + bool CContextSimulatorProxy::isRenderingEnabled() const + { + return m_dBusInterface->callDBusRet(QLatin1Literal("isRenderingEnabled")); + } + CLength CContextSimulatorProxy::getMaxRenderedDistance() const { return m_dBusInterface->callDBusRet(QLatin1Literal("getMaxRenderedDistance")); diff --git a/src/blackcore/context_simulator_proxy.h b/src/blackcore/context_simulator_proxy.h index a5c86ce52..594397286 100644 --- a/src/blackcore/context_simulator_proxy.h +++ b/src/blackcore/context_simulator_proxy.h @@ -108,6 +108,9 @@ namespace BlackCore //! \copydoc IContextSimulator::isRenderingRestricted virtual bool isRenderingRestricted() const override; + //! \copydoc IContextSimulator::isRenderingEnabled + virtual bool isRenderingEnabled() const override; + //! \copydoc IContextSimulator::getMaxRenderedDistance virtual BlackMisc::PhysicalQuantities::CLength getMaxRenderedDistance() const override; diff --git a/src/blackcore/simulator.h b/src/blackcore/simulator.h index 5ccc66f3e..6cdf7d234 100644 --- a/src/blackcore/simulator.h +++ b/src/blackcore/simulator.h @@ -154,6 +154,9 @@ namespace BlackCore //! Is there a restriction? No rendering -> limited number of aircraft -> unlimited number of aircraft virtual bool isRenderingRestricted() const = 0; + //! Is rendering enabled? + virtual bool isRenderingEnabled() const = 0; + //! Delete all restrictions (if any) -> unlimited number of aircraft virtual void deleteAllRenderingRestrictions() = 0; @@ -171,9 +174,6 @@ namespace BlackCore //! Highlight the aircraft for given time (or disable highlight) virtual void highlightAircraft(const BlackMisc::Simulation::CSimulatedAircraft &aircraftToHighlight, bool enableHighlight, const BlackMisc::PhysicalQuantities::CTime &displayTime) = 0; - //! Is rendering enabled - virtual bool isRenderingEnabled() const = 0; - //! Originator const QString &simulatorOriginator(); @@ -184,8 +184,8 @@ namespace BlackCore //! Emitted when own aircraft model has changed void ownAircraftModelChanged(BlackMisc::Simulation::CSimulatedAircraft aircraft); - //! Only a limited number of aircraft displayed - void restrictedRenderingChanged(bool restricted); + //! Render restrictions have been changed + void renderRestrictionsChanged(bool restricted, int maxAircraft, const BlackMisc::PhysicalQuantities::CLength &maxRenderedDistance, const BlackMisc::PhysicalQuantities::CLength &maxRenderedBoundary); //! A single model has been matched void modelMatchingCompleted(BlackMisc::Simulation::CSimulatedAircraft aircraft); @@ -193,6 +193,9 @@ namespace BlackCore //! Installed aircraft models ready or changed void installedAircraftModelsChanged(); + //! An airspace snapshot was handled + void airspaceSnapshotHandled(); + protected: //! Default constructor ISimulator(QObject *parent = nullptr) : QObject(parent) {} @@ -204,6 +207,9 @@ namespace BlackCore //! Remove remote aircraft from simulator virtual bool physicallyRemoveRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) = 0; + //! Remove remote aircraft from simulator + virtual bool physicallyRemoveMultipleRemoteAircraft(const BlackMisc::Aviation::CCallsignSet &callsigns) = 0; + //! Remove all remote aircraft virtual void physicallyRemoveAllRemoteAircraft() = 0; diff --git a/src/blackcore/simulator_common.cpp b/src/blackcore/simulator_common.cpp index 8820a4a8f..552da8dc4 100644 --- a/src/blackcore/simulator_common.cpp +++ b/src/blackcore/simulator_common.cpp @@ -8,7 +8,8 @@ */ #include "simulator_common.h" -#include "interpolator.h" +#include "blackcore/interpolator.h" +#include "blackcore/blackcorefreefunctions.h" #include "blackmisc/logmessage.h" #include "blackmisc/collection.h" @@ -40,7 +41,7 @@ namespace BlackCore std::bind(&CSimulatorCommon::ps_remoteProviderAddAircraftSituation, this, std::placeholders::_1), std::bind(&CSimulatorCommon::ps_remoteProviderAddAircraftParts, this, std::placeholders::_1), std::bind(&CSimulatorCommon::ps_remoteProviderRemovedAircraft, this, std::placeholders::_1), - std::bind(&CSimulatorCommon::ps_remoteProviderAircraftSnapshot, this, std::placeholders::_1) + std::bind(static_cast(&CSimulatorCommon::ps_recalculateRenderedAircraft), this, std::placeholders::_1) ); Q_ASSERT(c); Q_UNUSED(c); @@ -56,8 +57,8 @@ namespace BlackCore // if not restriced, directly change if (!isRenderingRestricted()) { return this->physicallyAddRemoteAircraft(remoteAircraft); } - //! \todo Go thru logic - return this->physicallyAddRemoteAircraft(remoteAircraft); + // will be added with next snapshot + return false; } bool CSimulatorCommon::logicallyRemoveRemoteAircraft(const CCallsign &callsign) @@ -65,8 +66,8 @@ namespace BlackCore // if not restriced, directly change if (!isRenderingRestricted()) { return this->physicallyRemoveRemoteAircraft(callsign); } - //! \todo Go thru logic - return this->physicallyRemoveRemoteAircraft(callsign); + // will be added with next snapshot + return false; } void CSimulatorCommon::blinkHighlightedAircraft() @@ -104,26 +105,6 @@ namespace BlackCore } } - void CSimulatorCommon::recalculateRestrictedAircraft() - { - if (!isMaxAircraftRestricted()) { return; } - if (!isRenderingEnabled()) { return; } - - CSimulatedAircraftList newAircraftInRange(getAircraftInRange().getClosestObjects(getMaxRenderedAircraft())); - CCallsignSet newAircraftCallsigns(newAircraftInRange.getCallsigns()); - CCallsignSet toBeRemovedCallsigns(m_callsignsToBeRendered.difference(newAircraftCallsigns)); - CCallsignSet toBeAddedCallsigns(newAircraftCallsigns.difference(m_callsignsToBeRendered)); - for (const CCallsign &cs : toBeRemovedCallsigns) - { - physicallyRemoveRemoteAircraft(cs); - } - for (const CCallsign &cs : toBeAddedCallsigns) - { - physicallyAddRemoteAircraft(newAircraftInRange.findFirstByCallsign(cs)); - } - this->m_callsignsToBeRendered = newAircraftCallsigns; - } - void CSimulatorCommon::resetAircraftFromBacked(const CCallsign &callsign) { CSimulatedAircraft aircraft(this->getAircraftInRangeForCallsign(callsign)); @@ -138,7 +119,7 @@ namespace BlackCore } else { - physicallyRemoveRemoteAircraft(callsign); + this->physicallyRemoveRemoteAircraft(callsign); } } @@ -147,15 +128,14 @@ namespace BlackCore if (!this->m_interpolator) { return; } const CCallsign callsign(aircraft.getCallsign()); - if (!(this->remoteAircraftSituationsCount(callsign) < 1)) { return; } + if (this->remoteAircraftSituationsCount(callsign) < 1) { return; } // with an interpolator the interpolated situation is used // to avoid position jittering qint64 time = QDateTime::currentMSecsSinceEpoch(); - IInterpolator::InterpolationStatus is; - CAircraftSituation as(m_interpolator->getInterpolatedSituation(callsign, time, aircraft.isVtol(), is)); - if (is.interpolationSucceeded) { aircraft.setSituation(as); } - + IInterpolator::InterpolationStatus interpolationStatus; + CAircraftSituation as(m_interpolator->getInterpolatedSituation(callsign, time, aircraft.isVtol(), interpolationStatus)); + if (interpolationStatus.interpolationSucceeded) { aircraft.setSituation(as); } } int CSimulatorCommon::getMaxRenderedAircraft() const @@ -180,24 +160,24 @@ namespace BlackCore } bool r = isRenderingRestricted(); - emit restrictedRenderingChanged(r); + emit renderRestrictionsChanged(r, getMaxRenderedAircraft(), getMaxRenderedDistance(), getRenderedDistanceBoundary()); } void CSimulatorCommon::setMaxRenderedDistance(CLength &distance) { if (distance == m_maxRenderedDistance) { return; } - if (distance.isNull() || distance >= getRenderedDistanceBoundary()) + if (distance.isNull() || distance > getRenderedDistanceBoundary() || distance.isNegativeWithEpsilonConsidered()) { m_maxRenderedDistance = CLength(0.0, CLengthUnit::nullUnit()); } else { - Q_ASSERT(distance.isPositiveWithEpsilonConsidered()); + Q_ASSERT(!distance.isNegativeWithEpsilonConsidered()); m_maxRenderedDistance = distance; } bool r = isRenderingRestricted(); - emit restrictedRenderingChanged(r); + emit renderRestrictionsChanged(r, getMaxRenderedAircraft(), getMaxRenderedDistance(), getRenderedDistanceBoundary()); } CLength CSimulatorCommon::getMaxRenderedDistance() const @@ -223,7 +203,7 @@ namespace BlackCore bool CSimulatorCommon::isMaxAircraftRestricted() const { - return m_maxRenderedAircraft < MaxAircraftInfinite && isRenderingEnabled(); + return m_maxRenderedAircraft < MaxAircraftInfinite; } bool CSimulatorCommon::isMaxDistanceRestricted() const @@ -258,8 +238,7 @@ namespace BlackCore { if (m_maxRenderedAircraft < 1) { return false; } if (!isMaxDistanceRestricted()) { return true; } - - return m_maxRenderedDistance.valueRounded(CLengthUnit::NM(), 2) > 0.1; + return m_maxRenderedDistance.isPositiveWithEpsilonConsidered(); } bool CSimulatorCommon::isRenderingRestricted() const @@ -269,22 +248,24 @@ namespace BlackCore void CSimulatorCommon::deleteAllRenderingRestrictions() { - if (!isRenderingEnabled()) { return; } this->m_maxRenderedDistance = CLength(0, CLengthUnit::nullUnit()); this->m_maxRenderedAircraft = MaxAircraftInfinite; - emit restrictedRenderingChanged(false); + emit renderRestrictionsChanged(false, getMaxRenderedAircraft(), getMaxRenderedDistance(), getRenderedDistanceBoundary()); + } + + bool CSimulatorCommon::physicallyRemoveMultipleRemoteAircraft(const CCallsignSet &callsigns) + { + int removed = 0; + for (const CCallsign &callsign : callsigns) + { + if (physicallyRemoveRemoteAircraft(callsign)) { removed++; } + } + return removed > 0; } void CSimulatorCommon::ps_oneSecondTimer() { - m_timerCounter++; blinkHighlightedAircraft(); - - // any seconds - if (m_timerCounter % 10 == 0) - { - recalculateRestrictedAircraft(); - } } void CSimulatorCommon::ps_recalculateRenderedAircraft() @@ -294,9 +275,39 @@ namespace BlackCore void CSimulatorCommon::ps_recalculateRenderedAircraft(const CAirspaceAircraftSnapshot &snapshot) { - if (!snapshot.isValidSnapshot()) { return;} - CCallsignSet callsignsInSimuator(physicallyRenderedAircraft()); + Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this)); + if (!snapshot.isValidSnapshot()) { return;} + + // for unrestricted values all add/remove actions are directly linked + // when changing back from restricted->unrestricted an one time update is required + if (!snapshot.isRestricted() && !snapshot.isRestrictionChanged()) { return; } + + // we will handle snapshot + emit airspaceSnapshotHandled(); + + + // restricted snapshot values + if (!snapshot.isRenderingEnabled()) + { + this->physicallyRemoveAllRemoteAircraft(); + return; + } + + CCallsignSet callsignsInSimulator(physicallyRenderedAircraft()); + CCallsignSet callsignsToBeRemoved(callsignsInSimulator.difference(snapshot.getEnabledAircraftCallsignsByDistance())); + CCallsignSet callsignsToBeAdded(snapshot.getEnabledAircraftCallsignsByDistance().difference(callsignsInSimulator)); + this->physicallyRemoveMultipleRemoteAircraft(callsignsToBeRemoved); + + if (!callsignsToBeAdded.isEmpty()) + { + CSimulatedAircraftList aircraftToBeAdded(getAircraftInRange().findByCallsigns(callsignsToBeAdded)); // thread safe copy + for (const CSimulatedAircraft &aircraft : aircraftToBeAdded) + { + Q_ASSERT_X(aircraft.isEnabled(), Q_FUNC_INFO, "Disabled aircraft detected as to be added"); + this->physicallyAddRemoteAircraft(aircraft); + } + } } void CSimulatorCommon::ps_remoteProviderAddAircraftSituation(const CAircraftSituation &situation) @@ -314,9 +325,4 @@ namespace BlackCore Q_UNUSED(callsign); } - void CSimulatorCommon::ps_remoteProviderAircraftSnapshot(const CAirspaceAircraftSnapshot &aircraftSnapshot) - { - ps_recalculateRenderedAircraft(aircraftSnapshot); - } - } // namespace diff --git a/src/blackcore/simulator_common.h b/src/blackcore/simulator_common.h index 80c9a8bd6..dfff84543 100644 --- a/src/blackcore/simulator_common.h +++ b/src/blackcore/simulator_common.h @@ -83,7 +83,10 @@ namespace BlackCore virtual const BlackMisc::Simulation::CSimulatorSetup &getSimulatorSetup() const override; //! \copydoc IContextSimulator::deleteAllRenderingRestrictions - virtual void deleteAllRenderingRestrictions(); + virtual void deleteAllRenderingRestrictions() override; + + //! \copydoc IContextSimulator::physicallyRemoveRemoteAircraft + virtual bool physicallyRemoveMultipleRemoteAircraft(const BlackMisc::Aviation::CCallsignSet &callsigns) override; protected slots: //! Slow timer used to highlight aircraft, can be used for other things too @@ -104,9 +107,6 @@ namespace BlackCore //! Provider removed aircraft virtual void ps_remoteProviderRemovedAircraft(const BlackMisc::Aviation::CCallsign &callsign); - //! Provider aircraft snapshot - virtual void ps_remoteProviderAircraftSnapshot(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &aircraftSnapshot); - protected: //! Constructor CSimulatorCommon(const BlackMisc::Simulation::CSimulatorPluginInfo &info, @@ -123,9 +123,6 @@ namespace BlackCore //! Blink the highlighted aircraft void blinkHighlightedAircraft(); - //! Recalculate the restricted aircraft - void recalculateRestrictedAircraft(); - //! Restore aircraft from backedn data void resetAircraftFromBacked(const BlackMisc::Aviation::CCallsign &callsign); diff --git a/src/blackmisc/simulation/airspaceaircraftsnapshot.cpp b/src/blackmisc/simulation/airspaceaircraftsnapshot.cpp index 846c9a505..b9a77e27d 100644 --- a/src/blackmisc/simulation/airspaceaircraftsnapshot.cpp +++ b/src/blackmisc/simulation/airspaceaircraftsnapshot.cpp @@ -10,6 +10,7 @@ #include "airspaceaircraftsnapshot.h" using namespace BlackMisc::Aviation; +using namespace BlackMisc::PhysicalQuantities; namespace BlackMisc { @@ -18,20 +19,66 @@ namespace BlackMisc CAirspaceAircraftSnapshot::CAirspaceAircraftSnapshot() { } - CAirspaceAircraftSnapshot::CAirspaceAircraftSnapshot(const CSimulatedAircraftList &allAircraft) : - m_timestampMsSinceEpoch(QDateTime::currentMSecsSinceEpoch()) + CAirspaceAircraftSnapshot::CAirspaceAircraftSnapshot( + const CSimulatedAircraftList &allAircraft, + bool restricted, int maxAircraft, const CLength &maxRenderedDistance, const CLength &maxRenderedBoundary) : + m_timestampMsSinceEpoch(QDateTime::currentMSecsSinceEpoch()), + m_restricted(restricted) { - if (!allAircraft.isEmpty()) + m_renderingEnabled = !restricted || ( + maxAircraft > 0 && + (maxRenderedBoundary.isNull() || maxRenderedBoundary.isPositiveWithEpsilonConsidered()) && + (maxRenderedDistance.isNull() || maxRenderedDistance.isPositiveWithEpsilonConsidered()) + ); + if (allAircraft.isEmpty()) { return; } + + CSimulatedAircraftList aircraft(allAircraft); + aircraft.sortByDistanceToOwnAircraft(); + CSimulatedAircraftList vtolAircraft(aircraft.findByVtol(true)); + m_aircraftCallsignsByDistance = aircraft.getCallsigns(); + m_vtolAircraftCallsignsByDistance = vtolAircraft.getCallsigns(); + + if (!restricted) { - CSimulatedAircraftList aircraft(allAircraft); - aircraft.sortByDistanceToOwnAircraft(); - CSimulatedAircraftList vtolAircraft(aircraft.findByVtol(true)); - m_aircraftCallsignsByDistance = aircraft.getCallsigns(); m_enabledAircraftCallsignsByDistance = aircraft.findByEnabled(true).getCallsigns(); m_disabledAircraftCallsignsByDistance = aircraft.findByEnabled(false).getCallsigns(); - m_vtolAircraftCallsignsByDistance = vtolAircraft.getCallsigns(); m_enabledVtolAircraftCallsignsByDistance = vtolAircraft.findByEnabled(true).getCallsigns(); } + else + { + // if no rendering all aircraft are disabled + if (!m_renderingEnabled) + { + m_disabledAircraftCallsignsByDistance = aircraft.getCallsigns(); + return; + } + + int count = 0; + for (const CSimulatedAircraft ¤tAircraft : aircraft) + { + CCallsign cs(currentAircraft.getCallsign()); + if (currentAircraft.isEnabled()) + { + CLength distance(currentAircraft.getDistanceToOwnAircraft()); + if (count >= maxAircraft || + (!maxRenderedDistance.isNull() && distance >= maxRenderedBoundary) || + (!maxRenderedBoundary.isNull() && distance >= maxRenderedBoundary)) + { + m_disabledAircraftCallsignsByDistance.push_back(cs); + } + else + { + count++; + m_enabledAircraftCallsignsByDistance.push_back(cs); + if (currentAircraft.isVtol()) { m_enabledVtolAircraftCallsignsByDistance.push_back(cs); } + } + } + else + { + m_disabledAircraftCallsignsByDistance.push_back(cs); + } + } + } } bool CAirspaceAircraftSnapshot::isValidSnapshot() const @@ -39,6 +86,18 @@ namespace BlackMisc return m_timestampMsSinceEpoch > 0; } + void CAirspaceAircraftSnapshot::setRestrictionChanged(const CAirspaceAircraftSnapshot &snapshot) + { + if (this->isValidSnapshot() == snapshot.isValidSnapshot()) + { + this->m_restrictionChanged = (snapshot.m_restricted != this->m_restricted); + } + else + { + this->m_restrictionChanged = true; + } + } + CVariant CAirspaceAircraftSnapshot::propertyByIndex(const CPropertyIndex &index) const { if (index.isMyself()) { return this->toCVariant(); } diff --git a/src/blackmisc/simulation/airspaceaircraftsnapshot.h b/src/blackmisc/simulation/airspaceaircraftsnapshot.h index 90499c103..acdf6c0dc 100644 --- a/src/blackmisc/simulation/airspaceaircraftsnapshot.h +++ b/src/blackmisc/simulation/airspaceaircraftsnapshot.h @@ -29,7 +29,13 @@ namespace BlackMisc CAirspaceAircraftSnapshot(); //! Constructor - CAirspaceAircraftSnapshot(const BlackMisc::Simulation::CSimulatedAircraftList &allAircraft); + CAirspaceAircraftSnapshot( + const BlackMisc::Simulation::CSimulatedAircraftList &allAircraft, + bool restricted = false, + int maxAircraft = 100, + const BlackMisc::PhysicalQuantities::CLength &maxRenderedDistance = BlackMisc::PhysicalQuantities::CLength(0, BlackMisc::PhysicalQuantities::CLengthUnit::nullUnit()), + const BlackMisc::PhysicalQuantities::CLength &maxRenderedBoundary = BlackMisc::PhysicalQuantities::CLength(0, BlackMisc::PhysicalQuantities::CLengthUnit::nullUnit()) + ); //! Time when snapshot was taken const QDateTime getTimestamp() const { return QDateTime::fromMSecsSinceEpoch(m_timestampMsSinceEpoch); } @@ -52,6 +58,21 @@ namespace BlackMisc //! Valid snapshot? bool isValidSnapshot() const; + //! Restricted snapshot? + bool isValidRestricted() const { return m_restricted; } + + //! Did restriction change compared to last snapshot + void setRestrictionChanged(const CAirspaceAircraftSnapshot &snapshot); + + //! Did the restriction flag change? + bool isRestrictionChanged() const { return m_restrictionChanged; } + + //! Restricted values? + bool isRestricted() const { return m_restricted; } + + //! Rendering enabled or all aircraft disabled? + bool isRenderingEnabled() const { return m_renderingEnabled; } + //! \copydoc CValueObject::propertyByIndex virtual CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const override; @@ -65,6 +86,9 @@ namespace BlackMisc private: BLACK_ENABLE_TUPLE_CONVERSION(CAirspaceAircraftSnapshot) qint64 m_timestampMsSinceEpoch = -1; + bool m_restricted = false; + bool m_restrictionChanged = false; + bool m_renderingEnabled = true; // remark closest aircraft always first BlackMisc::Aviation::CCallsignSet m_aircraftCallsignsByDistance; diff --git a/src/plugins/simulator/fs9/simulator_fs9.cpp b/src/plugins/simulator/fs9/simulator_fs9.cpp index 81486dae2..a54c4fd68 100644 --- a/src/plugins/simulator/fs9/simulator_fs9.cpp +++ b/src/plugins/simulator/fs9/simulator_fs9.cpp @@ -57,7 +57,6 @@ namespace BlackSimPlugin connect(fs9Host.data(), &CFs9Host::customPacketReceived, this, &CSimulatorFs9::ps_processFs9Message); this->m_interpolator = new BlackCore::CInterpolatorLinear(remoteAircraftProvider, this); - this->m_interpolator->start(); } bool CSimulatorFs9::isConnected() const diff --git a/src/plugins/simulator/fsx/simconnect_object.cpp b/src/plugins/simulator/fsx/simconnect_object.cpp index b332641a6..5a56409a9 100644 --- a/src/plugins/simulator/fsx/simconnect_object.cpp +++ b/src/plugins/simulator/fsx/simconnect_object.cpp @@ -17,5 +17,10 @@ namespace BlackSimPlugin namespace Fsx { CSimConnectObject::CSimConnectObject() { } + + CSimConnectObject::CSimConnectObject(const BlackMisc::Aviation::CCallsign &callsign, int requestId, int objectId, bool vtol) : + m_callsign(callsign), m_requestId(requestId), m_objectId(objectId), m_vtol(vtol) + { } + } // namespace } // namespace diff --git a/src/plugins/simulator/fsx/simconnect_object.h b/src/plugins/simulator/fsx/simconnect_object.h index 8ef7d2ebd..d53cb2226 100644 --- a/src/plugins/simulator/fsx/simconnect_object.h +++ b/src/plugins/simulator/fsx/simconnect_object.h @@ -28,6 +28,9 @@ namespace BlackSimPlugin //! Constructor CSimConnectObject(); + //! Constructor + CSimConnectObject(const BlackMisc::Aviation::CCallsign &callsign, int requestId, int objectId, bool vtol); + //! Destructor ~CSimConnectObject() {} @@ -49,11 +52,17 @@ namespace BlackSimPlugin //! Set Simconnect object id int getObjectId() const { return m_objectId; } - private: + //! VTOL? + bool isVtol() const { return m_vtol; } + //! VTOL? + void setVtol(bool vtol) { m_vtol = vtol; } + + private: BlackMisc::Aviation::CCallsign m_callsign; int m_requestId = -1; int m_objectId = -1; + bool m_vtol = false; }; } // namespace } // namespace diff --git a/src/plugins/simulator/fsx/simulator_fsx.cpp b/src/plugins/simulator/fsx/simulator_fsx.cpp index e3f5de0fa..7c884611a 100644 --- a/src/plugins/simulator/fsx/simulator_fsx.cpp +++ b/src/plugins/simulator/fsx/simulator_fsx.cpp @@ -8,7 +8,8 @@ */ #include "simulator_fsx.h" -#include "simconnect_datadefinition.h" +#include "blackcore/interpolator_linear.h" +#include "blackcore/blackcorefreefunctions.h" #include "blackmisc/simulation/fscommon/bcdconversions.h" #include "blackmisc/simulation/fsx/simconnectutilities.h" #include "blackmisc/simulation/fsx/fsxsimulatorsetup.h" @@ -18,7 +19,6 @@ #include "blackmisc/aviation/airportlist.h" #include "blackmisc/logmessage.h" #include "blackmisc/network/aircraftmappinglist.h" -#include "blackcore/interpolator_linear.h" #include #include @@ -51,7 +51,6 @@ namespace BlackSimPlugin m_useFsuipc = false; // do not use FSUIPC at the moment with FSX this->m_interpolator = new CInterpolatorLinear(remoteAircraftProvider, this); - this->m_interpolator->start(); } CSimulatorFsx::~CSimulatorFsx() @@ -139,8 +138,9 @@ namespace BlackSimPlugin bool CSimulatorFsx::physicallyAddRemoteAircraft(const Simulation::CSimulatedAircraft &newRemoteAircraft) { - CCallsign callsign = newRemoteAircraft.getCallsign(); - Q_ASSERT(!callsign.isEmpty()); + CCallsign callsign(newRemoteAircraft.getCallsign()); + Q_ASSERT_X(BlackCore::isCurrentThreadCreatingThread(this), Q_FUNC_INFO, "thread"); + Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "empty callsign"); if (callsign.isEmpty()) { return false; } bool aircraftAlreadyExistsInSim = this->m_simConnectObjects.contains(callsign); @@ -155,10 +155,7 @@ namespace BlackSimPlugin this->setInitialAircraftSituationAndParts(newRemoteAircraftCopy); // set interpolated data/parts if available SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(newRemoteAircraftCopy.getSituation()); - CSimConnectObject simObj; - simObj.setCallsign(callsign); - simObj.setRequestId(m_nextObjID); - simObj.setObjectId(0); + CSimConnectObject simObj(callsign, m_nextObjID, 0, newRemoteAircraft.isVtol()); ++m_nextObjID; // matched models @@ -519,6 +516,7 @@ namespace BlackSimPlugin bool CSimulatorFsx::physicallyRemoveRemoteAircraft(const CCallsign &callsign) { // only remove from sim + Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this)); if (!m_simConnectObjects.contains(callsign)) { return false; } return physicallyRemoveRemoteAircraft(m_simConnectObjects.value(callsign)); } @@ -622,8 +620,8 @@ namespace BlackSimPlugin void CSimulatorFsx::updateRemoteAircraft() { static_assert(sizeof(DataDefinitionRemoteAircraftParts) == 120, "DataDefinitionRemoteAircraftParts has an incorrect size."); - Q_ASSERT(this->m_interpolator); - Q_ASSERT_X(this->m_interpolator->thread() != this->thread(), Q_FUNC_INFO, "interpolator should run in its own thread"); + Q_ASSERT_X(this->m_interpolator, Q_FUNC_INFO, "missing interpolator"); + Q_ASSERT_X(BlackCore::isCurrentThreadCreatingThread(this), Q_FUNC_INFO, "thread"); // nothing to do, reset request id and exit if (this->isPaused()) { return; } // no interpolation while paused @@ -635,19 +633,18 @@ namespace BlackSimPlugin // values used for position and parts bool isOnGround = false; - bool isVtolAircraft = false; //! \todo determine VTOL aircraft in interpolator - 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) + const QList simObjects(m_simConnectObjects.values()); + for (const CSimConnectObject &simObj : simObjects) { if (simObj.getObjectId() < 1) { continue; } const CCallsign callsign(simObj.getCallsign()); Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "missing callsign"); IInterpolator::InterpolationStatus interpolatorStatus; - CAircraftSituation interpolatedSituation = this->m_interpolator->getInterpolatedSituation(callsign, currentTimestamp, isVtolAircraft, interpolatorStatus); + CAircraftSituation interpolatedSituation = this->m_interpolator->getInterpolatedSituation(callsign, currentTimestamp, simObj.isVtol(), interpolatorStatus); // having the onGround flag in parts forces me to obtain parts here // which is not the smartest thing regarding performance