1// Copyright (C) 2016 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 QEVENTLOOP_H
5#define QEVENTLOOP_H
6
7#include <QtCore/qobject.h>
8#include <QtCore/qdeadlinetimer.h>
9
10QT_BEGIN_NAMESPACE
11
12class QEventLoopLocker;
13class QEventLoopPrivate;
14
15class Q_CORE_EXPORT QEventLoop : public QObject
16{
17 Q_OBJECT
18 Q_DECLARE_PRIVATE(QEventLoop)
19 friend class QEventLoopLocker;
20
21public:
22 explicit QEventLoop(QObject *parent = nullptr);
23 ~QEventLoop();
24
25 enum ProcessEventsFlag {
26 AllEvents = 0x00,
27 ExcludeUserInputEvents = 0x01,
28 ExcludeSocketNotifiers = 0x02,
29 WaitForMoreEvents = 0x04,
30 X11ExcludeTimers = 0x08,
31 EventLoopExec = 0x20,
32 DialogExec = 0x40,
33 ApplicationExec = 0x80,
34 };
35 Q_DECLARE_FLAGS(ProcessEventsFlags, ProcessEventsFlag)
36 Q_FLAG(ProcessEventsFlags)
37
38 bool processEvents(ProcessEventsFlags flags = AllEvents);
39 void processEvents(ProcessEventsFlags flags, int maximumTime);
40 void processEvents(ProcessEventsFlags flags, QDeadlineTimer deadline);
41
42 int exec(ProcessEventsFlags flags = AllEvents);
43 bool isRunning() const;
44
45 void wakeUp();
46
47 bool event(QEvent *event) override;
48
49public Q_SLOTS:
50 void exit(int returnCode = 0);
51 void quit();
52};
53
54Q_DECLARE_OPERATORS_FOR_FLAGS(QEventLoop::ProcessEventsFlags)
55
56class QEventLoopLockerPrivate;
57
58class QEventLoopLocker
59{
60public:
61 Q_NODISCARD_CTOR Q_CORE_EXPORT QEventLoopLocker() noexcept;
62 Q_NODISCARD_CTOR Q_CORE_EXPORT explicit QEventLoopLocker(QEventLoop *loop) noexcept;
63 Q_NODISCARD_CTOR Q_CORE_EXPORT explicit QEventLoopLocker(QThread *thread) noexcept;
64 Q_CORE_EXPORT ~QEventLoopLocker();
65
66 Q_NODISCARD_CTOR QEventLoopLocker(QEventLoopLocker &&other) noexcept
67 : p{std::exchange(obj&: other.p, new_val: 0)} {}
68 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QEventLoopLocker)
69
70 void swap(QEventLoopLocker &other) noexcept { std::swap(a&: p, b&: other.p); }
71 friend void swap(QEventLoopLocker &lhs, QEventLoopLocker &rhs) noexcept { lhs.swap(other&: rhs); }
72
73private:
74 Q_DISABLE_COPY(QEventLoopLocker)
75 friend class QEventLoopLockerPrivate;
76
77 //
78 // Private implementation details.
79 // Do not call from public inline API!
80 //
81 enum class Type : quintptr {
82 EventLoop,
83 Thread,
84 Application,
85 };
86 explicit QEventLoopLocker(void *ptr, Type t) noexcept;
87 quintptr p;
88 static constexpr quintptr TypeMask = 0x3;
89 Type type() const { return Type(p & TypeMask); }
90 void *pointer() const { return reinterpret_cast<void *>(p & ~TypeMask); }
91 template <typename Func>
92 void visit(Func func) const;
93};
94
95QT_END_NAMESPACE
96
97#endif // QEVENTLOOP_H
98