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 | |
11 | QT_BEGIN_NAMESPACE |
12 | |
13 | namespace QTest { |
14 | |
15 | Q_CORE_EXPORT void qSleep(int ms); |
16 | |
17 | template <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 | |
54 | Q_CORE_EXPORT void qWait(int ms); |
55 | |
56 | } // namespace QTest |
57 | |
58 | QT_END_NAMESPACE |
59 | |
60 | #endif |
61 | |