41void QQmlAbstractBinding::addToObject()
43 Q_ASSERT(!nextBinding());
44 Q_ASSERT(isAddedToObject() ==
false);
46 QObject *obj = targetObject();
49 QQmlData *data = QQmlData::get(obj,
true);
51 int coreIndex = targetPropertyIndex().coreIndex();
52 if (targetPropertyIndex().hasValueTypeIndex()) {
56 QQmlValueTypeProxyBinding *proxy =
nullptr;
57 QQmlAbstractBinding *b = data->bindings;
58 while (b && (b->targetPropertyIndex().coreIndex() != coreIndex ||
59 b->targetPropertyIndex().hasValueTypeIndex())) {
63 if (b && b->kind() == QQmlAbstractBinding::ValueTypeProxy) {
64 proxy =
static_cast<QQmlValueTypeProxyBinding *>(b);
66 proxy =
new QQmlValueTypeProxyBinding(obj, QQmlPropertyIndex(coreIndex));
68 Q_ASSERT(proxy->targetPropertyIndex().coreIndex() == coreIndex);
69 Q_ASSERT(!proxy->targetPropertyIndex().hasValueTypeIndex());
70 Q_ASSERT(proxy->targetObject() == obj);
75 setNextBinding(proxy->m_bindings.data());
76 proxy->m_bindings =
this;
79 setNextBinding(data->bindings);
81 data->bindings->ref.deref();
82 Q_ASSERT(data->bindings->ref.refCount > 0);
84 data->bindings =
this;
87 data->setBindingBit(obj, coreIndex);
90 setAddedToObject(
true);
96void QQmlAbstractBinding::removeFromObject()
98 if (!isAddedToObject())
101 setAddedToObject(
false);
103 QObject *obj = targetObject();
104 QQmlData *data = QQmlData::get(obj,
false);
107 QQmlAbstractBinding::Ptr next;
108 next = nextBinding();
109 setNextBinding(
nullptr);
111 int coreIndex = targetPropertyIndex().coreIndex();
112 if (targetPropertyIndex().hasValueTypeIndex()) {
115 QQmlAbstractBinding *vtbinding = data->bindings;
117 while (vtbinding->targetPropertyIndex().coreIndex() != coreIndex
118 || vtbinding->targetPropertyIndex().hasValueTypeIndex()) {
119 vtbinding = vtbinding->nextBinding();
122 Q_ASSERT(vtbinding->kind() == QQmlAbstractBinding::ValueTypeProxy);
124 QQmlValueTypeProxyBinding *vtproxybinding =
125 static_cast<QQmlValueTypeProxyBinding *>(vtbinding);
127 QQmlAbstractBinding *binding = vtproxybinding->m_bindings.data();
128 if (binding ==
this) {
129 vtproxybinding->m_bindings = next;
131 while (binding->nextBinding() !=
this) {
132 binding = binding->nextBinding();
135 binding->setNextBinding(next.data());
144 if (data->bindings ==
this) {
147 data->bindings = next.data();
151 QQmlAbstractBinding *binding = data->bindings;
152 while (binding->nextBinding() !=
this) {
153 binding = binding->nextBinding();
156 binding->setNextBinding(next.data());
159 data->clearBindingBit(coreIndex);
167void QQmlAbstractBinding::getPropertyData(
168 const QQmlPropertyData **propertyData, QQmlPropertyData *valueTypeData)
const
170 Q_ASSERT(propertyData);
172 QQmlData *data = QQmlData::get(m_target.data(),
false);
175 if (Q_UNLIKELY(!data->propertyCache))
176 data->propertyCache = QQmlMetaType::propertyCache(m_target->metaObject());
178 *propertyData = data->propertyCache->property(m_targetIndex.coreIndex());
179 Q_ASSERT(*propertyData);
181 if (Q_UNLIKELY(m_targetIndex.hasValueTypeIndex() && valueTypeData)) {
182 const QMetaObject *valueTypeMetaObject
183 = QQmlMetaType::metaObjectForValueType((*propertyData)->propType());
184 Q_ASSERT(valueTypeMetaObject);
185 QMetaProperty vtProp = valueTypeMetaObject->property(m_targetIndex.valueTypeIndex());
186 valueTypeData->setFlags(QQmlPropertyData::flagsForProperty(vtProp));
187 valueTypeData->setPropType(vtProp.metaType());
188 valueTypeData->setCoreIndex(m_targetIndex.valueTypeIndex());
207bool QQmlAbstractBinding::setTarget(
208 QObject *object,
const QQmlPropertyData &core,
const QQmlPropertyData *valueType)
210 return setTarget(object, core.coreIndex(), core.isAlias(),
211 valueType ? valueType->coreIndex() : -1);
231bool QQmlAbstractBinding::setTarget(
232 QObject *object,
int coreIndex,
bool coreIsAlias,
int valueTypeIndex)
234 auto invalidate = [
this]() {
236 m_targetIndex = QQmlPropertyIndex();
245 for (
bool isAlias = coreIsAlias; isAlias;) {
246 QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
249 if (!vme->aliasTarget(coreIndex, &object, &coreIndex, &aValueTypeIndex)) {
254 const QQmlPropertyData *propertyData = getObjectPropertyData(object, coreIndex);
258 if (aValueTypeIndex != -1) {
259 if (propertyData->propType().flags().testFlag(QMetaType::PointerToQObject)) {
261 propertyData->readProperty(object, &object);
262 coreIndex = aValueTypeIndex;
264 propertyData = getObjectPropertyData(object, coreIndex);
268 valueTypeIndex = aValueTypeIndex;
273 isAlias = propertyData->isAlias();
274 coreIndex = propertyData->coreIndex();
276 m_targetIndex = QQmlPropertyIndex(coreIndex, valueTypeIndex);
278 QQmlData *data = QQmlData::get(m_target.data(),
true);
279 if (!data->propertyCache)
280 data->propertyCache = QQmlMetaType::propertyCache(m_target->metaObject());