summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/ivicore/qface-ivi-remote/server_qtro/processingservice.cpp2
-rw-r--r--examples/ivicore/qface-ivi-remote/server_qtro/processingservice.h2
-rw-r--r--src/tools/ivigenerator/common/interface.rep.tpl5
-rw-r--r--src/tools/ivigenerator/templates_backend_qtro/backend.cpp.tpl51
-rw-r--r--src/tools/ivigenerator/templates_backend_qtro/backend.h.tpl2
-rw-r--r--tests/auto/core/ivigenerator/org.example.echo.qtro.qface3
-rw-r--r--tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echoservice.cpp25
-rw-r--r--tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echoservice.h11
-rw-r--r--tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echozonedservice.cpp20
-rw-r--r--tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echozonedservice.h7
-rw-r--r--tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/tst_echoqtro.cpp65
-rw-r--r--tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/tst_echoqtro.h1
12 files changed, 166 insertions, 28 deletions
diff --git a/examples/ivicore/qface-ivi-remote/server_qtro/processingservice.cpp b/examples/ivicore/qface-ivi-remote/server_qtro/processingservice.cpp
index 3f20ec9..e266407 100644
--- a/examples/ivicore/qface-ivi-remote/server_qtro/processingservice.cpp
+++ b/examples/ivicore/qface-ivi-remote/server_qtro/processingservice.cpp
@@ -57,7 +57,7 @@ ProcessingService::ProcessingService()
setLastMessage(QStringLiteral("Service online."));
}
-int ProcessingService::process(const QString & data)
+QVariant 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
index 8c7f6b2..1f65e82 100644
--- a/examples/ivicore/qface-ivi-remote/server_qtro/processingservice.h
+++ b/examples/ivicore/qface-ivi-remote/server_qtro/processingservice.h
@@ -60,7 +60,7 @@ class ProcessingService : public ProcessingServiceSimpleSource
public:
ProcessingService();
- int process(const QString & data) override;
+ QVariant process(const QString & data) override;
};
//! [0]
#endif // PROCESSINGSERVICE_H
diff --git a/src/tools/ivigenerator/common/interface.rep.tpl b/src/tools/ivigenerator/common/interface.rep.tpl
index 7297971..46dcc02 100644
--- a/src/tools/ivigenerator/common/interface.rep.tpl
+++ b/src/tools/ivigenerator/common/interface.rep.tpl
@@ -56,6 +56,8 @@
{{inc}}
{% endfor %}
+POD {{interface}}PendingResult(quint64 id, bool failed)
+
class {{class}}
{
{% for property in interface.properties %}
@@ -82,9 +84,10 @@ class {{class}}
{% endif %}
{% for operation in interface.operations %}
- SLOT({{operation|return_type}} {{operation}}({{ivi.join_params(operation, zoned = interface_zoned)}}))
+ SLOT(QVariant {{operation}}({{ivi.join_params(operation, zoned = interface_zoned)}}))
{% endfor %}
+ SIGNAL(pendingResultAvailable(quint64 id, bool isSuccess, const QVariant &value))
{% for signal in interface.signals %}
SIGNAL({{signal}}({{ivi.join_params(signal, zoned = interface_zoned)}}))
{% endfor %}
diff --git a/src/tools/ivigenerator/templates_backend_qtro/backend.cpp.tpl b/src/tools/ivigenerator/templates_backend_qtro/backend.cpp.tpl
index a2a5e5f..9d4fddf 100644
--- a/src/tools/ivigenerator/templates_backend_qtro/backend.cpp.tpl
+++ b/src/tools/ivigenerator/templates_backend_qtro/backend.cpp.tpl
@@ -48,6 +48,8 @@
#include <QSettings>
#include "{{module.module_name|lower}}module.h"
+Q_LOGGING_CATEGORY(qLcRO{{interface}}, "{{module|qml_type|lower}}.{{interface|lower}}backend.remoteobjects", QtInfoMsg)
+
{% for property in interface.properties %}
{% if property.type.is_model %}
{% include "pagingmodel.cpp.tpl" %}
@@ -245,22 +247,40 @@ QStringList {{class}}::availableZones() const
{% endif %}
{% set function_parameters = function_parameters + 'zone' %}
{% endif%}
-{% if not operation.type.is_void %}
- QRemoteObjectPendingReply<{{operation|return_type}}> reply = m_replica->{{operation}}({{function_parameters}});
+ qCDebug(qLcRO{{interface}}) << "{{operation}} called";
+ QRemoteObjectPendingReply<QVariant> reply = m_replica->{{operation}}({{function_parameters}});
auto watcher = new QRemoteObjectPendingCallWatcher(reply);
connect(watcher, &QRemoteObjectPendingCallWatcher::finished, this, [this, iviReply](QRemoteObjectPendingCallWatcher *self) mutable {
if (self->error() == QRemoteObjectPendingCallWatcher::NoError) {
- iviReply.setSuccess(self->returnValue().value<{{operation|return_type}}>());
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 1)
+ QVariant value = self->returnValue();
+#else
+ QVariant value = self->returnValue().value<QVariant>();
+#endif
+ if (value.canConvert<{{interface}}PendingResult>()) {
+ {{interface}}PendingResult result = value.value<{{interface}}PendingResult>();
+ if (result.failed()) {
+ qCDebug(qLcRO{{interface}}) << "Pending Result with id:" << result.id() << "failed";
+ iviReply.setFailed();
+ } else {
+ qCDebug(qLcRO{{interface}}) << "Result not available yet. Waiting for id:" << result.id();
+ m_pendingReplies.insert(result.id(), iviReply);
+ }
+ } else {
+{% if operation.type.is_void %}
+ qCDebug(qLcRO{{interface}}) << "Got the value right away: void";
+ iviReply.setSuccess();
+{% else %}
+ qCDebug(qLcRO{{interface}}) << "Got the value right away:" << value.value<{{operation|return_type}}>();
+ iviReply.setSuccess(value.value<{{operation|return_type}}>());
+{% endif %}
+ }
} else {
iviReply.setFailed();
emit errorChanged(QIviAbstractFeature::InvalidOperation, QStringLiteral("{{class}}, remote call of method {{operation}} failed"));
}
self->deleteLater();
});
-{% else %}
- m_replica->{{operation}}({{function_parameters}});
- iviReply.setSuccess();
-{% endif %}
return iviReply;
}
@@ -268,6 +288,7 @@ QStringList {{class}}::availableZones() const
void {{class}}::setupConnections()
{
+ connect(m_replica.data(), &{{interface}}Replica::pendingResultAvailable, this, &{{class}}::onPendingResultAvailable);
{% if interface_zoned %}
connect(m_replica.data(), &QRemoteObjectReplica::initialized, this, &{{class}}::syncZones);
{% else %}
@@ -318,6 +339,22 @@ void {{class}}::onNodeError(QRemoteObjectNode::ErrorCode code)
emit errorChanged(QIviAbstractFeature::Unknown, "QRemoteObjectNode error, code: " + code);
}
+void {{class}}::onPendingResultAvailable(quint64 id, bool isSuccess, const QVariant &value)
+{
+ qCDebug(qLcRO{{interface}}) << "pending result available" << id;
+ if (!m_pendingReplies.contains(id)) {
+ qCDebug(qLcRO{{interface}}) << "Received a result for an unexpected id:" << id << ". Ignoring!";
+ return;
+ }
+
+ QIviPendingReplyBase iviReply = m_pendingReplies.take(id);
+
+ if (isSuccess)
+ iviReply.setSuccess(value);
+ else
+ iviReply.setFailed();
+}
+
{% if interface_zoned %}
void {{class}}::onZoneSyncDone()
{
diff --git a/src/tools/ivigenerator/templates_backend_qtro/backend.h.tpl b/src/tools/ivigenerator/templates_backend_qtro/backend.h.tpl
index c0ebb61..04a0642 100644
--- a/src/tools/ivigenerator/templates_backend_qtro/backend.h.tpl
+++ b/src/tools/ivigenerator/templates_backend_qtro/backend.h.tpl
@@ -131,6 +131,7 @@ protected Q_SLOTS:
void onReplicaStateChanged(QRemoteObjectReplica::State newState,
QRemoteObjectReplica::State oldState);
void onNodeError(QRemoteObjectNode::ErrorCode code);
+ void onPendingResultAvailable(quint64 id, bool isSuccess, const QVariant &value);
{% if interface_zoned %}
void syncZones();
void onZoneSyncDone();
@@ -142,6 +143,7 @@ protected:
QSharedPointer<{{interface}}Replica> m_replica;
QRemoteObjectNode* m_node= nullptr;
QUrl m_url;
+ QHash<quint64, QIviPendingReplyBase> m_pendingReplies;
{% for property in interface.properties %}
{% if property.type.is_model %}
QIviPagingModelInterface *m_{{property}};
diff --git a/tests/auto/core/ivigenerator/org.example.echo.qtro.qface b/tests/auto/core/ivigenerator/org.example.echo.qtro.qface
index edbcd24..82f7f82 100644
--- a/tests/auto/core/ivigenerator/org.example.echo.qtro.qface
+++ b/tests/auto/core/ivigenerator/org.example.echo.qtro.qface
@@ -34,6 +34,8 @@ interface Echo {
Combo getCombo();
void voidSlot();
void voidSlot2(int param);
+ void timer(int interval);
+
signal anotherChanged(AnotherStruct another);
signal foobar(string foo);
signal somethingHappened();
@@ -103,6 +105,7 @@ interface EchoZoned {
string id();
var varMethod();
Combo getCombo();
+ string timer(int interval);
signal anotherChanged(AnotherStruct another);
signal foobar(string foo);
diff --git a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echoservice.cpp b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echoservice.cpp
index 57e4782..c3edac1 100644
--- a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echoservice.cpp
+++ b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echoservice.cpp
@@ -28,6 +28,7 @@
****************************************************************************/
#include "echoservice.h"
+#include <QTimer>
EchoService::EchoService()
: m_testCombo(Contact(QStringLiteral("Antti"), 34, true, QVariant()), EchoModule::Friday)
@@ -41,30 +42,42 @@ void EchoService::setLastMessage(QString lastMessage)
EchoSimpleSource::setLastMessage(lastMessage);
}
-QString EchoService::echo(const QString &msg)
+QVariant EchoService::echo(const QString &msg)
{
emit echoSlotCalled(msg);
return msg;
}
-QString EchoService::id()
+QVariant EchoService::id()
{
emit idSlotCalled();
return m_testId;
}
-Combo EchoService::getCombo()
+QVariant EchoService::getCombo()
{
emit getComboSlotCalled();
- return m_testCombo;
+ return QVariant::fromValue(m_testCombo);
}
-void EchoService::voidSlot()
+QVariant EchoService::voidSlot()
{
emit voidSlotCalled();
+ return QVariant();
}
-void EchoService::voidSlot2(int param)
+QVariant EchoService::voidSlot2(int param)
{
emit voidSlot2Called(param);
+ return QVariant();
+}
+
+QVariant EchoService::timer(int interval)
+{
+ static quint64 counter = 0;
+ EchoPendingResult pendingResult(counter++, false);
+ QTimer::singleShot(interval, this, [this, pendingResult](){
+ emit pendingResultAvailable(pendingResult.id(), true, QVariant());
+ });
+ return QVariant::fromValue(pendingResult);
}
diff --git a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echoservice.h b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echoservice.h
index ad3eba1..2bdbf54 100644
--- a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echoservice.h
+++ b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echoservice.h
@@ -45,11 +45,12 @@ public:
virtual void setLastMessage(QString lastMessage) override;
public Q_SLOTS:
- virtual QString echo(const QString &msg) override;
- virtual QString id() override;
- virtual Combo getCombo() override;
- virtual void voidSlot() override;
- virtual void voidSlot2(int param) override;
+ virtual QVariant echo(const QString &msg) override;
+ virtual QVariant id() override;
+ virtual QVariant getCombo() override;
+ virtual QVariant voidSlot() override;
+ virtual QVariant voidSlot2(int param) override;
+ virtual QVariant timer(int interval) override;
Q_SIGNALS:
void echoSlotCalled(const QString &msg);
diff --git a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echozonedservice.cpp b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echozonedservice.cpp
index f7c5862..8476f35 100644
--- a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echozonedservice.cpp
+++ b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echozonedservice.cpp
@@ -28,6 +28,8 @@
#include "echozonedservice.h"
+#include <QTimer>
+
#define SET_VALUE(m_VALUE, VALUE, CHANGED_SIGNAL) \
if (m_zoneHash.value(zone).m_VALUE == VALUE) \
return; \
@@ -207,13 +209,13 @@ QStringList EchoZonedService::availableZones()
return keys;
}
-QString EchoZonedService::echo(const QString &msg, const QString &zone)
+QVariant EchoZonedService::echo(const QString &msg, const QString &zone)
{
emit echoSlotCalled(msg, zone);
return msg;
}
-QString EchoZonedService::id(const QString &zone)
+QVariant EchoZonedService::id(const QString &zone)
{
emit idSlotCalled(zone);
return m_testId;
@@ -225,8 +227,18 @@ QVariant EchoZonedService::varMethod(const QString &zone)
return QVariant("FOOOO");
}
-Combo EchoZonedService::getCombo(const QString &zone)
+QVariant EchoZonedService::getCombo(const QString &zone)
{
emit getComboSlotCalled(zone);
- return m_testCombo;
+ return QVariant::fromValue(m_testCombo);
+}
+
+QVariant EchoZonedService::timer(int interval, const QString &zone)
+{
+ static quint64 counter = 0;
+ EchoZonedPendingResult pendingResult(counter++, false);
+ QTimer::singleShot(interval, this, [this, pendingResult, zone](){
+ emit pendingResultAvailable(pendingResult.id(), true, zone);
+ });
+ return QVariant::fromValue(pendingResult);
}
diff --git a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echozonedservice.h b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echozonedservice.h
index acdb5f5..6bfb567 100644
--- a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echozonedservice.h
+++ b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/echozonedservice.h
@@ -70,10 +70,11 @@ public slots:
qreal UPPERCASEPROPERTY(const QString &zone) override;
void setUPPERCASEPROPERTY(qreal UPPERCASEPROPERTY, const QString &zone) override;
QStringList availableZones() override;
- QString echo(const QString &msg, const QString &zone) override;
- QString id(const QString &zone) override;
+ QVariant echo(const QString &msg, const QString &zone) override;
+ QVariant id(const QString &zone) override;
QVariant varMethod(const QString &zone) override;
- Combo getCombo(const QString &zone) override;
+ QVariant getCombo(const QString &zone) override;
+ QVariant timer(int interval, const QString &zone) override;
Q_SIGNALS:
void echoSlotCalled(const QString &msg, const QString& zone);
diff --git a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/tst_echoqtro.cpp b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/tst_echoqtro.cpp
index c1f520a..33508d7 100644
--- a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/tst_echoqtro.cpp
+++ b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/tst_echoqtro.cpp
@@ -801,6 +801,71 @@ void EchoQtroTest::testMultipleSlotCalls()
QCOMPARE(echoZonedSpy[0][1].toString(), frontLeftZone);
}
+void EchoQtroTest::testAsyncSlotResults()
+{
+ Server server;
+ server.start();
+
+ Echo client;
+ QSignalSpy initSpy(&client, SIGNAL(isInitializedChanged(bool)));
+ QVERIFY(initSpy.isValid());
+ QVERIFY(client.startAutoDiscovery() == QIviAbstractFeature::ProductionBackendLoaded);
+
+ //wait until the client has connected and initial values are set
+ initSpy.wait(1000);
+ QCOMPARE(initSpy.count(), 1);
+ QVERIFY(client.isInitialized());
+
+ // test the timer() function which uses a pendingReply on the server side to return the
+ // function when the timer is finished.
+ QIviPendingReply<void> reply = client.timer(1000);
+ QIviPendingReply<void> reply2 = client.timer(500);
+ QSignalSpy echoReplySpy(reply.watcher(), SIGNAL(replySuccess()));
+ QSignalSpy echoReplySpy2(reply2.watcher(), SIGNAL(replySuccess()));
+
+ //Wait for the second reply to return first. Verify the other reply is not yet ready.
+ echoReplySpy2.wait();
+ QCOMPARE(echoReplySpy2.count(), 1);
+ QCOMPARE(echoReplySpy.count(), 0);
+
+ //Wait for the first reply and verify both replies were sent.
+ echoReplySpy.wait();
+ QCOMPARE(echoReplySpy2.count(), 1);
+ QCOMPARE(echoReplySpy.count(), 1);
+
+ EchoZoned zonedClient;
+ QSignalSpy zonedInitSpy(&zonedClient, SIGNAL(isInitializedChanged(bool)));
+ QVERIFY(zonedInitSpy.isValid());
+ QVERIFY(zonedClient.startAutoDiscovery() == QIviAbstractFeature::ProductionBackendLoaded);
+
+ //wait until the client has connected and initial values are set
+ zonedInitSpy.wait(1000);
+ QCOMPARE(zonedInitSpy.count(), 1);
+ QVERIFY(zonedClient.isInitialized());
+
+ EchoZoned *zone = qobject_cast<EchoZoned*>(zonedClient.zoneAt(frontLeftZone));
+ QVERIFY(zone);
+
+ // test the timer() function which uses a pendingReply on the server side to return the
+ // function when the timer is finished.
+ QIviPendingReply<QString> zonedReply = zonedClient.timer(1000);
+ QIviPendingReply<QString> zonedReply2 = zone->timer(500);
+ QSignalSpy zonedEchoReplySpy(zonedReply.watcher(), SIGNAL(replySuccess()));
+ QSignalSpy zonedEchoReplySpy2(zonedReply2.watcher(), SIGNAL(replySuccess()));
+
+ //Wait for the second reply to return first. Verify the other reply is not yet ready.
+ zonedEchoReplySpy2.wait();
+ QCOMPARE(zonedEchoReplySpy2.count(), 1);
+ QCOMPARE(zonedEchoReplySpy.count(), 0);
+ QCOMPARE(zonedReply2.value(), frontLeftZone);
+
+ //Wait for the first reply and verify both replies were sent.
+ zonedEchoReplySpy.wait();
+ QCOMPARE(zonedEchoReplySpy2.count(), 1);
+ QCOMPARE(zonedEchoReplySpy.count(), 1);
+ QCOMPARE(zonedReply.value(), QString());
+}
+
void EchoQtroTest::testSignals()
{
Server server;
diff --git a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/tst_echoqtro.h b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/tst_echoqtro.h
index 84aabcd..5ff3da4 100644
--- a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/tst_echoqtro.h
+++ b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/tst_echoqtro.h
@@ -52,6 +52,7 @@ private slots:
void testSlots();
void testZonedSlots();
void testMultipleSlotCalls();
+ void testAsyncSlotResults();
void testSignals();
void testModel();
};