Ensure that chained incubation works from componentCompleted.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativevme_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 QDECLARATIVEVME_P_H
43 #define QDECLARATIVEVME_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 "qdeclarativeerror.h"
57 #include <private/qbitfield_p.h>
58 #include "qdeclarativeinstruction_p.h"
59 #include <private/qrecursionwatcher_p.h>
60
61 #include <QtCore/QStack>
62 #include <QtCore/QString>
63 #include <QtCore/qelapsedtimer.h>
64 #include <QtCore/qcoreapplication.h>
65
66 #include <private/qv8_p.h>
67 #include <private/qdeclarativeengine_p.h>
68 #include <private/qfinitestack_p.h>
69
70 QT_BEGIN_NAMESPACE
71
72 class QObject;
73 class QJSValue;
74 class QDeclarativeScriptData;
75 class QDeclarativeCompiledData;
76 class QDeclarativeCompiledData;
77 class QDeclarativeContextData;
78
79 namespace QDeclarativeVMETypes {
80     struct List
81     {
82         List() : type(0) {}
83         List(int t) : type(t) {}
84
85         int type;
86         QDeclarativeListProperty<void> qListProperty;
87     };
88 }
89 Q_DECLARE_TYPEINFO(QDeclarativeVMETypes::List, Q_PRIMITIVE_TYPE  | Q_MOVABLE_TYPE);
90
91 class QDeclarativeVME
92 {
93     Q_DECLARE_TR_FUNCTIONS(QDeclarativeVME)
94 public:
95     class Interrupt {
96     public:
97         inline Interrupt();
98         inline Interrupt(bool *runWhile);
99         inline Interrupt(int nsecs);
100
101         inline void reset();
102         inline bool shouldInterrupt() const;
103     private:
104         enum Mode { None, Time, Flag };
105         Mode mode;
106         union {
107             struct {
108                 QElapsedTimer timer;
109                 int nsecs;
110             };
111             bool *runWhile;
112         };
113     };
114
115     QDeclarativeVME() : data(0), componentAttached(0) {}
116     QDeclarativeVME(void *data) : data(data), componentAttached(0) {}
117
118     void *data;
119     QDeclarativeComponentAttached *componentAttached;
120     QList<QDeclarativeEnginePrivate::FinalizeCallback> finalizeCallbacks;
121
122     void init(QDeclarativeContextData *, QDeclarativeCompiledData *, int start,
123               QDeclarativeContextData * = 0);
124     bool initDeferred(QObject *);
125     void reset();
126
127     QObject *execute(QList<QDeclarativeError> *errors, const Interrupt & = Interrupt());
128     QDeclarativeContextData *complete(const Interrupt & = Interrupt());
129
130 private:
131     friend class QDeclarativeVMEGuard;
132
133     QObject *run(QList<QDeclarativeError> *errors, const Interrupt &
134 #ifdef QML_THREADED_VME_INTERPRETER
135                  , void ***storeJumpTable = 0
136 #endif
137                 );
138     v8::Persistent<v8::Object> run(QDeclarativeContextData *, QDeclarativeScriptData *);
139
140 #ifdef QML_THREADED_VME_INTERPRETER
141     static void **instructionJumpTable();
142     friend class QDeclarativeCompiledData;
143 #endif
144
145     QDeclarativeEngine *engine;
146     QRecursionNode recursion;
147
148     QFiniteStack<QObject *> objects;
149     QFiniteStack<QDeclarativeVMETypes::List> lists;
150
151     QFiniteStack<QDeclarativeAbstractBinding *> bindValues;
152     QFiniteStack<QDeclarativeParserStatus *> parserStatus;
153     QDeclarativeGuardedContextData rootContext;
154     QDeclarativeGuardedContextData creationContext;
155
156     struct State {
157         enum Flag { Deferred = 0x00000001 };
158
159         State() : flags(0), context(0), compiledData(0), instructionStream(0) {}
160         quint32 flags;
161         QDeclarativeContextData *context;
162         QDeclarativeCompiledData *compiledData;
163         const char *instructionStream;
164         QBitField bindingSkipList;
165     };
166
167     QStack<State> states;
168
169     static void blank(QFiniteStack<QDeclarativeParserStatus *> &);
170     static void blank(QFiniteStack<QDeclarativeAbstractBinding *> &);
171 };
172
173 // Used to check that a QDeclarativeVME that is interrupted mid-execution
174 // is still valid.  Checks all the objects and contexts have not been 
175 // deleted.
176 class QDeclarativeVMEGuard
177 {
178 public:
179     QDeclarativeVMEGuard();
180     ~QDeclarativeVMEGuard();
181
182     void guard(QDeclarativeVME *);
183     void clear();
184
185     bool isOK() const;
186
187 private:
188     int m_objectCount;
189     QDeclarativeGuard<QObject> *m_objects;
190     int m_contextCount;
191     QDeclarativeGuardedContextData *m_contexts;
192 };
193
194 QDeclarativeVME::Interrupt::Interrupt()
195 : mode(None)
196 {
197 }
198
199 QDeclarativeVME::Interrupt::Interrupt(bool *runWhile)
200 : mode(Flag), runWhile(runWhile)
201 {
202 }
203
204 QDeclarativeVME::Interrupt::Interrupt(int nsecs)
205 : mode(Time), nsecs(nsecs)
206 {
207 }
208
209 void QDeclarativeVME::Interrupt::reset()
210 {
211     if (mode == Time) 
212         timer.start();
213 }
214
215 bool QDeclarativeVME::Interrupt::shouldInterrupt() const
216 {
217     if (mode == None) {
218         return false;
219     } else if (mode == Time) {
220         return timer.nsecsElapsed() > nsecs;
221     } else if (mode == Flag) {
222         return !*runWhile;
223     } else {
224         return false;
225     }
226 }
227
228 QT_END_NAMESPACE
229
230 #endif // QDECLARATIVEVME_P_H