Improve documentation.
[profile/ivi/qtdeclarative.git] / src / qml / qml / qqmldata_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QQMLDATA_P_H
43 #define QQMLDATA_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 <private/qtqmlglobal_p.h>
57 #include <private/qobject_p.h>
58 #include <private/qv8_p.h>
59
60 QT_BEGIN_NAMESPACE
61
62 template <class Key, class T> class QHash;
63 class QQmlGuardImpl;
64 class QQmlCompiledData;
65 class QQmlAbstractBinding;
66 class QQmlAbstractBoundSignal;
67 class QQmlContext;
68 class QQmlPropertyCache;
69 class QQmlContextData;
70 class QQmlNotifier;
71 class QQmlDataExtended;
72 class QQmlNotifierEndpoint;
73 // This class is structured in such a way, that simply zero'ing it is the
74 // default state for elemental object allocations.  This is crucial in the
75 // workings of the QQmlInstruction::CreateSimpleObject instruction.
76 // Don't change anything here without first considering that case!
77 class Q_QML_PRIVATE_EXPORT QQmlData : public QAbstractDeclarativeData
78 {
79 public:
80     QQmlData()
81         : ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false), 
82           hasTaintedV8Object(false), isQueuedForDeletion(false), rootObjectInCreation(false),
83           hasVMEMetaObject(false), parentFrozen(false), notifyList(0), context(0), outerContext(0),
84           bindings(0), signalHandlers(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0), bindingBits(0),
85           lineNumber(0), columnNumber(0), compiledData(0), deferredIdx(0), v8objectid(0),
86           propertyCache(0), guards(0), extendedData(0) {
87         init();
88     }
89
90     static inline void init() {
91         static bool initialized = false;
92         if (!initialized) {
93             initialized = true;
94             QAbstractDeclarativeData::destroyed = destroyed;
95             QAbstractDeclarativeData::parentChanged = parentChanged;
96             QAbstractDeclarativeData::signalEmitted = signalEmitted;
97             QAbstractDeclarativeData::receivers = receivers;
98             QAbstractDeclarativeData::isSignalConnected = isSignalConnected;
99         }
100     }
101
102     static void destroyed(QAbstractDeclarativeData *, QObject *);
103     static void parentChanged(QAbstractDeclarativeData *, QObject *, QObject *);
104     static void signalEmitted(QAbstractDeclarativeData *, QObject *, int, void **);
105     static int receivers(QAbstractDeclarativeData *, const QObject *, int);
106     static bool isSignalConnected(QAbstractDeclarativeData *, const QObject *, int);
107
108     void destroyed(QObject *);
109     void parentChanged(QObject *, QObject *);
110
111     void setImplicitDestructible() {
112         if (!explicitIndestructibleSet) indestructible = false;
113     }
114
115     quint32 ownMemory:1;
116     quint32 ownContext:1;
117     quint32 indestructible:1;
118     quint32 explicitIndestructibleSet:1;
119     quint32 hasTaintedV8Object:1;
120     quint32 isQueuedForDeletion:1;
121     /*
122      * rootObjectInCreation should be true only when creating top level CPP and QML objects,
123      * v8 GC will check this flag, only deletes the objects when rootObjectInCreation is false.
124      */
125     quint32 rootObjectInCreation:1;
126     quint32 hasVMEMetaObject:1;
127     quint32 parentFrozen:1;
128     quint32 dummy:23;
129
130     struct NotifyList {
131         quint64 connectionMask;
132
133         quint16 maximumTodoIndex;
134         quint16 notifiesSize;
135
136         QQmlNotifierEndpoint *todo;
137         QQmlNotifierEndpoint**notifies;
138         void layout();
139     private:
140         void layout(QQmlNotifierEndpoint*);
141     };
142     NotifyList *notifyList;
143     
144     inline QQmlNotifierEndpoint *notify(int index);
145     void addNotify(int index, QQmlNotifierEndpoint *);
146     int endpointCount(int index);
147     bool signalHasEndpoint(int index);
148     void disconnectNotifiers();
149
150     // The context that created the C++ object
151     QQmlContextData *context; 
152     // The outermost context in which this object lives
153     QQmlContextData *outerContext;
154
155     QQmlAbstractBinding *bindings;
156     QQmlAbstractBoundSignal *signalHandlers;
157
158     // Linked list for QQmlContext::contextObjects
159     QQmlData *nextContextObject;
160     QQmlData**prevContextObject;
161
162     int bindingBitsSize;
163     quint32 *bindingBits; 
164
165     inline bool hasBindingBit(int) const;
166     void clearBindingBit(int);
167     void setBindingBit(QObject *obj, int);
168
169     inline bool hasPendingBindingBit(int) const;
170     void setPendingBindingBit(QObject *obj, int);
171     void clearPendingBindingBit(int);
172
173     quint16 lineNumber;
174     quint16 columnNumber;
175
176     QQmlCompiledData *compiledData;
177     unsigned int deferredIdx;
178
179     quint32 v8objectid;
180     v8::Persistent<v8::Object> v8object;
181
182     QQmlPropertyCache *propertyCache;
183
184     QQmlGuardImpl *guards;
185
186     static QQmlData *get(const QObject *object, bool create = false) {
187         QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
188         if (priv->wasDeleted) {
189             Q_ASSERT(!create);
190             return 0;
191         } else if (priv->declarativeData) {
192             return static_cast<QQmlData *>(priv->declarativeData);
193         } else if (create) {
194             priv->declarativeData = new QQmlData;
195             return static_cast<QQmlData *>(priv->declarativeData);
196         } else {
197             return 0;
198         }
199     }
200
201     bool hasExtendedData() const { return extendedData != 0; }
202     QHash<int, QObject *> *attachedProperties() const;
203
204     static inline bool wasDeleted(QObject *);
205
206     static void markAsDeleted(QObject *);
207     static void setQueuedForDeletion(QObject *);
208
209     static inline void flushPendingBinding(QObject *, int coreIndex);
210
211 private:
212     // For attachedProperties
213     mutable QQmlDataExtended *extendedData;
214
215     void flushPendingBindingImpl(int coreIndex);
216 };
217
218 bool QQmlData::wasDeleted(QObject *object)
219 {
220     if (!object)
221         return true;
222
223     QObjectPrivate *priv = QObjectPrivate::get(object);
224     if (priv->wasDeleted)
225         return true;
226
227     return priv->declarativeData &&
228            static_cast<QQmlData *>(priv->declarativeData)->isQueuedForDeletion;
229 }
230
231 QQmlNotifierEndpoint *QQmlData::notify(int index)
232 {
233     Q_ASSERT(index <= 0xFFFF);
234
235     if (!notifyList || !(notifyList->connectionMask & (1ULL << quint64(index % 64)))) {
236         return 0;
237     } else if (index < notifyList->notifiesSize) {
238         return notifyList->notifies[index];
239     } else if (index <= notifyList->maximumTodoIndex) {
240         notifyList->layout();
241     }
242
243     if (index < notifyList->notifiesSize) {
244         return notifyList->notifies[index];
245     } else {
246         return 0;
247     }
248 }
249
250 bool QQmlData::hasBindingBit(int coreIndex) const
251 {
252     int bit = coreIndex * 2;
253     if (bindingBitsSize > bit)
254         return bindingBits[bit / 32] & (1 << (bit % 32));
255     else
256         return false;
257 }
258
259 bool QQmlData::hasPendingBindingBit(int coreIndex) const
260 {
261     int bit = coreIndex * 2 + 1;
262     if (bindingBitsSize > bit)
263         return bindingBits[bit / 32] & (1 << (bit % 32));
264     else
265         return false;
266 }
267
268 void QQmlData::flushPendingBinding(QObject *o, int coreIndex)
269 {
270     QQmlData *data = QQmlData::get(o, false);
271     if (data && data->hasPendingBindingBit(coreIndex))
272         data->flushPendingBindingImpl(coreIndex);
273 }
274
275 QT_END_NAMESPACE
276
277 #endif // QQMLDATA_P_H