summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brasser <mbrasser@ford.com>2020-02-22 18:25:11 -0600
committerMichael Brasser <mbrasser@ford.com>2020-02-25 11:58:32 -0600
commit14daacff9654980381a1d0b7b09d0b25f6c9dbb2 (patch)
tree44e04cb331ec4b01c897b7e534ff9fb587c0164b
parent4520d5d091373f4ec1af0c5a134eef806a98e6b7 (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.cpp24
-rw-r--r--tests/auto/integration/tst_integration.cpp26
-rw-r--r--tests/auto/qml/usertypes/data/twoReplicas.qml29
-rw-r--r--tests/auto/qml/usertypes/tst_usertypes.cpp19
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"