Improvements during shutdown

* stop listeners
* check if airspace monitor and FSD still exist
* stop listeners on "aboutToShutdown()"
* check for processEventsFor(500)
This commit is contained in:
Klaus Basan
2020-04-20 20:45:36 +02:00
committed by Mat Sutcliffe
parent 95ca63ce6d
commit 9235f3232e
6 changed files with 139 additions and 38 deletions

View File

@@ -126,8 +126,8 @@ namespace BlackCore
void CContextNetwork::setSimulationEnvironmentProvider(ISimulationEnvironmentProvider *provider) void CContextNetwork::setSimulationEnvironmentProvider(ISimulationEnvironmentProvider *provider)
{ {
if (m_airspace) { m_airspace->setSimulationEnvironmentProvider(provider); } if (this->canUseAirspaceMonitor()) { m_airspace->setSimulationEnvironmentProvider(provider); }
if (m_fsdClient) { m_fsdClient->setSimulationEnvironmentProvider(provider); } if (this->canUseFsd()) { m_fsdClient->setSimulationEnvironmentProvider(provider); }
} }
CContextNetwork::~CContextNetwork() CContextNetwork::~CContextNetwork()
@@ -137,25 +137,25 @@ namespace BlackCore
CAircraftSituationList CContextNetwork::remoteAircraftSituations(const CCallsign &callsign) const CAircraftSituationList CContextNetwork::remoteAircraftSituations(const CCallsign &callsign) const
{ {
Q_ASSERT(m_airspace); if (!this->canUseAirspaceMonitor()) { return {}; }
return m_airspace->remoteAircraftSituations(callsign); return m_airspace->remoteAircraftSituations(callsign);
} }
CAircraftSituation CContextNetwork::remoteAircraftSituation(const Aviation::CCallsign &callsign, int index) const CAircraftSituation CContextNetwork::remoteAircraftSituation(const Aviation::CCallsign &callsign, int index) const
{ {
Q_ASSERT(m_airspace); if (!this->canUseAirspaceMonitor()) { return {}; }
return m_airspace->remoteAircraftSituation(callsign, index); return m_airspace->remoteAircraftSituation(callsign, index);
} }
MillisecondsMinMaxMean CContextNetwork::remoteAircraftSituationsTimestampDifferenceMinMaxMean(const CCallsign &callsign) const MillisecondsMinMaxMean CContextNetwork::remoteAircraftSituationsTimestampDifferenceMinMaxMean(const CCallsign &callsign) const
{ {
Q_ASSERT(m_airspace); if (!this->canUseAirspaceMonitor()) { return {}; }
return m_airspace->remoteAircraftSituationsTimestampDifferenceMinMaxMean(callsign); return m_airspace->remoteAircraftSituationsTimestampDifferenceMinMaxMean(callsign);
} }
CAircraftSituationList CContextNetwork::latestRemoteAircraftSituations() const CAircraftSituationList CContextNetwork::latestRemoteAircraftSituations() const
{ {
Q_ASSERT(m_airspace); if (!this->canUseAirspaceMonitor()) { return {}; }
return m_airspace->latestRemoteAircraftSituations(); return m_airspace->latestRemoteAircraftSituations();
} }
@@ -167,43 +167,43 @@ namespace BlackCore
CAircraftPartsList CContextNetwork::remoteAircraftParts(const CCallsign &callsign) const CAircraftPartsList CContextNetwork::remoteAircraftParts(const CCallsign &callsign) const
{ {
Q_ASSERT(m_airspace); if (!this->canUseAirspaceMonitor()) { return {}; }
return m_airspace->remoteAircraftParts(callsign); return m_airspace->remoteAircraftParts(callsign);
} }
int CContextNetwork::remoteAircraftPartsCount(const CCallsign &callsign) const int CContextNetwork::remoteAircraftPartsCount(const CCallsign &callsign) const
{ {
Q_ASSERT(m_airspace); if (!this->canUseAirspaceMonitor()) { return 0; }
return m_airspace->remoteAircraftPartsCount(callsign); return m_airspace->remoteAircraftPartsCount(callsign);
} }
int CContextNetwork::remoteAircraftSituationsCount(const CCallsign &callsign) const int CContextNetwork::remoteAircraftSituationsCount(const CCallsign &callsign) const
{ {
Q_ASSERT(m_airspace); if (!this->canUseAirspaceMonitor()) { return 0; }
return m_airspace->remoteAircraftSituationsCount(callsign); return m_airspace->remoteAircraftSituationsCount(callsign);
} }
bool CContextNetwork::isRemoteAircraftSupportingParts(const CCallsign &callsign) const bool CContextNetwork::isRemoteAircraftSupportingParts(const CCallsign &callsign) const
{ {
Q_ASSERT(m_airspace); if (!this->canUseAirspaceMonitor()) { return false; }
return m_airspace->isRemoteAircraftSupportingParts(callsign); return m_airspace->isRemoteAircraftSupportingParts(callsign);
} }
CCallsignSet CContextNetwork::remoteAircraftSupportingParts() const CCallsignSet CContextNetwork::remoteAircraftSupportingParts() const
{ {
Q_ASSERT(m_airspace); if (!this->canUseAirspaceMonitor()) { return {}; }
return m_airspace->remoteAircraftSupportingParts(); return m_airspace->remoteAircraftSupportingParts();
} }
Aviation::CAircraftSituationChangeList CContextNetwork::remoteAircraftSituationChanges(const CCallsign &callsign) const CAircraftSituationChangeList CContextNetwork::remoteAircraftSituationChanges(const CCallsign &callsign) const
{ {
Q_ASSERT(m_airspace); if (!this->canUseAirspaceMonitor()) { return {}; }
return m_airspace->remoteAircraftSituationChanges(callsign); return m_airspace->remoteAircraftSituationChanges(callsign);
} }
int CContextNetwork::remoteAircraftSituationChangesCount(const CCallsign &callsign) const int CContextNetwork::remoteAircraftSituationChangesCount(const CCallsign &callsign) const
{ {
Q_ASSERT(m_airspace); if (!this->canUseAirspaceMonitor()) { return {}; }
return m_airspace->remoteAircraftSituationChangesCount(callsign); return m_airspace->remoteAircraftSituationChangesCount(callsign);
} }
@@ -222,17 +222,27 @@ namespace BlackCore
{ {
this->disconnect(); // all signals this->disconnect(); // all signals
if (this->isConnected()) { this->disconnectFromNetwork(); } if (this->isConnected()) { this->disconnectFromNetwork(); }
if (m_airspace) { m_airspace->gracefulShutdown(); }
if (m_fsdClient) if (m_fsdClient)
{ {
m_fsdClient->gracefulShutdown(); m_fsdClient->gracefulShutdown();
m_fsdClient->setClientProvider(nullptr); m_fsdClient->setClientProvider(nullptr);
m_fsdClient->deleteLater();
m_fsdClient = nullptr;
}
if (m_airspace)
{
m_airspace->gracefulShutdown();
m_airspace->deleteLater();
m_airspace = nullptr;
} }
} }
CStatusMessage CContextNetwork::connectToNetwork(const CServer &server, const QString &extraLiveryString, bool sendLivery, const QString &extraModelString, bool sendModelString, const CCallsign &partnerCallsign, CLoginMode mode) CStatusMessage CContextNetwork::connectToNetwork(const CServer &server, const QString &extraLiveryString, bool sendLivery, const QString &extraModelString, bool sendModelString, const CCallsign &partnerCallsign, CLoginMode mode)
{ {
if (!this->canUseFsd()) { return { CStatusMessage({ CLogCategory::validation() }, CStatusMessage::SeverityInfo, u"Invalid FSD state (shutdown)") }; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
QString msg; QString msg;
if (!server.getUser().hasCredentials()) { return CStatusMessage({ CLogCategory::validation() }, CStatusMessage::SeverityError, u"Invalid user credentials"); } if (!server.getUser().hasCredentials()) { return CStatusMessage({ CLogCategory::validation() }, CStatusMessage::SeverityError, u"Invalid user credentials"); }
if (!this->ownAircraft().getAircraftIcaoCode().hasDesignator()) { return CStatusMessage({ CLogCategory::validation() }, CStatusMessage::SeverityError, u"Invalid ICAO data for own aircraft"); } if (!this->ownAircraft().getAircraftIcaoCode().hasDesignator()) { return CStatusMessage({ CLogCategory::validation() }, CStatusMessage::SeverityError, u"Invalid ICAO data for own aircraft"); }
@@ -295,17 +305,20 @@ namespace BlackCore
CServer CContextNetwork::getConnectedServer() const CServer CContextNetwork::getConnectedServer() const
{ {
if (!this->canUseFsd()) { return {}; }
return this->isConnected() ? m_fsdClient->getServer() : CServer(); return this->isConnected() ? m_fsdClient->getServer() : CServer();
} }
CLoginMode CContextNetwork::getLoginMode() const CLoginMode CContextNetwork::getLoginMode() const
{ {
if (!this->canUseFsd()) { return {}; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
return m_fsdClient->getLoginMode(); return m_fsdClient->getLoginMode();
} }
CStatusMessage CContextNetwork::disconnectFromNetwork() CStatusMessage CContextNetwork::disconnectFromNetwork()
{ {
if (!this->canUseFsd()) { return { CStatusMessage({ CLogCategory::validation() }, CStatusMessage::SeverityInfo, u"Invalid FSD state (shutdown)") }; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
if (m_fsdClient->isConnected() || m_fsdClient->isPendingConnection()) if (m_fsdClient->isConnected() || m_fsdClient->isPendingConnection())
{ {
@@ -320,19 +333,25 @@ namespace BlackCore
bool CContextNetwork::isConnected() const bool CContextNetwork::isConnected() const
{ {
if (!this->canUseFsd()) { return false; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
return m_fsdClient->isConnected(); return m_fsdClient->isConnected();
} }
bool CContextNetwork::isPendingConnection() const bool CContextNetwork::isPendingConnection() const
{ {
if (!this->canUseFsd()) { return false; }
return m_fsdClient->isPendingConnection(); return m_fsdClient->isPendingConnection();
} }
bool CContextNetwork::parseCommandLine(const QString &commandLine, const CIdentifier &originator) bool CContextNetwork::parseCommandLine(const QString &commandLine, const CIdentifier &originator)
{ {
Q_UNUSED(originator;) Q_UNUSED(originator;)
if (!this->canUseAirspaceMonitor()) { return false; }
if (!this->canUseFsd()) { return false; }
if (commandLine.isEmpty()) { return false; } if (commandLine.isEmpty()) { return false; }
static const QStringList cmds({ ".msg", ".m", ".chat", ".altos", ".altoffset", ".addtimeos", ".addtimeoffset", ".wallop", ".watchdog", ".reinit", ".reinitialize", ".enable", ".disable", ".ignore", ".unignore", ".fsd" }); static const QStringList cmds({ ".msg", ".m", ".chat", ".altos", ".altoffset", ".addtimeos", ".addtimeoffset", ".wallop", ".watchdog", ".reinit", ".reinitialize", ".enable", ".disable", ".ignore", ".unignore", ".fsd" });
CSimpleCommandParser parser(cmds); CSimpleCommandParser parser(cmds);
parser.parse(commandLine); parser.parse(commandLine);
@@ -548,21 +567,22 @@ namespace BlackCore
CFlightPlan CContextNetwork::loadFlightPlanFromNetwork(const CCallsign &callsign) const CFlightPlan CContextNetwork::loadFlightPlanFromNetwork(const CCallsign &callsign) const
{ {
if (!this->canUseFsd()) { return {}; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
return m_airspace->loadFlightPlanFromNetwork(callsign); return m_airspace->loadFlightPlanFromNetwork(callsign);
} }
CUserList CContextNetwork::getUsers() const CUserList CContextNetwork::getUsers() const
{ {
if (!this->canUseAirspaceMonitor()) { return {}; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
return m_airspace->getUsers(); return m_airspace->getUsers();
} }
CUserList CContextNetwork::getUsersForCallsigns(const CCallsignSet &callsigns) const CUserList CContextNetwork::getUsersForCallsigns(const CCallsignSet &callsigns) const
{ {
if (!this->canUseAirspaceMonitor() || callsigns.isEmpty()) { return {}; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
CUserList users;
if (callsigns.isEmpty()) return users;
return m_airspace->getUsersForCallsigns(callsigns); return m_airspace->getUsersForCallsigns(callsigns);
} }
@@ -578,39 +598,46 @@ namespace BlackCore
CClientList CContextNetwork::getClients() const CClientList CContextNetwork::getClients() const
{ {
if (!this->canUseAirspaceMonitor()) { return {}; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
return m_airspace->getClients(); return m_airspace->getClients();
} }
CClientList CContextNetwork::getClientsForCallsigns(const CCallsignSet &callsigns) const CClientList CContextNetwork::getClientsForCallsigns(const CCallsignSet &callsigns) const
{ {
if (!this->canUseAirspaceMonitor()) { return {}; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
return m_airspace->getClientsForCallsigns(callsigns); return m_airspace->getClientsForCallsigns(callsigns);
} }
bool CContextNetwork::setOtherClient(const CClient &client) bool CContextNetwork::setOtherClient(const CClient &client)
{ {
if (!this->canUseAirspaceMonitor()) { return false; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
return m_airspace->setOtherClient(client); return m_airspace->setOtherClient(client);
} }
int CContextNetwork::removeClient(const Aviation::CCallsign &callsign) int CContextNetwork::removeClient(const Aviation::CCallsign &callsign)
{ {
if (!this->canUseAirspaceMonitor()) { return 0; }
return m_airspace->removeClient(callsign); return m_airspace->removeClient(callsign);
} }
bool CContextNetwork::autoAdjustCientGndCapability(const Aviation::CAircraftSituation &situation) bool CContextNetwork::autoAdjustCientGndCapability(const Aviation::CAircraftSituation &situation)
{ {
if (!this->canUseAirspaceMonitor()) { return false; }
return m_airspace->autoAdjustCientGndCapability(situation); return m_airspace->autoAdjustCientGndCapability(situation);
} }
bool CContextNetwork::addClientGndCapability(const CCallsign &callsign) bool CContextNetwork::addClientGndCapability(const CCallsign &callsign)
{ {
if (!this->canUseAirspaceMonitor()) { return false; }
return m_airspace->addClientGndCapability(callsign); return m_airspace->addClientGndCapability(callsign);
} }
bool CContextNetwork::setClientGndCapability(const Aviation::CCallsign &callsign, bool supportGndFlag) bool CContextNetwork::setClientGndCapability(const Aviation::CCallsign &callsign, bool supportGndFlag)
{ {
if (!this->canUseAirspaceMonitor()) { return false; }
return m_airspace->setClientGndCapability(callsign, supportGndFlag); return m_airspace->setClientGndCapability(callsign, supportGndFlag);
} }
@@ -716,6 +743,16 @@ namespace BlackCore
} }
} }
bool CContextNetwork::canUseFsd() const
{
return sApp && !sApp->isShuttingDown() && m_fsdClient;
}
bool CContextNetwork::canUseAirspaceMonitor() const
{
return sApp && !sApp->isShuttingDown() && m_airspace;
}
void CContextNetwork::updateMetars(const CMetarList &metars) void CContextNetwork::updateMetars(const CMetarList &metars)
{ {
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
@@ -1027,7 +1064,7 @@ namespace BlackCore
void CContextNetwork::requestAircraftDataUpdates() void CContextNetwork::requestAircraftDataUpdates()
{ {
Q_ASSERT(m_airspace); if (!canUseAirspaceMonitor()) { return; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
if (!this->isConnected()) { return; } if (!this->isConnected()) { return; }
@@ -1037,7 +1074,7 @@ namespace BlackCore
void CContextNetwork::requestAtisUpdates() void CContextNetwork::requestAtisUpdates()
{ {
Q_ASSERT(m_airspace); if (!canUseAirspaceMonitor()) { return; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
if (!this->isConnected()) { return; } if (!this->isConnected()) { return; }
@@ -1047,7 +1084,7 @@ namespace BlackCore
bool CContextNetwork::updateAircraftEnabled(const CCallsign &callsign, bool enabledForRendering) bool CContextNetwork::updateAircraftEnabled(const CCallsign &callsign, bool enabledForRendering)
{ {
Q_ASSERT(m_airspace); if (!canUseAirspaceMonitor()) { return false; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << enabledForRendering; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << enabledForRendering; }
const bool c = m_airspace->updateAircraftEnabled(callsign, enabledForRendering); const bool c = m_airspace->updateAircraftEnabled(callsign, enabledForRendering);
if (c) if (c)
@@ -1061,13 +1098,14 @@ namespace BlackCore
bool CContextNetwork::setAircraftEnabledFlag(const CCallsign &callsign, bool enabledForRendering) bool CContextNetwork::setAircraftEnabledFlag(const CCallsign &callsign, bool enabledForRendering)
{ {
if (!canUseAirspaceMonitor()) { return false; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign; }
return m_airspace->setAircraftEnabledFlag(callsign, enabledForRendering); return m_airspace->setAircraftEnabledFlag(callsign, enabledForRendering);
} }
bool CContextNetwork::updateAircraftModel(const CCallsign &callsign, const CAircraftModel &model, const CIdentifier &originator) bool CContextNetwork::updateAircraftModel(const CCallsign &callsign, const CAircraftModel &model, const CIdentifier &originator)
{ {
Q_ASSERT(m_airspace); if (!canUseAirspaceMonitor()) { return false; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << model; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << model; }
const bool c = m_airspace->updateAircraftModel(callsign, model, originator); const bool c = m_airspace->updateAircraftModel(callsign, model, originator);
if (c) if (c)
@@ -1081,6 +1119,7 @@ namespace BlackCore
bool CContextNetwork::updateAircraftNetworkModel(const CCallsign &callsign, const CAircraftModel &model, const CIdentifier &originator) bool CContextNetwork::updateAircraftNetworkModel(const CCallsign &callsign, const CAircraftModel &model, const CIdentifier &originator)
{ {
if (!canUseAirspaceMonitor()) { return false; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << model; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << model; }
const bool c = m_airspace->updateAircraftNetworkModel(callsign, model, originator); const bool c = m_airspace->updateAircraftNetworkModel(callsign, model, originator);
if (c) if (c)
@@ -1093,6 +1132,7 @@ namespace BlackCore
bool CContextNetwork::updateFastPositionEnabled(const CCallsign &callsign, bool enableFastPositonUpdates) bool CContextNetwork::updateFastPositionEnabled(const CCallsign &callsign, bool enableFastPositonUpdates)
{ {
if (!canUseAirspaceMonitor()) { return false; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << enableFastPositonUpdates; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << enableFastPositonUpdates; }
const bool c = m_airspace->updateFastPositionEnabled(callsign, enableFastPositonUpdates); const bool c = m_airspace->updateFastPositionEnabled(callsign, enableFastPositonUpdates);
if (c) if (c)
@@ -1119,6 +1159,7 @@ namespace BlackCore
bool CContextNetwork::updateCG(const Aviation::CCallsign &callsign, const CLength &cg) bool CContextNetwork::updateCG(const Aviation::CCallsign &callsign, const CLength &cg)
{ {
if (!canUseAirspaceMonitor()) { return false; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << cg.valueRoundedWithUnit(1); } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << cg.valueRoundedWithUnit(1); }
const bool c = m_airspace->updateCG(callsign, cg); const bool c = m_airspace->updateCG(callsign, cg);
return c; return c;
@@ -1126,6 +1167,7 @@ namespace BlackCore
CCallsignSet CContextNetwork::updateCGForModel(const QString &modelString, const CLength &cg) CCallsignSet CContextNetwork::updateCGForModel(const QString &modelString, const CLength &cg)
{ {
if (!canUseAirspaceMonitor()) { return {}; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << modelString << cg.valueRoundedWithUnit(1); } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << modelString << cg.valueRoundedWithUnit(1); }
const CCallsignSet set = m_airspace->updateCGForModel(modelString, cg); const CCallsignSet set = m_airspace->updateCGForModel(modelString, cg);
return set; return set;
@@ -1133,6 +1175,7 @@ namespace BlackCore
bool CContextNetwork::updateCGAndModelString(const CCallsign &callsign, const CLength &cg, const QString &modelString) bool CContextNetwork::updateCGAndModelString(const CCallsign &callsign, const CLength &cg, const QString &modelString)
{ {
if (!canUseAirspaceMonitor()) { return false; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << cg.valueRoundedWithUnit(1) << modelString; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign << cg.valueRoundedWithUnit(1) << modelString; }
const bool c = m_airspace->updateCGAndModelString(callsign, cg, modelString); const bool c = m_airspace->updateCGAndModelString(callsign, cg, modelString);
return c; return c;
@@ -1140,71 +1183,84 @@ namespace BlackCore
void CContextNetwork::requestAtcBookingsUpdate() const void CContextNetwork::requestAtcBookingsUpdate() const
{ {
if (!canUseAirspaceMonitor()) { return; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
m_airspace->requestAtcBookingsUpdate(); m_airspace->requestAtcBookingsUpdate();
} }
bool CContextNetwork::updateAircraftRendered(const CCallsign &callsign, bool rendered) bool CContextNetwork::updateAircraftRendered(const CCallsign &callsign, bool rendered)
{ {
if (!canUseAirspaceMonitor()) { return false; }
const bool c = m_airspace->updateAircraftRendered(callsign, rendered); const bool c = m_airspace->updateAircraftRendered(callsign, rendered);
return c; return c;
} }
int CContextNetwork::updateMultipleAircraftRendered(const CCallsignSet &callsigns, bool rendered) int CContextNetwork::updateMultipleAircraftRendered(const CCallsignSet &callsigns, bool rendered)
{ {
if (!canUseAirspaceMonitor()) { return 0; }
const int c = m_airspace->updateMultipleAircraftRendered(callsigns, rendered); const int c = m_airspace->updateMultipleAircraftRendered(callsigns, rendered);
return c; return c;
} }
int CContextNetwork::updateMultipleAircraftEnabled(const CCallsignSet &callsigns, bool enabled) int CContextNetwork::updateMultipleAircraftEnabled(const CCallsignSet &callsigns, bool enabled)
{ {
if (!canUseAirspaceMonitor()) { return 0; }
const int c = m_airspace->updateMultipleAircraftEnabled(callsigns, enabled); const int c = m_airspace->updateMultipleAircraftEnabled(callsigns, enabled);
return c; return c;
} }
int CContextNetwork::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info, bool *setForOnGroundPosition) int CContextNetwork::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info, bool *setForOnGroundPosition)
{ {
if (!canUseAirspaceMonitor()) { return 0; }
return m_airspace->updateAircraftGroundElevation(callsign, elevation, info, setForOnGroundPosition); return m_airspace->updateAircraftGroundElevation(callsign, elevation, info, setForOnGroundPosition);
} }
void CContextNetwork::updateMarkAllAsNotRendered() void CContextNetwork::updateMarkAllAsNotRendered()
{ {
if (!canUseAirspaceMonitor()) { return; }
m_airspace->updateMarkAllAsNotRendered(); m_airspace->updateMarkAllAsNotRendered();
} }
CLength CContextNetwork::getCGFromDB(const CCallsign &callsign) const CLength CContextNetwork::getCGFromDB(const CCallsign &callsign) const
{ {
if (!canUseAirspaceMonitor()) { return {}; }
return m_airspace->getCGFromDB(callsign); return m_airspace->getCGFromDB(callsign);
} }
CLength CContextNetwork::getCGFromDB(const QString &modelString) const CLength CContextNetwork::getCGFromDB(const QString &modelString) const
{ {
if (!canUseAirspaceMonitor()) { return {}; }
return m_airspace->getCGFromDB(modelString); return m_airspace->getCGFromDB(modelString);
} }
void CContextNetwork::rememberCGFromDB(const CLength &cgFromDB, const CCallsign &callsign) void CContextNetwork::rememberCGFromDB(const CLength &cgFromDB, const CCallsign &callsign)
{ {
if (!canUseAirspaceMonitor()) { return; }
m_airspace->rememberCGFromDB(cgFromDB, callsign); m_airspace->rememberCGFromDB(cgFromDB, callsign);
} }
void CContextNetwork::rememberCGFromDB(const CLength &cgFromDB, const QString &modelString) void CContextNetwork::rememberCGFromDB(const CLength &cgFromDB, const QString &modelString)
{ {
if (!canUseAirspaceMonitor()) { return; }
m_airspace->rememberCGFromDB(cgFromDB, modelString); m_airspace->rememberCGFromDB(cgFromDB, modelString);
} }
int CContextNetwork::reInitializeAllAircraft() int CContextNetwork::reInitializeAllAircraft()
{ {
if (!canUseAirspaceMonitor()) { return 0; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; }
return m_airspace->reInitializeAllAircraft(); return m_airspace->reInitializeAllAircraft();
} }
CAirspaceAircraftSnapshot CContextNetwork::getLatestAirspaceAircraftSnapshot() const CAirspaceAircraftSnapshot CContextNetwork::getLatestAirspaceAircraftSnapshot() const
{ {
if (!canUseAirspaceMonitor()) { return {}; }
return m_airspace->getLatestAirspaceAircraftSnapshot(); return m_airspace->getLatestAirspaceAircraftSnapshot();
} }
CElevationPlane CContextNetwork::averageElevationOfNonMovingAircraft(const CAircraftSituation &reference, const CLength &range, int minValues, int sufficientValues) const CElevationPlane CContextNetwork::averageElevationOfNonMovingAircraft(const CAircraftSituation &reference, const CLength &range, int minValues, int sufficientValues) const
{ {
if (!canUseAirspaceMonitor()) { return {}; }
return m_airspace->averageElevationOfNonMovingAircraft(reference, range, minValues, sufficientValues); return m_airspace->averageElevationOfNonMovingAircraft(reference, range, minValues, sufficientValues);
} }
@@ -1220,21 +1276,25 @@ namespace BlackCore
CClient CContextNetwork::getClientOrDefaultForCallsign(const Aviation::CCallsign &callsign) const CClient CContextNetwork::getClientOrDefaultForCallsign(const Aviation::CCallsign &callsign) const
{ {
if (!canUseAirspaceMonitor()) { return {}; }
return m_airspace->getClientOrDefaultForCallsign(callsign); return m_airspace->getClientOrDefaultForCallsign(callsign);
} }
bool CContextNetwork::hasClientInfo(const Aviation::CCallsign &callsign) const bool CContextNetwork::hasClientInfo(const Aviation::CCallsign &callsign) const
{ {
if (!canUseAirspaceMonitor()) { return false; }
return m_airspace->hasClientInfo(callsign); return m_airspace->hasClientInfo(callsign);
} }
bool CContextNetwork::addNewClient(const CClient &client) bool CContextNetwork::addNewClient(const CClient &client)
{ {
if (!canUseAirspaceMonitor()) { return false; }
return m_airspace->addNewClient(client); return m_airspace->addNewClient(client);
} }
int CContextNetwork::updateOrAddClient(const Aviation::CCallsign &callsign, const CPropertyIndexVariantMap &vm, bool skipEqualValues) int CContextNetwork::updateOrAddClient(const Aviation::CCallsign &callsign, const CPropertyIndexVariantMap &vm, bool skipEqualValues)
{ {
if (!canUseAirspaceMonitor()) { return 0; }
return m_airspace->updateOrAddClient(callsign, vm, skipEqualValues); return m_airspace->updateOrAddClient(callsign, vm, skipEqualValues);
} }
@@ -1254,47 +1314,45 @@ namespace BlackCore
QString CContextNetwork::getLibraryInfo(bool detailed) const QString CContextNetwork::getLibraryInfo(bool detailed) const
{ {
if (!this->canUseFsd()) { return QString(); }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << detailed; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << detailed; }
Q_ASSERT(m_fsdClient);
return ""; return "";
} }
void CContextNetwork::testRequestAircraftConfig(const CCallsign &callsign) void CContextNetwork::testRequestAircraftConfig(const CCallsign &callsign)
{ {
if (!this->canUseFsd()) { return; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign; }
Q_ASSERT(m_fsdClient);
m_fsdClient->sendClientQueryAircraftConfig(callsign); m_fsdClient->sendClientQueryAircraftConfig(callsign);
} }
void CContextNetwork::testCreateDummyOnlineAtcStations(int number) void CContextNetwork::testCreateDummyOnlineAtcStations(int number)
{ {
if (!this->canUseAirspaceMonitor()) { return; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << number; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << number; }
m_airspace->testCreateDummyOnlineAtcStations(number); m_airspace->testCreateDummyOnlineAtcStations(number);
} }
void CContextNetwork::testAddAircraftParts(const CCallsign &callsign, const CAircraftParts &parts, bool incremental) void CContextNetwork::testAddAircraftParts(const CCallsign &callsign, const CAircraftParts &parts, bool incremental)
{ {
if (!this->canUseAirspaceMonitor()) { return; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << parts << incremental; } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << parts << incremental; }
m_airspace->testAddAircraftParts(callsign, parts, incremental); m_airspace->testAddAircraftParts(callsign, parts, incremental);
} }
void CContextNetwork::testReceivedAtisMessage(const CCallsign &callsign, const CInformationMessage &msg) void CContextNetwork::testReceivedAtisMessage(const CCallsign &callsign, const CInformationMessage &msg)
{ {
if (!this->canUseFsd()) { return; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign.asString(); } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign.asString(); }
if (this->fsdClient())
{
emit this->fsdClient()->atisReplyReceived(callsign, msg); emit this->fsdClient()->atisReplyReceived(callsign, msg);
} }
}
void CContextNetwork::testReceivedTextMessages(const CTextMessageList &textMessages) void CContextNetwork::testReceivedTextMessages(const CTextMessageList &textMessages)
{ {
if (!this->canUseFsd()) { return; }
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << textMessages.toQString(); } if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << textMessages.toQString(); }
if (this->fsdClient())
{
emit this->fsdClient()->textMessagesReceived(textMessages); emit this->fsdClient()->textMessagesReceived(textMessages);
} }
}
CMetar CContextNetwork::getMetarForAirport(const CAirportIcaoCode &airportIcaoCode) const CMetar CContextNetwork::getMetarForAirport(const CAirportIcaoCode &airportIcaoCode) const
{ {

View File

@@ -352,6 +352,12 @@ namespace BlackCore
//! Status of simulator changed //! Status of simulator changed
//! \ingroup crosscontextfunction //! \ingroup crosscontextfunction
void xCtxSimulatorStatusChanged(int status); void xCtxSimulatorStatusChanged(int status);
//! Can FSD be used?
bool canUseFsd() const;
//! Can the airspace monitor be used be used?
bool canUseAirspaceMonitor() const;
}; };
} // ns } // ns
} // ns } // ns

View File

@@ -144,8 +144,14 @@ namespace BlackCore
m_validator->deleteLater(); m_validator->deleteLater();
m_validator = nullptr; m_validator = nullptr;
} }
this->stopSimulatorListeners();
this->disconnect(); this->disconnect();
this->unloadSimulatorPlugin(); this->unloadSimulatorPlugin();
// give listeners a head start
// if simconnect is running remotely it can take a while until it shutdowns
m_listenersThread.quit();
m_listenersThread.wait(10 * 1000);
} }
CSimulatorPluginInfoList CContextSimulator::getAvailableSimulatorPlugins() const CSimulatorPluginInfoList CContextSimulator::getAvailableSimulatorPlugins() const
@@ -934,7 +940,7 @@ namespace BlackCore
{ {
if (!m_simulatorPlugin.first.isUnspecified()) { return; } if (!m_simulatorPlugin.first.isUnspecified()) { return; }
stopSimulatorListeners(); this->stopSimulatorListeners();
const QStringList enabledSimulators = m_enabledSimulators.getThreadLocal(); const QStringList enabledSimulators = m_enabledSimulators.getThreadLocal();
const CSimulatorPluginInfoList allSimulators = m_plugins->getAvailableSimulatorPlugins(); const CSimulatorPluginInfoList allSimulators = m_plugins->getAvailableSimulatorPlugins();
for (const CSimulatorPluginInfo &s : allSimulators) for (const CSimulatorPluginInfo &s : allSimulators)

View File

@@ -1430,8 +1430,15 @@ namespace BlackCore
this->setObjectName("ISimulatorListener:" + info.toQString()); this->setObjectName("ISimulatorListener:" + info.toQString());
// stop listener after it reports simulator ready // stop listener after it reports simulator ready
const bool s = connect(this, &ISimulatorListener::simulatorStarted, this, &ISimulatorListener::stop, Qt::QueuedConnection); bool s = connect(this, &ISimulatorListener::simulatorStarted, this, &ISimulatorListener::stop, Qt::QueuedConnection);
Q_ASSERT_X(s, Q_FUNC_INFO, "connect failed"); Q_ASSERT_X(s, Q_FUNC_INFO, "connect failed");
if (sApp)
{
s = connect(sApp, &CApplication::aboutToShutdown, this, &ISimulatorListener::onAboutToShutdown, Qt::QueuedConnection);
Q_ASSERT_X(s, Q_FUNC_INFO, "connect failed");
}
Q_UNUSED(s) Q_UNUSED(s)
} }
@@ -1442,7 +1449,14 @@ namespace BlackCore
bool ISimulatorListener::isShuttingDown() const bool ISimulatorListener::isShuttingDown() const
{ {
return (!sApp || sApp->isShuttingDown()); return (!sApp || sApp->isShuttingDown() || m_aboutToShutdown);
}
void ISimulatorListener::onAboutToShutdown()
{
if (!m_aboutToShutdown) { return; }
m_aboutToShutdown = true;
this->stop();
} }
void ISimulatorListener::start() void ISimulatorListener::start()

View File

@@ -720,8 +720,12 @@ namespace BlackCore
virtual void checkImpl() = 0; virtual void checkImpl() = 0;
private: private:
//! swift will shutdown
void onAboutToShutdown();
BlackMisc::Simulation::CSimulatorPluginInfo m_info; BlackMisc::Simulation::CSimulatorPluginInfo m_info;
std::atomic_bool m_isRunning { false }; std::atomic_bool m_isRunning { false };
std::atomic_bool m_aboutToShutdown { false }; // swift will shutdown
}; };
//! Factory pattern class to create instances of ISimulator //! Factory pattern class to create instances of ISimulator

View File

@@ -33,6 +33,7 @@
#include <QPointer> #include <QPointer>
#include <QStringBuilder> #include <QStringBuilder>
#include <type_traits> #include <type_traits>
#include <QElapsedTimer>
using namespace BlackConfig; using namespace BlackConfig;
using namespace BlackMisc; using namespace BlackMisc;
@@ -2823,13 +2824,15 @@ namespace BlackSimPlugin
if (!m_timer.isActive()) { return; } if (!m_timer.isActive()) { return; }
if (this->isShuttingDown()) { return; } if (this->isShuttingDown()) { return; }
m_timer.start(); // restart because we will check just now
QPointer<CSimulatorFsxCommonListener> myself(this); QPointer<CSimulatorFsxCommonListener> myself(this);
QTimer::singleShot(0, this, [ = ] QTimer::singleShot(0, this, [ = ]
{ {
if (!myself || !sApp || sApp->isShuttingDown()) { return; } if (!myself || !sApp || sApp->isShuttingDown()) { return; }
this->checkConnection(); this->checkConnection();
}); });
// restart because we have just checked now
m_timer.start();
} }
QString CSimulatorFsxCommonListener::backendInfo() const QString CSimulatorFsxCommonListener::backendInfo() const
@@ -2841,6 +2844,7 @@ namespace BlackSimPlugin
void CSimulatorFsxCommonListener::checkConnection() void CSimulatorFsxCommonListener::checkConnection()
{ {
if (this->isShuttingDown()) { return; } if (this->isShuttingDown()) { return; }
QElapsedTimer t; t.start();
Q_ASSERT_X(!CThreadUtils::isCurrentThreadApplicationThread(), Q_FUNC_INFO, "Expect to run in background"); Q_ASSERT_X(!CThreadUtils::isCurrentThreadApplicationThread(), Q_FUNC_INFO, "Expect to run in background");
HANDLE hSimConnect; HANDLE hSimConnect;
HRESULT result = SimConnect_Open(&hSimConnect, sApp->swiftVersionChar(), nullptr, 0, nullptr, 0); HRESULT result = SimConnect_Open(&hSimConnect, sApp->swiftVersionChar(), nullptr, 0, nullptr, 0);
@@ -2851,11 +2855,18 @@ namespace BlackSimPlugin
// blocks remote calls -> RESTART // blocks remote calls -> RESTART
for (int i = 0; !check && i < 3 && !this->isShuttingDown(); i++) for (int i = 0; !check && i < 3 && !this->isShuttingDown(); i++)
{ {
if (this->thread()->isInterruptionRequested())
{
m_timer.stop();
check = false;
break;
}
// result not always in first dispatch as we first have to obtain simulator name // result not always in first dispatch as we first have to obtain simulator name
result = SimConnect_CallDispatch(hSimConnect, CSimulatorFsxCommonListener::SimConnectProc, this); result = SimConnect_CallDispatch(hSimConnect, CSimulatorFsxCommonListener::SimConnectProc, this);
if (isFailure(result)) { break; } // means serious failure if (isFailure(result)) { break; } // means serious failure
check = this->checkVersionAndSimulator(); check = this->checkVersionAndSimulator();
if (!check && sApp) { sApp->processEventsFor(500); } if (!check && sApp) { CApplication::processEventsFor(500); }
} }
} }
SimConnect_Close(hSimConnect); SimConnect_Close(hSimConnect);
@@ -2864,6 +2875,8 @@ namespace BlackSimPlugin
{ {
emit this->simulatorStarted(this->getPluginInfo()); emit this->simulatorStarted(this->getPluginInfo());
} }
CLogMessage(this).debug(u"Checked sim connection in %1ms") << t.elapsed();
} }
bool CSimulatorFsxCommonListener::checkVersionAndSimulator() const bool CSimulatorFsxCommonListener::checkVersionAndSimulator() const