1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #ifndef QQMLTYPELOADER_P_H
43 #define QQMLTYPELOADER_P_H
49 // This file is not part of the Qt API. It exists purely as an
50 // implementation detail. This header file may change from version to
51 // version without notice, or even be removed.
56 #include <QtCore/qobject.h>
57 #include <QtCore/qatomic.h>
58 #include <QtNetwork/qnetworkreply.h>
59 #include <QtQml/qqmlerror.h>
60 #include <QtQml/qqmlengine.h>
62 #include <private/qv8_p.h>
63 #include <private/qhashedstring_p.h>
64 #include <private/qqmlscript_p.h>
65 #include <private/qqmlimport_p.h>
66 #include <private/qqmlcleanup_p.h>
67 #include <private/qqmldirparser_p.h>
75 class QQmlCompiledData;
76 class QQmlComponentPrivate;
79 class QQmlExtensionInterface;
81 // Exported for QtQuick1
82 class Q_QML_PRIVATE_EXPORT QQmlDataBlob : public QQmlRefCount
86 Null, // Prior to QQmlDataLoader::load()
87 Loading, // Prior to data being received and dataReceived() being called
88 WaitingForDependencies, // While there are outstanding addDependency()s
99 QQmlDataBlob(const QUrl &, Type);
100 virtual ~QQmlDataBlob();
104 Status status() const;
106 bool isLoading() const;
107 bool isWaiting() const;
108 bool isComplete() const;
109 bool isError() const;
110 bool isCompleteOrError() const;
112 qreal progress() const;
115 QUrl finalUrl() const;
116 QString finalUrlString() const;
118 QList<QQmlError> errors() const;
121 // Can be called from within callbacks
122 void setError(const QQmlError &);
123 void setError(const QList<QQmlError> &errors);
124 void addDependency(QQmlDataBlob *);
126 // Callbacks made in load thread
127 virtual void dataReceived(const QByteArray &) = 0;
129 virtual void networkError(QNetworkReply::NetworkError);
130 virtual void dependencyError(QQmlDataBlob *);
131 virtual void dependencyComplete(QQmlDataBlob *);
132 virtual void allDependenciesDone();
134 // Callbacks made in main thread
135 virtual void downloadProgressChanged(qreal);
136 virtual void completed();
138 friend class QQmlDataLoader;
139 friend class QQmlDataLoaderThread;
142 void cancelAllWaitingFor();
143 void notifyAllWaitingOnMe();
144 void notifyComplete(QQmlDataBlob *);
148 inline QQmlDataBlob::Status status() const;
149 inline void setStatus(QQmlDataBlob::Status);
150 inline bool isAsync() const;
151 inline void setIsAsync(bool);
152 inline quint8 progress() const;
153 inline void setProgress(quint8);
160 // m_errors should *always* be written before the status is set to Error.
161 // We use the status change as a memory fence around m_errors so that locking
162 // isn't required. Once the status is set to Error (or Complete), m_errors
163 // cannot be changed.
164 QList<QQmlError> m_errors;
170 mutable QString m_finalUrlString;
172 // List of QQmlDataBlob's that are waiting for me to complete.
173 QList<QQmlDataBlob *> m_waitingOnMe;
175 // List of QQmlDataBlob's that I am waiting for to complete.
176 QList<QQmlDataBlob *> m_waitingFor;
178 // Manager that is currently fetching data for me
179 QQmlDataLoader *m_manager;
180 int m_redirectCount:30;
185 class QQmlDataLoaderThread;
186 // Exported for QtQuick1
187 class Q_QML_PRIVATE_EXPORT QQmlDataLoader
190 QQmlDataLoader(QQmlEngine *);
196 bool isConcurrent() const { return true; }
198 enum Mode { PreferSynchronous, Asynchronous };
200 void load(QQmlDataBlob *, Mode = PreferSynchronous);
201 void loadWithStaticData(QQmlDataBlob *, const QByteArray &, Mode = PreferSynchronous);
203 QQmlEngine *engine() const;
204 void initializeEngine(QQmlExtensionInterface *, const char *);
207 friend class QQmlDataBlob;
208 friend class QQmlDataLoaderThread;
209 friend class QQmlDataLoaderNetworkReplyProxy;
211 void loadThread(QQmlDataBlob *);
212 void loadWithStaticDataThread(QQmlDataBlob *, const QByteArray &);
213 void networkReplyFinished(QNetworkReply *);
214 void networkReplyProgress(QNetworkReply *, qint64, qint64);
216 typedef QHash<QNetworkReply *, QQmlDataBlob *> NetworkReplies;
218 void setData(QQmlDataBlob *, const QByteArray &);
220 QQmlEngine *m_engine;
221 QQmlDataLoaderThread *m_thread;
222 NetworkReplies m_networkReplies;
225 // Exported for QtQuick1
226 class Q_QML_PRIVATE_EXPORT QQmlTypeLoader : public QQmlDataLoader
228 Q_DECLARE_TR_FUNCTIONS(QQmlTypeLoader)
230 QQmlTypeLoader(QQmlEngine *);
237 Q_DECLARE_FLAGS(Options, Option)
239 QQmlTypeData *get(const QUrl &url);
240 QQmlTypeData *get(const QByteArray &, const QUrl &url, Options = None);
243 QQmlScriptBlob *getScript(const QUrl &);
244 QQmlQmldirData *getQmldir(const QUrl &);
246 QString absoluteFilePath(const QString &path);
247 bool directoryExists(const QString &path);
248 const QQmlDirParser *qmlDirParser(const QString &absoluteFilePath);
250 typedef QHash<QUrl, QQmlTypeData *> TypeCache;
251 typedef QHash<QUrl, QQmlScriptBlob *> ScriptCache;
252 typedef QHash<QUrl, QQmlQmldirData *> QmldirCache;
253 typedef QStringHash<bool> StringSet;
254 typedef QStringHash<StringSet*> ImportDirCache;
255 typedef QStringHash<QQmlDirParser*> ImportQmlDirCache;
257 TypeCache m_typeCache;
258 ScriptCache m_scriptCache;
259 QmldirCache m_qmldirCache;
260 ImportDirCache m_importDirCache;
261 ImportQmlDirCache m_importQmlDirCache;
264 Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlTypeLoader::Options)
266 class Q_AUTOTEST_EXPORT QQmlTypeData : public QQmlDataBlob
271 TypeReference() : type(0), majorVersion(0), minorVersion(0), typeData(0) {}
273 QQmlScript::Location location;
277 QQmlTypeData *typeData;
280 struct ScriptReference
282 ScriptReference() : script(0) {}
284 QQmlScript::Location location;
286 QQmlScriptBlob *script;
289 QQmlTypeData(const QUrl &, QQmlTypeLoader::Options, QQmlTypeLoader *);
292 QQmlTypeLoader *typeLoader() const;
294 const QQmlImports &imports() const;
295 const QQmlScript::Parser &parser() const;
297 const QList<TypeReference> &resolvedTypes() const;
298 const QList<ScriptReference> &resolvedScripts() const;
299 const QSet<QString> &namespaces() const;
301 QQmlCompiledData *compiledData() const;
303 // Used by QQmlComponent to get notifications
304 struct TypeDataCallback {
305 ~TypeDataCallback() {}
306 virtual void typeDataProgress(QQmlTypeData *, qreal) {}
307 virtual void typeDataReady(QQmlTypeData *) {}
309 void registerCallback(TypeDataCallback *);
310 void unregisterCallback(TypeDataCallback *);
314 virtual void completed();
315 virtual void dataReceived(const QByteArray &);
316 virtual void allDependenciesDone();
317 virtual void downloadProgressChanged(qreal);
323 QQmlTypeLoader::Options m_options;
325 QQmlQmldirData *qmldirForUrl(const QUrl &);
327 QQmlScript::Parser scriptParser;
328 QQmlImports m_imports;
330 QList<ScriptReference> m_scripts;
331 QList<QQmlQmldirData *> m_qmldirs;
333 QSet<QString> m_namespaces;
335 QList<TypeReference> m_types;
336 bool m_typesResolved:1;
338 QQmlCompiledData *m_compiledData;
340 QList<TypeDataCallback *> m_callbacks;
342 QQmlTypeLoader *m_typeLoader;
345 // QQmlScriptData instances are created, uninitialized, by the loader in the
346 // load thread. The first time they are used by the VME, they are initialized which
347 // creates their v8 objects and they are referenced and added to the engine's cleanup
348 // list. During QQmlCleanup::clear() all v8 resources are destroyed, and the
349 // reference that was created is released but final deletion only occurs once all the
350 // references as released. This is all intended to ensure that the v8 resources are
351 // only created and destroyed in the main thread :)
352 class Q_AUTOTEST_EXPORT QQmlScriptData : public QQmlCleanup,
361 QQmlTypeNameCache *importCache;
362 QList<QQmlScriptBlob *> scripts;
363 QQmlScript::Object::ScriptBlock::Pragmas pragmas;
365 bool isInitialized() const { return hasEngine(); }
366 void initialize(QQmlEngine *);
369 virtual void clear(); // From QQmlCleanup
372 friend class QQmlVME;
373 friend class QQmlScriptBlob;
376 QByteArray m_programSource;
377 v8::Persistent<v8::Script> m_program;
378 v8::Persistent<v8::Object> m_value;
381 class Q_AUTOTEST_EXPORT QQmlScriptBlob : public QQmlDataBlob
384 QQmlScriptBlob(const QUrl &, QQmlTypeLoader *);
387 struct ScriptReference
389 ScriptReference() : script(0) {}
391 QQmlScript::Location location;
393 QQmlScriptBlob *script;
396 QQmlScript::Object::ScriptBlock::Pragmas pragmas() const;
398 QQmlTypeLoader *typeLoader() const;
399 const QQmlImports &imports() const;
401 QQmlScriptData *scriptData() const;
404 virtual void dataReceived(const QByteArray &);
408 QQmlScript::Object::ScriptBlock::Pragmas m_pragmas;
411 QQmlImports m_imports;
412 QList<ScriptReference> m_scripts;
413 QQmlScriptData *m_scriptData;
415 QQmlTypeLoader *m_typeLoader;
418 class Q_AUTOTEST_EXPORT QQmlQmldirData : public QQmlDataBlob
421 QQmlQmldirData(const QUrl &);
423 const QQmlDirComponents &dirComponents() const;
426 virtual void dataReceived(const QByteArray &);
429 QQmlDirComponents m_components;
435 #endif // QQMLTYPELOADER_P_H