goud_engine/ecs/system/system_param/
event_params.rs1use std::marker::PhantomData;
7
8use crate::core::event::{Event, Events};
9use crate::ecs::query::Access;
10use crate::ecs::resource::{Res, ResMut, ResourceId};
11use crate::ecs::World;
12
13use super::traits::{ReadOnlySystemParam, SystemParam, SystemParamState};
14
15pub struct EcsEventReaderState<E: Event> {
24 cursor: usize,
28 _marker: PhantomData<fn() -> E>,
29}
30
31impl<E: Event> SystemParamState for EcsEventReaderState<E> {
32 fn init(_world: &mut World) -> Self {
33 Self {
34 cursor: 0,
35 _marker: PhantomData,
36 }
37 }
38}
39
40pub struct EcsEventReader<'w, 's, E: Event> {
61 events: &'w Events<E>,
62 cursor: &'s mut usize,
63}
64
65impl<'w, 's, E: Event> EcsEventReader<'w, 's, E> {
66 pub fn read(&mut self) -> impl Iterator<Item = &'w E> {
71 let buffer = self.events.read_buffer();
72 let start = (*self.cursor).min(buffer.len());
74 *self.cursor = buffer.len();
75 buffer[start..].iter()
76 }
77
78 #[must_use]
80 pub fn is_empty(&self) -> bool {
81 let buffer = self.events.read_buffer();
82 (*self.cursor).min(buffer.len()) >= buffer.len()
83 }
84
85 #[must_use]
87 pub fn len(&self) -> usize {
88 let buffer = self.events.read_buffer();
89 buffer.len().saturating_sub(*self.cursor)
90 }
91}
92
93impl<E: Event> SystemParam for EcsEventReader<'_, '_, E> {
94 type State = EcsEventReaderState<E>;
95 type Item<'w, 's> = EcsEventReader<'w, 's, E>;
96
97 fn update_access(_state: &Self::State, access: &mut Access) {
98 access.add_resource_read(ResourceId::of::<Events<E>>());
99 }
100
101 fn get_param<'w, 's>(state: &'s mut Self::State, world: &'w World) -> Self::Item<'w, 's> {
102 let events: Res<'w, Events<E>> = world
103 .resource::<Events<E>>()
104 .expect("Events<E> resource not found. Insert it with world.insert_resource(Events::<E>::new()).");
105 let events_ref: &'w Events<E> = events.into_inner();
106 EcsEventReader {
107 events: events_ref,
108 cursor: &mut state.cursor,
109 }
110 }
111}
112
113impl<E: Event> ReadOnlySystemParam for EcsEventReader<'_, '_, E> {}
115
116pub struct EcsEventWriterState<E: Event> {
124 _marker: PhantomData<fn() -> E>,
125}
126
127impl<E: Event> SystemParamState for EcsEventWriterState<E> {
128 fn init(_world: &mut World) -> Self {
129 Self {
130 _marker: PhantomData,
131 }
132 }
133}
134
135pub struct EcsEventWriter<'w, E: Event> {
148 events: ResMut<'w, Events<E>>,
149}
150
151impl<E: Event> EcsEventWriter<'_, E> {
152 pub fn send(&mut self, event: E) {
154 self.events.send(event);
155 }
156
157 pub fn send_batch(&mut self, events: impl IntoIterator<Item = E>) {
159 self.events.send_batch(events);
160 }
161}
162
163impl<E: Event> SystemParam for EcsEventWriter<'_, E> {
164 type State = EcsEventWriterState<E>;
165 type Item<'w, 's> = EcsEventWriter<'w, E>;
166
167 fn update_access(_state: &Self::State, access: &mut Access) {
168 access.add_resource_write(ResourceId::of::<Events<E>>());
169 }
170
171 fn get_param<'w, 's>(_state: &'s mut Self::State, _world: &'w World) -> Self::Item<'w, 's> {
172 panic!("EcsEventWriter<E> requires mutable world access. Use get_param_mut instead.");
173 }
174
175 fn get_param_mut<'w, 's>(
176 _state: &'s mut Self::State,
177 world: &'w mut World,
178 ) -> Self::Item<'w, 's> {
179 let events = world
180 .resource_mut::<Events<E>>()
181 .expect("Events<E> resource not found. Insert it with world.insert_resource(Events::<E>::new()).");
182 EcsEventWriter { events }
183 }
184}
185
186