Rename QDeclarativePropertyCache::Data to QDeclarativePropertyData
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativepropertycache_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 QDECLARATIVEPROPERTYCACHE_P_H
43 #define QDECLARATIVEPROPERTYCACHE_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/qdeclarativerefcount_p.h>
57 #include "qdeclarativecleanup_p.h"
58 #include "qdeclarativenotifier_p.h"
59
60 #include <private/qhashedstring_p.h>
61 #include <QtCore/qvarlengtharray.h>
62 #include <QtCore/qvector.h>
63
64 QT_BEGIN_NAMESPACE
65
66 class QDeclarativeEngine;
67 class QMetaProperty;
68 class QV8Engine;
69 class QV8QObjectWrapper;
70 class QDeclarativePropertyCacheMethodArguments;
71 class QDeclarativePropertyData;
72
73 // We have this somewhat aweful split between RawData and Data so that RawData can be
74 // used in unions.  In normal code, you should always use Data which initializes RawData
75 // to an invalid state on construction.
76 class QDeclarativePropertyRawData
77 {
78 public:
79     enum Flag {
80         NoFlags           = 0x00000000,
81         ValueTypeFlagMask = 0x0000FFFF, // Flags in valueTypeFlags must fit in this mask
82
83         // Can apply to all properties, except IsFunction
84         IsConstant         = 0x00000001, // Has CONST flag
85         IsWritable         = 0x00000002, // Has WRITE function
86         IsResettable       = 0x00000004, // Has RESET function
87         IsAlias            = 0x00000008, // Is a QML alias to another property
88         IsFinal            = 0x00000010, // Has FINAL flag
89         IsDirect           = 0x00000020, // Exists on a C++ QMetaObject
90
91         // These are mutualy exclusive
92         IsFunction         = 0x00000040, // Is an invokable
93         IsQObjectDerived   = 0x00000080, // Property type is a QObject* derived type
94         IsEnumType         = 0x00000100, // Property type is an enum
95         IsQList            = 0x00000200, // Property type is a QML list
96         IsQmlBinding       = 0x00000400, // Property type is a QDeclarativeBinding*
97         IsQJSValue         = 0x00000800, // Property type is a QScriptValue
98         IsV8Handle         = 0x00001000, // Property type is a QDeclarativeV8Handle
99         IsVMEProperty      = 0x00002000, // Property type is a "var" property of VMEMO
100         IsValueTypeVirtual = 0x00004000, // Property is a value type "virtual" property
101
102         // Apply only to IsFunctions
103         IsVMEFunction      = 0x00008000, // Function was added by QML
104         HasArguments       = 0x00010000, // Function takes arguments
105         IsSignal           = 0x00020000, // Function is a signal
106         IsVMESignal        = 0x00040000, // Signal was added by QML
107         IsV8Function       = 0x00080000, // Function takes QDeclarativeV8Function* args
108         IsSignalHandler    = 0x00100000, // Function is a signal handler
109         IsOverload         = 0x00200000, // Function is an overload of another function
110
111         // Internal QDeclarativePropertyCache flags
112         NotFullyResolved   = 0x00400000  // True if the type data is to be lazily resolved
113     };
114     Q_DECLARE_FLAGS(Flags, Flag)
115
116     Flags getFlags() const { return Flag(flags); }
117     void setFlags(Flags f) { flags = f; }
118
119     bool isValid() const { return coreIndex != -1; }
120
121     bool isConstant() const { return flags & IsConstant; }
122     bool isWritable() const { return flags & IsWritable; }
123     bool isResettable() const { return flags & IsResettable; }
124     bool isAlias() const { return flags & IsAlias; }
125     bool isFinal() const { return flags & IsFinal; }
126     bool isDirect() const { return flags & IsDirect; }
127     bool isFunction() const { return flags & IsFunction; }
128     bool isQObject() const { return flags & IsQObjectDerived; }
129     bool isEnum() const { return flags & IsEnumType; }
130     bool isQList() const { return flags & IsQList; }
131     bool isQmlBinding() const { return flags & IsQmlBinding; }
132     bool isQJSValue() const { return flags & IsQJSValue; }
133     bool isV8Handle() const { return flags & IsV8Handle; }
134     bool isVMEProperty() const { return flags & IsVMEProperty; }
135     bool isValueTypeVirtual() const { return flags & IsValueTypeVirtual; }
136     bool isVMEFunction() const { return flags & IsVMEFunction; }
137     bool hasArguments() const { return flags & HasArguments; }
138     bool isSignal() const { return flags & IsSignal; }
139     bool isVMESignal() const { return flags & IsVMESignal; }
140     bool isV8Function() const { return flags & IsV8Function; }
141     bool isSignalHandler() const { return flags & IsSignalHandler; }
142     bool isOverload() const { return flags & IsOverload; }
143
144     union {
145         int propType;             // When !NotFullyResolved
146         const char *propTypeName; // When NotFullyResolved
147     };
148     int coreIndex;
149     union {
150         int notifyIndex;  // When !IsFunction
151         void *arguments;  // When IsFunction && HasArguments
152     };
153     union {
154         struct { // When !IsValueTypeVirtual
155             uint overrideIndexIsProperty : 1;
156             signed int overrideIndex : 31;
157         };
158         struct { // When IsValueTypeVirtual
159             quint16 valueTypeFlags; // flags of the access property on the value type proxy object
160             quint8 valueTypePropType; // The QVariant::Type of access property on the value type
161                                       // proxy object
162             quint8 valueTypeCoreIndex; // The prop index of the access property on the value type
163                                        //proxy object
164         };
165     };
166     int revision;
167     int metaObjectOffset;
168
169 private:
170     friend class QDeclarativePropertyData;
171     friend class QDeclarativePropertyCache;
172     quint32 flags;
173 };
174 Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyRawData::Flags);
175
176 class QDeclarativePropertyData : public QDeclarativePropertyRawData
177 {
178 public:
179     inline QDeclarativePropertyData();
180     inline QDeclarativePropertyData(const QDeclarativePropertyRawData &);
181
182     inline bool operator==(const QDeclarativePropertyRawData &);
183
184     static Flags flagsForProperty(const QMetaProperty &, QDeclarativeEngine *engine = 0);
185     void load(const QMetaProperty &, QDeclarativeEngine *engine = 0);
186     void load(const QMetaMethod &);
187     QString name(QObject *);
188     QString name(const QMetaObject *);
189
190     // Returns -1 if not a value type virtual property
191     inline int getValueTypeCoreIndex() const;
192
193 private:
194     friend class QDeclarativePropertyCache;
195     void lazyLoad(const QMetaProperty &, QDeclarativeEngine *engine = 0);
196     void lazyLoad(const QMetaMethod &);
197     bool notFullyResolved() const { return flags & NotFullyResolved; }
198 };
199
200 class Q_DECLARATIVE_EXPORT QDeclarativePropertyCache : public QDeclarativeRefCount, public QDeclarativeCleanup
201 {
202 public:
203     QDeclarativePropertyCache(QDeclarativeEngine *);
204     QDeclarativePropertyCache(QDeclarativeEngine *, const QMetaObject *);
205     virtual ~QDeclarativePropertyCache();
206
207     void update(QDeclarativeEngine *, const QMetaObject *);
208
209     QDeclarativePropertyCache *copy(int reserve = 0);
210     void append(QDeclarativeEngine *, const QMetaObject *,
211                 QDeclarativePropertyData::Flag propertyFlags = QDeclarativePropertyData::NoFlags,
212                 QDeclarativePropertyData::Flag methodFlags = QDeclarativePropertyData::NoFlags,
213                 QDeclarativePropertyData::Flag signalFlags = QDeclarativePropertyData::NoFlags);
214     void append(QDeclarativeEngine *, const QMetaObject *, int revision,
215                 QDeclarativePropertyData::Flag propertyFlags = QDeclarativePropertyData::NoFlags,
216                 QDeclarativePropertyData::Flag methodFlags = QDeclarativePropertyData::NoFlags,
217                 QDeclarativePropertyData::Flag signalFlags = QDeclarativePropertyData::NoFlags);
218
219     static QDeclarativePropertyData create(const QMetaObject *, const QString &);
220
221     inline QDeclarativePropertyData *property(const QHashedV8String &) const;
222     QDeclarativePropertyData *property(const QHashedStringRef &) const;
223     QDeclarativePropertyData *property(const QHashedCStringRef &) const;
224     QDeclarativePropertyData *property(const QString &) const;
225     QDeclarativePropertyData *property(int) const;
226     QDeclarativePropertyData *method(int) const;
227     QStringList propertyNames() const;
228
229     inline QDeclarativePropertyData *overrideData(QDeclarativePropertyData *) const;
230     inline bool isAllowedInRevision(QDeclarativePropertyData *) const;
231
232     inline QDeclarativeEngine *qmlEngine() const;
233     static QDeclarativePropertyData *property(QDeclarativeEngine *, QObject *, const QString &,
234                                               QDeclarativePropertyData &);
235     static QDeclarativePropertyData *property(QDeclarativeEngine *, QObject *, const QHashedV8String &,
236                                               QDeclarativePropertyData &);
237     static int *methodParameterTypes(QObject *, int index, QVarLengthArray<int, 9> &dummy,
238                                      QByteArray *unknownTypeError);
239
240     static bool isDynamicMetaObject(const QMetaObject *);
241 protected:
242     virtual void destroy();
243     virtual void clear();
244
245 private:
246     friend class QDeclarativeEnginePrivate;
247     friend class QV8QObjectWrapper;
248
249     // Implemented in v8/qv8qobjectwrapper.cpp
250     v8::Local<v8::Object> newQObject(QObject *, QV8Engine *);
251
252     typedef QVector<QDeclarativePropertyData> IndexCache;
253     typedef QStringHash<QDeclarativePropertyData *> StringCache;
254     typedef QVector<int> AllowedRevisionCache;
255
256     void resolve(QDeclarativePropertyData *) const;
257     void updateRecur(QDeclarativeEngine *, const QMetaObject *);
258
259     QDeclarativeEngine *engine;
260     
261     QDeclarativePropertyCache *parent;
262     int propertyIndexCacheStart;
263     int methodIndexCacheStart;
264
265     IndexCache propertyIndexCache;
266     IndexCache methodIndexCache;
267     IndexCache signalHandlerIndexCache;
268     StringCache stringCache;
269     AllowedRevisionCache allowedRevisionCache;
270     v8::Persistent<v8::Function> constructor;
271
272     const QMetaObject *metaObject;
273     QDeclarativePropertyCacheMethodArguments *argumentsCache;
274 };
275   
276 QDeclarativePropertyData::QDeclarativePropertyData()
277 {
278     propType = 0;
279     coreIndex = -1;
280     notifyIndex = -1;
281     overrideIndexIsProperty = false;
282     overrideIndex = -1;
283     revision = 0;
284     metaObjectOffset = -1; 
285     flags = 0;
286 }
287
288 QDeclarativePropertyData::QDeclarativePropertyData(const QDeclarativePropertyRawData &d)
289 {
290     *(static_cast<QDeclarativePropertyRawData *>(this)) = d;
291 }
292
293 bool QDeclarativePropertyData::operator==(const QDeclarativePropertyRawData &other)
294 {
295     return flags == other.flags &&
296            propType == other.propType &&
297            coreIndex == other.coreIndex &&
298            notifyIndex == other.notifyIndex &&
299            revision == other.revision &&
300            (!isValueTypeVirtual() || 
301             (valueTypeCoreIndex == other.valueTypeCoreIndex && 
302              valueTypePropType == other.valueTypePropType));
303 }
304
305 int QDeclarativePropertyData::getValueTypeCoreIndex() const
306 {
307     return isValueTypeVirtual()?valueTypeCoreIndex:-1;
308 }
309
310 QDeclarativePropertyData *
311 QDeclarativePropertyCache::overrideData(QDeclarativePropertyData *data) const
312 {
313     if (data->overrideIndex < 0)
314         return 0;
315
316     if (data->overrideIndexIsProperty)
317         return property(data->overrideIndex);
318     else
319         return method(data->overrideIndex);
320 }
321
322 bool QDeclarativePropertyCache::isAllowedInRevision(QDeclarativePropertyData *data) const
323 {
324     return (data->metaObjectOffset == -1 && data->revision == 0) ||
325            (allowedRevisionCache[data->metaObjectOffset] >= data->revision);
326 }
327
328 QDeclarativeEngine *QDeclarativePropertyCache::qmlEngine() const
329 {
330     return engine;
331 }
332
333 QDeclarativePropertyData *QDeclarativePropertyCache::property(const QHashedV8String &str) const
334 {
335     QDeclarativePropertyData **rv = stringCache.value(str);
336     if (rv && (*rv)->notFullyResolved()) resolve(*rv);
337     return rv?*rv:0;
338 }
339
340 QT_END_NAMESPACE
341
342 #endif // QDECLARATIVEPROPERTYCACHE_P_H