42void QQmlAbstractBinding::addToObject()
44 Q_ASSERT(!nextBinding());
45 Q_ASSERT(isAddedToObject() ==
false);
47 QObject *obj = targetObject();
50 QQmlData *data = QQmlData::get(obj,
true);
52 int coreIndex = targetPropertyIndex().coreIndex();
53 if (targetPropertyIndex().hasValueTypeIndex()) {
57 QQmlValueTypeProxyBinding *proxy =
nullptr;
58 QQmlAbstractBinding *b = data->bindings;
59 while (b && (b->targetPropertyIndex().coreIndex() != coreIndex ||
60 b->targetPropertyIndex().hasValueTypeIndex())) {
64 if (b && b->kind() == QQmlAbstractBinding::ValueTypeProxy) {
65 proxy =
static_cast<QQmlValueTypeProxyBinding *>(b);
67 proxy =
new QQmlValueTypeProxyBinding(obj, QQmlPropertyIndex(coreIndex));
69 Q_ASSERT(proxy->targetPropertyIndex().coreIndex() == coreIndex);
70 Q_ASSERT(!proxy->targetPropertyIndex().hasValueTypeIndex());
71 Q_ASSERT(proxy->targetObject() == obj);
76 setNextBinding(proxy->m_bindings.data());
77 proxy->m_bindings =
this;
80 setNextBinding(data->bindings);
82 data->bindings->ref.deref();
83 Q_ASSERT(data->bindings->ref.refCount > 0);
85 data->bindings =
this;
88 data->setBindingBit(obj, coreIndex);
91 setAddedToObject(
true);
97void QQmlAbstractBinding::removeFromObject()
99 if (!isAddedToObject())
102 setAddedToObject(
false);
104 QObject *obj = targetObject();
105 QQmlData *data = QQmlData::get(obj,
false);
108 QQmlAbstractBinding::Ptr next;
109 next = nextBinding();
110 setNextBinding(
nullptr);
112 int coreIndex = targetPropertyIndex().coreIndex();
113 if (targetPropertyIndex().hasValueTypeIndex()) {
116 QQmlAbstractBinding *vtbinding = data->bindings;
118 while (vtbinding->targetPropertyIndex().coreIndex() != coreIndex
119 || vtbinding->targetPropertyIndex().hasValueTypeIndex()) {
120 vtbinding = vtbinding->nextBinding();
123 Q_ASSERT(vtbinding->kind() == QQmlAbstractBinding::ValueTypeProxy);
125 QQmlValueTypeProxyBinding *vtproxybinding =
126 static_cast<QQmlValueTypeProxyBinding *>(vtbinding);
128 QQmlAbstractBinding *binding = vtproxybinding->m_bindings.data();
129 if (binding ==
this) {
130 vtproxybinding->m_bindings = next;
132 while (binding->nextBinding() !=
this) {
133 binding = binding->nextBinding();
136 binding->setNextBinding(next.data());
145 if (data->bindings ==
this) {
148 data->bindings = next.data();
152 QQmlAbstractBinding *binding = data->bindings;
153 while (binding->nextBinding() !=
this) {
154 binding = binding->nextBinding();
157 binding->setNextBinding(next.data());
160 data->clearBindingBit(coreIndex);
168void QQmlAbstractBinding::getPropertyData(
169 const QQmlPropertyData **propertyData, QQmlPropertyData *valueTypeData)
const
171 Q_ASSERT(propertyData);
173 QQmlData *data = QQmlData::get(m_target.data(),
false);
176 if (Q_UNLIKELY(!data->propertyCache))
177 data->propertyCache = QQmlMetaType::propertyCache(m_target->metaObject());
179 *propertyData = data->propertyCache->property(m_targetIndex.coreIndex());
180 Q_ASSERT(*propertyData);
182 if (Q_UNLIKELY(m_targetIndex.hasValueTypeIndex() && valueTypeData)) {
183 const QMetaObject *valueTypeMetaObject
184 = QQmlMetaType::metaObjectForValueType((*propertyData)->propType());
185 Q_ASSERT(valueTypeMetaObject);
186 QMetaProperty vtProp = valueTypeMetaObject->property(m_targetIndex.valueTypeIndex());
187 valueTypeData->setFlags(QQmlPropertyData::flagsForProperty(vtProp));
188 valueTypeData->setPropType(vtProp.metaType());
189 valueTypeData->setCoreIndex(m_targetIndex.valueTypeIndex());
208bool QQmlAbstractBinding::setTarget(
209 QObject *object,
const QQmlPropertyData &core,
const QQmlPropertyData *valueType)
211 return setTarget(object, core.coreIndex(), core.isAlias(),
212 valueType ? valueType->coreIndex() : -1);
232bool QQmlAbstractBinding::setTarget(
233 QObject *object,
int coreIndex,
bool coreIsAlias,
int valueTypeIndex)
235 auto invalidate = [
this]() {
237 m_targetIndex = QQmlPropertyIndex();
246 for (
bool isAlias = coreIsAlias; isAlias;) {
247 QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
250 if (!vme->aliasTarget(coreIndex, &object, &coreIndex, &aValueTypeIndex)) {
255 const QQmlPropertyData *propertyData = getObjectPropertyData(object, coreIndex);
259 if (aValueTypeIndex != -1) {
260 if (propertyData->propType().flags().testFlag(QMetaType::PointerToQObject)) {
262 propertyData->readProperty(object, &object);
263 coreIndex = aValueTypeIndex;
265 propertyData = getObjectPropertyData(object, coreIndex);
269 valueTypeIndex = aValueTypeIndex;
274 isAlias = propertyData->isAlias();
275 coreIndex = propertyData->coreIndex();
277 m_targetIndex = QQmlPropertyIndex(coreIndex, valueTypeIndex);
279 QQmlData *data = QQmlData::get(m_target.data(),
true);
280 if (!data->propertyCache)
281 data->propertyCache = QQmlMetaType::propertyCache(m_target->metaObject());