Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickdeferredexecute.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 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
5
6#include <QtCore/qhash.h>
7#include <QtQml/qqmlengine.h>
8#include <QtQml/private/qqmldata_p.h>
9#include <QtQml/private/qqmlcomponent_p.h>
10#include <QtQml/private/qqmlobjectcreator_p.h>
11
12#include <deque>
13
15
16namespace QtQuickPrivate {
17
18static void cancelDeferred(QQmlData *ddata, int propertyIndex)
19{
20 auto dit = ddata->deferredData.rbegin();
21 while (dit != ddata->deferredData.rend()) {
22 (*dit)->bindings.remove(propertyIndex);
23 ++dit;
24 }
25}
26
28{
29 QObject *object = property.object();
30 QQmlData *ddata = QQmlData::get(object);
31 Q_ASSERT(!ddata->deferredData.isEmpty());
32
33 if (!ddata->propertyCache)
34 ddata->propertyCache = QQmlMetaType::propertyCache(object->metaObject());
35
36 int propertyIndex = property.index();
37 int wasInProgress = enginePriv->inProgressCreations;
38
39 /* we don't want deferred properties to suddenly depend on arbitrary
40 other properties which might have trigerred the construction of
41 objects as a consequence of a read.
42 */
44 auto cleanup = qScopeGuard([&](){
46 });
47
48 for (auto dit = ddata->deferredData.rbegin(); dit != ddata->deferredData.rend(); ++dit) {
49 QQmlData::DeferredData *deferData = *dit;
50
51 auto bindings = deferData->bindings;
52 auto range = bindings.equal_range(propertyIndex);
53 if (range.first == bindings.end())
54 continue;
55
58
59 QQmlContextData *creationContext = nullptr;
60 state.initCreator(deferData->context->parent(), deferData->compilationUnit, creationContext);
61
62 enginePriv->inProgressCreations++;
63
64 std::deque<const QV4::CompiledData::Binding *> reversedBindings;
65 std::copy(range.first, range.second, std::front_inserter(reversedBindings));
66 state.creator()->beginPopulateDeferred(deferData->context);
67 for (const QV4::CompiledData::Binding *binding : reversedBindings)
68 state.creator()->populateDeferredBinding(property, deferData->deferredIdx, binding);
69 state.creator()->finalizePopulateDeferred();
70 state.appendCreatorErrors();
71
72 deferredState->push_back(std::move(state));
73
74 // Cleanup any remaining deferred bindings for this property, also in inner contexts,
75 // to avoid executing them later and overriding the property that was just populated.
76 cancelDeferred(ddata, propertyIndex);
77 break;
78 }
79
80 return enginePriv->inProgressCreations > wasInProgress;
81}
82
84 QQuickUntypedDeferredPointer *delegate, bool isOwnState)
85{
86 QQmlData *data = QQmlData::get(object);
87 if (data && !data->deferredData.isEmpty() && !data->wasDeleted(object) && data->context) {
88 QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine());
89
91 if (beginDeferred(ep, QQmlProperty(object, property), &state)) {
92 if (QQmlComponentPrivate::DeferredState *delegateState = delegate->deferredState())
93 delegateState->swap(state);
94 } else if (isOwnState) {
95 delegate->clearDeferredState();
96 }
97
98 // Release deferred data for those compilation units that no longer have deferred bindings
99 data->releaseDeferredData();
100 } else if (isOwnState) {
101 delegate->clearDeferredState();
102 }
103}
104
106{
107 QQmlData *data = QQmlData::get(object);
108 if (data)
110}
111
113{
116 if (!state)
117 return;
118
119 QQmlData *data = QQmlData::get(object);
120 if (data && !data->wasDeleted(object)) {
121 /* we don't want deferred properties to suddenly depend on arbitrary
122 other properties which might have trigerred the construction of
123 objects as a consequence of a read.
124 */
126 auto cleanup = qScopeGuard([&](){
128 });
129
130 QQmlComponentPrivate::DeferredState localState = std::move(*state);
131 delegate->clearDeferredState();
132 QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine());
134 } else {
135 delegate->clearDeferredState();
136 }
137}
138
139} // QtQuickPrivate
140
std::pair< iterator, iterator > equal_range(const Key &key)
Definition qhash.h:2266
\inmodule QtCore
Definition qobject.h:103
std::vector< ConstructionState > DeferredState
static void completeDeferred(QQmlEnginePrivate *enginePriv, DeferredState *deferredState)
QQmlRefPointer< QQmlContextData > parent() const
static QQmlData * get(QObjectPrivate *priv, bool create)
Definition qqmldata_p.h:199
static QQmlEnginePrivate * get(QQmlEngine *e)
static QQmlPropertyCache::ConstPtr propertyCache(QObject *object, QTypeRevision version=QTypeRevision())
Returns a QQmlPropertyCache for obj if one is available.
The QQmlProperty class abstracts accessing properties on objects created from QML.
QQmlComponentPrivate::DeferredState * deferredState() const
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
else opt state
[0]
Combined button and popup list for selecting options.
BindingEvaluationState * suspendCurrentBindingStatus()
void restoreBindingStatus(BindingEvaluationState *status)
static void cancelDeferred(QQmlData *ddata, int propertyIndex)
void completeDeferred(QObject *object, const QString &property, QQuickUntypedDeferredPointer *delegate)
static bool beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &property, QQmlComponentPrivate::DeferredState *deferredState)
GLuint index
[2]
GLuint object
[3]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei range
static Q_CONSTINIT thread_local QBindingStatus bindingStatus
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
Definition qscopeguard.h:60
#define Q_UNUSED(x)
const char property[13]
Definition qwizard.cpp:101
QQmlRefPointer< QQmlContextData > context
Definition qqmldata_p.h:183
unsigned int deferredIdx
Definition qqmldata_p.h:176
QQmlRefPointer< QV4::ExecutableCompilationUnit > compilationUnit
Definition qqmldata_p.h:180
QMultiHash< int, const QV4::CompiledData::Binding * > bindings
Definition qqmldata_p.h:177