summaryrefslogtreecommitdiffstats
path: root/src/corelib/statemachine
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-10-28 15:09:47 +0100
committerKent Hansen <khansen@trolltech.com>2009-10-28 15:35:07 +0100
commit5d8dcd57cd13fdd9c8643fa3bdda9f197a4351ff (patch)
treefe37e87419eeaf01b0f4a441b3694fac35e15111 /src/corelib/statemachine
parent36e362cffe74d8f7fb3eb6b6a67fbab2ebda1a21 (diff)
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
Diffstat (limited to 'src/corelib/statemachine')
-rw-r--r--src/corelib/statemachine/qstate.cpp23
-rw-r--r--src/corelib/statemachine/qstate_p.h2
2 files changed, 17 insertions, 8 deletions
diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp
index a6e4a57469..9abf20b32d 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 20cda29cab..3b5f416436 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;
};