refs #310, used empty network context with runtime/context base classes

* refactored to member initialization
* adjusted asserts
* adjusted isXXObject methods
* changed create method for ContextNetwork to support empty context
* empty status message used as return value in empty context
This commit is contained in:
Klaus Basan
2014-10-08 19:08:35 +02:00
parent dc173403fc
commit 9e23b0a2c0
7 changed files with 132 additions and 54 deletions

View File

@@ -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 "context.h"
#include <QDebug> #include <QDebug>
using namespace BlackMisc;
namespace BlackCore namespace BlackCore
{ {
@@ -63,4 +73,10 @@ namespace BlackCore
{ {
return this->getRuntime()->getIContextSimulator(); return this->getRuntime()->getIContextSimulator();
} }
}
const CStatusMessage &CContext::statusMessageEmptyContext()
{
static const CStatusMessage m("swift.context.emptycontext", CStatusMessage::SeverityWarning, "empty context");
return m;
}
} // namespace

View File

@@ -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 #ifndef BLACKCORE_CONTEXT_H
#define BLACKCORE_CONTEXT_H #define BLACKCORE_CONTEXT_H
@@ -17,12 +26,24 @@ namespace BlackCore
//! Destructor //! Destructor
~CContext() {} ~CContext() {}
//! Using local objects? //! Using local implementing object?
bool usingLocalObjects() const bool isUsingImplementingObject() const
{ {
return m_mode == CRuntimeConfig::Local || m_mode == CRuntimeConfig::LocalInDbusServer; 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 //! Runtime
CRuntime *getRuntime() CRuntime *getRuntime()
{ {
@@ -98,11 +119,11 @@ namespace BlackCore
//! Path and context id //! Path and context id
QString buildPathAndContextId(const QString &path) const QString buildPathAndContextId(const QString &path) const
{ {
return QString(path). return QString(path) + ":" + QString::number(this->getUniqueId());
append(':').
append(QString::number(this->getUniqueId()));
} }
//! Standard message when status message is returned in empty context
static const BlackMisc::CStatusMessage &statusMessageEmptyContext();
}; };
} }
#endif // guard #endif // guard

View File

@@ -10,22 +10,24 @@
#include "context_network.h" #include "context_network.h"
#include "context_network_impl.h" #include "context_network_impl.h"
#include "context_network_proxy.h" #include "context_network_proxy.h"
#include "context_network_empty.h"
namespace BlackCore 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) switch (mode)
{ {
case CRuntimeConfig::Local: case CRuntimeConfig::Local:
case CRuntimeConfig::LocalInDbusServer: case CRuntimeConfig::LocalInDbusServer:
return (new CContextNetwork(mode, parent))->registerWithDBus(server); return (new CContextNetwork(mode, runtime))->registerWithDBus(server);
case CRuntimeConfig::Remote: 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: default:
return nullptr; // network not mandatory return new BlackCore::CContextNetworkEmpty(true, runtime);
} }
} }
} } // namesapce

View File

@@ -192,7 +192,6 @@ namespace BlackCore
protected: protected:
//! Constructor //! Constructor
IContextNetwork(CRuntimeConfig::ContextMode mode, CRuntime *runtime) : CContext(mode, runtime) {} IContextNetwork(CRuntimeConfig::ContextMode mode, CRuntime *runtime) : CContext(mode, runtime) {}
}; };
} }

View File

@@ -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_impl.h"
#include "blackcore/context_all_proxies.h" #include "blackcore/context_all_proxies.h"
#include "blackcore/context_all_empties.h"
#include "blackcore/blackcorefreefunctions.h" #include "blackcore/blackcorefreefunctions.h"
#include "blacksim/blacksimfreefunctions.h" #include "blacksim/blacksimfreefunctions.h"
#include "blackmisc/nwserver.h" #include "blackmisc/nwserver.h"
#include "blackmisc/statusmessagelist.h" #include "blackmisc/statusmessagelist.h"
#include "blackmisc/avaircraft.h" #include "blackmisc/avaircraft.h"
@@ -18,10 +26,7 @@ namespace BlackCore
/* /*
* Constructor * Constructor
*/ */
CRuntime::CRuntime(const CRuntimeConfig &config, QObject *parent) : CRuntime::CRuntime(const CRuntimeConfig &config, QObject *parent) : 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)
{ {
this->init(config); this->init(config);
} }
@@ -94,10 +99,10 @@ namespace BlackCore
// checks -------------- // checks --------------
// 1. own aircraft and simulator should reside in same location // 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 // 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) // post inits, wiring things among context (e.g. signal slots)
this->initPostSetup(); this->initPostSetup();
@@ -110,13 +115,13 @@ namespace BlackCore
bool CRuntime::hasRemoteApplicationContext() const bool CRuntime::hasRemoteApplicationContext() const
{ {
Q_ASSERT(this->m_contextApplication); Q_ASSERT(this->m_contextApplication);
return !this->m_contextApplication->usingLocalObjects(); return !this->m_contextApplication->isUsingImplementingObject();
} }
bool CRuntime::canPingApplicationContext() const bool CRuntime::canPingApplicationContext() const
{ {
Q_ASSERT(this->m_contextApplication); Q_ASSERT(this->m_contextApplication);
if (this->m_contextApplication->usingLocalObjects()) return true; if (this->m_contextApplication->isUsingImplementingObject()) return true;
qint64 token = QDateTime::currentMSecsSinceEpoch(); qint64 token = QDateTime::currentMSecsSinceEpoch();
return (token == this->m_contextApplication->ping(token)); return (token == this->m_contextApplication->ping(token));
} }
@@ -141,10 +146,10 @@ namespace BlackCore
} }
// local simulator? // 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 // 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, c = connect(this->m_contextNetwork, &IContextNetwork::textMessagesReceived,
this->getCContextSimulator(), &CContextSimulator::ps_textMessagesReceived); this->getCContextSimulator(), &CContextSimulator::ps_textMessagesReceived);
@@ -152,7 +157,7 @@ namespace BlackCore
} }
// only if own aircraft runs locally // 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, c = connect(this->m_contextOwnAircraft, &IContextOwnAircraft::changedAircraftCockpit,
this->getCContextSimulator(), &CContextSimulator::ps_updateCockpitFromContext); this->getCContextSimulator(), &CContextSimulator::ps_updateCockpitFromContext);
@@ -171,7 +176,7 @@ namespace BlackCore
} }
// only where network and(!) own aircraft run locally // 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, c = this->connect(this->m_contextNetwork, &IContextNetwork::changedAtcStationOnlineConnectionStatus,
this->getCContextOwnAircraft(), &CContextOwnAircraft::ps_changedAtcStationOnlineConnectionStatus); this->getCContextOwnAircraft(), &CContextOwnAircraft::ps_changedAtcStationOnlineConnectionStatus);
@@ -209,12 +214,13 @@ namespace BlackCore
{ {
disconnect(this->getIContextNetwork()); disconnect(this->getIContextNetwork());
this->getIContextNetwork()->disconnectFromNetwork(); this->getIContextNetwork()->disconnectFromNetwork();
if (this->m_contextNetwork->usingLocalObjects()) if (this->m_contextNetwork->isUsingImplementingObject())
{ {
this->getCContextNetwork()->gracefulShutdown(); // for threads this->getCContextNetwork()->gracefulShutdown(); // for threads
} }
this->getIContextNetwork()->deleteLater(); 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()) if (this->getIContextAudio())
@@ -319,61 +325,61 @@ namespace BlackCore
CContextAudio *CRuntime::getCContextAudio() 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<CContextAudio *>(this->m_contextAudio); return static_cast<CContextAudio *>(this->m_contextAudio);
} }
const CContextAudio *CRuntime::getCContextAudio() const 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<CContextAudio *>(this->m_contextAudio); return static_cast<CContextAudio *>(this->m_contextAudio);
} }
CContextApplication *CRuntime::getCContextApplication() 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<CContextApplication *>(this->m_contextApplication); return static_cast<CContextApplication *>(this->m_contextApplication);
} }
const CContextApplication *CRuntime::getCContextApplication() const 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<CContextApplication *>(this->m_contextApplication); return static_cast<CContextApplication *>(this->m_contextApplication);
} }
CContextNetwork *CRuntime::getCContextNetwork() 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<CContextNetwork *>(this->m_contextNetwork); return static_cast<CContextNetwork *>(this->m_contextNetwork);
} }
const CContextNetwork *CRuntime::getCContextNetwork() const 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<CContextNetwork *>(this->m_contextNetwork); return static_cast<CContextNetwork *>(this->m_contextNetwork);
} }
CContextOwnAircraft *CRuntime::getCContextOwnAircraft() 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<CContextOwnAircraft *>(this->m_contextOwnAircraft); return static_cast<CContextOwnAircraft *>(this->m_contextOwnAircraft);
} }
const CContextOwnAircraft *CRuntime::getCContextOwnAircraft() const 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<CContextOwnAircraft *>(this->m_contextOwnAircraft); return static_cast<CContextOwnAircraft *>(this->m_contextOwnAircraft);
} }
CContextSimulator *CRuntime::getCContextSimulator() 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<CContextSimulator *>(this->m_contextSimulator); return static_cast<CContextSimulator *>(this->m_contextSimulator);
} }
const CContextSimulator *CRuntime::getCContextSimulator() const 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<CContextSimulator *>(this->m_contextSimulator); return static_cast<CContextSimulator *>(this->m_contextSimulator);
} }
@@ -428,4 +434,4 @@ namespace BlackCore
cfg.m_audio = CRuntimeConfig::Local; cfg.m_audio = CRuntimeConfig::Local;
return cfg; return cfg;
} }
} } // namespace

View File

@@ -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 #ifndef BLACKCORE_CONTEXT_RUNTIME_H
#define BLACKCORE_CONTEXT_RUNTIME_H #define BLACKCORE_CONTEXT_RUNTIME_H
@@ -142,18 +153,41 @@ namespace BlackCore
bool canPingApplicationContext() const; bool canPingApplicationContext() const;
private: private:
bool m_init; /*!< flag */ bool m_init = false; /*!< flag */
CDBusServer *m_dbusServer;
bool m_initDBusConnection; // DBus
QDBusConnection m_dbusConnection; CDBusServer *m_dbusServer = nullptr;
IContextApplication *m_contextApplication; QDBusConnection m_dbusConnection = QDBusConnection("default");
IContextAudio *m_contextAudio; bool m_initDBusConnection = false;
IContextNetwork *m_contextNetwork;
IContextOwnAircraft *m_contextOwnAircraft; // logging on signals / slots
IContextSettings *m_contextSettings; bool m_signalLogApplication = false;
IContextSimulator *m_contextSimulator; 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<QString, QMetaObject::Connection> m_logSignalConnections;
// thread safety for logging
mutable QReadWriteLock m_lock; 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) //! initialization of DBus connection (where applicable)
void initDBusConnection(const QString &address); void initDBusConnection(const QString &address);
@@ -163,5 +197,5 @@ namespace BlackCore
//! post init tasks, mainly connecting context signal slots //! post init tasks, mainly connecting context signal slots
void initPostSetup(); void initPostSetup();
}; };
} } // namespace
#endif // guard #endif // guard

View File

@@ -13,10 +13,10 @@ namespace BlackCore
//! How to handle a given context //! How to handle a given context
enum ContextMode enum ContextMode
{ {
NotUsed, NotUsed, //!< during shutdown or not used at all
Local, Local, //!< in same process
LocalInDbusServer, LocalInDbusServer, //!< in same process, also registered in DBus, will be accessed by proxy objects too
Remote Remote //!< proxy object
}; };
private: private: