DBus enabling of base classes plus sample for testing / show how to use them. Also qdbuscpp2xml plugin for blackmisc classes.

This commit is contained in:
Klaus Basan
2013-07-22 14:33:50 +02:00
parent 6736209945
commit 8b512ba818
48 changed files with 1264 additions and 52 deletions

View File

@@ -1,13 +1,13 @@
QT += core
QT += core dbus
QT -= gui
TARGET = sample_physicalquantities
TARGET = sample_quantities_avionics
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
DEPENDPATH += . ../../src
DEPENDPATH += . ../../src/blackmisc
INCLUDEPATH += . ../../src
LIBS += -L../../lib -lblackmisc
@@ -19,3 +19,5 @@ DESTDIR = ../../bin
HEADERS += *.h
SOURCES += *.cpp
OTHER_FILES +=

View File

@@ -0,0 +1,22 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="blackmisctest.testservice">
<signal name="sendStringMessage">
<arg name="message" type="s" direction="out"/>
</signal>
<method name="receiveStringMessage">
<arg name="message" type="s" direction="in"/>
</method>
<method name="receiveVariant">
<arg name="variant" type="v" direction="in"/>
</method>
<method name="receiveSpeed">
<arg name="speed" type="(didb(s)(s))" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="BlackMisc::PhysicalQuantities::CSpeed"/>
</method>
<method name="receiveComUnit">
<arg name="comUnit" type="((didb(s)(s))(didb(s)(s))i)" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="BlackMisc::Aviation::CComSystem"/>
</method>
</interface>
</node>

View File

@@ -0,0 +1,114 @@
/* Copyright (C) 2013 VATSIM Community / authors
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <QDBusMetaType>
#include <QtDBus/qdbusabstractinterface.h>
#include <QtDBus/qdbusconnection.h>
#include <QCoreApplication>
#include "testservice.h"
#include "testservice_adaptor.h"
#include "testservice_interface.h"
#include "testservicetool.h"
using namespace BlackMisc::PhysicalQuantities;
using namespace BlackMisc::Aviation;
using namespace BlackMiscTest;
/*!
* Sample tests
*/
int main(int argc, char *argv[])
{
BlackMisc::registerMetadata();
QCoreApplication a(argc, argv);
// init
if (argc < 1) {
qFatal("Missing name of executable");
}
const QString executable = QString(argv[0]);
Testservice* pTestservice = NULL;
TestserviceAdaptor* pTestserviceAdaptor = NULL;
// Create a Testservice instance and register it with the session bus only if
// the service isn't already available.
QDBusConnection connection = QDBusConnection::sessionBus();
if (!connection.interface()->isServiceRegistered(Testservice::ServiceName)) {
pTestservice = new Testservice(&a);
pTestserviceAdaptor = new TestserviceAdaptor(pTestservice);
if (!connection.registerService(Testservice::ServiceName)) {
QDBusError err = connection.lastError();
qWarning() << err.message();
qWarning() << "Started dbus-daemon.exe --session?";
qWarning() << "Created directory session.d? See https://dev.vatsim-germany.org/projects/vatpilotclient/wiki/DBusExample#Running-the-example";
qFatal("Could not register service!");
}
if (!connection.registerObject(Testservice::ServicePath, pTestservice)) {
qFatal("Could not register service object!");
}
qDebug() << "Registration running as pid: " << TestserviceTool::getPid();
if (pTestservice) qDebug() << "Service registered";
if (pTestserviceAdaptor) qDebug() << "Adaptor object registered";
new TestserviceAdaptor(pTestservice); // adaptor
QString service; // service not needed
if (QDBusConnection::sessionBus().connect(
service, Testservice::ServicePath, Testservice::ServiceName,
"sendStringMessage", pTestservice,
SLOT(receiveStringMessage(const QString &)))) {
qDebug() << "Connected object with bus sendStringMessage";
} else {
qFatal("Cannot connect service with DBus");
}
// Call myself to implement client
TestserviceTool::startNewProcess(executable, &a);
} else {
qDebug() << "Already registered, assuming 2nd pid: " << TestserviceTool::getPid();
BlackmisctestTestserviceInterface testserviceInterface(Testservice::ServiceName, Testservice::ServicePath, connection, &a);
double speedValue = 200.0;
while (true) {
QDBusMessage m = QDBusMessage::createSignal(
Testservice::ServicePath, Testservice::ServiceName,
"sendStringMessage");
//The << operator is used to add the parameters for the slot
QDateTime dtnow = QDateTime::currentDateTimeUtc();
QString msg = QString("Message from %1 at %2").arg(TestserviceTool::getPid()).arg(dtnow.toString("MM/dd/yyyy @ hh:mm:ss"));
m << msg;
// We send this as a non-replying message. This is used for sending errors, replys, signals,
// and method calls (slots) that don't return
if (connection.send(m)) {
qDebug() << "Send via low level method" << m;
}
TestserviceTool::sleep(2500);
// same as interface message
testserviceInterface.receiveStringMessage(msg);
qDebug() << "Send string via interface" << msg;
TestserviceTool::sleep(2500);
// PQs
CSpeed speed(speedValue++, BlackMisc::PhysicalQuantities::CSpeedUnit::km_h());
testserviceInterface.receiveSpeed(speed);
qDebug() << "Send speed via interface" << speed;
TestserviceTool::sleep(2500);
// Aviation
CComSystem comSystem = CComSystem("DBUS COM1", CPhysicalQuantitiesConstants::FrequencyInternationalAirDistress(), CPhysicalQuantitiesConstants::FrequencyUnicom());
testserviceInterface.receiveComUnit(comSystem);
qDebug() << "Send COM via interface" << comSystem;
TestserviceTool::sleep(2500);
}
}
return a.exec();
}

View File

@@ -0,0 +1,9 @@
Starting: dbus-daemon.exe --session
- blocks CMD (sometimes daemon continues to run when pressing CTRL/C)
- does not start without directory session.d, i.e. ..\Qt\Qt5.1.0DBus\qtbase\etc\dbus-1\session.d
qdbuscpp2xml testservice.h -x H:\Projects\QtBuilds\build-client-Qt_5_1_0_VATSIM_qmake_Microsoft_Visual_C_Compiler_10_0_x86_2-Release\bin\blackmisc_cpp2xml.dll -o BlackMiscTest.Testservice.xml
Done automatically, but if required manually
Interface: qdbusxml2cpp blackbus.testservice.xml -p itestservice
Adaptor: qdbusxml2cpp blackbus.testservice.xml -a atestservice

View File

@@ -0,0 +1,30 @@
QT += core dbus
QT -= gui
TARGET = sample_quantities_avionics_dbus
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
# Causes nmake to run qdbusxml2cpp to automatically generate the dbus adaptor and interface classes,
# then automatically adds them to the sources to compile
DBUS_ADAPTORS += BlackMiscTest.Testservice.xml
DBUS_INTERFACES += BlackMiscTest.Testservice.xml
QDBUSXML2CPP_INTERFACE_HEADER_FLAGS = -i blackmisc/blackmiscfreefunctions.h
QDBUSXML2CPP_ADAPTOR_HEADER_FLAGS = -i blackmisc/blackmiscfreefunctions.h
DEPENDPATH += . ../../src/blackmisc
INCLUDEPATH += . ../../src
LIBS += -L../../lib -lblackmisc
win32:!win32-g++*: PRE_TARGETDEPS += ../../lib/blackmisc.lib
else: PRE_TARGETDEPS += ../../lib/libblackmisc.a
DESTDIR = ../../bin
HEADERS += *.h
SOURCES += *.cpp
OTHER_FILES += readme.txt BlackMiscTest.Testservice.xml

View File

@@ -0,0 +1,56 @@
/* Copyright (C) 2013 VATSIM Community / authors
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "testservice.h"
namespace BlackMiscTest
{
const QString Testservice::ServiceName = QString(BLACKMISCKTEST_SERVICENAME);
const QString Testservice::ServicePath = QString(BLACKMISCKTEST_SERVICEPATH);
/*
* Constructor
*/
Testservice::Testservice(QObject *parent) : QObject(parent)
{
// void
}
/*
* Slot to receive messages
*/
void Testservice::receiveStringMessage(const QString &message)
{
qDebug() << "Pid:" << TestserviceTool::getPid() << "Received message:" << message;
}
/*
* Receive variant
*/
void Testservice::receiveVariant(const QDBusVariant &variant)
{
QVariant qv = variant.variant();
qDebug() << "Pid:" << TestserviceTool::getPid() << "Received variant:" << qv;
}
/*
* Receive speed
*/
void Testservice::receiveSpeed(const BlackMisc::PhysicalQuantities::CSpeed &speed)
{
qDebug() << "Pid:" << TestserviceTool::getPid() << "Received speed:" << speed;
}
/*
* Receive COM unit
*/
void Testservice::receiveComUnit(const BlackMisc::Aviation::CComSystem &comUnit)
{
qDebug() << "Pid:" << TestserviceTool::getPid() << "Received COM:" << comUnit;
}
} // namespace

View File

@@ -0,0 +1,89 @@
/* Copyright (C) 2013 VATSIM Community / authors
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef BLACKMISCKTEST_TESTSERVICEPQAV_H
#define BLACKMISCKTEST_TESTSERVICEPQAV_H
// clash with struct interace in objbase.h used to happen
#pragma push_macro("interface")
#undef interface
#define BLACKMISCKTEST_SERVICENAME "blackmisctest.testservice"
#define BLACKMISCKTEST_SERVICEPATH "/blackbus"
#include <QObject>
#include <QDebug>
#include <QDBusVariant>
#include "blackmisc/blackmiscfreefunctions.h"
#include "testservicetool.h"
namespace BlackMiscTest {
/*!
* \brief Testservice for PQ DBus tests
*/
class Testservice : public QObject
{
// http://techbase.kde.org/Development/Tutorials/D-Bus/CustomTypes#Write_a_class
// https://dev.vatsim-germany.org/projects/vatpilotclient/wiki/DBusExample
// http://qt-project.org/doc/qt-4.8/examples-dbus.html
// http://dbus.freedesktop.org/doc/dbus-tutorial.html#meta
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", BLACKMISCKTEST_SERVICENAME)
// For some reasons the interface name in the XML is not set correctly
// to the above name
signals:
/*!
* \brief Send string message
* \param message
*/
void sendStringMessage(const QString& message);
public slots:
/*!
* \brief Receive string message
* \param message
*/
void receiveStringMessage(const QString &message);
/*!
* \brief Receive a QVariant
* \param variant
*/
void receiveVariant(const QDBusVariant &variant);
/*!
* \brief Receive speed
* \param speed
*/
void receiveSpeed(const BlackMisc::PhysicalQuantities::CSpeed &speed);
/*!
* \brief receiveComUnit
* \param comUnit
*/
void receiveComUnit(const BlackMisc::Aviation::CComSystem &comUnit);
public:
static const QString ServiceName;
static const QString ServicePath;
/*!
* \brief Constructor
* \param parent
*/
explicit Testservice(QObject *parent = 0);
};
} // namespace
#pragma pop_macro("interface")
#endif // BLACKMISCKTEST_TESTSERVICEPQAV_H

View File

@@ -0,0 +1,32 @@
#include "testservicetool.h"
namespace BlackMiscTest
{
/*
* Start a new process
*/
QProcess * TestserviceTool::startNewProcess(const QString &executable, QObject *parent = 0)
{
QProcess *process = new QProcess(parent);
process->startDetached(executable);
return process;
}
/*
* Sleep
*/
void TestserviceTool::sleep(qint32 ms)
{
if (ms < 1) return;
#ifdef Q_OS_WIN
Sleep(uint(ms));
#else
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
nanosleep(&ts, NULL);
#endif
}
} // namespace

View File

@@ -0,0 +1,53 @@
#ifndef BLACKMISCTEST_TESTSERVICETOOL_H
#define BLACKMISCTEST_TESTSERVICETOOL_H
#include <QCoreApplication>
#include <QProcess>
#ifdef Q_OS_WIN
// for qdatetime, see here http://qt-project.org/forums/viewthread/22133
#define NOMINMAX
#include <windows.h> // for Sleep
#endif
namespace BlackMiscTest
{
/*!
* \brief Supporting functions for running the tests
*/
class TestserviceTool
{
private:
/*!
* \brief Constructor
*/
TestserviceTool() {}
public:
/*!
* \brief Get process id
* \return
*/
static qint64 getPid() {
return QCoreApplication::applicationPid();
}
/*!
* \brief Start a new process
* \param executable
* \param parent
* \return
*/
static QProcess *startNewProcess(const QString &executable, QObject *parent);
/*!
* \brief Own sleep to avoid inlude of QTest
* \param ms
*/
static void sleep(qint32 ms);
};
} // namespace
#endif // BLACKMISCTEST_TESTSERVICETOOL_H

View File

@@ -0,0 +1,25 @@
QT += core dbus
TARGET = sample_quantities_avionics_xmlplugin
TEMPLATE = lib
CONFIG += plugin
DEPENDPATH += . ../../src/blackmisc
INCLUDEPATH += . ../../src
LIBS += -L../../lib -lblackmisc \
../blackmiscquantities_dbus/release/dummy.obj \
../blackmiscquantities_dbus/release/moc_dummy.obj \
../blackmiscquantities_dbus/release/dummynoq.obj
win32:!win32-g++*: PRE_TARGETDEPS += ../../lib/blackmisc.lib \
../../samples/blackmiscquantities_dbus/release/dummy.obj
else: PRE_TARGETDEPS += ../../lib/libblackmisc.a \
../../samples/blackmiscquantities_dbus/release/dummy.obj
DESTDIR = ../../bin
HEADERS += *.h
SOURCES += *.cpp

View File

@@ -0,0 +1,12 @@
#include "sampleplugin.h"
void CXmlSamplePlugin::registerMetaTypes()
{
qRegisterMetaType<BlackMiscTest::Dummy>("BlackMiscTest::Dummy");
qDBusRegisterMetaType<BlackMiscTest::Dummy>();
qRegisterMetaType<BlackMiscTest::DummyNoQ>("BlackMiscTest::DummyNoQ");
qDBusRegisterMetaType<BlackMiscTest::DummyNoQ>();
}

View File

@@ -0,0 +1,21 @@
#ifndef SAMPLEPLUGIN_H
#define SAMPLEPLUGIN_H
#include <QObject>
#include <QDebug>
#include <QDBusMetaType>
#include <QMetaType>
#include "../blackmiscquantities_dbus/dummy.h"
#include "../blackmiscquantities_dbus/dummynoq.h"
class CXmlSamplePlugin : public QObject, public QDBusCpp2XmlPlugin
{
Q_OBJECT
Q_INTERFACES(QDBusCpp2XmlPlugin)
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.DBus.Cpp2XmlPlugin")
public:
virtual void registerMetaTypes();
};
#endif // SAMPLEPLUGIN_H

View File

@@ -1,4 +1,4 @@
QT += core
QT += core dbus
TARGET = sample_vector_geo
CONFIG += console

View File

@@ -1,4 +1,4 @@
QT += core
QT += core dbus
TARGET = sample_interpolator
CONFIG += console