Initial V8 integration
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativeengine_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QDECLARATIVEENGINE_P_H
43 #define QDECLARATIVEENGINE_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
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.
52 //
53 // We mean it.
54 //
55
56 #include "qdeclarativeengine.h"
57
58 #include "private/qdeclarativetypeloader_p.h"
59 #include "private/qdeclarativeimport_p.h"
60 #include "private/qpodvector_p.h"
61 #include "qdeclarative.h"
62 #include "private/qdeclarativevaluetype_p.h"
63 #include "qdeclarativecontext.h"
64 #include "private/qdeclarativecontext_p.h"
65 #include "qdeclarativeexpression.h"
66 #include "qdeclarativeimageprovider.h"
67 #include "private/qdeclarativeproperty_p.h"
68 #include "private/qdeclarativepropertycache_p.h"
69 #include "private/qdeclarativemetatype_p.h"
70 #include "private/qdeclarativedirparser_p.h"
71 #include "private/qintrusivelist_p.h"
72
73 #include <QtScript/QScriptValue>
74 #include <QtScript/QScriptString>
75 #include <QtCore/qstring.h>
76 #include <QtCore/qlist.h>
77 #include <QtCore/qpair.h>
78 #include <QtCore/qstack.h>
79 #include <QtCore/qmutex.h>
80 #include <QtScript/qscriptengine.h>
81
82 #include <private/qobject_p.h>
83
84 #include <private/qv8engine_p.h>
85
86 QT_BEGIN_NAMESPACE
87
88 class QDeclarativeContext;
89 class QDeclarativeEngine;
90 class QDeclarativeContextPrivate;
91 class QDeclarativeExpression;
92 class QDeclarativeImportDatabase;
93 class ScarceResourceData;
94 class QScriptEngineDebugger;
95 class QNetworkReply;
96 class QNetworkAccessManager;
97 class QDeclarativeNetworkAccessManagerFactory;
98 class QDeclarativeAbstractBinding;
99 class QScriptDeclarativeClass;
100 class QDeclarativeTypeNameCache;
101 class QDeclarativeComponentAttached;
102 class QDeclarativeCleanup;
103 class QDeclarativeDelayedError;
104 class QDeclarativeWorkerScriptEngine;
105 class QDir;
106 class QSGTexture;
107 class QSGContext;
108
109 class QDeclarativeScriptEngine : public QScriptEngine
110 {
111 public:
112     QDeclarativeScriptEngine(QDeclarativeEnginePrivate *priv);
113     virtual ~QDeclarativeScriptEngine();
114
115     static QDeclarativeScriptEngine *get(QScriptEngine* e) { return static_cast<QDeclarativeScriptEngine*>(e); }
116
117     QDeclarativeEnginePrivate *p;
118
119     QUrl baseUrl;
120
121     virtual QNetworkAccessManager *networkAccessManager();
122 };
123
124 class Q_AUTOTEST_EXPORT QDeclarativeEnginePrivate : public QObjectPrivate
125 {
126     Q_DECLARE_PUBLIC(QDeclarativeEngine)
127 public:
128     QDeclarativeEnginePrivate(QDeclarativeEngine *);
129     ~QDeclarativeEnginePrivate();
130
131     void init();
132
133     struct CapturedProperty {
134         CapturedProperty(QObject *o, int c, int n)
135             : object(o), coreIndex(c), notifier(0), notifyIndex(n) {}
136         CapturedProperty(QDeclarativeNotifier *n)
137             : object(0), coreIndex(-1), notifier(n), notifyIndex(-1) {}
138
139         QObject *object;
140         int coreIndex;
141         QDeclarativeNotifier *notifier;
142         int notifyIndex;
143     };
144     bool captureProperties;
145     QPODVector<CapturedProperty> capturedProperties;
146
147     QDeclarativeContext *rootContext;
148     bool isDebugging;
149
150     bool outputWarningsToStdErr;
151
152     QDeclarativeContextData *sharedContext;
153     QObject *sharedScope;
154
155     // Registered cleanup handlers
156     QDeclarativeCleanup *cleanup;
157
158     // Bindings that have had errors during startup
159     QDeclarativeDelayedError *erroredBindings;
160     int inProgressCreations;
161
162     // V8 Engine
163     QV8Engine v8engine;
164
165     QDeclarativeScriptEngine scriptEngine;
166
167     QDeclarativeWorkerScriptEngine *getWorkerScriptEngine();
168     QDeclarativeWorkerScriptEngine *workerScriptEngine;
169
170     QUrl baseUrl;
171
172     template<class T>
173     struct SimpleList {
174         SimpleList()
175             : count(0), values(0) {}
176         SimpleList(int r)
177             : count(0), values(new T*[r]) {}
178
179         int count;
180         T **values;
181
182         void append(T *v) {
183             values[count++] = v;
184         }
185
186         T *at(int idx) const {
187             return values[idx];
188         }
189
190         void clear() {
191             delete [] values;
192         }
193     };
194
195     static void clear(SimpleList<QDeclarativeAbstractBinding> &);
196     static void clear(SimpleList<QDeclarativeParserStatus> &);
197
198     QList<SimpleList<QDeclarativeAbstractBinding> > bindValues;
199     QList<SimpleList<QDeclarativeParserStatus> > parserStatus;
200     QList<QPair<QDeclarativeGuard<QObject>,int> > finalizedParserStatus;
201     QDeclarativeComponentAttached *componentAttached;
202
203     void registerFinalizedParserStatusObject(QObject *obj, int index) {
204         finalizedParserStatus.append(qMakePair(QDeclarativeGuard<QObject>(obj), index));
205     }
206
207     bool inBeginCreate;
208
209     QNetworkAccessManager *createNetworkAccessManager(QObject *parent) const;
210     QNetworkAccessManager *getNetworkAccessManager() const;
211     mutable QNetworkAccessManager *networkAccessManager;
212     mutable QDeclarativeNetworkAccessManagerFactory *networkAccessManagerFactory;
213
214     QHash<QString,QSharedPointer<QDeclarativeImageProvider> > imageProviders;
215     QDeclarativeImageProvider::ImageType getImageProviderType(const QUrl &url);
216     QSGTexture *getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
217     QImage getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
218     QPixmap getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
219
220     // Scarce resources are "exceptionally high cost" QVariant types where allowing the
221     // normal JavaScript GC to clean them up is likely to lead to out-of-memory or other
222     // out-of-resource situations.  When such a resource is passed into JavaScript we
223     // add it to the scarceResources list and it is destroyed when we return from the
224     // JavaScript execution that created it.  The user can prevent this behavior by
225     // calling preserve() on the object which removes it from this scarceResource list.
226     class ScarceResourceData {
227     public:
228         ScarceResourceData(const QVariant &data) : data(data) {}
229         QVariant data;
230         QIntrusiveListNode node;
231     };
232     QIntrusiveList<ScarceResourceData, &ScarceResourceData::node> scarceResources;
233     int scarceResourcesRefCount;
234     void referenceScarceResources();
235     void dereferenceScarceResources();
236
237     mutable QMutex mutex;
238
239     QDeclarativeTypeLoader typeLoader;
240     QDeclarativeImportDatabase importDatabase;
241
242     QString offlineStoragePath;
243
244     mutable quint32 uniqueId;
245     quint32 getUniqueId() const {
246         return uniqueId++;
247     }
248
249     QDeclarativeValueTypeFactory valueTypes;
250
251     QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *> moduleApiInstances;
252
253     QHash<const QMetaObject *, QDeclarativePropertyCache *> propertyCache;
254     QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *> typePropertyCache;
255     inline QDeclarativePropertyCache *cache(QObject *obj);
256     inline QDeclarativePropertyCache *cache(const QMetaObject *);
257     inline QDeclarativePropertyCache *cache(QDeclarativeType *, int, QDeclarativeError &error);
258     QDeclarativePropertyCache *createCache(const QMetaObject *);
259     QDeclarativePropertyCache *createCache(QDeclarativeType *, int, QDeclarativeError &error);
260
261     void registerCompositeType(QDeclarativeCompiledData *);
262
263     bool isQObject(int);
264     QObject *toQObject(const QVariant &, bool *ok = 0) const;
265     QDeclarativeMetaType::TypeCategory typeCategory(int) const;
266     bool isList(int) const;
267     int listType(int) const;
268     const QMetaObject *rawMetaObjectForType(int) const;
269     const QMetaObject *metaObjectForType(int) const;
270     QHash<int, int> m_qmlLists;
271     QHash<int, QDeclarativeCompiledData *> m_compositeTypes;
272
273     void sendQuit();
274     void warning(const QDeclarativeError &);
275     void warning(const QList<QDeclarativeError> &);
276     static void warning(QDeclarativeEngine *, const QDeclarativeError &);
277     static void warning(QDeclarativeEngine *, const QList<QDeclarativeError> &);
278     static void warning(QDeclarativeEnginePrivate *, const QDeclarativeError &);
279     static void warning(QDeclarativeEnginePrivate *, const QList<QDeclarativeError> &);
280
281     static QScriptEngine *getScriptEngine(QDeclarativeEngine *e) { return &e->d_func()->scriptEngine; }
282     static QDeclarativeEngine *getEngine(QScriptEngine *e) { return static_cast<QDeclarativeScriptEngine*>(e)->p->q_func(); }
283     static QDeclarativeEnginePrivate *get(QDeclarativeEngine *e) { return e->d_func(); }
284     static QDeclarativeEnginePrivate *get(QDeclarativeContext *c) { return (c && c->engine()) ? QDeclarativeEnginePrivate::get(c->engine()) : 0; }
285     static QDeclarativeEnginePrivate *get(QDeclarativeContextData *c) { return (c && c->engine) ? QDeclarativeEnginePrivate::get(c->engine) : 0; }
286     static QDeclarativeEnginePrivate *get(QScriptEngine *e) { return static_cast<QDeclarativeScriptEngine*>(e)->p; }
287     static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p) { return p->q_func(); }
288
289     static QString urlToLocalFileOrQrc(const QUrl& url);
290
291     static void defineModule();
292
293     static bool qml_debugging_enabled;
294
295     QSGContext *sgContext;
296 };
297
298 /*!
299 Returns a QDeclarativePropertyCache for \a obj if one is available.
300
301 If \a obj is null, being deleted or contains a dynamic meta object 0 
302 is returned.
303
304 The returned cache is not referenced, so if it is to be stored, call addref().
305 */
306 QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QObject *obj) 
307 {
308     if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted) 
309         return 0;
310
311     const QMetaObject *mo = obj->metaObject();
312     QDeclarativePropertyCache *rv = propertyCache.value(mo);
313     if (!rv) rv = createCache(mo);
314     return rv;
315 }
316
317 /*!
318 Returns a QDeclarativePropertyCache for \a metaObject.  
319
320 As the cache is persisted for the life of the engine, \a metaObject must be
321 a static "compile time" meta-object, or a meta-object that is otherwise known to 
322 exist for the lifetime of the QDeclarativeEngine.
323
324 The returned cache is not referenced, so if it is to be stored, call addref().
325 */
326 QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(const QMetaObject *metaObject)
327 {
328     Q_ASSERT(metaObject);
329
330     QDeclarativePropertyCache *rv = propertyCache.value(metaObject);
331     if (!rv) rv = createCache(metaObject);
332     return rv;
333 }
334
335 /*!
336 Returns a QDeclarativePropertyCache for \a type with \a minorVersion.
337
338 The returned cache is not referenced, so if it is to be stored, call addref().
339 */
340 QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QDeclarativeType *type, int minorVersion, QDeclarativeError &error)
341 {
342     Q_ASSERT(type);
343
344     if (minorVersion == -1 || !type->containsRevisionedAttributes())
345         return cache(type->metaObject());
346
347     QDeclarativePropertyCache *rv = typePropertyCache.value(qMakePair(type, minorVersion));
348     if (!rv) rv = createCache(type, minorVersion, error);
349     return rv;
350 }
351
352 QT_END_NAMESPACE
353
354 #endif // QDECLARATIVEENGINE_P_H