18using namespace swift::misc::aviation;
19using namespace swift::misc::physical_quantities;
20using namespace swift::misc::geo;
21using namespace swift::misc::network;
22using namespace swift::misc::math;
23using namespace swift::misc::simulation;
24using namespace swift::misc::simulation::settings;
26using namespace swift::core::context;
28namespace swift::simplugin::emulated
35 Q_ASSERT_X(sApp && sApp->getIContextSimulator(), Q_FUNC_INFO,
"Need context");
38 this->onSettingsChanged();
48 this->connectOwnSignals();
56 m_monitorWidget->close();
57 m_monitorWidget->deleteLater();
58 m_monitorWidget.clear();
66 if (myself.
isNull() || !sGui || sGui->isShuttingDown())
71 m_monitorWidget->show();
77 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO);
86 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO);
88 m_renderedAircraft.clear();
89 return CSimulatorPluginCommon::disconnectFrom();
96 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO);
98 CSimulatorPluginCommon::unload();
105 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, remoteAircraft.
toQString());
114 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, callsign.
toQString());
121 if (canLog()) m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, callsigns.
toQString());
129 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, aircraft.
toQString());
138 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, aircraft.
toQString());
148 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, aircraft.
toQString(), originator.
toQString());
167 m_myAircraft.setCockpit(a);
176 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, selcal.
toQString(), originator.
toQString());
182 if (m_myAircraft.getSelcal() == selcal)
186 m_myAircraft.setSelcal(selcal);
199 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, message.
toQString());
201 m_monitorWidget->displayStatusMessage(message);
210 if (canLog()) m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, message.
toQString());
211 m_monitorWidget->displayTextMessage(message);
216 if (canLog()) m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, callsign.
toQString());
217 return m_renderedAircraft.containsCallsign(callsign);
224 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO);
226 return m_renderedAircraft.getCallsigns();
233 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO);
235 if (!m_interpolators.contains(callsign))
247 if (!m_renderedAircraft.containsCallsign(callsign))
251 m_renderedAircraft.setAircraftSituation(callsign, situation);
252 m_renderedAircraft.setAircraftPartsSynchronized(callsign, parts);
258 const bool hasRequested = CSimulatorPluginCommon::requestElevation(reference, callsign);
297 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, commandLine, originator.
toQString());
299 return CSimulatorPluginCommon::parseCommandLine(commandLine, originator);
316 m_connected = connected;
317 m_simulating = simulating;
324 return m_pluginSettings.get().getEmulatedSimulator();
329 bool changed =
false;
342 if (aircraft.
getSelcal() != m_myAircraft.getSelcal())
351 m_myAircraft.setCockpit(aircraft);
357 if (m_myAircraft.getComSystem(unit) == comSystem)
361 m_myAircraft.setComSystem(comSystem, unit);
372 if (m_myAircraft.getSelcal() == selcal)
376 m_myAircraft.setSelcal(selcal);
382 if (m_myAircraft.getSituation() == situation)
386 m_myAircraft.setSituation(situation);
393 if (m_myAircraft.getParts() == parts)
397 m_myAircraft.setParts(parts);
405 m_interpolatorFetchTimer.stop();
409 m_interpolatorFetchTimer.start(timeMs);
411 return m_interpolatorFetchTimer.isActive();
420 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO);
429 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO);
438 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO);
447 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, remoteAircraft.
toQString());
452 m_interpolators.insert(
456 m_renderedAircraft.push_back(aircraft);
463 Q_UNUSED(networkModel)
464 Q_UNUSED(currentModel)
473 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO, callsign.
toQString());
475 m_interpolators.remove(callsign);
476 const int c = m_renderedAircraft.removeByCallsign(callsign);
478 CSimulatorPluginCommon::physicallyRemoveRemoteAircraft(callsign);
486 m_monitorWidget->appendReceivingCall(Q_FUNC_INFO);
497 m_monitorWidget->show();
502 m_monitorWidget->hide();
506 return CSimulatorPluginCommon::parseDetails(parser);
509 void CSimulatorEmulated::setObjectName(
const CSimulatorInfo &info)
515 bool CSimulatorEmulated::canLog()
const {
return this->canDisplay() && m_log; }
517 bool CSimulatorEmulated::canDisplay()
const {
return sApp && !sApp->isShuttingDown() && m_monitorWidget; }
519 void CSimulatorEmulated::closeMonitor()
523 m_monitorWidget->close();
527 void CSimulatorEmulated::onSettingsChanged()
533 const CSwiftPluginSettings settings(m_pluginSettings.get());
534 m_log = settings.isLoggingFunctionCalls();
536 CSimulatorInfo simulator = settings.getEmulatedSimulator();
545 const CSimulatorPluginInfo plugin = plugins.
findBySimulator(simulator);
555 CLogMessage(
this).validationError(u
"No valid plugin in emulated driver for '%1'") << simulator.
toQString();
556 const QString sn = simulator.
toQString(
true);
557 const CSimulatorPluginInfo fakedPlugin =
559 QStringLiteral(
"Emulated, but uninstalled '%1'").arg(sn),
false);
565 this->setObjectName(simulator);
570 m_monitorWidget->updateWindowTitleAndUiValues(simulator);
574 void CSimulatorEmulated::connectOwnSignals()
577 m_connectionGuard.append(
connect(
579 [=,
this](SimulatorStatus status) {
580 if (!m_monitorWidget)
return;
581 m_monitorWidget->appendSendingCall(
"simulatorStatusChanged",
586 m_connectionGuard.append(
connect(
588 [=,
this](
const CAircraftModel &model) {
589 if (!m_monitorWidget)
return;
590 m_monitorWidget->appendSendingCall(
"ownAircraftModelChanged", model.
toQString());
594 m_connectionGuard.append(
connect(
596 [=,
this](
bool restricted,
bool enabled,
int maxAircraft,
const CLength &maxRenderedDistance) {
597 if (!m_monitorWidget)
return;
598 static const QString params(
"restricted: %1 enabled: %2 max aircraft: %3");
599 m_monitorWidget->appendSendingCall(
600 "renderRestrictionsChanged",
606 m_connectionGuard.append(
connect(
609 if (!m_monitorWidget)
return;
610 m_monitorWidget->appendSendingCall(
"interpolationAndRenderingSetupChanged");
614 m_connectionGuard.append(
connect(
616 [=,
this](
const CSimulatedAircraft &aircraft) {
617 if (!m_monitorWidget)
return;
618 m_monitorWidget->appendSendingCall(
"aircraftRenderingChanged", aircraft.
toQString());
622 m_connectionGuard.append(
connect(
624 [=,
this](
const CSimulatedAircraft &aircraft) {
625 if (!m_monitorWidget)
return;
626 m_monitorWidget->appendSendingCall(
"physicallyAddingRemoteModelFailed", aircraft.
toQString());
630 m_connectionGuard.append(
connect(
633 if (!m_monitorWidget)
return;
634 m_monitorWidget->appendSendingCall(
"airspaceSnapshotHandled");
639 void CSimulatorEmulated::updateRemoteAircraft()
643 uint32_t aircraftNumber = 0;
645 for (
const CSimulatedAircraft &aircraft : m_renderedAircraft)
648 if (!m_interpolators.contains(callsign))
652 const CInterpolationAndRenderingSetupPerCallsign setup =
654 CInterpolatorMulti *im = m_interpolators[callsign];
655 Q_ASSERT_X(im, Q_FUNC_INFO,
"interpolator missing");
656 const CInterpolationResult result = im->
getInterpolation(now, setup, aircraftNumber++);
657 const CAircraftSituation s = result;
658 const CAircraftParts p = result;
659 m_countInterpolatedParts++;
660 m_countInterpolatedSituations++;
683 Q_ASSERT_X(this->
getPluginInfo().isValid(), Q_FUNC_INFO,
"Invalid plugin");
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
void aboutToShutdown()
About to shutdown.
bool isShuttingDown() const
Is application shutting down?
const context::IContextSimulator * getIContextSimulator() const
Direct access to contexts if a CCoreFacade has been initialized.
static QString statusToString(SimulatorStatus status)
Status to string.
virtual void callbackReceivedRequestedElevation(const swift::misc::geo::CElevationPlane &plane, const swift::misc::aviation::CCallsign &callsign, bool isWater)
A requested elevation has been received.
swift::misc::simulation::settings::CMultiSimulatorSettings m_multiSettings
simulator settings for all simulators
swift::misc::aviation::CAltitude m_pseudoElevation
pseudo elevation for testing purposes
void renderRestrictionsChanged(bool restricted, bool enabled, int maxAircraft, const swift::misc::physical_quantities::CLength &maxRenderedDistance)
Render restrictions have been changed.
bool updateOwnSituationAndGroundElevation(const swift::misc::aviation::CAircraftSituation &situation)
Update own aircraft position and if suitable use it to update ground elevation.
bool isUpdateAllRemoteAircraft(qint64 currentTimestamp=-1) const
Do update all remote aircraft?
virtual bool logicallyRemoveRemoteAircraft(const swift::misc::aviation::CCallsign &callsign)
Logically remove remote aircraft from simulator. Depending on max. aircraft, enabled status etc....
void requestedElevation(const swift::misc::aviation::CCallsign &callsign)
Requested elevation, call pending.
void physicallyAddingRemoteModelFailed(const swift::misc::simulation::CSimulatedAircraft &remoteAircraft, bool disabled, bool requestFailover, const swift::misc::CStatusMessage &message)
Adding the remote model failed.
void ownAircraftModelChanged(const swift::misc::simulation::CAircraftModel &model)
Emitted when own aircraft model has changed.
void simulatorStatusChanged(swift::core::ISimulator::SimulatorStatus status)
Simulator combined status.
void finishUpdateRemoteAircraftAndSetStatistics(qint64 startTime, bool limited=false)
Update stats and flags.
void emitSimulatorCombinedStatus(SimulatorStatus oldStatus=Unspecified)
Emit the combined status.
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.
swift::misc::simulation::CInterpolationAndRenderingSetupPerCallsign getInterpolationSetupConsolidated(const swift::misc::aviation::CCallsign &callsign, bool forceFullUpdate) const
Consolidate setup with other data like from swift::misc::simulation::IRemoteAircraftProvider.
swift::misc::simulation::CInterpolationLogger m_interpolationLogger
log.interpolation
void aircraftRenderingChanged(const swift::misc::simulation::CSimulatedAircraft &aircraft)
Aircraft rendering changed.
virtual int physicallyRemoveMultipleRemoteAircraft(const swift::misc::aviation::CCallsignSet &callsigns)
Remove remote aircraft from 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...
void interpolationAndRenderingSetupChanged()
Interpolation or rendering setup changed.
virtual bool changeRemoteAircraftEnabled(const swift::misc::simulation::CSimulatedAircraft &aircraft)
Aircraft got enabled / disabled.
bool m_enablePseudoElevation
return faked elevations (testing)
void simulatorStarted(const swift::misc::simulation::CSimulatorPluginInfo &info)
Emitted when the listener discovers the simulator running.
const swift::misc::simulation::CSimulatorPluginInfo & getPluginInfo() const
Corresponding info.
ISimulatorListener(const swift::misc::simulation::CSimulatorPluginInfo &info)
Constructor.
virtual bool isShuttingDown() const
Overall (swift) application shutting down.
virtual swift::misc::simulation::CSimulatorPluginInfoList getAvailableSimulatorPlugins() const =0
Return list of available simulator plugins.
static void modalWindowToFront()
Bring any modal dialog to front.
static QWidget * mainApplicationWidget()
Main application window widget.
const CIdentifier & identifier() const
Get identifier.
Value object encapsulating information identifying a component of a modular distributed swift process...
Utility methods for simple line parsing used with the command line.
static void registerCommand(const CommandHtmlHelp &command)
Register a command.
bool matchesPart(int index, const QString &toMatch, Qt::CaseSensitivity cs=Qt::CaseInsensitive) const
Matches given part.
bool isKnownCommand() const
Known command?
static bool registered(const QString &helpContext)
Help already registered.
Streamable status message, e.g.
Status messages, e.g. from Core -> GUI.
Value object encapsulating information of aircraft's parts.
Value object encapsulating information of an aircraft's situation.
Altitude as used in aviation, can be AGL or MSL altitude.
Value object encapsulating information of a callsign.
Value object for a set of callsigns.
COM system (aka "radio").
static CComSystem getCom1System(double activeFrequencyMHz, double standbyFrequencyMHz=-1)
COM1 unit.
void setFrequencyStandby(const physical_quantities::CFrequency &frequency)
Set active frequency.
void setFrequencyActive(const physical_quantities::CFrequency &frequency)
Set active frequency.
static CComSystem getCom2System(double activeFrequencyMHz, double standbyFrequencyMHz=-1)
COM2 unit.
swift::misc::physical_quantities::CFrequency getFrequencyStandby() const
Standby frequency.
swift::misc::physical_quantities::CFrequency getFrequencyActive() const
Active frequency.
void setGeodeticHeight(const aviation::CAltitude &height)
Set height (ellipsoidal or geodetic height).
Plane of same elevation, can be a single point or larger area (e.g. airport).
static const physical_quantities::CLength & singlePointRadius()
Radius for single point.
Geodetic coordinate, a position in 3D space relative to the reference geoid.
static double randomDouble(double max=1)
Random double 0-max.
QString toQString(bool i18n=false) const
Cast as QString.
Value object encapsulating information of a text message.
Direct in memory access to client (network client) data.
static CLengthUnit m()
Meter m.
static CLengthUnit ft()
Foot ft.
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".
Aircraft model (used by another pilot, my models on disk).
InterpolatorMode getInterpolatorMode() const
Interpolator mode.
Value object for interpolator and rendering per callsign.
CInterpolationResult getInterpolation(qint64 currentTimeSinceEpoch, const CInterpolationAndRenderingSetupPerCallsign &setup, uint32_t aircraftNumber)
Get interpolated situation.
CInterpolatorMulti which can be used with QMap/QHash.
bool updateOwnParts(const aviation::CAircraftParts &parts)
Update own parts.
bool updateOwnModel(const swift::misc::simulation::CAircraftModel &model)
Update model.
bool updateCockpit(const swift::misc::simulation::CSimulatedAircraft &aircraft, const swift::misc::CIdentifier &originator)
Update cockpit, but only send signals when applicable.
bool updateSelcal(const aviation::CSelcal &selcal, const swift::misc::CIdentifier &originator)
Update cockpit, but only send signals when applicable.
CSimulatedAircraft getOwnAircraft() const
Own aircraft.
IRemoteAircraftProvider * getRemoteAircraftProvider() const
Get the aircraft provider.
bool updateAircraftRendered(const aviation::CCallsign &callsign, bool rendered)
Set aircraft rendered.
Comprehensive information of an aircraft.
const aviation::CSelcal getSelcal() const
SELCAL.
const aviation::CComSystem & getCom2System() const
Get COM2 system.
const aviation::CComSystem & getCom1System() const
Get COM1 system.
const aviation::CCallsign & getCallsign() const
Get callsign.
bool setRendered(bool rendered)
Rendered?
void setCom1System(const aviation::CComSystem &comSystem)
Set COM1 system.
const aviation::CTransponder & getTransponder() const
Get transponder.
void setCom2System(const aviation::CComSystem &comSystem)
Set COM2 system.
const simulation::CAircraftModel & getModel() const
Get model (model used for mapping).
const simulation::CAircraftModel & getNetworkModel() const
Get network model.
Simple hardcoded info about the corresponding simulator.
bool isSingleSimulator() const
Single simulator selected.
static const CSimulatorInfo & guessDefaultSimulator()
Guess a default simulator based on installation.
Describing a simulator plugin.
static const QString & identifierFromSimulatorInfo(const CSimulatorInfo &)
Simulator info to plugin indentifier, empty string if not single simulator.
bool isValid() const
Check if the provided plugin metadata is valid. Simulator plugin (driver) has to meet the following r...
CSimulatorPluginInfo findBySimulator(const swift::misc::simulation::CSimulatorInfo &simulator) const
Find by simulator.
CInterpolationAndRenderingSetupPerCallsign getInterpolationSetupPerCallsignOrDefault(const aviation::CCallsign &callsign) const
Get the setup for callsign, if not existing the global setup.
Direct threadsafe in memory access to own aircraft.
Direct thread safe in memory access to remote aircraft.
void setNewPluginInfo(const CSimulatorPluginInfo &info, const settings::CSimulatorSettings &settings, const CAircraftModel &defaultModel)
New plugin info and default model.
CSimulatorPluginCommon(const swift::misc::simulation::CSimulatorPluginInfo &info, swift::misc::simulation::IOwnAircraftProvider *ownAircraftProvider, swift::misc::simulation::IRemoteAircraftProvider *renderedAircraftProvider, swift::misc::network::IClientProvider *clientProvider, QObject *parent=nullptr)
Constructor.
bool updateOwnSimulatorSelcal(const swift::misc::aviation::CSelcal &selcal, const swift::misc::CIdentifier &originator)
Update own aircraft cockpit (usually from context).
bool isInterpolatorFetching() const
Is fetching from interpolator.
bool testSendSituationAndParts(const swift::misc::aviation::CCallsign &callsign, const swift::misc::aviation::CAircraftSituation &situation, const swift::misc::aviation::CAircraftParts &parts)
Send situation/parts for testing.
bool changeRemoteAircraftModel(const swift::misc::simulation::CSimulatedAircraft &aircraft)
Change remote aircraft per property.
swift::misc::simulation::CSimulatorInfo getEmulatedSimulator() const
The emulated simulated simulator.
bool disconnectFrom()
Disconnect from simulator.
bool physicallyAddRemoteAircraft(const swift::misc::simulation::CSimulatedAircraft &remoteAircraft)
Add new remote aircraft physically to the simulator.
void internalAircraftChanged()
Internal aircraft changed.
swift::misc::aviation::CCallsignSet physicallyRenderedAircraft() const
Physically rendered (displayed in simulator) This shall only return aircraft handled in the simulator...
CSimulatorEmulated(const swift::misc::simulation::CSimulatorPluginInfo &info, swift::misc::simulation::IOwnAircraftProvider *ownAircraftProvider, swift::misc::simulation::IRemoteAircraftProvider *remoteAircraftProvider, swift::misc::network::IClientProvider *clientProvider, QObject *parent=nullptr)
Constructor, parameters as in.
bool connectTo()
Connect to simulator.
bool updateOwnSimulatorCockpit(const swift::misc::simulation::CSimulatedAircraft &aircraft, const swift::misc::CIdentifier &originator)
Update own aircraft cockpit (usually from context).
swift::misc::CStatusMessageList getInterpolationMessages(const swift::misc::aviation::CCallsign &callsign) const
Interpolation messages for callsign.
bool logicallyRemoveRemoteAircraft(const swift::misc::aviation::CCallsign &callsign)
Logically remove remote aircraft from simulator. Depending on max. aircraft, enabled status etc....
bool requestElevation(const swift::misc::geo::ICoordinateGeodetic &reference, const swift::misc::aviation::CCallsign &callsign)
Request elevation, there is no guarantee the requested elevation will be available in the provider.
bool changeInternalSituation(const swift::misc::aviation::CAircraftSituation &situation)
Simulator internal change of situation.
friend class CSimulatorEmulatedMonitorDialog
the monitor widget represents the simulator and needs access to internals (i.e.
void displayTextMessage(const swift::misc::network::CTextMessage &message) const
Display a text message.
bool changeInternalCom(const swift::misc::simulation::CSimulatedAircraft &aircraft)
Simulator internal change of COM values.
bool isSimulating() const
Simulator running?
bool setInterpolatorFetchTime(int timeMs)
Interpolator fetch time, <=0 stops.
void unload()
Driver will be unloaded.
bool parseDetails(const swift::misc::CSimpleCommandParser &parser)
Parsed in derived classes.
static void registerHelp()
Register help.
bool changeInternalParts(const swift::misc::aviation::CAircraftParts &parts)
Simulator internal change of parts.
~CSimulatorEmulated()
Destructor.
int physicallyRemoveMultipleRemoteAircraft(const swift::misc::aviation::CCallsignSet &callsigns)
Remove remote aircraft from simulator.
bool changeInternalSelcal(const swift::misc::aviation::CSelcal &selcal)
Simulator internal change of SELCAL.
bool changeRemoteAircraftEnabled(const swift::misc::simulation::CSimulatedAircraft &aircraft)
Aircraft got enabled / disabled.
bool logicallyAddRemoteAircraft(const swift::misc::simulation::CSimulatedAircraft &remoteAircraft)
Logically add a new aircraft. Depending on max. aircraft, enabled status etc. it will physically adde...
bool physicallyRemoveRemoteAircraft(const swift::misc::aviation::CCallsign &callsign)
Remove remote aircraft from simulator.
bool isConnected() const
Are we connected to the simulator?
bool isPaused() const
Simulator paused?
bool isPhysicallyRenderedAircraft(const swift::misc::aviation::CCallsign &callsign) const
Is the aircraft rendered (displayed in simulator)? This shall only return true if the aircraft is rea...
void displayStatusMessage(const swift::misc::CStatusMessage &message) const
Display a status message in the simulator.
void setCombinedStatus(bool connected, bool simulating, bool paused)
UI setter.
int physicallyRemoveAllRemoteAircraft()
Remove all remote aircraft and their data via ISimulator::clearAllRemoteAircraftData.
void startImpl()
Plugin specific implementation to start listener.
CSimulatorEmulatedListener(const swift::misc::simulation::CSimulatorPluginInfo &info)
Constructor.
void checkImpl()
Plugin specific implementation to stop listener.
void stopImpl()
Plugin specific implementation to stop listener.
bool parseCommandLine(const QString &commandLine, const swift::misc::CIdentifier &originator)
Backend services of the swift project, like dealing with the network or the simulators.
Free functions in swift::misc.
SWIFT_MISC_EXPORT const QString & boolToYesNo(bool v)
Bool to yes/no.
qint64 currentMSecsSinceEpoch()
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
void setObjectName(QAnyStringView name)
bool isNull() const const