summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/corelib/statemachine/qabstracttransition_p.h2
-rw-r--r--src/corelib/statemachine/qsignalevent.h2
-rw-r--r--src/corelib/statemachine/qsignaltransition.cpp17
-rw-r--r--src/corelib/statemachine/qsignaltransition_p.h3
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp7
-rw-r--r--tests/auto/qstatemachine/tst_qstatemachine.cpp42
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"