diff --git a/crates/bevy_ecs/src/event.rs b/crates/bevy_ecs/src/event.rs index 8b45aac68f55e3..ef162e4f9a4e1e 100644 --- a/crates/bevy_ecs/src/event.rs +++ b/crates/bevy_ecs/src/event.rs @@ -1,10 +1,7 @@ //! Event handling types. use crate as bevy_ecs; -use crate::{ - schedule::SystemLabel, - system::{Local, Res, ResMut, SystemParam}, -}; +use crate::system::{Local, Res, ResMut, SystemParam}; use bevy_utils::tracing::trace; use std::ops::{Deref, DerefMut}; use std::{ @@ -182,52 +179,9 @@ impl DerefMut for EventSequence { } } -/// [Label](SystemLabel) for a [`System`](crate::system::System) that reads events of type `E`. -/// This is automatically applied to any system that contains an [`EventReader`]. -/// -/// # Examples -/// ``` -/// # use bevy_ecs::prelude::*; -/// use bevy_ecs::event::Reads; -/// -/// // New event type. -/// struct MyEvent; -/// -/// // Declare a system that reads from it. -/// fn reader_system(event_reader: EventReader) { -/// // ... -/// # unimplemented!() -/// } -/// -/// // The system has been automatically given the label `Reads::from::()`. -/// let system = IntoSystem::into_system(reader_system); -/// assert!(system.default_labels().contains(&Reads::from::().as_label())); -/// ``` -pub struct Reads(()); - -impl Reads { - /// Returns a [`SystemLabel`] for a system that reads events of type `E`. - pub fn from() -> impl SystemLabel { - struct ReadSystem(PhantomData); - - impl SystemLabel for ReadSystem { - fn as_str(&self) -> &'static str { - // FIXME: using `type_name` for equality is kinda sketchy, - // but we won't need it after https://github.com/bevyengine/bevy/pull/5377. - // This *should* be fine for the time being though, as the behavior - // of `type_name` is only subject to change between compiler versions, - // so the only place it might be able to cause issues is with dynamic plugins. - std::any::type_name::() - } - } - - ReadSystem::(PhantomData) - } -} - /// Reads events of type `T` in order and tracks which events have already been read. #[derive(SystemParam)] -#[system_param(label = Reads::from::())] +#[system_param(label = crate::system::Reads::from::())] pub struct EventReader<'w, 's, E: Event> { reader: Local<'s, ManualEventReader>, events: Res<'w, Events>, @@ -295,44 +249,6 @@ impl<'w, 's, E: Event> EventReader<'w, 's, E> { } } -/// [Label](SystemLabel) for a [`System`](crate::system::System) that can write events of type `E`. -/// This is automatically applied to any system that contains an [`EventWriter`]. -/// -/// # Examples -/// ``` -/// # use bevy_ecs::prelude::*; -/// use bevy_ecs::event::Writes; -/// -/// // New event type. -/// struct MyEvent; -/// -/// // Declare a system that writes to it. -/// fn writer_system(mut event_writer: EventWriter) { -/// // ... -/// # unimplemented!() -/// } -/// -/// // The system has automatically been given the label `Writes::to::()`. -/// let system = IntoSystem::into_system(writer_system); -/// assert!(system.default_labels().contains(&Writes::to::().as_label())); -/// ``` -pub struct Writes(()); - -impl Writes { - /// Returns a [`SystemLabel`] for a system that can write events of type `E`. - pub fn to() -> impl SystemLabel { - struct WriteSystem(PhantomData); - - impl SystemLabel for WriteSystem { - fn as_str(&self) -> &'static str { - std::any::type_name::() - } - } - - WriteSystem::(PhantomData) - } -} - /// Sends events of type `T`. /// /// # Usage @@ -377,7 +293,7 @@ impl Writes { /// ``` /// Note that this is considered *non-idiomatic*, and should only be used when `EventWriter` will not work. #[derive(SystemParam)] -#[system_param(label = Writes::to::())] +#[system_param(label = crate::system::Writes::to::())] pub struct EventWriter<'w, 's, E: Event> { events: ResMut<'w, Events>, #[system_param(ignore)] diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index 3764e380857730..7b92b16c48c93d 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -8,7 +8,7 @@ use crate::{ query::{ Access, FilteredAccess, FilteredAccessSet, QueryState, ReadOnlyWorldQuery, WorldQuery, }, - schedule::SystemLabelId, + schedule::{SystemLabel, SystemLabelId}, system::{CommandQueue, Commands, Query, SystemMeta}, world::{FromWorld, World}, }; @@ -227,6 +227,89 @@ pub trait Resource: Send + Sync + 'static {} impl Resource for T where T: Send + Sync + 'static {} +/// [Label](SystemLabel) for a [`System`](crate::system::System) that reads events of type `E`. +/// This is automatically applied to any system that contains an [`EventReader`]. +/// +/// # Examples +/// ``` +/// # use bevy_ecs::{prelude::*, event::Events}; +/// use bevy_ecs::system::Reads; +/// +/// // New event type. +/// struct MyEvent; +/// +/// // Declare a system that reads from it. +/// fn reader_system(event_reader: EventReader) { +/// // ... +/// # unimplemented!() +/// } +/// +/// // The system has been automatically given the label `Reads::from::()`. +/// let system = IntoSystem::into_system(reader_system); +/// assert!(system.default_labels().contains(&Reads::from::().as_label())); +/// # assert!(system.default_labels().contains(&Reads::from::>().as_label())); +/// ``` +pub struct Reads(()); + +impl Reads { + /// Returns a [`SystemLabel`] for a system that can read the resource `E`. + pub fn from() -> impl SystemLabel { + struct ReadSystem(PhantomData); + + impl SystemLabel for ReadSystem { + fn as_str(&self) -> &'static str { + // FIXME: using `type_name` for equality is kinda sketchy, + // but we won't need it after https://github.com/bevyengine/bevy/pull/5377. + // This *should* be fine for the time being though, as the behavior + // of `type_name` is only subject to change between compiler versions, + // so the only place it might be able to cause issues is with dynamic plugins. + std::any::type_name::() + } + } + + ReadSystem::(PhantomData) + } +} + +/// [Label](SystemLabel) for a [`System`](crate::system::System) that can write events of type `E`. +/// This is automatically applied to any system that contains an [`EventWriter`]. +/// +/// # Examples +/// ``` +/// # use bevy_ecs::{prelude::*, event::Events}; +/// use bevy_ecs::system::Writes; +/// +/// // New event type. +/// struct MyEvent; +/// +/// // Declare a system that writes to it. +/// fn writer_system(mut event_writer: EventWriter) { +/// // ... +/// # unimplemented!() +/// } +/// +/// // The system has automatically been given the label `Writes::to::()`. +/// let system = IntoSystem::into_system(writer_system); +/// assert!(system.default_labels().contains(&Writes::to::().as_label())); +/// # assert!(system.default_labels().contains(&Writes::to::>().as_label())); +/// ``` +pub struct Writes(()); + +impl Writes { + /// Returns a [`SystemLabel`] for a system that might modify the resource `E`. + pub fn to() -> impl SystemLabel { + struct WriteSystem(PhantomData); + + impl SystemLabel for WriteSystem { + fn as_str(&self) -> &'static str { + std::any::type_name::() + } + } + + WriteSystem::(PhantomData) + } +} + /// Shared borrow of a resource. /// /// See the [`World`] documentation to see the usage of a resource. @@ -309,6 +392,10 @@ pub struct ResState { impl<'a, T: Resource> SystemParam for Res<'a, T> { type Fetch = ResState; + #[inline] + fn auto_labels() -> Vec { + vec![Reads::from::().as_label()] + } } // SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res @@ -417,6 +504,10 @@ pub struct ResMutState { impl<'a, T: Resource> SystemParam for ResMut<'a, T> { type Fetch = ResMutState; + #[inline] + fn auto_labels() -> Vec { + vec![Writes::to::().as_label()] + } } // SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res