mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-06 10:15:38 +08:00
* added unload function to disconnect signals / slots and simulator * changed remote provider to return signal/slot connections to manually disconnect functor connects * flag so pause can freeze or continue AI aircraft * slightly changed unload behaviour in simulator context Remark: Tested for FSX only Solves #424 for FSX
This commit is contained in:
@@ -129,29 +129,22 @@ namespace BlackCore
|
||||
return m_aircraftSupportingParts;
|
||||
}
|
||||
|
||||
bool CAirspaceMonitor::connectRemoteAircraftProviderSignals(
|
||||
QList<QMetaObject::Connection> CAirspaceMonitor::connectRemoteAircraftProviderSignals(
|
||||
std::function<void(const CAircraftSituation &)> situationSlot,
|
||||
std::function<void(const CAircraftParts &)> partsSlot,
|
||||
std::function<void(const CCallsign &)> removedAircraftSlot,
|
||||
std::function<void(const CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot
|
||||
)
|
||||
{
|
||||
bool s1 = connect(this, &CAirspaceMonitor::addedAircraftSituation, situationSlot);
|
||||
Q_ASSERT(s1);
|
||||
bool s2 = connect(this, &CAirspaceMonitor::addedAircraftParts, partsSlot);
|
||||
Q_ASSERT(s2);
|
||||
bool s3 = connect(this, &CAirspaceMonitor::removedAircraft, removedAircraftSlot);
|
||||
Q_ASSERT(s3);
|
||||
bool s4 = connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, aircraftSnapshotSlot);
|
||||
Q_ASSERT(s4);
|
||||
|
||||
return s1 && s2 && s3 && s4;
|
||||
}
|
||||
|
||||
bool CAirspaceMonitor::disconnectRemoteAircraftProviderSignals(QObject *receiver)
|
||||
{
|
||||
if (!receiver) { return false; }
|
||||
return this->disconnect(receiver);
|
||||
QMetaObject::Connection c1 = connect(this, &CAirspaceMonitor::addedAircraftSituation, situationSlot);
|
||||
Q_ASSERT(c1);
|
||||
QMetaObject::Connection c2 = connect(this, &CAirspaceMonitor::addedAircraftParts, partsSlot);
|
||||
Q_ASSERT(c2);
|
||||
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);
|
||||
return QList<QMetaObject::Connection>({ c1, c2, c3, c4});
|
||||
}
|
||||
|
||||
bool CAirspaceMonitor::updateAircraftEnabled(const CCallsign &callsign, bool enabledForRedering, const QString &originator)
|
||||
|
||||
@@ -147,16 +147,13 @@ namespace BlackCore
|
||||
void testAddAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts, bool incremental);
|
||||
|
||||
//! \copydoc IRemoteAircraftProvider::connectRemoteAircraftProviderSignals
|
||||
virtual bool connectRemoteAircraftProviderSignals(
|
||||
virtual QList<QMetaObject::Connection> connectRemoteAircraftProviderSignals(
|
||||
std::function<void(const BlackMisc::Aviation::CAircraftSituation &)> addedSituationSlot,
|
||||
std::function<void(const BlackMisc::Aviation::CAircraftParts &)> addedPartsSlot,
|
||||
std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot,
|
||||
std::function<void(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot
|
||||
) override;
|
||||
|
||||
//! \copydoc IRemoteAircraftProvider::disconnectRemoteAircraftProviderSignals
|
||||
virtual bool disconnectRemoteAircraftProviderSignals(QObject *receiver) override;
|
||||
|
||||
//! Is interim position sending enabled?
|
||||
bool isFastPositionSendingEnabled() const;
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace BlackCore
|
||||
return m_airspace->remoteAircraftSupportingParts();
|
||||
}
|
||||
|
||||
bool CContextNetwork::connectRemoteAircraftProviderSignals(
|
||||
QList<QMetaObject::Connection> CContextNetwork::connectRemoteAircraftProviderSignals(
|
||||
std::function<void (const CAircraftSituation &)> situationSlot,
|
||||
std::function<void (const CAircraftParts &)> partsSlot,
|
||||
std::function<void (const CCallsign &)> removedAircraftSlot,
|
||||
@@ -145,12 +145,6 @@ namespace BlackCore
|
||||
return this->m_airspace->connectRemoteAircraftProviderSignals(situationSlot, partsSlot, removedAircraftSlot, aircraftSnapshotSlot);
|
||||
}
|
||||
|
||||
bool CContextNetwork::disconnectRemoteAircraftProviderSignals(QObject *receiver)
|
||||
{
|
||||
Q_ASSERT(this->m_airspace);
|
||||
return this->m_airspace->disconnectRemoteAircraftProviderSignals(receiver);
|
||||
}
|
||||
|
||||
void CContextNetwork::gracefulShutdown()
|
||||
{
|
||||
if (this->m_vatsimBookingReader) { this->m_vatsimBookingReader->requestStop(); this->m_vatsimBookingReader->quit(); }
|
||||
|
||||
@@ -74,17 +74,13 @@ namespace BlackCore
|
||||
|
||||
//! \copydoc IRemoteAircraftProvider::connectSignals
|
||||
//! \ingroup remoteaircraftprovider
|
||||
virtual bool connectRemoteAircraftProviderSignals(
|
||||
virtual QList<QMetaObject::Connection> connectRemoteAircraftProviderSignals(
|
||||
std::function<void(const BlackMisc::Aviation::CAircraftSituation &)> addedSituationSlot,
|
||||
std::function<void(const BlackMisc::Aviation::CAircraftParts &)> addedPartsSlot,
|
||||
std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot,
|
||||
std::function<void(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot
|
||||
) override;
|
||||
|
||||
//! \copydoc IRemoteAircraftProvider::disconnectRemoteAircraftProviderSignals
|
||||
//! \ingroup remoteaircraftprovider
|
||||
virtual bool disconnectRemoteAircraftProviderSignals(QObject *receiver) override;
|
||||
|
||||
//! \copydoc IRemoteAircraftProvider::updateAircraftRendered
|
||||
//! \ingroup remoteaircraftprovider
|
||||
virtual bool updateAircraftRendered(const BlackMisc::Aviation::CCallsign &callsign, bool rendered, const QString &originator) override;
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace BlackCore
|
||||
bool parseCommandLine(const QString commandLine, const QString &originator);
|
||||
|
||||
private:
|
||||
bool m_init = false; /*!< flag */
|
||||
bool m_init = false; //!< flag
|
||||
|
||||
// DBus
|
||||
CDBusServer *m_dbusServer = nullptr;
|
||||
|
||||
@@ -542,16 +542,10 @@ namespace BlackCore
|
||||
Q_ASSERT(this->getIContextNetwork()->isLocalObject());
|
||||
Q_ASSERT(m_simulatorPlugin->simulator);
|
||||
|
||||
// disconnect from simulator
|
||||
if (m_simulatorPlugin->simulator->isConnected())
|
||||
{
|
||||
m_simulatorPlugin->simulator->disconnectFrom();
|
||||
}
|
||||
// unload and disconnect
|
||||
m_simulatorPlugin->simulator->unload();
|
||||
|
||||
// disconnect signals
|
||||
this->getRuntime()->getCContextNetwork()->disconnectRemoteAircraftProviderSignals(m_simulatorPlugin->simulator);
|
||||
m_simulatorPlugin->simulator->disconnect();
|
||||
CLogHandler::instance()->disconnect(m_simulatorPlugin->simulator);
|
||||
this->disconnect(m_simulatorPlugin->simulator);
|
||||
|
||||
m_simulatorPlugin->simulator->deleteLater();
|
||||
@@ -599,8 +593,15 @@ namespace BlackCore
|
||||
|
||||
if (!(status & ISimulator::Connected))
|
||||
{
|
||||
// we got disconnected
|
||||
unloadSimulatorPlugin();
|
||||
listenForSimulatorFromSettings();
|
||||
|
||||
// do not immediately listen again, but allow some time for the simulator to shutdown
|
||||
// otherwise we risk reconnecting to a closing simulator
|
||||
BlackMisc::singleShot(1000, QThread::currentThread(), [ = ]()
|
||||
{
|
||||
listenForSimulatorFromSettings();
|
||||
});
|
||||
}
|
||||
emit simulatorStatusChanged(status);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,22 @@ namespace BlackCore
|
||||
return o;
|
||||
}
|
||||
|
||||
QString ISimulator::statusToString(int status)
|
||||
{
|
||||
if (status > 0)
|
||||
{
|
||||
QString s;
|
||||
if (status & Connected) { s.append("Connected"); }
|
||||
if (status & Running) { if (!s.isEmpty()) { s.append(", "); } s.append("Simulating"); }
|
||||
if (status & Paused) { if (!s.isEmpty()) { s.append(", "); } s.append("Paused"); }
|
||||
return s;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Disconnected";
|
||||
}
|
||||
}
|
||||
|
||||
void ISimulator::emitSimulatorCombinedStatus()
|
||||
{
|
||||
int status =
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace BlackCore
|
||||
Paused = 1 << 2, //!< Is the simulator paused?
|
||||
};
|
||||
|
||||
//! Render all aircraft
|
||||
//! Render all aircraft if number of aircraft >= MaxAircraftInfinite
|
||||
const int MaxAircraftInfinite = 100;
|
||||
|
||||
//! Destructor
|
||||
@@ -174,9 +174,15 @@ 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;
|
||||
|
||||
//! Driver will be unloaded
|
||||
virtual void unload() = 0;
|
||||
|
||||
//! Originator
|
||||
const QString &simulatorOriginator();
|
||||
|
||||
//! Status to string
|
||||
static QString statusToString(int status);
|
||||
|
||||
signals:
|
||||
//! Simulator combined status
|
||||
void simulatorStatusChanged(int status);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "blackcore/interpolator.h"
|
||||
#include "blackcore/blackcorefreefunctions.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
#include "blackmisc/loghandler.h"
|
||||
#include "blackmisc/collection.h"
|
||||
|
||||
using namespace BlackMisc;
|
||||
@@ -31,24 +32,25 @@ namespace BlackCore
|
||||
m_simulatorPluginInfo(info)
|
||||
{
|
||||
this->setObjectName(info.getIdentifier());
|
||||
|
||||
// provider signals
|
||||
m_remoteAircraftProviderConnections = this->m_remoteAircraftProvider->connectRemoteAircraftProviderSignals(
|
||||
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));
|
||||
|
||||
// timer
|
||||
this->m_oneSecondTimer.setObjectName(this->objectName().append(":m_oneSecondTimer"));
|
||||
connect(&m_oneSecondTimer, &QTimer::timeout, this, &CSimulatorCommon::ps_oneSecondTimer);
|
||||
this->m_oneSecondTimer.start(1000);
|
||||
|
||||
// provider signals
|
||||
bool c = remoteAircraftProvider->connectRemoteAircraftProviderSignals(
|
||||
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)
|
||||
);
|
||||
Q_ASSERT(c);
|
||||
Q_UNUSED(c);
|
||||
|
||||
// info
|
||||
CLogMessage(this).info("Initialized simulator driver %1") << m_simulatorPluginInfo.toQString();
|
||||
}
|
||||
|
||||
CSimulatorCommon::~CSimulatorCommon() { }
|
||||
|
||||
bool CSimulatorCommon::logicallyAddRemoteAircraft(const CSimulatedAircraft &remoteAircraft)
|
||||
{
|
||||
if (!remoteAircraft.isEnabled()) { return false; }
|
||||
@@ -195,6 +197,18 @@ namespace BlackCore
|
||||
return m_simulatorSetup;
|
||||
}
|
||||
|
||||
void CSimulatorCommon::unload()
|
||||
{
|
||||
this->disconnectFrom(); // disconnect from simulator
|
||||
for (QMetaObject::Connection &c : m_remoteAircraftProviderConnections)
|
||||
{
|
||||
QObject::disconnect(c);
|
||||
}
|
||||
m_remoteAircraftProviderConnections.clear();
|
||||
this->disconnect();
|
||||
CLogHandler::instance()->disconnect();
|
||||
}
|
||||
|
||||
CLength CSimulatorCommon::getRenderedDistanceBoundary() const
|
||||
{
|
||||
return CLength(20.0, CLengthUnit::NM());
|
||||
@@ -282,31 +296,32 @@ namespace BlackCore
|
||||
// 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())
|
||||
// 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);
|
||||
|
||||
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)
|
||||
if (!callsignsToBeAdded.isEmpty())
|
||||
{
|
||||
Q_ASSERT_X(aircraft.isEnabled(), Q_FUNC_INFO, "Disabled aircraft detected as to be added");
|
||||
this->physicallyAddRemoteAircraft(aircraft);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->physicallyRemoveAllRemoteAircraft();
|
||||
}
|
||||
|
||||
// we handled snapshot
|
||||
emit airspaceSnapshotHandled();
|
||||
|
||||
}
|
||||
|
||||
void CSimulatorCommon::ps_remoteProviderAddAircraftSituation(const CAircraftSituation &situation)
|
||||
|
||||
@@ -41,6 +41,9 @@ namespace BlackCore
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Destructor
|
||||
virtual ~CSimulatorCommon();
|
||||
|
||||
//! \copydoc ISimulator::getMaxRenderedAircraft
|
||||
virtual int getMaxRenderedAircraft() const override;
|
||||
|
||||
@@ -83,6 +86,9 @@ namespace BlackCore
|
||||
//! \copydoc IContextSimulator::getSimulatorSetup
|
||||
virtual const BlackMisc::Simulation::CSimulatorSetup &getSimulatorSetup() const override;
|
||||
|
||||
//! \copydoc IContextSimulator::unload
|
||||
virtual void unload();
|
||||
|
||||
//! \copydoc IContextSimulator::deleteAllRenderingRestrictions
|
||||
virtual void deleteAllRenderingRestrictions() override;
|
||||
|
||||
@@ -132,6 +138,7 @@ namespace BlackCore
|
||||
|
||||
bool m_debugMessages = false; //!< Display debug messages
|
||||
bool m_blinkCycle = false; //!< use for highlighting
|
||||
bool m_pausedSimFreezesInterpolation = false; //!< paused simulator will also pause interpolation (so AI aircraft will hold)
|
||||
IInterpolator *m_interpolator = nullptr; //!< interpolator instance
|
||||
qint64 m_highlightEndTimeMsEpoch = 0; //!< end highlighting
|
||||
int m_timerCounter = 0; //!< allows to calculate n seconds
|
||||
@@ -142,6 +149,8 @@ namespace BlackCore
|
||||
BlackMisc::Aviation::CCallsignSet m_callsignsToBeRendered; //!< callsigns which will be rendered
|
||||
int m_maxRenderedAircraft = MaxAircraftInfinite; //!< max.rendered aircraft
|
||||
BlackMisc::PhysicalQuantities::CLength m_maxRenderedDistance { 0.0, BlackMisc::PhysicalQuantities::CLengthUnit::nullUnit()}; //!< max.distance for rendering
|
||||
QList<QMetaObject::Connection> m_remoteAircraftProviderConnections; //!< connected signal/slots
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user