9 #include <QDesktopServices>
14 #include <QStringBuilder>
31 using namespace swift::config;
33 using namespace swift::misc::aviation;
34 using namespace swift::misc::geo;
35 using namespace swift::misc::math;
36 using namespace swift::misc::simulation;
37 using namespace swift::misc::simulation::data;
38 using namespace swift::misc::simulation::settings;
39 using namespace swift::misc::physical_quantities;
40 using namespace swift::misc::network;
41 using namespace swift::misc::weather;
46 const QStringList &ISimulator::getLogCategories()
48 static const QStringList cats({ CLogCategories::driver(), CLogCategories::plugin() });
52 ISimulator::~ISimulator() { this->safeKillTimer(); }
54 ISimulator::SimulatorStatus ISimulator::getSimulatorStatus()
const
56 if (!this->isConnected()) {
return ISimulator::Disconnected; }
57 const SimulatorStatus status =
64 bool ISimulator::logicallyRemoveRemoteAircraft(
const CCallsign &callsign)
67 if (!this->getInterpolationSetupGlobal().isRenderingRestricted())
69 m_statsPhysicallyAddedAircraft++;
70 this->callPhysicallyRemoveRemoteAircraft(callsign);
80 if (!this->validateModelOfAircraft(remoteAircraft))
83 CLogMessage(
this).
warning(u
"Invalid aircraft detected, which will be disabled: '%1' '%2'")
85 this->updateAircraftEnabled(cs,
false);
86 this->updateAircraftRendered(cs,
false);
91 const bool renderingRestricted = this->getInterpolationSetupGlobal().isRenderingRestricted();
92 if (this->showDebugLogMessage())
94 this->debugLogMessage(Q_FUNC_INFO,
95 QStringLiteral(
"Restricted: %1 cs: '%2' enabled: %3")
97 boolToYesNo(remoteAircraft.
isEnabled())));
99 if (!remoteAircraft.
isEnabled()) {
return false; }
102 if (!renderingRestricted)
104 this->callPhysicallyAddRemoteAircraft(remoteAircraft);
112 bool ISimulator::followAircraft(
const CCallsign &callsign)
118 void ISimulator::recalculateAllAircraft() { this->setUpdateAllRemoteAircraft(); }
120 void ISimulator::setFlightNetworkConnected(
bool connected) { m_networkConnected = connected; }
122 void ISimulator::clearAllRemoteAircraftData()
125 m_addAgainAircraftWhenRemoved.clear();
126 m_callsignsToBeRendered.clear();
127 this->resetLastSentValues();
128 m_updateRemoteAircraftInProgress =
false;
130 this->clearInterpolationSetupsPerCallsign();
131 this->resetAircraftStatistics();
134 void ISimulator::debugLogMessage(
const QString &msg)
136 if (!this->showDebugLogMessage()) {
return; }
137 if (msg.isEmpty()) {
return; }
139 emit this->driverMessages(m);
142 void ISimulator::debugLogMessage(
const QString &funcInfo,
const QString &msg)
144 if (!this->showDebugLogMessage()) {
return; }
145 if (msg.isEmpty()) {
return; }
147 emit this->driverMessages(m);
150 bool ISimulator::showDebugLogMessage()
const
152 const bool show = this->getInterpolationSetupGlobal().showSimulatorDebugMessages();
156 void ISimulator::resetAircraftFromProvider(
const CCallsign &callsign)
159 const bool enabled = aircraft.
isEnabled();
163 if (!this->isPhysicallyRenderedAircraft(callsign))
165 this->callPhysicallyAddRemoteAircraft(aircraft);
168 else { this->callPhysicallyRemoveRemoteAircraft(callsign); }
173 m_statsPhysicallyRemovedAircraft++;
174 m_lastSentParts.remove(callsign);
175 m_lastSentSituations.remove(callsign);
176 m_loopbackSituations.clear();
177 this->removeInterpolationSetupPerCallsign(callsign);
183 if (!this->isLogCallsign(cs)) {
return false; }
192 if (!this->isLogCallsign(callsign)) {
return false; }
203 void ISimulator::reset()
205 this->clearAllRemoteAircraftData();
207 m_simTimeRatio = 1.0;
208 m_trackMilesShort = 0.0;
212 bool ISimulator::isUpdateAllRemoteAircraft(qint64 currentTimestamp)
const
214 if (m_updateAllRemoteAircraftUntil < 1) {
return false; }
215 if (currentTimestamp < 0) { currentTimestamp = QDateTime::currentMSecsSinceEpoch(); }
216 return (m_updateAllRemoteAircraftUntil > currentTimestamp);
219 void ISimulator::setUpdateAllRemoteAircraft(qint64 currentTimestamp, qint64 forMs)
221 if (currentTimestamp < 0) { currentTimestamp = QDateTime::currentMSecsSinceEpoch(); }
222 if (forMs < 0) { forMs = 10 * 1000; }
223 m_updateAllRemoteAircraftUntil = currentTimestamp + forMs;
224 this->resetLastSentValues();
227 void ISimulator::resetUpdateAllRemoteAircraft() { m_updateAllRemoteAircraftUntil = -1; }
229 void ISimulator::safeKillTimer()
231 if (m_timerId < 0) {
return; }
232 SWIFT_AUDIT_X(CThreadUtils::isInThisThread(
this), Q_FUNC_INFO,
"Try to kill timer from another thread");
233 this->killTimer(m_timerId);
238 bool forceFullUpdate)
const
241 const CClient client = this->getClientOrDefaultForCallsign(callsign);
257 if (this->isShuttingDown()) {
return; }
258 if (plane.
isNull()) {
return; }
262 bool updatedForOnGroundPosition =
false;
263 const int updated = CRemoteAircraftAware::updateAircraftGroundElevation(
264 callsign, plane, CAircraftSituation::FromProvider, &updatedForOnGroundPosition);
267 const bool likelyOnGroundElevation = updated > 0 && updatedForOnGroundPosition;
268 ISimulationEnvironmentProvider::rememberGroundElevation(callsign, likelyOnGroundElevation,
273 emit this->receivedRequestedElevation(plane, callsign);
277 void ISimulator::resetAircraftStatistics()
279 m_statsUpdateAircraftRuns = 0;
280 m_statsUpdateAircraftTimeAvgMs = 0;
281 m_statsUpdateAircraftTimeTotalMs = 0;
282 m_statsMaxUpdateTimeMs = 0;
283 m_statsCurrentUpdateTimeMs = 0;
284 m_statsPhysicallyAddedAircraft = 0;
285 m_statsPhysicallyRemovedAircraft = 0;
286 m_statsUpdateAircraftLimited = 0;
287 m_statsLastUpdateAircraftRequestedMs = 0;
288 m_statsUpdateAircraftRequestedDeltaMs = 0;
289 ISimulationEnvironmentProvider::resetSimulationEnvironmentStatistics();
292 bool ISimulator::isEmulatedDriver()
const
294 const QString
className = this->metaObject()->className();
295 return className.contains(
"emulated", Qt::CaseInsensitive);
298 bool ISimulator::parseCommandLine(
const QString &commandLine,
const CIdentifier &originator)
300 if (this->isMyIdentifier(originator)) {
return false; }
301 if (this->isShuttingDown()) {
return false; }
303 if (commandLine.isEmpty()) {
return false; }
305 parser.
parse(commandLine);
306 if (!parser.isKnownCommand()) {
return false; }
309 if (parser.matchesPart(1,
"unload"))
316 const QString part1(parser.part(1).toLower().trimmed());
317 if (part1.startsWith(
"logint") && parser.hasPart(2))
319 const QString part2 = parser.part(2).toLower();
320 if (part2 ==
"off" || part2 ==
"false")
323 this->clearInterpolationLogCallsigns();
326 if (part2 ==
"clear" || part2 ==
"clr")
328 m_interpolationLogger.clearLog();
330 this->clearInterpolationLogCallsigns();
333 if (part2.startsWith(
"max"))
335 if (!parser.hasPart(3)) {
return false; }
337 const int max = parser.part(3).toInt(&ok);
338 if (!ok) {
return false; }
339 m_interpolationLogger.setMaxSituations(max);
343 if (part2 ==
"write" || part2 ==
"save")
346 this->clearInterpolationLogCallsigns();
349 const bool clearLog =
true;
350 m_interpolationLogger.writeLogInBackground(clearLog);
356 const QDir dir(CInterpolationLogger::getLogDirectory());
357 if (CDirectoryUtils::isDirExisting(dir))
359 const QUrl dirUrl = QUrl::fromLocalFile(dir.absolutePath());
360 QDesktopServices::openUrl(dirUrl);
367 if (!cs.
isValid()) {
return false; }
368 if (this->getAircraftInRangeCallsigns().contains(cs))
371 this->setLogCallsign(
true, cs);
381 if (part1.startsWith(
"spline") || part1.startsWith(
"linear"))
383 if (parser.hasPart(2))
386 const bool changed = this->setInterpolationMode(part1, cs);
387 CLogMessage(
this).
info(changed ? QStringLiteral(
"Changed interpolation mode for '%1'") :
388 QStringLiteral(
"Unchanged interpolation mode for '%1'"))
396 if (changed) { this->setInterpolationSetupGlobal(setup); }
397 CLogMessage(
this).
info(changed ? QStringLiteral(
"Changed interpolation mode globally") :
398 QStringLiteral(
"Unchanged interpolation mode"));
403 if (part1.startsWith(
"pos"))
409 if (csSet.
size() != 1) {
return false; }
415 this->setLogCallsign(
true, cs);
417 this->displayLoggedSituationInSimulator(cs,
true);
421 if (parser.hasPart(2) && (part1.startsWith(
"aircraft") || part1.startsWith(
"ac")))
423 const QString part2 = parser.part(2).toLower();
424 if (parser.hasPart(3) && (part2.startsWith(
"readd") || part2.startsWith(
"re-add")))
426 const QString cs = parser.part(3).toUpper();
429 this->physicallyRemoveAllRemoteAircraft();
431 this->clearAllRemoteAircraftData();
432 if (!msgs.
isEmpty()) { emit this->driverMessages(msgs); }
436 if (a.isEnabled()) { this->logicallyAddRemoteAircraft(a); }
439 else if (CCallsign::isValidAircraftCallsign(cs))
441 this->logicallyReAddRemoteAircraft(cs);
446 if (parser.hasPart(3) && (part2.startsWith(
"rm") || part2.startsWith(
"remove")))
448 const QString cs = parser.part(3).toUpper();
449 if (CCallsign::isValidAircraftCallsign(cs)) { this->logicallyRemoveRemoteAircraft(cs); }
455 if (part1.startsWith(
"limit"))
457 const int perSecond = parser.toInt(2, -1);
458 this->limitToUpdatesPerSecond(perSecond);
459 CLogMessage(
this).
info(u
"Remote aircraft updates limitations: %1") << this->updateAircraftLimitationInfo();
464 if (part1 == QStringView(u
"cg"))
466 if (parser.part(2).startsWith(
"clear", Qt::CaseInsensitive))
472 for (
const CCallsign &cs : this->getAircraftInRangeCallsigns())
475 const CLength cg = cgsPerCallsign.contains(cs) ? cgsPerCallsign[cs] : CLength::null();
476 this->updateCG(cs, cg);
481 if (parser.hasPart(3))
484 const QString ms = parser.partAndRemainingStringAfter(3).toUpper();
490 const bool set = this->insertCGForModelStringOverridden(cg, ms);
493 const CCallsignSet callsigns = this->updateCGForModel(ms, cg);
496 this->insertCGOverridden(cg, callsigns);
509 return this->parseDetails(parser);
512 void ISimulator::registerHelp()
514 if (CSimpleCommandParser::registered(
"swift::core::ISimulator")) {
return; }
515 CSimpleCommandParser::registerCommand({
".drv",
"alias: .driver .plugin" });
516 CSimpleCommandParser::registerCommand({
".drv unload",
"unload driver" });
517 CSimpleCommandParser::registerCommand({
".drv cg length clear|modelstr.",
"override CG" });
518 CSimpleCommandParser::registerCommand(
519 {
".drv limit number/secs.",
"limit updates to number per second (0..off)" });
520 CSimpleCommandParser::registerCommand({
".drv logint callsign",
"log interpolator for callsign" });
521 CSimpleCommandParser::registerCommand({
".drv logint off",
"no log information for interpolator" });
522 CSimpleCommandParser::registerCommand({
".drv logint write",
"write interpolator log to file" });
523 CSimpleCommandParser::registerCommand({
".drv logint clear",
"clear current log" });
524 CSimpleCommandParser::registerCommand({
".drv logint max number",
"max. number of entries logged" });
525 CSimpleCommandParser::registerCommand({
".drv pos callsign",
"show position for callsign" });
526 CSimpleCommandParser::registerCommand(
527 {
".drv spline|linear callsign",
"set spline/linear interpolator for one/all callsign(s)" });
528 CSimpleCommandParser::registerCommand(
529 {
".drv aircraft readd callsign",
"add again (re-add) a given callsign" });
530 CSimpleCommandParser::registerCommand({
".drv aircraft readd all",
"add again (re-add) all aircraft" });
531 CSimpleCommandParser::registerCommand(
532 {
".drv aircraft rm callsign",
"remove a given callsign from simulator" });
536 CSimpleCommandParser::registerCommand({
".drv fsuipc on|off",
"enable/disable FSUIPC (if applicable)" });
540 QString ISimulator::statusToString(SimulatorStatus status)
543 if (status.testFlag(Unspecified)) { s << QStringLiteral(
"Unspecified"); }
544 if (status.testFlag(Disconnected)) { s << QStringLiteral(
"Disconnected"); }
545 if (status.testFlag(Connected)) { s << QStringLiteral(
"Connected"); }
546 if (status.testFlag(Simulating)) { s << QStringLiteral(
"Simulating"); }
547 if (status.testFlag(Paused)) { s << QStringLiteral(
"Paused"); }
553 Q_ASSERT_X(compare.hasCallsign(), Q_FUNC_INFO,
"Need callsign");
554 if (!m_lastSentSituations.contains(compare.getCallsign())) {
return false; }
555 if (compare.isNull()) {
return false; }
556 return compare.equalPbhVectorAltitudeElevation(m_lastSentSituations.value(compare.getCallsign()));
562 if (callsign.
isEmpty()) {
return false; }
563 if (!m_lastSentParts.contains(callsign)) {
return false; }
564 return compare.equalValues(m_lastSentParts.value(callsign));
573 if (!hasCs) {
return; }
574 m_lastSentSituations.insert(sent.
getCallsign(), sent);
582 if (callsign.
isEmpty()) {
return; }
583 m_lastSentParts.insert(callsign, sent);
588 const QList<CAircraftSituation> situations = m_lastSentSituations.values();
592 if (s.canLikelySkipNearGroundInterpolation()) { skipped.
push_back(s); }
597 bool ISimulator::isAnyConnectedStatus(SimulatorStatus status)
599 return (status.testFlag(Connected) || status.testFlag(Simulating) || status.testFlag(Paused));
615 this->setObjectName(
"Simulator: " + pluginInfo.
getIdentifier());
621 m_remoteAircraftProviderConnections.
append(
629 this->rapOnRecalculatedRenderedAircraft(snapshot);
646 CLogMessage(
this).
info(u
"Plugin '%1' with no simulator info yet, hope it will be set later")
677 Q_ASSERT_X(snapshot.
generatingThreadName() != QThread::currentThread()->objectName(), Q_FUNC_INFO,
678 "Expect snapshot from background thread");
681 bool changed =
false;
689 const CCallsignSet callsignsToBeRemoved(callsignsInSimulator.
difference(callsignsEnabledAndStillInRange));
691 if (!callsignsToBeRemoved.
isEmpty())
697 if (!callsignsToBeAdded.
isEmpty())
703 Q_ASSERT_X(aircraft.isEnabled(), Q_FUNC_INFO,
"Disabled aircraft detected as to be added");
704 Q_ASSERT_X(aircraft.hasModelString(), Q_FUNC_INFO,
"Missing model string");
705 this->callPhysicallyAddRemoteAircraft(aircraft);
729 if (callsigns.
isEmpty()) {
return 0; }
731 for (
const CCallsign &callsign : callsigns)
733 this->callPhysicallyRemoveRemoteAircraft(callsign);
774 if (callsign.
isEmpty()) {
return; }
785 if (modelString.isEmpty()) {
return; }
789 if (!cgOvr.
isNull() && !this->hasSameSimulatorCG(cgOvr, callsign))
794 if (source != CSimulatorSettings::CGFromDBOnly)
796 this->
insertCG(cgOvr, modelString, callsign);
815 if (oldStatus != newStatus)
819 QPointer<ISimulator> myself(
this);
826 this->setUpdateAllRemoteAircraft();
829 emit this->simulatorStatusChanged(
837 QPointer<ISimulator> myself(
this);
839 if (!myself) {
return; }
865 bool modified =
false;
867 CDatabaseUtils::consolidateOwnAircraftModelWithDbData(model,
false, &modified);
886 if (numberPerSecond < 1)
892 int tokens = qRound(0.1 * numberPerSecond);
899 tokens = qRound(0.25 * numberPerSecond);
905 tokens = qRound(0.5 * numberPerSecond);
911 tokens = numberPerSecond;
924 static const QString limInfo(
"Limited %1 time(s) with %2/secs.");
966 if (callsign.
isEmpty()) {
return false; }
970 const QPointer<ISimulator> myself(
this);
972 if (myself.isNull()) { return; }
998 const QPointer<ISimulator> myself(
this);
1000 if (!myself) {
return; }
1009 if (!CBuildConfig::isLocalDeveloperDebugBuild()) {
return msgs; }
1019 const QString &details)
const
1021 static const QString msg(
"Interpolation ('%1'): '%2'");
1023 if (details.isEmpty()) {
return m; }
1025 static const QString addDetails(
" details: '%1'");
1026 return m % addDetails.arg(details);
1031 const qint64 now = QDateTime::currentMSecsSinceEpoch();
1032 const qint64 dt = now - startTime;
1062 constexpr qint64 deltaMs = 5000;
1085 CElevationPlane::singlePointRadius() :
1090 if (CBuildConfig::isLocalDeveloperDebugBuild())
1095 Q_UNUSED(remembered)
1107 CCentralMultiSimulatorModelSetCachesProvider::modelCachesInstance().synchronizeCache(simulator);
1108 return CCentralMultiSimulatorModelSetCachesProvider::modelCachesInstance().getCachedModels(simulator);
1144 static const QString sep(
"\n------\n");
1149 s.
toQString(
false,
true,
true,
true,
true, sep);
1151 if (p.
tsCurrent > 0) { dm += (dm.isEmpty() ? u
"Parts: " : u
"\n\nParts: ") % p.
toQString(sep); }
1162 void ISimulator::callPhysicallyAddRemoteAircraft(
const CSimulatedAircraft &remoteAircraft)
1164 m_statsPhysicallyAddedAircraft++;
1168 void ISimulator::callPhysicallyRemoveRemoteAircraft(
const CCallsign &remoteCallsign)
1174 void ISimulator::displayLoggedSituationInSimulator(
const CCallsign &cs,
bool stopLogging,
int times)
1180 if (!logsCs) {
return; }
1183 stopLogging = stopLogging && logsCs;
1184 if (!stopLogging && times < 1) {
return; }
1187 if (!stopLogging && !inRange) {
return; }
1188 if (stopLogging && (times < 1 || !inRange))
1197 const int t = CMathUtils::randomInteger(4500, 5500);
1198 const QPointer<ISimulator> myself(
this);
1200 if (!myself || myself->isShuttingDown()) { return; }
1201 this->displayLoggedSituationInSimulator(cs, stopLogging, times - 1);
1220 if (CDatabaseUtils::hasDbAircraftData())
1230 [=] { this->reverseLookupAndUpdateOwnAircraftModel(model); });
1237 this->setObjectName(
"ISimulatorListener:" + info.
toQString());
1242 Q_ASSERT_X(s, Q_FUNC_INFO,
"connect failed");
1247 Qt::QueuedConnection);
1248 Q_ASSERT_X(s, Q_FUNC_INFO,
"connect failed");
1258 void ISimulatorListener::onAboutToShutdown()
1260 if (!m_aboutToShutdown) {
return; }
1261 m_aboutToShutdown =
true;
1267 if (m_isRunning) {
return; }
1271 QPointer<ISimulatorListener> myself(
this);
1273 if (myself) { this->
start(); }
1284 if (!m_isRunning) {
return; }
1288 QPointer<ISimulatorListener> myself(
this);
1290 if (myself) { this->
stop(); }
1296 m_isRunning =
false;
1301 if (!m_isRunning) {
return; }
1305 QPointer<ISimulatorListener> myself(
this);
1307 if (myself) { this->
check(); }
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
static constexpr bool isCompiledWithFsuipcSupport()
with FSUIPC support?
void aboutToShutdown()
About to shutdown.
bool hasWebDataServices() const
Web data services available?
bool isShuttingDown() const
Is application shutting down?
CWebDataServices * getWebDataServices() const
Get the web data services.
void swiftDbModelMatchingEntitiesRead()
All entities needed for model matching.
void swiftDbAllDataRead()
All swift DB data have been read.
virtual bool isPhysicallyRenderedAircraft(const swift::misc::aviation::CCallsign &callsign) const =0
Is the aircraft rendered (displayed in simulator)? This shall only return true if the aircraft is rea...
virtual bool logicallyReAddRemoteAircraft(const swift::misc::aviation::CCallsign &callsign)
Removes and adds again the aircraft.
swift::misc::simulation::settings::CMultiSimulatorSettings m_multiSettings
simulator settings for all simulators
void resetLastSentValues()
Reset the last sent values.
double m_simTimeRatio
ratio of simulation time to real time, due to low FPS (X-Plane)
void resetUpdateAllRemoteAircraft()
Reset.
void renderRestrictionsChanged(bool restricted, bool enabled, int maxAircraft, const swift::misc::physical_quantities::CLength &maxRenderedDistance)
Render restrictions have been changed.
bool setInterpolationSetupGlobal(const swift::misc::simulation::CInterpolationAndRenderingSetupGlobal &setup)
Set the global setup.
bool updateOwnSituationAndGroundElevation(const swift::misc::aviation::CAircraftSituation &situation)
Update own aircraft position and if suitable use it to update ground elevation.
virtual void onOwnModelChanged(const swift::misc::simulation::CAircraftModel &newModel)
Own model has been changed.
bool isUpdateAllRemoteAircraft(qint64 currentTimestamp=-1) const
Do update all remote aircraft?
virtual bool isShuttingDown() const
Is overall (swift) application shutting down.
QString updateAircraftLimitationInfo() const
Info about update aircraft limitations.
virtual bool logicallyRemoveRemoteAircraft(const swift::misc::aviation::CCallsign &callsign)
Logically remove remote aircraft from simulator. Depending on max. aircraft, enabled status etc....
bool limitToUpdatesPerSecond(int numberPerSecond)
Limit to updates per second.
virtual void onSwiftDbAllDataRead()
When swift DB data are read.
bool m_updateRemoteAircraftInProgress
currently updating remote aircraft
swift::misc::CTokenBucket m_limitUpdateAircraftBucket
means 50 per second
virtual swift::misc::aviation::CCallsignSet physicallyRenderedAircraft() const =0
Physically rendered (displayed in simulator) This shall only return aircraft handled in the simulator...
qint64 m_lastRecordedGndElevationMs
when gnd.elevation was last modified
virtual void clearAllRemoteAircraftData()
Clear all aircraft related data, but do not physically remove the aircraft.
void rememberElevationAndSimulatorCG(const swift::misc::aviation::CCallsign &callsign, const swift::misc::simulation::CAircraftModel &model, bool likelyOnGroundElevation, const swift::misc::geo::CElevationPlane &elevation, const swift::misc::physical_quantities::CLength &simulatorCG)
Set elevation and CG in the providers and for auto publishing.
double m_trackMilesShort
difference between real and reported groundspeed, multiplied by time
virtual bool physicallyRemoveRemoteAircraft(const swift::misc::aviation::CCallsign &callsign)=0
Remove remote aircraft from simulator.
void ownAircraftModelChanged(const swift::misc::simulation::CAircraftModel &model)
Emitted when own aircraft model has changed.
double m_minutesLate
difference between real and reported groundspeed, integrated over time
bool isAircraftInRangeOrTestMode(const swift::misc::aviation::CCallsign &callsign) const
Test version aware version of isAircraftInRange.
void finishUpdateRemoteAircraftAndSetStatistics(qint64 startTime, bool limited=false)
Update stats and flags.
swift::misc::aviation::CAircraftSituationList getLoopbackSituations(const swift::misc::aviation::CCallsign &callsign) const
The traced loopback situations.
virtual bool physicallyAddRemoteAircraft(const swift::misc::simulation::CSimulatedAircraft &remoteAircraft)=0
Add new remote aircraft physically to the simulator.
void reverseLookupAndUpdateOwnAircraftModel(const swift::misc::simulation::CAircraftModel &model)
Set own model.
int m_statsUpdateAircraftLimited
skipped because of max.update limitations
swift::misc::aviation::CAircraftPartsPerCallsign m_lastSentParts
last parts sent to simulator
virtual void clearData(const swift::misc::aviation::CCallsign &callsign)
Clear the related data as statistics etc.
void emitInterpolationSetupChanged()
Pseudo signal, override to emit signal.
swift::misc::simulation::CAutoPublishData m_autoPublishing
for the DB
virtual void displayStatusMessage(const swift::misc::CStatusMessage &message) const =0
Display a status message in the simulator.
qint64 m_statsUpdateAircraftRequestedDeltaMs
delta time between 2 aircraft updates
bool isTestMode() const
Test mode? (driver can skip code parts etc., driver dependent)
virtual void onRecalculatedRenderedAircraft(const swift::misc::simulation::CAirspaceAircraftSnapshot &snapshot)
Recalculate the rendered aircraft, this happens when restrictions are applied (max....
virtual void unload()
Driver will be unloaded.
swift::misc::simulation::CAircraftModelList getModelSet() const
Get the model set.
bool isUpdateAircraftLimited(qint64 timestamp=-1)
Limit reached (max number of updates by token bucket if enabled)
virtual swift::misc::CStatusMessageList debugVerifyStateAfterAllAircraftRemoved() const
Debug function to check state after all aircraft have been removed.
virtual bool disconnectFrom()
Disconnect from simulator.
bool validateModelOfAircraft(const swift::misc::simulation::CSimulatedAircraft &aircraft) const
Validate if model has callsign and such.
void emitSimulatorCombinedStatus(SimulatorStatus oldStatus=Unspecified)
Emit the combined status.
int m_statsUpdateAircraftRuns
statistics update count
swift::misc::simulation::CSimulatedAircraftList m_addAgainAircraftWhenRemoved
add this model again when removed, normally used to change model
bool m_limitUpdateAircraft
limit the update frequency by using swift::misc::CTokenBucket
swift::misc::simulation::CSimulatorInternals m_simulatorInternals
setup read from the sim
virtual void onSwiftDbModelMatchingEntitiesRead()
When swift DB data are read.
void autoPublishDataWritten(const swift::misc::simulation::CSimulatorInfo &simulator)
Auto publish data written for simulator.
void airspaceSnapshotHandled()
An airspace snapshot was handled.
virtual int physicallyRemoveAllRemoteAircraft()
Remove all remote aircraft and their data via ISimulator::clearAllRemoteAircraftData.
void logAddingAircraftModel(const swift::misc::simulation::CSimulatedAircraft &aircraft) const
Unified qeeing aircraft message.
SimulatorStatusFlag
ISimulator status.
@ Simulating
Is the simulator actually simulating?
virtual SimulatorStatus getSimulatorStatus() const
Combined status.
qint64 m_statsUpdateAircraftTimeTotalMs
statistics total update time
swift::misc::simulation::settings::CSpecializedSimulatorSettings getSimulatorSettings() const
Settings for current simulator.
qint64 m_statsLastUpdateAircraftRequestedMs
when was the last aircraft update requested
swift::misc::simulation::CInterpolationLogger m_interpolationLogger
log.interpolation
bool isUpdateAircraftLimitedWithStats(qint64 startTime=-1)
Limited as ISimulator::isUpdateAircraftLimited plus updating statistics.
double m_statsUpdateAircraftTimeAvgMs
statistics average update time
virtual int physicallyRemoveMultipleRemoteAircraft(const swift::misc::aviation::CCallsignSet &callsigns)
Remove remote aircraft from simulator.
swift::misc::aviation::CAircraftSituationListPerCallsign m_loopbackSituations
traced loopback situations
virtual void initSimulatorInternals()
Init the internals info from the simulator.
qint64 m_statsMaxUpdateTimeMs
statistics max.update time
virtual bool isSimulating() const
Simulator running?
virtual bool isConnected() const =0
Are we connected to the simulator?
static swift::misc::simulation::CAircraftModel reverseLookupModel(const swift::misc::simulation::CAircraftModel &model)
Lookup against DB data.
QString latestLoggedDataFormatted(const swift::misc::aviation::CCallsign &cs) const
The latest logged data formatted.
swift::misc::aviation::CAircraftSituationPerCallsign m_lastSentSituations
last situations sent to simulator
virtual bool logicallyAddRemoteAircraft(const swift::misc::simulation::CSimulatedAircraft &remoteAircraft)
Logically add a new aircraft. Depending on max. aircraft, enabled status etc. it will physically adde...
virtual bool changeRemoteAircraftModel(const swift::misc::simulation::CSimulatedAircraft &aircraft)
Change remote aircraft per property.
static void registerHelp()
Register help.
qint64 m_statsCurrentUpdateTimeMs
statistics current update time
void interpolationAndRenderingSetupChanged()
Interpolation or rendering setup changed.
virtual bool changeRemoteAircraftEnabled(const swift::misc::simulation::CSimulatedAircraft &aircraft)
Aircraft got enabled / disabled.
QString getInvalidSituationLogMessage(const swift::misc::aviation::CCallsign &callsign, const swift::misc::simulation::CInterpolationStatus &status, const QString &details={}) const
Info about invalid situation.
virtual void startImpl()=0
Plugin specific implementation to start listener.
void simulatorStarted(const swift::misc::simulation::CSimulatorPluginInfo &info)
Emitted when the listener discovers the simulator running.
ISimulatorListener(const swift::misc::simulation::CSimulatorPluginInfo &info)
Constructor.
virtual bool isShuttingDown() const
Overall (swift) application shutting down.
void start()
Start listening for the simulator to start.
void stop()
Stops listening.
void check()
Check simulator availability.
virtual QString backendInfo() const
Info about the backend system (if available)
virtual void checkImpl()=0
Plugin specific implementation to check.
virtual void stopImpl()=0
Plugin specific implementation to stop listener.
size_type size() const
Returns number of elements in the collection.
CCollection difference(const C &other) const
Returns a collection which contains all the elements from this collection which are not in the other ...
CCollection intersection(const C &other) const
Returns a collection which is the intersection of this collection and another.
iterator begin()
Returns iterator at the beginning of the collection.
bool isEmpty() const
Synonym for empty.
bool append(const QMetaObject::Connection &connection)
Add connection.
int disconnectAll()
Disconnect all.
static CCrashHandler * instance()
Get singleton instance.
void crashAndLogAppendInfo(const QString &info)
Append crash info.
Base class with a member CIdentifier to be inherited by a class which has an identity in the environm...
Value object encapsulating information identifying a component of a modular distributed swift process...
Class for emitting a log message.
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
bool contains(const T &object) const
Return true if there is an element equal to given object. Uses the most efficient implementation avai...
void push_back(const T &value)
Appends an element at the end of the sequence.
bool isEmpty() const
Synonym for empty.
Utility methods for simple line parsing used with the command line.
void parse(const QString &commandLine)
Parse.
Streamable status message, e.g.
Status messages, e.g. from Core -> GUI.
static bool isInThisThread(const QObject *toBeTested)
Is the current thread the object's thread?
void setCapacityAndTokensToRefill(int numTokens)
Tokens/capacity if both are same.
void setInterval(qint64 intervalMs)
Set the interval.
bool tryConsume(int numTokens=1, qint64 msSinceEpoch=-1)
Try to consume a number of tokens.
int getTokensPerSecond() const
Tokens per second.
IRemoteAircraftProvider * provider()
Provider.
qint64 getMSecsSinceEpoch() const
Timestamp as ms value.
void setCurrentUtcTime()
Set the current time as timestamp.
qint64 getTimeDifferenceAbsMs(qint64 compareTime) const
Time difference in ms.
void setTimeOffsetMs(qint64 offset)
Milliseconds to add to timestamp for interpolation.
void push_frontKeepLatestAdjustedFirst(const OBJ &value, bool replaceSameTimestamp=true, int maxElements=-1)
Insert as first element by keeping maxElements and the latest first.
Value object encapsulating information of aircraft's parts.
Value object encapsulating information of an aircraft's situation.
const CAltitude & getGroundElevation() const
Elevation of the ground directly beneath.
void setCG(const physical_quantities::CLength &cg)
Set CG.
bool setGroundElevation(const aviation::CAltitude &altitude, GndElevationInfo info, bool transferred=false)
Elevation of the ground directly beneath at the given situation.
bool hasCallsign() const
Has corresponding callsign.
bool isOnGround() const
Is on ground?
const CCallsign & getCallsign() const
Corresponding callsign.
const CAltitude & getAltitude() const
Get altitude.
List of aircraft situations.
Altitude as used in aviation, can be AGL or MSL altitude.
bool hasMeanSeaLevelValue() const
Non-NULL MSL value?
CAltitude withOffset(const CLength &offset) const
Altitude with offset.
Value object encapsulating information of a callsign.
const QString & asString() const
Get callsign (normalized)
bool isEmpty() const
Is empty?
bool isValid() const
Valid callsign?
Value object for a set of callsigns.
QString getCallsignsAsString(bool sorted=false, const QString &separator=", ") const
Callsigns as string.
QStringList getCallsignStrings(bool sorted=false) const
Get callsign string list.
Plane of same elevation, can be a single point or larger area (e.g. airport)
virtual bool isNull() const
Existing value?
Geodetic coordinate, a position in 3D space relative to the reference geoid.
bool hasMSLGeodeticHeight() const
Geodetic height not null and aviation::CAltitude::MeanSeaLevel.
QString toQString(bool i18n=false) const
Cast as QString.
Class which can be directly used to access an.
Direct in memory access to client (network client) data.
Physical unit length (length)
void parseFromString(const QString &value)
Parse value from string.
bool isNull() const
Is quantity null?
QString valueRoundedWithUnit(const MU &unit, int digits=-1, bool withGroupSeparator=false, bool i18n=false) const
Value to QString with the given unit, e.g. "5.00m".
bool isZeroEpsilonConsidered() const
Quantity value <= epsilon.
Aircraft model (used by another pilot, my models on disk)
void setModelString(const QString &modelString)
Model string.
CSimulatorInfo getSimulator() const
Simulator info.
const QString & getModelString() const
Model key, either queried or loaded from simulator model.
bool isCallsignEmpty() const
Callsign empty.
const physical_quantities::CLength & getCG() const
Get center of gravity.
QString getModelStringAndDbKey() const
Model string and DB key (if available)
bool hasModelString() const
Non empty model string?
Value object encapsulating a list of aircraft models.
Current situation in the skies analyzed.
bool isRestricted() const
Restricted values?
const QString & generatingThreadName() const
Generating thread name.
bool isValidSnapshot() const
Valid snapshot?
bool isRenderingEnabled() const
Rendering enabled or all aircraft disabled?
bool isRestrictionChanged() const
Did the restriction flag change?
const swift::misc::aviation::CCallsignSet & getEnabledAircraftCallsignsByDistance() const
Callsigns by distance, only enabled aircraft.
void insert(const QString &modelString, const physical_quantities::CLength &cg)
Insert values we might want to update in the DB.
bool writeJsonToFile() const
Write to file.
bool logInterpolation() const
Log.interpolation.
bool setInterpolatorMode(InterpolatorMode mode)
Set interpolator mode.
void setForceFullInterpolation(bool force)
Force full interpolation.
void consolidateWithClient(const network::CClient &client)
Consolidate with a network client.
Value object for interpolator and rendering.
bool isRenderingEnabled() const
Rendering enabled (at all)?
int getMaxRenderedAircraft() const
Max.number of aircraft rendered.
physical_quantities::CLength getMaxRenderedDistance() const
Max.distance for rendering.
bool isRenderingRestricted() const
Rendering enabled, but restricted.
Value object for interpolator and rendering per callsign.
PartsLog getLastPartsLog() const
Get last parts.
SituationLog getLastSituationLog() const
Get last log.
QString toQString() const
Info string.
Delegating class which can be directly used to access an.
bool updateOwnModel(const swift::misc::simulation::CAircraftModel &model)
Update model.
bool updateOwnSituation(const aviation::CAircraftSituation &situation)
Update own situation.
swift::misc::simulation::CAircraftModel getOwnAircraftModel() const
Own aircraft model.
CSimulatedAircraft getOwnAircraft() const
Own aircraft.
Class which can be directly used to access an.
aviation::CCallsignSet getAircraftInRangeCallsigns() const
Unique callsigns for aircraft in range.
bool isAircraftInRange(const aviation::CCallsign &callsign) const
Is aircraft in range?
CSimulatedAircraftList getAircraftInRange() const
All remote aircraft.
int getAircraftInRangeCount() const
Count remote aircraft.
CSimulatedAircraft getAircraftInRangeForCallsign(const aviation::CCallsign &callsign) const
Aircraft for callsign.
Comprehensive information of an aircraft.
bool hasModelString() const
Has model string?
bool hasCallsign() const
Callsign not empty, no further checks.
const aviation::CCallsign & getCallsign() const
Get callsign.
const simulation::CAircraftModel & getModel() const
Get model (model used for mapping)
bool isEnabled() const
Enabled? Enable means it shall be displayed in the simulator.
QString getCallsignAsString() const
Get callsign.
const QString & getModelString() const
Get model string.
Value object encapsulating a list of aircraft.
Simple hardcoded info about the corresponding simulator.
bool matchesAll(const CSimulatorInfo &otherInfo) const
Matches all simulators.
bool isSingleSimulator() const
Single simulator selected.
bool isUnspecified() const
Unspecified simulator.
void setSimulatorName(const QString &name)
Set simulator name.
void setSimulatorInstallationDirectory(const QString &fullFilePath)
Path where simulator is installed.
void setSwiftPluginName(const QString &name)
Set plugin name.
Describing a simulator plugin.
bool isEmulatedPlugin() const
Is this the emulated driver?
const QString & getIdentifier() const
Identifier.
const CSimulatorInfo & getSimulatorInfo() const
Simulator info object.
Direct in memory access to interpolation setup, normally implemented by simulator.
void setLogCallsign(bool log, const aviation::CCallsign &callsign)
Log/un-log given callsign.
CInterpolationAndRenderingSetupPerCallsign getInterpolationSetupPerCallsignOrDefault(const aviation::CCallsign &callsign) const
Get the setup for callsign, if not existing the global setup.
virtual bool setInterpolationSetupGlobal(const CInterpolationAndRenderingSetupGlobal &setup)
Set the global setup.
Direct threadsafe in memory access to own aircraft.
Direct thread safe in memory access to remote aircraft.
Direct in memory access to elevation data.
void setNewPluginInfo(const CSimulatorPluginInfo &info, const settings::CSimulatorSettings &settings, const CAircraftModel &defaultModel)
New plugin info and default model.
CSimulatorPluginInfo getSimulatorPluginInfo() const
Get the represented plugin.
bool rememberGroundElevation(const aviation::CCallsign &requestedForCallsign, bool likelyOnGroundElevation, const geo::ICoordinateGeodetic &elevationCoordinate, const physical_quantities::CLength &epsilon=geo::CElevationPlane::singlePointRadius())
Remember a given elevation.
bool insertCG(const physical_quantities::CLength &cg, const aviation::CCallsign &cs)
Insert or replace a CG.
int setMaxElevationsRemembered(int max)
Set number of elevations kept.
CSimulatorInfo getSimulatorInfo() const
Get the represented simulator.
QString getSimulatorName() const
Simulator name as set from the running simulator.
physical_quantities::CLength overriddenCGorDefault(const physical_quantities::CLength &defaultCG, const QString &modelString) const
Return the overridden CG value or the given default CG value.
CSimulatorSettings getSettings(const CSimulatorInfo &simulator) const
Settings per simulator.
Settings for simulator Driver independent parts (such as directories), also used in model loaders.
swift::misc::physical_quantities::CLength getRecordedGndRadius() const
Record GND values with radius.
CGSource
Where we get the CG (aka vertical offset) from.
bool isRecordOwnAircraftGnd() const
Record GND values (of own aircraft)
CGSource getCGSource() const
CG source.
Allows to have specific utility functions for each simulator.
const CSimulatorSettings & getSimulatorSettings() const
The generic settings.
const QString & getSimulatorDirectoryOrDefault() const
Simulator directory or default path.
Classes interacting with the swift database (aka "datastore").
Backend services of the swift project, like dealing with the network or the simulators.
Free functions in swift::misc.
QString className(const QObject *object)
Class name as from QMetaObject::className with namespace.
auto singleShot(int msec, QObject *target, F &&task)
Starts a single-shot timer which will call a task in the thread of the given object when it times out...
Log entry for parts interpolation.
qint64 tsCurrent
current timestamp
QString toQString(const QString &separator={ " " }) const
To string.
Log entry for situation interpolation.
QString toQString(bool withSetup, bool withCurrentSituation, bool withElevation, bool withOtherPositions, bool withDeltaTimes, const QString &separator={ " " }) const
To string.
qint64 tsCurrent
current timestamp
CInterpolationAndRenderingSetupPerCallsign usedSetup
used setup
#define SWIFT_AUDIT_X(COND, WHERE, WHAT)
A weaker kind of verify.
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.