FINAL CUT
eventloop.h
1 /***********************************************************************
2 * eventloop.h - Implements the event loop *
3 * *
4 * This file is part of the FINAL CUT widget toolkit *
5 * *
6 * Copyright 2023-2026 Andreas Noe *
7 * *
8 * FINAL CUT is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as *
10 * published by the Free Software Foundation; either version 3 of *
11 * the License, or (at your option) any later version. *
12 * *
13 * FINAL CUT is distributed in the hope that it will be useful, but *
14 * WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this program. If not, see *
20 * <http://www.gnu.org/licenses/>. *
21 ***********************************************************************/
22 
23 /* Standalone class
24  * ════════════════
25  *
26  * ▕▔▔▔▔▔▔▔▔▔▔▔▏
27  * ▕ EventLoop ▏
28  * ▕▁▁▁▁▁▁▁▁▁▁▁▏
29  */
30 
31 #ifndef EVENTLOOP_H
32 #define EVENTLOOP_H
33 
34 #include <atomic>
35 #include <list>
36 #include <poll.h>
37 #include <thread>
38 
39 #include "final/eventloop/monitor.h"
40 #include "final/util/fstring.h"
41 
42 namespace finalcut
43 {
44 
45 //----------------------------------------------------------------------
46 // class EventLoop
47 //----------------------------------------------------------------------
48 
49 class EventLoop
50 {
51  public:
52  // Enumeration
53  enum class PollResult : uInt8
54  {
55  Success,
56  Timeout,
57  Error,
58  Interrupted
59  };
60 
61  // Constructor
62  EventLoop() = default;
63 
64  // Disable copy constructor
65  EventLoop (const EventLoop&) = delete;
66 
67  // Disable move constructor
68  EventLoop (EventLoop&&) = delete;
69 
70  // Destructor
71  ~EventLoop() = default;
72 
73  // Disable copy assignment operator (=)
74  auto operator = (const EventLoop&) -> EventLoop& = delete;
75 
76  // Disable move assignment operator (=)
77  auto operator = (EventLoop&&) noexcept -> EventLoop& = delete;
78 
79  // Accessor
80  auto getClassName() const -> FString;
81 
82  // Methods
83  auto run() -> int;
84  void leave() noexcept;
85 
86  private:
87  // Constants
88  static constexpr std::size_t DEFAULT_MONITOR_CAPACITY{64};
89  static constexpr auto WAIT_INDEFINITELY{-1};
90  static constexpr int POLL_WAIT_MS{1};
91 
92  // Predicate
93  auto isRunning() const noexcept -> bool;
94  auto isChanged() const noexcept -> bool;
95 
96  // Methods
97  void reserveInitialCapacity();
98  void nonPollWaiting() const noexcept;
99  void rebuildPollStructures();
100  auto processNextEvents() -> bool;
101  auto processPoll (int&) -> PollResult;
102  void dispatcher (int, nfds_t);
103  void addMonitor (Monitor*);
104  void removeMonitor (Monitor*);
105 
106  // Data members
107  std::atomic<bool> running{false};
108  std::atomic<bool> monitors_changed{false};
109  std::vector<Monitor*> monitors{};
110 
111  // Cached poll structures - rebuilt when monitors change
112  std::vector<struct pollfd> cached_fds{};
113  std::vector<Monitor*> cached_lookup{};
114 
115  // Friend classes
116  friend class Monitor;
117 };
118 
119 // EventLoop inline functions
120 //----------------------------------------------------------------------
121 inline auto EventLoop::getClassName() const -> FString
122 { return "EventLoop"; }
123 
124 //----------------------------------------------------------------------
125 inline void EventLoop::leave() noexcept
126 { running.store(false); }
127 
128 //----------------------------------------------------------------------
129 inline auto EventLoop::isRunning() const noexcept -> bool
130 { return running.load(); }
131 
132 //----------------------------------------------------------------------
133 inline auto EventLoop::isChanged() const noexcept -> bool
134 { return monitors_changed.load(); }
135 
136 //----------------------------------------------------------------------
137 inline void EventLoop::reserveInitialCapacity()
138 {
139  // Reserve initial capacity to avoid frequent reallocations
140  monitors.reserve(DEFAULT_MONITOR_CAPACITY);
141  cached_fds.reserve(DEFAULT_MONITOR_CAPACITY);
142  cached_lookup.reserve(DEFAULT_MONITOR_CAPACITY);
143 }
144 
145 } // namespace finalcut
146 
147 #endif // EVENTLOOP_H
Definition: monitor.h:82
Definition: eventloop.h:49
Definition: class_template.cpp:25
Definition: fstring.h:82