Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmlabstractbinding_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQMLABSTRACTBINDING_P_H
5#define QQMLABSTRACTBINDING_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/qsharedpointer.h>
19#include <QtCore/qshareddata.h>
20#include <private/qtqmlglobal_p.h>
21#include <private/qqmlproperty_p.h>
22
23QT_BEGIN_NAMESPACE
24
25class QQmlObjectCreator;
26class QQmlAnyBinding;
27
28class Q_QML_EXPORT QQmlAbstractBinding
29{
30 friend class QQmlAnyBinding;
31protected:
32 QQmlAbstractBinding();
33public:
34 enum Kind {
35 ValueTypeProxy,
36 QmlBinding,
37 PropertyToPropertyBinding,
38 };
39
40 virtual ~QQmlAbstractBinding();
41
42 typedef QExplicitlySharedDataPointer<QQmlAbstractBinding> Ptr;
43
44 virtual QString expression() const;
45
46 virtual Kind kind() const = 0;
47
48 // Should return the encoded property index for the binding. Should return this value
49 // even if the binding is not enabled or added to an object.
50 // Encoding is: coreIndex | (valueTypeIndex << 16)
51 QQmlPropertyIndex targetPropertyIndex() const { return m_targetIndex; }
52
53 // Should return the object for the binding. Should return this object even if the
54 // binding is not enabled or added to the object.
55 QObject *targetObject() const { return m_target.data(); }
56
57 void setTarget(const QQmlProperty &);
58 bool setTarget(QObject *, const QQmlPropertyData &, const QQmlPropertyData *valueType);
59 bool setTarget(QObject *, int coreIndex, bool coreIsAlias, int valueTypeIndex);
60
61 virtual void setEnabled(bool e, QQmlPropertyData::WriteFlags f = QQmlPropertyData::DontRemoveBinding) = 0;
62
63 void addToObject();
64 void removeFromObject();
65
66 virtual void printBindingLoopError(const QQmlProperty &prop);
67
68 inline QQmlAbstractBinding *nextBinding() const;
69
70 inline bool canUseAccessor() const
71 { return m_target.tag().testFlag(CanUseAccessor); }
72 void setCanUseAccessor(bool canUseAccessor)
73 { m_target.setTag(m_target.tag().setFlag(CanUseAccessor, canUseAccessor)); }
74
75 bool isSticky() const { return m_target.tag().testFlag(IsSticky); }
76 void setSticky(bool isSticky) { m_target.setTag(m_target.tag().setFlag(IsSticky, isSticky)); }
77
78 struct RefCount {
79 RefCount() {}
80 int refCount = 0;
81 void ref() { ++refCount; }
82 int deref() { return --refCount; }
83 operator int() const { return refCount; }
84 };
85 RefCount ref;
86
87 // A binding can only be enabled if it's added to an object,
88 // and it can only be updating if it's enabled.
89 enum State {
90 Disabled = 0,
91 AddedToObject = 1,
92 BindingEnabled = 2,
93 UpdatingBinding = 3,
94 };
95
96 enum TargetTag {
97 NoTargetTag = 0x0,
98 CanUseAccessor = 0x1,
99 IsSticky = 0x2,
100 };
101 Q_DECLARE_FLAGS(TargetTags, TargetTag)
102
103protected:
104 friend class QQmlData;
105 friend class QQmlValueTypeProxyBinding;
106 friend class QQmlObjectCreator;
107
108 inline void setAddedToObject(bool v);
109 inline bool isAddedToObject() const;
110
111 inline void setNextBinding(QQmlAbstractBinding *);
112
113 void getPropertyData(
114 const QQmlPropertyData **propertyData, QQmlPropertyData *valueTypeData) const;
115
116 inline bool updatingFlag() const;
117 inline void setUpdatingFlag(bool);
118 inline bool enabledFlag() const;
119 inline void setEnabledFlag(bool);
120 void updateCanUseAccessor();
121
122 QQmlPropertyIndex m_targetIndex;
123
124 // Pointer is the target object to which the binding binds
125 QTaggedPointer<QObject, TargetTags> m_target;
126
127 // Pointer to the next binding in the linked list of bindings.
128 QTaggedPointer<QQmlAbstractBinding, State> m_nextBinding;
129
130private:
131 void setState(State state, bool enabled)
132 {
133 if (enabled) {
134 m_nextBinding.setTag(std::max(m_nextBinding.tag(), state));
135 return;
136 }
137
138 Q_ASSERT(state > 0);
139 m_nextBinding.setTag(std::min(m_nextBinding.tag(), State(state - 1)));
140 }
141
142 bool hasState(State state) const
143 {
144 return m_nextBinding.tag() >= state;
145 }
146};
147
148Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlAbstractBinding::TargetTags)
149
150void QQmlAbstractBinding::setAddedToObject(bool v)
151{
152 setState(AddedToObject, v);
153}
154
155bool QQmlAbstractBinding::isAddedToObject() const
156{
157 return hasState(AddedToObject);
158}
159
160QQmlAbstractBinding *QQmlAbstractBinding::nextBinding() const
161{
162 return m_nextBinding.data();
163}
164
165void QQmlAbstractBinding::setNextBinding(QQmlAbstractBinding *b)
166{
167 if (b)
168 b->ref.ref();
169 if (m_nextBinding.data() && !m_nextBinding->ref.deref())
170 delete m_nextBinding.data();
171 m_nextBinding = b;
172}
173
174bool QQmlAbstractBinding::updatingFlag() const
175{
176 return hasState(UpdatingBinding);
177}
178
179void QQmlAbstractBinding::setUpdatingFlag(bool v)
180{
181 setState(UpdatingBinding, v);
182}
183
184bool QQmlAbstractBinding::enabledFlag() const
185{
186 return hasState(BindingEnabled);
187}
188
189void QQmlAbstractBinding::setEnabledFlag(bool v)
190{
191 setState(BindingEnabled, v);
192}
193
194QT_END_NAMESPACE
195
196#endif // QQMLABSTRACTBINDING_P_H
QQmlAnyBinding is an abstraction over the various bindings in QML.
static const QQmlPropertyData * getObjectPropertyData(QObject *object, int coreIndex)