36void QQmlAbstractBinding::addToObject()
38 Q_ASSERT(!nextBinding());
39 Q_ASSERT(isAddedToObject() ==
false);
41 QObject *obj = targetObject();
44 QQmlData *data = QQmlData::get(obj,
true);
46 int coreIndex = targetPropertyIndex().coreIndex();
47 if (targetPropertyIndex().hasValueTypeIndex()) {
51 QQmlValueTypeProxyBinding *proxy =
nullptr;
52 QQmlAbstractBinding *b = data->bindings;
53 while (b && (b->targetPropertyIndex().coreIndex() != coreIndex ||
54 b->targetPropertyIndex().hasValueTypeIndex())) {
58 if (b && b->kind() == QQmlAbstractBinding::ValueTypeProxy) {
59 proxy =
static_cast<QQmlValueTypeProxyBinding *>(b);
61 proxy =
new QQmlValueTypeProxyBinding(obj, QQmlPropertyIndex(coreIndex));
63 Q_ASSERT(proxy->targetPropertyIndex().coreIndex() == coreIndex);
64 Q_ASSERT(!proxy->targetPropertyIndex().hasValueTypeIndex());
65 Q_ASSERT(proxy->targetObject() == obj);
70 setNextBinding(proxy->m_bindings.data());
71 proxy->m_bindings =
this;
74 setNextBinding(data->bindings);
76 data->bindings->ref.deref();
77 Q_ASSERT(data->bindings->ref.refCount > 0);
79 data->bindings =
this;
82 data->setBindingBit(obj, coreIndex);
85 setAddedToObject(
true);
91void QQmlAbstractBinding::removeFromObject()
93 if (!isAddedToObject())
96 setAddedToObject(
false);
98 QObject *obj = targetObject();
99 QQmlData *data = QQmlData::get(obj,
false);
102 QQmlAbstractBinding::Ptr next;
103 next = nextBinding();
104 setNextBinding(
nullptr);
106 int coreIndex = targetPropertyIndex().coreIndex();
107 if (targetPropertyIndex().hasValueTypeIndex()) {
110 QQmlAbstractBinding *vtbinding = data->bindings;
112 while (vtbinding->targetPropertyIndex().coreIndex() != coreIndex
113 || vtbinding->targetPropertyIndex().hasValueTypeIndex()) {
114 vtbinding = vtbinding->nextBinding();
117 Q_ASSERT(vtbinding->kind() == QQmlAbstractBinding::ValueTypeProxy);
119 QQmlValueTypeProxyBinding *vtproxybinding =
120 static_cast<QQmlValueTypeProxyBinding *>(vtbinding);
122 QQmlAbstractBinding *binding = vtproxybinding->m_bindings.data();
123 if (binding ==
this) {
124 vtproxybinding->m_bindings = next;
126 while (binding->nextBinding() !=
this) {
127 binding = binding->nextBinding();
130 binding->setNextBinding(next.data());
139 if (data->bindings ==
this) {
142 data->bindings = next.data();
146 QQmlAbstractBinding *binding = data->bindings;
147 while (binding->nextBinding() !=
this) {
148 binding = binding->nextBinding();
151 binding->setNextBinding(next.data());
154 data->clearBindingBit(coreIndex);
162void QQmlAbstractBinding::getPropertyData(
163 const QQmlPropertyData **propertyData, QQmlPropertyData *valueTypeData)
const
165 Q_ASSERT(propertyData);
167 QQmlData *data = QQmlData::get(m_target.data(),
false);
170 if (Q_UNLIKELY(!data->propertyCache))
171 data->propertyCache = QQmlMetaType::propertyCache(m_target->metaObject());
173 *propertyData = data->propertyCache->property(m_targetIndex.coreIndex());
174 Q_ASSERT(*propertyData);
176 if (Q_UNLIKELY(m_targetIndex.hasValueTypeIndex() && valueTypeData)) {
177 const QMetaObject *valueTypeMetaObject
178 = QQmlMetaType::metaObjectForValueType((*propertyData)->propType());
179 Q_ASSERT(valueTypeMetaObject);
180 QMetaProperty vtProp = valueTypeMetaObject->property(m_targetIndex.valueTypeIndex());
181 valueTypeData->setFlags(QQmlPropertyData::flagsForProperty(vtProp));
182 valueTypeData->setPropType(vtProp.metaType());
183 valueTypeData->setCoreIndex(m_targetIndex.valueTypeIndex());
202bool QQmlAbstractBinding::setTarget(
203 QObject *object,
const QQmlPropertyData &core,
const QQmlPropertyData *valueType)
205 return setTarget(object, core.coreIndex(), core.isAlias(),
206 valueType ? valueType->coreIndex() : -1);
226bool QQmlAbstractBinding::setTarget(
227 QObject *object,
int coreIndex,
bool coreIsAlias,
int valueTypeIndex)
229 auto invalidate = [
this]() {
231 m_targetIndex = QQmlPropertyIndex();
240 for (
bool isAlias = coreIsAlias; isAlias;) {
241 QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
244 if (!vme->aliasTarget(coreIndex, &object, &coreIndex, &aValueTypeIndex)) {
249 const QQmlPropertyData *propertyData = getObjectPropertyData(object, coreIndex);
253 if (aValueTypeIndex != -1) {
254 if (propertyData->propType().flags().testFlag(QMetaType::PointerToQObject)) {
256 propertyData->readProperty(object, &object);
257 coreIndex = aValueTypeIndex;
259 propertyData = getObjectPropertyData(object, coreIndex);
263 valueTypeIndex = aValueTypeIndex;
268 isAlias = propertyData->isAlias();
269 coreIndex = propertyData->coreIndex();
271 m_targetIndex = QQmlPropertyIndex(coreIndex, valueTypeIndex);
273 QQmlData *data = QQmlData::get(m_target.data(),
true);
274 if (!data->propertyCache)
275 data->propertyCache = QQmlMetaType::propertyCache(m_target->metaObject());