Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmlengine_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 QQMLENGINE_P_H
5#define QQMLENGINE_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 "qqmlengine.h"
19
20#include <private/qfieldlist_p.h>
21#include <private/qintrusivelist_p.h>
22#include <private/qjsengine_p.h>
23#include <private/qjsvalue_p.h>
24#include <private/qpodvector_p.h>
25#include <private/qqmldirparser_p.h>
26#include <private/qqmlimport_p.h>
27#include <private/qqmlmetatype_p.h>
28#include <private/qqmlnotifier_p.h>
29#include <private/qqmlproperty_p.h>
30#include <private/qqmltypeloader_p.h>
31#include <private/qqmlvaluetype_p.h>
32#include <private/qrecyclepool_p.h>
33#include <private/qv4engine_p.h>
34
35#include <QtQml/qqml.h>
36#include <QtQml/qqmlcontext.h>
37
38#include <QtCore/qlist.h>
39#include <QtCore/qmetaobject.h>
40#include <QtCore/qmutex.h>
41#include <QtCore/qpair.h>
42#include <QtCore/qproperty.h>
43#include <QtCore/qstack.h>
44#include <QtCore/qstring.h>
45#include <QtCore/qthread.h>
46
47#include <atomic>
48
50
53class QQmlIncubator;
54class QQmlMetaObject;
55class QQmlNetworkAccessManagerFactory;
57class QQmlProfiler;
59
65 Q_CLASSINFO("QML.OmitFromQmlTypes", "true")
66};
67
68// This needs to be declared here so that the pool for it can live in QQmlEnginePrivate.
69// The inline method definitions are in qqmljavascriptexpression_p.h
71{
72public:
74
77 inline void Delete();
78
81};
82
84 Q_DISABLE_COPY_MOVE(QPropertyChangeTrigger)
85
88 , m_expression(expression)
89 {
90 }
91
96
97 QMetaProperty property() const;
98};
99
102 : QPropertyChangeTrigger(expression)
103 {}
104 TriggerList *next = nullptr;
105};
106
107class Q_QML_PRIVATE_EXPORT QQmlEnginePrivate : public QJSEnginePrivate
108{
109 Q_DECLARE_PUBLIC(QQmlEngine)
110public:
111 explicit QQmlEnginePrivate(QQmlEngine *q) : importDatabase(q), typeLoader(q) {}
112 ~QQmlEnginePrivate() override;
113
114 void init();
115 // No mutex protecting baseModulesUninitialized, because use outside QQmlEngine
116 // is just qmlClearTypeRegistrations (which can't be called while an engine exists)
118
119 QQmlPropertyCapture *propertyCapture = nullptr;
120
123
124 QQmlContext *rootContext = nullptr;
126
127#if !QT_CONFIG(qml_debug)
128 static const quintptr profiler = 0;
129#else
130 QQmlProfiler *profiler = nullptr;
131#endif
132
133 bool outputWarningsToMsgLog = true;
134
135 // Bindings that have had errors during startup
136 QQmlDelayedError *erroredBindings = nullptr;
137 int inProgressCreations = 0;
138
139 QV4::ExecutionEngine *v4engine() const { return q_func()->handle(); }
140
141#if QT_CONFIG(qml_worker_script)
142 QThread *workerScriptEngine = nullptr;
143#endif
144
146
147 QQmlObjectCreator *activeObjectCreator = nullptr;
148#if QT_CONFIG(qml_network)
149 QNetworkAccessManager *createNetworkAccessManager(QObject *parent) const;
150 QNetworkAccessManager *getNetworkAccessManager() const;
151 mutable QNetworkAccessManager *networkAccessManager = nullptr;
152 mutable QQmlNetworkAccessManagerFactory *networkAccessManagerFactory = nullptr;
153#endif
156 QSharedPointer<QQmlImageProviderBase> imageProvider(const QString &providerId) const;
157
159
160 int scarceResourcesRefCount = 0;
161 void referenceScarceResources();
162 void dereferenceScarceResources();
163
166
168
169 // Unfortunate workaround to avoid a circular dependency between
170 // qqmlengine_p.h and qqmlincubator_p.h
171 struct Incubator {
173 };
175 unsigned int incubatorCount = 0;
176 QQmlIncubationController *incubationController = nullptr;
177 void incubate(QQmlIncubator &, const QQmlRefPointer<QQmlContextData> &);
178
179 // These methods may be called from any thread
180 QString offlineStorageDatabaseDirectory() const;
181
182 bool isTypeLoaded(const QUrl &url) const;
183 bool isScriptLoaded(const QUrl &url) const;
184
185 template <typename T>
186 T singletonInstance(const QQmlType &type);
187
188 void sendQuit();
189 void sendExit(int retCode = 0);
190 void warning(const QQmlError &);
191 void warning(const QList<QQmlError> &);
192 static void warning(QQmlEngine *, const QQmlError &);
193 static void warning(QQmlEngine *, const QList<QQmlError> &);
194 static void warning(QQmlEnginePrivate *, const QQmlError &);
195 static void warning(QQmlEnginePrivate *, const QList<QQmlError> &);
196
197 inline static QV4::ExecutionEngine *getV4Engine(QQmlEngine *e);
198 inline static QQmlEnginePrivate *get(QQmlEngine *e);
199 inline static const QQmlEnginePrivate *get(const QQmlEngine *e);
200 inline static QQmlEnginePrivate *get(QQmlContext *c);
202 inline static QQmlEngine *get(QQmlEnginePrivate *p);
204
205 static QList<QQmlError> qmlErrorFromDiagnostics(const QString &fileName, const QList<QQmlJS::DiagnosticMessage> &diagnosticMessages);
206
207 static bool designerMode();
208 static void activateDesignerMode();
209
210 static std::atomic<bool> qml_debugging_enabled;
211
213
215 {
216 int typeIndex = type.id();
217 auto it = cachedValueTypeInstances.find(typeIndex);
218 if (it != cachedValueTypeInstances.end())
219 return *it;
220
221 if (QQmlValueType *valueType = QQmlMetaType::valueType(type)) {
222 QQmlGadgetPtrWrapper *instance = new QQmlGadgetPtrWrapper(valueType);
223 cachedValueTypeInstances.insert(typeIndex, instance);
224 return instance;
225 }
226
227 return nullptr;
228 }
229
230 void executeRuntimeFunction(const QUrl &url, qsizetype functionIndex, QObject *thisObject,
231 int argc = 0, void **args = nullptr, QMetaType *types = nullptr);
232 void executeRuntimeFunction(const QV4::ExecutableCompilationUnit *unit, qsizetype functionIndex,
233 QObject *thisObject, int argc = 0, void **args = nullptr,
234 QMetaType *types = nullptr);
235 QV4::ExecutableCompilationUnit *compilationUnitFromUrl(const QUrl &url);
237 createInternalContext(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit,
238 const QQmlRefPointer<QQmlContextData> &parentContext,
239 int subComponentIndex, bool isComponentRoot);
242 {
243 Q_ASSERT(This);
244 QQmlData *ddata = QQmlData::get(This, /*create*/ true);
245 // NB: copied from QQmlObjectCreator::createInstance()
246 //
247 // the if-statement logic to determine the kind is:
248 // if (static_cast<quint32>(index) == 0 || ddata->rootObjectInCreation || isInlineComponent)
249 // then QQmlContextData::DocumentRoot. here, we pass this through qmltc
250 context->installContext(ddata, kind);
251 Q_ASSERT(qmlEngine(This));
252 }
253
254private:
255 class SingletonInstances : private QHash<QQmlType, QJSValue>
256 {
257 public:
258 void convertAndInsert(QV4::ExecutionEngine *engine, const QQmlType &type, QJSValue *value)
259 {
261 insert(type, *value);
262 }
263
264 void clear()
265 {
266 const auto canDelete = [](QObject *instance, const auto &type) -> bool {
267 if (!instance)
268 return false;
269
270 if (!type.singletonInstanceInfo()->url.isEmpty())
271 return true;
272
273 const auto *ddata = QQmlData::get(instance, false);
274 return !(ddata && ddata->indestructible && ddata->explicitIndestructibleSet);
275 };
276
277 for (auto it = constBegin(), end = constEnd(); it != end; ++it) {
278 auto *instance = it.value().toQObject();
279 if (canDelete(instance, it.key()))
280 QQmlData::markAsDeleted(instance);
281 }
282
283 for (auto it = constBegin(), end = constEnd(); it != end; ++it) {
284 QObject *instance = it.value().toQObject();
285
286 if (canDelete(instance, it.key()))
287 delete instance;
288 }
289
291 }
292
294 using QHash<QQmlType, QJSValue>::take;
295 };
296
297 SingletonInstances singletonInstances;
298 QHash<int, QQmlGadgetPtrWrapper *> cachedValueTypeInstances;
299
300 static bool s_designerMode;
301
302 void cleanupScarceResources();
303};
304
305/*
306 This function should be called prior to evaluation of any js expression,
307 so that scarce resources are not freed prematurely (eg, if there is a
308 nested javascript expression).
309 */
311{
313}
314
315/*
316 This function should be called after evaluation of the js expression is
317 complete, and so the scarce resources may be freed safely.
318 */
320{
323
324 // if the refcount is zero, then evaluation of the "top level"
325 // expression must have completed. We can safely release the
326 // scarce resources.
329 if (Q_UNLIKELY(!engine->scarceResources.isEmpty())) {
330 cleanupScarceResources();
331 }
332 }
333}
334
336{
337 Q_ASSERT(e);
338
339 return e->handle();
340}
341
343{
344 Q_ASSERT(e);
345
346 return e->d_func();
347}
348
350{
351 Q_ASSERT(e);
352
353 return e ? e->d_func() : nullptr;
354}
355
356template<typename Context>
358{
359 if (!context)
360 return nullptr;
361 if (QQmlEngine *engine = context->engine())
363 return nullptr;
364}
365
367{
368 return contextEngine(c);
369}
370
372{
373 return contextEngine(c);
374}
375
377{
378 Q_ASSERT(p);
379
380 return p->q_func();
381}
382
384{
385 QQmlEngine *qmlEngine = e->qmlEngine();
386 if (!qmlEngine)
387 return nullptr;
388 return get(qmlEngine);
389}
390
391template<>
392Q_QML_PRIVATE_EXPORT QJSValue QQmlEnginePrivate::singletonInstance<QJSValue>(const QQmlType &type);
393
394template<typename T>
396 return qobject_cast<T>(singletonInstance<QJSValue>(type).toQObject());
397}
398
400{
402
404 {
407 };
408
410
411protected:
412 void dataReceived(const SourceCodeData &) final { Q_UNREACHABLE(); }
413 void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *) final { Q_UNREACHABLE(); }
414
415private:
416 bool couldFindModule() const;
417 QString m_uri;
418};
419
420
422
423#endif // QQMLENGINE_P_H
\inmodule QtCore
\inmodule QtCore
Definition qhash.h:818
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
Definition qhash.h:949
The QIntrusiveList class is a template class that provides a list of objects using static storage.
static QJSEnginePrivate * get(QJSEngine *e)
Definition qjsengine_p.h:38
static void manageStringOnV4Heap(QV4::ExecutionEngine *e, QJSValue *jsval)
Definition qjsvalue_p.h:288
The QJSValue class acts as a container for Qt/JavaScript data types.
Definition qjsvalue.h:31
Definition qlist.h:74
\inmodule QtCore
\inmodule QtCore
Definition qmetatype.h:320
\inmodule QtCore
Definition qmutex.h:285
The QNetworkAccessManager class allows the application to send network requests and receive replies.
\inmodule QtCore
Definition qobject.h:90
\inmodule QtCore
Definition qpointer.h:18
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
static void markAsDeleted(QObject *)
static QQmlData * get(QObjectPrivate *priv, bool create)
Definition qqmldata_p.h:199
QHash< QString, QSharedPointer< QQmlImageProviderBase > > imageProviders
Q_OBJECT_BINDABLE_PROPERTY(QQmlEnginePrivate, QString, translationLanguage)
QMutex networkAccessManagerMutex
QRecyclePool< QQmlJavaScriptExpressionGuard > jsExpressionGuardPool
static std::atomic< bool > qml_debugging_enabled
\qmltype QtObject \instantiates QObject \inqmlmodule QtQml
QQmlTypeLoader typeLoader
QQmlGadgetPtrWrapper * valueTypeInstance(QMetaType type)
QIntrusiveList< Incubator, &Incubator::next > incubatorList
static bool baseModulesUninitialized
QQmlEnginePrivate(QQmlEngine *q)
static QQmlEnginePrivate * get(QQmlEngine *e)
void referenceScarceResources()
QV4::ExecutionEngine * v4engine() const
void dereferenceScarceResources()
QRecyclePool< TriggerList > qPropertyTriggerPool
QQmlImportDatabase importDatabase
static void setInternalContext(QObject *This, const QQmlRefPointer< QQmlContextData > &context, QQmlContextData::QmlObjectKind kind)
QString offlineStoragePath
T singletonInstance(const QQmlType &type)
QRecursiveMutex imageProviderMutex
QList< QQmlAbstractUrlInterceptor * > urlInterceptors
static QV4::ExecutionEngine * getV4Engine(QQmlEngine *e)
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
The QQmlError class encapsulates a QML error.
Definition qqmlerror.h:18
The QQmlImportDatabase class manages the QML imports for a QQmlEngine.
QQmlIncubationController instances drive the progress of QQmlIncubators.
The QQmlIncubator class allows QML objects to be created asynchronously.
QQmlJavaScriptExpressionGuard * next
static QQmlJavaScriptExpressionGuard * New(QQmlJavaScriptExpression *e, QQmlEngine *engine)
QQmlJavaScriptExpression * expression
static QQmlValueType * valueType(QMetaType metaType)
The QQmlTypeLoader class abstracts loading files and their dependencies over the network.
\inmodule QtCore
Definition qmutex.h:313
iterator end()
Definition qset.h:140
iterator find(const T &value)
Definition qset.h:159
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
\inmodule QtCore
Definition qurl.h:94
b clear()
double e
cache insert(employee->id(), employee)
QSet< QString >::iterator it
Combined button and popup list for selecting options.
static void * context
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
const char * typeName
GLuint GLuint end
GLsizei GLenum GLenum * types
GLenum type
const GLubyte * c
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
QQmlEngine * qmlEngine(const QObject *obj)
Definition qqml.cpp:76
QQmlEnginePrivate * contextEngine(const Context &context)
#define QML_NAMED_ELEMENT(NAME)
#define QML_ADDED_IN_VERSION(MAJOR, MINOR)
#define QML_FOREIGN(FOREIGN_TYPE)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
#define Q_CLASSINFO(name, value)
#define Q_GADGET
size_t quintptr
Definition qtypes.h:72
ptrdiff_t qsizetype
Definition qtypes.h:70
QUrl url("example.com")
[constructor-url-reference]
QJSValueList args
QJSEngine engine
[0]
enum LoadHelper::ResolveTypeResult::Status status
ResolveTypeResult resolveType(QAnyStringView typeName)
void dataReceived(const SourceCodeData &) final
Invoked when data for the blob is received.
void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *) final
QPointer< QObject > target
QQmlJavaScriptExpression * m_expression
static void trigger(QPropertyObserver *, QUntypedPropertyData *)
TriggerList * next
TriggerList(QQmlJavaScriptExpression *expression)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent