aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2016-06-14 16:28:34 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2017-01-24 15:02:36 +0000
commitca6b787a01ea289bd5c2a3e4ff3c7442a4ff58fc (patch)
tree8d8d49fe22b9686b44e78a99e93c0ba0535aab3f /src
parent94f6071b8a36501d9da516f2bf0f251147c8b934 (diff)
Allow canceling incubation
Qt Quick Controls must avoid destroying any object that belongs to a tree of objects being incubated. The problem is that QQC have no control over the incubation process. This patch adds private API that allows QQC to cancel incubation of a specific item that QQC would like to destroy. Change-Id: Id9f9004736e2b53fe46cdb6bb3055b7457def94d Task-number: QTBUG-50992 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/qml/qqmlincubator.cpp17
-rw-r--r--src/qml/qml/qqmlincubator_p.h5
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp15
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h1
-rw-r--r--src/qml/qml/qqmlvme.cpp12
-rw-r--r--src/qml/qml/qqmlvme_p.h1
6 files changed, 51 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index 963638ca34..54d0b240f5 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -380,6 +380,23 @@ finishIncubate:
}
}
+void QQmlIncubatorPrivate::cancel(QObject *object, QQmlContext *context)
+{
+ if (!context)
+ context = qmlContext(object);
+ if (!context)
+ return;
+
+ QQmlContextData *data = QQmlContextData::get(context);
+ QQmlIncubatorPrivate *p = (QQmlIncubatorPrivate *)data->activeVMEData;
+ if (!p)
+ return;
+
+ p->vmeGuard.unguard(object);
+ if (!p->creator.isNull())
+ p->creator->cancel(object);
+}
+
/*!
Incubate objects for \a msecs, or until there are no more objects to incubate.
*/
diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h
index ecf3b6d2ca..758e0a29f6 100644
--- a/src/qml/qml/qqmlincubator_p.h
+++ b/src/qml/qml/qqmlincubator_p.h
@@ -40,6 +40,8 @@
#ifndef QQMLINCUBATOR_P_H
#define QQMLINCUBATOR_P_H
+#include "qqmlincubator.h"
+
#include <private/qintrusivelist_p.h>
#include <private/qqmlvme_p.h>
#include <private/qrecursionwatcher_p.h>
@@ -100,6 +102,9 @@ public:
void forceCompletion(QQmlInstantiationInterrupt &i);
void incubate(QQmlInstantiationInterrupt &i);
+
+ // used by Qt Quick Controls 2
+ Q_QML_PRIVATE_EXPORT static void cancel(QObject *object, QQmlContext *context = 0);
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 09936f6e7a..38a16b8cde 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -1270,6 +1270,21 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
return sharedState->rootContext;
}
+void QQmlObjectCreator::cancel(QObject *object)
+{
+ int last = sharedState->allCreatedObjects.count() - 1;
+ int i = last;
+ while (i >= 0) {
+ if (sharedState->allCreatedObjects.at(i) == object) {
+ if (i < last)
+ qSwap(sharedState->allCreatedObjects[i], sharedState->allCreatedObjects[last]);
+ sharedState->allCreatedObjects.pop();
+ break;
+ }
+ --i;
+ }
+}
+
void QQmlObjectCreator::clear()
{
if (phase == Done || phase == Finalizing || phase == Startup)
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index caee7b9d1d..982324be3c 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -90,6 +90,7 @@ public:
QObject *create(int subComponentIndex = -1, QObject *parent = 0, QQmlInstantiationInterrupt *interrupt = 0);
bool populateDeferredProperties(QObject *instance);
QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt);
+ void cancel(QObject *object);
void clear();
QQmlComponentAttached **componentAttachment() const { return &sharedState->componentAttached; }
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 72d4ab7e8f..c60f4edc80 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -120,6 +120,18 @@ void QQmlVMEGuard::guard(QQmlObjectCreator *creator)
m_contexts[0] = creator->parentContextData();
}
+void QQmlVMEGuard::unguard(QObject *object)
+{
+ for (int ii = 0; ii < m_objectCount; ++ii) {
+ if (m_objects[ii] == object) {
+ if (ii < m_objectCount - 1)
+ ::memmove((void *) m_objects[ii], (void *) m_objects[ii + 1], sizeof(QPointer<QObject> *));
+ delete m_objects[--m_objectCount];
+ break;
+ }
+ }
+}
+
void QQmlVMEGuard::clear()
{
delete [] m_objects;
diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h
index 99d63380ad..9585b5b6df 100644
--- a/src/qml/qml/qqmlvme_p.h
+++ b/src/qml/qml/qqmlvme_p.h
@@ -131,6 +131,7 @@ public:
~QQmlVMEGuard();
void guard(QQmlObjectCreator *);
+ void unguard(QObject *);
void clear();
bool isOK() const;