Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmlobjectcreator_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#ifndef QQMLOBJECTCREATOR_P_H
4#define QQMLOBJECTCREATOR_P_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include <private/qqmlimport_p.h>
18#include <private/qqmltypenamecache_p.h>
19#include <private/qv4compileddata_p.h>
20#include <private/qfinitestack_p.h>
21#include <private/qrecursionwatcher_p.h>
22#include <private/qqmlprofiler_p.h>
23#include <private/qv4qmlcontext_p.h>
24#include <private/qqmlguardedcontextdata_p.h>
25#include <private/qqmlfinalizer_p.h>
26#include <private/qqmlvmemetaobject_p.h>
27
28#include <qpointer.h>
29
31
35
39};
40
49{
54};
55
57{
60 : object(object)
61 , data(data)
62 {}
63
64 const QObject *object = nullptr;
65 const QQmlPropertyData *data = nullptr;
66
67private:
68 friend size_t qHash(const RequiredPropertyKey &key, size_t seed = 0)
69 {
70 return qHashMulti(seed, key.object, key.data);
71 }
72
74 {
75 return a.object == b.object && a.data == b.data;
76 }
77};
78
79class RequiredProperties : public QHash<RequiredPropertyKey, RequiredPropertyInfo> {};
80
82 QObject *target = nullptr;
83 int properyIndex = -1;
85};
86
87struct QQmlObjectCreatorSharedState final : QQmlRefCounted<QQmlObjectCreatorSharedState>
88{
94 QV4::Value *allJavaScriptObjects; // pointer to vector on JS stack to reference JS wrappers during creation phase.
102};
103
104class Q_QML_PRIVATE_EXPORT QQmlObjectCreator
105{
107public:
110 const QQmlRefPointer<QQmlContextData> &creationContext,
111 QQmlIncubatorPrivate *incubator = nullptr);
113
114 enum CreationFlags { NormalObject = 1, InlineComponent = 2 };
115 QObject *create(int subComponentIndex = -1, QObject *parent = nullptr,
116 QQmlInstantiationInterrupt *interrupt = nullptr, int flags = NormalObject);
117
118 bool populateDeferredProperties(QObject *instance, const QQmlData::DeferredData *deferredData);
119
120 void beginPopulateDeferred(const QQmlRefPointer<QQmlContextData> &context);
121 void populateDeferredBinding(const QQmlProperty &qmlProperty, int deferredIndex,
122 const QV4::CompiledData::Binding *binding);
123 void finalizePopulateDeferred();
124
125 bool finalize(QQmlInstantiationInterrupt &interrupt);
126 void clear();
127
128 QQmlRefPointer<QQmlContextData> rootContext() const { return sharedState->rootContext; }
129 QQmlComponentAttached **componentAttachment() { return &sharedState->componentAttached; }
130
132
134 {
135 return parentContext.contextData();
136 }
137 QFiniteStack<QQmlGuard<QObject> > &allCreatedObjects() { return sharedState->allCreatedObjects; }
138
139 RequiredProperties *requiredProperties() {return &sharedState->requiredProperties;}
140 bool componentHadTopLevelRequiredProperties() const {return sharedState->hadTopLevelRequiredProperties;}
141
142 static QQmlComponent *createComponent(QQmlEngine *engine,
143 QV4::ExecutableCompilationUnit *compilationUnit,
144 int index, QObject *parent,
146
147 void removePendingBinding(QObject *target, int propertyIndex)
148 {
149 QList<DeferredQPropertyBinding> &pendingBindings = sharedState.data()->allQPropertyBindings;
150 auto it = std::remove_if(pendingBindings.begin(), pendingBindings.end(),
151 [&](const DeferredQPropertyBinding &deferred) {
152 return deferred.properyIndex == propertyIndex && deferred.target == target;
153 });
154 pendingBindings.erase(it, pendingBindings.end());
155 }
156
157private:
160 QQmlObjectCreatorSharedState *inheritedSharedState,
161 bool isContextObject);
162
163 void init(QQmlRefPointer<QQmlContextData> parentContext);
164
165 QObject *createInstance(int index, QObject *parent = nullptr, bool isContextObject = false);
166
167 bool populateInstance(int index, QObject *instance, QObject *bindingTarget,
168 const QQmlPropertyData *valueTypeProperty,
169 const QV4::CompiledData::Binding *binding = nullptr);
170
171 // If qmlProperty and binding are null, populate all properties, otherwise only the given one.
172 void populateDeferred(QObject *instance, int deferredIndex);
173 void populateDeferred(QObject *instance, int deferredIndex,
174 const QQmlPropertyPrivate *qmlProperty,
175 const QV4::CompiledData::Binding *binding);
176
177 enum BindingMode {
178 ApplyNone = 0x0,
179 ApplyImmediate = 0x1,
180 ApplyDeferred = 0x2,
181 ApplyAll = ApplyImmediate | ApplyDeferred,
182 };
183 Q_DECLARE_FLAGS(BindingSetupFlags, BindingMode);
184
185 void setupBindings(BindingSetupFlags mode = BindingMode::ApplyImmediate);
186 bool setPropertyBinding(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding);
187 void setPropertyValue(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding);
188 void setupFunctions();
189
190 QString stringAt(int idx) const { return compilationUnit->stringAt(idx); }
191 void recordError(const QV4::CompiledData::Location &location, const QString &description);
192
193 void registerObjectWithContextById(const QV4::CompiledData::Object *object, QObject *instance) const;
194
195 inline QV4::QmlContext *currentQmlContext();
196 QV4::ResolvedTypeReference *resolvedType(int id) const
197 {
198 return compilationUnit->resolvedType(id);
199 }
200
201 enum Phase {
202 Startup,
203 CreatingObjects,
204 CreatingObjectsPhase2,
205 ObjectsCreated,
206 Finalizing,
207 Done
208 } phase;
209
213 const QV4::CompiledData::Unit *qmlUnit;
214 QQmlGuardedContextData parentContext;
216 const QQmlPropertyCacheVector *propertyCaches;
218 bool topLevelCreator;
219 bool isContextObject;
220 QQmlIncubatorPrivate *incubator;
221
222 QObject *_qobject;
223 QObject *_scopeObject;
224 QObject *_bindingTarget;
225
226 const QQmlPropertyData *_valueTypeProperty; // belongs to _qobjectForBindings's property cache
227 int _compiledObjectIndex;
228 const QV4::CompiledData::Object *_compiledObject;
229 QQmlData *_ddata;
230 QQmlPropertyCache::ConstPtr _propertyCache;
231 QQmlVMEMetaObject *_vmeMetaObject;
232 QQmlListProperty<void> _currentList;
233 QV4::QmlContext *_qmlContext;
234
236
237 typedef std::function<bool(QQmlObjectCreatorSharedState *sharedState)> PendingAliasBinding;
238 std::vector<PendingAliasBinding> pendingAliasBindings;
239
240 template<typename Functor>
241 void doPopulateDeferred(QObject *instance, int deferredIndex, Functor f)
242 {
243 QQmlData *declarativeData = QQmlData::get(instance);
244 QObject *bindingTarget = instance;
245
247 QQmlVMEMetaObject *vmeMetaObject = QQmlVMEMetaObject::get(instance);
248
249 QObject *scopeObject = instance;
250 qt_ptr_swap(_scopeObject, scopeObject);
251
252 QV4::Scope valueScope(v4);
253 QScopedValueRollback<QV4::Value*> jsObjectGuard(sharedState->allJavaScriptObjects,
254 valueScope.alloc(compilationUnit->totalObjectCount()));
255
256 Q_ASSERT(topLevelCreator);
257 QV4::QmlContext *qmlContext = static_cast<QV4::QmlContext *>(valueScope.alloc());
258
259 qt_ptr_swap(_qmlContext, qmlContext);
260
261 _propertyCache.swap(cache);
262 qt_ptr_swap(_qobject, instance);
263
264 int objectIndex = deferredIndex;
265 std::swap(_compiledObjectIndex, objectIndex);
266
267 const QV4::CompiledData::Object *obj = compilationUnit->objectAt(_compiledObjectIndex);
268 qt_ptr_swap(_compiledObject, obj);
269 qt_ptr_swap(_ddata, declarativeData);
270 qt_ptr_swap(_bindingTarget, bindingTarget);
271 qt_ptr_swap(_vmeMetaObject, vmeMetaObject);
272
273 f();
274
275 qt_ptr_swap(_vmeMetaObject, vmeMetaObject);
276 qt_ptr_swap(_bindingTarget, bindingTarget);
277 qt_ptr_swap(_ddata, declarativeData);
278 qt_ptr_swap(_compiledObject, obj);
279 std::swap(_compiledObjectIndex, objectIndex);
280 qt_ptr_swap(_qobject, instance);
281 _propertyCache.swap(cache);
282
283 qt_ptr_swap(_qmlContext, qmlContext);
284 qt_ptr_swap(_scopeObject, scopeObject);
285 }
286};
287
289{
291
292 bool hasRecursed() const { return watcher.hasRecursed(); }
293
294private:
297};
298
299QV4::QmlContext *QQmlObjectCreator::currentQmlContext()
300{
301 if (!_qmlContext->isManaged())
302 _qmlContext->setM(QV4::QmlContext::create(v4->rootContext(), context, _scopeObject));
303
304 return _qmlContext;
305}
306
308
309#endif // QQMLOBJECTCREATOR_P_H
\inmodule QtCore
Definition qhash.h:818
Definition qlist.h:74
iterator erase(const_iterator begin, const_iterator end)
Definition qlist.h:882
iterator end()
Definition qlist.h:609
iterator begin()
Definition qlist.h:608
pointer data()
Definition qlist.h:414
\inmodule QtCore
Definition qobject.h:90
The QQmlComponent class encapsulates a QML component definition.
QQmlPropertyCache::ConstPtr propertyCache
Definition qqmldata_p.h:195
static QQmlData * get(QObjectPrivate *priv, bool create)
Definition qqmldata_p.h:199
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
The QQmlListProperty class allows applications to expose list-like properties of QObject-derived clas...
Definition qqmllist.h:24
QQmlComponentAttached ** componentAttachment()
QQmlObjectCreator(QQmlRefPointer< QQmlContextData > parentContext, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit, const QQmlRefPointer< QQmlContextData > &creationContext, QQmlIncubatorPrivate *incubator=nullptr)
bool componentHadTopLevelRequiredProperties() const
QQmlRefPointer< QQmlContextData > parentContextData() const
void removePendingBinding(QObject *target, int propertyIndex)
RequiredProperties * requiredProperties()
QList< QQmlError > errors
QFiniteStack< QQmlGuard< QObject > > & allCreatedObjects()
QQmlRefPointer< QQmlContextData > rootContext() const
The QQmlProperty class abstracts accessing properties on objects created from QML.
void swap(QQmlRefPointer &other) noexcept
static QQmlVMEMetaObject * get(QObject *o)
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
\inmodule QtCore
Definition qurl.h:94
b clear()
QCache< int, Employee > cache
[0]
QSet< QString >::iterator it
@ Startup
Definition qhooks_p.h:33
Combined button and popup list for selecting options.
static void * context
#define Q_DECLARE_TR_FUNCTIONS(context)
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition qflags.h:174
constexpr QtPrivate::QHashMultiReturnType< T... > qHashMulti(size_t seed, const T &... args) noexcept(std::conjunction_v< QtPrivate::QNothrowHashable< T >... >)
GLint location
GLboolean GLboolean GLboolean b
GLenum mode
GLuint64 key
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint index
[2]
GLuint object
[3]
GLfloat GLfloat f
GLenum target
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLhandleARB obj
[2]
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:71
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
constexpr void qt_ptr_swap(T *&lhs, T *&rhs) noexcept
Definition qswap.h:43
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
const char property[13]
Definition qwizard.cpp:101
QItemEditorCreatorBase * creator
view create()
QJSEngine engine
[0]
QUntypedPropertyBinding binding
QList< DeferredQPropertyBinding > allQPropertyBindings
QFiniteStack< QQmlAbstractBinding::Ptr > allCreatedBindings
QQmlRefPointer< QQmlContextData > rootContext
QQmlRefPointer< QQmlContextData > creationContext
QQmlComponentAttached * componentAttached
QFiniteStack< QQmlGuard< QObject > > allCreatedObjects
RequiredProperties requiredProperties
QFiniteStack< QQmlParserStatus * > allParserStatusCallbacks
QList< QQmlFinalizerHook * > finalizeHooks
ExecutionContext * rootContext() const
static Heap::QmlContext * create(QV4::ExecutionContext *parent, QQmlRefPointer< QQmlContextData > context, QObject *scopeObject)
bool isManaged() const
QVector< AliasToRequiredInfo > aliasesToRequired
QV4::CompiledData::Location location
friend bool operator==(const RequiredPropertyKey &a, const RequiredPropertyKey &b)
friend size_t qHash(const RequiredPropertyKey &key, size_t seed=0)
RequiredPropertyKey()=default
RequiredPropertyKey(const QObject *object, const QQmlPropertyData *data)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent