1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QTESTSUPPORT_CORE_H
5#define QTESTSUPPORT_CORE_H
6
7#include <QtCore/qcoreapplication.h>
8#include <QtCore/qdeadlinetimer.h>
9#include <QtCore/qthread.h>
10
11QT_BEGIN_NAMESPACE
12
13namespace QTest {
14
15Q_CORE_EXPORT void qSleep(int ms);
16
17template <typename Functor>
18[[nodiscard]] static bool qWaitFor(Functor predicate, int timeout = 5000)
19{
20 // We should not spin the event loop in case the predicate is already true,
21 // otherwise we might send new events that invalidate the predicate.
22 if (predicate())
23 return true;
24
25 // qWait() is expected to spin the event loop, even when called with a small
26 // timeout like 1ms, so we we can't use a simple while-loop here based on
27 // the deadline timer not having timed out. Use do-while instead.
28
29 int remaining = timeout;
30 QDeadlineTimer deadline(remaining, Qt::PreciseTimer);
31
32 do {
33 // We explicitly do not pass the remaining time to processEvents, as
34 // that would keep spinning processEvents for the whole duration if
35 // new events were posted as part of processing events, and we need
36 // to return back to this function to check the predicate between
37 // each pass of processEvents. Our own timer will take care of the
38 // timeout.
39 QCoreApplication::processEvents(flags: QEventLoop::AllEvents);
40 QCoreApplication::sendPostedEvents(receiver: nullptr, event_type: QEvent::DeferredDelete);
41
42 if (predicate())
43 return true;
44
45 remaining = int(deadline.remainingTime());
46 if (remaining > 0)
47 qSleep(ms: qMin(a: 10, b: remaining));
48 remaining = int(deadline.remainingTime());
49 } while (remaining > 0);
50
51 return predicate(); // Last chance
52}
53
54Q_CORE_EXPORT void qWait(int ms);
55
56} // namespace QTest
57
58QT_END_NAMESPACE
59
60#endif
61

source code of qtbase/src/corelib/kernel/qtestsupport_core.h