diff options
author | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2017-11-06 16:13:13 +0100 |
---|---|---|
committer | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2017-11-30 07:35:35 +0000 |
commit | 60d589ccddb036e84883a6c2ef63a5292c8ad022 (patch) | |
tree | d0615d751ed79e73a9f1ac7938831e144c513a81 /src/quick | |
parent | 8bdf33051aa679db1f060314c6ccab1cb9a77a7a (diff) |
QQmlIntanceModel: use QQmlIncubator::IncubationMode instead of bool to specify incubation mode
The current implementation would pass a boolean to signal if asynchronous
or synchronous incubation should be used to create an item. The problem with this approach
is that passing 'synchronous" would translate to QQmlIncubation::AsynchronousIfNested
later down the chain. This meant that even if the caller requested synchronous incubation, it
could end up with asynchronous incubation anyway, e.g if an async parent incubator was active at
the time of the call. And this can easily come as an unhandled supprise for the caller, and as
such, cause unforseen bugs.
This patch is a first of a set of patches that is done to fix the bug reported in the task below.
It will not change any behavior, it is written to preserve the logic exactly as it were, just
as a preparation for subsequent patches. It makes it explicit at the call location what
incubation mode will be used, and especially make it clear whenever the AsynchronousIfNested
flag is in play.
Task-number: QTBUG-61537
Change-Id: I8b3ba5438ebb2cd59983a098bd8ceeeb844da87b
Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/items/qquickgridview.cpp | 6 | ||||
-rw-r--r-- | src/quick/items/qquickitemview.cpp | 10 | ||||
-rw-r--r-- | src/quick/items/qquickitemview_p_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquicklistview.cpp | 6 | ||||
-rw-r--r-- | src/quick/items/qquickpathview.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickrepeater.cpp | 6 |
6 files changed, 18 insertions, 14 deletions
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index c570b95a21..e59c579790 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -511,9 +511,11 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal FxGridItemSG *item = 0; bool changed = false; + QQmlIncubator::IncubationMode incubationMode = doBuffer ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested; + while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) { qCDebug(lcItemViewDelegateLifecycle) << "refill: append item" << modelIndex << colPos << rowPos; - if (!(item = static_cast<FxGridItemSG*>(createItem(modelIndex, doBuffer)))) + if (!(item = static_cast<FxGridItemSG*>(createItem(modelIndex, incubationMode)))) break; if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() item->setPosition(colPos, rowPos, true); @@ -548,7 +550,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal colPos = colNum * colSize(); while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){ qCDebug(lcItemViewDelegateLifecycle) << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos; - if (!(item = static_cast<FxGridItemSG*>(createItem(visibleIndex-1, doBuffer)))) + if (!(item = static_cast<FxGridItemSG*>(createItem(visibleIndex-1, incubationMode)))) break; --visibleIndex; if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index c203f389ae..82dbf04090 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1729,7 +1729,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex) FxViewItem *oldCurrentItem = currentItem; int oldCurrentIndex = currentIndex; currentIndex = modelIndex; - currentItem = createItem(modelIndex, false); + currentItem = createItem(modelIndex, QQmlIncubator::AsynchronousIfNested); if (oldCurrentItem && oldCurrentItem->attached && (!currentItem || oldCurrentItem->item != currentItem->item)) oldCurrentItem->attached->setIsCurrentItem(false); if (currentItem) { @@ -2325,11 +2325,11 @@ void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickItemViewTransitiona When the item becomes available, refill() will be called and the item will be returned on the next call to createItem(). */ -FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous) +FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, QQmlIncubator::IncubationMode incubationMode) { Q_Q(QQuickItemView); - if (requestedIndex == modelIndex && asynchronous) + if (requestedIndex == modelIndex && incubationMode == QQmlIncubator::Asynchronous) return 0; for (int i=0; i<releasePendingTransition.count(); i++) { @@ -2340,11 +2340,11 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous) } } - if (asynchronous) + if (incubationMode == QQmlIncubator::Asynchronous) requestedIndex = modelIndex; inRequest = true; - QObject* object = model->object(modelIndex, asynchronous); + QObject* object = model->object(modelIndex, incubationMode); QQuickItem *item = qmlobject_cast<QQuickItem*>(object); if (!item) { if (object) { diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h index 2c04022cde..622ebb430f 100644 --- a/src/quick/items/qquickitemview_p_p.h +++ b/src/quick/items/qquickitemview_p_p.h @@ -206,7 +206,7 @@ public: void refill(qreal from, qreal to); void mirrorChange() override; - FxViewItem *createItem(int modelIndex, bool asynchronous = false); + FxViewItem *createItem(int modelIndex,QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested); virtual bool releaseItem(FxViewItem *item); QQuickItem *createHighlightItem() const; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index a6236d9801..d924bc4460 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -669,11 +669,13 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal } } + QQmlIncubator::IncubationMode incubationMode = doBuffer ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested; + bool changed = false; FxListItemSG *item = 0; qreal pos = itemEnd; while (modelIndex < model->count() && pos <= fillTo) { - if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex, doBuffer)))) + if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex, incubationMode)))) break; qCDebug(lcItemViewDelegateLifecycle) << "refill: append item" << modelIndex << "pos" << pos << "buffer" << doBuffer << "item" << (QObject *)(item->item); if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() @@ -690,7 +692,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal return changed; while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos > fillFrom) { - if (!(item = static_cast<FxListItemSG*>(createItem(visibleIndex-1, doBuffer)))) + if (!(item = static_cast<FxListItemSG*>(createItem(visibleIndex-1, incubationMode)))) break; qCDebug(lcItemViewDelegateLifecycle) << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos << "buffer" << doBuffer << "item" << (QObject *)(item->item); --visibleIndex; diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index aac2b0296a..b9fea974ce 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -129,7 +129,7 @@ QQuickItem *QQuickPathViewPrivate::getItem(int modelIndex, qreal z, bool async) requestedIndex = modelIndex; requestedZ = z; inRequest = true; - QObject *object = model->object(modelIndex, async); + QObject *object = model->object(modelIndex, async ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested); QQuickItem *item = qmlobject_cast<QQuickItem*>(object); if (!item) { if (object) { diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp index ebf6e9c5cb..658a7de3d4 100644 --- a/src/quick/items/qquickrepeater.cpp +++ b/src/quick/items/qquickrepeater.cpp @@ -401,7 +401,7 @@ void QQuickRepeater::regenerate() void QQuickRepeaterPrivate::requestItems() { for (int i = 0; i < itemCount; i++) { - QObject *object = model->object(i, false); + QObject *object = model->object(i, QQmlIncubator::AsynchronousIfNested); if (object) model->release(object); } @@ -410,7 +410,7 @@ void QQuickRepeaterPrivate::requestItems() void QQuickRepeater::createdItem(int index, QObject *) { Q_D(QQuickRepeater); - QObject *object = d->model->object(index, false); + QObject *object = d->model->object(index, QQmlIncubator::AsynchronousIfNested); QQuickItem *item = qmlobject_cast<QQuickItem*>(object); emit itemAdded(index, item); } @@ -508,7 +508,7 @@ void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset) int modelIndex = index + i; ++d->itemCount; d->deletables.insert(modelIndex, 0); - QObject *object = d->model->object(modelIndex, false); + QObject *object = d->model->object(modelIndex, QQmlIncubator::AsynchronousIfNested); if (object) d->model->release(object); } |