aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Hölttä <AHoelttae@luxoft.com>2018-03-27 13:45:10 +0200
committerDominik Holland <dominik.holland@pelagicore.com>2018-04-25 13:11:33 +0000
commit4b4a086f310ccf6570214e5ed4911116f8c96240 (patch)
tree282161e9519e81b90f4859144395f37cb47e4d90
parent7f49ef0fdbe26c9d639e52c3de1fd46ee3af7ab4 (diff)
Add documentation and an example for QtRemoteObjects templates
Add documentation for remote object templates: update list of template files and add a general description of the remote objects features. Add an example project and a walkthrough to demonstrate the remote objects generation features. Task-number: QTAUTO-919 Change-Id: I3d25d29fd9b9ca2a72bbc6662f05b968d9aa5413 Reviewed-by: Dominik Holland <dominik.holland@pelagicore.com>
-rw-r--r--examples/ivicore/ivicore.pro3
-rw-r--r--examples/ivicore/qface-ivi-remote/backend_qtro/backend_qtro.pro25
-rw-r--r--examples/ivicore/qface-ivi-remote/demo/demo.pro37
-rw-r--r--examples/ivicore/qface-ivi-remote/demo/main.cpp69
-rw-r--r--examples/ivicore/qface-ivi-remote/demo/main.qml103
-rw-r--r--examples/ivicore/qface-ivi-remote/demo/qml.qrc5
-rw-r--r--examples/ivicore/qface-ivi-remote/example-ivi-remote.qface16
-rw-r--r--examples/ivicore/qface-ivi-remote/frontend/frontend.pro18
-rw-r--r--examples/ivicore/qface-ivi-remote/qface-ivi-remote.pro11
-rw-r--r--examples/ivicore/qface-ivi-remote/server_qtro/main.cpp66
-rw-r--r--examples/ivicore/qface-ivi-remote/server_qtro/processingservice.cpp64
-rw-r--r--examples/ivicore/qface-ivi-remote/server_qtro/processingservice.h66
-rw-r--r--examples/ivicore/qface-ivi-remote/server_qtro/server_qtro.pro42
-rw-r--r--src/doc/qtivi/qtivi-project.qdocconf2
-rw-r--r--src/doc/qtivi/src/configuration.qdoc6
-rw-r--r--src/doc/qtivi/src/ivigenerator/generator-usage.qdoc67
-rw-r--r--src/doc/qtivi/src/ivigenerator/ivigenerator.qdoc2
-rw-r--r--src/doc/qtivi/src/ivigenerator/remotebackends.qdoc70
-rw-r--r--src/ivicore/doc/images/examples_qface_ivi_remote.pngbin0 -> 12878 bytes
-rw-r--r--src/ivicore/doc/src/examples-qface-ivi-climate.qdoc2
-rw-r--r--src/ivicore/doc/src/examples-qface-ivi-remote.qdoc311
21 files changed, 979 insertions, 6 deletions
diff --git a/examples/ivicore/ivicore.pro b/examples/ivicore/ivicore.pro
index 14dc55e..8e7798d 100644
--- a/examples/ivicore/ivicore.pro
+++ b/examples/ivicore/ivicore.pro
@@ -1,4 +1,5 @@
TEMPLATE = subdirs
QT_FOR_CONFIG += ivicore
-qtConfig(ivigenerator): SUBDIRS = qface-ivi-climate
+qtConfig(ivigenerator): SUBDIRS += qface-ivi-climate
+qtConfig(ivigenerator): qtConfig(remoteobjects): SUBDIRS += qface-ivi-remote
diff --git a/examples/ivicore/qface-ivi-remote/backend_qtro/backend_qtro.pro b/examples/ivicore/qface-ivi-remote/backend_qtro/backend_qtro.pro
new file mode 100644
index 0000000..6b7f191
--- /dev/null
+++ b/examples/ivicore/qface-ivi-remote/backend_qtro/backend_qtro.pro
@@ -0,0 +1,25 @@
+TEMPLATE=lib
+TARGET = $$qtLibraryTarget(example_ivi_remote)
+CONFIG += ivigenerator plugin
+macos: CONFIG += debug_and_release build_all
+
+QT_FOR_CONFIG += ivicore
+!qtConfig(ivigenerator): error("No ivigenerator available")
+
+LIBS += -L$$OUT_PWD/../ -l$$qtLibraryTarget(QtIviRemoteExample)
+DESTDIR = ../qtivi
+
+CONFIG += warn_off
+INCLUDEPATH += $$OUT_PWD/../frontend
+PLUGIN_TYPE = qtivi
+PLUGIN_EXTENDS = qtivi
+PLUGIN_CLASS_NAME = RemoteClientPlugin
+
+QT += core ivicore
+
+QFACE_FORMAT = backend_qtro
+QFACE_SOURCES = ../example-ivi-remote.qface
+
+CONFIG += install_ok # Do not cargo-cult this!
+target.path = $$[QT_INSTALL_EXAMPLES]/ivicore/qface-ivi-remote/qtivi/
+INSTALLS += target
diff --git a/examples/ivicore/qface-ivi-remote/demo/demo.pro b/examples/ivicore/qface-ivi-remote/demo/demo.pro
new file mode 100644
index 0000000..5a85a7c
--- /dev/null
+++ b/examples/ivicore/qface-ivi-remote/demo/demo.pro
@@ -0,0 +1,37 @@
+TARGET = qface-ivi-remote
+TEMPLATE = app
+
+QT += qml quick
+CONFIG += c++11
+CONFIG -= app_bundle
+DESTDIR = ../
+
+LIBS += -L$$OUT_PWD/../ -l$$qtLibraryTarget(QtIviRemoteExample)
+INCLUDEPATH += $$OUT_PWD/../frontend
+
+SOURCES += main.cpp
+
+RESOURCES += qml.qrc
+
+QMAKE_RPATHDIR += $ORIGIN
+
+# Additional import path used to resolve QML modules in Qt Creator's code model
+QML_IMPORT_PATH =
+
+# Additional import path used to resolve QML modules just for Qt Quick Designer
+QML_DESIGNER_IMPORT_PATH =
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+CONFIG += install_ok # Do not cargo-cult this!
+target.path = $$[QT_INSTALL_EXAMPLES]/ivicore/qface-ivi-remote
+INSTALLS += target
diff --git a/examples/ivicore/qface-ivi-remote/demo/main.cpp b/examples/ivicore/qface-ivi-remote/demo/main.cpp
new file mode 100644
index 0000000..1ccba57
--- /dev/null
+++ b/examples/ivicore/qface-ivi-remote/demo/main.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: BSD-3-Clause
+**
+****************************************************************************/
+
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+
+#include <remotemodule.h>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ RemoteModule::registerTypes();
+ RemoteModule::registerQmlTypes(QLatin1String("IviRemote"), 1, 0);
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+
+ return app.exec();
+}
diff --git a/examples/ivicore/qface-ivi-remote/demo/main.qml b/examples/ivicore/qface-ivi-remote/demo/main.qml
new file mode 100644
index 0000000..a5c6c80
--- /dev/null
+++ b/examples/ivicore/qface-ivi-remote/demo/main.qml
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: BSD-3-Clause
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import QtQuick.Controls 2.3
+import QtQuick.Window 2.2
+import IviRemote 1.0
+
+Window {
+ visible: true
+ width: 640
+ height: 480
+ title: qsTr("QtIVI Remote example")
+
+ UiProcessingService {
+ id: processingService
+ }
+
+ Column {
+ anchors.fill: parent
+ anchors.margins: 10
+
+ Row {
+ Button {
+ text: "Process"
+
+ onClicked: processingService.process(inputField.text).then(
+ function(result) { //success callback
+ resultLabel.text = result
+ },
+ function() { //failure callback
+ resultLabel.text = "failed"
+ } )
+ }
+ TextField {
+ placeholderText: "text to process"
+ id: inputField
+ }
+ }
+
+ Row {
+ Text { text: "Processing result: " }
+ Text { id: resultLabel }
+ }
+
+ Row {
+ Text { text: "Last message: " }
+ Text {
+ id: serverMessage
+ text: processingService.lastMessage
+ }
+ }
+ }
+}
diff --git a/examples/ivicore/qface-ivi-remote/demo/qml.qrc b/examples/ivicore/qface-ivi-remote/demo/qml.qrc
new file mode 100644
index 0000000..5f6483a
--- /dev/null
+++ b/examples/ivicore/qface-ivi-remote/demo/qml.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/ivicore/qface-ivi-remote/example-ivi-remote.qface b/examples/ivicore/qface-ivi-remote/example-ivi-remote.qface
new file mode 100644
index 0000000..444163e
--- /dev/null
+++ b/examples/ivicore/qface-ivi-remote/example-ivi-remote.qface
@@ -0,0 +1,16 @@
+/**
+ * Test module
+ */
+module Example.IVI.Remote 1.0;
+
+/**
+ * The ProcessingService provides a QML interface to a service doing
+ * all sorts of heavy processing
+ */
+@config: { id: "example.qtivi.ProcessingService/1.0", qml_type: "UiProcessingService" }
+interface ProcessingService {
+
+ string lastMessage;
+
+ int process(string data);
+}
diff --git a/examples/ivicore/qface-ivi-remote/frontend/frontend.pro b/examples/ivicore/qface-ivi-remote/frontend/frontend.pro
new file mode 100644
index 0000000..9259b86
--- /dev/null
+++ b/examples/ivicore/qface-ivi-remote/frontend/frontend.pro
@@ -0,0 +1,18 @@
+TARGET = $$qtLibraryTarget(QtIviRemoteExample)
+TEMPLATE = lib
+CONFIG += ivigenerator
+DESTDIR = ..
+macos: CONFIG += debug_and_release build_all
+
+QT_FOR_CONFIG += ivicore
+!qtConfig(ivigenerator): error("No ivigenerator available")
+
+QT += ivicore ivicore-private qml quick
+
+DEFINES += QT_BUILD_REMOTE_LIB
+
+QFACE_SOURCES = ../example-ivi-remote.qface
+
+CONFIG += install_ok # Do not cargo-cult this!
+target.path = $$[QT_INSTALL_EXAMPLES]/ivicore/qface-ivi-remote
+INSTALLS += target
diff --git a/examples/ivicore/qface-ivi-remote/qface-ivi-remote.pro b/examples/ivicore/qface-ivi-remote/qface-ivi-remote.pro
new file mode 100644
index 0000000..f487cec
--- /dev/null
+++ b/examples/ivicore/qface-ivi-remote/qface-ivi-remote.pro
@@ -0,0 +1,11 @@
+TEMPLATE = subdirs
+
+SUBDIRS = frontend \
+ backend_qtro \
+ server_qtro \
+ demo
+
+CONFIG += ordered
+
+OTHER_FILES += \
+ example-ivi-remote.qface
diff --git a/examples/ivicore/qface-ivi-remote/server_qtro/main.cpp b/examples/ivicore/qface-ivi-remote/server_qtro/main.cpp
new file mode 100644
index 0000000..9eb73d4
--- /dev/null
+++ b/examples/ivicore/qface-ivi-remote/server_qtro/main.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: BSD-3-Clause
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+
+#include "processingservice.h"
+#include "core.h"
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ ProcessingService service;
+ Core::instance()->host()->enableRemoting(&service,QStringLiteral("Example.IVI.Remote.ProcessingService"));
+
+ return app.exec();
+}
diff --git a/examples/ivicore/qface-ivi-remote/server_qtro/processingservice.cpp b/examples/ivicore/qface-ivi-remote/server_qtro/processingservice.cpp
new file mode 100644
index 0000000..a3f154c
--- /dev/null
+++ b/examples/ivicore/qface-ivi-remote/server_qtro/processingservice.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Luxoft GmbH
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: BSD-3-Clause
+**
+****************************************************************************/
+
+#include "processingservice.h"
+
+ProcessingService::ProcessingService()
+{
+ setLastMessage("Service online.");
+}
+
+int ProcessingService::process(const QString & data)
+{
+ setLastMessage(QStringLiteral("Processed data \'%1\'").arg(data));
+ return data.length();
+}
diff --git a/examples/ivicore/qface-ivi-remote/server_qtro/processingservice.h b/examples/ivicore/qface-ivi-remote/server_qtro/processingservice.h
new file mode 100644
index 0000000..c7ef6b8
--- /dev/null
+++ b/examples/ivicore/qface-ivi-remote/server_qtro/processingservice.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Luxoft GmbH
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: BSD-3-Clause
+**
+****************************************************************************/
+
+#ifndef PROCESSINGSERVICE_H
+#define PROCESSINGSERVICE_H
+
+#include "rep_processingservice_source.h"
+
+class ProcessingService : public ProcessingServiceSimpleSource
+{
+public:
+ ProcessingService();
+
+ int process(const QString & data) override;
+};
+
+#endif // PROCESSINGSERVICE_H
diff --git a/examples/ivicore/qface-ivi-remote/server_qtro/server_qtro.pro b/examples/ivicore/qface-ivi-remote/server_qtro/server_qtro.pro
new file mode 100644
index 0000000..145872e
--- /dev/null
+++ b/examples/ivicore/qface-ivi-remote/server_qtro/server_qtro.pro
@@ -0,0 +1,42 @@
+TARGET = qface-ivi-remote-server
+TEMPLATE = app
+
+QT -= gui
+CONFIG += c++11 ivigenerator
+CONFIG -= app_bundle
+DESTDIR = ../
+
+LIBS += -L$$OUT_PWD/../ -l$$qtLibraryTarget(QtIviRemoteExample)
+INCLUDEPATH += $$OUT_PWD/../frontend
+
+SOURCES += main.cpp \
+ processingservice.cpp
+
+QMAKE_RPATHDIR += $ORIGIN
+
+QFACE_FORMAT = server_qtro
+QFACE_SOURCES = ../example-ivi-remote.qface
+
+# Additional import path used to resolve QML modules in Qt Creator's code model
+QML_IMPORT_PATH =
+
+# Additional import path used to resolve QML modules just for Qt Quick Designer
+QML_DESIGNER_IMPORT_PATH =
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+CONFIG += install_ok # Do not cargo-cult this!
+target.path = $$[QT_INSTALL_EXAMPLES]/ivicore/qface-ivi-remote-server
+INSTALLS += target
+
+HEADERS += \
+ processingservice.h
diff --git a/src/doc/qtivi/qtivi-project.qdocconf b/src/doc/qtivi/qtivi-project.qdocconf
index 8fc5a9c..05d6ccf 100644
--- a/src/doc/qtivi/qtivi-project.qdocconf
+++ b/src/doc/qtivi/qtivi-project.qdocconf
@@ -59,7 +59,7 @@ qhp.QtIvi.subprojects.examples.sortPages = true
tagfile = qtivi.tags
-depends += qtcore qtdoc qtquick qtqml qtautomotivesuite
+depends += qtcore qtdoc qtquick qtqml qtautomotivesuite qtsimulator qtremoteobjects
navigation.homepage = "Qt Automotive Suite"
navigation.landingpage = "Qt IVI"
diff --git a/src/doc/qtivi/src/configuration.qdoc b/src/doc/qtivi/src/configuration.qdoc
index 6b1be4d..c5d4425 100644
--- a/src/doc/qtivi/src/configuration.qdoc
+++ b/src/doc/qtivi/src/configuration.qdoc
@@ -57,6 +57,12 @@ summary".
the needed code for the simulation backends to communicate over QtSimulator. In addition,
it also provides a new template to generate a controller application to communicate with
the simulation backend.
+\row
+ \li QtRemoteObjects Support
+ \keyword feature-qtremoteobjects
+ \li QtRemoteObjects module
+ \li The QtRemoteObjects Support is needed to generate qtivi backends, using QtRemoteObjects as
+ it's IPC. It also provides templates to generate the server part of this IPC.
\endtable
Additional command-line options to tailor the build-system to your needs:
diff --git a/src/doc/qtivi/src/ivigenerator/generator-usage.qdoc b/src/doc/qtivi/src/ivigenerator/generator-usage.qdoc
index 956fcaf..688633b 100644
--- a/src/doc/qtivi/src/ivigenerator/generator-usage.qdoc
+++ b/src/doc/qtivi/src/ivigenerator/generator-usage.qdoc
@@ -52,7 +52,7 @@ The options and parameters are:
\li specifies whether the generator should keep track of the changes in the IDL file
and update output on the fly (--no-reload by default)
\row
- \li -f, --format [frontend|backend_simulator|control_panel|<folder>]
+ \li -f, --format [frontend|backend_simulator|control_panel|backend_qtro|server_qtro|<folder>]
\li see below
\row
\li --help
@@ -67,7 +67,7 @@ The options and parameters are:
\li Generation destination folder
\endtable
-At the moment the generator is able to generate 2 kinds of projects given an interface IDL file
+At the moment the generator is able to generate 5 kinds of projects given an interface IDL file
based on the \e {--format} option value.
These are:
\table
@@ -85,7 +85,16 @@ These are:
\li \l {Control Panel} {control_panel}
\target control-panel-template
\li Generates a controller application, consisting of an UI and a C++ plugin, which communicates
- to the simulation backend generated from the same qface file using QtSimulator.
+ to the simulation backend generated from the same qface file using QtSimulator.
+ \row
+ \li \l {QtRemoteObjects Backend} {backend_qtro}
+ \target backend-qtro-template
+ \li Generates a QtRemoteObjects based backend client for the API generated by the "frontend" option.
+ This backend connects to a backend server.
+ \row
+ \li \l {QtRemoteObjects Server} {server_qtro}
+ \target server-qtro-template
+ \li Generates a QtRemoteObjects based backend server stub for the API generated by the "frontend" option.
\row
\li folder path
\li Uses templates inside the folder. A YAML file with the same name as the folder (and .yaml
@@ -363,4 +372,56 @@ for more information.
\li Control UI for this interface. Contains a interface to control every
property and method and log calls to signals.
\endtable
+
+\section2 QtRemoteObjects Backend
+
+The backend_qtro template is only available if the QtRemoteObjects module was found.
+Despite the name, the remote object backend is not the location for the implementation of the actual backend logic, but just a client for connecting to the remote backend server.
+
+\table
+ \header
+ \li File name
+ \li Purpose
+ \row
+ \li "{{module.module_name|lower}}plugin.h/cpp"
+ \li Files defining implementation of QtIvi backend plugin implementing
+ QIviServiceInterface
+ \row
+ \li "{{module.module_name|lower}}.json"
+ \li File containing identifiers of the exposed feature interfaces needed by the Qt plugin
+ system.
+ \row
+ \li "{{module|lower|replace('.', '-')}}.pri"
+ \li Standard Qt .pri file, containing all the generated files that can be used for
+ including the autogenerated files into a qmake project. Also adds the .rep file
+ to the project and calls the remote object compiler.
+ \row
+ \li "{{interface|lower}}backend.h/cpp"
+ \li Files containing the implementation of the remote object backend.
+ Establishes the connection and initializes the remote object replica.
+ \row
+ \li "{{interface|lower}}.rep"
+ \li The input file for Qt’s \l [QtRemoteObjects] {Qt Remote Objects Compiler} {replica compiler} for producing the replica class code.
+\endtable
+
+\section2 QtRemoteObjects server
+
+The server_qtro template is only available if the QtRemoteObjects module was found. The produced code contains merely the source classes to inherit and code for establishing the connection. It is up to the developer to implement the actual backend logic.
+
+\table
+ \header
+ \li File name
+ \li Purpose
+ \row
+ \li "core.h/cpp"
+ \li Code for establishing the connection and starting the remoting for the source objects.
+ \row
+ \li "{{srcBase|lower}}.pri"
+ \li Standard Qt .pri file, containing all the generated files that can be used for
+ including the autogenerated files into a qmake project. Also includes the .rep file
+ to the project and calls the remote object compiler.
+ \row
+ \li "{{interface|lower}}.rep"
+ \li The input file for the Qt’s \l [QtRemoteObjects] {Qt Remote Objects Compiler} {replica compiler} for producing the source class code.
+\endtable
*/
diff --git a/src/doc/qtivi/src/ivigenerator/ivigenerator.qdoc b/src/doc/qtivi/src/ivigenerator/ivigenerator.qdoc
index 4ce8013..3a50a38 100644
--- a/src/doc/qtivi/src/ivigenerator/ivigenerator.qdoc
+++ b/src/doc/qtivi/src/ivigenerator/ivigenerator.qdoc
@@ -39,6 +39,8 @@ library, which provides a generic autogeneration framework.
\li \l {Autogenerator Usage}
\li \l {Filter Reference}
\li \l {QMake Integration}
+ \li \l {QtIVI Remote backends}{Remote backends}
\li \l {ivicore/qface-ivi-climate}{Generator Example}
+ \li \l {ivicore/qface-ivi-remote}{Remote Backend Example}
\endlist
*/
diff --git a/src/doc/qtivi/src/ivigenerator/remotebackends.qdoc b/src/doc/qtivi/src/ivigenerator/remotebackends.qdoc
new file mode 100644
index 0000000..064a062
--- /dev/null
+++ b/src/doc/qtivi/src/ivigenerator/remotebackends.qdoc
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+/*!
+\page remotebackends.html
+\title QtIvi Remote Backends
+
+One of the features of the Qt IVI Generator is the possibility to create remote backends
+that utilize the QtRemoteObjects module.
+A remote backend may be an independently running process, even on a separate host machine, that can
+be accessed by multiple clients, or frontends. Such frontends are e.g. the main infotainment system
+UI, different applications running within the UI or mobile devices.
+
+\section1 Motivation
+
+The purpose of having remote backends is to enable the distribution of functionality and the sharing
+of information. This may be between multiple processes and even between multiple host machines.
+Separate processes improve the overall reliability of a complex system and make it possible to
+separate computationally intensive code from the UI code. Additionally, remote backends can be
+accessible by multiple frontend points, be it the central UI, separate applications or even mobile
+devices or third party applications.
+Combined with the automatic generation of code and uniform feature loading of QtIvi, the development
+of distributed features comes with a minimal development overhead and interchangeability and
+transparency on the UI code side.
+
+\section1 Code Generation
+
+The remote objects generator produces client side code as a QtIvi backend plugin and a remote server
+stub. The client is generated using the \l {backend-qtro-template}{backend_qtro} template and the s
+erver using the \l {server-qtro-template}{server_qtro} template. Both the plugin and the server
+contain generated c++ code and an intermediate .rep -file that is further processed by Qt’s
+\l [QtRemoteObjects] {Qt Remote Objects Compiler} {replica compiler} to produce the actual source
+and replica classes.
+
+The generated plugin is loaded and used as any other QtIvi plugin and is interchangeable with any
+other backend implementation with the same API. As all method calls over QtIvi feature interfaces
+are asynchronous, the use of a remote backend is similar to any other type of backend.
+
+The generated plugin is buildable and usable as it is, and does not require further changes by the
+developer. The task of the developer will be then to implement the intended functionality at the
+server side. To support getting started with the server, there is a generated class that initializes
+the connection. All connection parameters to the plugin and to the server are passed currently over
+a config file, either in a default location or at an user specified path.
+
+For a steb-by-step introduction to remote backends, see the \l {ivicore/qface-ivi-remote}{Remote Backend Example}.
+
+*/
diff --git a/src/ivicore/doc/images/examples_qface_ivi_remote.png b/src/ivicore/doc/images/examples_qface_ivi_remote.png
new file mode 100644
index 0000000..e6948c7
--- /dev/null
+++ b/src/ivicore/doc/images/examples_qface_ivi_remote.png
Binary files differ
diff --git a/src/ivicore/doc/src/examples-qface-ivi-climate.qdoc b/src/ivicore/doc/src/examples-qface-ivi-climate.qdoc
index 1847ecc..c66bc0a 100644
--- a/src/ivicore/doc/src/examples-qface-ivi-climate.qdoc
+++ b/src/ivicore/doc/src/examples-qface-ivi-climate.qdoc
@@ -230,7 +230,7 @@ works in the same way, but it is using the \e QFACE_FORMAT variable to tell the
a different generation template.
\code
-CONFIG += ivigenerator
+CONFIG += ivigenerator plugin
QFACE_FORMAT = backend_simulator
QFACE_SOURCES = ../example-ivi-climate.qface
\endcode
diff --git a/src/ivicore/doc/src/examples-qface-ivi-remote.qdoc b/src/ivicore/doc/src/examples-qface-ivi-remote.qdoc
new file mode 100644
index 0000000..a652c36
--- /dev/null
+++ b/src/ivicore/doc/src/examples-qface-ivi-remote.qdoc
@@ -0,0 +1,311 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\example ivicore/qface-ivi-remote
+\brief This Example shows how to use the Qt IVI Generator to create remote backends.
+\ingroup qtivicore-examples
+\title Qt IVI Generator Remote Objects Example
+\image examples_qface_ivi_remote.png
+
+\section1 Introduction
+
+This example shows how to create a remote backend and the client side components
+using the Qt IVI Generator. The communication between the client and server is done with
+QtRemoteObjects. Based on a single qface IDL file, it will generate:
+
+\list
+\li a shared library with the front-end code
+\li a back-end plugin that implements a client for connecting to the server
+\li a server that runs the actual remote backend logic
+\li a demo application that connects to the server and provides and UI for using the service
+\endlist
+
+In addition to the generated C++ code, the backend-plugin and the server contain also an
+intermediate .rep -file that is further processed by Qt’s replica compiler to produce the actual
+source and replica classes.
+
+\section2 Walkthrough
+
+The IDL file used in the example represents an imaginary remote service for processing data . It
+contains a single interface with a single property and a single method.
+
+First we need to define which \e module we want to describe. The \e module acts as a namespace,
+because the IDL file can contain multiple interfaces.
+
+\code
+module Example.IVI.Remote 1.0;
+\endcode
+
+The most important part is the definition of the \e interface.
+
+\code
+
+interface ProcessingService {
+
+ string lastMessage;
+
+ int process(string data);
+}
+
+\endcode
+
+In this case, we define an \e interface named \b ProcessingService consisting of a single property
+and a single method. Every property and method definition needs to contain at least a type and a
+name. Most of the basic types are builtin and can be found in the \l {QFace IDL syntax} {reference}.
+
+
+\section1 Frontend library
+
+Now we want to use the IVI Generator to generate a shared library containing a C++ implementation of
+our module and its interface. For this, the \e frontend template is used. This will generate a class
+derived from \c {QIviAbstractZonedFeature} including all the specified properties. The generated
+library will use the \l {Dynamic Backend System} from QtIviCore and by that provide an easy way to
+change the behavior implementations.
+
+In order to call the autogenerator for our shared library, the qmake project file needs to use the
+\e ivigenerator qmake feature. The following snippet shows how it can be added:
+
+\code
+CONFIG += ivigenerator
+QFACE_SOURCES = ../example-ivi-climate.qface
+\endcode
+
+By adding \e ivigenerator to the \e CONFIG variable, the \e ivigenerator feature file will be
+loaded and interpret the \e QFACE_SOURCES variable similar to \e SOURCES variable of normal qmake
+projects.
+Activating the qmake feature using the \e CONFIG variable has the disadvantage that it doesn't
+report any errors if the feature is not available. Because of this, it is encouraged to use the
+following additional code to report errors:
+
+\code
+QT_FOR_CONFIG += ivicore
+!qtConfig(ivigenerator): error("No ivigenerator available")
+\endcode
+
+The other part of the project file is a normal library setup which is supposed to work on
+Linux, macOS and Windows.
+
+
+\section1 RemoteObjects Backend Plugin
+
+As mentioned above, the \e frontend library will use the \l {Dynamic Backend System}. This means
+that for the library to provide some functionality, we also need a \e backend plugin. The generated
+plugin here will work as a client that connects to the server using the Qt Remote Objects. The qmake
+integration works in the same way, but it is using the \e QFACE_FORMAT variable to tell the
+ivigenerator to use a different generation template, \e backend_qtro:
+
+\code
+CONFIG += ivigenerator plugin
+QFACE_FORMAT = backend_qtro
+QFACE_SOURCES = ../example-ivi-climate.qface
+\endcode
+
+The generated backend plugin code is usable as is, and doesn't require further changes by the
+developer. As we want to generate a plugin instead of a plain library, we need to instrument qmake
+to do so by adding \e plugin to the \e CONFIG variable. For the plugin to compile correctly it needs
+to get the backend interface header from the previously created library. As this header is also
+generated, it is not part of our source tree, but part of the build tree. We do this by adding it to
+the include path using the following construct:
+
+\code
+INCLUDEPATH += $$OUT_PWD/../frontend
+\endcode
+
+Most of the code in the backend plugin is generated by the IVI Generator, but some of it is
+generated by the Qt's remote object compiler (repc). This is achieved by IVI Generator producing an
+intermediate .repc file that is further processed by the repc compiler. The repc is called via the
+generated .pri file, found in the build directory (notice, that you have to call qmake on the
+project at least once to have the generated files available).
+
+
+As our application doesn't know about the existence of our backend plugin, we need to put this
+plugin in a folder where our application searches for plugins. By default Qt either search in the
+\b plugins folder within Qt's installation directory or in the current working directory of the
+application. For QtIvi plugins to be found, they need to be provided within a \b qtivi sub-folder.
+This is achieved automatically by adding the following line to our backend project file:
+
+\code
+DESTDIR = ../qtivi
+\endcode
+
+
+\section1 RemoteObjects Server
+
+The server is an independent, GUIless application that contains the actual business logic of our
+backend and hence needs to have most of its implementation written by the developer. Nevertheless,
+the generator produces some code to simplify the development. We can generate server side code by
+using the IVI Generator with \e server_qtro template:
+
+\code
+TEMPLATE = app
+QT -= gui
+CONFIG += c++11 ivigenerator
+...
+QFACE_FORMAT = server_qtro
+QFACE_SOURCES = ../example-ivi-remote.qface
+\endcode
+
+To use the generated remote source, we need to inherit from one of the classes defined in the
+generated rep_processingservice_source.h file. In this example we implement our servers logic in the
+ProcessingService class and use the ProcessingServiceSimpleSource as the base class:
+
+\code
+// server_qtro/processingservice.h
+#include "rep_processingservice_source.h"
+
+class ProcessingService : public ProcessingServiceSimpleSource
+{
+public:
+ ProcessingService();
+
+ int process(const QString & data) override;
+};
+\endcode
+
+Please notice, that the base class contains already the definitions for property accessors, but any
+custom method or slot needs to be overridden and defined by the developer. Our implementation of the
+process function merely counts and returns the length of the passed data and updates the lastMessage
+property:
+
+\code
+// server_qtro/processingservice.cpp
+ProcessingService::ProcessingService()
+{
+ setLastMessage("Service online.");
+}
+
+int ProcessingService::process(const QString & data)
+{
+ setLastMessage("Processed data \'" +data+"\'");
+ return data.length();
+}
+\endcode
+
+In order to make the class \b ProcessingService accessible remotely, we need to share it. This is
+done with the QRemoteObjectNode::enableRemoting() function. The generated Core class provides a
+preconfigured instance of a remotenode that is used for the remoting. In order for the plugin to
+connect to the right object, use an identifier in the format ModuleName.InterfaceName, which in this
+case is "Example.IVI.Remote.ProcessingService". All this is done in the main()-function, along with
+the start of the main event loop:
+
+\code
+// server_qtro/main.cpp
+#include <QCoreApplication>
+
+#include "processingservice.h"
+#include "core.h"
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ ProcessingService service;
+ Core::instance()->host()->enableRemoting(&service,"Example.IVI.Remote.ProcessingService");
+
+ return app.exec();
+}
+\endcode
+
+Implementing a service that is accessible remotely is as simple as that; use the properties as usual
+and provide the method implementations. The QtRemoteObjects library takes care of the communication.
+
+
+\section1 Demo Client Application
+
+The demo application presents a simple QML GUI for using the remote service over
+the generated interface.
+
+As we do not provide a QML plugin, the application needs to link to the generated frontend library
+and call the \e {RemoteModule::registerTypes} and \e {RemoteModule::registerQmlTypes} methods
+that are generated in the module singleton to register all autogenerated interfaces and types with
+the QML engine.
+
+In our QML application, we still need to import the module using the name we provided to \e
+{RemoteModule::registerQmlTypes}. Afterwards the interface can be instantiated like any other
+QML item.
+
+\code
+// demo/main.qml
+import IviRemote 1.0
+
+Window {
+
+...
+
+ UiProcessingService {
+ id: processingService
+ }
+
+...
+
+}
+\endcode
+
+Every method call that is made through a generated API, is asynchronous. This means,
+that instead of directly returning a return value, a \c {QIviPendingReply} object is returned.
+Using the \l QIviPendingReply::then() method on the returned object, we may assign callbacks to it
+that are called when the method call has been successfully finished or if it has failed.
+
+\code
+// demo/main.qml
+Button {
+ text: "Process"
+
+ onClicked: processingService.process(inputField.text).then(
+ function(result) { //success callback
+ resultLabel.text = result
+ },
+ function() { //failure callback
+ resultLabel.text = "failed"
+ }
+ )
+}
+\endcode
+
+In case of properties, we just use bindings as usual:
+
+\code
+// demo/main.qml
+Row {
+ Text { text: "Last message: " }
+ Text {
+ id: serverMessage
+ text: processingService.lastMessage
+ }
+}
+\endcode
+
+
+\section1 Running the Example
+
+In order to see the whole functionality of the demo, run both the server and the demo application
+at the same time. You may leave the server running and restart the application, or vice versa,
+to see that the reconnection works. Run the demo application alone without the server running,
+to test how the remote method call fails when there is no connection.
+
+*/