summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp19
-rw-r--r--src/corelib/statemachine/qstatemachine_p.h2
-rw-r--r--tests/auto/qstatemachine/tst_qstatemachine.cpp48
3 files changed, 62 insertions, 7 deletions
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 2f620c7..046fbb4 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -1407,7 +1407,7 @@ void QStateMachinePrivate::registerEventTransition(QEventTransition *transition)
QObjectPrivate *od = QObjectPrivate::get(object);
if (!od->eventFilters.contains(q))
object->installEventFilter(q);
- qobjectEvents[object].insert(transition->eventType());
+ ++qobjectEvents[object][transition->eventType()];
QEventTransitionPrivate::get(transition)->registered = true;
#ifdef QSTATEMACHINE_DEBUG
qDebug() << q << ": added event transition from" << transition->sourceState()
@@ -1422,11 +1422,18 @@ void QStateMachinePrivate::unregisterEventTransition(QEventTransition *transitio
if (!QEventTransitionPrivate::get(transition)->registered)
return;
QObject *object = QEventTransitionPrivate::get(transition)->object;
- QSet<QEvent::Type> &events = qobjectEvents[object];
- events.remove(transition->eventType());
- if (events.isEmpty()) {
- qobjectEvents.remove(object);
- object->removeEventFilter(q);
+ QHash<QEvent::Type, int> &events = qobjectEvents[object];
+ Q_ASSERT(events.value(transition->eventType()) > 0);
+ if (--events[transition->eventType()] == 0) {
+ events.remove(transition->eventType());
+ int sum = 0;
+ QHash<QEvent::Type, int>::const_iterator it;
+ for (it = events.constBegin(); it != events.constEnd(); ++it)
+ sum += it.value();
+ if (sum == 0) {
+ qobjectEvents.remove(object);
+ object->removeEventFilter(q);
+ }
}
QEventTransitionPrivate::get(transition)->registered = false;
}
diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h
index 9b4b861..dfa5575 100644
--- a/src/corelib/statemachine/qstatemachine_p.h
+++ b/src/corelib/statemachine/qstatemachine_p.h
@@ -200,7 +200,7 @@ public:
QHash<const QObject*, QVector<int> > connections;
#ifndef QT_NO_STATEMACHINE_EVENTFILTER
- QHash<QObject*, QSet<QEvent::Type> > qobjectEvents;
+ QHash<QObject*, QHash<QEvent::Type, int> > qobjectEvents;
#endif
QHash<int, QEvent*> delayedEvents;
diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp
index 3f94ad9..f8a778a 100644
--- a/tests/auto/qstatemachine/tst_qstatemachine.cpp
+++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp
@@ -1881,6 +1881,54 @@ void tst_QStateMachine::eventTransitions()
QTRY_COMPARE(finishedSpy.count(), 1);
}
+ // Multiple transitions for same (object,event)
+ {
+ QStateMachine machine;
+ QState *s0 = new QState(machine.rootState());
+ QState *s1 = new QState(machine.rootState());
+ QEventTransition *t0 = new QEventTransition(&button, QEvent::MouseButtonPress);
+ t0->setTargetState(s1);
+ s0->addTransition(t0);
+ QEventTransition *t1 = new QEventTransition(&button, QEvent::MouseButtonPress);
+ t1->setTargetState(s0);
+ s1->addTransition(t1);
+
+ QSignalSpy finishedSpy(&machine, SIGNAL(finished()));
+ machine.setInitialState(s0);
+ machine.start();
+ QCoreApplication::processEvents();
+ QCOMPARE(machine.configuration().size(), 1);
+ QVERIFY(machine.configuration().contains(s0));
+
+ QTest::mousePress(&button, Qt::LeftButton);
+ QCoreApplication::processEvents();
+ QCOMPARE(machine.configuration().size(), 1);
+ QVERIFY(machine.configuration().contains(s1));
+
+ s0->removeTransition(t0);
+ QTest::mousePress(&button, Qt::LeftButton);
+ QCoreApplication::processEvents();
+ QCOMPARE(machine.configuration().size(), 1);
+ QVERIFY(machine.configuration().contains(s0));
+
+ QTest::mousePress(&button, Qt::LeftButton);
+ QCoreApplication::processEvents();
+ QCOMPARE(machine.configuration().size(), 1);
+ QVERIFY(machine.configuration().contains(s0));
+
+ s1->removeTransition(t1);
+ QTest::mousePress(&button, Qt::LeftButton);
+ QCoreApplication::processEvents();
+ QCOMPARE(machine.configuration().size(), 1);
+ QVERIFY(machine.configuration().contains(s0));
+
+ s0->addTransition(t0);
+ s1->addTransition(t1);
+ QTest::mousePress(&button, Qt::LeftButton);
+ QCoreApplication::processEvents();
+ QCOMPARE(machine.configuration().size(), 1);
+ QVERIFY(machine.configuration().contains(s1));
+ }
}
void tst_QStateMachine::historyStates()