diff options
author | Erik Verbruggen <erik.verbruggen@theqtcompany.com> | 2015-03-20 11:17:55 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@theqtcompany.com> | 2015-04-28 12:54:08 +0000 |
commit | fc51e86ca444e713586f31ab0e0d0e26144bbfa7 (patch) | |
tree | 7f46b0a245a3e2383577fd11be434077e8a378e6 /src/corelib/statemachine | |
parent | 0abf5ec7c4e035f2d37b45cc2da583df829ec0d0 (diff) |
QStateMachine: optimize conflict calculation.
Done by using in-place removal from the list of transitions using
iterators.
Change-Id: I6dced4b214b49b3dcd3ba19ca4cd81a601f81bb6
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
Diffstat (limited to 'src/corelib/statemachine')
-rw-r--r-- | src/corelib/statemachine/qstatemachine.cpp | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index dd0ba9260e..f02e27330d 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -483,6 +483,8 @@ function removeConflictingTransitions(enabledTransitions): filteredTransitions.add(t1) return filteredTransitions + +Note: the implementation below does not build the transitionsToRemove, but removes them in-place. */ void QStateMachinePrivate::removeConflictingTransitions(QList<QAbstractTransition*> &enabledTransitions) { @@ -492,24 +494,36 @@ void QStateMachinePrivate::removeConflictingTransitions(QList<QAbstractTransitio foreach (QAbstractTransition *t1, enabledTransitions) { bool t1Preempted = false; - QVarLengthArray<QAbstractTransition *> transitionsToRemove; QSet<QAbstractState*> exitSetT1 = computeExitSet_Unordered(QList<QAbstractTransition*>() << t1); - foreach (QAbstractTransition *t2, filteredTransitions) { + QList<QAbstractTransition*>::iterator t2It = filteredTransitions.begin(); + while (t2It != filteredTransitions.end()) { + QAbstractTransition *t2 = *t2It; + if (t1 == t2) { + // Special case: someone added the same transition object to a state twice. In this + // case, t2 (which is already in the list) "preempts" t1. + t1Preempted = true; + break; + } + QSet<QAbstractState*> exitSetT2 = computeExitSet_Unordered(QList<QAbstractTransition*>() << t2); - if (!exitSetT1.intersect(exitSetT2).isEmpty()) { + if (exitSetT1.intersect(exitSetT2).isEmpty()) { + // No conflict, no cry. Next patient please. + ++t2It; + } else { + // Houston, we have a conflict. Check which transition can be removed. if (isDescendant(t1->sourceState(), t2->sourceState())) { - transitionsToRemove.append(t2); + // t1 preempts t2, so we can remove t2 + t2It = filteredTransitions.erase(t2It); } else { + // t2 preempts t1, so there's no use in looking further and we don't need to add + // t1 to the list. t1Preempted = true; break; } } } - if (!t1Preempted) { - foreach (QAbstractTransition *t3, transitionsToRemove) - filteredTransitions.removeAll(t3); + if (!t1Preempted) filteredTransitions.append(t1); - } } enabledTransitions = filteredTransitions; |