aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorChris Adams <christopher.adams@nokia.com>2011-05-10 12:10:06 +1000
committerChris Adams <christopher.adams@nokia.com>2011-05-11 14:26:43 +1000
commit4ff72975b6501a0003329bb8183479d4df5eda4d (patch)
tree9cea160e81cf0a04eb166c67e2807ceb3c7de6a1 /doc
parent67d5026372cf8a7c9319703fc58073910820b740 (diff)
Add user documentation for scarce resource properties
Relates to commit 59ace5c5a666b1588560d2aeaa79a57da535e863. Task-number: QMLNG-18 Reviewed-by: Aaron Kennedy Change-Id: I216ced4c663ebab8003978999dc16ac809443a5f
Diffstat (limited to 'doc')
-rw-r--r--doc/src/declarative/basictypes.qdoc15
-rw-r--r--doc/src/declarative/javascriptblocks.qdoc191
2 files changed, 205 insertions, 1 deletions
diff --git a/doc/src/declarative/basictypes.qdoc b/doc/src/declarative/basictypes.qdoc
index 4792bba6ef..876ab0038a 100644
--- a/doc/src/declarative/basictypes.qdoc
+++ b/doc/src/declarative/basictypes.qdoc
@@ -439,7 +439,20 @@
}
\endqml
- The \c variant type can also hold:
+ A \c variant type property can also hold an image or pixmap.
+ A \c variant 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 variant property from within JavaScript. They
+ may also explicitly preserve the scarce resource by calling the
+ "preserve" method on the \c variant property from within JavaScript.
+ For more information regarding the usage of a scarce resource, please
+ see \l{Scarce Resources in JavaScript}.
+
+ Finally, the \c variant type can also hold:
\list
\o An array of \l {QML Basic Types}{basic type} values
diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc
index 90a91b3acd..984c81a870 100644
--- a/doc/src/declarative/javascriptblocks.qdoc
+++ b/doc/src/declarative/javascriptblocks.qdoc
@@ -359,4 +359,195 @@ Item {
\endlist
+\section1 Scarce Resources in JavaScript
+
+As described in the documentation for \l{QML Basic Types}, a \c variant type
+property may hold a "scarce resource" (image or pixmap). There are several
+important semantics of scarce resources which should be noted:
+
+\list
+\o By default, a scarce resource is automatically released by the declarative engine as soon as evaluation of the expression in which the scarce resource is allocated is complete if there are no other references to the resource
+\o A client may explicitly preserve a scarce resource, which will ensure that the resource will not be released until all references to the resource are released and the JavaScript engine runs its garbage collector
+\o A client may explicitly destroy a scarce resource, which will immediately release the resource
+\endlist
+
+In most cases, allowing the engine to automatically release the resource is
+the correct choice. In some cases, however, this may result in an invalid
+variant being returned from a function in JavaScript, and in those cases it
+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
+
+and that we have registered it with the QML type-system as follows:
+\code
+qmlRegisterType<AvatarExample>("Qt.example", 1, 0, "AvatarExample");
+\endcode
+
+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
+stored in a JavaScript object which can then be used within JavaScript. This
+copy will take up valuable system resources, and so by default the scarce
+resource copy in the JavaScript object will be released automatically by the
+declarative engine once evaluation of the JavaScript expression is complete,
+unless the client explicitly preserves it.
+
+\section2 Example One: Automatic Release
+
+In this example, the resource will be automatically
+released after the binding expression evaluation is
+complete.
+
+\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
+
+\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
+
+\section2 Example Two: 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
+
+\qml
+// exampleTwo.qml
+import QtQuick 1.0
+import Qt.example 1.0
+import "exampleTwo.js" as ExampleTwoJs
+
+QtObject {
+ property variant avatar: ExampleTwoJs.importAvatar()
+}
+\endqml
+
+\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
+
+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
+
+var component = Qt.createComponent("exampleOne.qml");
+var exampleOneElement = component.createObject(null);
+var avatarExample = exampleOneElement.a;
+var retn = avatarExample.avatar;
+retn.preserve();
+
+function importAvatar() {
+ return retn;
+}
+
+function releaseAvatar() {
+ retn.destroy();
+}
+\endcode
+
+\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
+
+\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
+
*/