aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlabstractbinding.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-05-20 15:26:47 +0200
committerUlf Hermann <ulf.hermann@qt.io>2022-05-24 15:44:16 +0200
commitdc77f7c71c532a1c51f7618765559937fd5d2eb3 (patch)
treef1d633a5033b0a4cc30c52aac9b3b0a5be05385d /src/qml/qml/qqmlabstractbinding.cpp
parent3d8702378ba7f8252862aac8d71995d61f4f2b69 (diff)
Replace synthetic AOT functions with property-to-property bindings
Those should be more efficient and make your feet attract fewer projectiles. Fixes: QTBUG-103588 Change-Id: I8b25b9edb1edf5e112dbcba5bba898646d29ae2b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlabstractbinding.cpp')
-rw-r--r--src/qml/qml/qqmlabstractbinding.cpp96
1 files changed, 95 insertions, 1 deletions
diff --git a/src/qml/qml/qqmlabstractbinding.cpp b/src/qml/qml/qqmlabstractbinding.cpp
index 8c28c525f2..a84607d035 100644
--- a/src/qml/qml/qqmlabstractbinding.cpp
+++ b/src/qml/qml/qqmlabstractbinding.cpp
@@ -42,6 +42,7 @@
#include <QtQml/qqmlinfo.h>
#include <private/qqmlbinding_p.h>
#include <private/qqmlvaluetypeproxybinding_p.h>
+#include <private/qqmlvmemetaobject_p.h>
QT_BEGIN_NAMESPACE
@@ -190,11 +191,104 @@ void QQmlAbstractBinding::removeFromObject()
data->clearBindingBit(coreIndex);
}
-void QQmlAbstractBinding::printBindingLoopError(QQmlProperty &prop)
+void QQmlAbstractBinding::printBindingLoopError(const QQmlProperty &prop)
{
qmlWarning(prop.object()) << QString(QLatin1String("Binding loop detected for property \"%1\"")).arg(prop.name());
}
+void QQmlAbstractBinding::getPropertyData(
+ const QQmlPropertyData **propertyData, QQmlPropertyData *valueTypeData) const
+{
+ Q_ASSERT(propertyData);
+
+ QQmlData *data = QQmlData::get(m_target.data(), false);
+ Q_ASSERT(data);
+
+ if (Q_UNLIKELY(!data->propertyCache))
+ data->propertyCache = QQmlMetaType::propertyCache(m_target->metaObject());
+
+ *propertyData = data->propertyCache->property(m_targetIndex.coreIndex());
+ Q_ASSERT(*propertyData);
+
+ if (Q_UNLIKELY(m_targetIndex.hasValueTypeIndex() && valueTypeData)) {
+ const QMetaObject *valueTypeMetaObject
+ = QQmlMetaType::metaObjectForValueType((*propertyData)->propType());
+ Q_ASSERT(valueTypeMetaObject);
+ QMetaProperty vtProp = valueTypeMetaObject->property(m_targetIndex.valueTypeIndex());
+ valueTypeData->setFlags(QQmlPropertyData::flagsForProperty(vtProp));
+ valueTypeData->setPropType(vtProp.metaType());
+ valueTypeData->setCoreIndex(m_targetIndex.valueTypeIndex());
+ }
+}
+
+void QQmlAbstractBinding::updateCanUseAccessor()
+{
+ setCanUseAccessor(true); // Always use accessors, except when:
+ if (auto interceptorMetaObject = QQmlInterceptorMetaObject::get(targetObject())) {
+ if (!m_targetIndex.isValid() || interceptorMetaObject->intercepts(m_targetIndex))
+ setCanUseAccessor(false);
+ }
+}
+
+void QQmlAbstractBinding::setTarget(const QQmlProperty &prop)
+{
+ auto pd = QQmlPropertyPrivate::get(prop);
+ setTarget(prop.object(), pd->core, &pd->valueTypeData);
+}
+
+bool QQmlAbstractBinding::setTarget(
+ QObject *object, const QQmlPropertyData &core, const QQmlPropertyData *valueType)
+{
+ return setTarget(object, core.coreIndex(), core.isAlias(),
+ valueType ? valueType->coreIndex() : -1);
+}
+
+bool QQmlAbstractBinding::setTarget(
+ QObject *object, int coreIndex, bool coreIsAlias, int valueTypeIndex)
+{
+ m_target = object;
+
+ if (!object) {
+ m_targetIndex = QQmlPropertyIndex();
+ return false;
+ }
+
+ for (bool isAlias = coreIsAlias; isAlias;) {
+ QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
+
+ int aValueTypeIndex;
+ if (!vme->aliasTarget(coreIndex, &object, &coreIndex, &aValueTypeIndex)) {
+ // can't resolve id (yet)
+ m_target = nullptr;
+ m_targetIndex = QQmlPropertyIndex();
+ return false;
+ }
+ if (valueTypeIndex == -1)
+ valueTypeIndex = aValueTypeIndex;
+
+ QQmlData *data = QQmlData::get(object, false);
+ if (!data || !data->propertyCache) {
+ m_target = nullptr;
+ m_targetIndex = QQmlPropertyIndex();
+ return false;
+ }
+ const QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex);
+ Q_ASSERT(propertyData);
+
+ m_target = object;
+ isAlias = propertyData->isAlias();
+ coreIndex = propertyData->coreIndex();
+ }
+ m_targetIndex = QQmlPropertyIndex(coreIndex, valueTypeIndex);
+
+ QQmlData *data = QQmlData::get(m_target.data(), true);
+ if (!data->propertyCache)
+ data->propertyCache = QQmlMetaType::propertyCache(m_target->metaObject());
+
+ return true;
+}
+
+
QString QQmlAbstractBinding::expression() const
{
return QLatin1String("<Unknown>");