aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-10-07 13:16:47 +1000
committerQt by Nokia <qt-info@nokia.com>2011-10-12 01:31:11 +0200
commit3422d4adda7480a44a063ab86447c2fe2792fe02 (patch)
tree21cd120a33e7a9df586f45896d50b5688fdbc782
parent6fcaca378b84ada546dc62d72a53a71d0da86ef9 (diff)
Component.incubateObject() autotest
Change-Id: I37f76d5b273ae4f032c4de5ac8fcbff4204b78fe Reviewed-on: http://codereview.qt-project.org/6200 Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com> Sanity-Review: Aaron Kennedy <aaron.kennedy@nokia.com>
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp61
-rw-r--r--tests/auto/declarative/qdeclarativecomponent/data/incubateObject.qml36
-rw-r--r--tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp35
3 files changed, 127 insertions, 5 deletions
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index 8aeeb78a56..eafe8539df 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -1052,6 +1052,57 @@ void QDeclarativeComponent::createObject(QDeclarativeV8Function *args)
args->returnValue(object);
}
+/*!
+ \qmlmethod object Component::incubateObject(Item parent, object properties, enum mode)
+
+ Creates an incubator for instance of this component. Incubators allow new component
+ instances to be instantiated asynchronously and not cause freezes in the UI.
+
+ The \a parent argument specifies the parent the created instance will have. Omitting the
+ parameter or passing null will create anobject with no parent. In this case, a reference
+ to the created object must be maintained by the application of the object will eventually
+ be garbage collected.
+
+ The \a properties argument is specified as a map of property-value items which will be
+ set on the created object during its construction. \a mode may be Qt.Synchronous or
+ Qt.Asynchronous and controls whether the instance is created synchronously or asynchronously.
+ The default is asynchronously. In some circumstances, even if Qt.Synchronous is specified,
+ the incubator may create the object asynchronously. This happens if the component calling
+ incubateObject() is itself being created asynchronously.
+
+ All three arguments are optional.
+
+ If successful, the method returns an incubator, otherwise null. The incubator has the following
+ properties:
+
+ \list
+ \i status The status of the incubator. Valid values are Component.Ready, Component.Loading and
+ Component.Error.
+ \i object The created object instance. Will only be available once the incubator is in the
+ Ready status.
+ \i onStatusChanged Specifies a callback function to be invoked when the status changes. The
+ status is passed as a parameter to the callback.
+ \i forceCompletion() Call to complete incubation synchronously.
+ \endlist
+
+ The following example demonstrates how to use an incubator:
+
+ \js
+ var component = Qt.createComponent("Button.qml");
+
+ var incubator = component.incubateObject(parent, { x: 10, y: 10 });
+ if (incubator.status != Component.Ready) {
+ incubator.onStatusChanged = function(status) {
+ if (status == Component.Ready) {
+ print ("Object", incubator.object, "is now ready!");
+ }
+ }
+ } else {
+ print ("Object", incubator.object, "is ready immediately!");
+ }
+ \endjs
+*/
+
void QDeclarativeComponent::incubateObject(QDeclarativeV8Function *args)
{
Q_D(QDeclarativeComponent);
@@ -1067,12 +1118,14 @@ void QDeclarativeComponent::incubateObject(QDeclarativeV8Function *args)
if (args->Length() >= 2) {
v8::Local<v8::Value> v = (*args)[1];
- if (!v->IsObject() || v->IsArray()) {
+ if (v->IsNull()) {
+ } else if (!v->IsObject() || v->IsArray()) {
qmlInfo(this) << tr("createObject: value is not an object");
args->returnValue(v8::Null());
return;
+ } else {
+ valuemap = v8::Local<v8::Object>::Cast(v);
}
- valuemap = v8::Local<v8::Object>::Cast(v);
}
if (args->Length() >= 3) {
@@ -1159,7 +1212,7 @@ QDeclarativeComponentExtension::QDeclarativeComponentExtension(QV8Engine *engine
#define INITIALPROPERTIES_SOURCE \
"(function(object, values) {"\
"try {"\
- "for(var property in values) {"\
+ "for(var property in values) {" \
"try {"\
"var properties = property.split(\".\");"\
"var o = object;"\
@@ -1242,7 +1295,7 @@ void QV8IncubatorResource::setInitialState(QObject *o)
v8::Context::Scope scope(engine->context());
v8::Handle<v8::Value> function = e->initialProperties->Run(qmlGlobal);
- v8::Handle<v8::Value> args[] = { me, valuemap };
+ v8::Handle<v8::Value> args[] = { engine->newQObject(o), valuemap };
v8::Handle<v8::Function>::Cast(function)->Call(engine->global(), 2, args);
qPersistentDispose(valuemap);
diff --git a/tests/auto/declarative/qdeclarativecomponent/data/incubateObject.qml b/tests/auto/declarative/qdeclarativecomponent/data/incubateObject.qml
new file mode 100644
index 0000000000..c11319db30
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativecomponent/data/incubateObject.qml
@@ -0,0 +1,36 @@
+import QtQuick 2.0
+
+Item{
+ id: root
+
+ property bool test1: false
+ property bool test2: false
+
+ property var i
+
+ Component{
+ id: component
+ Item {
+ property int dummy: 13
+ property int dummy2: 26
+ }
+ }
+
+ Component.onCompleted: {
+ i = component.incubateObject(null, { dummy2: 19 });
+
+ if (i.status != Component.Loading) return;
+ if (i.object != null) return;
+
+ i.onStatusChanged = function(status) {
+ if (status != Component.Ready) return;
+ if (i.object == null) return;
+ if (i.object.dummy != 13) return;
+ if (i.object.dummy2 != 19) return;
+ test2 = true;
+ }
+
+ test1 = true;
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
index fe947fd201..89148812c5 100644
--- a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
+++ b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
@@ -45,22 +45,42 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/qsgitem.h>
#include <QtDeclarative/qdeclarativeproperty.h>
+#include <QtDeclarative/qdeclarativeincubator.h>
#include <qcolor.h>
+#include "../../../shared/util.h"
+
+#ifdef Q_OS_SYMBIAN
+// In Symbian OS test data is located in applications private dir
+#define SRCDIR "."
+#endif
+
+class MyIC : public QObject, public QDeclarativeIncubationController
+{
+ Q_OBJECT
+public:
+ MyIC() { startTimer(5); }
+protected:
+ virtual void timerEvent(QTimerEvent*) {
+ incubateFor(5);
+ }
+};
class tst_qdeclarativecomponent : public QObject
{
Q_OBJECT
public:
- tst_qdeclarativecomponent() { }
+ tst_qdeclarativecomponent() { engine.setIncubationController(&ic); }
private slots:
void null();
void loadEmptyUrl();
void qmlCreateObject();
void qmlCreateObjectWithProperties();
+ void qmlIncubateObject();
private:
QDeclarativeEngine engine;
+ MyIC ic;
};
void tst_qdeclarativecomponent::null()
@@ -91,6 +111,19 @@ void tst_qdeclarativecomponent::loadEmptyUrl()
QCOMPARE(error.description(), QLatin1String("Invalid empty URL"));
}
+void tst_qdeclarativecomponent::qmlIncubateObject()
+{
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/incubateObject.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QCOMPARE(object->property("test1").toBool(), true);
+ QCOMPARE(object->property("test2").toBool(), false);
+
+ QTRY_VERIFY(object->property("test2").toBool() == true);
+
+ delete object;
+}
+
void tst_qdeclarativecomponent::qmlCreateObject()
{
QDeclarativeEngine engine;