diff options
author | Michael Brasser <mbrasser@ford.com> | 2020-02-22 18:25:11 -0600 |
---|---|---|
committer | Michael Brasser <mbrasser@ford.com> | 2020-02-25 11:58:32 -0600 |
commit | 14daacff9654980381a1d0b7b09d0b25f6c9dbb2 (patch) | |
tree | 44e04cb331ec4b01c897b7e534ff9fb587c0164b | |
parent | 4520d5d091373f4ec1af0c5a134eef806a98e6b7 (diff) |
Fix QML bindings to second replica properties
Ensure notify signals are emitted when the second replica
is initialized.
Change-Id: Ie78ba4a66e08db9514b16f6e18f7950a5246f8ab
Reviewed-by: Brett Stottlemyer <bstottle@ford.com>
-rw-r--r-- | src/remoteobjects/qremoteobjectreplica.cpp | 24 | ||||
-rw-r--r-- | tests/auto/integration/tst_integration.cpp | 26 | ||||
-rw-r--r-- | tests/auto/qml/usertypes/data/twoReplicas.qml | 29 | ||||
-rw-r--r-- | tests/auto/qml/usertypes/tst_usertypes.cpp | 19 |
4 files changed, 96 insertions, 2 deletions
diff --git a/src/remoteobjects/qremoteobjectreplica.cpp b/src/remoteobjects/qremoteobjectreplica.cpp index 4669230..4557ae4 100644 --- a/src/remoteobjects/qremoteobjectreplica.cpp +++ b/src/remoteobjects/qremoteobjectreplica.cpp @@ -546,9 +546,29 @@ void QRemoteObjectReplicaImplementation::configurePrivate(QRemoteObjectReplica * void QConnectedReplicaImplementation::configurePrivate(QRemoteObjectReplica *rep) { - if (m_metaObject) + if (m_metaObject) { + // see QRemoteObjectReplicaImplementation::configurePrivate + const bool firstReplicaInstance = (m_methodOffset == 0); + QRemoteObjectReplicaImplementation::configurePrivate(rep); - else + + // ensure that notify signals are emitted for the new replica, when + // we are initializing an nth replica of the same type + if (!firstReplicaInstance) { + const int offset = m_propertyOffset; + const int nParam = m_propertyStorage.count(); + void *args[] = {nullptr, nullptr}; + for (int i = 0; i < nParam; ++i) { + const int notifyIndex = m_metaObject->property(i+offset).notifySignalIndex(); + if (notifyIndex < 0) + continue; + qCDebug(QT_REMOTEOBJECT) << " Before activate" << notifyIndex << m_metaObject->property(i+offset).name(); + args[1] = m_propertyStorage[i].data(); + // NOTE: this over-emits (assumes all values have changed) + QMetaObject::activate(rep, rep->metaObject(), notifyIndex - m_signalOffset, args); + } + } + } else m_parentsNeedingConnect.append(rep); } diff --git a/tests/auto/integration/tst_integration.cpp b/tests/auto/integration/tst_integration.cpp index 0718219..4f65243 100644 --- a/tests/auto/integration/tst_integration.cpp +++ b/tests/auto/integration/tst_integration.cpp @@ -1062,6 +1062,32 @@ private slots: QCOMPARE(engine_r2->rpm(), e.rpm()); } + // verify that our second replica emits "Changed" signals when initialized + void doubleReplicaTest2() + { + setupHost(); + Engine e; + host->enableRemoting(&e); + e.setRpm(3412); + + setupClient(); + + const QScopedPointer<EngineReplica> engine_r1(client->acquire< EngineReplica >()); + QSignalSpy spy_r1(engine_r1.data(), SIGNAL(rpmChanged(int))); + engine_r1->waitForSource(); + QCOMPARE(engine_r1->rpm(), e.rpm()); + QCOMPARE(spy_r1.count(), 1); + + // NOTE: A second replica will have initialized and notify signals emitted as part of acquire, + // which leads to different semantics for first and second replicas. Specifically, there is no + // way to hook in to initialized and the initial notify signals. We should consider changing this. + const QScopedPointer<EngineReplica> engine_r2(client->acquire< EngineReplica >()); +// QSignalSpy spy_r2(engine_r2.data(), SIGNAL(rpmChanged(int))); +// engine_r2->waitForSource(); + QCOMPARE(engine_r2->rpm(), e.rpm()); +// QCOMPARE(spy_r2.count(), 1); + } + void twoReplicaTest() { setupHost(); Engine e; diff --git a/tests/auto/qml/usertypes/data/twoReplicas.qml b/tests/auto/qml/usertypes/data/twoReplicas.qml new file mode 100644 index 0000000..1516465 --- /dev/null +++ b/tests/auto/qml/usertypes/data/twoReplicas.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 +import QtRemoteObjects 5.12 +import usertypes 1.0 + +Item { + property int result: replica.hour + property int result2: replica2.hour + + Node { + id: sharedNode + registryUrl: "local:testTwoReplicas" + } + + SimpleClockReplica { + id: replica + node: sharedNode + } + + SimpleClockReplica { + id: replica2 + } + + Timer { + running: true + interval: 200 + onTriggered: replica2.node = sharedNode + } +} + diff --git a/tests/auto/qml/usertypes/tst_usertypes.cpp b/tests/auto/qml/usertypes/tst_usertypes.cpp index ddfb234..ecc6f15 100644 --- a/tests/auto/qml/usertypes/tst_usertypes.cpp +++ b/tests/auto/qml/usertypes/tst_usertypes.cpp @@ -63,6 +63,7 @@ private Q_SLOTS: void complexInQml_data(); void complexInQml(); void watcherInQml(); + void twoReplicas(); }; tst_usertypes::tst_usertypes() @@ -254,6 +255,24 @@ void tst_usertypes::watcherInQml() QCOMPARE(obj->property("hasError").value<bool>(), false); } +void tst_usertypes::twoReplicas() +{ + qmlRegisterType<SimpleClockReplica>("usertypes", 1, 0, "SimpleClockReplica"); + + QRemoteObjectRegistryHost host(QUrl("local:testTwoReplicas")); + SimpleClockSimpleSource clock; + clock.setHour(7); + host.enableRemoting(&clock); + + QQmlEngine e; + QQmlComponent c(&e, SRCDIR "data/twoReplicas.qml"); + QObject *obj = c.create(); + QVERIFY(obj); + + QTRY_COMPARE_WITH_TIMEOUT(obj->property("result").value<int>(), 7, 300); + QTRY_COMPARE_WITH_TIMEOUT(obj->property("result2").value<int>(), 7, 500); +} + QTEST_MAIN(tst_usertypes) #include "tst_usertypes.moc" |