Make EventReader a SystemParam (#1244)
* Add generic support for `#[derive(SystemParam)]` * Make EventReader a SystemParam
This commit is contained in:
parent
71c6a19ed8
commit
a880b54508
@ -1,4 +1,4 @@
|
||||
use bevy_ecs::ResMut;
|
||||
use bevy_ecs::{Local, Res, ResMut, SystemParam};
|
||||
use bevy_utils::tracing::trace;
|
||||
use std::{fmt, marker::PhantomData};
|
||||
|
||||
@ -122,141 +122,105 @@ fn map_instance_event<T>(event_instance: &EventInstance<T>) -> &T {
|
||||
}
|
||||
|
||||
/// Reads events of type `T` in order and tracks which events have already been read.
|
||||
pub struct EventReader<T> {
|
||||
#[derive(SystemParam)]
|
||||
pub struct EventReader<'a, T: bevy_ecs::Resource> {
|
||||
last_event_count: Local<'a, (usize, PhantomData<T>)>,
|
||||
events: Res<'a, Events<T>>,
|
||||
}
|
||||
|
||||
pub struct ManualEventReader<T> {
|
||||
last_event_count: usize,
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> Default for EventReader<T> {
|
||||
impl<T> Default for ManualEventReader<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
ManualEventReader {
|
||||
last_event_count: 0,
|
||||
_marker: PhantomData::default(),
|
||||
_marker: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EventReader<T> {
|
||||
/// 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.
|
||||
impl<T> ManualEventReader<T> {
|
||||
/// See [`EventReader::iter`]
|
||||
pub fn iter<'a>(&mut self, events: &'a Events<T>) -> impl DoubleEndedIterator<Item = &'a T> {
|
||||
self.iter_with_id(events).map(|(event, _id)| event)
|
||||
internal_event_reader(&mut self.last_event_count, events).map(|(e, _)| e)
|
||||
}
|
||||
|
||||
/// Like [`iter`](Self::iter), except also returning the [`EventId`] of the events.
|
||||
/// See [`EventReader::iter_with_id`]
|
||||
pub fn iter_with_id<'a>(
|
||||
&mut self,
|
||||
events: &'a Events<T>,
|
||||
) -> impl DoubleEndedIterator<Item = (&'a T, EventId<T>)> {
|
||||
self.iter_internal(events).map(|(event, id)| {
|
||||
internal_event_reader(&mut self.last_event_count, events)
|
||||
}
|
||||
}
|
||||
|
||||
/// Like [`iter_with_id`](EventReader::iter_with_id) except not emitting any traces for read messages.
|
||||
fn internal_event_reader<'a, T>(
|
||||
last_event_count: &mut usize,
|
||||
events: &'a Events<T>,
|
||||
) -> impl DoubleEndedIterator<Item = (&'a T, EventId<T>)> {
|
||||
// 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 *last_event_count > events.a_start_event_count {
|
||||
*last_event_count - events.a_start_event_count
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let b_index = if *last_event_count > events.b_start_event_count {
|
||||
*last_event_count - events.b_start_event_count
|
||||
} else {
|
||||
0
|
||||
};
|
||||
*last_event_count = events.event_count;
|
||||
match events.state {
|
||||
State::A => events
|
||||
.events_b
|
||||
.get(b_index..)
|
||||
.unwrap_or_else(|| &[])
|
||||
.iter()
|
||||
.map(map_instance_event_with_id)
|
||||
.chain(
|
||||
events
|
||||
.events_a
|
||||
.get(a_index..)
|
||||
.unwrap_or_else(|| &[])
|
||||
.iter()
|
||||
.map(map_instance_event_with_id),
|
||||
),
|
||||
State::B => events
|
||||
.events_a
|
||||
.get(a_index..)
|
||||
.unwrap_or_else(|| &[])
|
||||
.iter()
|
||||
.map(map_instance_event_with_id)
|
||||
.chain(
|
||||
events
|
||||
.events_b
|
||||
.get(b_index..)
|
||||
.unwrap_or_else(|| &[])
|
||||
.iter()
|
||||
.map(map_instance_event_with_id),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: bevy_ecs::Resource> EventReader<'a, T> {
|
||||
/// 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(&mut self) -> impl DoubleEndedIterator<Item = &T> {
|
||||
self.iter_with_id().map(|(event, _id)| event)
|
||||
}
|
||||
|
||||
/// Like [`iter`](Self::iter), except also returning the [`EventId`] of the events.
|
||||
pub fn iter_with_id(&mut self) -> impl DoubleEndedIterator<Item = (&T, EventId<T>)> {
|
||||
internal_event_reader(&mut self.last_event_count.0, &self.events).map(|(event, id)| {
|
||||
trace!("EventReader::iter() -> {}", id);
|
||||
(event, id)
|
||||
})
|
||||
}
|
||||
|
||||
/// Like [`iter_with_id`](Self::iter_with_id) except not emitting any traces for read messages.
|
||||
fn iter_internal<'a>(
|
||||
&mut self,
|
||||
events: &'a Events<T>,
|
||||
) -> impl DoubleEndedIterator<Item = (&'a T, EventId<T>)> {
|
||||
// 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_instance_event_with_id)
|
||||
.chain(
|
||||
events
|
||||
.events_a
|
||||
.get(a_index..)
|
||||
.unwrap_or_else(|| &[])
|
||||
.iter()
|
||||
.map(map_instance_event_with_id),
|
||||
),
|
||||
State::B => events
|
||||
.events_a
|
||||
.get(a_index..)
|
||||
.unwrap_or_else(|| &[])
|
||||
.iter()
|
||||
.map(map_instance_event_with_id)
|
||||
.chain(
|
||||
events
|
||||
.events_b
|
||||
.get(b_index..)
|
||||
.unwrap_or_else(|| &[])
|
||||
.iter()
|
||||
.map(map_instance_event_with_id),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// 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<T>) -> Option<&'a T> {
|
||||
self.latest_with_id(events).map(|(event, _)| event)
|
||||
}
|
||||
|
||||
/// Like [`latest`](Self::latest), except also returning the [`EventId`] of the event.
|
||||
pub fn latest_with_id<'a>(&mut self, events: &'a Events<T>) -> Option<(&'a T, EventId<T>)> {
|
||||
self.iter_internal(events).rev().next().map(|(event, id)| {
|
||||
trace!("EventReader::latest() -> {}", id);
|
||||
(event, id)
|
||||
})
|
||||
}
|
||||
|
||||
/// 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<T>,
|
||||
predicate: impl FnMut(&&T) -> bool,
|
||||
) -> Option<&'a T> {
|
||||
self.find_latest_with_id(events, predicate)
|
||||
.map(|(event, _)| event)
|
||||
}
|
||||
|
||||
/// Like [`find_latest`](Self::find_latest), except also returning the [`EventId`] of the event.
|
||||
pub fn find_latest_with_id<'a>(
|
||||
&mut self,
|
||||
events: &'a Events<T>,
|
||||
mut predicate: impl FnMut(&&T) -> bool,
|
||||
) -> Option<(&'a T, EventId<T>)> {
|
||||
self.iter_internal(events)
|
||||
.rev()
|
||||
.find(|(event, _id)| predicate(event))
|
||||
.map(|(event, id)| {
|
||||
trace!("EventReader::find_latest() -> {}", id);
|
||||
(event, id)
|
||||
})
|
||||
}
|
||||
|
||||
/// 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<T>) -> Option<&'a T> {
|
||||
self.earliest_with_id(events).map(|(event, _)| event)
|
||||
}
|
||||
|
||||
/// Like [`earliest`](Self::earliest), except also returning the [`EventId`] of the event.
|
||||
pub fn earliest_with_id<'a>(&mut self, events: &'a Events<T>) -> Option<(&'a T, EventId<T>)> {
|
||||
self.iter_internal(events).next().map(|(event, id)| {
|
||||
trace!("EventReader::earliest() -> {}", id);
|
||||
(event, id)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: bevy_ecs::Resource> Events<T> {
|
||||
@ -278,17 +242,17 @@ impl<T: bevy_ecs::Resource> Events<T> {
|
||||
self.event_count += 1;
|
||||
}
|
||||
|
||||
/// Gets a new [EventReader]. This will include all events already in the event buffers.
|
||||
pub fn get_reader(&self) -> EventReader<T> {
|
||||
EventReader {
|
||||
/// Gets a new [ManualEventReader]. This will include all events already in the event buffers.
|
||||
pub fn get_reader(&self) -> ManualEventReader<T> {
|
||||
ManualEventReader {
|
||||
last_event_count: 0,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a new [EventReader]. This will ignore all events already in the event buffers. It will read all future events.
|
||||
pub fn get_reader_current(&self) -> EventReader<T> {
|
||||
EventReader {
|
||||
/// Gets a new [ManualEventReader]. This will ignore all events already in the event buffers. It will read all future events.
|
||||
pub fn get_reader_current(&self) -> ManualEventReader<T> {
|
||||
ManualEventReader {
|
||||
last_event_count: self.event_count,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
@ -461,7 +425,7 @@ mod tests {
|
||||
|
||||
fn get_events(
|
||||
events: &Events<TestEvent>,
|
||||
reader: &mut EventReader<TestEvent>,
|
||||
reader: &mut ManualEventReader<TestEvent>,
|
||||
) -> Vec<TestEvent> {
|
||||
reader.iter(events).cloned().collect::<Vec<TestEvent>>()
|
||||
}
|
||||
|
@ -1,9 +1,5 @@
|
||||
use super::{App, AppBuilder};
|
||||
use crate::{
|
||||
app::AppExit,
|
||||
event::{EventReader, Events},
|
||||
plugin::Plugin,
|
||||
};
|
||||
use crate::{app::AppExit, event::Events, plugin::Plugin, ManualEventReader};
|
||||
use bevy_utils::{Duration, Instant};
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
@ -56,7 +52,7 @@ impl Plugin for ScheduleRunnerPlugin {
|
||||
.get_or_insert_with(ScheduleRunnerSettings::default)
|
||||
.to_owned();
|
||||
app.set_runner(move |mut app: App| {
|
||||
let mut app_exit_event_reader = EventReader::<AppExit>::default();
|
||||
let mut app_exit_event_reader = ManualEventReader::<AppExit>::default();
|
||||
match settings.run_mode {
|
||||
RunMode::Once => {
|
||||
app.update();
|
||||
@ -68,7 +64,8 @@ impl Plugin for ScheduleRunnerPlugin {
|
||||
let start_time = Instant::now();
|
||||
|
||||
if let Some(app_exit_events) = app.resources.get_mut::<Events<AppExit>>() {
|
||||
if let Some(exit) = app_exit_event_reader.latest(&app_exit_events) {
|
||||
if let Some(exit) = app_exit_event_reader.iter(&app_exit_events).last()
|
||||
{
|
||||
return Err(exit.clone());
|
||||
}
|
||||
}
|
||||
@ -76,7 +73,8 @@ impl Plugin for ScheduleRunnerPlugin {
|
||||
app.update();
|
||||
|
||||
if let Some(app_exit_events) = app.resources.get_mut::<Events<AppExit>>() {
|
||||
if let Some(exit) = app_exit_event_reader.latest(&app_exit_events) {
|
||||
if let Some(exit) = app_exit_event_reader.iter(&app_exit_events).last()
|
||||
{
|
||||
return Err(exit.clone());
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ use proc_macro::TokenStream;
|
||||
use proc_macro2::{Span, TokenStream as TokenStream2};
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
parse::ParseStream, parse_macro_input, Data, DataStruct, DeriveInput, Error, Field, Fields,
|
||||
Ident, Index, Lifetime, Path, Result,
|
||||
parse::ParseStream, parse_macro_input, punctuated::Punctuated, Data, DataStruct, DeriveInput,
|
||||
Error, Field, Fields, GenericParam, Ident, Index, Lifetime, Path, Result, Token,
|
||||
};
|
||||
|
||||
/// Implement `Bundle` for a monomorphic struct
|
||||
@ -410,16 +410,44 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
|
||||
let generics = ast.generics;
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let lifetimeless_generics: Vec<_> = generics
|
||||
.params
|
||||
.iter()
|
||||
.filter(|g| matches!(g, GenericParam::Type(_)))
|
||||
.collect();
|
||||
|
||||
let phantoms = lifetimeless_generics
|
||||
.iter()
|
||||
.map(|g| {
|
||||
let g = match g {
|
||||
GenericParam::Type(g) => &g.ident,
|
||||
_ => panic!(),
|
||||
};
|
||||
quote! { ::std::marker::PhantomData::<#g>, }
|
||||
})
|
||||
.fold(quote!(), |old, new| {
|
||||
quote! { #old #new }
|
||||
});
|
||||
|
||||
let mut punctuated_generics = Punctuated::<_, Token![,]>::new();
|
||||
punctuated_generics.extend(lifetimeless_generics.iter());
|
||||
|
||||
let mut punctuated_generic_idents = Punctuated::<_, Token![,]>::new();
|
||||
punctuated_generic_idents.extend(lifetimeless_generics.iter().map(|g| match g {
|
||||
GenericParam::Type(g) => &g.ident,
|
||||
_ => panic!(),
|
||||
}));
|
||||
|
||||
let struct_name = &ast.ident;
|
||||
let fetch_struct_name = Ident::new(&format!("Fetch{}", struct_name), Span::call_site());
|
||||
|
||||
TokenStream::from(quote! {
|
||||
pub struct #fetch_struct_name;
|
||||
pub struct #fetch_struct_name<#punctuated_generics>(#phantoms);
|
||||
impl #impl_generics #path::SystemParam for #struct_name#ty_generics #where_clause {
|
||||
type Fetch = #fetch_struct_name;
|
||||
type Fetch = #fetch_struct_name <#punctuated_generic_idents>;
|
||||
}
|
||||
|
||||
impl #impl_generics #path::FetchSystemParam<'a> for #fetch_struct_name {
|
||||
impl #impl_generics #path::FetchSystemParam<'a> for #fetch_struct_name<#punctuated_generic_idents> {
|
||||
type Item = #struct_name#ty_generics;
|
||||
fn init(system_state: &mut #path::SystemState, world: &#path::World, resources: &mut #path::Resources) {
|
||||
#(<<#field_types as SystemParam>::Fetch as #path::FetchSystemParam>::init(system_state, world, resources);)*
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{Axis, Input};
|
||||
use bevy_app::{EventReader, Events};
|
||||
use bevy_ecs::{Local, Res, ResMut};
|
||||
use bevy_ecs::{Res, ResMut};
|
||||
use bevy_utils::HashMap;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
@ -202,16 +202,15 @@ impl ButtonAxisSettings {
|
||||
}
|
||||
|
||||
pub fn gamepad_event_system(
|
||||
mut event_reader: Local<EventReader<GamepadEventRaw>>,
|
||||
mut button_input: ResMut<Input<GamepadButton>>,
|
||||
mut axis: ResMut<Axis<GamepadAxis>>,
|
||||
mut button_axis: ResMut<Axis<GamepadButton>>,
|
||||
raw_events: Res<Events<GamepadEventRaw>>,
|
||||
mut raw_events: EventReader<GamepadEventRaw>,
|
||||
mut events: ResMut<Events<GamepadEvent>>,
|
||||
settings: Res<GamepadSettings>,
|
||||
) {
|
||||
button_input.update();
|
||||
for event in event_reader.iter(&raw_events) {
|
||||
for event in raw_events.iter() {
|
||||
let (gamepad, event) = (event.0, &event.1);
|
||||
match event {
|
||||
GamepadEventType::Connected => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{ElementState, Input};
|
||||
use bevy_app::prelude::*;
|
||||
use bevy_ecs::{Local, Res, ResMut};
|
||||
use bevy_ecs::ResMut;
|
||||
|
||||
/// A key input event from a keyboard device
|
||||
#[derive(Debug, Clone)]
|
||||
@ -10,23 +10,13 @@ pub struct KeyboardInput {
|
||||
pub state: ElementState,
|
||||
}
|
||||
|
||||
/// State used by the keyboard input system
|
||||
#[derive(Default)]
|
||||
pub struct KeyboardInputState {
|
||||
keyboard_input_event_reader: EventReader<KeyboardInput>,
|
||||
}
|
||||
|
||||
/// Updates the Input<KeyCode> resource with the latest KeyboardInput events
|
||||
pub fn keyboard_input_system(
|
||||
mut state: Local<KeyboardInputState>,
|
||||
mut keyboard_input: ResMut<Input<KeyCode>>,
|
||||
keyboard_input_events: Res<Events<KeyboardInput>>,
|
||||
mut keyboard_input_events: EventReader<KeyboardInput>,
|
||||
) {
|
||||
keyboard_input.update();
|
||||
for event in state
|
||||
.keyboard_input_event_reader
|
||||
.iter(&keyboard_input_events)
|
||||
{
|
||||
for event in keyboard_input_events.iter() {
|
||||
if let KeyboardInput {
|
||||
key_code: Some(key_code),
|
||||
state,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{ElementState, Input};
|
||||
use bevy_app::prelude::{EventReader, Events};
|
||||
use bevy_ecs::{Local, Res, ResMut};
|
||||
use bevy_app::prelude::EventReader;
|
||||
use bevy_ecs::ResMut;
|
||||
use bevy_math::Vec2;
|
||||
|
||||
/// A mouse button input event
|
||||
@ -41,23 +41,13 @@ pub struct MouseWheel {
|
||||
pub y: f32,
|
||||
}
|
||||
|
||||
/// State used by the mouse button input system
|
||||
#[derive(Default)]
|
||||
pub struct MouseButtonInputState {
|
||||
mouse_button_input_event_reader: EventReader<MouseButtonInput>,
|
||||
}
|
||||
|
||||
/// Updates the Input<MouseButton> resource with the latest MouseButtonInput events
|
||||
pub fn mouse_button_input_system(
|
||||
mut state: Local<MouseButtonInputState>,
|
||||
mut mouse_button_input: ResMut<Input<MouseButton>>,
|
||||
mouse_button_input_events: Res<Events<MouseButtonInput>>,
|
||||
mut mouse_button_input_events: EventReader<MouseButtonInput>,
|
||||
) {
|
||||
mouse_button_input.update();
|
||||
for event in state
|
||||
.mouse_button_input_event_reader
|
||||
.iter(&mouse_button_input_events)
|
||||
{
|
||||
for event in mouse_button_input_events.iter() {
|
||||
match event.state {
|
||||
ElementState::Pressed => mouse_button_input.press(event.button),
|
||||
ElementState::Released => mouse_button_input.release(event.button),
|
||||
|
@ -6,21 +6,14 @@ use bevy_app::{
|
||||
prelude::{EventReader, Events},
|
||||
AppExit,
|
||||
};
|
||||
use bevy_ecs::{Local, Res, ResMut};
|
||||
|
||||
/// Local "exit on escape" system state
|
||||
#[derive(Default)]
|
||||
pub struct ExitOnEscapeState {
|
||||
reader: EventReader<KeyboardInput>,
|
||||
}
|
||||
use bevy_ecs::ResMut;
|
||||
|
||||
/// Sends the AppExit event whenever the "esc" key is pressed.
|
||||
pub fn exit_on_esc_system(
|
||||
mut state: Local<ExitOnEscapeState>,
|
||||
keyboard_input_events: Res<Events<KeyboardInput>>,
|
||||
mut keyboard_input_events: EventReader<KeyboardInput>,
|
||||
mut app_exit_events: ResMut<Events<AppExit>>,
|
||||
) {
|
||||
for event in state.reader.iter(&keyboard_input_events) {
|
||||
for event in keyboard_input_events.iter() {
|
||||
if let Some(key_code) = event.key_code {
|
||||
if event.state == ElementState::Pressed && key_code == KeyCode::Escape {
|
||||
app_exit_events.send(AppExit);
|
||||
|
@ -1,5 +1,5 @@
|
||||
use bevy_app::{EventReader, Events};
|
||||
use bevy_ecs::{Local, Res, ResMut};
|
||||
use bevy_app::EventReader;
|
||||
use bevy_ecs::ResMut;
|
||||
use bevy_math::Vec2;
|
||||
use bevy_utils::HashMap;
|
||||
|
||||
@ -77,11 +77,6 @@ pub enum TouchPhase {
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct TouchSystemState {
|
||||
touch_event_reader: EventReader<TouchInput>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Touch {
|
||||
id: u64,
|
||||
@ -226,13 +221,12 @@ impl Touches {
|
||||
|
||||
/// Updates the Touches resource with the latest TouchInput events
|
||||
pub fn touch_screen_input_system(
|
||||
mut state: Local<TouchSystemState>,
|
||||
mut touch_state: ResMut<Touches>,
|
||||
touch_input_events: Res<Events<TouchInput>>,
|
||||
mut touch_input_events: EventReader<TouchInput>,
|
||||
) {
|
||||
touch_state.update();
|
||||
|
||||
for event in state.touch_event_reader.iter(&touch_input_events) {
|
||||
for event in touch_input_events.iter() {
|
||||
touch_state.process_touch_event(event);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::CameraProjection;
|
||||
use bevy_app::prelude::{EventReader, Events};
|
||||
use bevy_ecs::{Added, Component, Entity, Local, Query, QuerySet, Res};
|
||||
use bevy_app::prelude::EventReader;
|
||||
use bevy_ecs::{Added, Component, Entity, Query, QuerySet, Res};
|
||||
use bevy_math::Mat4;
|
||||
use bevy_reflect::{Reflect, ReflectComponent};
|
||||
use bevy_window::{WindowCreated, WindowId, WindowResized, Windows};
|
||||
@ -28,16 +28,9 @@ impl Default for DepthCalculation {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CameraSystemState {
|
||||
window_resized_event_reader: EventReader<WindowResized>,
|
||||
window_created_event_reader: EventReader<WindowCreated>,
|
||||
}
|
||||
|
||||
pub fn camera_system<T: CameraProjection + Component>(
|
||||
mut state: Local<CameraSystemState>,
|
||||
window_resized_events: Res<Events<WindowResized>>,
|
||||
window_created_events: Res<Events<WindowCreated>>,
|
||||
mut window_resized_events: EventReader<WindowResized>,
|
||||
mut window_created_events: EventReader<WindowCreated>,
|
||||
windows: Res<Windows>,
|
||||
mut queries: QuerySet<(
|
||||
Query<(Entity, &mut Camera, &mut T)>,
|
||||
@ -46,11 +39,7 @@ pub fn camera_system<T: CameraProjection + Component>(
|
||||
) {
|
||||
let mut changed_window_ids = Vec::new();
|
||||
// handle resize events. latest events are handled first because we only want to resize each window once
|
||||
for event in state
|
||||
.window_resized_event_reader
|
||||
.iter(&window_resized_events)
|
||||
.rev()
|
||||
{
|
||||
for event in window_resized_events.iter().rev() {
|
||||
if changed_window_ids.contains(&event.id) {
|
||||
continue;
|
||||
}
|
||||
@ -59,11 +48,7 @@ pub fn camera_system<T: CameraProjection + Component>(
|
||||
}
|
||||
|
||||
// handle resize events. latest events are handled first because we only want to resize each window once
|
||||
for event in state
|
||||
.window_created_event_reader
|
||||
.iter(&window_created_events)
|
||||
.rev()
|
||||
{
|
||||
for event in window_created_events.iter().rev() {
|
||||
if changed_window_ids.contains(&event.id) {
|
||||
continue;
|
||||
}
|
||||
|
@ -51,7 +51,6 @@ use shader::ShaderLoader;
|
||||
use texture::HdrTextureLoader;
|
||||
#[cfg(feature = "png")]
|
||||
use texture::ImageTextureLoader;
|
||||
use texture::TextureResourceSystemState;
|
||||
|
||||
/// The names of "render" App stages
|
||||
pub mod stage {
|
||||
@ -133,7 +132,6 @@ impl Plugin for RenderPlugin {
|
||||
.init_resource::<RenderGraph>()
|
||||
.init_resource::<PipelineCompiler>()
|
||||
.init_resource::<RenderResourceBindings>()
|
||||
.init_resource::<TextureResourceSystemState>()
|
||||
.init_resource::<AssetRenderResourceBindings>()
|
||||
.init_resource::<ActiveCameras>()
|
||||
.add_system_to_stage(
|
||||
|
@ -2,7 +2,7 @@ use crate::{
|
||||
pipeline::{IndexFormat, PrimitiveTopology, RenderPipelines, VertexFormat},
|
||||
renderer::{BufferInfo, BufferUsage, RenderResourceContext, RenderResourceId},
|
||||
};
|
||||
use bevy_app::prelude::{EventReader, Events};
|
||||
use bevy_app::prelude::EventReader;
|
||||
use bevy_asset::{AssetEvent, Assets, Handle};
|
||||
use bevy_core::AsBytes;
|
||||
use bevy_ecs::{Changed, Entity, Local, Mut, Query, QuerySet, Res, With};
|
||||
@ -349,7 +349,6 @@ pub struct MeshEntities {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MeshResourceProviderState {
|
||||
mesh_event_reader: EventReader<AssetEvent<Mesh>>,
|
||||
mesh_entities: HashMap<Handle<Mesh>, MeshEntities>,
|
||||
}
|
||||
|
||||
@ -357,7 +356,7 @@ pub fn mesh_resource_provider_system(
|
||||
mut state: Local<MeshResourceProviderState>,
|
||||
render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
||||
meshes: Res<Assets<Mesh>>,
|
||||
mesh_events: Res<Events<AssetEvent<Mesh>>>,
|
||||
mut mesh_events: EventReader<AssetEvent<Mesh>>,
|
||||
mut queries: QuerySet<(
|
||||
Query<&mut RenderPipelines, With<Handle<Mesh>>>,
|
||||
Query<(Entity, &Handle<Mesh>, &mut RenderPipelines), Changed<Handle<Mesh>>>,
|
||||
@ -365,7 +364,7 @@ pub fn mesh_resource_provider_system(
|
||||
) {
|
||||
let mut changed_meshes = HashSet::default();
|
||||
let render_resource_context = &**render_resource_context;
|
||||
for event in state.mesh_event_reader.iter(&mesh_events) {
|
||||
for event in mesh_events.iter() {
|
||||
match event {
|
||||
AssetEvent::Created { ref handle } => {
|
||||
changed_meshes.insert(handle.clone_weak());
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
texture,
|
||||
};
|
||||
|
||||
use bevy_app::{EventReader, Events};
|
||||
use bevy_app::EventReader;
|
||||
use bevy_asset::{Asset, AssetEvent, Assets, Handle, HandleId};
|
||||
use bevy_ecs::{
|
||||
BoxedSystem, Changed, Commands, Entity, IntoSystem, Local, Or, Query, QuerySet, Res, ResMut,
|
||||
@ -600,14 +600,14 @@ where
|
||||
}
|
||||
|
||||
struct AssetRenderNodeState<T: Asset> {
|
||||
event_reader: EventReader<AssetEvent<T>>,
|
||||
assets_waiting_for_textures: Vec<HandleId>,
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: Asset> Default for AssetRenderNodeState<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
event_reader: Default::default(),
|
||||
_marker: Default::default(),
|
||||
assets_waiting_for_textures: Default::default(),
|
||||
}
|
||||
}
|
||||
@ -618,7 +618,7 @@ fn asset_render_resources_node_system<T: RenderResources + Asset>(
|
||||
mut state: Local<RenderResourcesNodeState<HandleId, T>>,
|
||||
mut asset_state: Local<AssetRenderNodeState<T>>,
|
||||
assets: Res<Assets<T>>,
|
||||
asset_events: Res<Events<AssetEvent<T>>>,
|
||||
mut asset_events: EventReader<AssetEvent<T>>,
|
||||
mut asset_render_resource_bindings: ResMut<AssetRenderResourceBindings>,
|
||||
render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
||||
mut queries: QuerySet<(
|
||||
@ -632,7 +632,7 @@ fn asset_render_resources_node_system<T: RenderResources + Asset>(
|
||||
let render_resource_context = &**render_resource_context;
|
||||
|
||||
let mut changed_assets = HashMap::default();
|
||||
for event in asset_state.event_reader.iter(&asset_events) {
|
||||
for event in asset_events.iter() {
|
||||
match event {
|
||||
AssetEvent::Created { ref handle } => {
|
||||
if let Some(asset) = assets.get(handle) {
|
||||
|
@ -3,14 +3,14 @@ use crate::{
|
||||
renderer::{BufferInfo, BufferUsage, RenderContext},
|
||||
texture::{Texture, TextureDescriptor, TEXTURE_ASSET_INDEX},
|
||||
};
|
||||
use bevy_app::prelude::{EventReader, Events};
|
||||
use bevy_app::{prelude::Events, ManualEventReader};
|
||||
use bevy_asset::{AssetEvent, Assets};
|
||||
use bevy_ecs::{Resources, World};
|
||||
use bevy_utils::HashSet;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct TextureCopyNode {
|
||||
pub texture_event_reader: EventReader<AssetEvent<Texture>>,
|
||||
pub texture_event_reader: ManualEventReader<AssetEvent<Texture>>,
|
||||
}
|
||||
|
||||
impl Node for TextureCopyNode {
|
||||
|
@ -2,15 +2,15 @@ use crate::{
|
||||
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
|
||||
renderer::{RenderContext, RenderResourceId, RenderResourceType},
|
||||
};
|
||||
use bevy_app::prelude::{EventReader, Events};
|
||||
use bevy_app::{prelude::Events, ManualEventReader};
|
||||
use bevy_ecs::{Resources, World};
|
||||
use bevy_window::{WindowCreated, WindowId, WindowResized, Windows};
|
||||
use std::borrow::Cow;
|
||||
|
||||
pub struct WindowSwapChainNode {
|
||||
window_id: WindowId,
|
||||
window_created_event_reader: EventReader<WindowCreated>,
|
||||
window_resized_event_reader: EventReader<WindowResized>,
|
||||
window_created_event_reader: ManualEventReader<WindowCreated>,
|
||||
window_resized_event_reader: ManualEventReader<WindowResized>,
|
||||
}
|
||||
|
||||
impl WindowSwapChainNode {
|
||||
@ -56,12 +56,12 @@ impl Node for WindowSwapChainNode {
|
||||
// create window swapchain when window is resized or created
|
||||
if self
|
||||
.window_created_event_reader
|
||||
.find_latest(&window_created_events, |e| e.id == window.id())
|
||||
.is_some()
|
||||
.iter(&window_created_events)
|
||||
.any(|e| e.id == window.id())
|
||||
|| self
|
||||
.window_resized_event_reader
|
||||
.find_latest(&window_resized_events, |e| e.id == window.id())
|
||||
.is_some()
|
||||
.iter(&window_resized_events)
|
||||
.any(|e| e.id == window.id())
|
||||
{
|
||||
render_resource_context.create_swap_chain(window);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use crate::{
|
||||
renderer::{RenderContext, RenderResourceId, RenderResourceType},
|
||||
texture::TextureDescriptor,
|
||||
};
|
||||
use bevy_app::prelude::{EventReader, Events};
|
||||
use bevy_app::{prelude::Events, ManualEventReader};
|
||||
use bevy_ecs::{Resources, World};
|
||||
use bevy_window::{WindowCreated, WindowId, WindowResized, Windows};
|
||||
use std::borrow::Cow;
|
||||
@ -11,8 +11,8 @@ use std::borrow::Cow;
|
||||
pub struct WindowTextureNode {
|
||||
window_id: WindowId,
|
||||
descriptor: TextureDescriptor,
|
||||
window_created_event_reader: EventReader<WindowCreated>,
|
||||
window_resized_event_reader: EventReader<WindowResized>,
|
||||
window_created_event_reader: ManualEventReader<WindowCreated>,
|
||||
window_resized_event_reader: ManualEventReader<WindowResized>,
|
||||
}
|
||||
|
||||
impl WindowTextureNode {
|
||||
@ -56,12 +56,12 @@ impl Node for WindowTextureNode {
|
||||
|
||||
if self
|
||||
.window_created_event_reader
|
||||
.find_latest(&window_created_events, |e| e.id == window.id())
|
||||
.is_some()
|
||||
.iter(&window_created_events)
|
||||
.any(|e| e.id == window.id())
|
||||
|| self
|
||||
.window_resized_event_reader
|
||||
.find_latest(&window_resized_events, |e| e.id == window.id())
|
||||
.is_some()
|
||||
.iter(&window_resized_events)
|
||||
.any(|e| e.id == window.id())
|
||||
{
|
||||
let render_resource_context = render_context.resources_mut();
|
||||
if let Some(RenderResourceId::Texture(old_texture)) = output.get(WINDOW_TEXTURE) {
|
||||
|
@ -4,9 +4,9 @@ use crate::{
|
||||
};
|
||||
|
||||
use super::ShaderLayout;
|
||||
use bevy_app::{EventReader, Events};
|
||||
use bevy_app::EventReader;
|
||||
use bevy_asset::{AssetEvent, AssetLoader, Assets, Handle, LoadContext, LoadedAsset};
|
||||
use bevy_ecs::{Local, Res, ResMut};
|
||||
use bevy_ecs::{Res, ResMut};
|
||||
use bevy_reflect::TypeUuid;
|
||||
use bevy_utils::{tracing::error, BoxedFuture};
|
||||
use std::marker::Copy;
|
||||
@ -281,12 +281,11 @@ impl AssetLoader for ShaderLoader {
|
||||
pub fn shader_update_system(
|
||||
mut shaders: ResMut<Assets<Shader>>,
|
||||
mut pipelines: ResMut<Assets<PipelineDescriptor>>,
|
||||
shader_events: Res<Events<AssetEvent<Shader>>>,
|
||||
mut shader_event_reader: Local<EventReader<AssetEvent<Shader>>>,
|
||||
mut shader_events: EventReader<AssetEvent<Shader>>,
|
||||
mut pipeline_compiler: ResMut<PipelineCompiler>,
|
||||
render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
||||
) {
|
||||
for event in shader_event_reader.iter(&shader_events) {
|
||||
for event in shader_events.iter() {
|
||||
match event {
|
||||
AssetEvent::Modified { handle } => {
|
||||
if let Err(e) = pipeline_compiler.update_shader(
|
||||
|
@ -2,9 +2,9 @@ use super::{Extent3d, SamplerDescriptor, TextureDescriptor, TextureDimension, Te
|
||||
use crate::renderer::{
|
||||
RenderResource, RenderResourceContext, RenderResourceId, RenderResourceType,
|
||||
};
|
||||
use bevy_app::prelude::{EventReader, Events};
|
||||
use bevy_app::prelude::EventReader;
|
||||
use bevy_asset::{AssetEvent, Assets, Handle};
|
||||
use bevy_ecs::{Res, ResMut};
|
||||
use bevy_ecs::Res;
|
||||
use bevy_reflect::TypeUuid;
|
||||
use bevy_utils::HashSet;
|
||||
|
||||
@ -126,14 +126,13 @@ impl Texture {
|
||||
}
|
||||
|
||||
pub fn texture_resource_system(
|
||||
mut state: ResMut<TextureResourceSystemState>,
|
||||
render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
||||
textures: Res<Assets<Texture>>,
|
||||
texture_events: Res<Events<AssetEvent<Texture>>>,
|
||||
mut texture_events: EventReader<AssetEvent<Texture>>,
|
||||
) {
|
||||
let render_resource_context = &**render_resource_context;
|
||||
let mut changed_textures = HashSet::default();
|
||||
for event in state.event_reader.iter(&texture_events) {
|
||||
for event in texture_events.iter() {
|
||||
match event {
|
||||
AssetEvent::Created { handle } => {
|
||||
changed_textures.insert(handle);
|
||||
@ -191,11 +190,6 @@ impl Texture {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct TextureResourceSystemState {
|
||||
event_reader: EventReader<AssetEvent<Texture>>,
|
||||
}
|
||||
|
||||
impl RenderResource for Option<Handle<Texture>> {
|
||||
fn resource_type(&self) -> Option<RenderResourceType> {
|
||||
self.as_ref().map(|_texture| RenderResourceType::Texture)
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{DynamicScene, Scene};
|
||||
use bevy_app::prelude::*;
|
||||
use bevy_app::{prelude::*, ManualEventReader};
|
||||
use bevy_asset::{AssetEvent, Assets, Handle};
|
||||
use bevy_ecs::{Entity, EntityMap, Resources, World};
|
||||
use bevy_reflect::{ReflectComponent, ReflectMapEntities, TypeRegistryArc};
|
||||
@ -27,7 +27,7 @@ pub struct SceneSpawner {
|
||||
spawned_scenes: HashMap<Handle<Scene>, Vec<InstanceId>>,
|
||||
spawned_dynamic_scenes: HashMap<Handle<DynamicScene>, Vec<InstanceId>>,
|
||||
spawned_instances: HashMap<InstanceId, InstanceInfo>,
|
||||
scene_asset_event_reader: EventReader<AssetEvent<DynamicScene>>,
|
||||
scene_asset_event_reader: ManualEventReader<AssetEvent<DynamicScene>>,
|
||||
dynamic_scenes_to_spawn: Vec<Handle<DynamicScene>>,
|
||||
scenes_to_spawn: Vec<(Handle<Scene>, InstanceId)>,
|
||||
scenes_to_despawn: Vec<Handle<DynamicScene>>,
|
||||
|
@ -1,8 +1,8 @@
|
||||
mod convert;
|
||||
|
||||
use crate::{Node, Style};
|
||||
use bevy_app::{EventReader, Events};
|
||||
use bevy_ecs::{Changed, Entity, Flags, Local, Query, QueryFilter, Res, ResMut, With, Without};
|
||||
use bevy_app::EventReader;
|
||||
use bevy_ecs::{Changed, Entity, Flags, Query, QueryFilter, Res, ResMut, With, Without};
|
||||
use bevy_log::warn;
|
||||
use bevy_math::Vec2;
|
||||
use bevy_text::CalculatedSize;
|
||||
@ -187,8 +187,7 @@ unsafe impl Sync for FlexSurface {}
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn flex_node_system(
|
||||
windows: Res<Windows>,
|
||||
mut scale_factor_reader: Local<EventReader<WindowScaleFactorChanged>>,
|
||||
scale_factor_events: Res<Events<WindowScaleFactorChanged>>,
|
||||
mut scale_factor_events: EventReader<WindowScaleFactorChanged>,
|
||||
mut flex_surface: ResMut<FlexSurface>,
|
||||
root_node_query: Query<Entity, (With<Node>, Without<Parent>)>,
|
||||
node_query: Query<(Entity, &Style, Option<&CalculatedSize>), (With<Node>, Changed<Style>)>,
|
||||
@ -219,7 +218,7 @@ pub fn flex_node_system(
|
||||
1.
|
||||
};
|
||||
|
||||
if scale_factor_reader.latest(&scale_factor_events).is_some() {
|
||||
if scale_factor_events.iter().next_back().is_some() {
|
||||
update_changed(
|
||||
&mut *flex_surface,
|
||||
logical_to_physical_factor,
|
||||
|
@ -2,7 +2,7 @@ use crate::{
|
||||
renderer::{WgpuRenderGraphExecutor, WgpuRenderResourceContext},
|
||||
WgpuBackend, WgpuOptions, WgpuPowerOptions,
|
||||
};
|
||||
use bevy_app::prelude::*;
|
||||
use bevy_app::{prelude::*, ManualEventReader};
|
||||
use bevy_ecs::{Resources, World};
|
||||
use bevy_render::{
|
||||
render_graph::{DependentNodeStager, RenderGraph, RenderGraphStager},
|
||||
@ -15,8 +15,8 @@ pub struct WgpuRenderer {
|
||||
pub instance: wgpu::Instance,
|
||||
pub device: Arc<wgpu::Device>,
|
||||
pub queue: wgpu::Queue,
|
||||
pub window_resized_event_reader: EventReader<WindowResized>,
|
||||
pub window_created_event_reader: EventReader<WindowCreated>,
|
||||
pub window_resized_event_reader: ManualEventReader<WindowResized>,
|
||||
pub window_created_event_reader: ManualEventReader<WindowCreated>,
|
||||
pub initialized: bool,
|
||||
}
|
||||
|
||||
|
@ -3,24 +3,13 @@ use bevy_app::{
|
||||
prelude::{EventReader, Events},
|
||||
AppExit,
|
||||
};
|
||||
use bevy_ecs::{Local, Res, ResMut};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ExitOnWindowCloseState {
|
||||
event_reader: EventReader<WindowCloseRequested>,
|
||||
}
|
||||
use bevy_ecs::ResMut;
|
||||
|
||||
pub fn exit_on_window_close_system(
|
||||
mut state: Local<ExitOnWindowCloseState>,
|
||||
mut app_exit_events: ResMut<Events<AppExit>>,
|
||||
window_close_requested_events: Res<Events<WindowCloseRequested>>,
|
||||
mut window_close_requested_events: EventReader<WindowCloseRequested>,
|
||||
) {
|
||||
if state
|
||||
.event_reader
|
||||
.iter(&window_close_requested_events)
|
||||
.next()
|
||||
.is_some()
|
||||
{
|
||||
if window_close_requested_events.iter().next().is_some() {
|
||||
app_exit_events.send(AppExit);
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use bevy_input::{
|
||||
pub use winit_config::*;
|
||||
pub use winit_windows::*;
|
||||
|
||||
use bevy_app::{prelude::*, AppExit};
|
||||
use bevy_app::{prelude::*, AppExit, ManualEventReader};
|
||||
use bevy_ecs::{IntoSystem, Resources, World};
|
||||
use bevy_math::Vec2;
|
||||
use bevy_utils::tracing::{error, trace, warn};
|
||||
@ -191,8 +191,8 @@ pub fn winit_runner_any_thread(app: App) {
|
||||
}
|
||||
|
||||
pub fn winit_runner_with(mut app: App, mut event_loop: EventLoop<()>) {
|
||||
let mut create_window_event_reader = EventReader::<CreateWindow>::default();
|
||||
let mut app_exit_event_reader = EventReader::<AppExit>::default();
|
||||
let mut create_window_event_reader = ManualEventReader::<CreateWindow>::default();
|
||||
let mut app_exit_event_reader = ManualEventReader::<AppExit>::default();
|
||||
|
||||
app.resources.insert_thread_local(event_loop.create_proxy());
|
||||
|
||||
@ -209,7 +209,11 @@ pub fn winit_runner_with(mut app: App, mut event_loop: EventLoop<()>) {
|
||||
*control_flow = ControlFlow::Poll;
|
||||
|
||||
if let Some(app_exit_events) = app.resources.get_mut::<Events<AppExit>>() {
|
||||
if app_exit_event_reader.latest(&app_exit_events).is_some() {
|
||||
if app_exit_event_reader
|
||||
.iter(&app_exit_events)
|
||||
.next_back()
|
||||
.is_some()
|
||||
{
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
}
|
||||
@ -453,7 +457,7 @@ pub fn winit_runner_with(mut app: App, mut event_loop: EventLoop<()>) {
|
||||
fn handle_create_window_events(
|
||||
resources: &mut Resources,
|
||||
event_loop: &EventLoopWindowTarget<()>,
|
||||
create_window_event_reader: &mut EventReader<CreateWindow>,
|
||||
create_window_event_reader: &mut ManualEventReader<CreateWindow>,
|
||||
) {
|
||||
let mut winit_windows = resources.get_mut::<WinitWindows>().unwrap();
|
||||
let mut windows = resources.get_mut::<Windows>().unwrap();
|
||||
|
@ -7,11 +7,8 @@ fn main() {
|
||||
.run();
|
||||
}
|
||||
|
||||
fn file_drag_and_drop_system(
|
||||
mut reader: Local<EventReader<FileDragAndDrop>>,
|
||||
events: Res<Events<FileDragAndDrop>>,
|
||||
) {
|
||||
for event in reader.iter(&events) {
|
||||
fn file_drag_and_drop_system(mut events: EventReader<FileDragAndDrop>) {
|
||||
for event in events.iter() {
|
||||
println!("{:?}", event);
|
||||
}
|
||||
}
|
||||
|
@ -42,11 +42,8 @@ fn event_trigger_system(
|
||||
}
|
||||
|
||||
// prints events as they come in
|
||||
fn event_listener_system(
|
||||
mut my_event_reader: Local<EventReader<MyEvent>>,
|
||||
my_events: Res<Events<MyEvent>>,
|
||||
) {
|
||||
for my_event in my_event_reader.iter(&my_events) {
|
||||
fn event_listener_system(mut events: EventReader<MyEvent>) {
|
||||
for my_event in events.iter() {
|
||||
println!("{}", my_event.message);
|
||||
}
|
||||
}
|
||||
|
@ -7,17 +7,9 @@ fn main() {
|
||||
.run();
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct State {
|
||||
event_reader: EventReader<ReceivedCharacter>,
|
||||
}
|
||||
|
||||
/// This system prints out all char events as they come in
|
||||
fn print_char_event_system(
|
||||
mut state: Local<State>,
|
||||
char_input_events: Res<Events<ReceivedCharacter>>,
|
||||
) {
|
||||
for event in state.event_reader.iter(&char_input_events) {
|
||||
fn print_char_event_system(mut char_input_events: EventReader<ReceivedCharacter>) {
|
||||
for event in char_input_events.iter() {
|
||||
println!("{:?}: '{}'", event, event.char);
|
||||
}
|
||||
}
|
||||
|
@ -16,11 +16,13 @@ fn main() {
|
||||
#[derive(Default)]
|
||||
struct GamepadLobby {
|
||||
gamepads: HashSet<Gamepad>,
|
||||
gamepad_event_reader: EventReader<GamepadEvent>,
|
||||
}
|
||||
|
||||
fn connection_system(mut lobby: ResMut<GamepadLobby>, gamepad_event: Res<Events<GamepadEvent>>) {
|
||||
for event in lobby.gamepad_event_reader.iter(&gamepad_event) {
|
||||
fn connection_system(
|
||||
mut lobby: ResMut<GamepadLobby>,
|
||||
mut gamepad_event: EventReader<GamepadEvent>,
|
||||
) {
|
||||
for event in gamepad_event.iter() {
|
||||
match &event {
|
||||
GamepadEvent(gamepad, GamepadEventType::Connected) => {
|
||||
lobby.gamepads.insert(*gamepad);
|
||||
|
@ -10,11 +10,8 @@ fn main() {
|
||||
.run();
|
||||
}
|
||||
|
||||
fn gamepad_events(
|
||||
mut event_reader: Local<EventReader<GamepadEvent>>,
|
||||
gamepad_event: Res<Events<GamepadEvent>>,
|
||||
) {
|
||||
for event in event_reader.iter(&gamepad_event) {
|
||||
fn gamepad_events(mut gamepad_event: EventReader<GamepadEvent>) {
|
||||
for event in gamepad_event.iter() {
|
||||
match &event {
|
||||
GamepadEvent(gamepad, GamepadEventType::Connected) => {
|
||||
println!("{:?} Connected", gamepad);
|
||||
|
@ -7,17 +7,9 @@ fn main() {
|
||||
.run();
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct State {
|
||||
event_reader: EventReader<KeyboardInput>,
|
||||
}
|
||||
|
||||
/// This system prints out all keyboard events as they come in
|
||||
fn print_keyboard_event_system(
|
||||
mut state: Local<State>,
|
||||
keyboard_input_events: Res<Events<KeyboardInput>>,
|
||||
) {
|
||||
for event in state.event_reader.iter(&keyboard_input_events) {
|
||||
fn print_keyboard_event_system(mut keyboard_input_events: EventReader<KeyboardInput>) {
|
||||
for event in keyboard_input_events.iter() {
|
||||
println!("{:?}", event);
|
||||
}
|
||||
}
|
||||
|
@ -11,38 +11,26 @@ fn main() {
|
||||
.run();
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct State {
|
||||
mouse_button_event_reader: EventReader<MouseButtonInput>,
|
||||
mouse_motion_event_reader: EventReader<MouseMotion>,
|
||||
cursor_moved_event_reader: EventReader<CursorMoved>,
|
||||
mouse_wheel_event_reader: EventReader<MouseWheel>,
|
||||
}
|
||||
|
||||
/// This system prints out all mouse events as they come in
|
||||
fn print_mouse_events_system(
|
||||
mut state: Local<State>,
|
||||
mouse_button_input_events: Res<Events<MouseButtonInput>>,
|
||||
mouse_motion_events: Res<Events<MouseMotion>>,
|
||||
cursor_moved_events: Res<Events<CursorMoved>>,
|
||||
mouse_wheel_events: Res<Events<MouseWheel>>,
|
||||
mut mouse_button_input_events: EventReader<MouseButtonInput>,
|
||||
mut mouse_motion_events: EventReader<MouseMotion>,
|
||||
mut cursor_moved_events: EventReader<CursorMoved>,
|
||||
mut mouse_wheel_events: EventReader<MouseWheel>,
|
||||
) {
|
||||
for event in state
|
||||
.mouse_button_event_reader
|
||||
.iter(&mouse_button_input_events)
|
||||
{
|
||||
for event in mouse_button_input_events.iter() {
|
||||
println!("{:?}", event);
|
||||
}
|
||||
|
||||
for event in state.mouse_motion_event_reader.iter(&mouse_motion_events) {
|
||||
for event in mouse_motion_events.iter() {
|
||||
println!("{:?}", event);
|
||||
}
|
||||
|
||||
for event in state.cursor_moved_event_reader.iter(&cursor_moved_events) {
|
||||
for event in cursor_moved_events.iter() {
|
||||
println!("{:?}", event);
|
||||
}
|
||||
|
||||
for event in state.mouse_wheel_event_reader.iter(&mouse_wheel_events) {
|
||||
for event in mouse_wheel_events.iter() {
|
||||
println!("{:?}", event);
|
||||
}
|
||||
}
|
||||
|
@ -7,13 +7,8 @@ fn main() {
|
||||
.run();
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct State {
|
||||
event_reader: EventReader<TouchInput>,
|
||||
}
|
||||
|
||||
fn touch_event_system(mut state: Local<State>, touch_events: Res<Events<TouchInput>>) {
|
||||
for event in state.event_reader.iter(&touch_events) {
|
||||
fn touch_event_system(mut touch_events: EventReader<TouchInput>) {
|
||||
for event in touch_events.iter() {
|
||||
println!("{:?}", event);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ fn main() {
|
||||
// Track ticks (sanity check, whether game loop is running)
|
||||
.add_system(counter.system())
|
||||
// Track input events
|
||||
.init_resource::<TrackInputState>()
|
||||
.add_system(track_input_events.system())
|
||||
.run();
|
||||
}
|
||||
@ -45,25 +44,15 @@ struct CounterState {
|
||||
count: u32,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct TrackInputState {
|
||||
keys: EventReader<KeyboardInput>,
|
||||
cursor: EventReader<CursorMoved>,
|
||||
motion: EventReader<MouseMotion>,
|
||||
mousebtn: EventReader<MouseButtonInput>,
|
||||
scroll: EventReader<MouseWheel>,
|
||||
}
|
||||
|
||||
fn track_input_events(
|
||||
mut state: ResMut<TrackInputState>,
|
||||
ev_keys: Res<Events<KeyboardInput>>,
|
||||
ev_cursor: Res<Events<CursorMoved>>,
|
||||
ev_motion: Res<Events<MouseMotion>>,
|
||||
ev_mousebtn: Res<Events<MouseButtonInput>>,
|
||||
ev_scroll: Res<Events<MouseWheel>>,
|
||||
mut ev_keys: EventReader<KeyboardInput>,
|
||||
mut ev_cursor: EventReader<CursorMoved>,
|
||||
mut ev_motion: EventReader<MouseMotion>,
|
||||
mut ev_mousebtn: EventReader<MouseButtonInput>,
|
||||
mut ev_scroll: EventReader<MouseWheel>,
|
||||
) {
|
||||
// Keyboard input
|
||||
for ev in state.keys.iter(&ev_keys) {
|
||||
for ev in ev_keys.iter() {
|
||||
if ev.state.is_pressed() {
|
||||
info!("Just pressed key: {:?}", ev.key_code);
|
||||
} else {
|
||||
@ -72,17 +61,17 @@ fn track_input_events(
|
||||
}
|
||||
|
||||
// Absolute cursor position (in window coordinates)
|
||||
for ev in state.cursor.iter(&ev_cursor) {
|
||||
for ev in ev_cursor.iter() {
|
||||
info!("Cursor at: {}", ev.position);
|
||||
}
|
||||
|
||||
// Relative mouse motion
|
||||
for ev in state.motion.iter(&ev_motion) {
|
||||
for ev in ev_motion.iter() {
|
||||
info!("Mouse moved {} pixels", ev.delta);
|
||||
}
|
||||
|
||||
// Mouse buttons
|
||||
for ev in state.mousebtn.iter(&ev_mousebtn) {
|
||||
for ev in ev_mousebtn.iter() {
|
||||
if ev.state.is_pressed() {
|
||||
info!("Just pressed mouse button: {:?}", ev.button);
|
||||
} else {
|
||||
@ -91,7 +80,7 @@ fn track_input_events(
|
||||
}
|
||||
|
||||
// scrolling (mouse wheel, touchpad, etc.)
|
||||
for ev in state.scroll.iter(&ev_scroll) {
|
||||
for ev in ev_scroll.iter() {
|
||||
info!(
|
||||
"Scrolled vertically by {} and horizontally by {}.",
|
||||
ev.y, ev.x
|
||||
|
Loading…
Reference in New Issue
Block a user