refs #199 , the context runtime now can be initialized for local and for remote objects.

* In order to configure how a context is deployed, a runtime config object has been added
* Context now only can be obtained from the runtime, the constructors of contexts will be no longer public
* The runtime is responsible for connecting signal/slots among contexts
* The runtime reads the settings
This commit is contained in:
Klaus Basan
2014-04-01 11:23:16 +02:00
parent 8603bc1cb0
commit 4441b44d53
3 changed files with 415 additions and 0 deletions

View File

@@ -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<CContextAudio *>(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;
}
}

View File

@@ -0,0 +1,100 @@
#ifndef BLACKCORE_CONTEXT_RUNTIME_H
#define BLACKCORE_CONTEXT_RUNTIME_H
#include <QDBusConnection>
#include <QObject>
#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

View File

@@ -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