1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #ifndef QDECLARATIVETYPELOADER_P_H
43 #define QDECLARATIVETYPELOADER_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 <QtDeclarative/qdeclarativeerror.h>
60 #include <QtDeclarative/qdeclarativeengine.h>
62 #include <private/qv8_p.h>
63 #include <private/qhashedstring_p.h>
64 #include <private/qdeclarativescript_p.h>
65 #include <private/qdeclarativeimport_p.h>
66 #include <private/qdeclarativecleanup_p.h>
67 #include <private/qdeclarativedirparser_p.h>
71 class QDeclarativeScriptData;
72 class QDeclarativeScriptBlob;
73 class QDeclarativeQmldirData;
74 class QDeclarativeTypeLoader;
75 class QDeclarativeCompiledData;
76 class QDeclarativeComponentPrivate;
77 class QDeclarativeTypeData;
78 class QDeclarativeDataLoader;
79 class QDeclarativeExtensionInterface;
81 // Exported for QtQuick1
82 class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDataBlob : public QDeclarativeRefCount
86 Null, // Prior to QDeclarativeDataLoader::load()
87 Loading, // Prior to data being received and dataReceived() being called
88 WaitingForDependencies, // While there are outstanding addDependency()s
99 QDeclarativeDataBlob(const QUrl &, Type);
100 virtual ~QDeclarativeDataBlob();
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;
117 QList<QDeclarativeError> errors() const;
120 // Can be called from within callbacks
121 void setError(const QDeclarativeError &);
122 void setError(const QList<QDeclarativeError> &errors);
123 void addDependency(QDeclarativeDataBlob *);
125 // Callbacks made in load thread
126 virtual void dataReceived(const QByteArray &) = 0;
128 virtual void networkError(QNetworkReply::NetworkError);
129 virtual void dependencyError(QDeclarativeDataBlob *);
130 virtual void dependencyComplete(QDeclarativeDataBlob *);
131 virtual void allDependenciesDone();
133 // Callbacks made in main thread
134 virtual void downloadProgressChanged(qreal);
135 virtual void completed();
137 friend class QDeclarativeDataLoader;
138 friend class QDeclarativeDataLoaderThread;
141 void cancelAllWaitingFor();
142 void notifyAllWaitingOnMe();
143 void notifyComplete(QDeclarativeDataBlob *);
147 inline QDeclarativeDataBlob::Status status() const;
148 inline void setStatus(QDeclarativeDataBlob::Status);
149 inline bool isAsync() const;
150 inline void setIsAsync(bool);
151 inline quint8 progress() const;
152 inline void setProgress(quint8);
159 // m_errors should *always* be written before the status is set to Error.
160 // We use the status change as a memory fence around m_errors so that locking
161 // isn't required. Once the status is set to Error (or Complete), m_errors
162 // cannot be changed.
163 QList<QDeclarativeError> m_errors;
170 // List of QDeclarativeDataBlob's that are waiting for me to complete.
171 QList<QDeclarativeDataBlob *> m_waitingOnMe;
173 // List of QDeclarativeDataBlob's that I am waiting for to complete.
174 QList<QDeclarativeDataBlob *> m_waitingFor;
176 // Manager that is currently fetching data for me
177 QDeclarativeDataLoader *m_manager;
178 int m_redirectCount:30;
183 class QDeclarativeDataLoaderThread;
184 // Exported for QtQuick1
185 class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDataLoader
188 QDeclarativeDataLoader(QDeclarativeEngine *);
189 ~QDeclarativeDataLoader();
194 bool isConcurrent() const { return true; }
196 enum Mode { PreferSynchronous, Asynchronous };
198 void load(QDeclarativeDataBlob *, Mode = PreferSynchronous);
199 void loadWithStaticData(QDeclarativeDataBlob *, const QByteArray &, Mode = PreferSynchronous);
201 QDeclarativeEngine *engine() const;
202 void initializeEngine(QDeclarativeExtensionInterface *, const char *);
205 friend class QDeclarativeDataBlob;
206 friend class QDeclarativeDataLoaderThread;
207 friend class QDeclarativeDataLoaderNetworkReplyProxy;
209 void loadThread(QDeclarativeDataBlob *);
210 void loadWithStaticDataThread(QDeclarativeDataBlob *, const QByteArray &);
211 void networkReplyFinished(QNetworkReply *);
212 void networkReplyProgress(QNetworkReply *, qint64, qint64);
214 typedef QHash<QNetworkReply *, QDeclarativeDataBlob *> NetworkReplies;
216 void setData(QDeclarativeDataBlob *, const QByteArray &);
218 QDeclarativeEngine *m_engine;
219 QDeclarativeDataLoaderThread *m_thread;
220 NetworkReplies m_networkReplies;
223 // Exported for QtQuick1
224 class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeTypeLoader : public QDeclarativeDataLoader
226 Q_DECLARE_TR_FUNCTIONS(QDeclarativeTypeLoader)
228 QDeclarativeTypeLoader(QDeclarativeEngine *);
229 ~QDeclarativeTypeLoader();
235 Q_DECLARE_FLAGS(Options, Option)
237 QDeclarativeTypeData *get(const QUrl &url);
238 QDeclarativeTypeData *get(const QByteArray &, const QUrl &url, Options = None);
241 QDeclarativeScriptBlob *getScript(const QUrl &);
242 QDeclarativeQmldirData *getQmldir(const QUrl &);
244 QString absoluteFilePath(const QString &path);
245 bool directoryExists(const QString &path);
246 const QDeclarativeDirParser *qmlDirParser(const QString &absoluteFilePath);
248 typedef QHash<QUrl, QDeclarativeTypeData *> TypeCache;
249 typedef QHash<QUrl, QDeclarativeScriptBlob *> ScriptCache;
250 typedef QHash<QUrl, QDeclarativeQmldirData *> QmldirCache;
251 typedef QStringHash<bool> StringSet;
252 typedef QStringHash<StringSet*> ImportDirCache;
253 typedef QStringHash<QDeclarativeDirParser*> ImportQmlDirCache;
255 TypeCache m_typeCache;
256 ScriptCache m_scriptCache;
257 QmldirCache m_qmldirCache;
258 ImportDirCache m_importDirCache;
259 ImportQmlDirCache m_importQmlDirCache;
262 Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeTypeLoader::Options)
264 class Q_AUTOTEST_EXPORT QDeclarativeTypeData : public QDeclarativeDataBlob
269 TypeReference() : type(0), majorVersion(0), minorVersion(0), typeData(0) {}
271 QDeclarativeScript::Location location;
272 QDeclarativeType *type;
275 QDeclarativeTypeData *typeData;
278 struct ScriptReference
280 ScriptReference() : script(0) {}
282 QDeclarativeScript::Location location;
284 QDeclarativeScriptBlob *script;
287 QDeclarativeTypeData(const QUrl &, QDeclarativeTypeLoader::Options, QDeclarativeTypeLoader *);
288 ~QDeclarativeTypeData();
290 QDeclarativeTypeLoader *typeLoader() const;
292 const QDeclarativeImports &imports() const;
293 const QDeclarativeScript::Parser &parser() const;
295 const QList<TypeReference> &resolvedTypes() const;
296 const QList<ScriptReference> &resolvedScripts() const;
298 QDeclarativeCompiledData *compiledData() const;
300 // Used by QDeclarativeComponent to get notifications
301 struct TypeDataCallback {
302 ~TypeDataCallback() {}
303 virtual void typeDataProgress(QDeclarativeTypeData *, qreal) {}
304 virtual void typeDataReady(QDeclarativeTypeData *) {}
306 void registerCallback(TypeDataCallback *);
307 void unregisterCallback(TypeDataCallback *);
311 virtual void completed();
312 virtual void dataReceived(const QByteArray &);
313 virtual void allDependenciesDone();
314 virtual void downloadProgressChanged(qreal);
320 QDeclarativeTypeLoader::Options m_options;
322 QDeclarativeQmldirData *qmldirForUrl(const QUrl &);
324 QDeclarativeScript::Parser scriptParser;
325 QDeclarativeImports m_imports;
327 QList<ScriptReference> m_scripts;
328 QList<QDeclarativeQmldirData *> m_qmldirs;
330 QList<TypeReference> m_types;
331 bool m_typesResolved:1;
333 QDeclarativeCompiledData *m_compiledData;
335 QList<TypeDataCallback *> m_callbacks;
337 QDeclarativeTypeLoader *m_typeLoader;
340 // QDeclarativeScriptData instances are created, uninitialized, by the loader in the
341 // load thread. The first time they are used by the VME, they are initialized which
342 // creates their v8 objects and they are referenced and added to the engine's cleanup
343 // list. During QDeclarativeCleanup::clear() all v8 resources are destroyed, and the
344 // reference that was created is released but final deletion only occurs once all the
345 // references as released. This is all intended to ensure that the v8 resources are
346 // only created and destroyed in the main thread :)
347 class Q_AUTOTEST_EXPORT QDeclarativeScriptData : public QDeclarativeCleanup,
348 public QDeclarativeRefCount
351 QDeclarativeScriptData();
352 ~QDeclarativeScriptData();
355 QDeclarativeTypeNameCache *importCache;
356 QList<QDeclarativeScriptBlob *> scripts;
357 QDeclarativeScript::Object::ScriptBlock::Pragmas pragmas;
359 bool isInitialized() const { return hasEngine(); }
360 void initialize(QDeclarativeEngine *);
363 virtual void clear(); // From QDeclarativeCleanup
366 friend class QDeclarativeVME;
367 friend class QDeclarativeScriptBlob;
370 QString m_programSource;
371 v8::Persistent<v8::Script> m_program;
372 v8::Persistent<v8::Object> m_value;
375 class Q_AUTOTEST_EXPORT QDeclarativeScriptBlob : public QDeclarativeDataBlob
378 QDeclarativeScriptBlob(const QUrl &, QDeclarativeTypeLoader *);
379 ~QDeclarativeScriptBlob();
381 struct ScriptReference
383 ScriptReference() : script(0) {}
385 QDeclarativeScript::Location location;
387 QDeclarativeScriptBlob *script;
390 QDeclarativeScript::Object::ScriptBlock::Pragmas pragmas() const;
391 QString scriptSource() const;
393 QDeclarativeTypeLoader *typeLoader() const;
394 const QDeclarativeImports &imports() const;
396 QDeclarativeScriptData *scriptData() const;
399 virtual void dataReceived(const QByteArray &);
403 QDeclarativeScript::Object::ScriptBlock::Pragmas m_pragmas;
406 QDeclarativeImports m_imports;
407 QList<ScriptReference> m_scripts;
408 QDeclarativeScriptData *m_scriptData;
410 QDeclarativeTypeLoader *m_typeLoader;
413 class Q_AUTOTEST_EXPORT QDeclarativeQmldirData : public QDeclarativeDataBlob
416 QDeclarativeQmldirData(const QUrl &);
418 const QDeclarativeDirComponents &dirComponents() const;
421 virtual void dataReceived(const QByteArray &);
424 QDeclarativeDirComponents m_components;
430 #endif // QDECLARATIVETYPELOADER_P_H