aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Adams <christopher.adams@nokia.com>2011-10-10 12:11:21 +1000
committerQt by Nokia <qt-info@nokia.com>2011-12-06 02:46:28 +0100
commit564d58025e46c825ec763193767defd78f5e13a0 (patch)
tree31d046ac0c016df416afd4923fb749d8bf73d6bc
parent8601f3444f7926a7b47ae217d8bf51044ff61809 (diff)
Ensure that scarce resources work with var properties
Now that we have a new property type which stores JavaScript handles, we need to ensure that scarce resources can be used with them. Task-number: QMLNG-18 Task-number: QTBUG-21843 Change-Id: I4a920ae39e7d33cf5e33362e5e0ee21c74cb35e3 Reviewed-by: Martin Jones <martin.jones@nokia.com>
-rw-r--r--doc/src/declarative/basictypes.qdoc13
-rw-r--r--doc/src/declarative/javascriptblocks.qdoc172
-rw-r--r--doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.cpp124
-rw-r--r--doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.h73
-rw-r--r--doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFive.qml54
-rw-r--r--doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFour.js56
-rw-r--r--doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFour.qml56
-rw-r--r--doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleOne.qml54
-rw-r--r--doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleThree.js58
-rw-r--r--doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleThree.qml49
-rw-r--r--doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleTwo.qml51
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp48
-rw-r--r--src/declarative/qml/v8/qv8variantresource_p.h81
-rw-r--r--src/declarative/qml/v8/qv8variantwrapper.cpp30
-rw-r--r--src/declarative/qml/v8/v8.pri1
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVar.qml9
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVariant.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/ScarceResourceSignalComponent.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceVarComponent.qml13
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.var.qml14
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.variant.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopy.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.var.qml14
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.variant.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyFromJs.qml)2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.js (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.js)3
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.qml18
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.js25
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.qml)4
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.js19
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.qml22
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.js (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.js)3
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.qml7
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.js19
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.qml)2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.js (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.js)3
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.qml)2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.js15
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.qml12
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.var.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyNoBinding.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.variant.qml14
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.var.qml13
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.variant.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceDestroyedCopy.qml)2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.var.qml23
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.variant.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunction.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.var.qml23
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.variant.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunctionFail.qml)3
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.js14
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.qml14
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.js15
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.qml14
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameWithBinding.var.qml12
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceObjectGc.var.qml30
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.var.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceSignal.qml)4
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.variant.qml29
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.js (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.js)0
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.js48
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.qml14
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.var.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestMultiple.qml)2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.variant.qml15
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.var.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestPreserve.qml)2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.variant.qml15
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp420
61 files changed, 1606 insertions, 246 deletions
diff --git a/doc/src/declarative/basictypes.qdoc b/doc/src/declarative/basictypes.qdoc
index 98eea78a07..a908e73ca8 100644
--- a/doc/src/declarative/basictypes.qdoc
+++ b/doc/src/declarative/basictypes.qdoc
@@ -479,6 +479,19 @@
}
\endqml
+ A \c var type property can also hold an image or pixmap.
+ A \c var which contains a QPixmap or QImage is known as a
+ "scarce resource" and the declarative engine will attempt to
+ automatically release such resources after evaluation of any JavaScript
+ expression which requires one to be copied has completed.
+
+ Clients may explicitly release such a scarce resource by calling the
+ "destroy" method on the \c var property from within JavaScript. They
+ may also explicitly preserve the scarce resource by calling the
+ "preserve" method on the \c var property from within JavaScript.
+ For more information regarding the usage of a scarce resource, please
+ see \l{Scarce Resources in JavaScript}.
+
\sa {QML Basic Types}
*/
diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc
index a9e383c258..34a1986db6 100644
--- a/doc/src/declarative/javascriptblocks.qdoc
+++ b/doc/src/declarative/javascriptblocks.qdoc
@@ -362,7 +362,7 @@ Item {
\section1 Scarce Resources in JavaScript
-As described in the documentation for \l{QML Basic Types}, a \c variant type
+As described in the documentation for \l{QML Basic Types}, a \c var type
property may hold a "scarce resource" (image or pixmap). There are several
important semantics of scarce resources which should be noted:
@@ -379,30 +379,12 @@ may be necessary for clients to manually preserve or destroy resources for
themselves.
For the following examples, imagine that we have defined the following class:
-\code
-class AvatarExample : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QPixmap avatar READ avatar WRITE setAvatar NOTIFY avatarChanged)
-public:
- AvatarExample(QObject *parent = 0) : QObject(parent), m_value(100, 100) { m_value.fill(Qt::blue); }
- ~AvatarExample() {}
-
- QPixmap avatar() const { return m_value; }
- void setAvatar(QPixmap v) { m_value = v; emit avatarChanged(); }
-
-signals:
- void avatarChanged();
-
-private:
- QPixmap m_value;
-};
-\endcode
+
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.h 0
and that we have registered it with the QML type-system as follows:
-\code
-qmlRegisterType<AvatarExample>("Qt.example", 1, 0, "AvatarExample");
-\endcode
+
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.cpp 0
The AvatarExample class has a property which is a pixmap. When the property
is accessed in JavaScript scope, a copy of the resource will be created and
@@ -414,141 +396,59 @@ unless the client explicitly preserves it.
\section2 Example One: Automatic Release
-In this example, the resource will be automatically
+In the following example, the scarce resource will be automatically released
+after the binding evaluation is complete.
+
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleOne.qml 0
+
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.cpp 1
+
+\section2 Example Two: Automatic Release Prevented By Reference
+
+In this example, the resource will not be automatically
released after the binding expression evaluation is
-complete.
+complete, because there is a property var referencing the
+scarce resource.
-\qml
-// exampleOne.qml
-import QtQuick 1.0
-import Qt.example 1.0
-
-QtObject {
- property AvatarExample a;
- a: AvatarExample { id: example }
- property variant avatar: example.avatar
-}
-\endqml
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleTwo.qml 0
-\code
-QDeclarativeComponent component(&engine, "exampleOne.qml");
-QObject *object = component.create();
-// The scarce resource will have been released automatically
-// after the binding expression was evaluated.
-// Since the scarce resource was not released explicitly prior
-// to the binding expression being evaluated, we get the
-// expected result:
-//object->property("scarceResourceCopy").isValid() == true
-delete object;
-\endcode
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.cpp 2
-\section2 Example Two: Explicit Preservation
+\section2 Example Three: Explicit Preservation
In this example, the resource must be explicitly preserved in order
to prevent the declarative engine from automatically releasing the
resource after evaluation of the imported script.
-\code
-// exampleTwo.js
-.import Qt.example 1.0 as QtExample
-
-var component = Qt.createComponent("exampleOne.qml");
-var exampleOneElement = component.createObject(null);
-var avatarExample = exampleOneElement.a;
-var retn = avatarExample.avatar;
-
-// without the following call, the scarce resource held
-// by retn would be automatically released by the engine
-// after the import statement in exampleTwo.qml, prior
-// to the variable assignment.
-retn.preserve();
-
-function importAvatar() {
- return retn;
-}
-\endcode
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleThree.js 0
-\qml
-// exampleTwo.qml
-import QtQuick 1.0
-import Qt.example 1.0
-import "exampleTwo.js" as ExampleTwoJs
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleThree.qml 0
-QtObject {
- property variant avatar: ExampleTwoJs.importAvatar()
-}
-\endqml
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.cpp 3
-\code
-QDeclarativeComponent component(&engine, "exampleTwo.qml");
-QObject *object = component.create();
-// The resource was preserved explicitly during evaluation of the
-// JavaScript expression. Thus, during property assignment, the
-// scarce resource was still valid, and so we get the expected result:
-//object->property("avatar").isValid() == true
-// The scarce resource may not have been cleaned up by the JS GC yet;
-// it will continue to consume system resources until the JS GC runs.
-delete object;
-\endcode
-
-\section2 Example Three: Explicit Destruction
+\section2 Example Four: Explicit Destruction
In the following example, we release (via destroy()) an explicitly preserved
scarce resource variant. This example shows how a client may free system
resources by releasing the scarce resource held in a JavaScript object, if
required, during evaluation of a JavaScript expression.
-\code
-// exampleThree.js
-.import Qt.example 1.0 as QtExample
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFour.js 0
-var component = Qt.createComponent("exampleOne.qml");
-var exampleOneElement = component.createObject(null);
-var avatarExample = exampleOneElement.a;
-var retn = avatarExample.avatar;
-retn.preserve();
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFour.qml 0
-function importAvatar() {
- return retn;
-}
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.cpp 4
-function releaseAvatar() {
- retn.destroy();
-}
-\endcode
+\section2 Example Five: Explicit Destruction And JavaScript References
-\qml
-// exampleThree.qml
-import QtQuick 1.0
-import Qt.example 1.0
-import "exampleThree.js" as ExampleThreeJs
-
-QtObject {
- property variant avatarOne
- property variant avatarTwo
-
- Component.onCompleted: {
- avatarOne = ExampleThreeJs.importAvatar(); // valid at this stage
- ExampleThreeJs.releaseAvatar(); // explicit release
- avatarTwo = ExampleThreeJs.importAvatar(); // invalid at this stage
- }
-}
-\endqml
+One thing to be aware of when using "var" type properties is that they
+hold references to JavaScript objects. As such, if multiple references
+to one scarce resource is held, and the client calls destroy() on one
+of those references (to explicitly release the scarce resource), all of
+the references will be affected.
-\code
-QDeclarativeComponent component(&engine, "exampleThree.qml");
-QObject *object = component.create();
-// The scarce resource was explicitly preserved by the client during
-// the evaluation of the imported script, and so the scarce resource
-// remains valid until the explicit call to releaseAvatar(). As such,
-// we get the expected results:
-//object->property("avatarOne").isValid() == true
-//object->property("avatarTwo").isValid() == false
-// Because the scarce resource was released explicitly, it will no longer
-// be consuming any system resources (beyond what a normal JS Object would;
-// that small overhead will exist until the JS GC runs, as per any other
-// JavaScript object).
-delete object;
-\endcode
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFive.qml 0
+
+\snippet doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.cpp 5
*/
diff --git a/doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.cpp b/doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.cpp
new file mode 100644
index 0000000000..eb521e1e7e
--- /dev/null
+++ b/doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "avatarExample.h"
+#include <QDeclarativeEngine>
+#include <QDeclarativeComponent>
+
+void registerTypes()
+{
+//![0]
+ qmlRegisterType<AvatarExample>("Qt.example", 1, 0, "AvatarExample");
+//![0]
+}
+
+void expectOne()
+{
+//![1]
+QDeclarativeComponent component(&engine, "exampleOne.qml");
+QObject *object = component.create();
+// The scarce resource will have been released automatically
+// by this point, after the binding expression was evaluated.
+delete object;
+//![1]
+}
+
+void expectTwo()
+{
+//![2]
+QDeclarativeComponent component(&engine, "exampleTwo.qml");
+QObject *object = component.create();
+// The scarce resource will not have been released automatically
+// after the binding expression was evaluated.
+// Since the scarce resource was not released explicitly prior
+// to the binding expression being evaluated, we get:
+bool expectedResult = (object->property("avatar").isValid() == true);
+delete object;
+//![2]
+}
+
+void expectThree()
+{
+//![3]
+QDeclarativeComponent component(&engine, "exampleThree.qml");
+QObject *object = component.create();
+// The resource was preserved explicitly during evaluation of the
+// JavaScript expression. Thus, during property assignment, the
+// scarce resource was still valid, and so we get:
+bool expectedResult = (object->property("avatar").isValid() == true);
+// The scarce resource will not be released until all references to
+// the resource are released, and the JavaScript garbage collector runs.
+delete object;
+//![3]
+}
+
+void expectFour()
+{
+//![4]
+QDeclarativeComponent component(&engine, "exampleFour.qml");
+QObject *object = component.create();
+// The scarce resource was explicitly preserved by the client during
+// the importAvatar() function, and so the scarce resource
+// remains valid until the explicit call to releaseAvatar(). As such,
+// we get the expected results:
+bool expectedResultOne = (object->property("avatarOne").isValid() == true);
+bool expectedResultTwo = (object->property("avatarTwo").isValid() == false);
+// Because the scarce resource referenced by avatarTwo was released explicitly,
+// it will no longer be consuming any system resources (beyond what a normal
+// JS Object would; that small overhead will exist until the JS GC runs, as per
+// any other JavaScript object).
+delete object;
+//![4]
+}
+
+void expectFive()
+{
+//![5]
+QDeclarativeComponent component(&engine, "exampleFive.qml");
+QObject *object = component.create();
+// We have the expected results:
+bool expectedResultOne = (object->property("avatarOne").isValid() == false);
+bool expectedResultTwo = (object->property("avatarTwo").isValid() == false);
+// Because although only avatarTwo was explicitly released,
+// avatarOne and avatarTwo were referencing the same
+// scarce resource.
+delete object;
+//![5]
+}
diff --git a/doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.h b/doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.h
new file mode 100644
index 0000000000..17cef5e5cd
--- /dev/null
+++ b/doc/src/snippets/declarative/integrating-javascript/scarceresources/avatarExample.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AVATAREXAMPLE_P_H
+#define AVATAREXAMPLE_P_H
+
+#include <QObject>
+#include <QPixmap>
+
+//![0]
+// avatarExample.h
+class AvatarExample : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QPixmap avatar READ avatar WRITE setAvatar NOTIFY avatarChanged)
+public:
+ AvatarExample(QObject *parent = 0)
+ : QObject(parent), m_value(100, 100)
+ {
+ m_value.fill(Qt::blue);
+ }
+
+ ~AvatarExample() {}
+
+ QPixmap avatar() const { return m_value; }
+ void setAvatar(QPixmap v) { m_value = v; emit avatarChanged(); }
+
+signals:
+ void avatarChanged();
+
+private:
+ QPixmap m_value;
+};
+//![0]
+
+#endif
diff --git a/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFive.qml b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFive.qml
new file mode 100644
index 0000000000..33326b744d
--- /dev/null
+++ b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFive.qml
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+// exampleFive.qml
+import QtQuick 2.0
+import Qt.example 1.0
+import "exampleFour.js" as ExampleFourJs // use factory from example four
+
+QtObject {
+ property var avatarOne: ExampleFourJs.importAvatar()
+ property var avatarTwo: avatarOne
+
+ Component.onCompleted: {
+ ExampleFourJs.releaseAvatar(avatarTwo);
+ }
+}
+//![0] \ No newline at end of file
diff --git a/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFour.js b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFour.js
new file mode 100644
index 0000000000..476e03fdf8
--- /dev/null
+++ b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFour.js
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+// exampleFour.js
+.import Qt.example 1.0 as QtExample
+
+function importAvatar() {
+ var component = Qt.createComponent("exampleTwo.qml");
+ var exampleOneElement = component.createObject(null);
+ var avatarExample = exampleOneElement.a;
+ var retn = avatarExample.avatar;
+ retn.preserve();
+ return retn;
+}
+
+function releaseAvatar(avatar) {
+ avatar.destroy();
+}
+//![0] \ No newline at end of file
diff --git a/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFour.qml b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFour.qml
new file mode 100644
index 0000000000..e423771a20
--- /dev/null
+++ b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleFour.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+// exampleFour.qml
+import QtQuick 2.0
+import Qt.example 1.0
+import "exampleFour.js" as ExampleFourJs
+
+QtObject {
+ property var avatarOne
+ property var avatarTwo
+
+ Component.onCompleted: {
+ avatarOne = ExampleFourJs.importAvatar();
+ avatarTwo = ExampleFourJs.importAvatar();
+ ExampleFourJs.releaseAvatar(avatarTwo);
+ }
+}
+//![0] \ No newline at end of file
diff --git a/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleOne.qml b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleOne.qml
new file mode 100644
index 0000000000..c8579b7c6c
--- /dev/null
+++ b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleOne.qml
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+// exampleOne.qml
+import QtQuick 1.0
+import Qt.example 1.0
+
+QtObject {
+ property AvatarExample a;
+ a: AvatarExample { id: example }
+ property var avatarWidth: example.avatar,100
+ // Here, we use "example.avatar,100" purely for illustration.
+ // The value of `avatarWidth' will be 100 after evaluation.
+ // E.g., you could imagine some js function which takes
+ // an avatar, and returns the width of the avatar.
+}
+//![0] \ No newline at end of file
diff --git a/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleThree.js b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleThree.js
new file mode 100644
index 0000000000..4fefb1e3f7
--- /dev/null
+++ b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleThree.js
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+// exampleThree.js
+.import Qt.example 1.0 as QtExample
+
+var component = Qt.createComponent("exampleTwo.qml");
+var exampleOneElement = component.createObject(null);
+var avatarExample = exampleOneElement.a;
+var retn = avatarExample.avatar;
+
+// without the following call, the scarce resource held
+// by retn would be automatically released by the engine
+// after the import statement in exampleTwo.qml, prior
+// to the variable assignment.
+retn.preserve();
+
+function importAvatar() {
+ return retn;
+}
+//![0] \ No newline at end of file
diff --git a/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleThree.qml b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleThree.qml
new file mode 100644
index 0000000000..58382902c8
--- /dev/null
+++ b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleThree.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+// exampleThree.qml
+import QtQuick 1.0
+import Qt.example 1.0
+import "exampleThree.js" as ExampleThreeJs
+
+QtObject {
+ property var avatar: ExampleThreeJs.importAvatar()
+}
+//![0] \ No newline at end of file
diff --git a/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleTwo.qml b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleTwo.qml
new file mode 100644
index 0000000000..610a75b97f
--- /dev/null
+++ b/doc/src/snippets/declarative/integrating-javascript/scarceresources/exampleTwo.qml
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+// exampleTwo.qml
+import QtQuick 1.0
+import Qt.example 1.0
+
+QtObject {
+ property AvatarExample a;
+ a: AvatarExample { id: example }
+ property var avatar: example.avatar
+ // Now `avatar' contains a reference to the scarce resource.
+}
+//![0] \ No newline at end of file
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
index 229a93b961..0ff6ad581c 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp
@@ -50,6 +50,8 @@
#include "qdeclarativebinding_p.h"
#include "qdeclarativepropertyvalueinterceptor_p.h"
+#include <private/qv8variantresource_p.h>
+
Q_DECLARE_METATYPE(QJSValue);
QT_BEGIN_NAMESPACE
@@ -819,8 +821,28 @@ QVariant QDeclarativeVMEMetaObject::readPropertyAsVariant(int id)
void QDeclarativeVMEMetaObject::writeVarProperty(int id, v8::Handle<v8::Value> value)
{
Q_ASSERT(id >= firstVarPropertyIndex);
-
ensureVarPropertiesAllocated();
+
+ // Importantly, if the current value is a scarce resource, we need to ensure that it
+ // gets automatically released by the engine if no other references to it exist.
+ v8::Local<v8::Value> oldv = varProperties->Get(id - firstVarPropertyIndex);
+ if (oldv->IsObject()) {
+ QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(oldv));
+ if (r) {
+ r->removeVmePropertyReference();
+ }
+ }
+
+ // And, if the new value is a scarce resource, we need to ensure that it does not get
+ // automatically released by the engine until no other references to it exist.
+ if (value->IsObject()) {
+ QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(value));
+ if (r) {
+ r->addVmePropertyReference();
+ }
+ }
+
+ // Write the value and emit change signal as appropriate.
varProperties->Set(id - firstVarPropertyIndex, value);
activate(object, methodOffset + id, 0);
}
@@ -829,8 +851,30 @@ void QDeclarativeVMEMetaObject::writeProperty(int id, const QVariant &value)
{
if (id >= firstVarPropertyIndex) {
ensureVarPropertiesAllocated();
+
+ // Importantly, if the current value is a scarce resource, we need to ensure that it
+ // gets automatically released by the engine if no other references to it exist.
+ v8::Local<v8::Value> oldv = varProperties->Get(id - firstVarPropertyIndex);
+ if (oldv->IsObject()) {
+ QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(oldv));
+ if (r) {
+ r->removeVmePropertyReference();
+ }
+ }
+
+ // And, if the new value is a scarce resource, we need to ensure that it does not get
+ // automatically released by the engine until no other references to it exist.
+ v8::Handle<v8::Value> newv = QDeclarativeEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value);
+ if (newv->IsObject()) {
+ QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(newv));
+ if (r) {
+ r->addVmePropertyReference();
+ }
+ }
+
+ // Write the value and emit change signal as appropriate.
QVariant currentValue = readPropertyAsVariant(id);
- varProperties->Set(id - firstVarPropertyIndex, QDeclarativeEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value));
+ varProperties->Set(id - firstVarPropertyIndex, newv);
if ((currentValue.userType() != value.userType() || currentValue != value))
activate(object, methodOffset + id, 0);
} else {
diff --git a/src/declarative/qml/v8/qv8variantresource_p.h b/src/declarative/qml/v8/qv8variantresource_p.h
new file mode 100644
index 0000000000..d1a5f92696
--- /dev/null
+++ b/src/declarative/qml/v8/qv8variantresource_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QV8VARIANTRESOURCE_P_H
+#define QV8VARIANTRESOURCE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <private/qv8_p.h>
+#include <private/qv8engine_p.h>
+#include <private/qdeclarativeengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QV8VariantResource : public QV8ObjectResource,
+ public QDeclarativeEnginePrivate::ScarceResourceData
+{
+ V8_RESOURCE_TYPE(VariantType)
+
+public:
+ QV8VariantResource(QV8Engine *engine, const QVariant &data);
+
+ void addVmePropertyReference();
+ void removeVmePropertyReference();
+
+ bool m_isScarceResource;
+ int m_vmePropertyReferenceCount;
+};
+
+QT_END_NAMESPACE
+
+#endif // QV8VARIANTRESOURCE_P_H
+
diff --git a/src/declarative/qml/v8/qv8variantwrapper.cpp b/src/declarative/qml/v8/qv8variantwrapper.cpp
index 671e4d33c3..28bcccbaab 100644
--- a/src/declarative/qml/v8/qv8variantwrapper.cpp
+++ b/src/declarative/qml/v8/qv8variantwrapper.cpp
@@ -40,22 +40,35 @@
****************************************************************************/
#include "qv8variantwrapper_p.h"
+#include "qv8variantresource_p.h"
#include "qv8engine_p.h"
#include <private/qdeclarativeengine_p.h>
QT_BEGIN_NAMESPACE
-class QV8VariantResource : public QV8ObjectResource,
- public QDeclarativeEnginePrivate::ScarceResourceData
+QV8VariantResource::QV8VariantResource(QV8Engine *engine, const QVariant &data)
+: QV8ObjectResource(engine), QDeclarativeEnginePrivate::ScarceResourceData(data), m_isScarceResource(false), m_vmePropertyReferenceCount(0)
{
- V8_RESOURCE_TYPE(VariantType);
-public:
- QV8VariantResource(QV8Engine *engine, const QVariant &data);
-};
+}
-QV8VariantResource::QV8VariantResource(QV8Engine *engine, const QVariant &data)
-: QV8ObjectResource(engine), QDeclarativeEnginePrivate::ScarceResourceData(data)
+void QV8VariantResource::addVmePropertyReference()
+{
+ if (m_isScarceResource && ++m_vmePropertyReferenceCount == 1) {
+ // remove from the ep->scarceResources list
+ // since it is now no longer eligible to be
+ // released automatically by the engine.
+ node.remove();
+ }
+}
+
+void QV8VariantResource::removeVmePropertyReference()
{
+ if (m_isScarceResource && --m_vmePropertyReferenceCount == 0) {
+ // and add to the ep->scarceResources list
+ // since it is now eligible to be released
+ // automatically by the engine.
+ QDeclarativeEnginePrivate::get(engine->engine())->scarceResources.insert(this);
+ }
}
QV8VariantWrapper::QV8VariantWrapper()
@@ -133,6 +146,7 @@ v8::Local<v8::Object> QV8VariantWrapper::newVariant(const QVariant &value)
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(m_engine->engine());
Q_ASSERT(ep->scarceResourcesRefCount);
rv = m_scarceConstructor->NewInstance();
+ r->m_isScarceResource = true;
ep->scarceResources.insert(r);
} else {
rv = m_constructor->NewInstance();
diff --git a/src/declarative/qml/v8/v8.pri b/src/declarative/qml/v8/v8.pri
index 924602ec39..e3488cd1e5 100644
--- a/src/declarative/qml/v8/v8.pri
+++ b/src/declarative/qml/v8/v8.pri
@@ -16,6 +16,7 @@ HEADERS += \
$$PWD/qv8typewrapper_p.h \
$$PWD/qv8listwrapper_p.h \
$$PWD/qv8variantwrapper_p.h \
+ $$PWD/qv8variantresource_p.h \
$$PWD/qv8valuetypewrapper_p.h \
$$PWD/qv8include_p.h \
$$PWD/qv8worker_p.h \
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVar.qml b/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVar.qml
new file mode 100644
index 0000000000..d56bd41a99
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVar.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ property var scarceResourceCopy
+ property int width: 5
+ signal testSignal
+ signal testSignal2
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/ScarceResourceSignalComponent.qml b/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVariant.qml
index e10fcfe36a..e10fcfe36a 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/ScarceResourceSignalComponent.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVariant.qml
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceVarComponent.qml b/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceVarComponent.qml
new file mode 100644
index 0000000000..2cf6b4223b
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceVarComponent.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: first
+ property var vp: Item {
+ id: second
+ property MyScarceResourceObject srp;
+ srp: MyScarceResourceObject { id: scarceResourceProvider }
+ property var sr: scarceResourceProvider.scarceResource
+ property var canary: 5
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.var.qml
new file mode 100644
index 0000000000..805655fc17
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.var.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+// Here we import a scarce resource directly.
+// The instance has a property which is a copy
+// of the scarce resource, so it should not be
+// detached (but we should automatically release
+// the resource from our engine internal list).
+
+QtObject {
+ property MyScarceResourceObject a;
+ a: MyScarceResourceObject { id: scarceResourceProvider }
+ property var scarceResourceCopy: scarceResourceProvider.scarceResource
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopy.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.variant.qml
index ee5b05b28a..ee5b05b28a 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopy.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.variant.qml
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.var.qml
new file mode 100644
index 0000000000..09868e5e7c
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.var.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+import Qt.test 1.0
+import "scarceResourceTest.var.js" as ScarceResourceProviderJs
+
+// Here we import a scarce resource directly, from JS module.
+// It is not preserved or released manually, so it should be
+// automatically released once evaluation of the binding
+// is complete.
+
+QtObject {
+ property MyScarceResourceObject a;
+ a: MyScarceResourceObject { id: scarceResourceProvider }
+ property var scarceResourceCopy: ScarceResourceProviderJs.importScarceResource(scarceResourceProvider)
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyFromJs.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.variant.qml
index 40f6d7bbd6..a1ebeb4073 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyFromJs.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.variant.qml
@@ -1,6 +1,6 @@
import QtQuick 2.0
import Qt.test 1.0
-import "scarceResourceTest.js" as ScarceResourceProviderJs
+import "scarceResourceTest.variant.js" as ScarceResourceProviderJs
// Here we import a scarce resource directly, from JS module.
// It is not preserved or released manually, so it should be
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.js
index bacc50dcc9..468a6b4f2e 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.js
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.js
@@ -6,7 +6,7 @@
// resource would automatically be released after import completes
// but before the binding is evaluated.
-var component = Qt.createComponent("scarceResourceCopy.qml");
+var component = Qt.createComponent("scarceResourceCopy.var.qml");
var scarceResourceElement = component.createObject(null);
var scarceResourceProvider = scarceResourceElement.a;
var retn = scarceResourceProvider.scarceResource;
@@ -22,3 +22,4 @@ function importScarceResource() {
function destroyScarceResource() {
retn.destroy();
}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.qml
new file mode 100644
index 0000000000..9321481f45
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.0
+import Qt.test 1.0
+import "scarceResourceCopyImport.var.js" as ScarceResourceCopyImportJs
+
+QtObject {
+ // this binding is evaluated once, prior to the resource being released
+ property var scarceResourceImportedCopy: ScarceResourceCopyImportJs.importScarceResource()
+
+ property bool arePropertiesEqual
+ property var scarceResourceAssignedCopyOne;
+ property var scarceResourceAssignedCopyTwo;
+ Component.onCompleted: {
+ scarceResourceAssignedCopyOne = ScarceResourceCopyImportJs.importScarceResource();
+ arePropertiesEqual = (scarceResourceAssignedCopyOne == scarceResourceImportedCopy);
+ ScarceResourceCopyImportJs.destroyScarceResource(); // makes all properties invalid.
+ scarceResourceAssignedCopyTwo = ScarceResourceCopyImportJs.importScarceResource();
+ }
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.js
new file mode 100644
index 0000000000..9aeb507487
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.js
@@ -0,0 +1,25 @@
+.import Qt.test 1.0 as JsQtTest
+
+// In this case, the "retn" variable will be evaluated during import.
+// Since the "importScarceResource()" function depends on this variable,
+// we must explicitly preserve the "retn" variable or the scarce
+// resource would automatically be released after import completes
+// but before the binding is evaluated.
+
+var component = Qt.createComponent("scarceResourceCopy.variant.qml");
+var scarceResourceElement = component.createObject(null);
+var scarceResourceProvider = scarceResourceElement.a;
+var retn = scarceResourceProvider.scarceResource;
+retn.preserve(); // must preserve manually or it will be released!
+
+function importScarceResource() {
+ // if called prior to calling destroyScarceResource(),
+ // this function should return the preserved scarce resource.
+ // otherwise, it should return an invalid variant.
+ return retn;
+}
+
+function destroyScarceResource() {
+ retn.destroy();
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.qml
index 08acc1b694..e8b53979dd 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.qml
@@ -1,10 +1,10 @@
import QtQuick 2.0
import Qt.test 1.0
-import "scarceResourceCopyImport.js" as ScarceResourceCopyImportJs
+import "scarceResourceCopyImport.variant.js" as ScarceResourceCopyImportJs
QtObject {
// this binding is evaluated once, prior to the resource being released
- property variant scarceResourceCopy: ScarceResourceCopyImportJs.importScarceResource()
+ property variant scarceResourceImportedCopy: ScarceResourceCopyImportJs.importScarceResource()
// this code is evaluated on completion, and so copy one should be valid, copy two invalid.
property variant scarceResourceAssignedCopyOne;
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.js
new file mode 100644
index 0000000000..000eeddb34
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.js
@@ -0,0 +1,19 @@
+.import Qt.test 1.0 as JsQtTest
+
+// In this case, we create the returned scarce resource each call,
+// so the object will be different every time it is returned.
+
+var mostRecent
+
+function importScarceResource() {
+ var component = Qt.createComponent("scarceResourceCopy.var.qml");
+ var scarceResourceElement = component.createObject(null);
+ var scarceResourceProvider = scarceResourceElement.a;
+ var retn = scarceResourceProvider.scarceResource;
+ mostRecent = retn;
+ return retn;
+}
+
+function destroyScarceResource() {
+ mostRecent.destroy();
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.qml
new file mode 100644
index 0000000000..082d132c24
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+import Qt.test 1.0
+import "scarceResourceCopyImportDifferent.var.js" as ScarceResourceCopyImportJs
+
+// in this case, the ScarceResourceCopyImportJs returns a _new_, different
+// scarce resource each time. Invalidating one will not invalidate the others.
+
+QtObject {
+ // this binding is evaluated once, prior to the resource being released
+ property var scarceResourceImportedCopy: ScarceResourceCopyImportJs.importScarceResource()
+
+ // the following properties are assigned on component completion.
+ property bool arePropertiesEqual
+ property var scarceResourceAssignedCopyOne;
+ property var scarceResourceAssignedCopyTwo;
+ Component.onCompleted: {
+ scarceResourceAssignedCopyOne = ScarceResourceCopyImportJs.importScarceResource();
+ arePropertiesEqual = (scarceResourceAssignedCopyOne != scarceResourceImportedCopy); // they're not the same object.
+ ScarceResourceCopyImportJs.destroyScarceResource(); // makes the MOST RECENT resource invalid (ie, assignedCopyOne).
+ scarceResourceAssignedCopyTwo = ScarceResourceCopyImportJs.importScarceResource();
+ }
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.js
index 6c495863b5..ba52b323f0 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.js
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.js
@@ -8,7 +8,7 @@
// Thus, "importScarceResource()" will return a released (invalid)
// scarce resource.
-var component = Qt.createComponent("scarceResourceCopy.qml");
+var component = Qt.createComponent("scarceResourceCopy.var.qml");
var scarceResourceElement = component.createObject(null);
var scarceResourceProvider = scarceResourceElement.a;
var retn = scarceResourceProvider.scarceResource;
@@ -16,3 +16,4 @@ var retn = scarceResourceProvider.scarceResource;
function importScarceResource() {
return retn; // should return a released (invalid) scarce resource
}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.qml
new file mode 100644
index 0000000000..a1a3c1d66f
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+import Qt.test 1.0
+import "scarceResourceCopyImportFail.var.js" as ScarceResourceCopyImportFailJs
+
+QtObject {
+ property var scarceResourceCopy: ScarceResourceCopyImportFailJs.importScarceResource()
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.js
new file mode 100644
index 0000000000..b59b5b1fa9
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.js
@@ -0,0 +1,19 @@
+.import Qt.test 1.0 as JsQtTest
+
+// In this case, the "retn" variable will be evaluated during import.
+// Since the importScarceResource() function depends on this variable,
+// because we DO NOT call "retn.preserve()", the scarce resource will
+// be released after the import completes but prior to evaluation of
+// any binding which calls "importScarceResource()".
+// Thus, "importScarceResource()" will return a released (invalid)
+// scarce resource.
+
+var component = Qt.createComponent("scarceResourceCopy.variant.qml");
+var scarceResourceElement = component.createObject(null);
+var scarceResourceProvider = scarceResourceElement.a;
+var retn = scarceResourceProvider.scarceResource;
+
+function importScarceResource() {
+ return retn; // should return a released (invalid) scarce resource
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.qml
index 613d3a8ee8..8f6dcd6603 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.qml
@@ -1,6 +1,6 @@
import QtQuick 2.0
import Qt.test 1.0
-import "scarceResourceCopyImportFail.js" as ScarceResourceCopyImportFailJs
+import "scarceResourceCopyImportFail.variant.js" as ScarceResourceCopyImportFailJs
QtObject {
property variant scarceResourceCopy: ScarceResourceCopyImportFailJs.importScarceResource()
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.js
index 4a5b6b4427..130199f78a 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.js
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.js
@@ -8,7 +8,8 @@
// Thus, "importScarceResource()" will return a released (invalid)
// scarce resource.
-var component = Qt.createComponent("scarceResourceCopyNoBinding.qml");
+var component = Qt.createComponent("scarceResourceCopyNoBinding.var.qml");
var scarceResourceElement = component.createObject(null);
var scarceResourceProvider = scarceResourceElement.a;
var retn = scarceResourceProvider.scarceResource;
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.qml
index 81deec0713..5284b40cc8 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.qml
@@ -2,7 +2,7 @@ import QtQuick 2.0
import Qt.test 1.0
// the following js import doesn't manually preserve or destroy any resources
-import "scarceResourceCopyImportNoBinding.js" as ScarceResourceCopyImportNoBindingJs
+import "scarceResourceCopyImportNoBinding.var.js" as ScarceResourceCopyImportNoBindingJs
QtObject {
// in this case, there is an import but no binding evaluated.
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.js
new file mode 100644
index 0000000000..14a36a19ea
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.js
@@ -0,0 +1,15 @@
+.import Qt.test 1.0 as JsQtTest
+
+// In this case, the "retn" variable will be evaluated during import.
+// Since the importScarceResource() function depends on this variable,
+// because we DO NOT call "retn.preserve()", the scarce resource will
+// be released after the import completes but prior to evaluation of
+// any binding which calls "importScarceResource()".
+// Thus, "importScarceResource()" will return a released (invalid)
+// scarce resource.
+
+var component = Qt.createComponent("scarceResourceCopyNoBinding.variant.qml");
+var scarceResourceElement = component.createObject(null);
+var scarceResourceProvider = scarceResourceElement.a;
+var retn = scarceResourceProvider.scarceResource;
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.qml
new file mode 100644
index 0000000000..826cbe49fc
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+// the following js import doesn't manually preserve or destroy any resources
+import "scarceResourceCopyImportNoBinding.variant.js" as ScarceResourceCopyImportNoBindingJs
+
+QtObject {
+ // in this case, there is an import but no binding evaluated.
+ // nonetheless, any resources which are not preserved, should
+ // be automatically released by the engine.
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyNoBinding.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.var.qml
index 4adef39980..4adef39980 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyNoBinding.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.var.qml
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.variant.qml
new file mode 100644
index 0000000000..4adef39980
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.variant.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+QtObject {
+ // this component doesn't bind any property to a scarce
+ // resource from the scarce resource provider,
+ // so the binding evaluation resource cleanup
+ // codepath shouldn't be activated; so if the resources
+ // are released, it will be due to the import evaluation
+ // resource cleanup codepath being activated correctly.
+ property MyScarceResourceObject a;
+ a: MyScarceResourceObject { id: scarceResourceProvider }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.var.qml
new file mode 100644
index 0000000000..500f5d5bd7
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.var.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+import Qt.test 1.0
+import "scarceResourceTest.var.js" as ScarceResourceProviderJs
+
+// In this case, following the evaluation of the binding,
+// the scarceResourceTest value should be an invalid variant,
+// since the scarce resource will have been released.
+
+QtObject {
+ property MyScarceResourceObject a;
+ a: MyScarceResourceObject { id: scarceResourceProvider }
+ property var scarceResourceCopy: ScarceResourceProviderJs.importReleasedScarceResource(scarceResourceProvider);
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceDestroyedCopy.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.variant.qml
index e47c37aba3..7a3b845247 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceDestroyedCopy.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.variant.qml
@@ -1,6 +1,6 @@
import QtQuick 2.0
import Qt.test 1.0
-import "scarceResourceTest.js" as ScarceResourceProviderJs
+import "scarceResourceTest.variant.js" as ScarceResourceProviderJs
// In this case, following the evaluation of the binding,
// the scarceResourceTest value should be an invalid variant,
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.var.qml
new file mode 100644
index 0000000000..23e4c8d15e
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.var.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+// Here we import a scarce resource directly.
+// The copy is only assigned when retrieveScarceResource()
+// is called, and so should be detached prior to that.
+// The copy should be released when releaseScarceResource()
+// is called, and so should be detached after that.
+
+QtObject {
+ id: root
+ property MyScarceResourceObject a: MyScarceResourceObject { id: scarceResourceProvider }
+ property var scarceResourceCopy;
+
+ function retrieveScarceResource() {
+ root.scarceResourceCopy = scarceResourceProvider.scarceResource;
+ }
+
+ function releaseScarceResource() {
+ root.scarceResourceCopy = null;
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunction.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.variant.qml
index fe3707b5d3..fe3707b5d3 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunction.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.variant.qml
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.var.qml
new file mode 100644
index 0000000000..7b4463773c
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.var.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+// In this example, a common syntax error will only be "caught"
+// when the function is called via:
+// QDeclarativeVMEMetaObject::metaCall->invokeMetaMethod()
+// We would like to ensure that a useful error message is printed.
+
+QtObject {
+ id: root
+ property MyScarceResourceObject a: MyScarceResourceObject { id: scarceResourceProvider }
+ property var scarceResourceCopy;
+ property string srp_name: a.toString();
+
+ function retrieveScarceResource() {
+ root.scarceResourceCopy = scarceResourceProvider.scarceResource(); // common syntax error, should throw exception
+ }
+
+ function releaseScarceResource() {
+ root.scarceResourceCopy = null;
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunctionFail.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.variant.qml
index 38de0ae0aa..45acc53e63 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunctionFail.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.variant.qml
@@ -4,8 +4,7 @@ import Qt.test 1.0
// In this example, a common syntax error will only be "caught"
// when the function is called via:
// QDeclarativeVMEMetaObject::metaCall->invokeMetaMethod()
-// We would like to ensure that a useful error message is printed,
-// rather than having QScriptValue::call() function fail silently.
+// We would like to ensure that a useful error message is printed.
QtObject {
id: root
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.js
new file mode 100644
index 0000000000..217f693456
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.js
@@ -0,0 +1,14 @@
+.import Qt.test 1.0 as JsQtTest
+
+function importScarceResource() {
+ var component = Qt.createComponent("scarceResourceCopy.var.qml");
+ var scarceResourceElement = component.createObject(null);
+ var scarceResourceProvider = scarceResourceElement.a;
+ var retn = scarceResourceProvider.scarceResource;
+ retn.preserve();
+ return retn;
+}
+
+function releaseScarceResource(resource) {
+ resource.destroy();
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.qml
new file mode 100644
index 0000000000..205131661f
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+import Qt.test 1.0
+import "scarceResourceMultipleDifferentNoBinding.var.js" as ScarceResourcesMultipleDifferentNoBinding
+
+QtObject {
+ property var resourceOne
+ property var resourceTwo
+
+ Component.onCompleted: {
+ resourceOne = ScarceResourcesMultipleDifferentNoBinding.importScarceResource();
+ resourceTwo = ScarceResourcesMultipleDifferentNoBinding.importScarceResource();
+ ScarceResourcesMultipleDifferentNoBinding.releaseScarceResource(resourceTwo);
+ }
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.js
new file mode 100644
index 0000000000..5b2494c8e6
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.js
@@ -0,0 +1,15 @@
+.import Qt.test 1.0 as JsQtTest
+
+var component = Qt.createComponent("scarceResourceCopy.var.qml");
+var scarceResourceElement = component.createObject(null);
+var scarceResourceProvider = scarceResourceElement.a;
+var retn = scarceResourceProvider.scarceResource;
+retn.preserve();
+
+function importScarceResource() {
+ return retn;
+}
+
+function releaseScarceResource(resource) {
+ resource.destroy();
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.qml
new file mode 100644
index 0000000000..e7f6d7868f
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+import Qt.test 1.0
+import "scarceResourceMultipleSameNoBinding.var.js" as ScarceResourcesMultipleSameNoBinding
+
+QtObject {
+ property var resourceOne
+ property var resourceTwo
+
+ Component.onCompleted: {
+ resourceOne = ScarceResourcesMultipleSameNoBinding.importScarceResource();
+ resourceTwo = ScarceResourcesMultipleSameNoBinding.importScarceResource();
+ ScarceResourcesMultipleSameNoBinding.releaseScarceResource(resourceTwo);
+ }
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameWithBinding.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameWithBinding.var.qml
new file mode 100644
index 0000000000..34cb97f39c
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameWithBinding.var.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+import Qt.test 1.0
+import "scarceResourceMultipleDifferentNoBinding.var.js" as ScarceResourcesMultipleDifferentNoBinding
+
+QtObject {
+ property var resourceOne: ScarceResourcesMultipleDifferentNoBinding.importScarceResource()
+ property var resourceTwo: resourceOne
+
+ Component.onCompleted: {
+ ScarceResourcesMultipleDifferentNoBinding.releaseScarceResource(resourceTwo);
+ }
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceObjectGc.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceObjectGc.var.qml
new file mode 100644
index 0000000000..7ec98e6619
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceObjectGc.var.qml
@@ -0,0 +1,30 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: testScarce
+
+ property var varProperty
+
+ property var canary: 4
+
+ // constructs an Item which contains a scarce resource.
+ function constructScarceObject() {
+ var retn = 1;
+ var component = Qt.createComponent("ScarceResourceVarComponent.qml");
+ if (component.status == Component.Ready) {
+ retn = component.createObject(null); // has JavaScript ownership
+ }
+ return retn;
+ }
+
+ function assignVarProperty() {
+ varProperty = constructScarceObject();
+ gc();
+ }
+
+ function deassignVarProperty() {
+ varProperty = 2; // causes the original object to be garbage collected.
+ gc(); // image should be detached; ep->sr should be empty!
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceSignal.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.var.qml
index 1d5a39c52d..0b30e88fa8 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceSignal.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.var.qml
@@ -7,8 +7,8 @@ QtObject {
property MyScarceResourceObject a;
a: MyScarceResourceObject { id: scarceResourceProvider }
- property ScarceResourceSignalComponent b;
- b: ScarceResourceSignalComponent {
+ property ScarceResourceSignalComponentVar b;
+ b: ScarceResourceSignalComponentVar {
objectName: "srsc"
onTestSignal: {
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.variant.qml
new file mode 100644
index 0000000000..1011c7e240
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.variant.qml
@@ -0,0 +1,29 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+QtObject {
+ id: root
+
+ property MyScarceResourceObject a;
+ a: MyScarceResourceObject { id: scarceResourceProvider }
+
+ property ScarceResourceSignalComponentVariant b;
+ b: ScarceResourceSignalComponentVariant {
+ objectName: "srsc"
+
+ onTestSignal: {
+ // this signal will be invoked manually in the test.
+ // the scarce resource should be released automatically after evaluation
+ // and since we don't keep a copy of it, the pixmap will be detached.
+ width = (scarceResourceProvider.scarceResource,10)
+ }
+
+ onTestSignal2: {
+ // this signal will be invoked manually in the test.
+ // the scarce resource should be released automatically after evaluation
+ // but since we assign it to a property, the pixmap won't be detached.
+ scarceResourceCopy = scarceResourceProvider.scarceResource
+ }
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.js
index c904eb3564..c904eb3564 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.js
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.js
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.qml
index 1d4e67055e..1d4e67055e 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.qml
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.js
new file mode 100644
index 0000000000..c904eb3564
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.js
@@ -0,0 +1,48 @@
+.import Qt.test 1.0 as JsQtTest
+
+function importScarceResource(scarceResourceProvider) {
+ // the scarce resource should be automatically released
+ // after the binding is evaluated if preserve is not
+ // called.
+ return scarceResourceProvider.scarceResource;
+}
+
+function importPreservedScarceResource(scarceResourceProvider) {
+ // the scarce resource is manually preserved
+ // during the evaluation of the binding.
+ // it should not be released.
+ var scarceResource = scarceResourceProvider.scarceResource;
+ scarceResource.preserve();
+ return scarceResource;
+}
+
+function importReleasedScarceResource(scarceResourceProvider) {
+ // release the scarce resource during the
+ // evaluation of the binding. The returned
+ // variant will therefore be invalid.
+ var scarceResource = scarceResourceProvider.scarceResource;
+ scarceResource.destroy();
+ return scarceResource;
+}
+
+function importPreservedScarceResourceFromMultiple(scarceResourceProvider) {
+ // some scarce resources are manually preserved,
+ // some of them are manually destroyed,
+ // and some are automatically managed.
+ // We return a preserved resource
+ var sr1 = scarceResourceProvider.scarceResource; // preserved/destroyed.
+ sr1.preserve();
+ var sr2 = scarceResourceProvider.scarceResource; // preserved/destroyed
+ sr2.preserve();
+ var sr3 = scarceResourceProvider.scarceResource; // automatic.
+ var sr4 = scarceResourceProvider.scarceResource; // automatic and returned.
+ var sr5 = scarceResourceProvider.scarceResource; // destroyed
+ sr5.destroy();
+ sr2.destroy();
+ var sr6 = scarceResourceProvider.scarceResource; // destroyed
+ var sr7 = scarceResourceProvider.scarceResource; // automatic
+ sr1.destroy();
+ sr6.destroy();
+ return sr4;
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.qml
new file mode 100644
index 0000000000..1d4e67055e
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+// Here we import a scarce resource directly, and use it in a binding.
+// It is not preserved or released manually, so it should be
+// automatically released once evaluation of the binding
+// is complete.
+
+QtObject {
+ property MyScarceResourceObject a;
+ a: MyScarceResourceObject { id: scarceResourceProvider }
+ property int scarceResourceTest: scarceResourceProvider.scarceResource,100 // return 100, but include the scarceResource in the binding to be evaluated.
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestMultiple.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.var.qml
index 9a6ee30ff1..5e6c2d97f9 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestMultiple.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.var.qml
@@ -1,6 +1,6 @@
import QtQuick 2.0
import Qt.test 1.0
-import "scarceResourceTest.js" as ScarceResourceProviderJs
+import "scarceResourceTest.var.js" as ScarceResourceProviderJs
// In this case, multiple scarce resource are explicity preserved
// and then explicitly destroyed, while others are automatically
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.variant.qml
new file mode 100644
index 0000000000..2970bcb26c
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.variant.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+import Qt.test 1.0
+import "scarceResourceTest.variant.js" as ScarceResourceProviderJs
+
+// In this case, multiple scarce resource are explicity preserved
+// and then explicitly destroyed, while others are automatically
+// managed. Since none are manually preserved without subsequently
+// being destroyed, after the evaluation of the binding the
+// scarce resource should be detached.
+
+QtObject {
+ property MyScarceResourceObject a;
+ a: MyScarceResourceObject { id: scarceResourceProvider }
+ property int scarceResourceTest: ScarceResourceProviderJs.importPreservedScarceResourceFromMultiple(scarceResourceProvider), 100
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestPreserve.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.var.qml
index d7a40312ab..9e9495c0fa 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestPreserve.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.var.qml
@@ -1,6 +1,6 @@
import QtQuick 2.0
import Qt.test 1.0
-import "scarceResourceTest.js" as ScarceResourceProviderJs
+import "scarceResourceTest.var.js" as ScarceResourceProviderJs
// In this case, the scarce resource is explicity preserved.
// It should not be automatically released after the evaluation
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.variant.qml
new file mode 100644
index 0000000000..022067beca
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.variant.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+import Qt.test 1.0
+import "scarceResourceTest.variant.js" as ScarceResourceProviderJs
+
+// In this case, the scarce resource is explicity preserved.
+// It should not be automatically released after the evaluation
+// of the binding is complete, but instead will be kept in
+// memory until the JS garbage collector runs.
+
+QtObject {
+ property MyScarceResourceObject a;
+ a: MyScarceResourceObject { id: scarceResourceProvider }
+ property int scarceResourceTest: ScarceResourceProviderJs.importPreservedScarceResource(scarceResourceProvider),100 // return 100, but the resource should be preserved.
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
index 3d50d6ee3d..5e62ec6508 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
@@ -152,6 +152,8 @@ private slots:
void importScripts_data();
void importScripts();
void scarceResources();
+ void scarceResources_data();
+ void scarceResources_other();
void propertyChangeSlots();
void propertyVar_data();
void propertyVar();
@@ -1412,15 +1414,15 @@ void tst_qdeclarativeecmascript::functionErrors()
delete object;
// test that if an exception occurs while invoking js function from cpp, it is reported as expected.
- QDeclarativeComponent componentTwo(&engine, TEST_FILE("scarceresources/scarceResourceFunctionFail.qml"));
+ QDeclarativeComponent componentTwo(&engine, TEST_FILE("scarceResourceFunctionFail.var.qml"));
url = componentTwo.url().toString();
object = componentTwo.create();
QVERIFY(object != 0);
QString srpname = object->property("srp_name").toString();
- warning = url + QLatin1String(":17: TypeError: Property 'scarceResource' of object ") + srpname +
- QLatin1String(" is not a function");
+ warning = url + QLatin1String(":16: TypeError: Property 'scarceResource' of object ") + srpname
+ + QLatin1String(" is not a function");
QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); // we expect a meaningful warning to be printed.
QMetaObject::invokeMethod(object, "retrieveScarceResource");
delete object;
@@ -3197,110 +3199,98 @@ void tst_qdeclarativeecmascript::importScripts()
}
}
-void tst_qdeclarativeecmascript::scarceResources()
+void tst_qdeclarativeecmascript::scarceResources_other()
{
+ /* These tests require knowledge of state, since we test values after
+ performing signal or function invocation. */
+
QPixmap origPixmap(100, 100);
origPixmap.fill(Qt::blue);
-
+ QString srp_name, expectedWarning;
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(&engine);
ScarceResourceObject *eo = 0;
+ QObject *srsc = 0;
QObject *object = 0;
- // in the following three cases, the instance created from the component
- // has a property which is a copy of the scarce resource; hence, the
- // resource should NOT be detached prior to deletion of the object instance,
- // unless the resource is destroyed explicitly.
- QDeclarativeComponent component(&engine, TEST_FILE("scarceresources/scarceResourceCopy.qml"));
- object = component.create();
- QVERIFY(object != 0);
- QVERIFY(object->property("scarceResourceCopy").isValid());
- QCOMPARE(object->property("scarceResourceCopy").value<QPixmap>(), origPixmap);
- QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
+ /* property var semantics */
+
+ // test that scarce resources are handled properly in signal invocation
+ QDeclarativeComponent varComponentTen(&engine, TEST_FILE("scarceResourceSignal.var.qml"));
+ object = varComponentTen.create();
+ srsc = object->findChild<QObject*>("srsc");
+ QVERIFY(srsc);
+ QVERIFY(!srsc->property("scarceResourceCopy").isValid()); // hasn't been instantiated yet.
+ QCOMPARE(srsc->property("width"), QVariant(5)); // default value is 5.
+ eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
+ QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
+ QMetaObject::invokeMethod(srsc, "testSignal");
+ QVERIFY(!srsc->property("scarceResourceCopy").isValid()); // still hasn't been instantiated
+ QCOMPARE(srsc->property("width"), QVariant(10)); // but width was assigned to 10.
eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
- QVERIFY(!eo->scarceResourceIsDetached()); // there are two copies of it in existence: the property of object, and the property of eo.
+ QVERIFY(eo->scarceResourceIsDetached()); // should still be no other copies of it at this stage.
+ QMetaObject::invokeMethod(srsc, "testSignal2"); // assigns scarceResourceCopy to the scarce pixmap.
+ QVERIFY(srsc->property("scarceResourceCopy").isValid());
+ QCOMPARE(srsc->property("scarceResourceCopy").value<QPixmap>(), origPixmap);
+ eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
+ QVERIFY(!(eo->scarceResourceIsDetached())); // should be another copy of the resource now.
+ QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
delete object;
- QDeclarativeComponent componentTwo(&engine, TEST_FILE("scarceresources/scarceResourceCopyFromJs.qml"));
- object = componentTwo.create();
+ // test that scarce resources are handled properly from js functions in qml files
+ QDeclarativeComponent varComponentEleven(&engine, TEST_FILE("scarceResourceFunction.var.qml"));
+ object = varComponentEleven.create();
QVERIFY(object != 0);
- QVERIFY(object->property("scarceResourceCopy").isValid());
+ QVERIFY(!object->property("scarceResourceCopy").isValid()); // not yet assigned, so should not be valid
+ eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
+ QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
+ QMetaObject::invokeMethod(object, "retrieveScarceResource");
+ QVERIFY(object->property("scarceResourceCopy").isValid()); // assigned, so should be valid.
QCOMPARE(object->property("scarceResourceCopy").value<QPixmap>(), origPixmap);
- QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
- QVERIFY(!eo->scarceResourceIsDetached()); // there are two copies of it in existence: the property of object, and the property of eo.
- delete object;
-
- QDeclarativeComponent componentThree(&engine, TEST_FILE("scarceresources/scarceResourceDestroyedCopy.qml"));
- object = componentThree.create();
- QVERIFY(object != 0);
- QVERIFY(!(object->property("scarceResourceCopy").isValid())); // was manually released prior to being returned.
- QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
+ QVERIFY(!eo->scarceResourceIsDetached()); // should be a copy of the resource at this stage.
+ QMetaObject::invokeMethod(object, "releaseScarceResource");
+ QVERIFY(!object->property("scarceResourceCopy").isValid()); // just released, so should not be valid
eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
- QVERIFY(eo->scarceResourceIsDetached()); // should have explicitly been released during the evaluation of the binding.
- delete object;
-
- // in the following three cases, no other copy should exist in memory,
- // and so it should be detached (unless explicitly preserved).
- QDeclarativeComponent componentFour(&engine, TEST_FILE("scarceresources/scarceResourceTest.qml"));
- object = componentFour.create();
- QVERIFY(object != 0);
- QVERIFY(object->property("scarceResourceTest").isValid());
- QCOMPARE(object->property("scarceResourceTest").toInt(), 100);
+ QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
- eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
- QVERIFY(eo->scarceResourceIsDetached()); // the resource should have been released after the binding was evaluated.
delete object;
- QDeclarativeComponent componentFive(&engine, TEST_FILE("scarceresources/scarceResourceTestPreserve.qml"));
- object = componentFive.create();
+ // test that if an exception occurs while invoking js function from cpp, that the resources are released.
+ QDeclarativeComponent varComponentTwelve(&engine, TEST_FILE("scarceResourceFunctionFail.var.qml"));
+ object = varComponentTwelve.create();
QVERIFY(object != 0);
- QVERIFY(object->property("scarceResourceTest").isValid());
- QCOMPARE(object->property("scarceResourceTest").toInt(), 100);
- QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
+ QVERIFY(!object->property("scarceResourceCopy").isValid()); // not yet assigned, so should not be valid
eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
- QVERIFY(!eo->scarceResourceIsDetached()); // this won't be detached since we explicitly preserved it.
- delete object;
-
- QDeclarativeComponent componentSix(&engine, TEST_FILE("scarceresources/scarceResourceTestMultiple.qml"));
- object = componentSix.create();
- QVERIFY(object != 0);
- QVERIFY(object->property("scarceResourceTest").isValid());
- QCOMPARE(object->property("scarceResourceTest").toInt(), 100);
- QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
+ QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
+ srp_name = object->property("srp_name").toString();
+ expectedWarning = varComponentTwelve.url().toString() + QLatin1String(":16: TypeError: Property 'scarceResource' of object ") + srp_name + QLatin1String(" is not a function");
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(expectedWarning)); // we expect a meaningful warning to be printed.
+ QMetaObject::invokeMethod(object, "retrieveScarceResource");
+ QVERIFY(!object->property("scarceResourceCopy").isValid()); // due to exception, assignment will NOT have occurred.
eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
- QVERIFY(eo->scarceResourceIsDetached()); // all resources were released manually or automatically released.
- delete object;
-
- // test that scarce resources are handled correctly for imports
- QDeclarativeComponent componentSeven(&engine, TEST_FILE("scarceresources/scarceResourceCopyImportNoBinding.qml"));
- object = componentSeven.create();
- QVERIFY(object != 0); // the import should have caused the addition of a resource to the ScarceResources list
- QVERIFY(ep->scarceResources.isEmpty()); // but they should have been released by this point.
- delete object;
-
- QDeclarativeComponent componentEight(&engine, TEST_FILE("scarceresources/scarceResourceCopyImportFail.qml"));
- object = componentEight.create();
- QVERIFY(object != 0);
- QVERIFY(!object->property("scarceResourceCopy").isValid()); // wasn't preserved, so shouldn't be valid.
+ QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
delete object;
- QDeclarativeComponent componentNine(&engine, TEST_FILE("scarceresources/scarceResourceCopyImport.qml"));
- object = componentNine.create();
+ // test that if an Item which has JS ownership but has a scarce resource property is garbage collected,
+ // that the scarce resource is removed from the engine's list of scarce resources to clean up.
+ QDeclarativeComponent varComponentThirteen(&engine, TEST_FILE("scarceResourceObjectGc.var.qml"));
+ object = varComponentThirteen.create();
QVERIFY(object != 0);
- QVERIFY(object->property("scarceResourceCopy").isValid()); // preserved, so should be valid.
- QCOMPARE(object->property("scarceResourceCopy").value<QPixmap>(), origPixmap);
- QVERIFY(object->property("scarceResourceAssignedCopyOne").isValid()); // assigned before destroy(), so should be valid.
- QCOMPARE(object->property("scarceResourceAssignedCopyOne").value<QPixmap>(), origPixmap);
- QVERIFY(!object->property("scarceResourceAssignedCopyTwo").isValid()); // assigned after destroy(), so should be invalid.
- QVERIFY(ep->scarceResources.isEmpty()); // this will still be zero, because "preserve()" REMOVES it from this list.
+ QVERIFY(!object->property("varProperty").isValid()); // not assigned yet
+ QMetaObject::invokeMethod(object, "assignVarProperty");
+ QVERIFY(ep->scarceResources.isEmpty()); // the scarce resource is a VME property.
+ QMetaObject::invokeMethod(object, "deassignVarProperty");
+ QVERIFY(ep->scarceResources.isEmpty()); // should still be empty; the resource should have been released on gc.
delete object;
+ /* property variant semantics */
+
// test that scarce resources are handled properly in signal invocation
- QDeclarativeComponent componentTen(&engine, TEST_FILE("scarceresources/scarceResourceSignal.qml"));
- object = componentTen.create();
+ QDeclarativeComponent variantComponentTen(&engine, TEST_FILE("scarceResourceSignal.variant.qml"));
+ object = variantComponentTen.create();
QVERIFY(object != 0);
- QObject *srsc = object->findChild<QObject*>("srsc");
+ srsc = object->findChild<QObject*>("srsc");
QVERIFY(srsc);
QVERIFY(!srsc->property("scarceResourceCopy").isValid()); // hasn't been instantiated yet.
QCOMPARE(srsc->property("width"), QVariant(5)); // default value is 5.
@@ -3320,8 +3310,8 @@ void tst_qdeclarativeecmascript::scarceResources()
delete object;
// test that scarce resources are handled properly from js functions in qml files
- QDeclarativeComponent componentEleven(&engine, TEST_FILE("scarceresources/scarceResourceFunction.qml"));
- object = componentEleven.create();
+ QDeclarativeComponent variantComponentEleven(&engine, TEST_FILE("scarceResourceFunction.variant.qml"));
+ object = variantComponentEleven.create();
QVERIFY(object != 0);
QVERIFY(!object->property("scarceResourceCopy").isValid()); // not yet assigned, so should not be valid
eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
@@ -3339,14 +3329,14 @@ void tst_qdeclarativeecmascript::scarceResources()
delete object;
// test that if an exception occurs while invoking js function from cpp, that the resources are released.
- QDeclarativeComponent componentTwelve(&engine, TEST_FILE("scarceresources/scarceResourceFunctionFail.qml"));
- object = componentTwelve.create();
+ QDeclarativeComponent variantComponentTwelve(&engine, TEST_FILE("scarceResourceFunctionFail.variant.qml"));
+ object = variantComponentTwelve.create();
QVERIFY(object != 0);
QVERIFY(!object->property("scarceResourceCopy").isValid()); // not yet assigned, so should not be valid
eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
- QString srp_name = object->property("srp_name").toString();
- QString expectedWarning = componentTwelve.url().toString() + QLatin1String(":17: TypeError: Property 'scarceResource' of object ") + srp_name + QLatin1String(" is not a function");
+ srp_name = object->property("srp_name").toString();
+ expectedWarning = variantComponentTwelve.url().toString() + QLatin1String(":16: TypeError: Property 'scarceResource' of object ") + srp_name + QLatin1String(" is not a function");
QTest::ignoreMessage(QtWarningMsg, qPrintable(expectedWarning)); // we expect a meaningful warning to be printed.
QMetaObject::invokeMethod(object, "retrieveScarceResource");
QVERIFY(!object->property("scarceResourceCopy").isValid()); // due to exception, assignment will NOT have occurred.
@@ -3356,6 +3346,266 @@ void tst_qdeclarativeecmascript::scarceResources()
delete object;
}
+void tst_qdeclarativeecmascript::scarceResources_data()
+{
+ QTest::addColumn<QUrl>("qmlFile");
+ QTest::addColumn<bool>("readDetachStatus");
+ QTest::addColumn<bool>("expectedDetachStatus");
+ QTest::addColumn<QStringList>("propertyNames");
+ QTest::addColumn<QVariantList>("expectedValidity");
+ QTest::addColumn<QVariantList>("expectedValues");
+ QTest::addColumn<QStringList>("expectedErrors");
+
+ QPixmap origPixmap(100, 100);
+ origPixmap.fill(Qt::blue);
+
+ /* property var semantics */
+
+ // in the following three cases, the instance created from the component
+ // has a property which is a copy of the scarce resource; hence, the
+ // resource should NOT be detached prior to deletion of the object instance,
+ // unless the resource is destroyed explicitly.
+ QTest::newRow("var: import scarce resource copy directly")
+ << TEST_FILE("scarceResourceCopy.var.qml")
+ << true
+ << false // won't be detached, because assigned to property and not explicitly released
+ << (QStringList() << QLatin1String("scarceResourceCopy"))
+ << (QList<QVariant>() << true)
+ << (QList<QVariant>() << origPixmap)
+ << QStringList();
+
+ QTest::newRow("var: import scarce resource copy from JS")
+ << TEST_FILE("scarceResourceCopyFromJs.var.qml")
+ << true
+ << false // won't be detached, because assigned to property and not explicitly released
+ << (QStringList() << QLatin1String("scarceResourceCopy"))
+ << (QList<QVariant>() << true)
+ << (QList<QVariant>() << origPixmap)
+ << QStringList();
+
+ QTest::newRow("var: import released scarce resource copy from JS")
+ << TEST_FILE("scarceResourceDestroyedCopy.var.qml")
+ << true
+ << true // explicitly released, so it will be detached
+ << (QStringList() << QLatin1String("scarceResourceCopy"))
+ << (QList<QVariant>() << false)
+ << (QList<QVariant>() << QVariant())
+ << QStringList();
+
+ // in the following three cases, no other copy should exist in memory,
+ // and so it should be detached (unless explicitly preserved).
+ QTest::newRow("var: import auto-release SR from JS in binding side-effect")
+ << TEST_FILE("scarceResourceTest.var.qml")
+ << true
+ << true // auto released, so it will be detached
+ << (QStringList() << QLatin1String("scarceResourceTest"))
+ << (QList<QVariant>() << true)
+ << (QList<QVariant>() << QVariant(100))
+ << QStringList();
+ QTest::newRow("var: import explicit-preserve SR from JS in binding side-effect")
+ << TEST_FILE("scarceResourceTestPreserve.var.qml")
+ << true
+ << false // won't be detached because we explicitly preserve it
+ << (QStringList() << QLatin1String("scarceResourceTest"))
+ << (QList<QVariant>() << true)
+ << (QList<QVariant>() << QVariant(100))
+ << QStringList();
+ QTest::newRow("var: import explicit-preserve SR from JS in binding side-effect")
+ << TEST_FILE("scarceResourceTestMultiple.var.qml")
+ << true
+ << true // will be detached because all resources were released manually or automatically.
+ << (QStringList() << QLatin1String("scarceResourceTest"))
+ << (QList<QVariant>() << true)
+ << (QList<QVariant>() << QVariant(100))
+ << QStringList();
+
+ // In the following three cases, test that scarce resources are handled
+ // correctly for imports.
+ QTest::newRow("var: import with no binding")
+ << TEST_FILE("scarceResourceCopyImportNoBinding.var.qml")
+ << false // cannot check detach status.
+ << false
+ << QStringList()
+ << QList<QVariant>()
+ << QList<QVariant>()
+ << QStringList();
+ QTest::newRow("var: import with binding without explicit preserve")
+ << TEST_FILE("scarceResourceCopyImportNoBinding.var.qml")
+ << false
+ << false
+ << (QStringList() << QLatin1String("scarceResourceCopy"))
+ << (QList<QVariant>() << false) // will have been released prior to evaluation of binding.
+ << (QList<QVariant>() << QVariant())
+ << QStringList();
+ QTest::newRow("var: import with explicit release after binding evaluation")
+ << TEST_FILE("scarceResourceCopyImport.var.qml")
+ << false
+ << false
+ << (QStringList() << QLatin1String("scarceResourceImportedCopy") << QLatin1String("scarceResourceAssignedCopyOne") << QLatin1String("scarceResourceAssignedCopyTwo") << QLatin1String("arePropertiesEqual"))
+ << (QList<QVariant>() << false << false << false << true) // since property var = JS object reference, by releasing the provider's resource, all handles are invalidated.
+ << (QList<QVariant>() << QVariant() << QVariant() << QVariant() << QVariant(true))
+ << QStringList();
+ QTest::newRow("var: import with different js objects")
+ << TEST_FILE("scarceResourceCopyImportDifferent.var.qml")
+ << false
+ << false
+ << (QStringList() << QLatin1String("scarceResourceAssignedCopyOne") << QLatin1String("scarceResourceAssignedCopyTwo") << QLatin1String("arePropertiesEqual"))
+ << (QList<QVariant>() << false << true << true) // invalidating one shouldn't invalidate the other, because they're not references to the same JS object.
+ << (QList<QVariant>() << QVariant() << QVariant(origPixmap) << QVariant(false))
+ << QStringList();
+ QTest::newRow("var: import with different js objects and explicit release")
+ << TEST_FILE("scarceResourceMultipleDifferentNoBinding.var.qml")
+ << false
+ << false
+ << (QStringList() << QLatin1String("resourceOne") << QLatin1String("resourceTwo"))
+ << (QList<QVariant>() << true << false) // invalidating one shouldn't invalidate the other, because they're not references to the same JS object.
+ << (QList<QVariant>() << QVariant(origPixmap) << QVariant())
+ << QStringList();
+ QTest::newRow("var: import with same js objects and explicit release")
+ << TEST_FILE("scarceResourceMultipleSameNoBinding.var.qml")
+ << false
+ << false
+ << (QStringList() << QLatin1String("resourceOne") << QLatin1String("resourceTwo"))
+ << (QList<QVariant>() << false << false) // invalidating one should invalidate the other, because they're references to the same JS object.
+ << (QList<QVariant>() << QVariant() << QVariant())
+ << QStringList();
+ QTest::newRow("var: binding with same js objects and explicit release")
+ << TEST_FILE("scarceResourceMultipleSameWithBinding.var.qml")
+ << false
+ << false
+ << (QStringList() << QLatin1String("resourceOne") << QLatin1String("resourceTwo"))
+ << (QList<QVariant>() << false << false) // invalidating one should invalidate the other, because they're references to the same JS object.
+ << (QList<QVariant>() << QVariant() << QVariant())
+ << QStringList();
+
+
+ /* property variant semantics */
+
+ // in the following three cases, the instance created from the component
+ // has a property which is a copy of the scarce resource; hence, the
+ // resource should NOT be detached prior to deletion of the object instance,
+ // unless the resource is destroyed explicitly.
+ QTest::newRow("variant: import scarce resource copy directly")
+ << TEST_FILE("scarceResourceCopy.variant.qml")
+ << true
+ << false // won't be detached, because assigned to property and not explicitly released
+ << (QStringList() << QLatin1String("scarceResourceCopy"))
+ << (QList<QVariant>() << true)
+ << (QList<QVariant>() << origPixmap)
+ << QStringList();
+
+ QTest::newRow("variant: import scarce resource copy from JS")
+ << TEST_FILE("scarceResourceCopyFromJs.variant.qml")
+ << true
+ << false // won't be detached, because assigned to property and not explicitly released
+ << (QStringList() << QLatin1String("scarceResourceCopy"))
+ << (QList<QVariant>() << true)
+ << (QList<QVariant>() << origPixmap)
+ << QStringList();
+
+ QTest::newRow("variant: import released scarce resource copy from JS")
+ << TEST_FILE("scarceResourceDestroyedCopy.variant.qml")
+ << true
+ << true // explicitly released, so it will be detached
+ << (QStringList() << QLatin1String("scarceResourceCopy"))
+ << (QList<QVariant>() << false)
+ << (QList<QVariant>() << QVariant())
+ << QStringList();
+
+ // in the following three cases, no other copy should exist in memory,
+ // and so it should be detached (unless explicitly preserved).
+ QTest::newRow("variant: import auto-release SR from JS in binding side-effect")
+ << TEST_FILE("scarceResourceTest.variant.qml")
+ << true
+ << true // auto released, so it will be detached
+ << (QStringList() << QLatin1String("scarceResourceTest"))
+ << (QList<QVariant>() << true)
+ << (QList<QVariant>() << QVariant(100))
+ << QStringList();
+ QTest::newRow("variant: import explicit-preserve SR from JS in binding side-effect")
+ << TEST_FILE("scarceResourceTestPreserve.variant.qml")
+ << true
+ << false // won't be detached because we explicitly preserve it
+ << (QStringList() << QLatin1String("scarceResourceTest"))
+ << (QList<QVariant>() << true)
+ << (QList<QVariant>() << QVariant(100))
+ << QStringList();
+ QTest::newRow("variant: import multiple scarce resources")
+ << TEST_FILE("scarceResourceTestMultiple.variant.qml")
+ << true
+ << true // will be detached because all resources were released manually or automatically.
+ << (QStringList() << QLatin1String("scarceResourceTest"))
+ << (QList<QVariant>() << true)
+ << (QList<QVariant>() << QVariant(100))
+ << QStringList();
+
+ // In the following three cases, test that scarce resources are handled
+ // correctly for imports.
+ QTest::newRow("variant: import with no binding")
+ << TEST_FILE("scarceResourceCopyImportNoBinding.variant.qml")
+ << false // cannot check detach status.
+ << false
+ << QStringList()
+ << QList<QVariant>()
+ << QList<QVariant>()
+ << QStringList();
+ QTest::newRow("variant: import with binding without explicit preserve")
+ << TEST_FILE("scarceResourceCopyImportNoBinding.variant.qml")
+ << false
+ << false
+ << (QStringList() << QLatin1String("scarceResourceCopy"))
+ << (QList<QVariant>() << false) // will have been released prior to evaluation of binding.
+ << (QList<QVariant>() << QVariant())
+ << QStringList();
+ QTest::newRow("variant: import with explicit release after binding evaluation")
+ << TEST_FILE("scarceResourceCopyImport.variant.qml")
+ << false
+ << false
+ << (QStringList() << QLatin1String("scarceResourceImportedCopy") << QLatin1String("scarceResourceAssignedCopyOne") << QLatin1String("scarceResourceAssignedCopyTwo"))
+ << (QList<QVariant>() << true << true << false) // since property variant = variant copy, releasing the provider's resource does not invalidate previously assigned copies.
+ << (QList<QVariant>() << origPixmap << origPixmap << QVariant())
+ << QStringList();
+}
+
+void tst_qdeclarativeecmascript::scarceResources()
+{
+ QFETCH(QUrl, qmlFile);
+ QFETCH(bool, readDetachStatus);
+ QFETCH(bool, expectedDetachStatus);
+ QFETCH(QStringList, propertyNames);
+ QFETCH(QVariantList, expectedValidity);
+ QFETCH(QVariantList, expectedValues);
+ QFETCH(QStringList, expectedErrors);
+
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(&engine);
+ ScarceResourceObject *eo = 0;
+ QObject *object = 0;
+
+ QDeclarativeComponent c(&engine, qmlFile);
+ object = c.create();
+ QVERIFY(object != 0);
+ for (int i = 0; i < propertyNames.size(); ++i) {
+ QString prop = propertyNames.at(i);
+ bool validity = expectedValidity.at(i).toBool();
+ QVariant value = expectedValues.at(i);
+
+ QCOMPARE(object->property(prop.toLatin1().constData()).isValid(), validity);
+ if (value.type() == QVariant::Int) {
+ QCOMPARE(object->property(prop.toLatin1().constData()).toInt(), value.toInt());
+ } else if (value.type() == QVariant::Pixmap) {
+ QCOMPARE(object->property(prop.toLatin1().constData()).value<QPixmap>(), value.value<QPixmap>());
+ }
+ }
+
+ if (readDetachStatus) {
+ eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
+ QCOMPARE(eo->scarceResourceIsDetached(), expectedDetachStatus);
+ }
+
+ QVERIFY(ep->scarceResources.isEmpty());
+ delete object;
+}
+
void tst_qdeclarativeecmascript::propertyChangeSlots()
{
// ensure that allowable property names are allowed and onPropertyNameChanged slots are generated correctly.