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; return m_aircraftSupportingParts;
} }
bool CAirspaceMonitor::connectRemoteAircraftProviderSignals( QList<QMetaObject::Connection> CAirspaceMonitor::connectRemoteAircraftProviderSignals(
std::function<void(const CAircraftSituation &)> situationSlot, std::function<void(const CAircraftSituation &)> situationSlot,
std::function<void(const CAircraftParts &)> partsSlot, std::function<void(const CAircraftParts &)> partsSlot,
std::function<void(const CCallsign &)> removedAircraftSlot, std::function<void(const CCallsign &)> removedAircraftSlot,
std::function<void(const CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot std::function<void(const CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot
) )
{ {
bool s1 = connect(this, &CAirspaceMonitor::addedAircraftSituation, situationSlot); QMetaObject::Connection c1 = connect(this, &CAirspaceMonitor::addedAircraftSituation, situationSlot);
Q_ASSERT(s1); Q_ASSERT(c1);
bool s2 = connect(this, &CAirspaceMonitor::addedAircraftParts, partsSlot); QMetaObject::Connection c2 = connect(this, &CAirspaceMonitor::addedAircraftParts, partsSlot);
Q_ASSERT(s2); Q_ASSERT(c2);
bool s3 = connect(this, &CAirspaceMonitor::removedAircraft, removedAircraftSlot); QMetaObject::Connection c3 = connect(this, &CAirspaceMonitor::removedAircraft, removedAircraftSlot);
Q_ASSERT(s3); Q_ASSERT(c3);
bool s4 = connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, aircraftSnapshotSlot); QMetaObject::Connection c4 = this->connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, aircraftSnapshotSlot);
Q_ASSERT(s4); Q_ASSERT(c4);
return QList<QMetaObject::Connection>({ c1, c2, c3, c4});
return s1 && s2 && s3 && s4;
}
bool CAirspaceMonitor::disconnectRemoteAircraftProviderSignals(QObject *receiver)
{
if (!receiver) { return false; }
return this->disconnect(receiver);
} }
bool CAirspaceMonitor::updateAircraftEnabled(const CCallsign &callsign, bool enabledForRedering, const QString &originator) 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); void testAddAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts, bool incremental);
//! \copydoc IRemoteAircraftProvider::connectRemoteAircraftProviderSignals //! \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::CAircraftSituation &)> addedSituationSlot,
std::function<void(const BlackMisc::Aviation::CAircraftParts &)> addedPartsSlot, std::function<void(const BlackMisc::Aviation::CAircraftParts &)> addedPartsSlot,
std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot, std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot,
std::function<void(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot std::function<void(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot
) override; ) override;
//! \copydoc IRemoteAircraftProvider::disconnectRemoteAircraftProviderSignals
virtual bool disconnectRemoteAircraftProviderSignals(QObject *receiver) override;
//! Is interim position sending enabled? //! Is interim position sending enabled?
bool isFastPositionSendingEnabled() const; bool isFastPositionSendingEnabled() const;

View File

@@ -135,7 +135,7 @@ namespace BlackCore
return m_airspace->remoteAircraftSupportingParts(); return m_airspace->remoteAircraftSupportingParts();
} }
bool CContextNetwork::connectRemoteAircraftProviderSignals( QList<QMetaObject::Connection> CContextNetwork::connectRemoteAircraftProviderSignals(
std::function<void (const CAircraftSituation &)> situationSlot, std::function<void (const CAircraftSituation &)> situationSlot,
std::function<void (const CAircraftParts &)> partsSlot, std::function<void (const CAircraftParts &)> partsSlot,
std::function<void (const CCallsign &)> removedAircraftSlot, std::function<void (const CCallsign &)> removedAircraftSlot,
@@ -145,12 +145,6 @@ namespace BlackCore
return this->m_airspace->connectRemoteAircraftProviderSignals(situationSlot, partsSlot, removedAircraftSlot, aircraftSnapshotSlot); 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() void CContextNetwork::gracefulShutdown()
{ {
if (this->m_vatsimBookingReader) { this->m_vatsimBookingReader->requestStop(); this->m_vatsimBookingReader->quit(); } if (this->m_vatsimBookingReader) { this->m_vatsimBookingReader->requestStop(); this->m_vatsimBookingReader->quit(); }

View File

@@ -74,17 +74,13 @@ namespace BlackCore
//! \copydoc IRemoteAircraftProvider::connectSignals //! \copydoc IRemoteAircraftProvider::connectSignals
//! \ingroup remoteaircraftprovider //! \ingroup remoteaircraftprovider
virtual bool connectRemoteAircraftProviderSignals( virtual QList<QMetaObject::Connection> connectRemoteAircraftProviderSignals(
std::function<void(const BlackMisc::Aviation::CAircraftSituation &)> addedSituationSlot, std::function<void(const BlackMisc::Aviation::CAircraftSituation &)> addedSituationSlot,
std::function<void(const BlackMisc::Aviation::CAircraftParts &)> addedPartsSlot, std::function<void(const BlackMisc::Aviation::CAircraftParts &)> addedPartsSlot,
std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot, std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot,
std::function<void(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot std::function<void(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot
) override; ) override;
//! \copydoc IRemoteAircraftProvider::disconnectRemoteAircraftProviderSignals
//! \ingroup remoteaircraftprovider
virtual bool disconnectRemoteAircraftProviderSignals(QObject *receiver) override;
//! \copydoc IRemoteAircraftProvider::updateAircraftRendered //! \copydoc IRemoteAircraftProvider::updateAircraftRendered
//! \ingroup remoteaircraftprovider //! \ingroup remoteaircraftprovider
virtual bool updateAircraftRendered(const BlackMisc::Aviation::CCallsign &callsign, bool rendered, const QString &originator) override; 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); bool parseCommandLine(const QString commandLine, const QString &originator);
private: private:
bool m_init = false; /*!< flag */ bool m_init = false; //!< flag
// DBus // DBus
CDBusServer *m_dbusServer = nullptr; CDBusServer *m_dbusServer = nullptr;

View File

@@ -542,16 +542,10 @@ namespace BlackCore
Q_ASSERT(this->getIContextNetwork()->isLocalObject()); Q_ASSERT(this->getIContextNetwork()->isLocalObject());
Q_ASSERT(m_simulatorPlugin->simulator); Q_ASSERT(m_simulatorPlugin->simulator);
// disconnect from simulator // unload and disconnect
if (m_simulatorPlugin->simulator->isConnected()) m_simulatorPlugin->simulator->unload();
{
m_simulatorPlugin->simulator->disconnectFrom();
}
// disconnect signals // disconnect signals
this->getRuntime()->getCContextNetwork()->disconnectRemoteAircraftProviderSignals(m_simulatorPlugin->simulator);
m_simulatorPlugin->simulator->disconnect();
CLogHandler::instance()->disconnect(m_simulatorPlugin->simulator);
this->disconnect(m_simulatorPlugin->simulator); this->disconnect(m_simulatorPlugin->simulator);
m_simulatorPlugin->simulator->deleteLater(); m_simulatorPlugin->simulator->deleteLater();
@@ -599,8 +593,15 @@ namespace BlackCore
if (!(status & ISimulator::Connected)) if (!(status & ISimulator::Connected))
{ {
// we got disconnected
unloadSimulatorPlugin(); 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); emit simulatorStatusChanged(status);
} }

View File

@@ -28,6 +28,22 @@ namespace BlackCore
return o; 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() void ISimulator::emitSimulatorCombinedStatus()
{ {
int status = int status =

View File

@@ -45,7 +45,7 @@ namespace BlackCore
Paused = 1 << 2, //!< Is the simulator paused? Paused = 1 << 2, //!< Is the simulator paused?
}; };
//! Render all aircraft //! Render all aircraft if number of aircraft >= MaxAircraftInfinite
const int MaxAircraftInfinite = 100; const int MaxAircraftInfinite = 100;
//! Destructor //! Destructor
@@ -174,9 +174,15 @@ namespace BlackCore
//! Highlight the aircraft for given time (or disable highlight) //! 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; 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 //! Originator
const QString &simulatorOriginator(); const QString &simulatorOriginator();
//! Status to string
static QString statusToString(int status);
signals: signals:
//! Simulator combined status //! Simulator combined status
void simulatorStatusChanged(int status); void simulatorStatusChanged(int status);

View File

@@ -11,6 +11,7 @@
#include "blackcore/interpolator.h" #include "blackcore/interpolator.h"
#include "blackcore/blackcorefreefunctions.h" #include "blackcore/blackcorefreefunctions.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include "blackmisc/loghandler.h"
#include "blackmisc/collection.h" #include "blackmisc/collection.h"
using namespace BlackMisc; using namespace BlackMisc;
@@ -31,24 +32,25 @@ namespace BlackCore
m_simulatorPluginInfo(info) m_simulatorPluginInfo(info)
{ {
this->setObjectName(info.getIdentifier()); 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")); this->m_oneSecondTimer.setObjectName(this->objectName().append(":m_oneSecondTimer"));
connect(&m_oneSecondTimer, &QTimer::timeout, this, &CSimulatorCommon::ps_oneSecondTimer); connect(&m_oneSecondTimer, &QTimer::timeout, this, &CSimulatorCommon::ps_oneSecondTimer);
this->m_oneSecondTimer.start(1000); 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 // info
CLogMessage(this).info("Initialized simulator driver %1") << m_simulatorPluginInfo.toQString(); CLogMessage(this).info("Initialized simulator driver %1") << m_simulatorPluginInfo.toQString();
} }
CSimulatorCommon::~CSimulatorCommon() { }
bool CSimulatorCommon::logicallyAddRemoteAircraft(const CSimulatedAircraft &remoteAircraft) bool CSimulatorCommon::logicallyAddRemoteAircraft(const CSimulatedAircraft &remoteAircraft)
{ {
if (!remoteAircraft.isEnabled()) { return false; } if (!remoteAircraft.isEnabled()) { return false; }
@@ -195,6 +197,18 @@ namespace BlackCore
return m_simulatorSetup; 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 CLength CSimulatorCommon::getRenderedDistanceBoundary() const
{ {
return CLength(20.0, CLengthUnit::NM()); return CLength(20.0, CLengthUnit::NM());
@@ -282,31 +296,32 @@ namespace BlackCore
// when changing back from restricted->unrestricted an one time update is required // when changing back from restricted->unrestricted an one time update is required
if (!snapshot.isRestricted() && !snapshot.isRestrictionChanged()) { return; } if (!snapshot.isRestricted() && !snapshot.isRestrictionChanged()) { return; }
// we will handle snapshot // restricted snapshot values?
emit airspaceSnapshotHandled(); if (snapshot.isRenderingEnabled())
// restricted snapshot values
if (!snapshot.isRenderingEnabled())
{ {
this->physicallyRemoveAllRemoteAircraft(); CCallsignSet callsignsInSimulator(physicallyRenderedAircraft());
return; CCallsignSet callsignsToBeRemoved(callsignsInSimulator.difference(snapshot.getEnabledAircraftCallsignsByDistance()));
} CCallsignSet callsignsToBeAdded(snapshot.getEnabledAircraftCallsignsByDistance().difference(callsignsInSimulator));
this->physicallyRemoveMultipleRemoteAircraft(callsignsToBeRemoved);
CCallsignSet callsignsInSimulator(physicallyRenderedAircraft()); if (!callsignsToBeAdded.isEmpty())
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"); CSimulatedAircraftList aircraftToBeAdded(getAircraftInRange().findByCallsigns(callsignsToBeAdded)); // thread safe copy
this->physicallyAddRemoteAircraft(aircraft); 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) void CSimulatorCommon::ps_remoteProviderAddAircraftSituation(const CAircraftSituation &situation)

View File

@@ -41,6 +41,9 @@ namespace BlackCore
Q_OBJECT Q_OBJECT
public: public:
//! Destructor
virtual ~CSimulatorCommon();
//! \copydoc ISimulator::getMaxRenderedAircraft //! \copydoc ISimulator::getMaxRenderedAircraft
virtual int getMaxRenderedAircraft() const override; virtual int getMaxRenderedAircraft() const override;
@@ -83,6 +86,9 @@ namespace BlackCore
//! \copydoc IContextSimulator::getSimulatorSetup //! \copydoc IContextSimulator::getSimulatorSetup
virtual const BlackMisc::Simulation::CSimulatorSetup &getSimulatorSetup() const override; virtual const BlackMisc::Simulation::CSimulatorSetup &getSimulatorSetup() const override;
//! \copydoc IContextSimulator::unload
virtual void unload();
//! \copydoc IContextSimulator::deleteAllRenderingRestrictions //! \copydoc IContextSimulator::deleteAllRenderingRestrictions
virtual void deleteAllRenderingRestrictions() override; virtual void deleteAllRenderingRestrictions() override;
@@ -132,6 +138,7 @@ namespace BlackCore
bool m_debugMessages = false; //!< Display debug messages bool m_debugMessages = false; //!< Display debug messages
bool m_blinkCycle = false; //!< use for highlighting 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 IInterpolator *m_interpolator = nullptr; //!< interpolator instance
qint64 m_highlightEndTimeMsEpoch = 0; //!< end highlighting qint64 m_highlightEndTimeMsEpoch = 0; //!< end highlighting
int m_timerCounter = 0; //!< allows to calculate n seconds 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 BlackMisc::Aviation::CCallsignSet m_callsignsToBeRendered; //!< callsigns which will be rendered
int m_maxRenderedAircraft = MaxAircraftInfinite; //!< max.rendered aircraft int m_maxRenderedAircraft = MaxAircraftInfinite; //!< max.rendered aircraft
BlackMisc::PhysicalQuantities::CLength m_maxRenderedDistance { 0.0, BlackMisc::PhysicalQuantities::CLengthUnit::nullUnit()}; //!< max.distance for rendering BlackMisc::PhysicalQuantities::CLength m_maxRenderedDistance { 0.0, BlackMisc::PhysicalQuantities::CLengthUnit::nullUnit()}; //!< max.distance for rendering
QList<QMetaObject::Connection> m_remoteAircraftProviderConnections; //!< connected signal/slots
}; };
} // namespace } // namespace

View File

@@ -100,17 +100,14 @@ namespace BlackMisc
virtual ~IRemoteAircraftProvider() {} virtual ~IRemoteAircraftProvider() {}
//! Connect signals to slot receiver. As the interface is no QObject, slots can not be connected directly. //! Connect signals to slot receiver. As the interface is no QObject, slots can not be connected directly.
virtual bool connectRemoteAircraftProviderSignals( //! In order to disconnect a list of connections is provided, which have to be disconnected manually.
//! \note connections are direct as functors have no parameter for connection type
virtual QList<QMetaObject::Connection> connectRemoteAircraftProviderSignals(
std::function<void(const BlackMisc::Aviation::CAircraftSituation &)> addedSituationSlot, std::function<void(const BlackMisc::Aviation::CAircraftSituation &)> addedSituationSlot,
std::function<void(const BlackMisc::Aviation::CAircraftParts &)> addedPartsSlot, std::function<void(const BlackMisc::Aviation::CAircraftParts &)> addedPartsSlot,
std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot, std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot,
std::function<void(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &)> aircraftSnapshot std::function<void(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &)> aircraftSnapshot
) = 0; ) = 0;
//! Disconnect signals from receiver. As the interface is no QObject, slots can not be connected directly.
virtual bool disconnectRemoteAircraftProviderSignals(
QObject *receiver
) = 0;
}; };
//! Class which can be directly used to access an \sa IRemoteAircraftProvider object //! Class which can be directly used to access an \sa IRemoteAircraftProvider object

View File

@@ -65,25 +65,21 @@ namespace BlackMisc
return remoteAircraftParts(callsign).size() > 0; return remoteAircraftParts(callsign).size() > 0;
} }
bool CRemoteAircraftProviderDummy::connectRemoteAircraftProviderSignals( QList<QMetaObject::Connection> CRemoteAircraftProviderDummy::connectRemoteAircraftProviderSignals(
std::function<void (const CAircraftSituation &)> situationSlot, std::function<void (const CAircraftSituation &)> situationSlot,
std::function<void (const CAircraftParts &)> partsSlot, std::function<void (const CAircraftParts &)> partsSlot,
std::function<void (const CCallsign &)> removedAircraftSlot, std::function<void (const CCallsign &)> removedAircraftSlot,
std::function<void (const CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot std::function<void (const CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot
) )
{ {
bool s1 = connect(this, &CRemoteAircraftProviderDummy::addedRemoteAircraftSituation, situationSlot); QList<QMetaObject::Connection> c(
bool s2 = connect(this, &CRemoteAircraftProviderDummy::addedRemoteAircraftParts, partsSlot); {
bool s3 = connect(this, &CRemoteAircraftProviderDummy::removedRemoteAircraft, removedAircraftSlot); connect(this, &CRemoteAircraftProviderDummy::addedRemoteAircraftSituation, situationSlot) ,
bool s4 = connect(this, &CRemoteAircraftProviderDummy::airspaceAircraftSnapshot, aircraftSnapshotSlot); connect(this, &CRemoteAircraftProviderDummy::addedRemoteAircraftParts, partsSlot) ,
connect(this, &CRemoteAircraftProviderDummy::removedRemoteAircraft, removedAircraftSlot) ,
return s1 && s2 && s3 && s4; connect(this, &CRemoteAircraftProviderDummy::airspaceAircraftSnapshot, aircraftSnapshotSlot)
} });
return c;
bool CRemoteAircraftProviderDummy::disconnectRemoteAircraftProviderSignals(QObject *receiver)
{
if (!receiver) { return false; }
return this->disconnect(receiver);
} }
bool CRemoteAircraftProviderDummy::updateAircraftEnabled(const CCallsign &callsign, bool enabledForRendering, const QString &originator) bool CRemoteAircraftProviderDummy::updateAircraftEnabled(const CCallsign &callsign, bool enabledForRendering, const QString &originator)

View File

@@ -60,16 +60,13 @@ namespace BlackMisc
virtual bool isRemoteAircraftSupportingParts(const Aviation::CCallsign &callsign) const override; virtual bool isRemoteAircraftSupportingParts(const Aviation::CCallsign &callsign) const override;
//! \copydoc IRemoteAircraftProvider::connectRemoteAircraftProviderSignals //! \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::CAircraftSituation &)> addedSituationSlot,
std::function<void(const BlackMisc::Aviation::CAircraftParts &)> addedPartsSlot, std::function<void(const BlackMisc::Aviation::CAircraftParts &)> addedPartsSlot,
std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot, std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot,
std::function<void(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot std::function<void(const BlackMisc::Simulation::CAirspaceAircraftSnapshot &)> aircraftSnapshotSlot
) override; ) override;
//! \copydoc IRemoteAircraftProvider::disconnectRemoteAircraftProviderSignals
virtual bool disconnectRemoteAircraftProviderSignals(QObject *receiver) override;
//! \copydoc IRemoteAircraftProvider::updateAircraftEnabled //! \copydoc IRemoteAircraftProvider::updateAircraftEnabled
virtual bool updateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRendering, const QString &originator) override; virtual bool updateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRendering, const QString &originator) override;

View File

@@ -56,6 +56,7 @@ namespace BlackSimPlugin
CSimulatorFsx::~CSimulatorFsx() CSimulatorFsx::~CSimulatorFsx()
{ {
disconnectFrom(); disconnectFrom();
// fsuipc is disconnected in CSimulatorFsCommon
} }
bool CSimulatorFsx::isConnected() const bool CSimulatorFsx::isConnected() const
@@ -168,7 +169,7 @@ namespace BlackSimPlugin
emit modelMatchingCompleted(aircraftAfterModelApplied); emit modelMatchingCompleted(aircraftAfterModelApplied);
// create AI // create AI
if (isSimulating()) if (isConnected())
{ {
//! \todo FSX driver if exists, recreate (new model?, new ICAO code) //! \todo FSX driver if exists, recreate (new model?, new ICAO code)
QByteArray m = aircraftModel.getModelString().toLocal8Bit(); QByteArray m = aircraftModel.getModelString().toLocal8Bit();
@@ -304,7 +305,9 @@ namespace BlackSimPlugin
void CSimulatorFsx::onSimRunning() void CSimulatorFsx::onSimRunning()
{ {
if (m_simRunning) { return; } if (m_simRunning) { return; }
m_simRunning = true; qDebug() << "onSimRunning";
m_simRunning = true; // only place where this should be set to true
m_simConnected = true;
HRESULT hr = SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraft, HRESULT hr = SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraft,
CSimConnectDefinitions::DataOwnAircraft, CSimConnectDefinitions::DataOwnAircraft,
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME);
@@ -340,11 +343,7 @@ namespace BlackSimPlugin
void CSimulatorFsx::onSimStopped() void CSimulatorFsx::onSimStopped()
{ {
if (m_simRunning) m_simRunning = false;
{
m_simRunning = false;
mapperInstance()->gracefulShutdown(); // stop background reading if ongoing
}
emitSimulatorCombinedStatus(); emitSimulatorCombinedStatus();
} }
@@ -355,8 +354,14 @@ namespace BlackSimPlugin
void CSimulatorFsx::onSimExit() void CSimulatorFsx::onSimExit()
{ {
// reset complete state, we are going down
m_simConnected = false; m_simConnected = false;
this->onSimStopped(); m_simRunning = false;
m_simPaused = false;
// stop background reading if ongoing
mapperInstance()->gracefulShutdown();
emitSimulatorCombinedStatus();
} }
void CSimulatorFsx::updateOwnAircraftFromSimulator(DataDefinitionOwnAircraft simulatorOwnAircraft) void CSimulatorFsx::updateOwnAircraftFromSimulator(DataDefinitionOwnAircraft simulatorOwnAircraft)
@@ -503,12 +508,13 @@ namespace BlackSimPlugin
initDataDefinitionsWhenConnected(); initDataDefinitionsWhenConnected();
m_simconnectTimerId = startTimer(10); m_simconnectTimerId = startTimer(10);
m_simConnected = true; m_simConnected = true;
emitSimulatorCombinedStatus(); emitSimulatorCombinedStatus();
} }
else else
{ {
if (m_simconnectTimerId >= 0) { killTimer(m_simconnectTimerId); }
m_simConnected = false; m_simConnected = false;
m_simRunning = false;
emitSimulatorCombinedStatus(); emitSimulatorCombinedStatus();
} }
} }
@@ -549,6 +555,7 @@ namespace BlackSimPlugin
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventObjectRemoved, "ObjectRemoved"); hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventObjectRemoved, "ObjectRemoved");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventFrame, "Frame"); hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventFrame, "Frame");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventPause, "Pause"); hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventPause, "Pause");
hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventFlightLoaded, "FlightLoaded");
if (hr != S_OK) if (hr != S_OK)
{ {
CLogMessage(this).error("FSX plugin error: %1") << "SimConnect_SubscribeToSystemEvent failed"; CLogMessage(this).error("FSX plugin error: %1") << "SimConnect_SubscribeToSystemEvent failed";
@@ -624,7 +631,7 @@ namespace BlackSimPlugin
Q_ASSERT_X(BlackCore::isCurrentThreadCreatingThread(this), Q_FUNC_INFO, "thread"); Q_ASSERT_X(BlackCore::isCurrentThreadCreatingThread(this), Q_FUNC_INFO, "thread");
// nothing to do, reset request id and exit // nothing to do, reset request id and exit
if (this->isPaused()) { return; } // no interpolation while paused if (this->isPaused() && this->m_pausedSimFreezesInterpolation) { return; } // no interpolation while paused
int remoteAircraftNo = this->getAircraftInRangeCount(); int remoteAircraftNo = this->getAircraftInRangeCount();
if (remoteAircraftNo < 1) { m_interpolationRequest = 0; return; } if (remoteAircraftNo < 1) { m_interpolationRequest = 0; return; }

View File

@@ -49,6 +49,7 @@ namespace BlackSimPlugin
SystemEventSlewToggle, SystemEventSlewToggle,
SystemEventFrame, SystemEventFrame,
SystemEventPause, SystemEventPause,
SystemEventFlightLoaded,
EventPauseToggle, EventPauseToggle,
EventFreezeLat, EventFreezeLat,
EventFreezeAlt, EventFreezeAlt,
@@ -127,15 +128,6 @@ namespace BlackSimPlugin
//! \copydoc ISimulator::physicallyRenderedAircraft //! \copydoc ISimulator::physicallyRenderedAircraft
virtual BlackMisc::Aviation::CCallsignSet physicallyRenderedAircraft() const override; virtual BlackMisc::Aviation::CCallsignSet physicallyRenderedAircraft() const override;
//! Called when sim has started
void onSimRunning();
//! Called when sim has stopped
void onSimStopped();
//! Slot called every visual frame
void onSimFrame();
//! Called when data about our own aircraft are received //! Called when data about our own aircraft are received
void updateOwnAircraftFromSimulator(DataDefinitionOwnAircraft simulatorOwnAircraft); void updateOwnAircraftFromSimulator(DataDefinitionOwnAircraft simulatorOwnAircraft);
@@ -145,9 +137,6 @@ namespace BlackSimPlugin
//! Set ID of a SimConnect object //! Set ID of a SimConnect object
void setSimConnectObjectID(DWORD requestID, DWORD objectID); void setSimConnectObjectID(DWORD requestID, DWORD objectID);
//! \private
void onSimExit();
protected: protected:
//! Timer event (our SimConnect event loop), runs \sa ps_dispatch //! Timer event (our SimConnect event loop), runs \sa ps_dispatch
//! \sa m_simconnectTimerId //! \sa m_simconnectTimerId
@@ -161,6 +150,18 @@ namespace BlackSimPlugin
void ps_connectToFinished(); void ps_connectToFinished();
private: private:
//! Called when sim has started
void onSimRunning();
//! Slot called every visual frame
void onSimFrame();
//! Called when simulator has stopped, e.g. by selecting the "select aircraft screen"
void onSimStopped();
//! Simulator is going down
void onSimExit();
//! Remove a remote aircraft //! Remove a remote aircraft
bool physicallyRemoveRemoteAircraft(const CSimConnectObject &simObject); bool physicallyRemoveRemoteAircraft(const CSimConnectObject &simObject);

View File

@@ -60,18 +60,18 @@ namespace BlackSimPlugin
} }
case SIMCONNECT_RECV_ID_QUIT: case SIMCONNECT_RECV_ID_QUIT:
{ {
simulatorFsx->onSimExit(); // TODO: What is the difference to sim stopped? simulatorFsx->onSimExit();
break; break;
} }
case SIMCONNECT_RECV_ID_EVENT: case SIMCONNECT_RECV_ID_EVENT:
{ {
SIMCONNECT_RECV_EVENT *event = static_cast<SIMCONNECT_RECV_EVENT *>(pData); SIMCONNECT_RECV_EVENT *event = static_cast<SIMCONNECT_RECV_EVENT *>(pData);
switch (event->uEventID) switch (event->uEventID)
{ {
case SystemEventSimStatus: case SystemEventSimStatus:
{ {
if (event->dwData) bool running = event->dwData ? true : false;
if (running)
{ {
simulatorFsx->onSimRunning(); simulatorFsx->onSimRunning();
} }
@@ -83,22 +83,27 @@ namespace BlackSimPlugin
} }
case SystemEventPause: case SystemEventPause:
{ {
simulatorFsx->m_simPaused = event->dwData ? true : false; bool p = event->dwData ? true : false;
simulatorFsx->m_simPaused = p;
simulatorFsx->emitSimulatorCombinedStatus();
break; break;
} }
default:
break;
} }
break; break;
} }
case SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE: case SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE:
{ {
SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *event = static_cast<SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *>(pData); SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *event = static_cast<SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *>(pData);
if (event->uEventID == SystemEventObjectAdded) switch (event->uEventID)
{ {
// case SystemEventObjectAdded:
} break;
else if (event->uEventID == SystemEventObjectRemoved) case SystemEventObjectRemoved:
{ break;
// default:
break;
} }
break; break;
} }
@@ -171,7 +176,7 @@ namespace BlackSimPlugin
for (unsigned i = 0; i < pAirportList->dwArraySize; ++i) for (unsigned i = 0; i < pAirportList->dwArraySize; ++i)
{ {
SIMCONNECT_DATA_FACILITY_AIRPORT *pFacilityAirport = pAirportList->rgData + i; SIMCONNECT_DATA_FACILITY_AIRPORT *pFacilityAirport = pAirportList->rgData + i;
if (!pFacilityAirport) break; if (!pFacilityAirport) { break; }
const QString icao(pFacilityAirport->Icao); const QString icao(pFacilityAirport->Icao);
if (icao.isEmpty()) { continue; } // airfield without ICAO code if (icao.isEmpty()) { continue; } // airfield without ICAO code
if (!CAirportIcaoCode::isValidIcaoDesignator(icao)) { continue; } // tiny airfields in SIM if (!CAirportIcaoCode::isValidIcaoDesignator(icao)) { continue; } // tiny airfields in SIM
@@ -200,6 +205,18 @@ namespace BlackSimPlugin
} }
break; break;
} }
case SIMCONNECT_RECV_ID_EVENT_FILENAME:
{
SIMCONNECT_RECV_EVENT_FILENAME *event = static_cast<SIMCONNECT_RECV_EVENT_FILENAME *>(pData);
switch (event->uEventID)
{
case SystemEventFlightLoaded:
break;
default:
break;
}
break;
}
default: default:
break; break;