Add EventWriter (#1575)

This adds a `EventWriter<T>` `SystemParam` that is just a thin wrapper around `ResMut<Events<T>>`. 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.
This commit is contained in:
TheRawMeatball 2021-03-07 20:42:04 +00:00
parent 2b0a48d945
commit d9b8b3e618
15 changed files with 35 additions and 24 deletions

View file

@ -131,6 +131,22 @@ pub struct EventReader<'a, T: Component> {
events: Res<'a, Events<T>>,
}
/// Sends events of type `T`.
#[derive(SystemParam)]
pub struct EventWriter<'a, T: Component> {
events: ResMut<'a, Events<T>>,
}
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<Item = T>) {
self.events.extend(events);
}
}
pub struct ManualEventReader<T> {
last_event_count: usize,
_marker: PhantomData<T>,

View file

@ -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,
};
}

View file

@ -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<T: Asset> Assets<T> {
}
pub fn asset_event_system(
mut events: ResMut<Events<AssetEvent<T>>>,
mut events: EventWriter<AssetEvent<T>>,
mut assets: ResMut<Assets<T>>,
) {
events.extend(assets.events.drain())
events.send_batch(assets.events.drain())
}
pub fn len(&self) -> usize {

View file

@ -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<Axis<GamepadAxis>>,
mut button_axis: ResMut<Axis<GamepadButton>>,
mut raw_events: EventReader<GamepadEventRaw>,
mut events: ResMut<Events<GamepadEvent>>,
mut events: EventWriter<GamepadEvent>,
settings: Res<GamepadSettings>,
) {
button_input.update();

View file

@ -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<KeyboardInput>,
mut app_exit_events: ResMut<Events<AppExit>>,
mut app_exit_events: EventWriter<AppExit>,
) {
for event in keyboard_input_events.iter() {
if let Some(key_code) = event.key_code {

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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},

View file

@ -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},

View file

@ -16,7 +16,7 @@ pub mod prelude {
};
}
use bevy_app::prelude::*;
use bevy_app::{prelude::*, Events};
pub struct WindowPlugin {
pub add_primary_window: bool,

View file

@ -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<Events<AppExit>>,
mut app_exit_events: EventWriter<AppExit>,
mut window_close_requested_events: EventReader<WindowCloseRequested>,
) {
if window_close_requested_events.iter().next().is_some() {

View file

@ -124,7 +124,7 @@ fn score_check_system(
fn game_over_system(
game_rules: Res<GameRules>,
game_state: Res<GameState>,
mut app_exit_events: ResMut<Events<AppExit>>,
mut app_exit_events: EventWriter<AppExit>,
) {
if let Some(ref player) = game_state.winning_player {
println!("{} won the game!", player);

View file

@ -32,7 +32,7 @@ impl Default for EventTriggerState {
fn event_trigger_system(
time: Res<Time>,
mut state: ResMut<EventTriggerState>,
mut my_events: ResMut<Events<MyEvent>>,
mut my_events: EventWriter<MyEvent>,
) {
if state.event_timer.tick(time.delta()).finished() {
my_events.send(MyEvent {

View file

@ -37,7 +37,7 @@ enum AppState {
fn setup_window(
mut app_state: ResMut<State<AppState>>,
mut create_window_events: ResMut<Events<CreateWindow>>,
mut create_window_events: EventWriter<CreateWindow>,
) {
let window_id = WindowId::new();