diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2016-06-14 16:28:34 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2017-01-24 15:02:36 +0000 |
commit | ca6b787a01ea289bd5c2a3e4ff3c7442a4ff58fc (patch) | |
tree | 8d8d49fe22b9686b44e78a99e93c0ba0535aab3f /src | |
parent | 94f6071b8a36501d9da516f2bf0f251147c8b934 (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.cpp | 17 | ||||
-rw-r--r-- | src/qml/qml/qqmlincubator_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 15 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlvme.cpp | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmlvme_p.h | 1 |
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; |