diff --git a/src/blackcore/context.cpp b/src/blackcore/context.cpp index a0a834119..9daa1063d 100644 --- a/src/blackcore/context.cpp +++ b/src/blackcore/context.cpp @@ -1,6 +1,16 @@ +/* Copyright (C) 2013 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ #include "context.h" #include +using namespace BlackMisc; + namespace BlackCore { @@ -63,4 +73,10 @@ namespace BlackCore { return this->getRuntime()->getIContextSimulator(); } -} + + const CStatusMessage &CContext::statusMessageEmptyContext() + { + static const CStatusMessage m("swift.context.emptycontext", CStatusMessage::SeverityWarning, "empty context"); + return m; + } +} // namespace diff --git a/src/blackcore/context.h b/src/blackcore/context.h index d4eb88d8f..dbe793c5a 100644 --- a/src/blackcore/context.h +++ b/src/blackcore/context.h @@ -1,3 +1,12 @@ +/* Copyright (C) 2013 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + #ifndef BLACKCORE_CONTEXT_H #define BLACKCORE_CONTEXT_H @@ -17,12 +26,24 @@ namespace BlackCore //! Destructor ~CContext() {} - //! Using local objects? - bool usingLocalObjects() const + //! Using local implementing object? + bool isUsingImplementingObject() const { return m_mode == CRuntimeConfig::Local || m_mode == CRuntimeConfig::LocalInDbusServer; } + //! Local or remote object? + bool isLocalObject() const + { + return isUsingImplementingObject() || m_mode == CRuntimeConfig::NotUsed; + } + + //! Empty object? + bool isEmptyObject() const + { + return m_mode == CRuntimeConfig::NotUsed; + } + //! Runtime CRuntime *getRuntime() { @@ -98,11 +119,11 @@ namespace BlackCore //! Path and context id QString buildPathAndContextId(const QString &path) const { - return QString(path). - append(':'). - append(QString::number(this->getUniqueId())); + return QString(path) + ":" + QString::number(this->getUniqueId()); } + //! Standard message when status message is returned in empty context + static const BlackMisc::CStatusMessage &statusMessageEmptyContext(); }; } #endif // guard diff --git a/src/blackcore/context_network.cpp b/src/blackcore/context_network.cpp index 7c86f8e23..e5ce2f91b 100644 --- a/src/blackcore/context_network.cpp +++ b/src/blackcore/context_network.cpp @@ -10,22 +10,24 @@ #include "context_network.h" #include "context_network_impl.h" #include "context_network_proxy.h" +#include "context_network_empty.h" namespace BlackCore { - IContextNetwork *IContextNetwork::create(CRuntime *parent, CRuntimeConfig::ContextMode mode, CDBusServer *server, QDBusConnection &conn) + IContextNetwork *IContextNetwork::create(CRuntime *runtime, CRuntimeConfig::ContextMode mode, CDBusServer *server, QDBusConnection &conn) { switch (mode) { case CRuntimeConfig::Local: case CRuntimeConfig::LocalInDbusServer: - return (new CContextNetwork(mode, parent))->registerWithDBus(server); + return (new CContextNetwork(mode, runtime))->registerWithDBus(server); case CRuntimeConfig::Remote: - return new BlackCore::CContextNetworkProxy(BlackCore::CDBusServer::ServiceName, conn, mode, parent); + return new BlackCore::CContextNetworkProxy(BlackCore::CDBusServer::ServiceName, conn, mode, runtime); + case CRuntimeConfig::NotUsed: default: - return nullptr; // network not mandatory + return new BlackCore::CContextNetworkEmpty(true, runtime); } } -} +} // namesapce diff --git a/src/blackcore/context_network.h b/src/blackcore/context_network.h index 342af39aa..d417d5f9d 100644 --- a/src/blackcore/context_network.h +++ b/src/blackcore/context_network.h @@ -192,7 +192,6 @@ namespace BlackCore protected: //! Constructor IContextNetwork(CRuntimeConfig::ContextMode mode, CRuntime *runtime) : CContext(mode, runtime) {} - }; } diff --git a/src/blackcore/context_runtime.cpp b/src/blackcore/context_runtime.cpp index 708e4ce2f..7d5a62ff8 100644 --- a/src/blackcore/context_runtime.cpp +++ b/src/blackcore/context_runtime.cpp @@ -1,9 +1,17 @@ +/* Copyright (C) 2013 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + #include "blackcore/context_all_impl.h" #include "blackcore/context_all_proxies.h" +#include "blackcore/context_all_empties.h" #include "blackcore/blackcorefreefunctions.h" - #include "blacksim/blacksimfreefunctions.h" - #include "blackmisc/nwserver.h" #include "blackmisc/statusmessagelist.h" #include "blackmisc/avaircraft.h" @@ -18,10 +26,7 @@ namespace BlackCore /* * Constructor */ - CRuntime::CRuntime(const CRuntimeConfig &config, QObject *parent) : - QObject(parent), m_init(false), m_dbusServer(nullptr), m_initDBusConnection(false), - m_dbusConnection(QDBusConnection("default")), - m_contextApplication(nullptr), m_contextAudio(nullptr), m_contextNetwork(nullptr), m_contextSettings(nullptr), m_contextSimulator(nullptr) + CRuntime::CRuntime(const CRuntimeConfig &config, QObject *parent) : QObject(parent) { this->init(config); } @@ -94,10 +99,10 @@ namespace BlackCore // checks -------------- // 1. own aircraft and simulator should reside in same location - Q_ASSERT(!this->m_contextSimulator || (this->m_contextOwnAircraft->usingLocalObjects() == this->m_contextSimulator->usingLocalObjects())); + Q_ASSERT(!this->m_contextSimulator || (this->m_contextOwnAircraft->isUsingImplementingObject() == this->m_contextSimulator->isUsingImplementingObject())); // 2. own aircraft and network should reside in same location - Q_ASSERT(!this->m_contextNetwork || (this->m_contextOwnAircraft->usingLocalObjects() == this->m_contextNetwork->usingLocalObjects())); + Q_ASSERT(!this->m_contextNetwork || (this->m_contextOwnAircraft->isUsingImplementingObject() == this->m_contextNetwork->isUsingImplementingObject())); // post inits, wiring things among context (e.g. signal slots) this->initPostSetup(); @@ -110,13 +115,13 @@ namespace BlackCore bool CRuntime::hasRemoteApplicationContext() const { Q_ASSERT(this->m_contextApplication); - return !this->m_contextApplication->usingLocalObjects(); + return !this->m_contextApplication->isUsingImplementingObject(); } bool CRuntime::canPingApplicationContext() const { Q_ASSERT(this->m_contextApplication); - if (this->m_contextApplication->usingLocalObjects()) return true; + if (this->m_contextApplication->isUsingImplementingObject()) return true; qint64 token = QDateTime::currentMSecsSinceEpoch(); return (token == this->m_contextApplication->ping(token)); } @@ -141,10 +146,10 @@ namespace BlackCore } // local simulator? - if (this->m_contextSimulator && this->m_contextSimulator->usingLocalObjects()) + if (this->m_contextSimulator && this->m_contextSimulator->isUsingImplementingObject()) { // only connect if simulator runs locally, no round trips - if (this->m_contextNetwork && this->m_contextNetwork->usingLocalObjects()) + if (this->m_contextNetwork && this->m_contextNetwork->isUsingImplementingObject()) { c = connect(this->m_contextNetwork, &IContextNetwork::textMessagesReceived, this->getCContextSimulator(), &CContextSimulator::ps_textMessagesReceived); @@ -152,7 +157,7 @@ namespace BlackCore } // only if own aircraft runs locally - if (this->m_contextOwnAircraft && this->m_contextOwnAircraft->usingLocalObjects()) + if (this->m_contextOwnAircraft && this->m_contextOwnAircraft->isUsingImplementingObject()) { c = connect(this->m_contextOwnAircraft, &IContextOwnAircraft::changedAircraftCockpit, this->getCContextSimulator(), &CContextSimulator::ps_updateCockpitFromContext); @@ -171,7 +176,7 @@ namespace BlackCore } // only where network and(!) own aircraft run locally - if (this->m_contextNetwork && this->m_contextOwnAircraft && this->m_contextNetwork->usingLocalObjects() && this->m_contextOwnAircraft->usingLocalObjects()) + if (this->m_contextNetwork && this->m_contextOwnAircraft && this->m_contextNetwork->isUsingImplementingObject() && this->m_contextOwnAircraft->isUsingImplementingObject()) { c = this->connect(this->m_contextNetwork, &IContextNetwork::changedAtcStationOnlineConnectionStatus, this->getCContextOwnAircraft(), &CContextOwnAircraft::ps_changedAtcStationOnlineConnectionStatus); @@ -209,12 +214,13 @@ namespace BlackCore { disconnect(this->getIContextNetwork()); this->getIContextNetwork()->disconnectFromNetwork(); - if (this->m_contextNetwork->usingLocalObjects()) + if (this->m_contextNetwork->isUsingImplementingObject()) { this->getCContextNetwork()->gracefulShutdown(); // for threads } this->getIContextNetwork()->deleteLater(); - this->m_contextNetwork = nullptr; + // replace by dummy object avoiding nullptr issues during shutdown phase + this->m_contextNetwork = IContextNetwork::create(this, CRuntimeConfig::NotUsed, nullptr, this->m_dbusConnection); } if (this->getIContextAudio()) @@ -319,61 +325,61 @@ namespace BlackCore CContextAudio *CRuntime::getCContextAudio() { - Q_ASSERT_X(!this->m_contextAudio || this->m_contextAudio->usingLocalObjects(), "CCoreRuntime", "Cannot downcast to local object"); + Q_ASSERT_X(this->m_contextAudio && this->m_contextAudio->isUsingImplementingObject(), "CCoreRuntime", "Cannot downcast to local object"); return static_cast(this->m_contextAudio); } const CContextAudio *CRuntime::getCContextAudio() const { - Q_ASSERT_X(!this->m_contextAudio || this->m_contextAudio->usingLocalObjects(), "CCoreRuntime", "Cannot downcast to local object"); + Q_ASSERT_X(this->m_contextAudio && this->m_contextAudio->isUsingImplementingObject(), "CCoreRuntime", "Cannot downcast to local object"); return static_cast(this->m_contextAudio); } CContextApplication *CRuntime::getCContextApplication() { - Q_ASSERT_X(!this->m_contextApplication || this->m_contextApplication->usingLocalObjects(), "CCoreRuntime", "Cannot downcast to local object"); + Q_ASSERT_X(this->m_contextApplication && this->m_contextApplication->isUsingImplementingObject(), "CCoreRuntime", "Cannot downcast to local object"); return static_cast(this->m_contextApplication); } const CContextApplication *CRuntime::getCContextApplication() const { - Q_ASSERT_X(!this->m_contextApplication || this->m_contextApplication->usingLocalObjects(), "CCoreRuntime", "Cannot downcast to local object"); + Q_ASSERT_X(this->m_contextApplication && this->m_contextApplication->isUsingImplementingObject(), "CCoreRuntime", "Cannot downcast to local object"); return static_cast(this->m_contextApplication); } CContextNetwork *CRuntime::getCContextNetwork() { - Q_ASSERT_X(!this->m_contextApplication || this->m_contextNetwork->usingLocalObjects(), "CCoreRuntime", "Cannot downcast to local object"); + Q_ASSERT_X(this->m_contextNetwork && this->m_contextNetwork->isUsingImplementingObject(), "CCoreRuntime", "Cannot downcast to local object"); return static_cast(this->m_contextNetwork); } const CContextNetwork *CRuntime::getCContextNetwork() const { - Q_ASSERT_X(!this->m_contextApplication || this->m_contextNetwork->usingLocalObjects(), "CCoreRuntime", "Cannot downcast to local object"); + Q_ASSERT_X(this->m_contextNetwork && this->m_contextNetwork->isUsingImplementingObject(), "CCoreRuntime", "Cannot downcast to local object"); return static_cast(this->m_contextNetwork); } CContextOwnAircraft *CRuntime::getCContextOwnAircraft() { - Q_ASSERT_X(!this->m_contextOwnAircraft || this->m_contextOwnAircraft->usingLocalObjects(), "CCoreRuntime", "Cannot downcast to local object"); + Q_ASSERT_X(this->m_contextOwnAircraft && this->m_contextOwnAircraft->isUsingImplementingObject(), "CCoreRuntime", "Cannot downcast to local object"); return static_cast(this->m_contextOwnAircraft); } const CContextOwnAircraft *CRuntime::getCContextOwnAircraft() const { - Q_ASSERT_X(!this->m_contextOwnAircraft || this->m_contextOwnAircraft->usingLocalObjects(), "CCoreRuntime", "Cannot downcast to local object"); + Q_ASSERT_X(this->m_contextOwnAircraft && this->m_contextOwnAircraft->isUsingImplementingObject(), "CCoreRuntime", "Cannot downcast to local object"); return static_cast(this->m_contextOwnAircraft); } CContextSimulator *CRuntime::getCContextSimulator() { - Q_ASSERT_X(!this->m_contextSimulator || this->m_contextSimulator->usingLocalObjects(), "CCoreRuntime", "Cannot downcast to local object"); + Q_ASSERT_X(this->m_contextSimulator && this->m_contextSimulator->isUsingImplementingObject(), "CCoreRuntime", "Cannot downcast to local object"); return static_cast(this->m_contextSimulator); } const CContextSimulator *CRuntime::getCContextSimulator() const { - Q_ASSERT_X(!this->m_contextSimulator || this->m_contextSimulator->usingLocalObjects(), "CCoreRuntime", "Cannot downcast to local object"); + Q_ASSERT_X(this->m_contextSimulator && this->m_contextSimulator->isUsingImplementingObject(), "CCoreRuntime", "Cannot downcast to local object"); return static_cast(this->m_contextSimulator); } @@ -428,4 +434,4 @@ namespace BlackCore cfg.m_audio = CRuntimeConfig::Local; return cfg; } -} +} // namespace diff --git a/src/blackcore/context_runtime.h b/src/blackcore/context_runtime.h index 66c16c9bc..03eb5cf41 100644 --- a/src/blackcore/context_runtime.h +++ b/src/blackcore/context_runtime.h @@ -1,3 +1,14 @@ +/* Copyright (C) 2013 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + #ifndef BLACKCORE_CONTEXT_RUNTIME_H #define BLACKCORE_CONTEXT_RUNTIME_H @@ -142,18 +153,41 @@ namespace BlackCore bool canPingApplicationContext() const; private: - bool m_init; /*!< flag */ - CDBusServer *m_dbusServer; - bool m_initDBusConnection; - QDBusConnection m_dbusConnection; - IContextApplication *m_contextApplication; - IContextAudio *m_contextAudio; - IContextNetwork *m_contextNetwork; - IContextOwnAircraft *m_contextOwnAircraft; - IContextSettings *m_contextSettings; - IContextSimulator *m_contextSimulator; + bool m_init = false; /*!< flag */ + + // DBus + CDBusServer *m_dbusServer = nullptr; + QDBusConnection m_dbusConnection = QDBusConnection("default"); + bool m_initDBusConnection = false; + + // logging on signals / slots + bool m_signalLogApplication = false; + bool m_signalLogAudio = false; + bool m_signalLogNetwork = false; + bool m_signalLogOwnAircraft = false; + bool m_signalLogSettings = false; + bool m_signalLogSimulator = false; + bool m_slotLogApplication = false; + bool m_slotLogAudio = false; + bool m_slotLogNetwork = false; + bool m_slotLogOwnAircraft = false; + bool m_slotLogSettings = false; + bool m_slotLogSimulator = false; + QMultiMap m_logSignalConnections; + + // thread safety for logging mutable QReadWriteLock m_lock; + // contexts: + // There is a reason why we do not use smart pointers here. When the context is deleted + // we need to use deleteLater to gracefully shut the context + IContextApplication *m_contextApplication = nullptr; + IContextAudio *m_contextAudio = nullptr; + IContextNetwork *m_contextNetwork = nullptr; + IContextOwnAircraft *m_contextOwnAircraft = nullptr; + IContextSettings *m_contextSettings = nullptr; + IContextSimulator *m_contextSimulator = nullptr; + //! initialization of DBus connection (where applicable) void initDBusConnection(const QString &address); @@ -163,5 +197,5 @@ namespace BlackCore //! post init tasks, mainly connecting context signal slots void initPostSetup(); }; -} +} // namespace #endif // guard diff --git a/src/blackcore/context_runtime_config.h b/src/blackcore/context_runtime_config.h index da12e2933..c55f38d37 100644 --- a/src/blackcore/context_runtime_config.h +++ b/src/blackcore/context_runtime_config.h @@ -13,10 +13,10 @@ namespace BlackCore //! How to handle a given context enum ContextMode { - NotUsed, - Local, - LocalInDbusServer, - Remote + NotUsed, //!< during shutdown or not used at all + Local, //!< in same process + LocalInDbusServer, //!< in same process, also registered in DBus, will be accessed by proxy objects too + Remote //!< proxy object }; private: