diff options
author | Kent Hansen <khansen@trolltech.com> | 2009-10-28 14:09:47 (GMT) |
---|---|---|
committer | Kent Hansen <khansen@trolltech.com> | 2009-10-28 14:35:07 (GMT) |
commit | 5d8dcd57cd13fdd9c8643fa3bdda9f197a4351ff (patch) | |
tree | fe37e87419eeaf01b0f4a441b3694fac35e15111 | |
parent | 36e362cffe74d8f7fb3eb6b6a67fbab2ebda1a21 (diff) | |
download | Qt-5d8dcd57cd13fdd9c8643fa3bdda9f197a4351ff.zip Qt-5d8dcd57cd13fdd9c8643fa3bdda9f197a4351ff.tar.gz Qt-5d8dcd57cd13fdd9c8643fa3bdda9f197a4351ff.tar.bz2 |
Greatly improve the performance of obtaining a state's transitions
Transitions are children of their source state. We use
QObject::children() and qobject_cast() each child to a
QAbstractTransition to see if it is indeed a transition. However,
calling qobject_cast() is very expensive. This commit introduces
a cached list of transitions. The list is invalidated after a
child object has been added or removed.
In the typical case we expect the object hierarchy to remain fairly
constant once the state machine has been started (states, child states
and transitions are usually "static"), in other words the cached list
is not likely to be invalidated much.
Obtaining a state's transitions needs to be as fast as possible
because it's in the critical path of the state machine algorithm.
Reviewed-by: Eskil Abrahamsen Blomfeldt
-rw-r--r-- | src/corelib/statemachine/qstate.cpp | 23 | ||||
-rw-r--r-- | src/corelib/statemachine/qstate_p.h | 2 |
2 files changed, 17 insertions, 8 deletions
diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index a6e4a57..9abf20b 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -124,7 +124,8 @@ QT_BEGIN_NAMESPACE */ QStatePrivate::QStatePrivate() - : errorState(0), initialState(0), childMode(QState::ExclusiveStates) + : errorState(0), initialState(0), childMode(QState::ExclusiveStates), + transitionsListNeedsRefresh(true) { } @@ -205,14 +206,17 @@ QList<QHistoryState*> QStatePrivate::historyStates() const QList<QAbstractTransition*> QStatePrivate::transitions() const { - QList<QAbstractTransition*> result; - QList<QObject*>::const_iterator it; - for (it = children.constBegin(); it != children.constEnd(); ++it) { - QAbstractTransition *t = qobject_cast<QAbstractTransition*>(*it); - if (t) - result.append(t); + if (transitionsListNeedsRefresh) { + transitionsList.clear(); + QList<QObject*>::const_iterator it; + for (it = children.constBegin(); it != children.constEnd(); ++it) { + QAbstractTransition *t = qobject_cast<QAbstractTransition*>(*it); + if (t) + transitionsList.append(t); + } + transitionsListNeedsRefresh = false; } - return result; + return transitionsList; } #ifndef QT_NO_PROPERTIES @@ -468,6 +472,9 @@ void QState::setChildMode(ChildMode mode) */ bool QState::event(QEvent *e) { + Q_D(QState); + if ((e->type() == QEvent::ChildAdded) || (e->type() == QEvent::ChildRemoved)) + d->transitionsListNeedsRefresh = true; return QAbstractState::event(e); } diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h index 20cda29..3b5f416 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 transitionsListNeedsRefresh; + mutable QList<QAbstractTransition*> transitionsList; QList<QPropertyAssignment> propertyAssignments; }; |