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