58class Q_QML_EXPORT
QQmlData :
public QAbstractDeclarativeData
61 enum Ownership { DoesNotOwnMemory, OwnsMemory };
63 QQmlData(Ownership ownership);
66 static inline void init() {
67 static bool initialized =
false;
70 QAbstractDeclarativeData::destroyed = destroyed;
71 QAbstractDeclarativeData::signalEmitted = signalEmitted;
72 QAbstractDeclarativeData::receivers = receivers;
73 QAbstractDeclarativeData::isSignalConnected = isSignalConnected;
77 static void destroyed(QAbstractDeclarativeData *, QObject *);
78 static void signalEmitted(QAbstractDeclarativeData *, QObject *,
int,
void **);
79 static int receivers(QAbstractDeclarativeData *,
const QObject *,
int);
80 static bool isSignalConnected(QAbstractDeclarativeData *,
const QObject *,
int);
82 void destroyed(QObject *);
84 void setImplicitDestructible() {
85 if (!explicitIndestructibleSet) indestructible =
false;
95 quint32 indestructible:1;
98 quint32 explicitIndestructibleSet:1;
101 quint32 hasTaintedV4Object:1;
102 quint32 isQueuedForDeletion:1;
104
105
106
107 quint32 rootObjectInCreation:1;
109 quint32 hasInterceptorMetaObject:1;
110 quint32 hasVMEMetaObject:1;
112
113
114
115
116 quint32 hasConstWrapper: 1;
122 quint32 bindingBitsArraySize : 16;
123 typedef quintptr BindingBitsType;
125 BitsPerType =
sizeof(BindingBitsType) * 8,
126 InlineBindingArraySize = 2
129 BindingBitsType *bindingBits;
130 BindingBitsType bindingBitsValue[InlineBindingArraySize];
134 QAtomicInteger<quint64> connectionMask;
135 QQmlNotifierEndpoint *todo =
nullptr;
136 QQmlNotifierEndpoint**notifies =
nullptr;
137 quint16 maximumTodoIndex = 0;
138 quint16 notifiesSize = 0;
141 void layout(QQmlNotifierEndpoint*);
143 QAtomicPointer<NotifyList> notifyList;
145 inline QQmlNotifierEndpoint *notify(
int index)
const;
146 void addNotify(
int index, QQmlNotifierEndpoint *);
147 int endpointCount(
int index);
148 bool signalHasEndpoint(
int index)
const;
150 enum class DeleteNotifyList { Yes, No };
151 void disconnectNotifiers(DeleteNotifyList doDelete);
154 QQmlContextData *context =
nullptr;
156 QQmlContextData *outerContext =
nullptr;
157 QQmlRefPointer<QQmlContextData> ownContext;
159 QQmlAbstractBinding *bindings =
nullptr;
160 QQmlBoundSignal *signalHandlers =
nullptr;
161 std::vector<QQmlPropertyObserver> propertyObservers;
164 QQmlData *nextContextObject =
nullptr;
165 QQmlData**prevContextObject =
nullptr;
167 inline bool hasBindingBit(
int)
const;
168 inline void setBindingBit(QObject *obj,
int);
169 inline void clearBindingBit(
int);
171 inline bool hasPendingBindingBit(
int index)
const;
172 inline void setPendingBindingBit(QObject *obj,
int);
173 inline void clearPendingBindingBit(
int);
175 quint16 lineNumber = 0;
176 quint16 columnNumber = 0;
178 quint32 jsEngineId = 0;
180 struct DeferredData {
183 unsigned int deferredIdx;
184 QMultiHash<
int,
const QV4::CompiledData::Binding *> bindings;
187 QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
190 QQmlRefPointer<QQmlContextData> context;
192
193
194 QString inlineComponentName;
195 Q_DISABLE_COPY(DeferredData);
197 QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
198 QList<DeferredData *> deferredData;
200 void deferData(
int objectIndex,
const QQmlRefPointer<QV4::ExecutableCompilationUnit> &,
201 const QQmlRefPointer<QQmlContextData> &,
const QString &inlineComponentName);
202 void releaseDeferredData();
204 QV4::WeakValue jsWrapper;
206 QQmlPropertyCache::ConstPtr propertyCache;
208 QQmlGuardImpl *guards =
nullptr;
210 static QQmlData *get(QObjectPrivate *priv,
bool create) {
213 if (priv->isDeletingChildren || priv->wasDeleted) {
216 }
else if (priv->declarativeData) {
217 return static_cast<QQmlData *>(priv->declarativeData);
219 return createQQmlData(priv);
225 static QQmlData *get(
const QObjectPrivate *priv) {
228 if (priv->isDeletingChildren || priv->wasDeleted)
230 if (priv->declarativeData)
231 return static_cast<QQmlData *>(priv->declarativeData);
235 static QQmlData *get(QObject *object,
bool create) {
236 return QQmlData::get(QObjectPrivate::get(object), create);
239 static QQmlData *get(
const QObject *object) {
240 return QQmlData::get(QObjectPrivate::get(object));
244 static bool keepAliveDuringGarbageCollection(
const QObject *object) {
245 QQmlData *ddata = get(object);
246 if (!ddata || ddata->indestructible || ddata->rootObjectInCreation)
251 bool hasExtendedData()
const {
return extendedData !=
nullptr; }
252 QHash<QQmlAttachedPropertiesFunc, QObject *> *attachedProperties()
const;
254 static inline bool wasDeleted(
const QObject *);
255 static inline bool wasDeleted(
const QObjectPrivate *);
257 static void markAsDeleted(QObject *);
258 static void setQueuedForDeletion(QObject *);
260 static inline void flushPendingBinding(QObject *object,
int coreIndex);
261 void flushPendingBinding(
int coreIndex);
263 static QQmlPropertyCache::ConstPtr ensurePropertyCache(QObject *object)
265 QQmlData *ddata = QQmlData::get(object,
true);
266 if (Q_LIKELY(ddata->propertyCache))
267 return ddata->propertyCache;
268 return createPropertyCache(object);
271 Q_ALWAYS_INLINE
static uint offsetForBit(
int bit) {
return static_cast<uint>(bit) / BitsPerType; }
272 Q_ALWAYS_INLINE
static BindingBitsType bitFlagForBit(
int bit) {
return BindingBitsType(1) << (
static_cast<uint>(bit) & (BitsPerType - 1)); }
276 mutable QQmlDataExtended *extendedData =
nullptr;
278 Q_NEVER_INLINE
static QQmlData *createQQmlData(QObjectPrivate *priv);
279 Q_NEVER_INLINE
static QQmlPropertyCache::ConstPtr createPropertyCache(QObject *object);
281 void removeFromContext();
282 void clearBindings();
283 bool clearSignalHandlers();
285 Q_ALWAYS_INLINE
bool hasBitSet(
int bit)
const
287 uint offset = offsetForBit(bit);
288 if (bindingBitsArraySize <= offset)
291 const BindingBitsType *bits = (bindingBitsArraySize == InlineBindingArraySize) ? bindingBitsValue : bindingBits;
292 return bits[offset] & bitFlagForBit(bit);
295 Q_ALWAYS_INLINE
void clearBit(
int bit)
297 uint offset = QQmlData::offsetForBit(bit);
298 if (bindingBitsArraySize > offset) {
299 BindingBitsType *bits = (bindingBitsArraySize == InlineBindingArraySize) ? bindingBitsValue : bindingBits;
300 bits[offset] &= ~QQmlData::bitFlagForBit(bit);
304 Q_ALWAYS_INLINE
void setBit(QObject *obj,
int bit)
306 uint offset = QQmlData::offsetForBit(bit);
307 BindingBitsType *bits = (bindingBitsArraySize == InlineBindingArraySize) ? bindingBitsValue : bindingBits;
308 if (Q_UNLIKELY(bindingBitsArraySize <= offset))
309 bits = growBits(obj, bit);
310 bits[offset] |= QQmlData::bitFlagForBit(bit);
313 Q_NEVER_INLINE BindingBitsType *growBits(QObject *obj,
int bit);
315 Q_DISABLE_COPY_MOVE(QQmlData);