Skip to main content

goud_engine/core/event/
reader.rs

1//! Event reader types for consuming events from a queue.
2
3use crate::core::event::{queue::EventQueue, traits::Event};
4
5/// Read-only accessor for consuming events from an [`EventQueue`].
6///
7/// `EventReader` provides a way for systems to read events without consuming
8/// them immediately. It tracks a read index to ensure events are not read
9/// multiple times within the same frame by the same reader.
10///
11/// # Multiple Readers
12///
13/// Multiple `EventReader` instances can exist for the same queue (shared borrow).
14/// Each reader maintains its own read position, allowing different systems to
15/// read the same events independently.
16///
17/// # Read Tracking
18///
19/// The reader tracks which events have been read via an internal index. When
20/// `read()` is called, it returns only unread events and advances the index.
21/// This prevents double-processing of events within a single system.
22///
23/// # Example
24///
25/// ```rust
26/// use goud_engine::core::event::{EventQueue, EventReader};
27///
28/// #[derive(Debug, Clone)]
29/// struct DamageEvent { amount: u32 }
30///
31/// let mut queue: EventQueue<DamageEvent> = EventQueue::new();
32/// queue.send(DamageEvent { amount: 10 });
33/// queue.send(DamageEvent { amount: 25 });
34/// queue.swap_buffers();
35///
36/// // Create a reader
37/// let mut reader = EventReader::new(&queue);
38///
39/// // First read gets both events
40/// let events: Vec<_> = reader.read().collect();
41/// assert_eq!(events.len(), 2);
42///
43/// // Second read gets nothing (already read)
44/// let events: Vec<_> = reader.read().collect();
45/// assert!(events.is_empty());
46/// ```
47pub struct EventReader<'a, E: Event> {
48    /// Reference to the event queue
49    queue: &'a EventQueue<E>,
50    /// Index of the next unread event in the read buffer
51    read_index: usize,
52}
53
54impl<'a, E: Event> EventReader<'a, E> {
55    /// Creates a new `EventReader` for the given queue.
56    ///
57    /// The reader starts at index 0, meaning it will read all available events
58    /// in the read buffer on the first call to `read()`.
59    ///
60    /// # Example
61    ///
62    /// ```rust
63    /// use goud_engine::core::event::{EventQueue, EventReader};
64    ///
65    /// struct MyEvent { data: i32 }
66    ///
67    /// let queue: EventQueue<MyEvent> = EventQueue::new();
68    /// let reader = EventReader::new(&queue);
69    /// assert!(reader.is_empty());
70    /// ```
71    #[must_use]
72    pub fn new(queue: &'a EventQueue<E>) -> Self {
73        Self {
74            queue,
75            read_index: 0,
76        }
77    }
78
79    /// Returns an iterator over unread events.
80    ///
81    /// Each call to `read()` returns only events that haven't been read by
82    /// this reader instance yet. The read index is advanced after iteration.
83    ///
84    /// # Example
85    ///
86    /// ```rust
87    /// use goud_engine::core::event::{EventQueue, EventReader};
88    ///
89    /// #[derive(Debug)]
90    /// struct ScoreEvent { points: i32 }
91    ///
92    /// let mut queue: EventQueue<ScoreEvent> = EventQueue::new();
93    /// queue.send(ScoreEvent { points: 100 });
94    /// queue.send(ScoreEvent { points: 50 });
95    /// queue.swap_buffers();
96    ///
97    /// let mut reader = EventReader::new(&queue);
98    ///
99    /// // Read all events
100    /// for event in reader.read() {
101    ///     println!("Score: {}", event.points);
102    /// }
103    /// ```
104    pub fn read(&mut self) -> EventReaderIter<'_, 'a, E> {
105        EventReaderIter { reader: self }
106    }
107
108    /// Returns `true` if there are no unread events.
109    ///
110    /// This checks if all events in the read buffer have been consumed by
111    /// this reader.
112    ///
113    /// # Example
114    ///
115    /// ```rust
116    /// use goud_engine::core::event::{EventQueue, EventReader};
117    ///
118    /// struct Event;
119    ///
120    /// let mut queue: EventQueue<Event> = EventQueue::new();
121    /// queue.send(Event);
122    /// queue.swap_buffers();
123    ///
124    /// let mut reader = EventReader::new(&queue);
125    /// assert!(!reader.is_empty());
126    ///
127    /// // Consume all events
128    /// let _ = reader.read().count();
129    /// assert!(reader.is_empty());
130    /// ```
131    #[must_use]
132    pub fn is_empty(&self) -> bool {
133        self.read_index >= self.queue.read_len()
134    }
135
136    /// Returns the number of unread events.
137    ///
138    /// # Example
139    ///
140    /// ```rust
141    /// use goud_engine::core::event::{EventQueue, EventReader};
142    ///
143    /// struct Event;
144    ///
145    /// let mut queue: EventQueue<Event> = EventQueue::new();
146    /// queue.send(Event);
147    /// queue.send(Event);
148    /// queue.send(Event);
149    /// queue.swap_buffers();
150    ///
151    /// let mut reader = EventReader::new(&queue);
152    /// assert_eq!(reader.len(), 3);
153    ///
154    /// // Read one event
155    /// let _ = reader.read().next();
156    /// assert_eq!(reader.len(), 2);
157    /// ```
158    #[must_use]
159    pub fn len(&self) -> usize {
160        self.queue.read_len().saturating_sub(self.read_index)
161    }
162
163    /// Clears the reader's position, allowing events to be re-read.
164    ///
165    /// This resets the read index to 0. The next call to `read()` will
166    /// return all events in the read buffer again.
167    ///
168    /// # Example
169    ///
170    /// ```rust
171    /// use goud_engine::core::event::{EventQueue, EventReader};
172    ///
173    /// #[derive(Debug, Clone)]
174    /// struct Event { id: u32 }
175    ///
176    /// let mut queue: EventQueue<Event> = EventQueue::new();
177    /// queue.send(Event { id: 1 });
178    /// queue.swap_buffers();
179    ///
180    /// let mut reader = EventReader::new(&queue);
181    ///
182    /// // Read all events
183    /// let count1 = reader.read().count();
184    /// assert_eq!(count1, 1);
185    ///
186    /// // Nothing left to read
187    /// let count2 = reader.read().count();
188    /// assert_eq!(count2, 0);
189    ///
190    /// // Reset and read again
191    /// reader.clear();
192    /// let count3 = reader.read().count();
193    /// assert_eq!(count3, 1);
194    /// ```
195    pub fn clear(&mut self) {
196        self.read_index = 0;
197    }
198}
199
200/// Iterator over unread events from an [`EventReader`].
201///
202/// This iterator is returned by [`EventReader::read()`] and yields references
203/// to events that haven't been read yet by this reader.
204pub struct EventReaderIter<'r, 'a, E: Event> {
205    pub(crate) reader: &'r mut EventReader<'a, E>,
206}
207
208impl<'r, 'a, E: Event> Iterator for EventReaderIter<'r, 'a, E> {
209    type Item = &'a E;
210
211    fn next(&mut self) -> Option<Self::Item> {
212        let buffer = self.reader.queue.read_buffer();
213        if self.reader.read_index < buffer.len() {
214            let event = &buffer[self.reader.read_index];
215            self.reader.read_index += 1;
216            Some(event)
217        } else {
218            None
219        }
220    }
221
222    fn size_hint(&self) -> (usize, Option<usize>) {
223        let remaining = self.reader.len();
224        (remaining, Some(remaining))
225    }
226}
227
228impl<'r, 'a, E: Event> ExactSizeIterator for EventReaderIter<'r, 'a, E> {}