diff --git a/crates/bevy_app/src/event/event.rs b/crates/bevy_app/src/event/event.rs index dc6c9cee90..76c6d79f0c 100644 --- a/crates/bevy_app/src/event/event.rs +++ b/crates/bevy_app/src/event/event.rs @@ -35,12 +35,12 @@ enum State { /// events.send(MyEvent { value: 1 }); /// /// // somewhere else: read the events -/// for event in events.iter(&mut reader) { +/// for event in reader.iter(&events) { /// assert_eq!(event.value, 1) /// } /// /// // events are only processed once per reader -/// assert_eq!(events.iter(&mut reader).count(), 0); +/// assert_eq!(reader.iter(&events).count(), 0); /// ``` /// /// # Details @@ -93,6 +93,81 @@ pub struct EventReader { _marker: PhantomData, } +impl EventReader +where + T: Send + Sync + 'static, +{ + /// Iterates over the events this EventReader has not seen yet. This updates the EventReader's + /// event counter, which means subsequent event reads will not include events that happened before now. + pub fn iter<'a>(&mut self, events: &'a Events) -> impl DoubleEndedIterator { + // if the reader has seen some of the events in a buffer, find the proper index offset. + // otherwise read all events in the buffer + let a_index = if self.last_event_count > events.a_start_event_count { + self.last_event_count - events.a_start_event_count + } else { + 0 + }; + let b_index = if self.last_event_count > events.b_start_event_count { + self.last_event_count - events.b_start_event_count + } else { + 0 + }; + self.last_event_count = events.event_count; + match events.state { + State::A => events + .events_b + .get(b_index..) + .unwrap_or_else(|| &[]) + .iter() + .map(map_event_instance) + .chain( + events + .events_a + .get(a_index..) + .unwrap_or_else(|| &[]) + .iter() + .map(map_event_instance), + ), + State::B => events + .events_a + .get(a_index..) + .unwrap_or_else(|| &[]) + .iter() + .map(map_event_instance) + .chain( + events + .events_b + .get(b_index..) + .unwrap_or_else(|| &[]) + .iter() + .map(map_event_instance), + ), + } + } + + /// Retrieves the latest event that this EventReader hasn't seen yet. This updates the EventReader's + /// event counter, which means subsequent event reads will not include events that happened before now. + pub fn latest<'a>(&mut self, events: &'a Events) -> Option<&'a T> { + self.iter(events).rev().next() + } + + /// Retrieves the latest event that matches the given `predicate` that this reader hasn't seen yet. This updates the EventReader's + /// event counter, which means subsequent event reads will not include events that happened before now. + pub fn find_latest<'a>( + &mut self, + events: &'a Events, + predicate: impl FnMut(&&T) -> bool, + ) -> Option<&'a T> { + self.iter(events).rev().filter(predicate).next() + } + + /// Retrieves the earliest event in `events` that this reader hasn't seen yet. This updates the EventReader's + /// event counter, which means subsequent event reads will not include events that happened before now. + pub fn earliest<'a>(&mut self, events: &'a Events) -> Option<&'a T> { + self.iter(events).next() + } +} + impl Events where T: Send + Sync + 'static, @@ -112,74 +187,6 @@ where self.event_count += 1; } - /// Iterates over the events the `event_reader` has not seen yet. This updates the `event_reader`'s event counter, - /// which means subsequent event reads will not include events that happened before now. - pub fn iter(&self, event_reader: &mut EventReader) -> impl DoubleEndedIterator { - // if the reader has seen some of the events in a buffer, find the proper index offset. - // otherwise read all events in the buffer - let a_index = if event_reader.last_event_count > self.a_start_event_count { - event_reader.last_event_count - self.a_start_event_count - } else { - 0 - }; - let b_index = if event_reader.last_event_count > self.b_start_event_count { - event_reader.last_event_count - self.b_start_event_count - } else { - 0 - }; - event_reader.last_event_count = self.event_count; - match self.state { - State::A => self - .events_b - .get(b_index..) - .unwrap_or_else(|| &[]) - .iter() - .map(map_event_instance) - .chain( - self.events_a - .get(a_index..) - .unwrap_or_else(|| &[]) - .iter() - .map(map_event_instance), - ), - State::B => self - .events_a - .get(a_index..) - .unwrap_or_else(|| &[]) - .iter() - .map(map_event_instance) - .chain( - self.events_b - .get(b_index..) - .unwrap_or_else(|| &[]) - .iter() - .map(map_event_instance), - ), - } - } - - /// Retrieves the latest event. This updates the `event_reader`'s event counter, - /// which means subsequent event reads will not include events that happened before now. - pub fn latest(&self, event_reader: &mut EventReader) -> Option<&T> { - self.iter(event_reader).rev().next() - } - - /// Retrieves the latest event that matches the given `predicate`. This updates the `event_reader`'s event counter, - /// which means subsequent event reads will not include events that happened before now. - pub fn find_latest( - &self, - event_reader: &mut EventReader, - predicate: impl FnMut(&&T) -> bool, - ) -> Option<&T> { - self.iter(event_reader).rev().filter(predicate).next() - } - - /// Retrieves the earliest event. This updates the `event_reader`'s event counter, - /// which means subsequent event reads will not include events that happened before now. - pub fn earliest(&self, event_reader: &mut EventReader) -> Option<&T> { - self.iter(event_reader).next() - } - /// Gets a new [EventReader]. This will include all events already in the event buffers. pub fn get_reader(&self) -> EventReader { EventReader { @@ -342,6 +349,6 @@ mod tests { events: &Events, reader: &mut EventReader, ) -> Vec { - events.iter(reader).cloned().collect::>() + reader.iter(events).cloned().collect::>() } } diff --git a/crates/bevy_app/src/schedule_runner.rs b/crates/bevy_app/src/schedule_runner.rs index 3a00e7ce7b..b8540545e9 100644 --- a/crates/bevy_app/src/schedule_runner.rs +++ b/crates/bevy_app/src/schedule_runner.rs @@ -32,7 +32,7 @@ impl AppPlugin for ScheduleRunnerPlugin { } RunMode::Loop { wait } => loop { if let Some(app_exit_events) = app.resources.get_mut::>() { - if app_exit_events.latest(&mut app_exit_event_reader).is_some() { + if app_exit_event_reader.latest(&app_exit_events).is_some() { break; } } diff --git a/crates/bevy_input/src/system.rs b/crates/bevy_input/src/system.rs index 48fe10f927..1a8ef35dfc 100644 --- a/crates/bevy_input/src/system.rs +++ b/crates/bevy_input/src/system.rs @@ -9,7 +9,7 @@ pub fn exit_on_esc_system(resources: &mut Resources) -> Box { .write_resource::>() .build( move |_, _, (ref keyboard_input_events, ref mut app_exit_events), _| { - for event in keyboard_input_events.iter(&mut keyboard_input_event_reader) { + for event in keyboard_input_event_reader.iter(keyboard_input_events) { if let Some(virtual_key_code) = event.virtual_key_code { if event.state == ElementState::Pressed && virtual_key_code == VirtualKeyCode::Escape diff --git a/crates/bevy_render/src/camera.rs b/crates/bevy_render/src/camera.rs index 765a88c96d..744a64ea7a 100644 --- a/crates/bevy_render/src/camera.rs +++ b/crates/bevy_render/src/camera.rs @@ -126,8 +126,8 @@ pub fn camera_update_system(resources: &mut Resources) -> Box { .read_resource::>() .with_query(>::query()) .build(move |_, world, window_resized_events, query| { - let primary_window_resized_event = window_resized_events - .find_latest(&mut window_resized_event_reader, |event| event.is_primary); + let primary_window_resized_event = window_resized_event_reader + .find_latest(&window_resized_events, |event| event.is_primary); if let Some(primary_window_resized_event) = primary_window_resized_event { for mut camera in query.iter_mut(world) { camera.update( diff --git a/crates/bevy_render/src/render_graph/nodes/camera2d_node.rs b/crates/bevy_render/src/render_graph/nodes/camera2d_node.rs index 7bb5af6891..1cf6e85559 100644 --- a/crates/bevy_render/src/render_graph/nodes/camera2d_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/camera2d_node.rs @@ -62,8 +62,8 @@ impl SystemNode for Camera2dNode { camera_buffer = Some(buffer); } - let primary_window_resized_event = window_resized_events - .find_latest(&mut window_resized_event_reader, |event| event.is_primary); + let primary_window_resized_event = window_resized_event_reader + .find_latest(&window_resized_events, |event| event.is_primary); if let Some(_) = primary_window_resized_event { let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>(); for (camera, local_to_world, _) in query.iter(world) { diff --git a/crates/bevy_render/src/render_graph/nodes/camera_node.rs b/crates/bevy_render/src/render_graph/nodes/camera_node.rs index 55a2e10de3..4a2fcae344 100644 --- a/crates/bevy_render/src/render_graph/nodes/camera_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/camera_node.rs @@ -61,8 +61,8 @@ impl SystemNode for CameraNode { camera_buffer = Some(buffer); } - let primary_window_resized_event = window_resized_events - .find_latest(&mut window_resized_event_reader, |event| event.is_primary); + let primary_window_resized_event = window_resized_event_reader + .find_latest(&window_resized_events, |event| event.is_primary); if let Some(_) = primary_window_resized_event { let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>(); for (camera, local_to_world, _) in query.iter(world) { diff --git a/crates/bevy_render/src/render_graph/nodes/window_swapchain_node.rs b/crates/bevy_render/src/render_graph/nodes/window_swapchain_node.rs index 3055ed5340..e81e135f4d 100644 --- a/crates/bevy_render/src/render_graph/nodes/window_swapchain_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/window_swapchain_node.rs @@ -61,11 +61,11 @@ impl Node for WindowSwapChainNode { let render_resources = render_context.resources_mut(); // create window swapchain when window is resized or created - if window_created_events - .find_latest(&mut self.window_created_event_reader, |e| e.id == window.id) + if self.window_created_event_reader + .find_latest(&window_created_events, |e| e.id == window.id) .is_some() - || window_resized_events - .find_latest(&mut self.window_resized_event_reader, |e| e.id == window.id) + || self.window_resized_event_reader + .find_latest(&window_resized_events, |e| e.id == window.id) .is_some() { render_resources.create_swap_chain(window); diff --git a/crates/bevy_render/src/render_graph/nodes/window_texture_node.rs b/crates/bevy_render/src/render_graph/nodes/window_texture_node.rs index 78274ba6ce..7484abb0c8 100644 --- a/crates/bevy_render/src/render_graph/nodes/window_texture_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/window_texture_node.rs @@ -62,11 +62,11 @@ impl Node for WindowTextureNode { .expect("Received window resized event for non-existent window"), }; - if window_created_events - .find_latest(&mut self.window_created_event_reader, |e| e.id == window.id) + if self.window_created_event_reader + .find_latest(&window_created_events, |e| e.id == window.id) .is_some() - || window_resized_events - .find_latest(&mut self.window_resized_event_reader, |e| e.id == window.id) + || self.window_resized_event_reader + .find_latest(&window_resized_events, |e| e.id == window.id) .is_some() { let render_resources = render_context.resources_mut(); diff --git a/crates/bevy_wgpu/src/wgpu_renderer.rs b/crates/bevy_wgpu/src/wgpu_renderer.rs index 5d1f5ecb66..be6e67a683 100644 --- a/crates/bevy_wgpu/src/wgpu_renderer.rs +++ b/crates/bevy_wgpu/src/wgpu_renderer.rs @@ -60,7 +60,7 @@ impl WgpuRenderer { let windows = resources.get::().unwrap(); let window_created_events = resources.get::>().unwrap(); for window_created_event in - window_created_events.iter(&mut self.window_created_event_reader) + self.window_created_event_reader.iter(&window_created_events) { let window = windows .get(window_created_event.id) diff --git a/crates/bevy_window/src/system.rs b/crates/bevy_window/src/system.rs index fb6c5ef797..ba0094662b 100644 --- a/crates/bevy_window/src/system.rs +++ b/crates/bevy_window/src/system.rs @@ -14,7 +14,7 @@ pub fn exit_on_window_close_system( .build( move |_, _, (ref window_close_requested_events, ref mut app_exit_events), _| { for window_close_requested_event in - window_close_requested_events.iter(&mut window_close_requested_event_reader) + window_close_requested_event_reader.iter(window_close_requested_events) { match window_id.as_ref() { Some(window_id) => { diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index d69c51babe..03a0b1e344 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -52,7 +52,7 @@ pub fn winit_runner(mut app: App) { }; if let Some(app_exit_events) = app.resources.get_mut::>() { - if app_exit_events.latest(&mut app_exit_event_reader).is_some() { + if app_exit_event_reader.latest(&app_exit_events).is_some() { *control_flow = ControlFlow::Exit; } } @@ -141,7 +141,7 @@ fn handle_create_window_events( let mut windows = resources.get_mut::().unwrap(); let create_window_events = resources.get::>().unwrap(); let mut window_created_events = resources.get_mut::>().unwrap(); - for create_window_event in create_window_events.iter(create_window_event_reader) { + for create_window_event in create_window_event_reader.iter(&create_window_events) { let window = Window::new(&create_window_event.descriptor); winit_windows.create_window(event_loop, &window); let window_id = window.id; diff --git a/examples/event.rs b/examples/event.rs index 5b87008a1a..8bd8701966 100644 --- a/examples/event.rs +++ b/examples/event.rs @@ -54,7 +54,7 @@ impl From<&mut Resources> for EventListenerState { fn event_listener_system( (state, my_events): &mut (ResourceMut, Resource>), ) { - for my_event in my_events.iter(&mut state.my_event_reader) { + for my_event in state.my_event_reader.iter(&my_events) { println!("{}", my_event.message); } } diff --git a/examples/input_keyboard.rs b/examples/input_keyboard.rs index 660f6dccfe..ed0fc2c76d 100644 --- a/examples/input_keyboard.rs +++ b/examples/input_keyboard.rs @@ -22,7 +22,7 @@ pub fn move_on_input_system(resources: &mut Resources) -> Box { .with_query(<(Write, Read>)>::query()) .build( move |_command_buffer, world, (time, keyboard_input_events), mesh_query| { - for event in keyboard_input_events.iter(&mut keyboard_input_event_reader) { + for event in keyboard_input_event_reader.iter(&keyboard_input_events) { match event { KeyboardInput { virtual_key_code: Some(VirtualKeyCode::Left), diff --git a/examples/input_mouse.rs b/examples/input_mouse.rs index 035b002fc0..54ac2f452b 100644 --- a/examples/input_mouse.rs +++ b/examples/input_mouse.rs @@ -22,11 +22,11 @@ pub fn mouse_input_system(resources: &mut Resources) -> Box { _world, (mouse_button_input_events, mouse_motion_events), _queries| { - for event in mouse_button_input_events.iter(&mut mouse_button_input_event_reader) { + for event in mouse_button_input_event_reader.iter(&mouse_button_input_events) { println!("{:?}", event); } - for event in mouse_motion_events.iter(&mut mouse_motion_event_reader) { + for event in mouse_motion_event_reader.iter(&mouse_motion_events) { println!("{:?}", event); } },