std::chrono overload added to QStateMachine::postDelayedEvent()
Some Qt classes already accept std::chrono durations in their methods (see, for example, QTimer). The proposed change adds an overload with std::chrono::milliseconds to QStateMachine::postDelayedEvent(). Change-Id: I360fd2bb54fedc7415e9ec17e096095be3604d41 Reviewed-by: Erik Verbruggen <erik.verbruggen@me.com>
This commit is contained in:
parent
f415c5ad23
commit
9557715016
@ -3273,6 +3273,26 @@ QStateMachine::WrappedEvent::~WrappedEvent()
|
|||||||
\sa QStateMachine::running
|
\sa QStateMachine::running
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QStateMachine::postDelayedEvent(QEvent *event, std::chrono::milliseconds delay)
|
||||||
|
\since 5.15
|
||||||
|
\overload
|
||||||
|
\threadsafe
|
||||||
|
|
||||||
|
Posts the given \a event for processing by this state machine, with the
|
||||||
|
given \a delay in milliseconds. Returns an identifier associated with the
|
||||||
|
delayed event, or -1 if the event could not be posted.
|
||||||
|
|
||||||
|
This function returns immediately. When the delay has expired, the event
|
||||||
|
will be added to the state machine's event queue for processing. The state
|
||||||
|
machine takes ownership of the event and deletes it once it has been
|
||||||
|
processed.
|
||||||
|
|
||||||
|
You can only post events when the state machine is running.
|
||||||
|
|
||||||
|
\sa cancelDelayedEvent(), postEvent()
|
||||||
|
*/
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#include "qstatemachine.moc"
|
#include "qstatemachine.moc"
|
||||||
|
@ -48,6 +48,10 @@
|
|||||||
#include <QtCore/qset.h>
|
#include <QtCore/qset.h>
|
||||||
#include <QtCore/qvariant.h>
|
#include <QtCore/qvariant.h>
|
||||||
|
|
||||||
|
#if __has_include(<chrono>)
|
||||||
|
# include <chrono>
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_REQUIRE_CONFIG(statemachine);
|
QT_REQUIRE_CONFIG(statemachine);
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -145,6 +149,13 @@ public:
|
|||||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __has_include(<chrono>) || defined(Q_QDOC)
|
||||||
|
int postDelayedEvent(QEvent *event, std::chrono::milliseconds delay)
|
||||||
|
{
|
||||||
|
return postDelayedEvent(event, int(delay.count()));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
|
@ -253,6 +253,10 @@ private slots:
|
|||||||
void qtbug_46703();
|
void qtbug_46703();
|
||||||
void postEventFromBeginSelectTransitions();
|
void postEventFromBeginSelectTransitions();
|
||||||
void dontProcessSlotsWhenMachineIsNotRunning();
|
void dontProcessSlotsWhenMachineIsNotRunning();
|
||||||
|
|
||||||
|
void cancelDelayedEventWithChrono();
|
||||||
|
void postDelayedEventWithChronoAndStop();
|
||||||
|
void postDelayedEventWithChronoFromThread();
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestState : public QState
|
class TestState : public QState
|
||||||
@ -6702,5 +6706,163 @@ void tst_QStateMachine::dontProcessSlotsWhenMachineIsNotRunning()
|
|||||||
QTRY_VERIFY(emitter.thread.isFinished());
|
QTRY_VERIFY(emitter.thread.isFinished());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QStateMachine::cancelDelayedEventWithChrono()
|
||||||
|
{
|
||||||
|
#if __has_include(<chrono>)
|
||||||
|
QStateMachine machine;
|
||||||
|
QTest::ignoreMessage(QtWarningMsg,
|
||||||
|
"QStateMachine::cancelDelayedEvent: the machine is not running");
|
||||||
|
QVERIFY(!machine.cancelDelayedEvent(-1));
|
||||||
|
|
||||||
|
QState *s1 = new QState(&machine);
|
||||||
|
DEFINE_ACTIVE_SPY(s1);
|
||||||
|
QFinalState *s2 = new QFinalState(&machine);
|
||||||
|
s1->addTransition(new StringTransition("a", s2));
|
||||||
|
machine.setInitialState(s1);
|
||||||
|
|
||||||
|
QSignalSpy startedSpy(&machine, &QStateMachine::started);
|
||||||
|
QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
|
||||||
|
QVERIFY(startedSpy.isValid());
|
||||||
|
QVERIFY(runningSpy.isValid());
|
||||||
|
machine.start();
|
||||||
|
QTRY_COMPARE(startedSpy.count(), 1);
|
||||||
|
TEST_RUNNING_CHANGED(true);
|
||||||
|
TEST_ACTIVE_CHANGED(s1, 1);
|
||||||
|
QCOMPARE(machine.configuration().size(), 1);
|
||||||
|
QVERIFY(machine.configuration().contains(s1));
|
||||||
|
int id1 = machine.postDelayedEvent(new StringEvent("c"), std::chrono::seconds{50});
|
||||||
|
QVERIFY(id1 != -1);
|
||||||
|
int id2 = machine.postDelayedEvent(new StringEvent("b"), std::chrono::seconds{25});
|
||||||
|
QVERIFY(id2 != -1);
|
||||||
|
QVERIFY(id2 != id1);
|
||||||
|
int id3 = machine.postDelayedEvent(new StringEvent("a"), std::chrono::milliseconds{100});
|
||||||
|
QVERIFY(id3 != -1);
|
||||||
|
QVERIFY(id3 != id2);
|
||||||
|
QVERIFY(machine.cancelDelayedEvent(id1));
|
||||||
|
QVERIFY(!machine.cancelDelayedEvent(id1));
|
||||||
|
QVERIFY(machine.cancelDelayedEvent(id2));
|
||||||
|
QVERIFY(!machine.cancelDelayedEvent(id2));
|
||||||
|
|
||||||
|
QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
|
||||||
|
QVERIFY(finishedSpy.isValid());
|
||||||
|
QTRY_COMPARE(finishedSpy.count(), 1);
|
||||||
|
TEST_RUNNING_CHANGED(false);
|
||||||
|
TEST_ACTIVE_CHANGED(s1, 2);
|
||||||
|
QCOMPARE(machine.configuration().size(), 1);
|
||||||
|
QVERIFY(machine.configuration().contains(s2));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QStateMachine::postDelayedEventWithChronoAndStop()
|
||||||
|
{
|
||||||
|
#if __has_include(<chrono>)
|
||||||
|
QStateMachine machine;
|
||||||
|
QState *s1 = new QState(&machine);
|
||||||
|
DEFINE_ACTIVE_SPY(s1);
|
||||||
|
QFinalState *s2 = new QFinalState(&machine);
|
||||||
|
s1->addTransition(new StringTransition("a", s2));
|
||||||
|
machine.setInitialState(s1);
|
||||||
|
|
||||||
|
QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
|
||||||
|
QVERIFY(runningSpy.isValid());
|
||||||
|
QSignalSpy startedSpy(&machine, &QStateMachine::started);
|
||||||
|
QVERIFY(startedSpy.isValid());
|
||||||
|
machine.start();
|
||||||
|
QTRY_COMPARE(startedSpy.count(), 1);
|
||||||
|
TEST_RUNNING_CHANGED(true);
|
||||||
|
TEST_ACTIVE_CHANGED(s1, 1);
|
||||||
|
QCOMPARE(machine.configuration().size(), 1);
|
||||||
|
QVERIFY(machine.configuration().contains(s1));
|
||||||
|
|
||||||
|
int id1 = machine.postDelayedEvent(new StringEvent("a"), std::chrono::milliseconds{0});
|
||||||
|
QVERIFY(id1 != -1);
|
||||||
|
QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped);
|
||||||
|
QVERIFY(stoppedSpy.isValid());
|
||||||
|
machine.stop();
|
||||||
|
QTRY_COMPARE(stoppedSpy.count(), 1);
|
||||||
|
TEST_RUNNING_CHANGED(false);
|
||||||
|
TEST_ACTIVE_CHANGED(s1, 1);
|
||||||
|
QCOMPARE(machine.configuration().size(), 1);
|
||||||
|
QVERIFY(machine.configuration().contains(s1));
|
||||||
|
|
||||||
|
machine.start();
|
||||||
|
QTRY_COMPARE(startedSpy.count(), 2);
|
||||||
|
TEST_RUNNING_CHANGED(true);
|
||||||
|
TEST_ACTIVE_CHANGED(s1, 3);
|
||||||
|
QCOMPARE(machine.configuration().size(), 1);
|
||||||
|
QVERIFY(machine.configuration().contains(s1));
|
||||||
|
|
||||||
|
int id2 = machine.postDelayedEvent(new StringEvent("a"), std::chrono::seconds{1});
|
||||||
|
QVERIFY(id2 != -1);
|
||||||
|
machine.stop();
|
||||||
|
QTRY_COMPARE(stoppedSpy.count(), 2);
|
||||||
|
TEST_RUNNING_CHANGED(false);
|
||||||
|
TEST_ACTIVE_CHANGED(s1, 3);
|
||||||
|
machine.start();
|
||||||
|
QTRY_COMPARE(startedSpy.count(), 3);
|
||||||
|
TEST_RUNNING_CHANGED(true);
|
||||||
|
QTestEventLoop::instance().enterLoop(2);
|
||||||
|
QCOMPARE(machine.configuration().size(), 1);
|
||||||
|
QVERIFY(machine.configuration().contains(s1));
|
||||||
|
TEST_ACTIVE_CHANGED(s1, 5);
|
||||||
|
QVERIFY(machine.isRunning());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
class DelayedEventWithChronoPosterThread : public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
DelayedEventWithChronoPosterThread(QStateMachine *machine, QObject *parent = 0)
|
||||||
|
: QThread(parent), firstEventWasCancelled(false), m_machine(machine)
|
||||||
|
{
|
||||||
|
moveToThread(this);
|
||||||
|
QObject::connect(m_machine, SIGNAL(started()), this, SLOT(postEvent()));
|
||||||
|
}
|
||||||
|
|
||||||
|
mutable bool firstEventWasCancelled;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void postEvent()
|
||||||
|
{
|
||||||
|
#if __has_include(<chrono>)
|
||||||
|
int id = m_machine->postDelayedEvent(new QEvent(QEvent::User), std::chrono::seconds{1});
|
||||||
|
firstEventWasCancelled = m_machine->cancelDelayedEvent(id);
|
||||||
|
|
||||||
|
m_machine->postDelayedEvent(new QEvent(QEvent::User), std::chrono::milliseconds{1});
|
||||||
|
|
||||||
|
quit();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStateMachine *m_machine;
|
||||||
|
};
|
||||||
|
|
||||||
|
void tst_QStateMachine::postDelayedEventWithChronoFromThread()
|
||||||
|
{
|
||||||
|
#if __has_include(<chrono>)
|
||||||
|
QStateMachine machine;
|
||||||
|
QState *s1 = new QState(&machine);
|
||||||
|
DEFINE_ACTIVE_SPY(s1);
|
||||||
|
QFinalState *f = new QFinalState(&machine);
|
||||||
|
s1->addTransition(new EventTransition(QEvent::User, f));
|
||||||
|
machine.setInitialState(s1);
|
||||||
|
|
||||||
|
DelayedEventWithChronoPosterThread poster(&machine);
|
||||||
|
poster.start();
|
||||||
|
|
||||||
|
QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
|
||||||
|
QVERIFY(runningSpy.isValid());
|
||||||
|
QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
|
||||||
|
QVERIFY(finishedSpy.isValid());
|
||||||
|
machine.start();
|
||||||
|
QTRY_COMPARE(finishedSpy.count(), 1);
|
||||||
|
TEST_RUNNING_CHANGED_STARTED_STOPPED;
|
||||||
|
TEST_ACTIVE_CHANGED(s1, 2);
|
||||||
|
QVERIFY(poster.firstEventWasCancelled);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QStateMachine)
|
QTEST_MAIN(tst_QStateMachine)
|
||||||
#include "tst_qstatemachine.moc"
|
#include "tst_qstatemachine.moc"
|
||||||
|
Loading…
Reference in New Issue
Block a user