Ref T270, Ref T268, plugin common / simulator improvements

* connect with "about to quit"
* added interface declarations
* sim statistics, use common function setStatsRemoteAircraftUpdate and double for average values
This commit is contained in:
Klaus Basan
2018-05-30 12:51:07 +02:00
parent 2923df27e2
commit aa7363dcad
11 changed files with 114 additions and 48 deletions

View File

@@ -80,6 +80,8 @@ namespace BlackCore
connect(sApp->getWebDataServices(), &CWebDataServices::swiftDbModelMatchingEntitiesRead, this, &CSimulatorCommon::onSwiftDbModelMatchingEntitiesRead, Qt::QueuedConnection);
}
connect(sApp, &CApplication::aboutToShutdown, this, &CSimulatorCommon::unload, Qt::QueuedConnection);
// info
CLogMessage(this).info("Initialized simulator driver: '%1'") << this->getSimulatorInfo().toQString();
}
@@ -299,6 +301,12 @@ namespace BlackCore
m_remoteAircraftProviderConnections.disconnectAll(); // disconnect signals from provider
}
bool CSimulatorCommon::disconnectFrom()
{
// supposed to be overridden
return true;
}
bool CSimulatorCommon::isShuttingDown() const
{
return (!sApp || sApp->isShuttingDown());
@@ -574,7 +582,7 @@ namespace BlackCore
void CSimulatorCommon::resetAircraftStatistics()
{
m_statsUpdateAircraftCountMs = 0;
m_statsUpdateAircraftRuns = 0;
m_statsUpdateAircraftTimeAvgMs = 0;
m_statsUpdateAircraftTimeTotalMs = 0;
m_statsPhysicallyAddedAircraft = 0;
@@ -628,6 +636,15 @@ namespace BlackCore
m_clampedLogMsg.remove(callsign);
}
void CSimulatorCommon::setStatsRemoteAircraftUpdate(qint64 startTime)
{
const qint64 dt = QDateTime::currentMSecsSinceEpoch() - startTime;
m_statsUpdateAircraftTimeTotalMs += dt;
m_statsUpdateAircraftRuns++;
m_statsUpdateAircraftTimeAvgMs = static_cast<double>(m_statsUpdateAircraftTimeTotalMs) / static_cast<double>(m_statsUpdateAircraftRuns);
m_updateRemoteAircraftInProgress = false;
}
void CSimulatorCommon::onRecalculatedRenderedAircraft(const CAirspaceAircraftSnapshot &snapshot)
{
if (!snapshot.isValidSnapshot()) { return;}
@@ -710,6 +727,7 @@ namespace BlackCore
m_addAgainAircraftWhenRemoved.clear();
m_callsignsToBeRendered.clear();
m_clampedLogMsg.clear();
m_updateRemoteAircraftInProgress = false;
this->resetHighlighting();
this->resetAircraftStatistics();

View File

@@ -58,6 +58,8 @@ namespace BlackCore
{
Q_OBJECT
Q_INTERFACES(BlackCore::ISimulator)
Q_INTERFACES(BlackMisc::Simulation::ISimulationEnvironmentProvider)
Q_INTERFACES(BlackMisc::Simulation::IInterpolationSetupProvider)
public:
//! Log categories
@@ -74,6 +76,7 @@ namespace BlackCore
virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override;
virtual void setWeatherActivated(bool activated) override;
virtual void unload() override;
virtual bool disconnectFrom() override;
virtual bool isShuttingDown() const override;
virtual bool logicallyReAddRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
virtual BlackMisc::Aviation::CCallsignSet unrenderedEnabledAircraft() const override;
@@ -115,7 +118,7 @@ namespace BlackCore
int getStatisticsPhysicallyRemovedAircraft() const { return m_statsPhysicallyRemovedAircraft; }
//! Average update time in ms
qint64 getStatisticsAverageUpdateTimeMs() const { return m_statsUpdateAircraftTimeAvgMs; }
double getStatisticsAverageUpdateTimeMs() const { return m_statsUpdateAircraftTimeAvgMs; }
//! Total update time in ms
qint64 getStatisticsTotalUpdateTimeMs() const { return m_statsUpdateAircraftTimeTotalMs; }
@@ -225,15 +228,19 @@ namespace BlackCore
//! \remark use this function when there is a risk that a lot of log. messages will be generated in a short time
void removedClampedLog(const BlackMisc::Aviation::CCallsign &callsign);
//! Update stats and flags
void setStatsRemoteAircraftUpdate(qint64 startTime);
//! Lookup against DB data
static BlackMisc::Simulation::CAircraftModel reverseLookupModel(const BlackMisc::Simulation::CAircraftModel &model);
bool m_pausedSimFreezesInterpolation = false; //!< paused simulator will also pause interpolation (so AI aircraft will hold)
bool m_autoCalcAirportDistance = true; //!< automatically calculate airport distance and bearing
bool m_updateRemoteAircraftInProgress = false; //!< currently updating remote aircraft
int m_timerId = -1; //!< dispatch timer id
int m_statsUpdateAircraftCountMs = 0; //!< statistics update count
qint64 m_statsUpdateAircraftTimeTotalMs = 0; //!< statistics update time
qint64 m_statsUpdateAircraftTimeAvgMs = 0; //!< statistics update time
int m_statsUpdateAircraftRuns = 0; //!< statistics update count
qint64 m_statsUpdateAircraftTimeTotalMs = 0; //!< statistics total update time
double m_statsUpdateAircraftTimeAvgMs = 0; //!< statistics average update time
BlackMisc::Simulation::CSimulatorInternals m_simulatorInternals; //!< setup object
BlackMisc::Simulation::CInterpolationLogger m_interpolationLogger; //!< log.interpolation
QMap<BlackMisc::Aviation::CCallsign, qint64> m_clampedLogMsg; //!< when logged last so there, can be used so there is no log message overflow

View File

@@ -61,10 +61,10 @@ namespace BlackSimPlugin
bool CSimulatorEmulated::connectTo()
{
const QPointer<CSimulatorEmulated> guard(this);
const QPointer<CSimulatorEmulated> myself(this);
QTimer::singleShot(1000, this, [ = ]
{
if (guard.isNull()) { return; }
if (myself.isNull()) { return; }
this->emitSimulatorCombinedStatus();
m_monitorWidget->show();
});
@@ -75,9 +75,15 @@ namespace BlackSimPlugin
bool CSimulatorEmulated::disconnectFrom()
{
if (canLog()) m_monitorWidget->appendReceivingCall(Q_FUNC_INFO);
if (canLog()) { m_monitorWidget->appendReceivingCall(Q_FUNC_INFO); }
m_renderedAircraft.clear();
return true;
return CSimulatorPluginCommon::disconnectFrom();
}
void CSimulatorEmulated::unload()
{
if (canLog()) { m_monitorWidget->appendReceivingCall(Q_FUNC_INFO); }
return CSimulatorPluginCommon::unload();
}
bool CSimulatorEmulated::logicallyAddRemoteAircraft(const CSimulatedAircraft &remoteAircraft)

View File

@@ -34,6 +34,10 @@ namespace BlackSimPlugin
class CSimulatorEmulated : public Common::CSimulatorPluginCommon
{
Q_OBJECT
Q_INTERFACES(BlackCore::ISimulator)
Q_INTERFACES(BlackMisc::Simulation::ISimulationEnvironmentProvider)
Q_INTERFACES(BlackMisc::Simulation::IInterpolationSetupProvider)
friend class CSimulatorEmulatedMonitorDialog; //!< the monitor widget represents the simulator and needs access to internals (i.e. private/protected)
public:
@@ -50,6 +54,7 @@ namespace BlackSimPlugin
virtual bool isTimeSynchronized() const override;
virtual bool connectTo() override;
virtual bool disconnectFrom() override;
virtual void unload() override;
virtual bool changeRemoteAircraftModel(const BlackMisc::Simulation::CSimulatedAircraft &aircraft) override;
virtual bool changeRemoteAircraftEnabled(const BlackMisc::Simulation::CSimulatedAircraft &aircraft) override;
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const BlackMisc::CIdentifier &originator) override;

View File

@@ -85,7 +85,7 @@ namespace BlackSimPlugin
// reset flags
m_simPaused = false;
this->emitSimulatorCombinedStatus();
return true;
return CSimulatorPluginCommon::disconnectFrom();
}
bool CSimulatorFsCommon::isFsuipcConnected() const

View File

@@ -114,8 +114,7 @@ namespace BlackSimPlugin
this->reset(); // mark as disconnected and reset all values
// emit status and disconnect FSUIPC
CSimulatorFsCommon::disconnectFrom();
return true;
return CSimulatorFsCommon::disconnectFrom();
}
bool CSimulatorFsxCommon::physicallyAddRemoteAircraft(const CSimulatedAircraft &newRemoteAircraft)
@@ -367,7 +366,17 @@ namespace BlackSimPlugin
void CSimulatorFsxCommon::onSimFrame()
{
this->updateRemoteAircraft();
QPointer<CSimulatorFsxCommon> myself(this);
if (m_updateRemoteAircraftInProgress)
{
return;
}
QTimer::singleShot(0, this, [ = ]
{
// run decoupled from simconnect event queue
if (!myself) { return; }
myself->updateRemoteAircraft();
});
}
void CSimulatorFsxCommon::onSimExit()
@@ -1236,13 +1245,11 @@ namespace BlackSimPlugin
// nothing to do, reset request id and exit
const int remoteAircraftNo = this->getAircraftInRangeCount();
if (remoteAircraftNo < 1) { m_interpolationRequest = 0; return; }
// interpolate and send to simulator
m_interpolationRequest++;
if (remoteAircraftNo < 1) { m_statsUpdateAircraftRuns = 0; return; }
// values used for position and parts
const qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch();
m_updateRemoteAircraftInProgress = true;
// interpolation for all remote aircraft
const QList<CSimConnectObject> simObjects(m_simConnectObjects.values());
@@ -1298,10 +1305,8 @@ namespace BlackSimPlugin
} // all callsigns
const qint64 dt = QDateTime::currentMSecsSinceEpoch() - currentTimestamp;
m_statsUpdateAircraftTimeTotalMs += dt;
m_statsUpdateAircraftCountMs++;
m_statsUpdateAircraftTimeAvgMs = m_statsUpdateAircraftTimeTotalMs / m_statsUpdateAircraftCountMs;
// stats
this->setStatsRemoteAircraftUpdate(currentTimestamp);
}
bool CSimulatorFsxCommon::updateRemoteAircraftParts(const CSimConnectObject &simObject, const CInterpolationResult &result)
@@ -1608,7 +1613,6 @@ namespace BlackSimPlugin
m_simSimulating = false;
m_syncDeferredCounter = 0;
m_skipCockpitUpdateCycles = 0;
m_interpolationRequest = 0;
m_requestIdSimData = static_cast<SIMCONNECT_DATA_REQUEST_ID>(RequestIdSimDataStart);
m_dispatchErrors = 0;
m_receiveExceptionCount = 0;
@@ -1618,6 +1622,7 @@ namespace BlackSimPlugin
// m_simConnectObjects
// m_simConnectObjectsPositionAndPartsTraces
// m_addPendingAircraft
// m_updateRemoteAircraftInProgress
CSimulatorFsCommon::reset(); // clears all pending aircraft etc
}

View File

@@ -249,7 +249,7 @@ namespace BlackSimPlugin
//! Deferred version of onSimRunning to avoid jitter
void onSimRunningDefered(qint64 referenceTs);
//! Slot called every visual frame
//! Called every visual frame
void onSimFrame();
//! Called when simulator has stopped, e.g. by selecting the "select aircraft screen"
@@ -393,11 +393,10 @@ namespace BlackSimPlugin
bool m_useSbOffsets = true; //!< with SB offsets
bool m_traceSendId = false; //!< trace the send ids, meant for debugging
qint64 m_simulatingChangedTs = -1; //!< timestamp, when simulating changed (used to avoid jitter)
int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time
int m_skipCockpitUpdateCycles = 0; //!< skip some update cycles to allow changes in simulator cockpit to be set
int m_interpolationRequest = 0; //!< current interpolation request
int m_dispatchErrors = 0; //!< number of dispatched failed, \sa dispatch
int m_receiveExceptionCount = 0; //!< exceptions
int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time
int m_skipCockpitUpdateCycles = 0; //!< skip some update cycles to allow changes in simulator cockpit to be set
int m_dispatchErrors = 0; //!< number of dispatched failed, \sa dispatch
int m_receiveExceptionCount = 0; //!< exceptions
QList<TraceFsxSendId> m_sendIdTraces; //!< Send id traces for debugging
CSimConnectObjects m_simConnectObjects; //!< AI objects and their object / request ids
CSimConnectObjects m_simConnectProbes; //!< AI terrain probes

View File

@@ -19,9 +19,12 @@ namespace BlackSimPlugin
namespace P3D
{
//! P3D Simulator Implementation
class CSimulatorP3D : public BlackSimPlugin::FsxCommon::CSimulatorFsxCommon
class CSimulatorP3D : public FsxCommon::CSimulatorFsxCommon
{
Q_OBJECT
Q_INTERFACES(BlackCore::ISimulator)
Q_INTERFACES(BlackMisc::Simulation::ISimulationEnvironmentProvider)
Q_INTERFACES(BlackMisc::Simulation::IInterpolationSetupProvider)
public:
//! Constructor, parameters as in \sa BlackCore::ISimulatorFactory::create
@@ -41,7 +44,7 @@ namespace BlackSimPlugin
};
//! Listener for P3D
class CSimulatorP3DListener : public BlackSimPlugin::FsxCommon::CSimulatorFsxCommonListener
class CSimulatorP3DListener : public FsxCommon::CSimulatorFsxCommonListener
{
Q_OBJECT

View File

@@ -12,6 +12,7 @@
#include "blackgui/guiapplication.h"
#include "blackmisc/simplecommandparser.h"
using namespace BlackGui;
using namespace BlackGui::Components;
using namespace BlackCore;
using namespace BlackMisc;
@@ -37,21 +38,33 @@ namespace BlackSimPlugin
CSimulatorPluginCommon::~CSimulatorPluginCommon()
{
if (m_interpolationDisplay)
this->deleteInterpolationDisplay();
}
void CSimulatorPluginCommon::deleteInterpolationDisplay()
{
if (m_interpolationDisplayDialog)
{
m_interpolationDisplay->deleteLater();
// if there is no parent widget, we clean dialog up
// otherwise the parent is supposed to clean up
CInterpolationLogDisplayDialog *dialog = m_interpolationDisplayDialog;
m_interpolationDisplayDialog = nullptr;
dialog->close();
delete dialog;
}
}
void CSimulatorPluginCommon::showInterpolationDisplay()
{
if (!m_interpolationDisplay)
if (!m_interpolationDisplayDialog)
{
QWidget *parentWidget = sGui ? sGui->mainApplicationWidget() : nullptr;
CInterpolationLogDisplayDialog *dialog = new CInterpolationLogDisplayDialog(this, nullptr, parentWidget);
m_interpolationDisplay = dialog;
m_interpolationDisplayDialog = dialog;
m_interpolationDisplayDialog->setModal(false);
}
m_interpolationDisplay->show();
if (m_interpolationDisplayDialog) { m_interpolationDisplayDialog->show(); }
}
bool CSimulatorPluginCommon::parseDetails(const CSimpleCommandParser &parser)
@@ -67,14 +80,16 @@ namespace BlackSimPlugin
void CSimulatorPluginCommon::unload()
{
if (m_interpolationDisplay)
{
m_interpolationDisplay->hide();
m_interpolationDisplay->deleteLater();
}
this->deleteInterpolationDisplay();
CSimulatorCommon::unload();
}
bool CSimulatorPluginCommon::disconnectFrom()
{
this->deleteInterpolationDisplay();
return CSimulatorCommon::disconnectFrom();
}
void CSimulatorPluginCommon::registerHelp()
{
if (CSimpleCommandParser::registered("BlackSimPlugin::Common::CSimulatorPluginCommon")) { return; }

View File

@@ -24,10 +24,19 @@ namespace BlackSimPlugin
//! Common base class for simulator plugins
class CSimulatorPluginCommon : public BlackCore::CSimulatorCommon
{
Q_OBJECT
Q_INTERFACES(BlackCore::ISimulator)
Q_INTERFACES(BlackMisc::Simulation::ISimulationEnvironmentProvider)
Q_INTERFACES(BlackMisc::Simulation::IInterpolationSetupProvider)
public:
//! Destructor
virtual ~CSimulatorPluginCommon();
// --------- ISimulator implementations ------------
virtual void unload() override;
virtual bool disconnectFrom() override;
protected:
//! Constructor
CSimulatorPluginCommon(const BlackMisc::Simulation::CSimulatorPluginInfo &info,
@@ -45,9 +54,6 @@ namespace BlackSimPlugin
//! @}
virtual bool parseDetails(const BlackMisc::CSimpleCommandParser &parser) override;
// interface implementations
virtual void unload() override;
//! Register help
static void registerHelp();
@@ -55,7 +61,10 @@ namespace BlackSimPlugin
//! Show the interpolator display
void showInterpolationDisplay();
QPointer<BlackGui::Components::CInterpolationLogDisplayDialog> m_interpolationDisplay; //!< can be owned by main window after setting a parent
//! Clean up the interpolation log.display if any
void deleteInterpolationDisplay();
QPointer<BlackGui::Components::CInterpolationLogDisplayDialog> m_interpolationDisplayDialog; //!< can be owned by main window after setting a parent
};
} // namespace
} // namespace

View File

@@ -702,6 +702,7 @@ namespace BlackSimPlugin
if (remoteAircraftNo < 1) { return; }
// values used for position and parts
m_updateRemoteAircraftInProgress = true;
const qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch();
// interpolation for all remote aircraft
@@ -776,10 +777,8 @@ namespace BlackSimPlugin
m_trafficProxy->setPlanesSurfaces(planesSurfaces);
}
const qint64 dt = QDateTime::currentMSecsSinceEpoch() - currentTimestamp;
m_statsUpdateAircraftTimeTotalMs += dt;
m_statsUpdateAircraftCountMs++;
m_statsUpdateAircraftTimeAvgMs = m_statsUpdateAircraftTimeTotalMs / m_statsUpdateAircraftCountMs;
// stats
this->setStatsRemoteAircraftUpdate(currentTimestamp);
}
void CSimulatorXPlane::requestRemoteAircraftDataFromXPlane()