From 2f2e31fea77aef558e5c6e3727f9b31cf018599a Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 7 Jul 2016 16:15:02 +0200 Subject: Better connection mechanism for events The connectToEvent() mechanism is analogous to connectToState() and allows arbitrary event specifications, with '.' and '*'. In addition a QML component is provided to make event connections available in QML. Change-Id: Ie45422481a794b1b350347c383318857e5dc3f6d Reviewed-by: Jarek Kobus --- tests/auto/statemachine/statemachine.pro | 2 +- tests/auto/statemachine/tst_statemachine.cpp | 78 +++++++++++++++++++++------- 2 files changed, 61 insertions(+), 19 deletions(-) (limited to 'tests') diff --git a/tests/auto/statemachine/statemachine.pro b/tests/auto/statemachine/statemachine.pro index c96ce21..eefbd7f 100644 --- a/tests/auto/statemachine/statemachine.pro +++ b/tests/auto/statemachine/statemachine.pro @@ -1,4 +1,4 @@ -QT = core gui qml testlib scxml +QT = core gui qml testlib scxml-private CONFIG += testcase TARGET = tst_statemachine diff --git a/tests/auto/statemachine/tst_statemachine.cpp b/tests/auto/statemachine/tst_statemachine.cpp index b3c7251..227d427 100644 --- a/tests/auto/statemachine/tst_statemachine.cpp +++ b/tests/auto/statemachine/tst_statemachine.cpp @@ -31,6 +31,7 @@ #include #include #include +#include Q_DECLARE_METATYPE(QScxmlError); @@ -183,6 +184,13 @@ void tst_StateMachine::connections() QVERIFY(disconnect(final)); } +bool hasChildEventRouters(QScxmlStateMachine *stateMachine) +{ + // Cast to QObject, to avoid ambigous "children" member. + const QObject &parentRouter = QScxmlStateMachinePrivate::get(stateMachine)->m_router; + return !parentRouter.children().isEmpty(); +} + void tst_StateMachine::eventOccurred() { QScopedPointer stateMachine(QScxmlStateMachine::fromFile(QString(":/tst_statemachine/eventoccurred.scxml"))); @@ -190,29 +198,63 @@ void tst_StateMachine::eventOccurred() qRegisterMetaType(); QSignalSpy finishedSpy(stateMachine.data(), SIGNAL(finished())); - QSignalSpy eventOccurredSpy(stateMachine.data(), SIGNAL(eventOccurred(QScxmlEvent))); - QSignalSpy externalEventOccurredSpy(stateMachine.data(), SIGNAL(externalEventOccurred(QScxmlEvent))); + + int events = 0; + auto con1 = stateMachine->connectToEvent("internalEvent2", [&events](const QScxmlEvent &event) { + QCOMPARE(++events, 1); + QCOMPARE(event.name(), QString("internalEvent2")); + QCOMPARE(event.eventType(), QScxmlEvent::ExternalEvent); + }); + QVERIFY(con1); + + auto con2 = stateMachine->connectToEvent("externalEvent", [&events](const QScxmlEvent &event) { + QCOMPARE(++events, 2); + QCOMPARE(event.name(), QString("externalEvent")); + QCOMPARE(event.eventType(), QScxmlEvent::ExternalEvent); + }); + QVERIFY(con2); + + auto con3 = stateMachine->connectToEvent("timeout", [&events](const QScxmlEvent &event) { + QCOMPARE(++events, 3); + QCOMPARE(event.name(), QString("timeout")); + QCOMPARE(event.eventType(), QScxmlEvent::ExternalEvent); + }); + QVERIFY(con3); + + auto con4 = stateMachine->connectToEvent("done.*", [&events](const QScxmlEvent &event) { + QCOMPARE(++events, 4); + QCOMPARE(event.name(), QString("done.state.top")); + QCOMPARE(event.eventType(), QScxmlEvent::ExternalEvent); + }); + QVERIFY(con4); + + auto con5 = stateMachine->connectToEvent("done.state", [&events](const QScxmlEvent &event) { + QCOMPARE(++events, 5); + QCOMPARE(event.name(), QString("done.state.top")); + QCOMPARE(event.eventType(), QScxmlEvent::ExternalEvent); + }); + QVERIFY(con5); + + auto con6 = stateMachine->connectToEvent("done.state.top", [&events](const QScxmlEvent &event) { + QCOMPARE(++events, 6); + QCOMPARE(event.name(), QString("done.state.top")); + QCOMPARE(event.eventType(), QScxmlEvent::ExternalEvent); + }); + QVERIFY(con6); stateMachine->start(); finishedSpy.wait(5000); + QCOMPARE(events, 6); + + QVERIFY(disconnect(con1)); + QVERIFY(disconnect(con2)); + QVERIFY(disconnect(con3)); + QVERIFY(disconnect(con4)); + QVERIFY(disconnect(con5)); + QVERIFY(disconnect(con6)); - auto event = [&eventOccurredSpy](int eventIndex) -> QScxmlEvent { - return qvariant_cast(eventOccurredSpy.at(eventIndex).at(0)); - }; - - QCOMPARE(eventOccurredSpy.count(), 4); - QCOMPARE(event(0).name(), QLatin1String("internalEvent2")); - QCOMPARE(event(0).eventType(), QScxmlEvent::ExternalEvent); - QCOMPARE(event(1).name(), QLatin1String("externalEvent")); - QCOMPARE(event(1).eventType(), QScxmlEvent::ExternalEvent); - QCOMPARE(event(2).name(), QLatin1String("timeout")); - QCOMPARE(event(2).eventType(), QScxmlEvent::ExternalEvent); - QCOMPARE(event(3).name(), QLatin1String("done.state.top")); - QCOMPARE(event(3).eventType(), QScxmlEvent::ExternalEvent); - - QCOMPARE(externalEventOccurredSpy.count(), 1); - QCOMPARE(qvariant_cast(externalEventOccurredSpy.at(0).at(0)).name(), QLatin1String("externalEvent")); + QTRY_VERIFY(!hasChildEventRouters(stateMachine.data())); } void tst_StateMachine::doneDotStateEvent() -- cgit v1.2.3