From e84dbda1ec5a5698a02bf8d7b0deddcfacfc819f Mon Sep 17 00:00:00 2001 From: ira Date: Mon, 7 Nov 2022 21:25:31 +0000 Subject: [PATCH] Add `send_event` and friends to `WorldCell` (#6515) # Objective Copy `send_event` and friends from `World` to `WorldCell`. Clean up `bevy_winit` using `WorldCell::send_event`. ## Changelog Added `send_event`, `send_event_default`, and `send_event_batch` to `WorldCell`. Co-authored-by: devil-ira --- crates/bevy_ecs/src/world/world_cell.rs | 27 ++++++++ crates/bevy_window/src/lib.rs | 8 +-- crates/bevy_winit/src/lib.rs | 87 +++++++------------------ 3 files changed, 53 insertions(+), 69 deletions(-) diff --git a/crates/bevy_ecs/src/world/world_cell.rs b/crates/bevy_ecs/src/world/world_cell.rs index 7679e51c40730..39770890e2b0d 100644 --- a/crates/bevy_ecs/src/world/world_cell.rs +++ b/crates/bevy_ecs/src/world/world_cell.rs @@ -1,5 +1,8 @@ +use bevy_utils::tracing::error; + use crate::{ archetype::ArchetypeComponentId, + event::{Event, Events}, storage::SparseSet, system::Resource, world::{Mut, World}, @@ -317,6 +320,30 @@ impl<'w> WorldCell<'w> { ), } } + + /// Sends an [`Event`](crate::event::Event). + #[inline] + pub fn send_event(&self, event: E) { + self.send_event_batch(std::iter::once(event)); + } + + /// Sends the default value of the [`Event`](crate::event::Event) of type `E`. + #[inline] + pub fn send_event_default(&self) { + self.send_event_batch(std::iter::once(E::default())); + } + + /// Sends a batch of [`Event`](crate::event::Event)s from an iterator. + #[inline] + pub fn send_event_batch(&self, events: impl Iterator) { + match self.get_resource_mut::>() { + Some(mut events_resource) => events_resource.extend(events), + None => error!( + "Unable to send event `{}`\n\tEvent must be added to the app with `add_event()`\n\thttps://docs.rs/bevy/*/bevy/app/struct.App.html#method.add_event ", + std::any::type_name::() + ), + } + } } #[cfg(test)] diff --git a/crates/bevy_window/src/lib.rs b/crates/bevy_window/src/lib.rs index ecac9a4ae25d2..6bfd8532d2c1b 100644 --- a/crates/bevy_window/src/lib.rs +++ b/crates/bevy_window/src/lib.rs @@ -23,10 +23,7 @@ pub mod prelude { } use bevy_app::prelude::*; -use bevy_ecs::{ - event::Events, - schedule::{IntoSystemDescriptor, SystemLabel}, -}; +use bevy_ecs::schedule::{IntoSystemDescriptor, SystemLabel}; impl Default for WindowPlugin { fn default() -> Self { @@ -85,8 +82,7 @@ impl Plugin for WindowPlugin { .init_resource::(); if self.add_primary_window { - let mut create_window_event = app.world.resource_mut::>(); - create_window_event.send(CreateWindow { + app.world.send_event(CreateWindow { id: WindowId::primary(), descriptor: self.window.clone(), }); diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 831020323a45d..b4dcb56b00cac 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -14,11 +14,7 @@ use bevy_ecs::{ event::{Events, ManualEventReader}, world::World, }; -use bevy_input::{ - keyboard::KeyboardInput, - mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel}, - touch::TouchInput, -}; +use bevy_input::mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel}; use bevy_math::{ivec2, DVec2, UVec2, Vec2}; use bevy_utils::{ tracing::{error, info, trace, warn}, @@ -408,67 +404,51 @@ pub fn winit_runner_with(mut app: App) { match event { WindowEvent::Resized(size) => { window.update_actual_size_from_backend(size.width, size.height); - let mut resize_events = world.resource_mut::>(); - resize_events.send(WindowResized { + world.send_event(WindowResized { id: window_id, width: window.width(), height: window.height(), }); } WindowEvent::CloseRequested => { - let mut window_close_requested_events = - world.resource_mut::>(); - window_close_requested_events.send(WindowCloseRequested { id: window_id }); + world.send_event(WindowCloseRequested { id: window_id }); } WindowEvent::KeyboardInput { ref input, .. } => { - let mut keyboard_input_events = - world.resource_mut::>(); - keyboard_input_events.send(converters::convert_keyboard_input(input)); + world.send_event(converters::convert_keyboard_input(input)); } WindowEvent::CursorMoved { position, .. } => { - let mut cursor_moved_events = world.resource_mut::>(); - let physical_position = DVec2::new(position.x, position.y); window .update_cursor_physical_position_from_backend(Some(physical_position)); - cursor_moved_events.send(CursorMoved { + world.send_event(CursorMoved { id: window_id, position: (physical_position / window.scale_factor()).as_vec2(), }); } WindowEvent::CursorEntered { .. } => { - let mut cursor_entered_events = - world.resource_mut::>(); - cursor_entered_events.send(CursorEntered { id: window_id }); + world.send_event(CursorEntered { id: window_id }); } WindowEvent::CursorLeft { .. } => { - let mut cursor_left_events = world.resource_mut::>(); window.update_cursor_physical_position_from_backend(None); - cursor_left_events.send(CursorLeft { id: window_id }); + world.send_event(CursorLeft { id: window_id }); } WindowEvent::MouseInput { state, button, .. } => { - let mut mouse_button_input_events = - world.resource_mut::>(); - mouse_button_input_events.send(MouseButtonInput { + world.send_event(MouseButtonInput { button: converters::convert_mouse_button(button), state: converters::convert_element_state(state), }); } WindowEvent::MouseWheel { delta, .. } => match delta { event::MouseScrollDelta::LineDelta(x, y) => { - let mut mouse_wheel_input_events = - world.resource_mut::>(); - mouse_wheel_input_events.send(MouseWheel { + world.send_event(MouseWheel { unit: MouseScrollUnit::Line, x, y, }); } event::MouseScrollDelta::PixelDelta(p) => { - let mut mouse_wheel_input_events = - world.resource_mut::>(); - mouse_wheel_input_events.send(MouseWheel { + world.send_event(MouseWheel { unit: MouseScrollUnit::Pixel, x: p.x as f32, y: p.y as f32, @@ -476,8 +456,6 @@ pub fn winit_runner_with(mut app: App) { } }, WindowEvent::Touch(touch) => { - let mut touch_input_events = world.resource_mut::>(); - let mut location = touch.location.to_logical(window.scale_factor()); // On a mobile window, the start is from the top while on PC/Linux/OSX from @@ -486,13 +464,11 @@ pub fn winit_runner_with(mut app: App) { let window_height = windows.primary().height(); location.y = window_height - location.y; } - touch_input_events.send(converters::convert_touch_input(touch, location)); + + world.send_event(converters::convert_touch_input(touch, location)); } WindowEvent::ReceivedCharacter(c) => { - let mut char_input_events = - world.resource_mut::>(); - - char_input_events.send(ReceivedCharacter { + world.send_event(ReceivedCharacter { id: window_id, char: c, }); @@ -501,9 +477,7 @@ pub fn winit_runner_with(mut app: App) { scale_factor, new_inner_size, } => { - let mut backend_scale_factor_change_events = - world.resource_mut::>(); - backend_scale_factor_change_events.send(WindowBackendScaleFactorChanged { + world.send_event(WindowBackendScaleFactorChanged { id: window_id, scale_factor, }); @@ -521,10 +495,7 @@ pub fn winit_runner_with(mut app: App) { ) .to_physical::(forced_factor); } else if approx::relative_ne!(new_factor, prior_factor) { - let mut scale_factor_change_events = - world.resource_mut::>(); - - scale_factor_change_events.send(WindowScaleFactorChanged { + world.send_event(WindowScaleFactorChanged { id: window_id, scale_factor, }); @@ -535,8 +506,7 @@ pub fn winit_runner_with(mut app: App) { if approx::relative_ne!(window.width() as f64, new_logical_width) || approx::relative_ne!(window.height() as f64, new_logical_height) { - let mut resize_events = world.resource_mut::>(); - resize_events.send(WindowResized { + world.send_event(WindowResized { id: window_id, width: new_logical_width as f32, height: new_logical_height as f32, @@ -549,35 +519,30 @@ pub fn winit_runner_with(mut app: App) { } WindowEvent::Focused(focused) => { window.update_focused_status_from_backend(focused); - let mut focused_events = world.resource_mut::>(); - focused_events.send(WindowFocused { + world.send_event(WindowFocused { id: window_id, focused, }); } WindowEvent::DroppedFile(path_buf) => { - let mut events = world.resource_mut::>(); - events.send(FileDragAndDrop::DroppedFile { + world.send_event(FileDragAndDrop::DroppedFile { id: window_id, path_buf, }); } WindowEvent::HoveredFile(path_buf) => { - let mut events = world.resource_mut::>(); - events.send(FileDragAndDrop::HoveredFile { + world.send_event(FileDragAndDrop::HoveredFile { id: window_id, path_buf, }); } WindowEvent::HoveredFileCancelled => { - let mut events = world.resource_mut::>(); - events.send(FileDragAndDrop::HoveredFileCancelled { id: window_id }); + world.send_event(FileDragAndDrop::HoveredFileCancelled { id: window_id }); } WindowEvent::Moved(position) => { let position = ivec2(position.x, position.y); window.update_actual_position_from_backend(position); - let mut events = world.resource_mut::>(); - events.send(WindowMoved { + world.send_event(WindowMoved { id: window_id, position, }); @@ -589,8 +554,7 @@ pub fn winit_runner_with(mut app: App) { event: DeviceEvent::MouseMotion { delta: (x, y) }, .. } => { - let mut mouse_motion_events = app.world.resource_mut::>(); - mouse_motion_events.send(MouseMotion { + app.world.send_event(MouseMotion { delta: DVec2 { x, y }.as_vec2(), }); } @@ -681,9 +645,6 @@ fn handle_create_window_events( let mut winit_windows = world.non_send_resource_mut::(); let mut windows = world.resource_mut::(); let create_window_events = world.resource::>(); - let mut window_created_events = world.resource_mut::>(); - #[cfg(not(any(target_os = "windows", target_feature = "x11")))] - let mut window_resized_events = world.resource_mut::>(); for create_window_event in create_window_event_reader.iter(&create_window_events) { let window = winit_windows.create_window( event_loop, @@ -694,13 +655,13 @@ fn handle_create_window_events( // TODO: we aren't yet sure about native wayland, so we might be able to exclude it, // but sending a duplicate event isn't problematic, as windows already does this. #[cfg(not(any(target_os = "windows", target_feature = "x11")))] - window_resized_events.send(WindowResized { + world.send_event(WindowResized { id: create_window_event.id, width: window.width(), height: window.height(), }); windows.add(window); - window_created_events.send(WindowCreated { + world.send_event(WindowCreated { id: create_window_event.id, });