Optimize a code path in QGraphicsScenePrivate::cancelGesturesForChildren()

If ev.isAccepted(), since list is gestures.toList(), the
first foreach loop would clear 'gestures', one item at
a time. The second foreach loop would then not execute
at all.

Make this case clearer by not executing either loop if
ev.isAccepted().

Make it more performant by not iterating twice, but once,
simply skipping those gestures in the second (remaining)
loop which would have been removed by the first one.

Also iterate over the equivalent QList instead of the QSet,
because the former is way more efficient.

Text size savings are present, but minimal. The runtime
savings are signficant, of course.

Change-Id: I3d5bfe99c5d3fcbe4c98816577846551c632f315
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
bb10
Marc Mutz 2015-12-21 14:00:24 +01:00
parent f074c57cae
commit f68260e6c0
1 changed files with 21 additions and 20 deletions

View File

@ -6494,28 +6494,29 @@ void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original)
QGestureEvent ev(list);
sendEvent(target, &ev);
foreach (QGesture *g, list) {
if (ev.isAccepted() || ev.isAccepted(g))
gestures.remove(g);
}
if (!ev.isAccepted()) {
foreach (QGesture *g, list) {
foreach (QGesture *g, gestures) {
if (!g->hasHotSpot())
continue;
QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), g->d_func()->sceneHotSpot, 0);
for (int j = 0; j < items.size(); ++j) {
QGraphicsObject *item = items.at(j)->toGraphicsObject();
if (!item)
if (ev.isAccepted(g))
continue;
QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
if (d->gestureContext.contains(g->gestureType())) {
QList<QGesture *> list;
list << g;
QGestureEvent ev(list);
sendEvent(item, &ev);
if (ev.isAccepted() || ev.isAccepted(g))
break; // successfully delivered
if (!g->hasHotSpot())
continue;
QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), g->d_func()->sceneHotSpot, 0);
for (int j = 0; j < items.size(); ++j) {
QGraphicsObject *item = items.at(j)->toGraphicsObject();
if (!item)
continue;
QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
if (d->gestureContext.contains(g->gestureType())) {
QList<QGesture *> list;
list << g;
QGestureEvent ev(list);
sendEvent(item, &ev);
if (ev.isAccepted() || ev.isAccepted(g))
break; // successfully delivered
}
}
}
}