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
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/qpointer.h>
43#include <QtCore/qproperty.h>
44#include <QtCore/qstack.h>
45#include <QtCore/qstring.h>
46#include <QtCore/qthread.h>
47
48#include <atomic>
49
51
54class QQmlIncubator;
55class QQmlMetaObject;
56class QQmlNetworkAccessManagerFactory;
58class QQmlProfiler;
60
61// This needs to be declared here so that the pool for it can live in QQmlEnginePrivate.
62// The inline method definitions are in qqmljavascriptexpression_p.h
75
92
99
100class Q_QML_EXPORT QQmlEnginePrivate : public QJSEnginePrivate
101{
102 Q_DECLARE_PUBLIC(QQmlEngine)
103public:
104 explicit QQmlEnginePrivate(QQmlEngine *q) : importDatabase(q), typeLoader(q) {}
105 ~QQmlEnginePrivate() override;
106
107 void init();
108 // No mutex protecting baseModulesUninitialized, because use outside QQmlEngine
109 // is just qmlClearTypeRegistrations (which can't be called while an engine exists)
111
112 QQmlPropertyCapture *propertyCapture = nullptr;
113
114 QRecyclePool<QQmlJavaScriptExpressionGuard> jsExpressionGuardPool;
115 QRecyclePool<TriggerList> qPropertyTriggerPool;
116
117 QQmlContext *rootContext = nullptr;
119
120#if !QT_CONFIG(qml_debug)
121 static const quintptr profiler = 0;
122#else
123 QQmlProfiler *profiler = nullptr;
124#endif
125
126 bool outputWarningsToMsgLog = true;
127
128 // Bindings that have had errors during startup
129 QQmlDelayedError *erroredBindings = nullptr;
130 int inProgressCreations = 0;
131
132 QV4::ExecutionEngine *v4engine() const { return q_func()->handle(); }
133
134#if QT_CONFIG(qml_worker_script)
135 QThread *workerScriptEngine = nullptr;
136#endif
137
139
140 QQmlObjectCreator *activeObjectCreator = nullptr;
141#if QT_CONFIG(qml_network)
142 QNetworkAccessManager *createNetworkAccessManager(QObject *parent) const;
143 QNetworkAccessManager *getNetworkAccessManager() const;
144 mutable QNetworkAccessManager *networkAccessManager = nullptr;
145 mutable QQmlNetworkAccessManagerFactory *networkAccessManagerFactory = nullptr;
146#endif
148 QHash<QString,QSharedPointer<QQmlImageProviderBase> > imageProviders;
149 QSharedPointer<QQmlImageProviderBase> imageProvider(const QString &providerId) const;
150
151 QList<QQmlAbstractUrlInterceptor *> urlInterceptors;
152
153 int scarceResourcesRefCount = 0;
154 void referenceScarceResources();
155 void dereferenceScarceResources();
156
159
161
162 // Unfortunate workaround to avoid a circular dependency between
163 // qqmlengine_p.h and qqmlincubator_p.h
167 QIntrusiveList<Incubator, &Incubator::next> incubatorList;
168 unsigned int incubatorCount = 0;
169 QQmlIncubationController *incubationController = nullptr;
170 void incubate(QQmlIncubator &, const QQmlRefPointer<QQmlContextData> &);
171
172 // These methods may be called from any thread
173 QString offlineStorageDatabaseDirectory() const;
174
175 bool isTypeLoaded(const QUrl &url) const;
176 bool isScriptLoaded(const QUrl &url) const;
177
178 template <typename T>
179 T singletonInstance(const QQmlType &type);
180
181 void sendQuit();
182 void sendExit(int retCode = 0);
183 void warning(const QQmlError &);
184 void warning(const QList<QQmlError> &);
185 static void warning(QQmlEngine *, const QQmlError &);
186 static void warning(QQmlEngine *, const QList<QQmlError> &);
187 static void warning(QQmlEnginePrivate *, const QQmlError &);
188 static void warning(QQmlEnginePrivate *, const QList<QQmlError> &);
189
190 inline static QV4::ExecutionEngine *getV4Engine(QQmlEngine *e);
191 inline static QQmlEnginePrivate *get(QQmlEngine *e);
192 inline static const QQmlEnginePrivate *get(const QQmlEngine *e);
193 inline static QQmlEnginePrivate *get(QQmlContext *c);
194 inline static QQmlEnginePrivate *get(const QQmlRefPointer<QQmlContextData> &c);
195 inline static QQmlEngine *get(QQmlEnginePrivate *p);
196 inline static QQmlEnginePrivate *get(QV4::ExecutionEngine *e);
197
198 static QList<QQmlError> qmlErrorFromDiagnostics(const QString &fileName, const QList<QQmlJS::DiagnosticMessage> &diagnosticMessages);
199
200 static bool designerMode();
201 static void activateDesignerMode();
202
203 static std::atomic<bool> qml_debugging_enabled;
204
206
208 {
209 int typeIndex = type.id();
210 auto it = cachedValueTypeInstances.constFind(typeIndex);
211 if (it != cachedValueTypeInstances.cend())
212 return *it;
213
214 if (QQmlValueType *valueType = QQmlMetaType::valueType(type)) {
215 QQmlGadgetPtrWrapper *instance = new QQmlGadgetPtrWrapper(valueType);
216 cachedValueTypeInstances.insert(typeIndex, instance);
217 return instance;
218 }
219
220 return nullptr;
221 }
222
223 void executeRuntimeFunction(const QUrl &url, qsizetype functionIndex, QObject *thisObject,
224 int argc = 0, void **args = nullptr, QMetaType *types = nullptr);
225 void executeRuntimeFunction(const QV4::ExecutableCompilationUnit *unit, qsizetype functionIndex,
226 QObject *thisObject, int argc = 0, void **args = nullptr,
227 QMetaType *types = nullptr);
228 QV4::ExecutableCompilationUnit *compilationUnitFromUrl(const QUrl &url);
229 QQmlRefPointer<QQmlContextData>
230 createInternalContext(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit,
231 const QQmlRefPointer<QQmlContextData> &parentContext,
232 int subComponentIndex, bool isComponentRoot);
233 static void setInternalContext(QObject *This, const QQmlRefPointer<QQmlContextData> &context,
235 {
236 Q_ASSERT(This);
237 QQmlData *ddata = QQmlData::get(This, /*create*/ true);
238 // NB: copied from QQmlObjectCreator::createInstance()
239 //
240 // the if-statement logic to determine the kind is:
241 // if (static_cast<quint32>(index) == 0 || ddata->rootObjectInCreation || isInlineComponent)
242 // then QQmlContextData::DocumentRoot. here, we pass this through qmltc
243 context->installContext(ddata, kind);
244 Q_ASSERT(qmlEngine(This));
245 }
246
247private:
248 class SingletonInstances : private QHash<QQmlType::SingletonInstanceInfo::ConstPtr, QJSValue>
249 {
250 public:
251 void convertAndInsert(
254 {
256 insert(type, *value);
257 }
258
259 void clear()
260 {
261 const auto canDelete = [](QObject *instance, const auto &siinfo) -> bool {
262 if (!instance)
263 return false;
264
265 if (!siinfo->url.isEmpty())
266 return true;
267
268 const auto *ddata = QQmlData::get(instance, false);
269 return !(ddata && ddata->indestructible && ddata->explicitIndestructibleSet);
270 };
271
272 for (auto it = constBegin(), end = constEnd(); it != end; ++it) {
273 auto *instance = it.value().toQObject();
274 if (canDelete(instance, it.key()))
275 QQmlData::markAsDeleted(instance);
276 }
277
278 for (auto it = constBegin(), end = constEnd(); it != end; ++it) {
279 QObject *instance = it.value().toQObject();
280
281 if (canDelete(instance, it.key()))
282 delete instance;
283 }
284
286 }
287
290 };
291
292 SingletonInstances singletonInstances;
293 QHash<int, QQmlGadgetPtrWrapper *> cachedValueTypeInstances;
294
295 static bool s_designerMode;
296
297 void cleanupScarceResources();
298};
299
300/*
301 This function should be called prior to evaluation of any js expression,
302 so that scarce resources are not freed prematurely (eg, if there is a
303 nested javascript expression).
304 */
309
310/*
311 This function should be called after evaluation of the js expression is
312 complete, and so the scarce resources may be freed safely.
313 */
315{
318
319 // if the refcount is zero, then evaluation of the "top level"
320 // expression must have completed. We can safely release the
321 // scarce resources.
324 if (Q_UNLIKELY(!engine->scarceResources.isEmpty())) {
325 cleanupScarceResources();
326 }
327 }
328}
329
336
338{
339 Q_ASSERT(e);
340
341 return e->d_func();
342}
343
345{
346 Q_ASSERT(e);
347
348 return e ? e->d_func() : nullptr;
349}
350
351template<typename Context>
353{
354 if (!context)
355 return nullptr;
356 if (QQmlEngine *engine = context->engine())
358 return nullptr;
359}
360
365
366QQmlEnginePrivate *QQmlEnginePrivate::get(const QQmlRefPointer<QQmlContextData> &c)
367{
368 return contextEngine(c);
369}
370
372{
373 Q_ASSERT(p);
374
375 return p->q_func();
376}
377
379{
381 if (!qmlEngine)
382 return nullptr;
383 return get(qmlEngine);
384}
385
386template<>
387Q_QML_EXPORT QJSValue QQmlEnginePrivate::singletonInstance<QJSValue>(const QQmlType &type);
388
389template<typename T>
391 return qobject_cast<T>(singletonInstance<QJSValue>(type).toQObject());
392}
393
395{
397
403
405
406protected:
407 void dataReceived(const SourceCodeData &) final { Q_UNREACHABLE(); }
408 void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *) final { Q_UNREACHABLE(); }
409
410private:
411 bool couldFindModule() const;
412 QString m_uri;
413};
414
415
417
418#endif // QQMLENGINE_P_H
\inmodule QtCore
\inmodule QtCore
Definition qhash.h:820
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:951
QV4::ExecutionEngine * handle() const
Definition qjsengine.h:298
static void manageStringOnV4Heap(QV4::ExecutionEngine *e, QJSValue *jsval)
Definition qjsvalue_p.h:296
The QJSValue class acts as a container for Qt/JavaScript data types.
Definition qjsvalue.h:31
\inmodule QtCore
\inmodule QtCore
Definition qmetatype.h:341
\inmodule QtCore
Definition qmutex.h:281
The QNetworkAccessManager class allows the application to send network requests and receive replies.
\inmodule QtCore
Definition qobject.h:103
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
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:309
const_iterator cend() const noexcept
Definition qset.h:142
const_iterator constFind(const T &value) const
Definition qset.h:161
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
Definition qurl.h:94
b clear()
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)
static QDBusError::ErrorType get(const char *name)
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:80
QQmlEnginePrivate * contextEngine(const Context &context)
QDebug warning(QAnyStringView fileName, int lineNumber)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
size_t quintptr
Definition qtypes.h:167
ptrdiff_t qsizetype
Definition qtypes.h:165
QUrl url("example.com")
[constructor-url-reference]
QJSValueList args
QJSEngine engine
[0]
enum LoadHelper::ResolveTypeResult::Status status
LoadHelper(QQmlTypeLoader *loader, QAnyStringView uri)
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 *)
QQmlRefPointer< const SingletonInstanceInfo > ConstPtr
Definition qqmltype_p.h:127
QQmlEngine * qmlEngine() const
TriggerList * next
TriggerList(QQmlJavaScriptExpression *expression)