From d9b8b3e618755aa8492024efee4267c74d2af8ea Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Sun, 7 Mar 2021 20:42:04 +0000 Subject: [PATCH] Add EventWriter (#1575) This adds a `EventWriter` `SystemParam` that is just a thin wrapper around `ResMut>`. This is primarily to have API symmetry between the reader and writer, and has the added benefit of easily improving the API later with no breaking changes. --- crates/bevy_app/src/event.rs | 16 ++++++++++++++++ crates/bevy_app/src/lib.rs | 2 +- crates/bevy_asset/src/assets.rs | 6 +++--- crates/bevy_input/src/gamepad.rs | 4 ++-- crates/bevy_input/src/system.rs | 5 ++--- .../src/render_graph/nodes/texture_copy_node.rs | 2 +- .../render_graph/nodes/window_swapchain_node.rs | 2 +- .../render_graph/nodes/window_texture_node.rs | 2 +- crates/bevy_scene/src/scene_spawner.rs | 2 +- crates/bevy_wgpu/src/wgpu_renderer.rs | 2 +- crates/bevy_window/src/lib.rs | 2 +- crates/bevy_window/src/system.rs | 8 ++------ examples/ecs/ecs_guide.rs | 2 +- examples/ecs/event.rs | 2 +- examples/window/multiple_windows.rs | 2 +- 15 files changed, 35 insertions(+), 24 deletions(-) diff --git a/crates/bevy_app/src/event.rs b/crates/bevy_app/src/event.rs index 4e19ef6acd..491abe65b1 100644 --- a/crates/bevy_app/src/event.rs +++ b/crates/bevy_app/src/event.rs @@ -131,6 +131,22 @@ pub struct EventReader<'a, T: Component> { events: Res<'a, Events>, } +/// Sends events of type `T`. +#[derive(SystemParam)] +pub struct EventWriter<'a, T: Component> { + events: ResMut<'a, Events>, +} + +impl<'a, T: Component> EventWriter<'a, T> { + pub fn send(&mut self, event: T) { + self.events.send(event); + } + + pub fn send_batch(&mut self, events: impl Iterator) { + self.events.extend(events); + } +} + pub struct ManualEventReader { last_event_count: usize, _marker: PhantomData, diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 8224120e01..ab32956276 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -17,7 +17,7 @@ pub mod prelude { pub use crate::{ app::App, app_builder::AppBuilder, - event::{EventReader, Events}, + event::{EventReader, EventWriter}, CoreStage, DynamicPlugin, Plugin, PluginGroup, StartupStage, }; } diff --git a/crates/bevy_asset/src/assets.rs b/crates/bevy_asset/src/assets.rs index eb69de5aba..e650cf95c0 100644 --- a/crates/bevy_asset/src/assets.rs +++ b/crates/bevy_asset/src/assets.rs @@ -2,7 +2,7 @@ use crate::{ update_asset_storage_system, Asset, AssetLoader, AssetServer, AssetStage, Handle, HandleId, RefChange, }; -use bevy_app::{prelude::Events, AppBuilder}; +use bevy_app::{AppBuilder, EventWriter, Events}; use bevy_ecs::{ system::{IntoSystem, ResMut}, world::FromWorld, @@ -182,10 +182,10 @@ impl Assets { } pub fn asset_event_system( - mut events: ResMut>>, + mut events: EventWriter>, mut assets: ResMut>, ) { - events.extend(assets.events.drain()) + events.send_batch(assets.events.drain()) } pub fn len(&self) -> usize { diff --git a/crates/bevy_input/src/gamepad.rs b/crates/bevy_input/src/gamepad.rs index 23e2edd38b..d16c6acef1 100644 --- a/crates/bevy_input/src/gamepad.rs +++ b/crates/bevy_input/src/gamepad.rs @@ -1,5 +1,5 @@ use crate::{Axis, Input}; -use bevy_app::{EventReader, Events}; +use bevy_app::{EventReader, EventWriter}; use bevy_ecs::system::{Res, ResMut}; use bevy_utils::HashMap; @@ -206,7 +206,7 @@ pub fn gamepad_event_system( mut axis: ResMut>, mut button_axis: ResMut>, mut raw_events: EventReader, - mut events: ResMut>, + mut events: EventWriter, settings: Res, ) { button_input.update(); diff --git a/crates/bevy_input/src/system.rs b/crates/bevy_input/src/system.rs index 644fc67176..0df1be41e1 100644 --- a/crates/bevy_input/src/system.rs +++ b/crates/bevy_input/src/system.rs @@ -3,15 +3,14 @@ use crate::{ ElementState, }; use bevy_app::{ - prelude::{EventReader, Events}, + prelude::{EventReader, EventWriter}, AppExit, }; -use bevy_ecs::system::ResMut; /// Sends the AppExit event whenever the "esc" key is pressed. pub fn exit_on_esc_system( mut keyboard_input_events: EventReader, - mut app_exit_events: ResMut>, + mut app_exit_events: EventWriter, ) { for event in keyboard_input_events.iter() { if let Some(key_code) = event.key_code { diff --git a/crates/bevy_render/src/render_graph/nodes/texture_copy_node.rs b/crates/bevy_render/src/render_graph/nodes/texture_copy_node.rs index ef9a6c1b73..ac7c72fe84 100644 --- a/crates/bevy_render/src/render_graph/nodes/texture_copy_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/texture_copy_node.rs @@ -3,7 +3,7 @@ use crate::{ renderer::{BufferInfo, BufferUsage, RenderContext}, texture::{Texture, TextureDescriptor, TEXTURE_ASSET_INDEX}, }; -use bevy_app::{prelude::Events, ManualEventReader}; +use bevy_app::{Events, ManualEventReader}; use bevy_asset::{AssetEvent, Assets}; use bevy_ecs::world::World; use bevy_utils::HashSet; 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 40aa0f6640..959f39b4a1 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 @@ -2,7 +2,7 @@ use crate::{ render_graph::{Node, ResourceSlotInfo, ResourceSlots}, renderer::{RenderContext, RenderResourceId, RenderResourceType}, }; -use bevy_app::{prelude::Events, ManualEventReader}; +use bevy_app::{Events, ManualEventReader}; use bevy_ecs::world::World; use bevy_window::{WindowCreated, WindowId, WindowResized, Windows}; use std::borrow::Cow; 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 6ce0afae27..8bec3b0888 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 @@ -3,7 +3,7 @@ use crate::{ renderer::{RenderContext, RenderResourceId, RenderResourceType}, texture::TextureDescriptor, }; -use bevy_app::{prelude::Events, ManualEventReader}; +use bevy_app::{Events, ManualEventReader}; use bevy_ecs::world::World; use bevy_window::{WindowCreated, WindowId, WindowResized, Windows}; use std::borrow::Cow; diff --git a/crates/bevy_scene/src/scene_spawner.rs b/crates/bevy_scene/src/scene_spawner.rs index a87ff130d3..244d6548fa 100644 --- a/crates/bevy_scene/src/scene_spawner.rs +++ b/crates/bevy_scene/src/scene_spawner.rs @@ -1,5 +1,5 @@ use crate::{DynamicScene, Scene}; -use bevy_app::{prelude::*, ManualEventReader}; +use bevy_app::{Events, ManualEventReader}; use bevy_asset::{AssetEvent, Assets, Handle}; use bevy_ecs::{ entity::{Entity, EntityMap}, diff --git a/crates/bevy_wgpu/src/wgpu_renderer.rs b/crates/bevy_wgpu/src/wgpu_renderer.rs index 702d8d4873..cdd5e3cf0f 100644 --- a/crates/bevy_wgpu/src/wgpu_renderer.rs +++ b/crates/bevy_wgpu/src/wgpu_renderer.rs @@ -3,7 +3,7 @@ use crate::{ wgpu_type_converter::WgpuInto, WgpuBackend, WgpuOptions, WgpuPowerOptions, }; -use bevy_app::{prelude::*, ManualEventReader}; +use bevy_app::{Events, ManualEventReader}; use bevy_ecs::world::{Mut, World}; use bevy_render::{ render_graph::{DependentNodeStager, RenderGraph, RenderGraphStager}, diff --git a/crates/bevy_window/src/lib.rs b/crates/bevy_window/src/lib.rs index 2df043ac16..cd8f0d7997 100644 --- a/crates/bevy_window/src/lib.rs +++ b/crates/bevy_window/src/lib.rs @@ -16,7 +16,7 @@ pub mod prelude { }; } -use bevy_app::prelude::*; +use bevy_app::{prelude::*, Events}; pub struct WindowPlugin { pub add_primary_window: bool, diff --git a/crates/bevy_window/src/system.rs b/crates/bevy_window/src/system.rs index 900d04e4cb..1985f7db57 100644 --- a/crates/bevy_window/src/system.rs +++ b/crates/bevy_window/src/system.rs @@ -1,12 +1,8 @@ use crate::WindowCloseRequested; -use bevy_app::{ - prelude::{EventReader, Events}, - AppExit, -}; -use bevy_ecs::system::ResMut; +use bevy_app::{AppExit, EventReader, EventWriter}; pub fn exit_on_window_close_system( - mut app_exit_events: ResMut>, + mut app_exit_events: EventWriter, mut window_close_requested_events: EventReader, ) { if window_close_requested_events.iter().next().is_some() { diff --git a/examples/ecs/ecs_guide.rs b/examples/ecs/ecs_guide.rs index 44096dedd6..ac1ee132d6 100644 --- a/examples/ecs/ecs_guide.rs +++ b/examples/ecs/ecs_guide.rs @@ -124,7 +124,7 @@ fn score_check_system( fn game_over_system( game_rules: Res, game_state: Res, - mut app_exit_events: ResMut>, + mut app_exit_events: EventWriter, ) { if let Some(ref player) = game_state.winning_player { println!("{} won the game!", player); diff --git a/examples/ecs/event.rs b/examples/ecs/event.rs index cc2705474f..fa20353449 100644 --- a/examples/ecs/event.rs +++ b/examples/ecs/event.rs @@ -32,7 +32,7 @@ impl Default for EventTriggerState { fn event_trigger_system( time: Res