Merge branch 'qtquick2' of scm.dev.nokia.troll.no:qt/qtdeclarative-staging into v8
[profile/ivi/qtdeclarative.git] / src / declarative / qml / v8 / qv8variantwrapper.cpp
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 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qv8variantwrapper_p.h"
43 #include "qv8engine_p.h"
44 #include "qdeclarativeengine_p.h"
45
46 QT_BEGIN_NAMESPACE
47
48 class QV8VariantResource : public QV8ObjectResource, 
49                            public QDeclarativeEnginePrivate::ScarceResourceData
50 {
51     V8_RESOURCE_TYPE(VariantType);
52 public:
53     QV8VariantResource(QV8Engine *engine, const QVariant &data);
54 };
55
56 QV8VariantResource::QV8VariantResource(QV8Engine *engine, const QVariant &data)
57 : QV8ObjectResource(engine), QDeclarativeEnginePrivate::ScarceResourceData(data)
58 {
59 }
60
61 QV8VariantWrapper::QV8VariantWrapper()
62 : m_engine(0)
63 {
64 }
65
66 QV8VariantWrapper::~QV8VariantWrapper()
67 {
68 }
69
70 void QV8VariantWrapper::init(QV8Engine *engine)
71 {
72     m_engine = engine;
73     {
74     v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
75     ft->InstanceTemplate()->SetNamedPropertyHandler(Getter, Setter);
76     ft->InstanceTemplate()->SetHasExternalResource(true);
77     m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
78     }
79     {
80     m_preserve = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(Preserve)->GetFunction());
81     m_destroy = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(Destroy)->GetFunction());
82     v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
83     ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter);
84     ft->InstanceTemplate()->SetHasExternalResource(true);
85     ft->InstanceTemplate()->SetAccessor(v8::String::New("preserve"), PreserveGetter, 0, 
86                                         m_preserve, v8::DEFAULT, 
87                                         v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
88     ft->InstanceTemplate()->SetAccessor(v8::String::New("destroy"), DestroyGetter, 0, 
89                                         m_destroy, v8::DEFAULT, 
90                                         v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
91     m_scarceConstructor = qPersistentNew<v8::Function>(ft->GetFunction());
92     }
93
94 }
95
96 void QV8VariantWrapper::destroy()
97 {
98     qPersistentDispose(m_destroy);
99     qPersistentDispose(m_preserve);
100     qPersistentDispose(m_scarceConstructor);
101     qPersistentDispose(m_constructor);
102 }
103
104 v8::Local<v8::Object> QV8VariantWrapper::newVariant(const QVariant &value)
105 {
106     bool scarceResource = value.type() == QVariant::Pixmap ||
107                           value.type() == QVariant::Image;
108
109     // XXX NewInstance() should be optimized
110     v8::Local<v8::Object> rv;
111     QV8VariantResource *r = new QV8VariantResource(m_engine, value);
112
113     if (scarceResource) {
114         QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(m_engine->engine());
115         Q_ASSERT(ep->scarceResourcesRefCount);
116         rv = m_scarceConstructor->NewInstance();
117         ep->scarceResources.insert(r);
118     } else {
119         rv = m_constructor->NewInstance();
120     }
121
122     rv->SetExternalResource(r);
123     return rv;
124 }
125
126 bool QV8VariantWrapper::isVariant(v8::Handle<v8::Value> value)
127 {
128     return value->IsObject() && v8_resource_cast<QV8VariantResource>(value->ToObject());
129 }
130
131 QVariant QV8VariantWrapper::toVariant(v8::Handle<v8::Object> obj)
132 {
133     QV8VariantResource *r =  v8_resource_cast<QV8VariantResource>(obj);
134     return r?r->data:QVariant();
135 }
136
137 QVariant QV8VariantWrapper::toVariant(QV8ObjectResource *r)
138 {
139     Q_ASSERT(r->resourceType() == QV8ObjectResource::VariantType);
140     return static_cast<QV8VariantResource *>(r)->data;
141 }
142
143 v8::Handle<v8::Value> QV8VariantWrapper::Getter(v8::Local<v8::String> property, 
144                                                 const v8::AccessorInfo &info)
145 {
146     return v8::Undefined();
147 }
148
149 v8::Handle<v8::Value> QV8VariantWrapper::Setter(v8::Local<v8::String> property, 
150                                                 v8::Local<v8::Value> value,
151                                                 const v8::AccessorInfo &info)
152 {
153     return v8::Undefined();
154 }
155
156 v8::Handle<v8::Value> QV8VariantWrapper::PreserveGetter(v8::Local<v8::String> property, 
157                                                         const v8::AccessorInfo &info)
158 {
159     Q_UNUSED(property);
160     return info.Data();
161 }
162
163 v8::Handle<v8::Value> QV8VariantWrapper::DestroyGetter(v8::Local<v8::String> property, 
164                                                        const v8::AccessorInfo &info)
165 {
166     Q_UNUSED(property);
167     return info.Data();
168 }
169
170 v8::Handle<v8::Value> QV8VariantWrapper::Preserve(const v8::Arguments &args)
171 {
172     QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This());
173     if (resource) {
174         resource->node.remove();
175     }
176     return v8::Undefined();
177 }
178
179 v8::Handle<v8::Value> QV8VariantWrapper::Destroy(const v8::Arguments &args)
180 {
181     QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This());
182     if (resource) {
183         resource->data = QVariant();
184         resource->node.remove();
185     }
186     return v8::Undefined();
187 }
188
189 QT_END_NAMESPACE