summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-10-28 14:09:47 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-10-28 14:35:07 (GMT)
commit5d8dcd57cd13fdd9c8643fa3bdda9f197a4351ff (patch)
treefe37e87419eeaf01b0f4a441b3694fac35e15111
parent36e362cffe74d8f7fb3eb6b6a67fbab2ebda1a21 (diff)
downloadQt-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.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 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;
};