diff options
12 files changed, 143 insertions, 62 deletions
diff --git a/src/ivicore/qiviabstractfeature.cpp b/src/ivicore/qiviabstractfeature.cpp index 39d554a..6022c22 100644 --- a/src/ivicore/qiviabstractfeature.cpp +++ b/src/ivicore/qiviabstractfeature.cpp @@ -65,6 +65,9 @@ QIviAbstractFeaturePrivate::QIviAbstractFeaturePrivate(const QString &interface, , m_supportsPropertyOverriding(false) , m_propertyOverride(nullptr) { + qRegisterMetaType<QIviAbstractFeature::Error>(); + qRegisterMetaType<QIviAbstractFeature::DiscoveryMode>(); + qRegisterMetaType<QIviAbstractFeature::DiscoveryResult>(); } void QIviAbstractFeaturePrivate::initialize() @@ -228,9 +231,6 @@ QIviAbstractFeature::QIviAbstractFeature(const QString &interface, QObject *pare { Q_D(QIviAbstractFeature); d->initialize(); - qRegisterMetaType<QIviAbstractFeature::Error>(); - qRegisterMetaType<QIviAbstractFeature::DiscoveryMode>(); - qRegisterMetaType<QIviAbstractFeature::DiscoveryResult>(); } /*! diff --git a/src/ivicore/qiviabstractzonedfeature.cpp b/src/ivicore/qiviabstractzonedfeature.cpp index db40065..0bf98e3 100644 --- a/src/ivicore/qiviabstractzonedfeature.cpp +++ b/src/ivicore/qiviabstractzonedfeature.cpp @@ -121,10 +121,10 @@ void QIviAbstractZonedFeature::connectToServiceObject(QIviServiceObject *service else if (serviceObject) backend = qobject_cast<QIviZonedFeatureInterface*>(serviceObject->interfaceInstance(interfaceName())); - if (backend) { - connect(backend, &QIviZonedFeatureInterface::errorChanged, this, &QIviAbstractZonedFeature::onErrorChanged); + if (backend) initializeZones(); - } + + QIviAbstractFeature::connectToServiceObject(serviceObject); } /*! diff --git a/src/tools/ivigenerator/templates_backend_qtro/backend.cpp.tpl b/src/tools/ivigenerator/templates_backend_qtro/backend.cpp.tpl index a30437b..2c7f5a0 100644 --- a/src/tools/ivigenerator/templates_backend_qtro/backend.cpp.tpl +++ b/src/tools/ivigenerator/templates_backend_qtro/backend.cpp.tpl @@ -57,6 +57,15 @@ QT_BEGIN_NAMESPACE : {{class}}Interface(parent) { {{module.module_name|upperfirst}}Module::registerTypes(); +} + +{{class}}::~{{class}}() +{ + delete m_node; +} + +void {{class}}::initialize() +{ QString configPath = "./server.conf"; if (qEnvironmentVariableIsSet("SERVER_CONF_PATH")) configPath = QString::fromLatin1(qgetenv("SERVER_CONF_PATH")); @@ -66,23 +75,17 @@ QT_BEGIN_NAMESPACE settings.beginGroup("{{module.module_name|lower}}"); QUrl url = QUrl(settings.value("Registry", "local:{{module.module_name|lower}}").toString()); m_node = new QRemoteObjectNode(url); - connect(m_node, &QRemoteObjectNode::error, this, &{{class}}::onError); + connect(m_node, &QRemoteObjectNode::error, this, &{{class}}::onNodeError); m_replica.reset(m_node->acquire<{{interface}}Replica>("{{interface.qualified_name}}")); setupConnections(); -} -{{class}}::~{{class}}() -{ - delete m_node; -} - -void {{class}}::initialize() -{ {% for property in interface.properties %} {% if not property.is_model %} emit {{property}}Changed(m_replica->{{property}}()); {% endif %} {% endfor %} + if (m_replica->isInitialized()) + emit initializationDone(); } {% for property in interface.properties %} @@ -119,6 +122,8 @@ void {{class}}::set{{property|upperfirst}}({{ property|parameter_type }}) void {{class}}::setupConnections() { + connect(m_replica.data(), &QRemoteObjectReplica::initialized, this, &QIviFeatureInterface::initializationDone); + connect(m_replica.data(), &QRemoteObjectReplica::stateChanged, this, &{{class}}::onReplicaStateChanged); {% for property in interface.properties if not property.type.is_model %} connect(m_replica.data(), &{{interface}}Replica::{{property}}Changed, this, &{{class}}::{{property}}Changed); {% endfor %} @@ -127,10 +132,26 @@ void {{class}}::setupConnections() {% endfor %} } -void {{class}}::onError(QRemoteObjectNode::ErrorCode code) +void {{class}}::onReplicaStateChanged(QRemoteObjectReplica::State newState, + QRemoteObjectReplica::State oldState) +{ + if (newState == QRemoteObjectReplica::Suspect) { + qDebug() << "{{class}}, QRemoteObjectReplica error, connection to the source lost"; + emit errorChanged(QIviAbstractFeature::Unknown, + "QRemoteObjectReplica error, connection to the source lost"); + } else if (newState == QRemoteObjectReplica::SignatureMismatch) { + qDebug() << "{{class}}, QRemoteObjectReplica error, signature mismatch"; + emit errorChanged(QIviAbstractFeature::Unknown, + "QRemoteObjectReplica error, signature mismatch"); + } else if (newState==QRemoteObjectReplica::Valid) { + emit errorChanged(QIviAbstractFeature::NoError, ""); + } +} + +void {{class}}::onNodeError(QRemoteObjectNode::ErrorCode code) { - qDebug() << "{{class}}, QRemoteObjects error, code: " << code; - emit errorChanged(QIviAbstractFeature::Unknown, "QRemoteObjects error, code: " + code); + qDebug() << "{{class}}, QRemoteObjectNode error, code: " << code; + emit errorChanged(QIviAbstractFeature::Unknown, "QRemoteObjectNode error, code: " + code); } QT_END_NAMESPACE diff --git a/src/tools/ivigenerator/templates_backend_qtro/backend.h.tpl b/src/tools/ivigenerator/templates_backend_qtro/backend.h.tpl index 457b0fb..e49215d 100644 --- a/src/tools/ivigenerator/templates_backend_qtro/backend.h.tpl +++ b/src/tools/ivigenerator/templates_backend_qtro/backend.h.tpl @@ -74,7 +74,10 @@ public Q_SLOTS: virtual {{operation|return_type}} {{operation}}({{operation.parameters|map('parameter_type')|join(', ')}}){%if operation.const %} const{% endif %} override; {% endfor %} - void onError(QRemoteObjectNode::ErrorCode code); +protected Q_SLOTS: + void onReplicaStateChanged(QRemoteObjectReplica::State newState, + QRemoteObjectReplica::State oldState); + void onNodeError(QRemoteObjectNode::ErrorCode code); protected: void setupConnections(); diff --git a/src/tools/ivigenerator/templates_backend_simulator/backend.cpp.tpl b/src/tools/ivigenerator/templates_backend_simulator/backend.cpp.tpl index 499f1d7..090dd46 100644 --- a/src/tools/ivigenerator/templates_backend_simulator/backend.cpp.tpl +++ b/src/tools/ivigenerator/templates_backend_simulator/backend.cpp.tpl @@ -158,6 +158,7 @@ void {{class}}::initialize() mWorker->addReceiver(this); {% endif %} + emit initializationDone(); } {% for property in interface.properties %} diff --git a/src/tools/ivigenerator/templates_frontend/interface.cpp.tpl b/src/tools/ivigenerator/templates_frontend/interface.cpp.tpl index 9adb81e..f327da4 100644 --- a/src/tools/ivigenerator/templates_frontend/interface.cpp.tpl +++ b/src/tools/ivigenerator/templates_frontend/interface.cpp.tpl @@ -369,11 +369,6 @@ QIviAbstractZonedFeature *{{class}}::createZoneFeature(const QString &zone) /*! \internal */ void {{class}}::connectToServiceObject(QIviServiceObject *serviceObject) { -{% if interface.tags.config.zoned %} - QIviAbstractZonedFeature::connectToServiceObject(serviceObject); -{% else %} - Q_UNUSED(serviceObject); -{% endif %} auto d = {{class}}Private::get(this); auto *backend = qobject_cast<{{class}}BackendInterface*>(this->backend()); @@ -393,7 +388,11 @@ void {{class}}::connectToServiceObject(QIviServiceObject *serviceObject) d, &{{class}}Private::on{{signal|upperfirst}}); {% endfor %} - backend->initialize(); +{% if interface.tags.config.zoned %} + QIviAbstractZonedFeature::connectToServiceObject(serviceObject); +{% else %} + QIviAbstractFeature::connectToServiceObject(serviceObject); +{% endif %} } /*! \internal */ diff --git a/src/tools/ivigenerator/templates_test/tst_test.cpp.tpl b/src/tools/ivigenerator/templates_test/tst_test.cpp.tpl index bdbd248..106be23 100644 --- a/src/tools/ivigenerator/templates_test/tst_test.cpp.tpl +++ b/src/tools/ivigenerator/templates_test/tst_test.cpp.tpl @@ -242,6 +242,21 @@ void {{interface}}Test::cleanup() manager->unloadAllBackends(); } +void {{interface}}Test::testInitBackend() +{ + {{interface}}TestServiceObject *service = new {{interface}}TestServiceObject(); + manager->registerService(service, service->interfaces()); + + {{interface}} cc; + QSignalSpy initSpy(&cc, SIGNAL(isInitializedChanged(bool))); + QVERIFY(initSpy.isValid()); + cc.startAutoDiscovery(); + + QCOMPARE(initSpy.count(), 1); + QCOMPARE(initSpy.at(0).at(0).toBool(), true); + QVERIFY(cc.isInitialized()); +} + void {{interface}}Test::testWithoutBackend() { {{interface}} cc; diff --git a/src/tools/ivigenerator/templates_test/tst_test.h.tpl b/src/tools/ivigenerator/templates_test/tst_test.h.tpl index d97b126..714fa6f 100644 --- a/src/tools/ivigenerator/templates_test/tst_test.h.tpl +++ b/src/tools/ivigenerator/templates_test/tst_test.h.tpl @@ -52,6 +52,7 @@ public: private slots: void cleanup(); + void testInitBackend(); void testWithoutBackend(); void testInvalidBackend(); void testClearServiceObject(); diff --git a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/server.cpp b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/server.cpp index eac8f57..38bc5fd 100644 --- a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/server.cpp +++ b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/server.cpp @@ -34,7 +34,12 @@ bool Server::start() return Core::instance()->host()->enableRemoting(&m_service, "org.example.echo.Echo"); } +bool Server::stop() +{ + return Core::instance()->host()->disableRemoting(&m_service); +} + Server::~Server() { - qWarning() << "disableRemoting, returned=" << Core::instance()->host()->disableRemoting(&m_service); + stop(); } diff --git a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/server.h b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/server.h index da18928..b87f46e 100644 --- a/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/server.h +++ b/tests/auto/core/ivigenerator/projects/org-example-echo-qtro/server_qtro_test/server.h @@ -37,6 +37,7 @@ class Server : public QObject public Q_SLOTS: bool start(); + bool stop(); public: EchoService m_service; 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 9c61799..34d77cd 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 @@ -88,16 +88,17 @@ void EchoQtroTest::testInit() server.m_service.setContact(contactTestValue); server.m_service.setWeekDay(weekDayTestValue); - QVERIFY(server.start()); - + QVERIFY(!client.isInitialized()); + QCOMPARE(client.error(), QIviAbstractFeature::NoError); - //hack that makes sure we wait until the client is connected to the server - //QSignalSpy spy(&client, SIGNAL(weekDayChanged(EchoModule::WeekDay))); - QSignalSpy spy(&client, SIGNAL(floatValue1Changed(qreal))); - QVERIFY(spy.isValid()); - spy.wait(1000); - // end of hack + QVERIFY(server.start()); + //wait until the client has connected and initial values are set + QSignalSpy initSpy(&client, SIGNAL(isInitializedChanged(bool))); + QVERIFY(initSpy.isValid()); + initSpy.wait(1000); + QCOMPARE(initSpy.count(), 1); + QVERIFY(client.isInitialized()); //test that client gets the same values that were set at the server before connection was established QCOMPARE(client.lastMessage(),lastMessageTestValue); @@ -109,11 +110,10 @@ void EchoQtroTest::testInit() QCOMPARE(contactList[0].value<Contact>(), contactListTestValue[0].value<Contact>()); QCOMPARE(contactList[1].value<Contact>(), contactListTestValue[1].value<Contact>()); QCOMPARE(client.contact(), contactTestValue); - QCOMPARE(server.m_service.weekDay(), weekDayTestValue); QCOMPARE(client.weekDay(), weekDayTestValue); } -void EchoQtroTest::testClient2Server() +void EchoQtroTest::testReconnect() { Server server; QVERIFY(server.start()); @@ -121,13 +121,50 @@ void EchoQtroTest::testClient2Server() Echo client; QVERIFY(client.startAutoDiscovery()==QIviAbstractFeature::ProductionBackendLoaded); + //wait until the client has connected and initial values are set + QSignalSpy initSpy(&client, SIGNAL(isInitializedChanged(bool))); + QVERIFY(initSpy.isValid()); + initSpy.wait(1000); + QCOMPARE(initSpy.count(), 1); + QVERIFY(client.isInitialized()); + + //test disconnection + QCOMPARE(client.error(), QIviAbstractFeature::NoError); + QSignalSpy disconnectSpy(&client, SIGNAL(errorChanged(QIviAbstractFeature::Error,QString))); + QVERIFY(disconnectSpy.isValid()); + + server.stop(); + + disconnectSpy.wait(1000); + QCOMPARE(disconnectSpy.count(), 1); + QCOMPARE(client.error(), QIviAbstractFeature::Unknown); + + //test reconnection + QSignalSpy reconnectSpy(&client, SIGNAL(errorChanged(QIviAbstractFeature::Error,QString))); + QVERIFY(reconnectSpy.isValid()); + + server.start(); + + reconnectSpy.wait(1000); + QCOMPARE(reconnectSpy.count(), 1); + QCOMPARE(client.error(), QIviAbstractFeature::NoError); +} + +void EchoQtroTest::testClient2Server() +{ + Server server; + QVERIFY(server.start()); + + Echo client; + QVERIFY(client.startAutoDiscovery()==QIviAbstractFeature::ProductionBackendLoaded); - //hack that makes sure we wait until the client is connected to the server - server.m_service.setFloatValue1(1.0); - QSignalSpy spy(&client, SIGNAL(floatValue1Changed(qreal))); - spy.wait(1000); - // end of hack + //wait until the client has connected and initial values are set + QSignalSpy initSpy(&client, SIGNAL(isInitializedChanged(bool))); + QVERIFY(initSpy.isValid()); + initSpy.wait(1000); + QCOMPARE(initSpy.count(), 1); + QVERIFY(client.isInitialized()); //test properties QSignalSpy intValueSpy(&server.m_service, SIGNAL(intValueChanged(int))); @@ -202,12 +239,12 @@ void EchoQtroTest::testServer2Client() QVERIFY(client.startAutoDiscovery()==QIviAbstractFeature::ProductionBackendLoaded); - //hack that makes sure we wait until the client is connected to the server - server.m_service.setFloatValue1(1.0); - QSignalSpy spy(&client, SIGNAL(floatValue1Changed(qreal))); - spy.wait(1000); - // end of hack - + //wait until the client has connected and initial values are set + QSignalSpy initSpy(&client, SIGNAL(isInitializedChanged(bool))); + QVERIFY(initSpy.isValid()); + initSpy.wait(1000); + QCOMPARE(initSpy.count(), 1); + QVERIFY(client.isInitialized()); //test properties QSignalSpy intValueSpy(&client, SIGNAL(intValueChanged(int))); @@ -282,19 +319,18 @@ void EchoQtroTest::testSlots() client.startAutoDiscovery(); - //hack that makes sure we wait until the client is connected to the server - server.m_service.setFloatValue1(1.0); - QSignalSpy spy(&client, SIGNAL(floatValue1Changed(qreal))); - spy.wait(1000); - // end of hack - + //wait until the client has connected and initial values are set + QSignalSpy initSpy(&client, SIGNAL(isInitializedChanged(bool))); + QVERIFY(initSpy.isValid()); + initSpy.wait(1000); + QCOMPARE(initSpy.count(), 1); + QVERIFY(client.isInitialized()); //test slots by calling them on the client QSignalSpy echoSpy(&server.m_service, SIGNAL(echoSlotCalled(const QString&))); QVERIFY(echoSpy.isValid()); QString echoTestValue("this will be echoed"); QString echoReturnValue = client.echo(echoTestValue); - //echoSpy.wait(1000); QCOMPARE(echoReturnValue, echoTestValue); QCOMPARE(echoSpy.count(),1); QCOMPARE(echoSpy[0][0].toString(), echoTestValue); @@ -302,14 +338,12 @@ void EchoQtroTest::testSlots() QSignalSpy idSpy(&server.m_service, SIGNAL(idSlotCalled())); QVERIFY(idSpy.isValid()); QString idReturnValue = client.id(); - //idSpy.wait(1000); QCOMPARE(idReturnValue, server.m_service.m_testId); QCOMPARE(idSpy.count(),1); QSignalSpy getComboSpy(&server.m_service, SIGNAL(getComboSlotCalled())); QVERIFY(getComboSpy.isValid()); Combo comboReturnValue = client.getCombo(); - //getComboSpy.wait(1000); QCOMPARE(comboReturnValue, server.m_service.m_testCombo); QCOMPARE(getComboSpy.count(),1); @@ -337,12 +371,12 @@ void EchoQtroTest::testSignals() client.startAutoDiscovery(); - //hack that makes sure we wait until the client is connected to the server - server.m_service.setFloatValue1(1.0); - QSignalSpy spy(&client, SIGNAL(floatValue1Changed(qreal))); - spy.wait(1000); - // end of hack - + //wait until the client has connected and initial values are set + QSignalSpy initSpy(&client, SIGNAL(isInitializedChanged(bool))); + QVERIFY(initSpy.isValid()); + initSpy.wait(1000); + QCOMPARE(initSpy.count(), 1); + QVERIFY(client.isInitialized()); //test custom signals (other than property notifiers) from server to client QSignalSpy anotherChangedSpy(&client, SIGNAL(anotherChanged(AnotherStruct))); 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 cf58a40..263afc1 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 @@ -42,6 +42,7 @@ public: private slots: void cleanup(); void testInit(); + void testReconnect(); void testClient2Server(); void testServer2Client(); void testSlots(); |