qmlobject_cast: Make it useful again
The Qt 6 implementation of qmlobject_cast simply accessed the metaObject of the object (canConvert -> QQmlMetaObject::QQmlMetaObject(QObject*) -> QOject:metaObject). That would directly cause the creation of dynamic meta-objects, if they weren't created so far. Given that we still didn't get rid of the property-cache in QML, use it to optimize this code path: If the object has some associated QQmlData, retrieve it and check if we have a property cache. If we do, retrieve the first C++ meta object from it. We can safely ignore any dynamic meta-objects as T must be a static meta-object. Then do the normal inheritance check with the first C++ meta-object and T::staticMetaObject. If we don't have a property cache, fall back to the previous implementation (but without the QQmlMetaObject detour). Change-Id: Ie23d1a3dac6bf343ee2bc31e04c4592681ad9995 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
51c6db3f3d
commit
677cd24de6
|
@ -596,6 +596,16 @@ void QQmlApplication::setDomain(const QString &arg)
|
||||||
QCoreApplication::instance()->setOrganizationDomain(arg);
|
QCoreApplication::instance()->setOrganizationDomain(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool qmlobject_can_cast(QObject *object, const QMetaObject *mo)
|
||||||
|
{
|
||||||
|
Q_ASSERT(object);
|
||||||
|
Q_ASSERT(mo);
|
||||||
|
auto ddata = QQmlData::get(object, false);
|
||||||
|
if (!ddata || ! ddata->propertyCache)
|
||||||
|
return object->metaObject()->inherits(mo);
|
||||||
|
return ddata->propertyCache->firstCppMetaObject()->inherits(mo);
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#include "moc_qqmlglobal_p.cpp"
|
#include "moc_qqmlglobal_p.cpp"
|
||||||
|
|
|
@ -122,6 +122,8 @@ do { \
|
||||||
QMetaObject::disconnect(sender, signalIdx, receiver, methodIdx); \
|
QMetaObject::disconnect(sender, signalIdx, receiver, methodIdx); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
Q_QML_PRIVATE_EXPORT bool qmlobject_can_cast(QObject *object, const QMetaObject *mo);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
This method is identical to qobject_cast<T>() except that it does not require lazy
|
This method is identical to qobject_cast<T>() except that it does not require lazy
|
||||||
QMetaObjects to be built, so should be preferred in all QML code that might interact
|
QMetaObjects to be built, so should be preferred in all QML code that might interact
|
||||||
|
@ -137,7 +139,9 @@ do { \
|
||||||
template<class T>
|
template<class T>
|
||||||
T qmlobject_cast(QObject *object)
|
T qmlobject_cast(QObject *object)
|
||||||
{
|
{
|
||||||
if (object && QQmlMetaObject::canConvert(object, &reinterpret_cast<T>(object)->staticMetaObject))
|
if (!object)
|
||||||
|
return nullptr;
|
||||||
|
if (qmlobject_can_cast(object, &(std::remove_pointer_t<T>::staticMetaObject)))
|
||||||
return static_cast<T>(object);
|
return static_cast<T>(object);
|
||||||
else
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
Loading…
Reference in New Issue