Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qtdeclarative
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativescarceresourcescriptclass.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 "private/qdeclarativescarceresourcescriptclass_p.h"
43
44 #include "private/qdeclarativeengine_p.h"
45 #include "private/qdeclarativecontext_p.h"
46 #include "private/qdeclarativedata_p.h"
47 #include "private/qdeclarativetypenamescriptclass_p.h"
48 #include "private/qdeclarativelistscriptclass_p.h"
49 #include "private/qdeclarativebinding_p.h"
50 #include "private/qdeclarativeguard_p.h"
51 #include "private/qdeclarativevmemetaobject_p.h"
52
53 #include <QtCore/qtimer.h>
54 #include <QtCore/qvarlengtharray.h>
55 #include <QtScript/qscriptcontextinfo.h>
56
57 Q_DECLARE_METATYPE(QScriptValue);
58
59 QT_BEGIN_NAMESPACE
60
61 QDeclarativeScarceResourceScriptClass::QDeclarativeScarceResourceScriptClass(QDeclarativeEngine *bindEngine)
62     : QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine)
63 {
64     QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
65
66     // Properties of this type can be explicitly preserved by clients,
67     // which prevents the scarce resource from being automatically
68     // released after the binding has been evaluated.
69     m_preserve = scriptEngine->newFunction(preserve);
70     m_preserveId = createPersistentIdentifier(QLatin1String("preserve"));
71
72     // Similarly, they can be explicitly destroyed by clients,
73     // which releases the scarce resource.
74     m_destroy = scriptEngine->newFunction(destroy);
75     m_destroyId = createPersistentIdentifier(QLatin1String("destroy"));
76 }
77
78 QDeclarativeScarceResourceScriptClass::~QDeclarativeScarceResourceScriptClass()
79 {
80 }
81
82 /*
83   Returns a JavaScript object whose instance data is a new scarce resource data.
84   The scarce resource is added to the doubly-linked-list of scarce resources in the engine
85   so that the scarce resource can be released after evaluation completes.
86  */
87 QScriptValue QDeclarativeScarceResourceScriptClass::newScarceResource(const QVariant &v)
88 {
89     // create the scarce resource
90     ScarceResourceData *srd = new ScarceResourceData(v);
91
92     // insert into the linked list
93     QDeclarativeEnginePrivate *enginePrivate = QDeclarativeEnginePrivate::get(engine);
94     srd->insertInto(&enginePrivate->scarceResources);
95     Q_ASSERT(enginePrivate->scarceResourcesRefCount > 0);
96
97     // return the javascript object with the scarce resource instance data
98     QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
99     return QScriptDeclarativeClass::newObject(scriptEngine, this, srd); // JSC takes ownership of srd.
100 }
101
102 QVariant QDeclarativeScarceResourceScriptClass::toVariant(Object *object, bool *ok)
103 {
104     ScarceResourceData *obj = static_cast<ScarceResourceData*>(object);
105     if (ok) *ok = true;
106     return obj->resource;
107 }
108
109 QVariant QDeclarativeScarceResourceScriptClass::toVariant(const QScriptValue &value)
110 {
111     Q_ASSERT(scriptClass(value) == this);
112
113     return toVariant(object(value), 0);
114 }
115
116 // The destroy() and preserve() function properties are readable.
117 QScriptClass::QueryFlags
118 QDeclarativeScarceResourceScriptClass::queryProperty(Object *object, const Identifier &name,
119                                                      QScriptClass::QueryFlags flags)
120 {
121     Q_UNUSED(object)
122     Q_UNUSED(flags)
123
124     if (name == m_destroyId.identifier || name == m_preserveId.identifier)
125         return (QScriptClass::HandlesReadAccess);
126     return 0;
127 }
128
129 // Return the (function) values which may be evaluated by clients.
130 QDeclarativeScarceResourceScriptClass::Value
131 QDeclarativeScarceResourceScriptClass::property(Object *object, const Identifier &name)
132 {
133     Q_UNUSED(object)
134
135     QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
136
137     // functions
138     if (name == m_preserveId.identifier)
139         return Value(scriptEngine, m_preserve);
140     else if (name == m_destroyId.identifier)
141         return Value(scriptEngine, m_destroy);
142
143     return Value();
144 }
145
146 /*
147    This method is called when the user explicitly calls the "preserve" method of a scarce resource in JavaScript
148    within the specified evaluation context \a context of the script engine \a engine.
149    Calling this function signifies that the user explicitly wants to preserve the resource rather than let it
150    be automatically released once evaluation of the expression is complete.
151    This function removes the internal scarce resource from the declarative engine's linked list of scarce resources
152    to release after evaluation of the expression completes.  This means that the resource will only be truly
153    released when the JavaScript engine's garbage collector is run.
154
155    Example:
156    \qml
157    function getIcon(model) {
158        var icon = model.avatar; // a pixmap property
159        icon.preserve();         // explicitly preserves the resource
160        return icon;             // a valid variant will be returned
161    }
162    \endqml
163  */
164 QScriptValue QDeclarativeScarceResourceScriptClass::preserve(QScriptContext *context, QScriptEngine *engine)
165 {
166     QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
167     QScriptValue that = context->thisObject();
168
169     if (scriptClass(that) != p->scarceResourceClass)
170         return engine->undefinedValue();
171
172     // The client wishes to preserve the resource in this SRD.
173     ScarceResourceData *data = static_cast<ScarceResourceData *>(p->scarceResourceClass->object(that));
174     if (!data)
175         return engine->undefinedValue();
176
177     // remove node from list, without releasing the resource.
178     data->removeNode();
179
180     return engine->undefinedValue();
181 }
182
183 /*
184    This method is called when the user explicitly calls the "destroy" method of a scarce resource in JavaScript
185    within the specified evaluation context \a context of the script engine \a engine.
186    Calling this function signifies that the user explicitly wants to release the resource.
187    This function sets the internal scarce resource variant to the invalid variant, in order to release the original resource,
188    and then removes the resource from the declarative engine's linked-list of scarce resources to
189    to release after evaluation of the expression completes, as it has already been released.
190
191    Example:
192    \qml
193    function getIcon(model) {
194        var icon = model.avatar; // a pixmap property
195        icon.destroy();          // explicitly releases the resource
196        return icon;             // an invalid variant will be returned
197    }
198    \endqml
199  */
200 QScriptValue QDeclarativeScarceResourceScriptClass::destroy(QScriptContext *context, QScriptEngine *engine)
201 {
202     QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
203     QScriptValue that = context->thisObject();
204
205     if (scriptClass(that) != p->scarceResourceClass)
206         return engine->undefinedValue();
207
208     // the client wishes to release the resource in this SRD.
209     ScarceResourceData *data = static_cast<ScarceResourceData *>(p->scarceResourceClass->object(that));
210     if (!data)
211         return engine->undefinedValue();
212
213     // release the resource and remove the node from the list.
214     data->releaseResource();
215
216     return engine->undefinedValue();
217 }
218
219 QT_END_NAMESPACE