refs #199, featuring proxy to server side DBus signals.

So far we only could send server to proxy side signals, causing inconsistencies between remote and local contexts
This commit is contained in:
Klaus Basan
2014-04-08 17:24:45 +02:00
parent 760376d848
commit 60fc8b7074
6 changed files with 95 additions and 5 deletions

View File

@@ -1,4 +1,5 @@
#include "context.h" #include "context.h"
#include <QDebug>
namespace BlackCore namespace BlackCore
{ {
@@ -48,6 +49,26 @@ namespace BlackCore
return this->getRuntime()->getIContextSimulator(); return this->getRuntime()->getIContextSimulator();
} }
void CContext::reEmitSignalFromProxy(const QString &signalName)
{
if (signalName.isEmpty()) return;
if (this->usingLocalObjects())
{
// resent in implementation
QString sn = signalName;
if (!sn.endsWith("()")) sn.append("()");
const QMetaObject *metaObject = this->metaObject();
int signalId = metaObject->indexOfSignal(sn.toUtf8().constData());
Q_ASSERT(signalId >= 0);
void *a[] = { 0 };
QMetaObject::activate(this, signalId, a);
}
else
{
Q_ASSERT_X(false, "signalFromProxy", "Proxy needs to override method");
}
}
const IContextSimulator *CContext::getIContextSimulator() const const IContextSimulator *CContext::getIContextSimulator() const
{ {
return this->getRuntime()->getIContextSimulator(); return this->getRuntime()->getIContextSimulator();

View File

@@ -7,7 +7,7 @@
#define BLACKCORE_CONTEXTAPPLICATION_H #define BLACKCORE_CONTEXTAPPLICATION_H
#include "blackcore/context.h" #include "blackcore/context.h"
#include "blackmisc/statusmessage.h" #include "blackmisc/statusmessagelist.h"
#include <QObject> #include <QObject>
#define BLACKCORE_CONTEXTAPPLICATION_INTERFACENAME "net.vatsim.PilotClient.BlackCore.ContextApplication" #define BLACKCORE_CONTEXTAPPLICATION_INTERFACENAME "net.vatsim.PilotClient.BlackCore.ContextApplication"
@@ -29,6 +29,15 @@ namespace BlackCore
public: public:
//! What output to redirect
enum RedirectionLevel
{
RedirectNone,
RedirectAllOutput,
RedirectWarningAndAbove,
RedirectError
};
//! Service name //! Service name
static const QString &InterfaceName() static const QString &InterfaceName()
{ {
@@ -46,20 +55,51 @@ namespace BlackCore
//! Destructor //! Destructor
virtual ~IContextApplication() {} virtual ~IContextApplication() {}
//! Output redirection (redirect my output)
virtual RedirectionLevel getOutputRedirectionLevel() const = 0;
//! Output redirection (redirect my output)
virtual void setOutputRedirectionLevel(RedirectionLevel level) = 0;
//! Redirected output generated by others
virtual RedirectionLevel getStreamingForRedirectedOutputLevel() const = 0;
//! Redirected output generated by others
virtual void setStreamingForRedirectedOutputLevel(RedirectionLevel level) = 0;
signals: signals:
//! \brief Status message //! \brief Status message
//! \remarks not to be called directly, use IContextApplication::sendStatusMessage
void statusMessage(const BlackMisc::CStatusMessage &message); void statusMessage(const BlackMisc::CStatusMessage &message);
//! Send status messages
//! \remarks not to be called directly, use IContextApplication::sendStatusMessages
void statusMessages(const BlackMisc::CStatusMessageList &messages);
//! Redirect output streams as by qDebug(), qWarning(), qCritical()
//! \remarks context mode is an important means to avoid infinite redirect loops
//! never output redirected stream messages from the same context again
void redirectedOutput(const BlackMisc::CStatusMessage &message, qint64 contextId);
//! Widget GUI is about to start //! Widget GUI is about to start
void widgetGuiStarting() const; void widgetGuiStarting();
//! Widget GUI is about to terminate //! Widget GUI is about to terminate
void widgetGuiTerminating() const; void widgetGuiTerminating();
public slots: public slots:
//! \brief Ping a token, used to check if application is alive //! \brief Ping a token, used to check if application is alive
virtual qint64 ping(qint64 token) const = 0; virtual qint64 ping(qint64 token) const = 0;
//! \copydoc CContext::reEmitSignalFromProxy
virtual void signalFromProxy(const QString &signalName) = 0;
//! \brief Status message
virtual void sendStatusMessage(const BlackMisc::CStatusMessage &message) = 0;
//! Send status messages
virtual void sendStatusMessages(const BlackMisc::CStatusMessageList &messages) = 0;
}; };
} }

View File

@@ -27,4 +27,11 @@ namespace BlackCore
{ {
return token; return token;
} }
* Re-emit signal
*/
void CContextApplication::signalFromProxy(const QString &signalName)
{
CContext::reEmitSignalFromProxy(signalName);
}
} // namespace } // namespace

View File

@@ -23,6 +23,9 @@ namespace BlackCore
Q_OBJECT Q_OBJECT
friend class CRuntime; friend class CRuntime;
//! \copydoc CContext::reEmitSignalFromProxy
virtual void signalFromProxy(const QString &signalName) override;
protected: protected:
//! Constructor //! Constructor
CContextApplication(CRuntimeConfig::ContextMode mode, CRuntime *runtime); CContextApplication(CRuntimeConfig::ContextMode mode, CRuntime *runtime);

View File

@@ -26,12 +26,20 @@ namespace BlackCore
*/ */
void CContextApplicationProxy::relaySignals(const QString &serviceName, QDBusConnection &connection) void CContextApplicationProxy::relaySignals(const QString &serviceName, QDBusConnection &connection)
{ {
// signals originating from impl side
connection.connect(serviceName, IContextApplication::ObjectPath(), IContextApplication::InterfaceName(), connection.connect(serviceName, IContextApplication::ObjectPath(), IContextApplication::InterfaceName(),
"statusMessage", this, SIGNAL(statusMessage(BlackMisc::CStatusMessage))); "statusMessage", this, SIGNAL(statusMessage(BlackMisc::CStatusMessage)));
connection.connect(serviceName, IContextApplication::ObjectPath(), IContextApplication::InterfaceName(), connection.connect(serviceName, IContextApplication::ObjectPath(), IContextApplication::InterfaceName(),
"widgetGuiStarting", this, SIGNAL(widgetGuiStarting())); "statusMessages", this, SIGNAL(statusMessages(BlackMisc::CStatusMessageList)));
connection.connect(serviceName, IContextApplication::ObjectPath(), IContextApplication::InterfaceName(), connection.connect(serviceName, IContextApplication::ObjectPath(), IContextApplication::InterfaceName(),
"widgetGuiTerminating", this, SIGNAL(widgetGuiTerminating())); "redirectedOutput", this, SIGNAL(redirectedOutput(BlackMisc::CStatusMessage, qint64)));
// 1. No need to connect widgetGuiTerminating, only orginates from Proxy side / or is local
// 2. No need to connect widgetGuiStarting
// signals originating from proxy side
connect(this, &CContextApplicationProxy::widgetGuiStarting, [this] { this->signalFromProxy("widgetGuiStarting");});
connect(this, &CContextApplicationProxy::widgetGuiTerminating, [this] { this->signalFromProxy("widgetGuiTerminating");});
} }
/* /*
@@ -43,4 +51,12 @@ namespace BlackCore
return t; return t;
} }
/*
* Signal from proxy
*/
void CContextApplicationProxy::signalFromProxy(const QString &signalName)
{
this->m_dBusInterface->callDBus(QLatin1Literal("signalFromProxy"), signalName);
}
} // namespace } // namespace

View File

@@ -28,6 +28,9 @@ namespace BlackCore
//! \copydoc IContextApplication::ping() //! \copydoc IContextApplication::ping()
virtual qint64 ping(qint64 token) const override; virtual qint64 ping(qint64 token) const override;
//! \copydoc CContext::reEmitSignalFromProxy
void signalFromProxy(const QString &signalName) override;
protected: protected:
//! Constructor //! Constructor
CContextApplicationProxy(CRuntimeConfig::ContextMode mode, CRuntime *runtime) : IContextApplication(mode, runtime), m_dBusInterface(nullptr) {} CContextApplicationProxy(CRuntimeConfig::ContextMode mode, CRuntime *runtime) : IContextApplication(mode, runtime), m_dBusInterface(nullptr) {}