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 <justthecooldude@gmail.com>
This commit is contained in:
ira 2022-11-07 21:25:31 +00:00
parent 4ad621fe0f
commit d688ba5f29
3 changed files with 53 additions and 69 deletions

View File

@ -1,5 +1,8 @@
use bevy_utils::tracing::error;
use crate::{ use crate::{
archetype::ArchetypeComponentId, archetype::ArchetypeComponentId,
event::{Event, Events},
storage::SparseSet, storage::SparseSet,
system::Resource, system::Resource,
world::{Mut, World}, world::{Mut, World},
@ -317,6 +320,30 @@ impl<'w> WorldCell<'w> {
), ),
} }
} }
/// Sends an [`Event`](crate::event::Event).
#[inline]
pub fn send_event<E: 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<E: 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<E: Event>(&self, events: impl Iterator<Item = E>) {
match self.get_resource_mut::<Events<E>>() {
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::<E>()
),
}
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -23,10 +23,7 @@ pub mod prelude {
} }
use bevy_app::prelude::*; use bevy_app::prelude::*;
use bevy_ecs::{ use bevy_ecs::schedule::{IntoSystemDescriptor, SystemLabel};
event::Events,
schedule::{IntoSystemDescriptor, SystemLabel},
};
impl Default for WindowPlugin { impl Default for WindowPlugin {
fn default() -> Self { fn default() -> Self {
@ -85,8 +82,7 @@ impl Plugin for WindowPlugin {
.init_resource::<Windows>(); .init_resource::<Windows>();
if self.add_primary_window { if self.add_primary_window {
let mut create_window_event = app.world.resource_mut::<Events<CreateWindow>>(); app.world.send_event(CreateWindow {
create_window_event.send(CreateWindow {
id: WindowId::primary(), id: WindowId::primary(),
descriptor: self.window.clone(), descriptor: self.window.clone(),
}); });

View File

@ -14,11 +14,7 @@ use bevy_ecs::{
event::{Events, ManualEventReader}, event::{Events, ManualEventReader},
world::World, world::World,
}; };
use bevy_input::{ use bevy_input::mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel};
keyboard::KeyboardInput,
mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel},
touch::TouchInput,
};
use bevy_math::{ivec2, DVec2, UVec2, Vec2}; use bevy_math::{ivec2, DVec2, UVec2, Vec2};
use bevy_utils::{ use bevy_utils::{
tracing::{error, info, trace, warn}, tracing::{error, info, trace, warn},
@ -408,67 +404,51 @@ pub fn winit_runner_with(mut app: App) {
match event { match event {
WindowEvent::Resized(size) => { WindowEvent::Resized(size) => {
window.update_actual_size_from_backend(size.width, size.height); window.update_actual_size_from_backend(size.width, size.height);
let mut resize_events = world.resource_mut::<Events<WindowResized>>(); world.send_event(WindowResized {
resize_events.send(WindowResized {
id: window_id, id: window_id,
width: window.width(), width: window.width(),
height: window.height(), height: window.height(),
}); });
} }
WindowEvent::CloseRequested => { WindowEvent::CloseRequested => {
let mut window_close_requested_events = world.send_event(WindowCloseRequested { id: window_id });
world.resource_mut::<Events<WindowCloseRequested>>();
window_close_requested_events.send(WindowCloseRequested { id: window_id });
} }
WindowEvent::KeyboardInput { ref input, .. } => { WindowEvent::KeyboardInput { ref input, .. } => {
let mut keyboard_input_events = world.send_event(converters::convert_keyboard_input(input));
world.resource_mut::<Events<KeyboardInput>>();
keyboard_input_events.send(converters::convert_keyboard_input(input));
} }
WindowEvent::CursorMoved { position, .. } => { WindowEvent::CursorMoved { position, .. } => {
let mut cursor_moved_events = world.resource_mut::<Events<CursorMoved>>();
let physical_position = DVec2::new(position.x, position.y); let physical_position = DVec2::new(position.x, position.y);
window window
.update_cursor_physical_position_from_backend(Some(physical_position)); .update_cursor_physical_position_from_backend(Some(physical_position));
cursor_moved_events.send(CursorMoved { world.send_event(CursorMoved {
id: window_id, id: window_id,
position: (physical_position / window.scale_factor()).as_vec2(), position: (physical_position / window.scale_factor()).as_vec2(),
}); });
} }
WindowEvent::CursorEntered { .. } => { WindowEvent::CursorEntered { .. } => {
let mut cursor_entered_events = world.send_event(CursorEntered { id: window_id });
world.resource_mut::<Events<CursorEntered>>();
cursor_entered_events.send(CursorEntered { id: window_id });
} }
WindowEvent::CursorLeft { .. } => { WindowEvent::CursorLeft { .. } => {
let mut cursor_left_events = world.resource_mut::<Events<CursorLeft>>();
window.update_cursor_physical_position_from_backend(None); 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, .. } => { WindowEvent::MouseInput { state, button, .. } => {
let mut mouse_button_input_events = world.send_event(MouseButtonInput {
world.resource_mut::<Events<MouseButtonInput>>();
mouse_button_input_events.send(MouseButtonInput {
button: converters::convert_mouse_button(button), button: converters::convert_mouse_button(button),
state: converters::convert_element_state(state), state: converters::convert_element_state(state),
}); });
} }
WindowEvent::MouseWheel { delta, .. } => match delta { WindowEvent::MouseWheel { delta, .. } => match delta {
event::MouseScrollDelta::LineDelta(x, y) => { event::MouseScrollDelta::LineDelta(x, y) => {
let mut mouse_wheel_input_events = world.send_event(MouseWheel {
world.resource_mut::<Events<MouseWheel>>();
mouse_wheel_input_events.send(MouseWheel {
unit: MouseScrollUnit::Line, unit: MouseScrollUnit::Line,
x, x,
y, y,
}); });
} }
event::MouseScrollDelta::PixelDelta(p) => { event::MouseScrollDelta::PixelDelta(p) => {
let mut mouse_wheel_input_events = world.send_event(MouseWheel {
world.resource_mut::<Events<MouseWheel>>();
mouse_wheel_input_events.send(MouseWheel {
unit: MouseScrollUnit::Pixel, unit: MouseScrollUnit::Pixel,
x: p.x as f32, x: p.x as f32,
y: p.y as f32, y: p.y as f32,
@ -476,8 +456,6 @@ pub fn winit_runner_with(mut app: App) {
} }
}, },
WindowEvent::Touch(touch) => { WindowEvent::Touch(touch) => {
let mut touch_input_events = world.resource_mut::<Events<TouchInput>>();
let mut location = touch.location.to_logical(window.scale_factor()); 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 // 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(); let window_height = windows.primary().height();
location.y = window_height - location.y; 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) => { WindowEvent::ReceivedCharacter(c) => {
let mut char_input_events = world.send_event(ReceivedCharacter {
world.resource_mut::<Events<ReceivedCharacter>>();
char_input_events.send(ReceivedCharacter {
id: window_id, id: window_id,
char: c, char: c,
}); });
@ -501,9 +477,7 @@ pub fn winit_runner_with(mut app: App) {
scale_factor, scale_factor,
new_inner_size, new_inner_size,
} => { } => {
let mut backend_scale_factor_change_events = world.send_event(WindowBackendScaleFactorChanged {
world.resource_mut::<Events<WindowBackendScaleFactorChanged>>();
backend_scale_factor_change_events.send(WindowBackendScaleFactorChanged {
id: window_id, id: window_id,
scale_factor, scale_factor,
}); });
@ -521,10 +495,7 @@ pub fn winit_runner_with(mut app: App) {
) )
.to_physical::<u32>(forced_factor); .to_physical::<u32>(forced_factor);
} else if approx::relative_ne!(new_factor, prior_factor) { } else if approx::relative_ne!(new_factor, prior_factor) {
let mut scale_factor_change_events = world.send_event(WindowScaleFactorChanged {
world.resource_mut::<Events<WindowScaleFactorChanged>>();
scale_factor_change_events.send(WindowScaleFactorChanged {
id: window_id, id: window_id,
scale_factor, 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) if approx::relative_ne!(window.width() as f64, new_logical_width)
|| approx::relative_ne!(window.height() as f64, new_logical_height) || approx::relative_ne!(window.height() as f64, new_logical_height)
{ {
let mut resize_events = world.resource_mut::<Events<WindowResized>>(); world.send_event(WindowResized {
resize_events.send(WindowResized {
id: window_id, id: window_id,
width: new_logical_width as f32, width: new_logical_width as f32,
height: new_logical_height as f32, height: new_logical_height as f32,
@ -549,35 +519,30 @@ pub fn winit_runner_with(mut app: App) {
} }
WindowEvent::Focused(focused) => { WindowEvent::Focused(focused) => {
window.update_focused_status_from_backend(focused); window.update_focused_status_from_backend(focused);
let mut focused_events = world.resource_mut::<Events<WindowFocused>>(); world.send_event(WindowFocused {
focused_events.send(WindowFocused {
id: window_id, id: window_id,
focused, focused,
}); });
} }
WindowEvent::DroppedFile(path_buf) => { WindowEvent::DroppedFile(path_buf) => {
let mut events = world.resource_mut::<Events<FileDragAndDrop>>(); world.send_event(FileDragAndDrop::DroppedFile {
events.send(FileDragAndDrop::DroppedFile {
id: window_id, id: window_id,
path_buf, path_buf,
}); });
} }
WindowEvent::HoveredFile(path_buf) => { WindowEvent::HoveredFile(path_buf) => {
let mut events = world.resource_mut::<Events<FileDragAndDrop>>(); world.send_event(FileDragAndDrop::HoveredFile {
events.send(FileDragAndDrop::HoveredFile {
id: window_id, id: window_id,
path_buf, path_buf,
}); });
} }
WindowEvent::HoveredFileCancelled => { WindowEvent::HoveredFileCancelled => {
let mut events = world.resource_mut::<Events<FileDragAndDrop>>(); world.send_event(FileDragAndDrop::HoveredFileCancelled { id: window_id });
events.send(FileDragAndDrop::HoveredFileCancelled { id: window_id });
} }
WindowEvent::Moved(position) => { WindowEvent::Moved(position) => {
let position = ivec2(position.x, position.y); let position = ivec2(position.x, position.y);
window.update_actual_position_from_backend(position); window.update_actual_position_from_backend(position);
let mut events = world.resource_mut::<Events<WindowMoved>>(); world.send_event(WindowMoved {
events.send(WindowMoved {
id: window_id, id: window_id,
position, position,
}); });
@ -589,8 +554,7 @@ pub fn winit_runner_with(mut app: App) {
event: DeviceEvent::MouseMotion { delta: (x, y) }, event: DeviceEvent::MouseMotion { delta: (x, y) },
.. ..
} => { } => {
let mut mouse_motion_events = app.world.resource_mut::<Events<MouseMotion>>(); app.world.send_event(MouseMotion {
mouse_motion_events.send(MouseMotion {
delta: DVec2 { x, y }.as_vec2(), delta: DVec2 { x, y }.as_vec2(),
}); });
} }
@ -681,9 +645,6 @@ fn handle_create_window_events(
let mut winit_windows = world.non_send_resource_mut::<WinitWindows>(); let mut winit_windows = world.non_send_resource_mut::<WinitWindows>();
let mut windows = world.resource_mut::<Windows>(); let mut windows = world.resource_mut::<Windows>();
let create_window_events = world.resource::<Events<CreateWindow>>(); let create_window_events = world.resource::<Events<CreateWindow>>();
let mut window_created_events = world.resource_mut::<Events<WindowCreated>>();
#[cfg(not(any(target_os = "windows", target_feature = "x11")))]
let mut window_resized_events = world.resource_mut::<Events<WindowResized>>();
for create_window_event in create_window_event_reader.iter(&create_window_events) { for create_window_event in create_window_event_reader.iter(&create_window_events) {
let window = winit_windows.create_window( let window = winit_windows.create_window(
event_loop, 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, // 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. // but sending a duplicate event isn't problematic, as windows already does this.
#[cfg(not(any(target_os = "windows", target_feature = "x11")))] #[cfg(not(any(target_os = "windows", target_feature = "x11")))]
window_resized_events.send(WindowResized { world.send_event(WindowResized {
id: create_window_event.id, id: create_window_event.id,
width: window.width(), width: window.width(),
height: window.height(), height: window.height(),
}); });
windows.add(window); windows.add(window);
window_created_events.send(WindowCreated { world.send_event(WindowCreated {
id: create_window_event.id, id: create_window_event.id,
}); });