Fcitx
eventloopinterface.h
1 /*
2  * SPDX-FileCopyrightText: 2024-2024 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 #ifndef _FCITX_UTILS_EVENTLOOPINTERFACE_H_
8 #define _FCITX_UTILS_EVENTLOOPINTERFACE_H_
9 
10 #include <sys/types.h>
11 #include <cstdint>
12 #include <functional>
13 #include <memory>
14 #include <stdexcept>
15 #include <fcitx-utils/fcitxutils_export.h>
16 #include <fcitx-utils/flags.h>
17 #include <fcitx-utils/macros.h>
18 
19 #if defined(_WIN32)
20 #include <pthread.h>
21 #endif
22 
23 namespace fcitx {
24 
25 enum class IOEventFlag {
26  In = (1 << 0),
27  Out = (1 << 1),
28  Err = (1 << 2),
29  Hup = (1 << 3),
30  EdgeTrigger = (1 << 4),
31 };
32 
33 using IOEventFlags = Flags<IOEventFlag>;
34 
35 class FCITXUTILS_EXPORT EventLoopException : public std::runtime_error {
36 public:
37  EventLoopException(int error);
38 
39  FCITX_NODISCARD int error() const { return errno_; }
40 
41 private:
42  int errno_;
43 };
44 
45 struct FCITXUTILS_EXPORT EventSource {
46  virtual ~EventSource();
47  FCITX_NODISCARD virtual bool isEnabled() const = 0;
48  virtual void setEnabled(bool enabled) = 0;
49  FCITX_NODISCARD virtual bool isOneShot() const = 0;
50  virtual void setOneShot() = 0;
51 };
52 
53 struct FCITXUTILS_EXPORT EventSourceIO : public EventSource {
54  FCITX_NODISCARD virtual int fd() const = 0;
55  virtual void setFd(int fd) = 0;
56  FCITX_NODISCARD virtual IOEventFlags events() const = 0;
57  virtual void setEvents(IOEventFlags flags) = 0;
58  FCITX_NODISCARD virtual IOEventFlags revents() const = 0;
59 };
60 
61 struct FCITXUTILS_EXPORT EventSourceTime : public EventSource {
62  virtual void setNextInterval(uint64_t time);
63  FCITX_NODISCARD virtual uint64_t time() const = 0;
64  virtual void setTime(uint64_t time) = 0;
65  FCITX_NODISCARD virtual uint64_t accuracy() const = 0;
66  virtual void setAccuracy(uint64_t accuracy) = 0;
67  FCITX_NODISCARD virtual clockid_t clock() const = 0;
68 };
69 
70 /**
71  * A thread-safe event source can be triggered from other threads.
72  *
73  * @since 5.1.13
74  */
75 struct FCITXUTILS_EXPORT EventSourceAsync : public EventSource {
76  /**
77  * Trigger the event from other thread.
78  *
79  * The callback is guaranteed to be called send() if it is enabled.
80  * Multiple call to send() may only trigger the callback once.
81  */
82  virtual void send() = 0;
83 };
84 
85 using IOCallback =
86  std::function<bool(EventSourceIO *, int fd, IOEventFlags flags)>;
87 using TimeCallback = std::function<bool(EventSourceTime *, uint64_t usec)>;
88 using EventCallback = std::function<bool(EventSource *)>;
89 
90 FCITXUTILS_EXPORT uint64_t now(clockid_t clock);
91 
92 /**
93  * @brief Abstract Event Loop
94  *
95  * @since 5.1.12
96  */
97 class FCITXUTILS_EXPORT EventLoopInterface {
98 public:
99  virtual ~EventLoopInterface();
100 
101  /**
102  * @brief Execute event loop
103  *
104  * @return true if event loop is exited successfully.
105  */
106  virtual bool exec() = 0;
107 
108  /**
109  * @brief Quit event loop
110  *
111  * Request event loop to quit, pending event may still be executed before
112  * quit. Also execute exit event right before exiting.
113  *
114  * @see EventLoopInterface::addExitEvent
115  */
116  virtual void exit() = 0;
117 
118  /**
119  * @brief Return a static implementation name of event loop
120  *
121  * Fcitx right now supports sd-event and libuv as implementation.
122  * The library being used is decided at build time.
123  *
124  * @return Name of event loop implementation
125  */
126  virtual const char *implementation() const = 0;
127 
128  /**
129  * @brief Return the internal native handle to the event loop.
130  *
131  * This can be useful if you want to use the underlying API against
132  * event loop.
133  *
134  * For libuv, it will be uv_loop_t*.
135  * For sd-event, it will be sd_event*.
136  *
137  * @return internal implementation
138  * @see implementation
139  */
140  virtual void *nativeHandle() = 0;
141 
142  FCITX_NODISCARD std::unique_ptr<EventSourceIO> virtual addIOEvent(
143  int fd, IOEventFlags flags, IOCallback callback) = 0;
144  FCITX_NODISCARD std::unique_ptr<EventSourceTime> virtual addTimeEvent(
145  clockid_t clock, uint64_t usec, uint64_t accuracy,
146  TimeCallback callback) = 0;
147  FCITX_NODISCARD virtual std::unique_ptr<EventSource>
148  addExitEvent(EventCallback callback) = 0;
149  FCITX_NODISCARD virtual std::unique_ptr<EventSource>
150  addDeferEvent(EventCallback callback) = 0;
151  FCITX_NODISCARD virtual std::unique_ptr<EventSource>
152  addPostEvent(EventCallback callback) = 0;
153 };
154 
155 class FCITXUTILS_EXPORT EventLoopInterfaceV2 : public EventLoopInterface {
156 public:
157  FCITX_NODISCARD virtual std::unique_ptr<EventSourceAsync>
158  addAsyncEvent(EventCallback callback) = 0;
159 };
160 
161 } // namespace fcitx
162 
163 #endif // _FCITX_UTILS_EVENTLOOPINTERFACE_H_
Definition: action.cpp:17
Abstract Event Loop.
A thread-safe event source can be triggered from other threads.
Helper template class to make easier to use type safe enum flags.