Allow reference to signals using 'on' handler syntax.
[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 "private/qdeclarativecleanup_p.h"
58 #include "private/qdeclarativenotifier_p.h"
59
60 #include "private/qhashedstring_p.h"
61 #include <QtCore/qvector.h>
62
63 QT_BEGIN_NAMESPACE
64
65 class QDeclarativeEngine;
66 class QMetaProperty;
67 class QV8Engine;
68 class QV8QObjectWrapper;
69
70 class Q_DECLARATIVE_EXPORT QDeclarativePropertyCache : public QDeclarativeRefCount, public QDeclarativeCleanup
71 {
72 public:
73     QDeclarativePropertyCache(QDeclarativeEngine *);
74     QDeclarativePropertyCache(QDeclarativeEngine *, const QMetaObject *);
75     virtual ~QDeclarativePropertyCache();
76
77     struct Data {
78         inline Data(); 
79         inline bool operator==(const Data &);
80
81         enum Flag { 
82                     NoFlags           = 0x00000000,
83
84                     // Can apply to all properties, except IsFunction
85                     IsConstant        = 0x00000001, // Has CONST flag
86                     IsWritable        = 0x00000002, // Has WRITE function
87                     IsResettable      = 0x00000004, // Has RESET function
88                     IsAlias           = 0x00000008, // Is a QML alias to another property
89                     IsFinal           = 0x00000010, // Has FINAL flag
90                     IsDirect          = 0x00000020, // Exists on a C++ QMetaObject
91
92                     // These are mutualy exclusive
93                     IsFunction        = 0x00000040, // Is an invokable
94                     IsQObjectDerived  = 0x00000080, // Property type is a QObject* derived type
95                     IsEnumType        = 0x00000100, // Property type is an enum
96                     IsQList           = 0x00000200, // Property type is a QML list
97                     IsQmlBinding      = 0x00000400, // Property type is a QDeclarativeBinding*
98                     IsQJSValue    = 0x00000800, // Property type is a QScriptValue
99                     IsV8Handle        = 0x00001000, // Property type is a QDeclarativeV8Handle
100
101                     // Apply only to IsFunctions
102                     IsVMEFunction     = 0x00002000, // Function was added by QML
103                     HasArguments      = 0x00004000, // Function takes arguments
104                     IsSignal          = 0x00008000, // Function is a signal
105                     IsVMESignal       = 0x00010000, // Signal was added by QML
106                     IsV8Function      = 0x00020000, // Function takes QDeclarativeV8Function* args
107                     IsSignalHandler   = 0x00040000, // Function is a signal handler
108
109                     // Internal QDeclarativePropertyCache flags
110                     NotFullyResolved  = 0x00080000  // True if the type data is to be lazily resolved
111         };
112         Q_DECLARE_FLAGS(Flags, Flag)
113
114         Flags getFlags() const { return flags; }
115         void setFlags(Flags f) { flags = f; }
116
117         bool isValid() const { return coreIndex != -1; } 
118
119         bool isConstant() const { return flags & IsConstant; }
120         bool isWritable() const { return flags & IsWritable; }
121         bool isResettable() const { return flags & IsResettable; }
122         bool isAlias() const { return flags & IsAlias; }
123         bool isFinal() const { return flags & IsFinal; }
124         bool isDirect() const { return flags & IsDirect; }
125         bool isFunction() const { return flags & IsFunction; }
126         bool isQObject() const { return flags & IsQObjectDerived; }
127         bool isEnum() const { return flags & IsEnumType; }
128         bool isQList() const { return flags & IsQList; }
129         bool isQmlBinding() const { return flags & IsQmlBinding; }
130         bool isQJSValue() const { return flags & IsQJSValue; }
131         bool isV8Handle() const { return flags & IsV8Handle; }
132         bool isVMEFunction() const { return flags & IsVMEFunction; }
133         bool hasArguments() const { return flags & HasArguments; }
134         bool isSignal() const { return flags & IsSignal; }
135         bool isVMESignal() const { return flags & IsVMESignal; }
136         bool isV8Function() const { return flags & IsV8Function; }
137         bool isSignalHandler() const { return flags & IsSignalHandler; }
138
139         union {
140             int propType;             // When !NotFullyResolved
141             const char *propTypeName; // When NotFullyResolved
142         };
143         int coreIndex;
144         union {
145             int notifyIndex; // When !IsFunction
146             int relatedIndex; // When IsFunction
147         };
148         uint overrideIndexIsProperty : 1;
149         int overrideIndex : 31;
150         int revision; 
151         int metaObjectOffset;
152
153         static Flags flagsForProperty(const QMetaProperty &, QDeclarativeEngine *engine = 0);
154         void load(const QMetaProperty &, QDeclarativeEngine *engine = 0);
155         void load(const QMetaMethod &);
156         QString name(QObject *);
157         QString name(const QMetaObject *);
158
159     private:
160         void lazyLoad(const QMetaProperty &, QDeclarativeEngine *engine = 0);
161         void lazyLoad(const QMetaMethod &);
162         bool notFullyResolved() const { return flags & NotFullyResolved; }
163         friend class QDeclarativePropertyCache;
164         Flags flags;
165     };
166
167     struct ValueTypeData {
168         inline ValueTypeData();
169         inline bool operator==(const ValueTypeData &);
170         Data::Flags flags;     // flags of the access property on the value type proxy object
171         int valueTypeCoreIdx;  // The prop index of the access property on the value type proxy object
172         int valueTypePropType; // The QVariant::Type of access property on the value type proxy object
173     };
174
175     void update(QDeclarativeEngine *, const QMetaObject *);
176
177     QDeclarativePropertyCache *copy(int reserve = 0);
178     void append(QDeclarativeEngine *, const QMetaObject *, Data::Flag propertyFlags = Data::NoFlags,
179                 Data::Flag methodFlags = Data::NoFlags, Data::Flag signalFlags = Data::NoFlags);
180     void append(QDeclarativeEngine *, const QMetaObject *, int revision, Data::Flag propertyFlags = Data::NoFlags,
181                 Data::Flag methodFlags = Data::NoFlags, Data::Flag signalFlags = Data::NoFlags);
182
183     static Data create(const QMetaObject *, const QString &);
184
185     inline Data *property(const QHashedV8String &) const;
186     Data *property(const QHashedStringRef &) const;
187     Data *property(const QHashedCStringRef &) const;
188     Data *property(const QString &) const;
189     Data *property(int) const;
190     Data *method(int) const;
191     QStringList propertyNames() const;
192
193     inline Data *overrideData(Data *) const;
194     inline bool isAllowedInRevision(Data *) const;
195
196     inline QDeclarativeEngine *qmlEngine() const;
197     static Data *property(QDeclarativeEngine *, QObject *, const QString &, Data &);
198     static Data *property(QDeclarativeEngine *, QObject *, const QHashedV8String &, Data &);
199
200     static bool isDynamicMetaObject(const QMetaObject *);
201 protected:
202     virtual void clear();
203
204 private:
205     friend class QDeclarativeEnginePrivate;
206     friend class QV8QObjectWrapper;
207
208     // Implemented in v8/qv8qobjectwrapper.cpp
209     v8::Local<v8::Object> newQObject(QObject *, QV8Engine *);
210
211     typedef QVector<Data> IndexCache;
212     typedef QStringHash<Data *> StringCache;
213     typedef QVector<int> AllowedRevisionCache;
214
215     void resolve(Data *) const;
216     void updateRecur(QDeclarativeEngine *, const QMetaObject *);
217
218     QDeclarativeEngine *engine;
219     
220     QDeclarativePropertyCache *parent;
221     int propertyIndexCacheStart;
222     int methodIndexCacheStart;
223
224     IndexCache propertyIndexCache;
225     IndexCache methodIndexCache;
226     IndexCache signalHandlerIndexCache;
227     StringCache stringCache;
228     AllowedRevisionCache allowedRevisionCache;
229     v8::Persistent<v8::Function> constructor;
230 };
231 Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyCache::Data::Flags);
232   
233 QDeclarativePropertyCache::Data::Data()
234 : propType(0), coreIndex(-1), notifyIndex(-1), overrideIndexIsProperty(false), overrideIndex(-1),
235   revision(0), metaObjectOffset(-1), flags(0)
236 {
237 }
238
239 bool QDeclarativePropertyCache::Data::operator==(const QDeclarativePropertyCache::Data &other)
240 {
241     return flags == other.flags &&
242            propType == other.propType &&
243            coreIndex == other.coreIndex &&
244            notifyIndex == other.notifyIndex &&
245            revision == other.revision;
246 }
247
248 QDeclarativePropertyCache::Data *
249 QDeclarativePropertyCache::overrideData(Data *data) const
250 {
251     if (data->overrideIndex < 0)
252         return 0;
253
254     if (data->overrideIndexIsProperty)
255         return property(data->overrideIndex);
256     else
257         return method(data->overrideIndex);
258 }
259
260 QDeclarativePropertyCache::ValueTypeData::ValueTypeData()
261 : flags(QDeclarativePropertyCache::Data::NoFlags), valueTypeCoreIdx(-1), valueTypePropType(0) 
262 {
263 }
264
265 bool QDeclarativePropertyCache::ValueTypeData::operator==(const ValueTypeData &o) 
266
267     return flags == o.flags &&
268            valueTypeCoreIdx == o.valueTypeCoreIdx &&
269            valueTypePropType == o.valueTypePropType; 
270 }
271
272 bool QDeclarativePropertyCache::isAllowedInRevision(Data *data) const
273 {
274     return (data->metaObjectOffset == -1 && data->revision == 0) ||
275            (allowedRevisionCache[data->metaObjectOffset] >= data->revision);
276 }
277
278 QDeclarativeEngine *QDeclarativePropertyCache::qmlEngine() const
279 {
280     return engine;
281 }
282
283 QDeclarativePropertyCache::Data *QDeclarativePropertyCache::property(const QHashedV8String &str) const
284 {
285     QDeclarativePropertyCache::Data **rv = stringCache.value(str);
286     if (rv && (*rv)->notFullyResolved()) resolve(*rv);
287     return rv?*rv:0;
288 }
289
290 QT_END_NAMESPACE
291
292 #endif // QDECLARATIVEPROPERTYCACHE_P_H