1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
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
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.
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.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "private/qdeclarativescarceresourcescriptclass_p.h"
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"
53 #include <QtCore/qtimer.h>
54 #include <QtCore/qvarlengtharray.h>
55 #include <QtScript/qscriptcontextinfo.h>
57 Q_DECLARE_METATYPE(QScriptValue);
61 QDeclarativeScarceResourceScriptClass::QDeclarativeScarceResourceScriptClass(QDeclarativeEngine *bindEngine)
62 : QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine)
64 QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
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"));
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"));
78 QDeclarativeScarceResourceScriptClass::~QDeclarativeScarceResourceScriptClass()
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.
87 QScriptValue QDeclarativeScarceResourceScriptClass::newScarceResource(const QVariant &v)
89 // create the scarce resource
90 ScarceResourceData *srd = new ScarceResourceData(v);
92 // insert into the linked list
93 QDeclarativeEnginePrivate *enginePrivate = QDeclarativeEnginePrivate::get(engine);
94 srd->insertInto(&enginePrivate->scarceResources);
95 Q_ASSERT(enginePrivate->scarceResourcesRefCount > 0);
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.
102 QVariant QDeclarativeScarceResourceScriptClass::toVariant(Object *object, bool *ok)
104 ScarceResourceData *obj = static_cast<ScarceResourceData*>(object);
106 return obj->resource;
109 QVariant QDeclarativeScarceResourceScriptClass::toVariant(const QScriptValue &value)
111 Q_ASSERT(scriptClass(value) == this);
113 return toVariant(object(value), 0);
116 // The destroy() and preserve() function properties are readable.
117 QScriptClass::QueryFlags
118 QDeclarativeScarceResourceScriptClass::queryProperty(Object *object, const Identifier &name,
119 QScriptClass::QueryFlags flags)
124 if (name == m_destroyId.identifier || name == m_preserveId.identifier)
125 return (QScriptClass::HandlesReadAccess);
129 // Return the (function) values which may be evaluated by clients.
130 QDeclarativeScarceResourceScriptClass::Value
131 QDeclarativeScarceResourceScriptClass::property(Object *object, const Identifier &name)
135 QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
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);
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.
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
164 QScriptValue QDeclarativeScarceResourceScriptClass::preserve(QScriptContext *context, QScriptEngine *engine)
166 QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
167 QScriptValue that = context->thisObject();
169 if (scriptClass(that) != p->scarceResourceClass)
170 return engine->undefinedValue();
172 // The client wishes to preserve the resource in this SRD.
173 ScarceResourceData *data = static_cast<ScarceResourceData *>(p->scarceResourceClass->object(that));
175 return engine->undefinedValue();
177 // remove node from list, without releasing the resource.
180 return engine->undefinedValue();
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.
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
200 QScriptValue QDeclarativeScarceResourceScriptClass::destroy(QScriptContext *context, QScriptEngine *engine)
202 QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
203 QScriptValue that = context->thisObject();
205 if (scriptClass(that) != p->scarceResourceClass)
206 return engine->undefinedValue();
208 // the client wishes to release the resource in this SRD.
209 ScarceResourceData *data = static_cast<ScarceResourceData *>(p->scarceResourceClass->object(that));
211 return engine->undefinedValue();
213 // release the resource and remove the node from the list.
214 data->releaseResource();
216 return engine->undefinedValue();