summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrett Stottlemyer <bstottle@ford.com>2019-05-05 13:16:40 -0400
committerBrett Stottlemyer <bstottle@ford.com>2019-05-06 22:17:14 +0000
commitd52f983698f0d6239938dd748e30d98394fd2946 (patch)
tree284299e321bb07376e62e2d1facb88a654ac97f9
parent5517b432b1f3e602240bdf5b678a825f1ecafb35 (diff)
Fix a couple of metaObject vs m_metaObject issues
For a replica's private implementation, there are two metaObjects. The implementation class itself has a metaObject with the metacall magic shared amongst all replicas for forwarding calls. That version is returned by the private implementations metaObject() call. There is also the replica instances m_metaObject, which represents the interface the replica is copying. This is retrieved from the m_metaObject data member. There were a few cases where these were mixed up, so this cleans that up and tries to document the differences a little better. Change-Id: I6979e9e997a4e64dc35f91e94108165b50e7715f Reviewed-by: Michael Brasser <michael.brasser@live.com>
-rw-r--r--src/remoteobjects/qremoteobjectdynamicreplica.cpp16
-rw-r--r--src/remoteobjects/qremoteobjectnode.cpp8
2 files changed, 20 insertions, 4 deletions
diff --git a/src/remoteobjects/qremoteobjectdynamicreplica.cpp b/src/remoteobjects/qremoteobjectdynamicreplica.cpp
index 72f0c69..58b8778 100644
--- a/src/remoteobjects/qremoteobjectdynamicreplica.cpp
+++ b/src/remoteobjects/qremoteobjectdynamicreplica.cpp
@@ -78,15 +78,27 @@ QRemoteObjectDynamicReplica::~QRemoteObjectDynamicReplica()
/*!
\internal
- Returns a pointer to the dynamically generated meta-object of this object, or 0 if the object is not initialized. This function overrides the QObject::metaObject() virtual function to provide the same functionality for dynamic replicas.
+ Returns a pointer to the dynamically generated meta-object of this object, or
+ QRemoteObjectDynamicReplica's metaObject if the object is not initialized. This
+ function overrides the QObject::metaObject() virtual function to provide the same
+ functionality for dynamic replicas.
\sa QObject::metaObject(), {Replica Initialization}
*/
const QMetaObject* QRemoteObjectDynamicReplica::metaObject() const
{
auto impl = qSharedPointerCast<QRemoteObjectReplicaImplementation>(d_impl);
+ // Returning nullptr will likely result in a crash if this type is used before the
+ // definition is received. Note: QRemoteObjectDynamicReplica doesn't include the
+ // QObject macro, so it's metaobject would resolve to QRemoteObjectReplica::metaObject()
+ // if we weren't overriding it.
+ if (!impl->m_metaObject) {
+ qWarning() << "Dynamic metaobject is not assigned, returning generic Replica metaObject.";
+ qWarning() << "This may cause issues if used for more than checking the Replica state.";
+ return QRemoteObjectReplica::metaObject();
+ }
- return impl->m_metaObject ? impl->m_metaObject : QRemoteObjectReplica::metaObject();
+ return impl->m_metaObject;
}
/*!
diff --git a/src/remoteobjects/qremoteobjectnode.cpp b/src/remoteobjects/qremoteobjectnode.cpp
index 977d06f..d241e15 100644
--- a/src/remoteobjects/qremoteobjectnode.cpp
+++ b/src/remoteobjects/qremoteobjectnode.cpp
@@ -1229,6 +1229,8 @@ void QRemoteObjectNodePrivate::onClientRead(QObject *obj)
param[1] = paramValue.data();
}
qROPrivDebug() << "Replica Invoke-->" << rxName << rep->m_metaObject->method(index+rep->m_signalOffset).name() << index << rep->m_signalOffset;
+ // We activate on rep->metaobject() so the private metacall is used, not m_metaobject (which
+ // is the class thie replica looks like)
QMetaObject::activate(rep.data(), rep->metaObject(), index+rep->m_signalOffset, param.data());
} else { //replica has been deleted, remove from list
replicas.remove(rxName);
@@ -1804,8 +1806,10 @@ QVariant QRemoteObjectNodePrivate::handlePointerToQObjectProperty(QConnectedRepl
if (newReplica) {
if (rep->isInitialized()) {
auto childRep = qSharedPointerCast<QConnectedReplicaImplementation>(replicas.take(childInfo.name));
- if (childRep && !childRep->isShortCircuit())
- dynamicTypeManager.addFromMetaObject(childRep->metaObject());
+ if (childRep && !childRep->isShortCircuit()) {
+ qCDebug(QT_REMOTEOBJECT) << "Checking if dynamic type should be added to dynamicTypeManager (type =" << childRep->m_metaObject->className() << ")";
+ dynamicTypeManager.addFromMetaObject(childRep->m_metaObject);
+ }
}
if (childInfo.type == ObjectType::CLASS)
retval = QVariant::fromValue(q->acquireDynamic(childInfo.name));