Ref T275, improved tracing for FSX

* getStatisticsSimulatorSpecific for simulator specific traces/logs
* trace CSimulatorFsxCommon::SimConnectProc times
* trace which receive id is handled in SimConnectProc
* allow to limit aircraft updates (max FPS)
* handle airport updates outside SimConnectProc
This commit is contained in:
Klaus Basan
2018-06-08 22:03:05 +02:00
parent bdf58ff538
commit 4975ecd712
7 changed files with 242 additions and 44 deletions

View File

@@ -196,6 +196,9 @@ namespace BlackCore
//! \remark needs to be overridden if the concrete driver supports such an option
virtual bool requestElevation(const BlackMisc::Geo::ICoordinateGeodetic &reference, const BlackMisc::Aviation::CCallsign &callsign) override;
//! Allows to print out simulator specific statistics
virtual QString getStatisticsSimulatorSpecific() const { return QString(); }
//! \copydoc BlackMisc::IProvider::asQObject
virtual QObject *asQObject() override { return this; }

View File

@@ -244,15 +244,15 @@ namespace BlackCore
CAirportList CSimulatorCommon::getAirportsInRange() const
{
// default implementation
if (this->isShuttingDown()) { return CAirportList(); }
if (!sApp || !sApp->hasWebDataServices()) { return CAirportList(); }
if (sApp->isShuttingDown()) { return CAirportList(); }
CAirportList airports = sApp->getWebDataServices()->getAirports();
const CAirportList airports = sApp->getWebDataServices()->getAirports();
if (airports.isEmpty()) { return airports; }
const CCoordinateGeodetic ownPosition = this->getOwnAircraftPosition();
airports = airports.findClosest(maxAirportsInRange(), ownPosition);
if (m_autoCalcAirportDistance) { airports.calculcateAndUpdateRelativeDistanceAndBearing(ownPosition); }
return airports;
CAirportList airportInRange = airports.findClosest(maxAirportsInRange(), ownPosition);
if (m_autoCalcAirportDistance) { airportInRange.calculcateAndUpdateRelativeDistanceAndBearing(ownPosition); }
return airportInRange;
}
void CSimulatorCommon::setWeatherActivated(bool activated)
@@ -276,6 +276,53 @@ namespace BlackCore
return reverseModel;
}
bool CSimulatorCommon::isUpdateAircraftLimited(qint64 timestamp)
{
if (!m_limitUpdateAircraft) { return false; }
const bool hasToken = m_limitUpdateAircraftBucket.tryConsume(1, timestamp);
return !hasToken;
}
bool CSimulatorCommon::isUpdateAircraftLimitedWithStats(qint64 startTime)
{
const bool limited = this->isUpdateAircraftLimited(startTime);
this->setStatsRemoteAircraftUpdate(startTime, limited);
return limited;
}
bool CSimulatorCommon::limitToUpdatesPerSecond(int numberPerSecond)
{
if (numberPerSecond < 1)
{
m_limitUpdateAircraft = false;
return false;
}
int tokens = 0.1 * numberPerSecond; // 100ms
do
{
if (tokens >= 3) { m_limitUpdateAircraftBucket.setInterval(100); break; }
tokens = 0.25 * numberPerSecond; // 250ms
if (tokens >= 3) { m_limitUpdateAircraftBucket.setInterval(250); break; }
tokens = 0.5 * numberPerSecond; // 500ms
if (tokens >= 3) { m_limitUpdateAircraftBucket.setInterval(500); break; }
tokens = numberPerSecond;
m_limitUpdateAircraftBucket.setInterval(1000);
}
while (false);
m_limitUpdateAircraftBucket.setCapacityAndTokensToRefill(tokens);
m_limitUpdateAircraft = true;
return true;
}
QString CSimulatorCommon::updateAircraftLimitationInfo() const
{
if (!m_limitUpdateAircraft) { return QStringLiteral("not limited"); }
static const QString limInfo("Limited %1 times with %2/secs.");
return limInfo.arg(m_statsUpdateAircraftLimited).arg(m_limitUpdateAircraftBucket.getTokensPerSecond());
}
void CSimulatorCommon::onSwiftDbAllDataRead()
{
// void, can be overridden in specialized drivers
@@ -579,9 +626,18 @@ namespace BlackCore
this->logicallyRemoveRemoteAircraft(cs);
}
}
return false;
}
if (part1.startsWith("limit"))
{
const int perSecond = parser.toInt(2, -1);
this->limitToUpdatesPerSecond(perSecond);
CLogMessage(this).info("Remote aircraft updates limitations: %1") << this->updateAircraftLimitationInfo();
return true;
}
// driver specific cmd line arguments
return this->parseDetails(parser);
}
@@ -590,6 +646,7 @@ namespace BlackCore
{
if (CSimpleCommandParser::registered("BlackCore::CSimulatorCommon")) { return; }
CSimpleCommandParser::registerCommand({".drv", "alias: .driver .plugin"});
CSimpleCommandParser::registerCommand({".drv limit number/secs.", "limit updates to number per second (0..off)"});
CSimpleCommandParser::registerCommand({".drv logint callsign", "log interpolator for callsign"});
CSimpleCommandParser::registerCommand({".drv logint off", "no log information for interpolator"});
CSimpleCommandParser::registerCommand({".drv logint write", "write interpolator log to file"});
@@ -613,6 +670,7 @@ namespace BlackCore
m_statsPhysicallyRemovedAircraft = 0;
m_statsLastUpdateAircraftRequestedMs = 0;
m_statsUpdateAircraftRequestedDeltaMs = 0;
m_statsUpdateAircraftLimited = 0;
}
CStatusMessageList CSimulatorCommon::debugVerifyStateAfterAllAircraftRemoved() const
@@ -662,7 +720,7 @@ namespace BlackCore
m_clampedLogMsg.remove(callsign);
}
void CSimulatorCommon::setStatsRemoteAircraftUpdate(qint64 startTime)
void CSimulatorCommon::setStatsRemoteAircraftUpdate(qint64 startTime, bool limited)
{
const qint64 now = QDateTime::currentMSecsSinceEpoch();
const qint64 dt = now - startTime;
@@ -671,9 +729,11 @@ namespace BlackCore
m_statsUpdateAircraftRuns++;
m_statsUpdateAircraftTimeAvgMs = static_cast<double>(m_statsUpdateAircraftTimeTotalMs) / static_cast<double>(m_statsUpdateAircraftRuns);
m_updateRemoteAircraftInProgress = false;
m_statsLastUpdateAircraftRequestedMs = startTime;
if (m_statsMaxUpdateTimeMs < dt) { m_statsMaxUpdateTimeMs = dt; }
if (m_statsLastUpdateAircraftRequestedMs > 0) { m_statsUpdateAircraftRequestedDeltaMs = startTime - m_statsLastUpdateAircraftRequestedMs; }
m_statsLastUpdateAircraftRequestedMs = startTime;
if (limited) { m_statsUpdateAircraftLimited++; }
}
bool CSimulatorCommon::isEqualLastSent(const CAircraftSituation &compare) const
@@ -795,19 +855,22 @@ namespace BlackCore
CAirportList CSimulatorCommon::getWebServiceAirports() const
{
if (this->isShuttingDown()) { return CAirportList(); }
if (!sApp->hasWebDataServices()) { return CAirportList(); }
return sApp->getWebDataServices()->getAirports();
}
CAirport CSimulatorCommon::getWebServiceAirport(const CAirportIcaoCode &icao) const
{
if (this->isShuttingDown()) { return CAirport(); }
if (!sApp->hasWebDataServices()) { return CAirport(); }
return sApp->getWebDataServices()->getAirports().findFirstByIcao(icao);
}
void CSimulatorCommon::rapOnRecalculatedRenderedAircraft(const CAirspaceAircraftSnapshot &snapshot)
{
if (!this->isConnected()) return;
if (!this->isConnected()) { return; }
if (this->isShuttingDown()) { return; }
this->onRecalculatedRenderedAircraft(snapshot);
}

View File

@@ -33,6 +33,7 @@
#include "blackmisc/pq/length.h"
#include "blackmisc/pq/time.h"
#include "blackmisc/pq/units.h"
#include "blackmisc/tokenbucket.h"
#include "blackmisc/connectionguard.h"
namespace BlackMisc
@@ -93,6 +94,7 @@ namespace BlackCore
//! @{
//! <pre>
//! .drv unload unload plugin BlackCore::CSimulatorCommon
//! .drv limit number limit the number of updates BlackCore::CSimulatorCommon
//! .drv logint callsign log interpolator for callsign BlackCore::CSimulatorCommon
//! .drv logint off no log information for interpolator BlackCore::CSimulatorCommon
//! .drv logint write write interpolator log to file BlackCore::CSimulatorCommon
@@ -119,7 +121,7 @@ namespace BlackCore
static void registerHelp();
//! Reset the statistics counters
void resetAircraftStatistics();
virtual void resetAircraftStatistics();
//! Counter added aircraft
int getStatisticsPhysicallyAddedAircraft() const { return m_statsPhysicallyAddedAircraft; }
@@ -152,6 +154,9 @@ namespace BlackCore
//! \remark public only for log. displays
QString latestLoggedDataFormatted(const BlackMisc::Aviation::CCallsign &cs) const;
//! Info about update aircraft limitations
QString updateAircraftLimitationInfo() const;
protected:
//! Constructor
CSimulatorCommon(const BlackMisc::Simulation::CSimulatorPluginInfo &info,
@@ -246,7 +251,7 @@ namespace BlackCore
void removedClampedLog(const BlackMisc::Aviation::CCallsign &callsign);
//! Update stats and flags
void setStatsRemoteAircraftUpdate(qint64 startTime);
void setStatsRemoteAircraftUpdate(qint64 startTime, bool limited = false);
//! Equal to last sent situation
bool isEqualLastSent(const BlackMisc::Aviation::CAircraftSituation &compare) const;
@@ -268,6 +273,7 @@ namespace BlackCore
bool m_updateRemoteAircraftInProgress = false; //!< currently updating remote aircraft
int m_timerId = -1; //!< dispatch timer id
int m_statsUpdateAircraftRuns = 0; //!< statistics update count
int m_statsUpdateAircraftLimited = 0; //!< skipped because of max.update limitations
double m_statsUpdateAircraftTimeAvgMs = 0; //!< statistics average update time
qint64 m_statsUpdateAircraftTimeTotalMs = 0; //!< statistics total update time
qint64 m_statsCurrentUpdateTimeMs = 0; //!< statistics current update time
@@ -284,6 +290,19 @@ namespace BlackCore
// some optional functionality which can be used by the simulators as needed
BlackMisc::Simulation::CSimulatedAircraftList m_addAgainAircraftWhenRemoved; //!< add this model again when removed, normally used to change model
// limit the update aircraft to a maximum per second
BlackMisc::CTokenBucket m_limitUpdateAircraftBucket { 5, 100, 5 }; //!< means 50 per second
bool m_limitUpdateAircraft = false; //!< limit the update frequency by using BlackMisc::CTokenBucket
//! Limit reached (max number of updates by token bucket if enabled)
bool isUpdateAircraftLimited(qint64 timestamp = -1);
//! Limited as CSimulatorCommon::isUpdateAircraftLimited plus updating statistics
bool isUpdateAircraftLimitedWithStats(qint64 startTime = -1);
//! Limit to updates per seconds
bool limitToUpdatesPerSecond(int numberPerSecond);
// weather
bool m_isWeatherActivated = false; //!< Is simulator weather activated?
BlackMisc::Geo::CCoordinateGeodetic m_lastWeatherPosition; //!< Own aircraft position at which weather was fetched and injected last