diff options
-rw-r--r-- | src/corelib/statemachine/qabstracttransition_p.h | 2 | ||||
-rw-r--r-- | src/corelib/statemachine/qsignalevent.h | 2 | ||||
-rw-r--r-- | src/corelib/statemachine/qsignaltransition.cpp | 17 | ||||
-rw-r--r-- | src/corelib/statemachine/qsignaltransition_p.h | 3 | ||||
-rw-r--r-- | src/corelib/statemachine/qstatemachine.cpp | 7 | ||||
-rw-r--r-- | tests/auto/qstatemachine/tst_qstatemachine.cpp | 42 |
6 files changed, 72 insertions, 1 deletions
diff --git a/src/corelib/statemachine/qabstracttransition_p.h b/src/corelib/statemachine/qabstracttransition_p.h index 328be1677c..33e4474280 100644 --- a/src/corelib/statemachine/qabstracttransition_p.h +++ b/src/corelib/statemachine/qabstracttransition_p.h @@ -75,7 +75,7 @@ public: static QAbstractTransitionPrivate *get(QAbstractTransition *q); bool callEventTest(QEvent *e); - void callOnTransition(QEvent *e); + virtual void callOnTransition(QEvent *e); QState *sourceState() const; QStateMachine *machine() const; void emitTriggered(); diff --git a/src/corelib/statemachine/qsignalevent.h b/src/corelib/statemachine/qsignalevent.h index 7e5d8884cf..de166f4fa5 100644 --- a/src/corelib/statemachine/qsignalevent.h +++ b/src/corelib/statemachine/qsignalevent.h @@ -70,6 +70,8 @@ private: QObject *m_sender; int m_signalIndex; QList<QVariant> m_arguments; + + friend class QSignalTransitionPrivate; }; #endif //QT_NO_STATEMACHINE diff --git a/src/corelib/statemachine/qsignaltransition.cpp b/src/corelib/statemachine/qsignaltransition.cpp index e34448f65f..fb28c080aa 100644 --- a/src/corelib/statemachine/qsignaltransition.cpp +++ b/src/corelib/statemachine/qsignaltransition.cpp @@ -245,6 +245,23 @@ bool QSignalTransition::event(QEvent *e) return QAbstractTransition::event(e); } +void QSignalTransitionPrivate::callOnTransition(QEvent *e) +{ + Q_Q(QSignalTransition); + + QSignalEvent *se = static_cast<QSignalEvent *>(e); + int savedSignalIndex; + if (e->type() == QEvent::Signal) { + savedSignalIndex = se->m_signalIndex; + se->m_signalIndex = originalSignalIndex; + } + + q->onTransition(e); + + if (e->type() == QEvent::Signal) + se->m_signalIndex = savedSignalIndex; +} + QT_END_NAMESPACE #endif //QT_NO_STATEMACHINE diff --git a/src/corelib/statemachine/qsignaltransition_p.h b/src/corelib/statemachine/qsignaltransition_p.h index 21082ab7e2..69bbcc9723 100644 --- a/src/corelib/statemachine/qsignaltransition_p.h +++ b/src/corelib/statemachine/qsignaltransition_p.h @@ -69,9 +69,12 @@ public: void unregister(); void maybeRegister(); + virtual void callOnTransition(QEvent *e); + QObject *sender; QByteArray signal; int signalIndex; + int originalSignalIndex; }; QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index d6946dee13..e5bca2cc16 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -1408,6 +1408,7 @@ void QStateMachinePrivate::registerSignalTransition(QSignalTransition *transitio signal.remove(0, 1); const QMetaObject *meta = sender->metaObject(); int signalIndex = meta->indexOfSignal(signal); + int originalSignalIndex = signalIndex; if (signalIndex == -1) { signalIndex = meta->indexOfSignal(QMetaObject::normalizedSignature(signal)); if (signalIndex == -1) { @@ -1416,6 +1417,11 @@ void QStateMachinePrivate::registerSignalTransition(QSignalTransition *transitio return; } } + // The signal index we actually want to connect to is the one + // that is going to be sent, i.e. the non-cloned original index. + while (meta->method(signalIndex).attributes() & QMetaMethod::Cloned) + --signalIndex; + QVector<int> &connectedSignalIndexes = connections[sender]; if (connectedSignalIndexes.size() <= signalIndex) connectedSignalIndexes.resize(signalIndex+1); @@ -1435,6 +1441,7 @@ void QStateMachinePrivate::registerSignalTransition(QSignalTransition *transitio } ++connectedSignalIndexes[signalIndex]; QSignalTransitionPrivate::get(transition)->signalIndex = signalIndex; + QSignalTransitionPrivate::get(transition)->originalSignalIndex = originalSignalIndex; #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": added signal transition from" << transition->sourceState() << ": ( sender =" << sender << ", signal =" << signal diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 20e69ce885..643daa295b 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -93,10 +93,13 @@ Q_OBJECT { emit signalWithIntArg(arg); } void emitSignalWithStringArg(const QString &arg) { emit signalWithStringArg(arg); } + void emitSignalWithDefaultArg() + { emit signalWithDefaultArg(); } Q_SIGNALS: void signalWithNoArg(); void signalWithIntArg(int); void signalWithStringArg(const QString &); + void signalWithDefaultArg(int i = 42); }; class tst_QStateMachine : public QObject @@ -193,6 +196,8 @@ private slots: void nestedStateMachines(); void goToState(); + + void task260403_clonedSignals(); }; tst_QStateMachine::tst_QStateMachine() @@ -3937,5 +3942,42 @@ void tst_QStateMachine::goToState() QVERIFY(machine.configuration().contains(s2_1)); } +class CloneSignalTransition : public QSignalTransition +{ +public: + CloneSignalTransition(QObject *sender, const char *signal, QAbstractState *target) + : QSignalTransition(sender, signal) + { + setTargetState(target); + } + + void onTransition(QEvent *e) + { + QSignalTransition::onTransition(e); + QSignalEvent *se = static_cast<QSignalEvent*>(e); + eventSignalIndex = se->signalIndex(); + } + + int eventSignalIndex; +}; + +void tst_QStateMachine::task260403_clonedSignals() +{ + SignalEmitter emitter; + QStateMachine machine; + QState *s1 = new QState(&machine); + QState *s2 = new QState(&machine); + CloneSignalTransition *t1 = new CloneSignalTransition(&emitter, SIGNAL(signalWithDefaultArg()), s2); + s1->addTransition(t1); + + machine.setInitialState(s1); + machine.start(); + QTest::qWait(1); + + emitter.emitSignalWithDefaultArg(); + QTest::qWait(1); + QCOMPARE(t1->eventSignalIndex, emitter.metaObject()->indexOfSignal("signalWithDefaultArg()")); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" |