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> {}