From 093ededb85c73f30ce3abf43bc6da0fff55323c2 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 28 Oct 2009 16:45:46 +0100 Subject: Cache QState's child states This is the same type of optimization as that done for transitions in commit 5d8dcd57cd13fdd9c8643fa3bdda9f197a4351ff. The idea is to avoid calling qobject_cast() because it's very expensive. Obtaining child states needs to be as fast as possible because it's in the critical path of the state machine algorithm; it's called by a ton of internal functions, like isCompound(), isAtomic(), isInFinalState(). It's also called heavily for parallel state groups. Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qstate.cpp | 25 +++++++++++++++---------- src/corelib/statemachine/qstate_p.h | 2 ++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index 9abf20b..bcd8364 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -125,7 +125,7 @@ QT_BEGIN_NAMESPACE QStatePrivate::QStatePrivate() : errorState(0), initialState(0), childMode(QState::ExclusiveStates), - transitionsListNeedsRefresh(true) + childStatesListNeedsRefresh(true), transitionsListNeedsRefresh(true) { } @@ -181,15 +181,18 @@ QState::~QState() QList QStatePrivate::childStates() const { - QList result; - QList::const_iterator it; - for (it = children.constBegin(); it != children.constEnd(); ++it) { - QAbstractState *s = qobject_cast(*it); - if (!s || qobject_cast(s)) - continue; - result.append(s); + if (childStatesListNeedsRefresh) { + childStatesList.clear(); + QList::const_iterator it; + for (it = children.constBegin(); it != children.constEnd(); ++it) { + QAbstractState *s = qobject_cast(*it); + if (!s || qobject_cast(s)) + continue; + childStatesList.append(s); + } + childStatesListNeedsRefresh = false; } - return result; + return childStatesList; } QList QStatePrivate::historyStates() const @@ -473,8 +476,10 @@ void QState::setChildMode(ChildMode mode) bool QState::event(QEvent *e) { Q_D(QState); - if ((e->type() == QEvent::ChildAdded) || (e->type() == QEvent::ChildRemoved)) + if ((e->type() == QEvent::ChildAdded) || (e->type() == QEvent::ChildRemoved)) { + d->childStatesListNeedsRefresh = true; d->transitionsListNeedsRefresh = true; + } return QAbstractState::event(e); } diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h index 3b5f416..34c8838 100644 --- a/src/corelib/statemachine/qstate_p.h +++ b/src/corelib/statemachine/qstate_p.h @@ -99,6 +99,8 @@ public: QAbstractState *errorState; QAbstractState *initialState; QState::ChildMode childMode; + mutable bool childStatesListNeedsRefresh; + mutable QList childStatesList; mutable bool transitionsListNeedsRefresh; mutable QList transitionsList; -- cgit v0.12