goud_engine/core/event/queue.rs
1//! Double-buffered event queue storage.
2
3use crate::core::event::traits::Event;
4
5/// Double-buffered event queue for storing events of a single type.
6///
7/// EventQueue uses a double-buffer pattern where events are written to the
8/// active buffer and read from the inactive buffer. At the end of each frame,
9/// `swap_buffers` is called to switch which buffer is active.
10///
11/// # Double-Buffer Pattern
12///
13/// ```text
14/// Frame N:
15/// - Systems write new events to Buffer A (active write buffer)
16/// - Systems read events from Buffer B (read buffer from Frame N-1)
17///
18/// End of Frame N: swap_buffers()
19///
20/// Frame N+1:
21/// - Systems write new events to Buffer B (now active write buffer)
22/// - Systems read events from Buffer A (read buffer from Frame N)
23/// ```
24///
25/// This pattern ensures:
26/// - Writers and readers never access the same buffer simultaneously
27/// - Events persist for exactly one frame after being written
28/// - No locking required within a single-threaded frame
29///
30/// # Example
31///
32/// ```rust
33/// use goud_engine::core::event::EventQueue;
34///
35/// #[derive(Debug, Clone, PartialEq)]
36/// struct DamageEvent { amount: u32 }
37///
38/// let mut queue: EventQueue<DamageEvent> = EventQueue::new();
39///
40/// // Write to active buffer
41/// queue.send(DamageEvent { amount: 10 });
42/// queue.send(DamageEvent { amount: 25 });
43///
44/// // Read buffer is empty (events are in write buffer)
45/// assert!(queue.drain().collect::<Vec<_>>().is_empty());
46///
47/// // Swap buffers at frame boundary
48/// queue.swap_buffers();
49///
50/// // Now we can read the events
51/// let events: Vec<_> = queue.drain().collect();
52/// assert_eq!(events.len(), 2);
53/// assert_eq!(events[0].amount, 10);
54/// assert_eq!(events[1].amount, 25);
55/// ```
56pub struct EventQueue<E: Event> {
57 /// First buffer for events
58 events_a: Vec<E>,
59 /// Second buffer for events
60 events_b: Vec<E>,
61 /// Which buffer is currently the write buffer.
62 /// - false: Buffer A is write, Buffer B is read
63 /// - true: Buffer B is write, Buffer A is read
64 active_buffer: bool,
65}
66
67impl<E: Event> EventQueue<E> {
68 /// Creates a new empty EventQueue.
69 ///
70 /// Both buffers start empty, and Buffer A is the initial write buffer.
71 ///
72 /// # Example
73 ///
74 /// ```rust
75 /// use goud_engine::core::event::EventQueue;
76 ///
77 /// struct MyEvent { data: i32 }
78 /// let queue: EventQueue<MyEvent> = EventQueue::new();
79 /// assert!(queue.is_empty());
80 /// ```
81 #[must_use]
82 pub fn new() -> Self {
83 Self {
84 events_a: Vec::new(),
85 events_b: Vec::new(),
86 active_buffer: false,
87 }
88 }
89
90 /// Sends an event to the write buffer.
91 ///
92 /// The event will be available for reading after the next `swap_buffers` call.
93 ///
94 /// # Example
95 ///
96 /// ```rust
97 /// use goud_engine::core::event::EventQueue;
98 ///
99 /// struct ScoreEvent { points: i32 }
100 /// let mut queue: EventQueue<ScoreEvent> = EventQueue::new();
101 ///
102 /// queue.send(ScoreEvent { points: 100 });
103 /// queue.send(ScoreEvent { points: 50 });
104 ///
105 /// assert_eq!(queue.len(), 2);
106 /// ```
107 pub fn send(&mut self, event: E) {
108 self.write_buffer_mut().push(event);
109 }
110
111 /// Drains all events from the read buffer, returning an iterator.
112 ///
113 /// After draining, the read buffer will be empty. This is the primary
114 /// way to consume events during a frame.
115 ///
116 /// # Example
117 ///
118 /// ```rust
119 /// use goud_engine::core::event::EventQueue;
120 ///
121 /// #[derive(Debug)]
122 /// struct Event { id: u32 }
123 ///
124 /// let mut queue: EventQueue<Event> = EventQueue::new();
125 /// queue.send(Event { id: 1 });
126 /// queue.send(Event { id: 2 });
127 /// queue.swap_buffers();
128 ///
129 /// for event in queue.drain() {
130 /// println!("Processing event: {:?}", event);
131 /// }
132 /// ```
133 pub fn drain(&mut self) -> impl Iterator<Item = E> + '_ {
134 self.read_buffer_mut().drain(..)
135 }
136
137 /// Swaps the active and read buffers.
138 ///
139 /// This should be called exactly once per frame, typically at the frame
140 /// boundary. After swapping:
141 /// - The old write buffer becomes the new read buffer
142 /// - The old read buffer (now cleared) becomes the new write buffer
143 ///
144 /// # Example
145 ///
146 /// ```rust
147 /// use goud_engine::core::event::EventQueue;
148 ///
149 /// struct FrameEvent;
150 /// let mut queue: EventQueue<FrameEvent> = EventQueue::new();
151 ///
152 /// // Frame 1: send events
153 /// queue.send(FrameEvent);
154 ///
155 /// // End of Frame 1
156 /// queue.swap_buffers();
157 ///
158 /// // Frame 2: events from Frame 1 are now readable
159 /// let count = queue.drain().count();
160 /// assert_eq!(count, 1);
161 /// ```
162 pub fn swap_buffers(&mut self) {
163 // Clear the read buffer before it becomes the write buffer
164 self.read_buffer_mut().clear();
165 // Swap which buffer is active
166 self.active_buffer = !self.active_buffer;
167 }
168
169 /// Clears both buffers, removing all events.
170 ///
171 /// This is useful for resetting the event system, such as when
172 /// transitioning between game states.
173 ///
174 /// # Example
175 ///
176 /// ```rust
177 /// use goud_engine::core::event::EventQueue;
178 ///
179 /// struct Event;
180 /// let mut queue: EventQueue<Event> = EventQueue::new();
181 ///
182 /// queue.send(Event);
183 /// queue.swap_buffers();
184 /// queue.send(Event);
185 ///
186 /// queue.clear();
187 ///
188 /// assert!(queue.is_empty());
189 /// assert!(queue.drain().next().is_none());
190 /// ```
191 pub fn clear(&mut self) {
192 self.events_a.clear();
193 self.events_b.clear();
194 }
195
196 /// Returns `true` if the write buffer has no pending events.
197 ///
198 /// Note: This only checks the write buffer. The read buffer may still
199 /// contain events from the previous frame.
200 ///
201 /// # Example
202 ///
203 /// ```rust
204 /// use goud_engine::core::event::EventQueue;
205 ///
206 /// struct Event;
207 /// let mut queue: EventQueue<Event> = EventQueue::new();
208 ///
209 /// assert!(queue.is_empty());
210 ///
211 /// queue.send(Event);
212 /// assert!(!queue.is_empty());
213 /// ```
214 #[must_use]
215 pub fn is_empty(&self) -> bool {
216 self.write_buffer().is_empty()
217 }
218
219 /// Returns the number of events in the write buffer.
220 ///
221 /// Note: This only counts events in the write buffer (pending events).
222 /// Use `read_len()` to count events available for reading.
223 ///
224 /// # Example
225 ///
226 /// ```rust
227 /// use goud_engine::core::event::EventQueue;
228 ///
229 /// struct Event;
230 /// let mut queue: EventQueue<Event> = EventQueue::new();
231 ///
232 /// assert_eq!(queue.len(), 0);
233 ///
234 /// queue.send(Event);
235 /// queue.send(Event);
236 /// queue.send(Event);
237 ///
238 /// assert_eq!(queue.len(), 3);
239 /// ```
240 #[must_use]
241 pub fn len(&self) -> usize {
242 self.write_buffer().len()
243 }
244
245 /// Returns the number of events available for reading.
246 ///
247 /// # Example
248 ///
249 /// ```rust
250 /// use goud_engine::core::event::EventQueue;
251 ///
252 /// struct Event;
253 /// let mut queue: EventQueue<Event> = EventQueue::new();
254 ///
255 /// queue.send(Event);
256 /// queue.send(Event);
257 ///
258 /// // Events are in write buffer, not yet readable
259 /// assert_eq!(queue.read_len(), 0);
260 ///
261 /// queue.swap_buffers();
262 ///
263 /// // Now they're in the read buffer
264 /// assert_eq!(queue.read_len(), 2);
265 /// ```
266 #[must_use]
267 pub fn read_len(&self) -> usize {
268 self.read_buffer().len()
269 }
270
271 /// Returns a reference to the write buffer.
272 #[inline]
273 fn write_buffer(&self) -> &Vec<E> {
274 if self.active_buffer {
275 &self.events_b
276 } else {
277 &self.events_a
278 }
279 }
280
281 /// Returns a mutable reference to the write buffer.
282 #[inline]
283 fn write_buffer_mut(&mut self) -> &mut Vec<E> {
284 if self.active_buffer {
285 &mut self.events_b
286 } else {
287 &mut self.events_a
288 }
289 }
290
291 /// Returns a reference to the read buffer.
292 ///
293 /// This is exposed for use by [`crate::core::event::EventReader`] to access events without draining.
294 #[inline]
295 pub fn read_buffer(&self) -> &Vec<E> {
296 if self.active_buffer {
297 &self.events_a
298 } else {
299 &self.events_b
300 }
301 }
302
303 /// Returns a mutable reference to the read buffer.
304 #[inline]
305 fn read_buffer_mut(&mut self) -> &mut Vec<E> {
306 if self.active_buffer {
307 &mut self.events_a
308 } else {
309 &mut self.events_b
310 }
311 }
312}
313
314impl<E: Event> Default for EventQueue<E> {
315 fn default() -> Self {
316 Self::new()
317 }
318}