From d52f983698f0d6239938dd748e30d98394fd2946 Mon Sep 17 00:00:00 2001 From: Brett Stottlemyer Date: Sun, 5 May 2019 13:16:40 -0400 Subject: 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 --- src/remoteobjects/qremoteobjectdynamicreplica.cpp | 16 ++++++++++++++-- src/remoteobjects/qremoteobjectnode.cpp | 8 ++++++-- 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(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(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)); -- cgit v1.2.3