Improve QJSValueIterator implementation.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativecontext_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 ** 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.
17 **
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.
21 **
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.
29 **
30 ** Other Usage
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.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QDECLARATIVECONTEXT_P_H
43 #define QDECLARATIVECONTEXT_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 "qdeclarativecontext.h"
57
58 #include "private/qdeclarativedata_p.h"
59 #include "private/qdeclarativeintegercache_p.h"
60 #include "private/qdeclarativetypenamecache_p.h"
61 #include "private/qdeclarativenotifier_p.h"
62 #include "qdeclarativelist.h"
63 #include "private/qdeclarativeparser_p.h"
64
65 #include <QtCore/qhash.h>
66 #include <QtDeclarative/qjsvalue.h>
67 #include <QtCore/qset.h>
68
69 #include <private/qobject_p.h>
70 #include "private/qdeclarativeguard_p.h"
71
72 #include <private/qv8_p.h>
73
74 QT_BEGIN_NAMESPACE
75
76 class QV8Bindings;
77 class QDeclarativeContext;
78 class QDeclarativeExpression;
79 class QDeclarativeEngine;
80 class QDeclarativeExpression;
81 class QDeclarativeExpressionPrivate;
82 class QDeclarativeAbstractExpression;
83 class QDeclarativeV4Bindings;
84 class QDeclarativeContextData;
85
86 class QDeclarativeContextPrivate : public QObjectPrivate
87 {
88     Q_DECLARE_PUBLIC(QDeclarativeContext)
89 public:
90     QDeclarativeContextPrivate();
91
92     QDeclarativeContextData *data;
93
94     QList<QVariant> propertyValues;
95     int notifyIndex;
96
97     static QDeclarativeContextPrivate *get(QDeclarativeContext *context) {
98         return static_cast<QDeclarativeContextPrivate *>(QObjectPrivate::get(context));
99     }
100     static QDeclarativeContext *get(QDeclarativeContextPrivate *context) {
101         return static_cast<QDeclarativeContext *>(context->q_func());
102     }
103
104     // Only used for debugging
105     QList<QPointer<QObject> > instances;
106
107     static int context_count(QDeclarativeListProperty<QObject> *);
108     static QObject *context_at(QDeclarativeListProperty<QObject> *, int);
109 };
110
111 class QDeclarativeComponentAttached;
112 class QDeclarativeGuardedContextData;
113 class Q_DECLARATIVE_EXPORT QDeclarativeContextData
114 {
115 public:
116     QDeclarativeContextData();
117     QDeclarativeContextData(QDeclarativeContext *);
118     void clearContext();
119     void destroy();
120     void invalidate();
121
122     inline bool isValid() const {
123         return engine && (!isInternal || !contextObject || !QObjectPrivate::get(contextObject)->wasDeleted);
124     }
125
126     // My parent context and engine
127     QDeclarativeContextData *parent;
128     QDeclarativeEngine *engine;
129
130     void setParent(QDeclarativeContextData *, bool parentTakesOwnership = false);
131     void refreshExpressions();
132
133     void addObject(QObject *);
134
135     QUrl resolvedUrl(const QUrl &);
136
137     // My containing QDeclarativeContext.  If isInternal is true this owns publicContext.  
138     // If internal is false publicContext owns this.
139     QDeclarativeContext *asQDeclarativeContext();
140     QDeclarativeContextPrivate *asQDeclarativeContextPrivate();
141     quint32 isInternal:1;
142     quint32 ownedByParent:1; // unrelated to isInternal; parent context deletes children if true.
143     quint32 isJSContext:1;
144     quint32 isPragmaLibraryContext:1;
145     quint32 dummy:28;
146     QDeclarativeContext *publicContext;
147
148     // Property name cache
149     QDeclarativeIntegerCache *propertyNames;
150
151     // Context object
152     QObject *contextObject;
153
154     // Any script blocks that exist on this context
155     QList<v8::Persistent<v8::Object> > importedScripts;
156
157     // Context base url
158     QUrl url;
159
160     // List of imports that apply to this context
161     QDeclarativeTypeNameCache *imports;
162
163     // My children
164     QDeclarativeContextData *childContexts;
165
166     // My peers in parent's childContexts list
167     QDeclarativeContextData  *nextChild;
168     QDeclarativeContextData **prevChild;
169
170     // Expressions that use this context
171     QDeclarativeAbstractExpression *expressions;
172
173     // Doubly-linked list of objects that are owned by this context
174     QDeclarativeData *contextObjects;
175
176     // Doubly-linked list of context guards (XXX merge with contextObjects)
177     QDeclarativeGuardedContextData *contextGuards;
178
179     // id guards
180     struct ContextGuard : public QDeclarativeGuard<QObject>
181     {
182         ContextGuard() : context(0) {}
183         inline ContextGuard &operator=(QObject *obj)
184         { QDeclarativeGuard<QObject>::operator=(obj); return *this; }
185         virtual void objectDestroyed(QObject *) { 
186             if (context->contextObject && !QObjectPrivate::get(context->contextObject)->wasDeleted) bindings.notify(); 
187         }
188         QDeclarativeContextData *context;
189         QDeclarativeNotifier bindings;
190     };
191     ContextGuard *idValues;
192     int idValueCount;
193     void setIdProperty(int, QObject *);
194     void setIdPropertyData(QDeclarativeIntegerCache *);
195
196     // Linked contexts. this owns linkedContext.
197     QDeclarativeContextData *linkedContext;
198
199     // Linked list of uses of the Component attached property in this
200     // context
201     QDeclarativeComponentAttached *componentAttached;
202
203     // Optimized binding objects.  Needed for deferred properties.
204     QDeclarativeV4Bindings *v4bindings;
205     QV8Bindings *v8bindings;
206
207     // Return the outermost id for obj, if any.
208     QString findObjectId(const QObject *obj) const;
209
210     static QDeclarativeContextData *get(QDeclarativeContext *context) {
211         return QDeclarativeContextPrivate::get(context)->data;
212     }
213
214 private:
215     ~QDeclarativeContextData() {}
216 };
217
218 class QDeclarativeGuardedContextData
219 {
220 public:
221     inline QDeclarativeGuardedContextData();
222     inline QDeclarativeGuardedContextData(QDeclarativeContextData *);
223     inline ~QDeclarativeGuardedContextData();
224
225     inline QDeclarativeContextData *contextData();
226     inline void setContextData(QDeclarativeContextData *);
227
228     inline bool isNull() const { return !m_contextData; }
229
230     inline operator QDeclarativeContextData*() const { return m_contextData; }
231     inline QDeclarativeContextData* operator->() const { return m_contextData; }
232     inline QDeclarativeGuardedContextData &operator=(QDeclarativeContextData *d);
233
234 private:
235     QDeclarativeGuardedContextData &operator=(const QDeclarativeGuardedContextData &);
236     QDeclarativeGuardedContextData(const QDeclarativeGuardedContextData &);
237     friend class QDeclarativeContextData;
238
239     inline void clear();
240
241     QDeclarativeContextData *m_contextData;
242     QDeclarativeGuardedContextData  *m_next;
243     QDeclarativeGuardedContextData **m_prev;
244 };
245
246 QDeclarativeGuardedContextData::QDeclarativeGuardedContextData()
247 : m_contextData(0), m_next(0), m_prev(0)
248 {
249 }
250
251 QDeclarativeGuardedContextData::QDeclarativeGuardedContextData(QDeclarativeContextData *data)
252 : m_contextData(0), m_next(0), m_prev(0)
253 {
254     setContextData(data);
255 }
256
257 QDeclarativeGuardedContextData::~QDeclarativeGuardedContextData()
258 {
259     clear();
260 }
261
262 void QDeclarativeGuardedContextData::setContextData(QDeclarativeContextData *contextData)
263 {
264     clear();
265
266     if (contextData) {
267         m_contextData = contextData;
268         m_next = contextData->contextGuards;
269         if (m_next) m_next->m_prev = &m_next;
270         m_prev = &contextData->contextGuards;
271         contextData->contextGuards = this;
272     }
273 }
274
275 QDeclarativeContextData *QDeclarativeGuardedContextData::contextData()
276 {
277     return m_contextData;
278 }
279
280 void QDeclarativeGuardedContextData::clear()
281 {
282     if (m_prev) {
283         *m_prev = m_next;
284         if (m_next) m_next->m_prev = m_prev;
285         m_contextData = 0;
286         m_next = 0;
287         m_prev = 0;
288     }
289 }
290
291 QDeclarativeGuardedContextData &
292 QDeclarativeGuardedContextData::operator=(QDeclarativeContextData *d)
293 {
294     setContextData(d);
295     return *this;
296 }
297
298 QT_END_NAMESPACE
299
300 #endif // QDECLARATIVECONTEXT_P_H