refs #420, refs #421 Adjusted FSX driver to emit correct status flags and unloading

* 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:
Klaus Basan
2015-05-15 18:50:41 +02:00
parent eeb0d17dcb
commit de43caf451
16 changed files with 172 additions and 130 deletions

View File

@@ -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)

View File

@@ -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;

View File

@@ -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(); }

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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 =

View File

@@ -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);

View File

@@ -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)

View File

@@ -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