diff --git a/src/blackcore/context_runtime.cpp b/src/blackcore/context_runtime.cpp new file mode 100644 index 000000000..fe58f62ef --- /dev/null +++ b/src/blackcore/context_runtime.cpp @@ -0,0 +1,252 @@ +#include "blackcore/context_runtime.h" +#include "blackmisc/blackmiscfreefunctions.h" +#include "blackmisc/nwserver.h" + +#include "blackcore/context_application_impl.h" +#include "blackcore/context_network_impl.h" +#include "blackcore/context_settings_impl.h" +#include "blackcore/context_audio_impl.h" +#include "blackcore/context_simulator_impl.h" + +#include "blackcore/context_application_proxy.h" +#include "blackcore/context_network_proxy.h" +#include "blackcore/context_settings_proxy.h" +#include "blackcore/context_audio_proxy.h" +#include "blackcore/context_simulator_proxy.h" + + +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_contextNetwork(nullptr), m_contextAudio(nullptr), + m_contextSettings(nullptr), m_contextApplication(nullptr), + m_contextSimulator(nullptr) + { + this->init(config); + } + + /* + * Init runtime + */ + void CRuntime::init(const CRuntimeConfig &config) + { + if (m_init) return; + BlackMisc::registerMetadata(); + BlackMisc::initResources(); + + // upfront reading of settings, as DBus server alread relies on + // settings + CContextSettings *settings = nullptr; + QString dbusServerAddress; + if (config.hasLocalSettings()) + { + settings = new CContextSettings(config.getModeSettings(), this); + if (settings) settings->read(); + dbusServerAddress = settings->getNetworkSettings().getDBusServerAddress(); + } + + // contexts + switch (config.getModeSettings()) + { + case CRuntimeConfig::Local: + this->m_contextSettings = settings; + break; + case CRuntimeConfig::LocalInDbusServer: + this->initDBusServer(dbusServerAddress); + this->m_contextSettings = settings->registerWithDBus(this->m_dbusServer); + break; + case CRuntimeConfig::Remote: + this->initDBusConnection(); + this->m_contextSettings = new BlackCore::CContextSettingsProxy(BlackCore::CDBusServer::ServiceName, this->m_dbusConnection, config.getModeSettings(), this); + break; + default: + break; + } + + switch (config.getModeApplication()) + { + case CRuntimeConfig::Local: + this->m_contextApplication = new CContextApplication(config.getModeApplication(), this); + break; + case CRuntimeConfig::LocalInDbusServer: + this->initDBusServer(dbusServerAddress); + this->m_contextApplication = (new CContextApplication(config.getModeApplication(), this))->registerWithDBus(this->m_dbusServer); + break; + case CRuntimeConfig::Remote: + this->initDBusConnection(); + this->m_contextApplication = new BlackCore::CContextApplicationProxy(BlackCore::CDBusServer::ServiceName, this->m_dbusConnection, config.getModeApplication(), this); + break; + default: + break; + } + + switch (config.getModeAudio()) + { + case CRuntimeConfig::Local: + this->m_contextAudio = new CContextAudio(config.getModeAudio(), this); + break; + case CRuntimeConfig::LocalInDbusServer: + this->initDBusServer(dbusServerAddress); + this->m_contextAudio = (new CContextAudio(config.getModeAudio(), this))->registerWithDBus(this->m_dbusServer); + break; + case CRuntimeConfig::Remote: + this->initDBusConnection(); + this->m_contextAudio = new BlackCore::CContextAudioProxy(BlackCore::CDBusServer::ServiceName, this->m_dbusConnection, config.getModeAudio(), this); + break; + default: + break; + } + + switch (config.getModeNetwork()) + { + case CRuntimeConfig::Local: + this->m_contextNetwork = new CContextNetwork(config.getModeNetwork(), this); + break; + case CRuntimeConfig::LocalInDbusServer: + this->initDBusServer(dbusServerAddress); + this->m_contextNetwork = (new CContextNetwork(config.getModeNetwork(), this))->registerWithDBus(this->m_dbusServer); + break; + case CRuntimeConfig::Remote: + this->initDBusConnection(); + this->m_contextNetwork = new BlackCore::CContextNetworkProxy(BlackCore::CDBusServer::ServiceName, this->m_dbusConnection, config.getModeNetwork(), this); + break; + default: + break; + } + + switch (config.getModeSimulator()) + { + case CRuntimeConfig::Local: + this->m_contextSimulator = new CContextSimulator(config.getModeSimulator(), this); + break; + case CRuntimeConfig::LocalInDbusServer: + this->initDBusServer(dbusServerAddress); + this->m_contextSimulator = (new CContextSimulator(config.getModeSimulator(), this))->registerWithDBus(this->m_dbusServer); + break; + case CRuntimeConfig::Remote: + this->initDBusConnection(); + this->m_contextSimulator = new BlackCore::CContextSimulatorProxy(BlackCore::CDBusServer::ServiceName, this->m_dbusConnection, config.getModeSimulator(), this); + break; + default: + break; + } + + // post inits, wiring things among context (e.g. signal slots) + this->initPostSetup(); + + // flag + m_init = true; + } + + void CRuntime::initDBusServer(const QString &dBusAddress) + { + if (this->m_dbusServer) return; + Q_ASSERT(!dBusAddress.isEmpty()); + this->m_dbusServer = new CDBusServer(dBusAddress, this); + } + + void CRuntime::initPostSetup() + { + if (this->m_contextSettings && this->m_contextAudio && this->m_contextSettings->usingLocalObjects()) + { + // only, when both contexts exists and only if settings originate locally + connect(this->m_contextSettings, &IContextSettings::changedSettings, + this->getCContextAudio(), &CContextAudio::settingsChanged); + } + } + + void CRuntime::initDBusConnection() + { + if (this->m_initDBusConnection) return; + this->m_dbusConnection = QDBusConnection::sessionBus(); + } + + IContextNetwork *CRuntime::getIContextNetwork() + { + Q_ASSERT_X(this->m_contextSettings, "CCoreRuntime", "Requested missing network context"); + return this->m_contextNetwork; + } + + const IContextNetwork *CRuntime::getIContextNetwork() const + { + Q_ASSERT_X(this->m_contextSettings, "CCoreRuntime", "Requested missing network context"); + return this->m_contextNetwork; + } + + IContextAudio *CRuntime::getIContextAudio() + { + Q_ASSERT_X(this->m_contextSettings, "CCoreRuntime", "Requested missing audio context"); + return this->m_contextAudio; + } + + const IContextAudio *CRuntime::getIContextAudio() const + { + Q_ASSERT_X(this->m_contextSettings, "CCoreRuntime", "Requested missing audio context"); + return this->m_contextAudio; + } + + IContextSettings *CRuntime::getIContextSettings() + { + Q_ASSERT_X(this->m_contextSettings, "CCoreRuntime", "Requested missing settings context"); + return this->m_contextSettings; + } + + const IContextSettings *CRuntime::getIContextSettings() const + { + Q_ASSERT_X(this->m_contextSettings, "CCoreRuntime", "Requested missing settings context"); + return this->m_contextSettings; + } + + const IContextApplication *CRuntime::getIContextApplication() const + { + Q_ASSERT_X(this->m_contextSettings, "CCoreRuntime", "Requested missing application context"); + return this->m_contextApplication; + } + + IContextApplication *CRuntime::getIContextApplication() + { + Q_ASSERT_X(this->m_contextSettings, "CCoreRuntime", "Requested missing application context"); + return this->m_contextApplication; + } + + const IContextSimulator *CRuntime::getIContextSimulator() const + { + Q_ASSERT_X(this->m_contextSettings, "CCoreRuntime", "Requested missing simulator context"); + return this->m_contextSimulator; + } + + IContextSimulator *CRuntime::getIContextSimulator() + { + Q_ASSERT_X(this->m_contextSettings, "CCoreRuntime", "Requested missing simulator context"); + return this->m_contextSimulator; + } + + CContextAudio *CRuntime::getCContextAudio() + { + Q_ASSERT_X(this->m_contextSettings, "CCoreRuntime", "Requested missing audio context"); + Q_ASSERT_X(this->m_contextSimulator->usingLocalObjects(), "CCoreRuntime", "Cannot specialize to local object"); + return static_cast(this->m_contextAudio); + } + + const CRuntimeConfig &CRuntimeConfig::forCore() + { + static CRuntimeConfig cfg = CRuntimeConfig(CRuntimeConfig(CRuntimeConfig::LocalInDbusServer)); + return cfg; + } + + const CRuntimeConfig &CRuntimeConfig::local() + { + static CRuntimeConfig cfg = CRuntimeConfig(CRuntimeConfig(CRuntimeConfig::Local)); + return cfg; + } + + const CRuntimeConfig &CRuntimeConfig::remote() + { + static CRuntimeConfig cfg = CRuntimeConfig(CRuntimeConfig(CRuntimeConfig::Remote)); + return cfg; + } +} diff --git a/src/blackcore/context_runtime.h b/src/blackcore/context_runtime.h new file mode 100644 index 000000000..08539491c --- /dev/null +++ b/src/blackcore/context_runtime.h @@ -0,0 +1,100 @@ +#ifndef BLACKCORE_CONTEXT_RUNTIME_H +#define BLACKCORE_CONTEXT_RUNTIME_H + +#include +#include +#include "blackcore/context_runtime_config.h" + +namespace BlackCore +{ + // forward declaration, see review + // https://dev.vatsim-germany.org/boards/22/topics/1350?r=1359#message-1359 + class CDBusServer; + class CContextNetwork; + class CContextAudio; + class CContextSettings; + class CContextApplication; + class CContextSimulator; + class IContextNetwork; + class IContextAudio; + class IContextSettings; + class IContextApplication; + class IContextSimulator; + + //! The Context runtime class + class CRuntime : public QObject + { + Q_OBJECT + + private: + bool m_init; /*!< flag */ + CDBusServer *m_dbusServer; + bool m_initDBusConnection; + QDBusConnection m_dbusConnection; + IContextNetwork *m_contextNetwork; + IContextAudio *m_contextAudio; + IContextSettings *m_contextSettings; + IContextApplication *m_contextApplication; + IContextSimulator *m_contextSimulator; + + //! Init + void init(const CRuntimeConfig &config); + + //! initialization of DBus connection (where applicable) + void initDBusConnection(); + + //! initialization of DBus connection (where applicable) + void initDBusServer(const QString &dBusAddress); + + //! post init tasks, mainly connecting context signal slots + void initPostSetup(); + + public: + //! Constructor + CRuntime(const CRuntimeConfig &config, QObject *parent = nullptr); + + //! Destructor + virtual ~CRuntime() {} + + //! DBus server + const CDBusServer *getDBusServer() const + { + return this->m_dbusServer; + } + + //! Context for network + IContextNetwork *getIContextNetwork(); + + //! Context for network + const IContextNetwork *getIContextNetwork() const; + + //! Context for network + IContextAudio *getIContextAudio(); + + //! Context for network + const IContextAudio *getIContextAudio() const; + + //! Settings + IContextSettings *getIContextSettings(); + + //! Settings + const IContextSettings *getIContextSettings() const; + + //! Context for application + const IContextApplication *getIContextApplication() const; + + //! Application + IContextApplication *getIContextApplication(); + + //! Context for simulator + const IContextSimulator *getIContextSimulator() const; + + //! Simulator + IContextSimulator *getIContextSimulator(); + + private: + CContextAudio *getCContextAudio(); + CContextAudio *getCContextAudio() const; + }; +} +#endif // guard diff --git a/src/blackcore/context_runtime_config.h b/src/blackcore/context_runtime_config.h new file mode 100644 index 000000000..bead6937d --- /dev/null +++ b/src/blackcore/context_runtime_config.h @@ -0,0 +1,63 @@ +#ifndef BLACKCORE_CONTEXT_RUNTIME_CONFIG_H +#define BLACKCORE_CONTEXT_RUNTIME_CONFIG_H + +namespace BlackCore +{ + //! Helper to correctly run a context + class CRuntimeConfig + { + + public: + //! How to handle a given context + enum ContextMode + { + NotUsed, + Local, + LocalInDbusServer, + Remote + }; + + private: + ContextMode m_settings; + ContextMode m_audio; + ContextMode m_network; + ContextMode m_simulator; + ContextMode m_application; + + public: + + //! Constructor + CRuntimeConfig(ContextMode allTheSame): + m_settings(allTheSame), m_audio(allTheSame), m_network(allTheSame), m_simulator(allTheSame), m_application(allTheSame) + {} + + //! Constructor + CRuntimeConfig(ContextMode settings, ContextMode audio, ContextMode network, ContextMode simulator, ContextMode application): + m_settings(settings), m_audio(audio), m_network(network), m_simulator(simulator), m_application(application) + {} + + //! settings mode + ContextMode getModeSettings() const { return this->m_settings; } + //! audio mode + ContextMode getModeAudio() const { return this->m_audio; } + //! network mode + ContextMode getModeNetwork() const { return this->m_network; } + //! simulator mode + ContextMode getModeSimulator() const { return this->m_simulator; } + //! application mode + ContextMode getModeApplication() const { return this->m_application; } + //! local settings? + bool hasLocalSettings() const { return this->m_settings == Local || this->m_settings == LocalInDbusServer; } + + //! predefined for Core + static const CRuntimeConfig &forCore(); + + //! predefined, completely local (e.g. for unit tests) + static const CRuntimeConfig &local(); + + //! predefined, completely remote (e.g. for GUI with core) + static const CRuntimeConfig &remote(); + + }; +} +#endif // guard