swift
corefacade.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "core/corefacade.h"
5 
6 #include <QDBusConnection>
7 #include <QElapsedTimer>
8 #include <QMap>
9 #include <QObject>
10 #include <QString>
11 #include <QStringBuilder>
12 #include <QtGlobal>
13 
14 #include "core/airspacemonitor.h"
26 #include "core/corefacadeconfig.h"
28 #include "core/registermetadata.h"
29 #include "misc/dbusserver.h"
30 #include "misc/identifier.h"
31 #include "misc/loghistory.h"
32 #include "misc/logmessage.h"
33 #include "misc/registermetadata.h"
35 #include "misc/statusmessage.h"
36 #include "misc/stringutils.h"
37 #include "misc/verify.h"
38 
39 using namespace swift::misc;
40 using namespace swift::misc::aviation;
41 using namespace swift::misc::simulation;
42 using namespace swift::core::data;
43 using namespace swift::core::context;
44 
45 namespace swift::core
46 {
47  CCoreFacade::CCoreFacade(const CCoreFacadeConfig &config, QObject *parent) : QObject(parent), m_config(config)
48  {
49  this->init();
50  }
51 
53  {
54  if (m_shuttingDown) { return { this, CStatusMessage::SeverityInfo, u"Shutdown" }; }
55  if (!m_config.requiresDBusConnection()) { return { this, CStatusMessage::SeverityInfo, u"Not DBus based" }; }
56  const QString dBusAddress = this->getDBusAddress();
57  if (dBusAddress.isEmpty()) { return { this, CStatusMessage::SeverityInfo, u"Not DBus based, no address" }; }
58  QString connectMsg;
59  if (!CContextApplicationProxy::isContextResponsive(dBusAddress, connectMsg))
60  {
61  return { this, CStatusMessage::SeverityError,
62  u"Cannot connect DBus at '" % dBusAddress % u"', reason: " % connectMsg };
63  }
64 
65  // re-init
66  m_initalized = false;
67  this->init();
68 
69  // success
70  return CStatusMessage(this, CStatusMessage::SeverityInfo, u"Re-initialized via '%1'") << dBusAddress;
71  }
72 
73  void CCoreFacade::init()
74  {
75  if (m_initalized || m_shuttingDown) { return; }
76 
78  QElapsedTimer time;
80 
81  // either use explicit setting or last value
82  const QString dbusAddress = this->getDBusAddress();
83  m_launcherSetup.setProperty(CLauncherSetup::IndexDBusAddress, dbusAddress);
84 
85  // DBus
86  time.start();
87  if (m_config.requiresDBusSever()) { this->initDBusServer(dbusAddress); }
88  if (m_config.requiresDBusConnection())
89  {
90  this->initDBusConnection(dbusAddress);
91  if (!m_dbusConnection.isConnected())
92  {
93  const QString e = m_dbusConnection.lastError().message();
94  SWIFT_VERIFY_X(false, "CRuntime::init DBus problem", e.toUtf8().constData());
95  CLogMessage(this).error(u"DBus connection failed: '%1'") << e;
96  return;
97  }
98  }
99  times.insert("DBus", time.restart());
100 
101  // shared state infrastructure
102  m_dataLinkDBus = new shared_state::CDataLinkDBus(this);
103  switch (m_config.getMode())
104  {
106  case CCoreFacadeConfig::Local: m_dataLinkDBus->initializeLocal(nullptr); break;
107  case CCoreFacadeConfig::LocalInDBusServer: m_dataLinkDBus->initializeLocal(m_dbusServer); break;
109  m_dataLinkDBus->initializeRemote(m_dbusConnection, CDBusServer::coreServiceName(m_dbusConnection));
110  break;
111  default: qFatal("Invalid application context mode");
112  }
113 
114  // shared log history
115  m_logHistorySource = new CLogHistorySource(this);
116  m_logHistorySource->initialize(m_dataLinkDBus);
117  if (m_config.getMode() == CCoreFacadeConfig::Local ||
119  {
120  m_logHistory = new CLogHistory(this);
121  m_logHistory->initialize(m_dataLinkDBus);
122  }
123 
124  if (m_config.getMode() == CCoreFacadeConfig::NotUsed)
125  {
126  m_initalized = true;
127  return;
128  }
129 
130  // contexts
131  if (m_contextApplication) { m_contextApplication->deleteLater(); }
132  m_contextApplication = IContextApplication::create(this, m_config.getMode(), m_dbusServer, m_dbusConnection);
133  times.insert("Application", time.restart());
134 
135  if (m_contextAudio) { m_contextAudio->deleteLater(); }
136  m_contextAudio = qobject_cast<CContextAudioBase *>(
137  IContextAudio::create(this, m_config.getMode(), m_dbusServer, m_dbusConnection));
138  times.insert("Audio", time.restart());
139 
140  if (m_contextOwnAircraft) { m_contextOwnAircraft->deleteLater(); }
141  m_contextOwnAircraft = IContextOwnAircraft::create(this, m_config.getMode(), m_dbusServer, m_dbusConnection);
142  times.insert("Own aircraft", time.restart());
143 
144  if (m_contextSimulator) { m_contextSimulator->deleteLater(); }
145  m_contextSimulator = IContextSimulator::create(this, m_config.getMode(), m_dbusServer, m_dbusConnection);
146  times.insert("Simulator", time.restart());
147 
148  // depends on own aircraft and simulator context, which is bad style
149  if (m_contextNetwork) { m_contextNetwork->deleteLater(); }
150  m_contextNetwork = IContextNetwork::create(this, m_config.getMode(), m_dbusServer, m_dbusConnection);
151  times.insert("Network", time.restart());
152 
153  // checks --------------
154  // 1. own aircraft and simulator should reside in same location
155  Q_ASSERT(!m_contextSimulator || (m_contextOwnAircraft->isUsingImplementingObject() ==
156  m_contextSimulator->isUsingImplementingObject()));
157 
158  // 2. own aircraft and network should reside in same location
159  Q_ASSERT(!m_contextNetwork ||
160  (m_contextOwnAircraft->isUsingImplementingObject() == m_contextNetwork->isUsingImplementingObject()));
161 
162  // post inits, wiring things among context (e.g. signal slots)
163  time.restart();
164  this->initPostSetup(times);
165  times.insert("Post setup", time.restart());
166  CLogMessage(this).info(u"Init times: %1") << qmapToString(times);
167 
168  // flag
169  m_initalized = true;
170  }
171 
173  {
176  }
177 
178  bool CCoreFacade::parseCommandLine(const QString &commandLine, const CIdentifier &originator)
179  {
180  bool handled = false;
181  // audio can be empty depending on whre it runs
182  if (this->getIContextAudio() && !this->getIContextAudio()->isEmptyObject())
183  {
184  handled = handled || this->getIContextAudio()->parseCommandLine(commandLine, originator);
185  }
186  if (this->getIContextNetwork())
187  {
188  handled = handled || this->getIContextNetwork()->parseCommandLine(commandLine, originator);
189  }
190  if (this->getIContextOwnAircraft())
191  {
192  handled = handled || this->getIContextOwnAircraft()->parseCommandLine(commandLine, originator);
193  }
194  if (this->getIContextSimulator())
195  {
196  handled = handled || this->getIContextSimulator()->parseCommandLine(commandLine, originator);
197  }
198  return handled;
199  }
200 
201  void CCoreFacade::initDBusServer(const QString &dBusAddress)
202  {
203  Q_ASSERT(!dBusAddress.isEmpty());
204  if (m_dbusServer) { m_dbusServer->deleteLater(); } // delete if there was an existing one
205  m_dbusServer = new CDBusServer(dBusAddress, this);
206  CLogMessage(this).info(u"DBus server on address: '%1'") << dBusAddress;
207  }
208 
209  void CCoreFacade::initPostSetup(QMap<QString, qint64> &times)
210  {
211  bool c = false;
212  Q_UNUSED(c) // for release version
213  QElapsedTimer time;
214  time.start();
215 
216  times.insert("Post setup, connects first", time.restart());
217 
218  // local simulator?
219  if (m_contextSimulator && m_contextSimulator->isUsingImplementingObject())
220  {
221  // only connect if network runs locally, no round trips
222  // remark: from a design perspective it would be nice if those could be avoided (seperation of concerns)
223  // those connects here reprent cross context dependencies
224  if (m_contextNetwork && m_contextNetwork->isUsingImplementingObject())
225  {
226  Q_ASSERT_X(this->getCContextNetwork(), Q_FUNC_INFO, "No local network object");
227  Q_ASSERT_X(this->getCContextNetwork()->airspace(), Q_FUNC_INFO, "No airspace object");
228 
229  c = connect(m_contextNetwork, &IContextNetwork::textMessagesReceived, this->getCContextSimulator(),
230  &CContextSimulator::xCtxTextMessagesReceived, Qt::QueuedConnection);
231  Q_ASSERT(c);
232 
233  // use readyForModelMatching instead of CAirspaceMonitor::addedAircraft, as it contains client
234  // information ready for model matching is sent delayed when all information are available
235  c = connect(m_contextNetwork, &IContextNetwork::readyForModelMatching, this->getCContextSimulator(),
236  &CContextSimulator::xCtxAddedRemoteAircraftReadyForModelMatching, Qt::QueuedConnection);
237  Q_ASSERT(c);
238  c = connect(m_contextNetwork, &IContextNetwork::removedAircraft, this->getCContextSimulator(),
239  &CContextSimulator::xCtxRemovedRemoteAircraft, Qt::QueuedConnection);
240  Q_ASSERT(c);
241  c = connect(m_contextNetwork, &IContextNetwork::changedRemoteAircraftModel,
242  this->getCContextSimulator(), &CContextSimulator::xCtxChangedRemoteAircraftModel,
244  Q_ASSERT(c);
245  c = connect(m_contextNetwork, &IContextNetwork::changedRemoteAircraftEnabled,
246  this->getCContextSimulator(), &CContextSimulator::xCtxChangedRemoteAircraftEnabled,
248  Q_ASSERT(c);
249  c = connect(m_contextNetwork, &IContextNetwork::connectionStatusChanged, this->getCContextSimulator(),
250  &CContextSimulator::xCtxNetworkConnectionStatusChanged, Qt::QueuedConnection);
251  Q_ASSERT(c);
252  c = connect(this->getCContextNetwork()->airspace(), &CAirspaceMonitor::requestedNewAircraft,
253  this->getCContextSimulator(), &CContextSimulator::xCtxNetworkRequestedNewAircraft,
255  Q_ASSERT(c);
256  c = connect(this->getCContextSimulator(), &CContextSimulator::renderRestrictionsChanged,
257  this->getCContextNetwork(), &CContextNetwork::xCtxSimulatorRenderRestrictionsChanged,
259  Q_ASSERT(c);
260  c = connect(this->getCContextSimulator(), &CContextSimulator::simulatorStatusChanged,
261  this->getCContextNetwork(), &CContextNetwork::xCtxSimulatorStatusChanged,
263  Q_ASSERT(c);
264 
265  // set provider
267  }
268 
269  // only if own aircraft runs locally
270  if (m_contextOwnAircraft && m_contextOwnAircraft->isUsingImplementingObject())
271  {
272  c = connect(m_contextOwnAircraft, &IContextOwnAircraft::changedAircraftCockpit,
273  this->getCContextSimulator(), &CContextSimulator::xCtxUpdateSimulatorCockpitFromContext);
274  Q_ASSERT(c);
275  c = connect(m_contextOwnAircraft, &IContextOwnAircraft::changedSelcal, this->getCContextSimulator(),
276  &CContextSimulator::xCtxUpdateSimulatorSelcalFromContext);
277  Q_ASSERT(c);
278 
279  // relay changed aircraft to own aircraft provider but with identifier
280  // identifier is needed because own aircraft context also reports changed aircraft to
281  // xCtxChangedOwnAircraftModel and we avoid roundtrips
282  c = connect(this->getCContextSimulator(), &CContextSimulator::ownAircraftModelChanged,
283  this->getCContextOwnAircraft(), [=](const CAircraftModel &changedModel) {
284  if (!this->getIContextOwnAircraft()) { return; }
285  if (!this->getCContextSimulator()) { return; }
286  this->getCContextOwnAircraft()->xCtxChangedSimulatorModel(
287  changedModel, this->getCContextSimulator()->identifier());
288  });
289 
290  Q_ASSERT(c);
291  c = connect(this->getCContextSimulator(), &CContextSimulator::simulatorStatusChanged,
292  this->getCContextOwnAircraft(), &CContextOwnAircraft::xCtxChangedSimulatorStatus);
293  Q_ASSERT(c);
294 
295  // this is used if the value in own aircraft is changed, to callback simulator
296  c = connect(this->getCContextOwnAircraft(), &CContextOwnAircraft::ps_changedModel,
297  this->getCContextSimulator(), &CContextSimulator::xCtxChangedOwnAircraftModel);
298  Q_ASSERT(c);
299  }
300 
301  // times
302  times.insert("Post setup, sim.connects", time.restart());
303  }
304 
305  // connection status of network changed
306  // with AFV no longer use m_contextAudio->isUsingImplementingObject() as audio can run on both sides
307  if (this->getCContextAudioBase() && m_contextNetwork)
308  {
309  Q_ASSERT(m_contextApplication);
310  c = connect(m_contextNetwork, &IContextNetwork::connectionStatusChanged, this->getCContextAudioBase(),
311  &CContextAudio::xCtxNetworkConnectionStatusChanged, Qt::QueuedConnection);
312  Q_ASSERT(c);
313  times.insert("Post setup, connects audio", time.restart());
314  }
315  }
316 
318  {
319  QString dbusAddress;
320  if (m_config.hasDBusAddress()) { dbusAddress = m_config.getDBusAddress(); }
321  else
322  {
323  const CLauncherSetup setup = m_launcherSetup.get();
324  dbusAddress = setup.getDBusAddress();
325  }
326  return dbusAddress;
327  }
328 
330  {
331  if (!m_initalized) { return; }
332  if (m_shuttingDown) { return; }
333  m_shuttingDown = true;
334 
335  // disable all signals towards runtime
336  disconnect(this);
337 
338  // tear down shared state infrastructure
339  delete m_logHistory;
340  m_logHistory = nullptr;
341  delete m_logHistorySource;
342  m_logHistorySource = nullptr;
343  delete m_dataLinkDBus;
344  m_dataLinkDBus = nullptr;
345 
346  // unregister all from DBus
347  if (m_dbusServer) { m_dbusServer->removeAllObjects(); }
348 
349  // handle contexts
350 
351  if (this->getCContextAudioBase())
352  {
353  // there is no empty audio context since AFV
356  this->getIContextAudio()->deleteLater();
357  m_contextAudio = nullptr;
358  }
359 
360  // log off from network, if connected
361  if (this->getIContextNetwork())
362  {
365  if (m_contextNetwork->isUsingImplementingObject())
366  {
367  this->getCContextNetwork()->gracefulShutdown(); // for threads
368  }
369  this->getIContextNetwork()->deleteLater();
370  // replace by dummy object avoiding nullptr issues during shutdown phase
371  QDBusConnection defaultConnection("default");
372  m_contextNetwork = IContextNetwork::create(this, CCoreFacadeConfig::NotUsed, nullptr, defaultConnection);
373  }
374 
375  if (this->getIContextSimulator())
376  {
378  if (this->getIContextSimulator()->isUsingImplementingObject())
379  {
380  // shutdown the plugins
382  }
384  QDBusConnection defaultConnection("default");
385  m_contextSimulator =
386  IContextSimulator::create(this, CCoreFacadeConfig::NotUsed, nullptr, defaultConnection);
387  }
388 
389  if (this->getIContextOwnAircraft())
390  {
393  QDBusConnection defaultConnection("default");
394  m_contextOwnAircraft =
395  IContextOwnAircraft::create(this, CCoreFacadeConfig::NotUsed, nullptr, defaultConnection);
396  }
397 
398  if (this->getIContextApplication())
399  {
402  QDBusConnection defaultConnection("default");
403  m_contextApplication =
404  IContextApplication::create(this, CCoreFacadeConfig::NotUsed, nullptr, defaultConnection);
405  }
406  }
407 
408  void CCoreFacade::initDBusConnection(const QString &address)
409  {
410  if (m_initDBusConnection) { return; }
411  if (address.isEmpty() || address == CDBusServer::sessionBusAddress())
412  {
413  QDBusConnection::disconnectFromBus(m_dbusConnection.name());
414  m_dbusConnection = QDBusConnection::sessionBus();
415  }
416  else if (address == CDBusServer::systemBusAddress())
417  {
418  QDBusConnection::disconnectFromBus(m_dbusConnection.name());
419  m_dbusConnection = QDBusConnection::systemBus();
420  }
421  else
422  {
423  const QString name(CDBusServer::p2pConnectionName() + " " + address);
425  m_dbusConnection = QDBusConnection::connectToPeer(address, name);
426  }
427  }
428 
429  const IContextApplication *CCoreFacade::getIContextApplication() const { return m_contextApplication; }
430 
431  IContextApplication *CCoreFacade::getIContextApplication() { return m_contextApplication; }
432 
433  IContextAudio *CCoreFacade::getIContextAudio() { return m_contextAudio; }
434 
435  const IContextAudio *CCoreFacade::getIContextAudio() const { return m_contextAudio; }
436 
438 
439  const CContextAudioBase *CCoreFacade::getCContextAudioBase() const { return m_contextAudio; }
440 
441  IContextNetwork *CCoreFacade::getIContextNetwork() { return m_contextNetwork; }
442 
443  const IContextNetwork *CCoreFacade::getIContextNetwork() const { return m_contextNetwork; }
444 
445  IContextOwnAircraft *CCoreFacade::getIContextOwnAircraft() { return m_contextOwnAircraft; }
446 
447  const IContextOwnAircraft *CCoreFacade::getIContextOwnAircraft() const { return m_contextOwnAircraft; }
448 
449  const IContextSimulator *CCoreFacade::getIContextSimulator() const { return m_contextSimulator; }
450 
451  IContextSimulator *CCoreFacade::getIContextSimulator() { return m_contextSimulator; }
452 
454  {
455  Q_ASSERT_X(m_contextAudio && m_contextAudio->isUsingImplementingObject(), "CCoreRuntime",
456  "Cannot downcast to local object");
457  return static_cast<CContextAudio *>(m_contextAudio);
458  }
459 
461  {
462  Q_ASSERT_X(m_contextAudio && m_contextAudio->isUsingImplementingObject(), "CCoreRuntime",
463  "Cannot downcast to local object");
464  return static_cast<CContextAudio *>(m_contextAudio);
465  }
466 
468  {
469  Q_ASSERT_X(m_contextApplication && m_contextApplication->isUsingImplementingObject(), "CCoreRuntime",
470  "Cannot downcast to local object");
471  return static_cast<CContextApplication *>(m_contextApplication);
472  }
473 
475  {
476  Q_ASSERT_X(m_contextApplication && m_contextApplication->isUsingImplementingObject(), "CCoreRuntime",
477  "Cannot downcast to local object");
478  return static_cast<CContextApplication *>(m_contextApplication);
479  }
480 
482  {
483  Q_ASSERT_X(m_contextNetwork && m_contextNetwork->isUsingImplementingObject(), "CCoreRuntime",
484  "Cannot downcast to local object");
485  return static_cast<CContextNetwork *>(m_contextNetwork);
486  }
487 
489  {
490  Q_ASSERT_X(m_contextNetwork && m_contextNetwork->isUsingImplementingObject(), "CCoreRuntime",
491  "Cannot downcast to local object");
492  return static_cast<CContextNetwork *>(m_contextNetwork);
493  }
494 
496  {
497  Q_ASSERT_X(m_contextOwnAircraft && m_contextOwnAircraft->isUsingImplementingObject(), "CCoreRuntime",
498  "Cannot downcast to local object");
499  return static_cast<CContextOwnAircraft *>(m_contextOwnAircraft);
500  }
501 
503  {
504  Q_ASSERT_X(m_contextOwnAircraft && m_contextOwnAircraft->isUsingImplementingObject(), "CCoreRuntime",
505  "Cannot downcast to local object");
506  return static_cast<CContextOwnAircraft *>(m_contextOwnAircraft);
507  }
508 
510  {
511  Q_ASSERT_X(m_contextSimulator && m_contextSimulator->isUsingImplementingObject(), "CCoreRuntime",
512  "Cannot downcast to local object");
513  return static_cast<CContextSimulator *>(m_contextSimulator);
514  }
515 
517  {
518  Q_ASSERT_X(m_contextSimulator && m_contextSimulator->isUsingImplementingObject(), "CCoreRuntime",
519  "Cannot downcast to local object");
520  return static_cast<CContextSimulator *>(m_contextSimulator);
521  }
522 } // namespace swift::core
Configuration object for the contexts.
bool hasDBusAddress() const
DBus address?
bool requiresDBusSever() const
Requires server (at least one in server)?
ContextMode getMode() const
Mode.
bool requiresDBusConnection() const
Requires DBus connection (at least one remote)?
@ NotUsed
during shutdown or not used at all
@ Local
context runs in same process
@ Remote
context runs in a different process.
@ LocalInDBusServer
context runs in same process.
QString getDBusAddress() const
DBus address.
context::CContextSimulator * getCContextSimulator()
Context for simulator.
Definition: corefacade.cpp:509
void gracefulShutdown()
Clean up (will be connected to signal QCoreApplication::aboutToQuit)
Definition: corefacade.cpp:329
context::IContextAudio * getIContextAudio()
Context for audio.
Definition: corefacade.cpp:433
context::IContextOwnAircraft * getIContextOwnAircraft()
Context for own aircraft.
Definition: corefacade.cpp:445
context::IContextApplication * getIContextApplication()
Context for application.
Definition: corefacade.cpp:431
QString getDBusAddress() const
DBus address if any.
Definition: corefacade.cpp:317
context::IContextNetwork * getIContextNetwork()
Context for network.
Definition: corefacade.cpp:441
bool parseCommandLine(const QString &commandLine, const swift::misc::CIdentifier &originator)
Parse command line in all contexts.
Definition: corefacade.cpp:178
context::CContextAudio * getCContextAudio()
Context for audio.
Definition: corefacade.cpp:453
context::IContextSimulator * getIContextSimulator()
Context for simulator.
Definition: corefacade.cpp:451
context::CContextApplication * getCContextApplication()
Context for application.
Definition: corefacade.cpp:467
swift::misc::CStatusMessage tryToReconnectWithDBus()
In case connection between DBus parties is lost, try to reconnect.
Definition: corefacade.cpp:52
context::CContextNetwork * getCContextNetwork()
Context for network.
Definition: corefacade.cpp:481
context::CContextOwnAircraft * getCContextOwnAircraft()
Context for own aircraft.
Definition: corefacade.cpp:495
static void registerMetadata()
Register metadata.
Definition: corefacade.cpp:172
context::CContextAudioBase * getCContextAudioBase()
Context for audio.
Definition: corefacade.cpp:437
void gracefulShutdown()
Graceful shutdown.
Audio context implementation.
Network context implementation.
void gracefulShutdown()
Gracefully shut down, e.g. for thread safety.
void setSimulationEnvironmentProvider(swift::misc::simulation::ISimulationEnvironmentProvider *provider)
Set the provider.
Own aircraft context implementation. Central instance of data for.
Network simulator concrete implementation.
void gracefulShutdown()
Gracefully shut down, e.g. for plugin unloading.
Audio context interface.
Definition: contextaudio.h:61
bool isUsingImplementingObject() const
Using local implementing object?
Definition: context.h:45
virtual bool parseCommandLine(const QString &commandLine, const swift::misc::CIdentifier &originator)=0
Parse a given command line.
virtual swift::misc::CStatusMessage disconnectFromNetwork()=0
Disconnect from network.
const QString & getDBusAddress() const
Destructor.
Definition: launchersetup.h:56
Custom DBusServer.
Definition: dbusserver.h:34
void removeAllObjects()
Remove all objects added with addObject.
Definition: dbusserver.cpp:297
static const QString & systemBusAddress()
Address denoting a system bus server.
Definition: dbusserver.cpp:325
static const QString & sessionBusAddress()
Address denoting a session bus server.
Definition: dbusserver.cpp:319
static const QString & p2pConnectionName()
P2P connection name.
Definition: dbusserver.cpp:399
static const QString & coreServiceName()
Default service name.
Definition: dbusserver.cpp:98
Value object encapsulating information identifying a component of a modular distributed swift process...
Definition: identifier.h:29
Records all log messages to a list that persists for the lifetime of the application.
Definition: loghistory.h:24
Allows distributed insertion of log messages into a central CLogHistory.
Definition: loghistory.h:37
Class for emitting a log message.
Definition: logmessage.h:27
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
Streamable status message, e.g.
constexpr static auto SeverityError
Status severities.
constexpr static auto SeverityInfo
Status severities.
void initialize(IDataLink *)
Publish using the given transport mechanism.
Definition: listjournal.cpp:12
void initialize(IDataLink *)
Publish using the given transport mechanism.
Definition: listmutator.cpp:12
Aircraft model (used by another pilot, my models on disk)
Definition: aircraftmodel.h:71
Core data traits (aka cached values) and classes.
Backend services of the swift project, like dealing with the network or the simulators.
Definition: actionbind.cpp:7
void registerMetadata()
Register all relevant metadata in swift::core.
Free functions in swift::misc.
void registerMetadata()
Register all relevant metadata in Misc.
QString qmapToString(const QMap< K, V > &map)
A map converted to string.
Definition: stringutils.h:136
const char * constData() const const
QDBusConnection connectToPeer(const QString &address, const QString &name)
void disconnectFromBus(const QString &name)
void disconnectFromPeer(const QString &name)
bool isConnected() const const
QDBusError lastError() const const
QString name() const const
QDBusConnection sessionBus()
QDBusConnection systemBus()
QString message() const const
qint64 restart()
QMap< Key, T >::iterator insert(QMap< Key, T >::const_iterator pos, const Key &key, const T &value)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
bool disconnect(const QMetaObject::Connection &connection)
bool isEmpty() const const
QByteArray toUtf8() const const
QueuedConnection
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.
Definition: verify.h:26