mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-13 07:35:41 +08:00
refs #395, improvements for snapshot / restricted aircraft handling
* fixed isCurrentThreadCreatingThread and renamed to isCurrentThreadObjectThread (this check was never working), added 2 more thread checks * changed remove aircraft function to return number of returned aircraft (like with the containers this allows to avoid unnecessary signals) * removed unused function ps_recalculateRenderedAircraft() / SimulatorCommon * using Queued airspaceAircraftSnapshot signal for binding (functor connect does not provide connection type) * extened ASSERTs to check threads * simulator: initial situation function with return value (success?) * simulator: avoid unneccessary copy and provide correct rendered flag in add aircraft function
This commit is contained in:
@@ -7,7 +7,8 @@
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "airspace_analyzer.h"
|
||||
#include "blackcore/airspace_analyzer.h"
|
||||
#include "blackcore/blackcorefreefunctions.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
#include <QDateTime>
|
||||
|
||||
@@ -30,7 +31,7 @@ namespace BlackCore
|
||||
|
||||
// all in new thread from here on
|
||||
m_timer.setObjectName(this->objectName().append(":m_timer"));
|
||||
m_timer.start(5000);
|
||||
m_timer.start(7500);
|
||||
bool c = connect(&m_timer, &QTimer::timeout, this, &CAirspaceAnalyzer::ps_timeout);
|
||||
Q_ASSERT(c);
|
||||
|
||||
@@ -53,7 +54,8 @@ namespace BlackCore
|
||||
Q_ASSERT(c);
|
||||
Q_UNUSED(c);
|
||||
|
||||
this->start();
|
||||
// start in own thread
|
||||
this->start(QThread::LowestPriority);
|
||||
}
|
||||
|
||||
CAirspaceAircraftSnapshot CAirspaceAnalyzer::getLatestAirspaceAircraftSnapshot() const
|
||||
@@ -172,6 +174,9 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceAnalyzer::analyzeAirspace()
|
||||
{
|
||||
Q_ASSERT_X(!isCurrentThreadApplicationThread(), Q_FUNC_INFO, "Expect to run in background thread");
|
||||
Q_ASSERT_X(!isApplicationThreadObjectThread(this), Q_FUNC_INFO, "Expect to run in background thread affinity");
|
||||
|
||||
bool restricted;
|
||||
int maxAircraft;
|
||||
CLength maxRenderedDistance, maxRenderedBoundary;
|
||||
@@ -183,17 +188,24 @@ namespace BlackCore
|
||||
maxRenderedBoundary = this->m_simulatorMaxRenderedBoundary;
|
||||
}
|
||||
|
||||
//! \todo Analyzer: generate only when restricted?
|
||||
|
||||
CSimulatedAircraftList aircraftInRange(getAircraftInRange()); // thread safe copy from provider
|
||||
CAirspaceAircraftSnapshot snapshot(
|
||||
getAircraftInRange(), // thread safe copy
|
||||
aircraftInRange,
|
||||
restricted, maxAircraft, maxRenderedDistance, maxRenderedBoundary
|
||||
);
|
||||
|
||||
// lock block
|
||||
{
|
||||
QWriteLocker l(&m_lockSnapshot);
|
||||
snapshot.setRestrictionChanged(m_latestAircraftSnapshot);
|
||||
bool wasValid = m_latestAircraftSnapshot.isValidSnapshot();
|
||||
m_latestAircraftSnapshot = snapshot;
|
||||
|
||||
if (!wasValid) { return; } // ignore the 1st snapshot
|
||||
snapshot.setRestrictionChanged(m_latestAircraftSnapshot);
|
||||
}
|
||||
|
||||
emit airspaceAircraftSnapshot(snapshot);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,9 +58,12 @@ namespace BlackCore
|
||||
this->connect(this->m_vatsimBookingReader, &CVatsimBookingReader::dataRead, this, &CAirspaceMonitor::ps_receivedBookings);
|
||||
this->connect(this->m_vatsimDataFileReader, &CVatsimDataFileReader::dataRead, this, &CAirspaceMonitor::ps_receivedDataFile);
|
||||
|
||||
// Force snapshot in the main event loop
|
||||
this->connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, this, &CAirspaceMonitor::airspaceAircraftSnapshot, Qt::QueuedConnection);
|
||||
|
||||
// Analyzer
|
||||
this->connect(this->m_analyzer, &CAirspaceAnalyzer::timeoutAircraft, this, &CAirspaceMonitor::ps_pilotDisconnected);
|
||||
this->connect(this->m_analyzer, &CAirspaceAnalyzer::timeoutAtc, this, &CAirspaceMonitor::ps_atcControllerDisconnected);
|
||||
this->connect(this->m_analyzer, &CAirspaceAnalyzer::timeoutAircraft, this, &CAirspaceMonitor::ps_pilotDisconnected, Qt::QueuedConnection);
|
||||
this->connect(this->m_analyzer, &CAirspaceAnalyzer::timeoutAtc, this, &CAirspaceMonitor::ps_atcControllerDisconnected, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
CSimulatedAircraftList CAirspaceMonitor::getAircraftInRange() const
|
||||
@@ -136,14 +139,18 @@ namespace BlackCore
|
||||
std::function<void(const CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot
|
||||
)
|
||||
{
|
||||
// bind does not allow to define connection type
|
||||
// so anything in its own thread will be sent with this thread affinity
|
||||
QMetaObject::Connection c1 = connect(this, &CAirspaceMonitor::addedAircraftSituation, situationSlot);
|
||||
Q_ASSERT(c1);
|
||||
Q_ASSERT_X(c1, Q_FUNC_INFO, "connect failed");
|
||||
QMetaObject::Connection c2 = connect(this, &CAirspaceMonitor::addedAircraftParts, partsSlot);
|
||||
Q_ASSERT(c2);
|
||||
Q_ASSERT_X(c2, Q_FUNC_INFO, "connect failed");
|
||||
QMetaObject::Connection c3 = connect(this, &CAirspaceMonitor::removedAircraft, removedAircraftSlot);
|
||||
Q_ASSERT(c3);
|
||||
QMetaObject::Connection c4 = this->connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, aircraftSnapshotSlot);
|
||||
Q_ASSERT(c4);
|
||||
Q_ASSERT_X(c3, Q_FUNC_INFO, "connect failed");
|
||||
// trick is to use the Queued signal here
|
||||
// analyzer (own thread) -> airspaceAircraftSnapshot -> AirspaceMonitor -> airspaceAircraftSnapshot queued in main thread
|
||||
QMetaObject::Connection c4 = this->connect(this, &CAirspaceMonitor::airspaceAircraftSnapshot, aircraftSnapshotSlot);
|
||||
Q_ASSERT_X(c4, Q_FUNC_INFO, "connect failed");
|
||||
return QList<QMetaObject::Connection>({ c1, c2, c3, c4});
|
||||
}
|
||||
|
||||
@@ -600,7 +607,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_receivedBookings(const CAtcStationList &bookedStations)
|
||||
{
|
||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
|
||||
if (bookedStations.isEmpty())
|
||||
{
|
||||
this->m_atcStationsBooked.clear();
|
||||
@@ -620,7 +627,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_receivedDataFile()
|
||||
{
|
||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
|
||||
for (auto client = this->m_otherClients.begin(); client != this->m_otherClients.end(); ++client)
|
||||
{
|
||||
if (client->hasSpecifiedVoiceCapabilities()) { continue; } // we already have voice caps
|
||||
@@ -667,7 +674,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_atcPositionUpdate(const CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &frequency, const CCoordinateGeodetic &position, const BlackMisc::PhysicalQuantities::CLength &range)
|
||||
{
|
||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
|
||||
Q_ASSERT(CComSystem::isValidCivilAviationFrequency(frequency));
|
||||
if (!this->m_connected) { return; }
|
||||
CAtcStationList stationsWithCallsign = this->m_atcStationsOnline.findByCallsign(callsign);
|
||||
@@ -718,7 +725,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_atcControllerDisconnected(const CCallsign &callsign)
|
||||
{
|
||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
|
||||
|
||||
this->m_otherClients.removeByCallsign(callsign);
|
||||
if (this->m_atcStationsOnline.containsCallsign(callsign))
|
||||
@@ -735,7 +742,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_atisReceived(const CCallsign &callsign, const CInformationMessage &atisMessage)
|
||||
{
|
||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
|
||||
if (!this->m_connected || callsign.isEmpty()) return;
|
||||
CPropertyIndexVariantMap vm(CAtcStation::IndexAtis, atisMessage.toCVariant());
|
||||
int changedOnline = this->m_atcStationsOnline.applyIf(&CAtcStation::getCallsign, callsign, vm);
|
||||
@@ -749,7 +756,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_atisVoiceRoomReceived(const CCallsign &callsign, const QString &url)
|
||||
{
|
||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
|
||||
if (!this->m_connected) { return; }
|
||||
QString trimmedUrl = url.trimmed();
|
||||
CPropertyIndexVariantMap vm({ CAtcStation::IndexVoiceRoom, CVoiceRoom::IndexUrl }, trimmedUrl);
|
||||
@@ -776,7 +783,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_atisLogoffTimeReceived(const CCallsign &callsign, const QString &zuluTime)
|
||||
{
|
||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
|
||||
if (!this->m_connected) { return; }
|
||||
if (zuluTime.length() == 4)
|
||||
{
|
||||
@@ -800,7 +807,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_icaoCodesReceived(const CCallsign &callsign, const CAircraftIcaoData &icaoData)
|
||||
{
|
||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
|
||||
Q_ASSERT(!callsign.isEmpty());
|
||||
if (!this->m_connected) { return; }
|
||||
|
||||
@@ -833,7 +840,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_aircraftUpdateReceived(const CAircraftSituation &situation, const CTransponder &transponder)
|
||||
{
|
||||
Q_ASSERT_X(BlackCore::isCurrentThreadCreatingThread(this), Q_FUNC_INFO, "Called in different thread");
|
||||
Q_ASSERT_X(BlackCore::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "Called in different thread");
|
||||
if (!this->m_connected) { return; }
|
||||
|
||||
CCallsign callsign(situation.getCallsign());
|
||||
@@ -923,7 +930,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_aircraftInterimUpdateReceived(const CAircraftSituation &situation)
|
||||
{
|
||||
Q_ASSERT_X(BlackCore::isCurrentThreadCreatingThread(this), Q_FUNC_INFO, "Called in different thread");
|
||||
Q_ASSERT_X(BlackCore::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "Called in different thread");
|
||||
if (!this->m_connected) { return; }
|
||||
|
||||
CCallsign callsign(situation.getCallsign());
|
||||
@@ -955,14 +962,16 @@ namespace BlackCore
|
||||
vm.addValue(CAircraft::IndexDistanceToOwnAircraft, distance);
|
||||
|
||||
// here I expect always a changed value
|
||||
{
|
||||
QWriteLocker l(&m_lockAircraft);
|
||||
this->m_aircraftInRange.applyIfCallsign(callsign, vm);
|
||||
}
|
||||
emit this->changedAircraftInRange();
|
||||
QWriteLocker l(&m_lockAircraft);
|
||||
this->m_aircraftInRange.applyIfCallsign(callsign, vm);
|
||||
}
|
||||
|
||||
void CAirspaceMonitor::ps_pilotDisconnected(const CCallsign &callsign)
|
||||
{
|
||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
|
||||
|
||||
// in case of inconsistencies I always remove here
|
||||
this->m_otherClients.removeByCallsign(callsign);
|
||||
@@ -989,7 +998,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_frequencyReceived(const CCallsign &callsign, const CFrequency &frequency)
|
||||
{
|
||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
|
||||
|
||||
// update
|
||||
int changed;
|
||||
@@ -1003,7 +1012,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_aircraftConfigReceived(const BlackMisc::Aviation::CCallsign &callsign, const QJsonObject &jsonObject, bool isFull)
|
||||
{
|
||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
|
||||
|
||||
CSimulatedAircraft simAircraft(getAircraftInRangeForCallsign(callsign));
|
||||
|
||||
@@ -1039,7 +1048,7 @@ namespace BlackCore
|
||||
|
||||
void CAirspaceMonitor::ps_sendInterimPositions()
|
||||
{
|
||||
Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this));
|
||||
Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this));
|
||||
if (!this->m_connected || !m_sendInterimPositions) { return; }
|
||||
CSimulatedAircraftList aircrafts = m_aircraftInRange.findBy(&CSimulatedAircraft::fastPositionUpdates, true);
|
||||
m_network->sendInterimPositions(aircrafts.getCallsigns());
|
||||
|
||||
@@ -197,6 +197,9 @@ namespace BlackCore
|
||||
//! An aircraft disappeared
|
||||
void removedAircraft(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
|
||||
//! \copydoc CAirspaceAnalyzer::airspaceAircraftSnapshot
|
||||
void airspaceAircraftSnapshot(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &snapshot);
|
||||
|
||||
private:
|
||||
BlackMisc::Aviation::CAtcStationList m_atcStationsOnline;
|
||||
BlackMisc::Aviation::CAtcStationList m_atcStationsBooked;
|
||||
|
||||
@@ -17,11 +17,25 @@ namespace BlackCore
|
||||
qRegisterMetaType<BlackCore::INetwork::ConnectionStatus>();
|
||||
}
|
||||
|
||||
bool isCurrentThreadCreatingThread(QObject *toBeTested)
|
||||
bool isCurrentThreadObjectThread(QObject *toBeTested)
|
||||
{
|
||||
Q_ASSERT_X(toBeTested, Q_FUNC_INFO, "missing QObject");
|
||||
if (!toBeTested) { return false; }
|
||||
if (!toBeTested->thread()) { return false; }
|
||||
return (QThread::currentThreadId() == toBeTested->thread()->currentThreadId());
|
||||
return (QThread::currentThread() == toBeTested->thread());
|
||||
}
|
||||
|
||||
bool isApplicationThreadObjectThread(QObject *toBeTested)
|
||||
{
|
||||
Q_ASSERT_X(toBeTested, Q_FUNC_INFO, "missing QObject");
|
||||
if (!toBeTested) { return false; }
|
||||
if (!toBeTested->thread()) { return false; }
|
||||
return (QCoreApplication::instance()->thread() == toBeTested->thread());
|
||||
}
|
||||
|
||||
bool isCurrentThreadApplicationThread()
|
||||
{
|
||||
return (QCoreApplication::instance()->thread() == QThread::currentThread());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -14,9 +14,17 @@ namespace BlackCore
|
||||
//! Register all relevant metadata in BlackCore
|
||||
BLACKCORE_EXPORT void registerMetadata();
|
||||
|
||||
//! Is the current thread the one created the object
|
||||
//! Is the current thread the QObject's thread?
|
||||
//! \remarks can be used as ASSERT check for threaded objects
|
||||
BLACKCORE_EXPORT bool isCurrentThreadCreatingThread(QObject *toBeTested);
|
||||
BLACKCORE_EXPORT bool isCurrentThreadObjectThread(QObject *toBeTested);
|
||||
|
||||
//! Is the application thread the QObject's thread?
|
||||
//! \remarks can be used as ASSERT check for threaded objects
|
||||
BLACKCORE_EXPORT bool isApplicationThreadObjectThread(QObject *toBeTested);
|
||||
|
||||
//! Is the current thread the Application thread?
|
||||
//! \remarks can be used as ASSERT check for threaded objects
|
||||
BLACKCORE_EXPORT bool isCurrentThreadApplicationThread();
|
||||
|
||||
} // BlackCore
|
||||
|
||||
|
||||
@@ -214,10 +214,10 @@ namespace BlackCore
|
||||
virtual bool physicallyRemoveRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) = 0;
|
||||
|
||||
//! Remove remote aircraft from simulator
|
||||
virtual bool physicallyRemoveMultipleRemoteAircraft(const BlackMisc::Aviation::CCallsignSet &callsigns) = 0;
|
||||
virtual int physicallyRemoveMultipleRemoteAircraft(const BlackMisc::Aviation::CCallsignSet &callsigns) = 0;
|
||||
|
||||
//! Remove all remote aircraft
|
||||
virtual void physicallyRemoveAllRemoteAircraft() = 0;
|
||||
virtual int physicallyRemoveAllRemoteAircraft() = 0;
|
||||
|
||||
//! Emit the combined status
|
||||
//! \sa simulatorStatusChanged;
|
||||
|
||||
@@ -38,7 +38,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(static_cast<void(CSimulatorCommon::*)(const CAirspaceAircraftSnapshot &)>(&CSimulatorCommon::ps_recalculateRenderedAircraft), this, std::placeholders::_1));
|
||||
std::bind(&CSimulatorCommon::ps_recalculateRenderedAircraft, this, std::placeholders::_1));
|
||||
|
||||
// timer
|
||||
this->m_oneSecondTimer.setObjectName(this->objectName().append(":m_oneSecondTimer"));
|
||||
@@ -97,7 +97,7 @@ namespace BlackCore
|
||||
for (const CSimulatedAircraft &aircraft : m_highlightedAircraft)
|
||||
{
|
||||
// get the current state for this aircraft
|
||||
// it might has been removed in the mean time
|
||||
// it might has been removed in the meantime
|
||||
const CCallsign cs(aircraft.getCallsign());
|
||||
resetAircraftFromBacked(cs);
|
||||
}
|
||||
@@ -124,19 +124,26 @@ namespace BlackCore
|
||||
}
|
||||
}
|
||||
|
||||
void CSimulatorCommon::setInitialAircraftSituationAndParts(CSimulatedAircraft &aircraft) const
|
||||
bool CSimulatorCommon::setInitialAircraftSituation(CSimulatedAircraft &aircraft) const
|
||||
{
|
||||
if (!this->m_interpolator) { return; }
|
||||
|
||||
if (!this->m_interpolator) { return false; }
|
||||
const CCallsign callsign(aircraft.getCallsign());
|
||||
if (this->remoteAircraftSituationsCount(callsign) < 1) { return; }
|
||||
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "Missing callsign");
|
||||
|
||||
// with an interpolator the interpolated situation is used
|
||||
// to avoid position jittering
|
||||
// to avoid position jittering when displayed
|
||||
qint64 time = QDateTime::currentMSecsSinceEpoch();
|
||||
IInterpolator::InterpolationStatus interpolationStatus;
|
||||
CAircraftSituation as(m_interpolator->getInterpolatedSituation(callsign, time, aircraft.isVtol(), interpolationStatus));
|
||||
if (interpolationStatus.interpolationSucceeded) { aircraft.setSituation(as); }
|
||||
if (interpolationStatus.interpolationSucceeded)
|
||||
{
|
||||
aircraft.setSituation(as);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int CSimulatorCommon::getMaxRenderedAircraft() const
|
||||
@@ -268,14 +275,14 @@ namespace BlackCore
|
||||
emit renderRestrictionsChanged(false, getMaxRenderedAircraft(), getMaxRenderedDistance(), getRenderedDistanceBoundary());
|
||||
}
|
||||
|
||||
bool CSimulatorCommon::physicallyRemoveMultipleRemoteAircraft(const CCallsignSet &callsigns)
|
||||
int CSimulatorCommon::physicallyRemoveMultipleRemoteAircraft(const CCallsignSet &callsigns)
|
||||
{
|
||||
int removed = 0;
|
||||
for (const CCallsign &callsign : callsigns)
|
||||
{
|
||||
if (physicallyRemoveRemoteAircraft(callsign)) { removed++; }
|
||||
}
|
||||
return removed > 0;
|
||||
return removed;
|
||||
}
|
||||
|
||||
void CSimulatorCommon::ps_oneSecondTimer()
|
||||
@@ -283,28 +290,29 @@ namespace BlackCore
|
||||
blinkHighlightedAircraft();
|
||||
}
|
||||
|
||||
void CSimulatorCommon::ps_recalculateRenderedAircraft()
|
||||
{
|
||||
this->ps_recalculateRenderedAircraft(getLatestAirspaceAircraftSnapshot());
|
||||
}
|
||||
|
||||
void CSimulatorCommon::ps_recalculateRenderedAircraft(const CAirspaceAircraftSnapshot &snapshot)
|
||||
{
|
||||
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; }
|
||||
|
||||
Q_ASSERT_X(BlackCore::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "Needs to run in object thread");
|
||||
Q_ASSERT_X(snapshot.generatingThreadName() != QThread::currentThread(), Q_FUNC_INFO, "Expect snapshot from background thread");
|
||||
|
||||
// restricted snapshot values?
|
||||
bool changed = false;
|
||||
if (snapshot.isRenderingEnabled())
|
||||
{
|
||||
CCallsignSet callsignsInSimulator(physicallyRenderedAircraft());
|
||||
CCallsignSet callsignsInSimulator(physicallyRenderedAircraft()); // state in simulator
|
||||
CCallsignSet callsignsToBeRemoved(callsignsInSimulator.difference(snapshot.getEnabledAircraftCallsignsByDistance()));
|
||||
CCallsignSet callsignsToBeAdded(snapshot.getEnabledAircraftCallsignsByDistance().difference(callsignsInSimulator));
|
||||
this->physicallyRemoveMultipleRemoteAircraft(callsignsToBeRemoved);
|
||||
if (!callsignsToBeRemoved.isEmpty())
|
||||
{
|
||||
int r = this->physicallyRemoveMultipleRemoteAircraft(callsignsToBeRemoved);
|
||||
changed = r > 0;
|
||||
}
|
||||
|
||||
if (!callsignsToBeAdded.isEmpty())
|
||||
{
|
||||
@@ -312,18 +320,23 @@ namespace BlackCore
|
||||
for (const CSimulatedAircraft &aircraft : aircraftToBeAdded)
|
||||
{
|
||||
Q_ASSERT_X(aircraft.isEnabled(), Q_FUNC_INFO, "Disabled aircraft detected as to be added");
|
||||
this->physicallyAddRemoteAircraft(aircraft);
|
||||
bool a = this->physicallyAddRemoteAircraft(aircraft);
|
||||
changed = changed || a;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->physicallyRemoveAllRemoteAircraft();
|
||||
// no rendering at all, we remove everything
|
||||
int r = this->physicallyRemoveAllRemoteAircraft();
|
||||
changed = r > 0;
|
||||
}
|
||||
|
||||
// we handled snapshot
|
||||
emit airspaceSnapshotHandled();
|
||||
|
||||
if (changed)
|
||||
{
|
||||
emit airspaceSnapshotHandled();
|
||||
}
|
||||
}
|
||||
|
||||
void CSimulatorCommon::ps_remoteProviderAddAircraftSituation(const CAircraftSituation &situation)
|
||||
|
||||
@@ -93,15 +93,12 @@ namespace BlackCore
|
||||
virtual void deleteAllRenderingRestrictions() override;
|
||||
|
||||
//! \copydoc IContextSimulator::physicallyRemoveRemoteAircraft
|
||||
virtual bool physicallyRemoveMultipleRemoteAircraft(const BlackMisc::Aviation::CCallsignSet &callsigns) override;
|
||||
virtual int physicallyRemoveMultipleRemoteAircraft(const BlackMisc::Aviation::CCallsignSet &callsigns) override;
|
||||
|
||||
protected slots:
|
||||
//! Slow timer used to highlight aircraft, can be used for other things too
|
||||
virtual void ps_oneSecondTimer();
|
||||
|
||||
//! Recalculate the rendered aircraft
|
||||
virtual void ps_recalculateRenderedAircraft();
|
||||
|
||||
//! Recalculate the rendered aircraft
|
||||
virtual void ps_recalculateRenderedAircraft(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &snapshot);
|
||||
|
||||
@@ -130,11 +127,11 @@ namespace BlackCore
|
||||
//! Blink the highlighted aircraft
|
||||
void blinkHighlightedAircraft();
|
||||
|
||||
//! Restore aircraft from backedn data
|
||||
//! Restore aircraft from backend data
|
||||
void resetAircraftFromBacked(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
|
||||
//! Override parts and situation from current interpolator values, if any!
|
||||
void setInitialAircraftSituationAndParts(BlackMisc::Simulation::CSimulatedAircraft &aircraft) const;
|
||||
//! Override situation from current interpolator values, if any!
|
||||
bool setInitialAircraftSituation(BlackMisc::Simulation::CSimulatedAircraft &aircraft) const;
|
||||
|
||||
bool m_debugMessages = false; //!< Display debug messages
|
||||
bool m_blinkCycle = false; //!< use for highlighting
|
||||
|
||||
Reference in New Issue
Block a user