Skip to content

Commit

Permalink
generalize Reads/Writes to resources in general
Browse files Browse the repository at this point in the history
  • Loading branch information
JoJoJet committed Jul 21, 2022
1 parent 862ad96 commit 2891665
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 88 deletions.
90 changes: 3 additions & 87 deletions crates/bevy_ecs/src/event.rs
Original file line number Diff line number Diff line change
@@ -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::{
Expand Down Expand Up @@ -182,52 +179,9 @@ impl<E: Event> DerefMut for EventSequence<E> {
}
}

/// [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<MyEvent>) {
/// // ...
/// # unimplemented!()
/// }
///
/// // The system has been automatically given the label `Reads::from::<MyEvent>()`.
/// let system = IntoSystem::into_system(reader_system);
/// assert!(system.default_labels().contains(&Reads::from::<MyEvent>().as_label()));
/// ```
pub struct Reads(());

impl Reads {
/// Returns a [`SystemLabel`] for a system that reads events of type `E`.
pub fn from<E: Event>() -> impl SystemLabel {
struct ReadSystem<E>(PhantomData<E>);

impl<E: 'static> SystemLabel for ReadSystem<E> {
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::<Self>()
}
}

ReadSystem::<E>(PhantomData)
}
}

/// Reads events of type `T` in order and tracks which events have already been read.
#[derive(SystemParam)]
#[system_param(label = Reads::from::<E>())]
#[system_param(label = crate::system::Reads::from::<E>())]
pub struct EventReader<'w, 's, E: Event> {
reader: Local<'s, ManualEventReader<E>>,
events: Res<'w, Events<E>>,
Expand Down Expand Up @@ -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<MyEvent>) {
/// // ...
/// # unimplemented!()
/// }
///
/// // The system has automatically been given the label `Writes::to::<MyEvent>()`.
/// let system = IntoSystem::into_system(writer_system);
/// assert!(system.default_labels().contains(&Writes::to::<MyEvent>().as_label()));
/// ```
pub struct Writes(());

impl Writes {
/// Returns a [`SystemLabel`] for a system that can write events of type `E`.
pub fn to<E: Event>() -> impl SystemLabel {
struct WriteSystem<E>(PhantomData<E>);

impl<E: 'static> SystemLabel for WriteSystem<E> {
fn as_str(&self) -> &'static str {
std::any::type_name::<E>()
}
}

WriteSystem::<E>(PhantomData)
}
}

/// Sends events of type `T`.
///
/// # Usage
Expand Down Expand Up @@ -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::<E>())]
#[system_param(label = crate::system::Writes::to::<E>())]
pub struct EventWriter<'w, 's, E: Event> {
events: ResMut<'w, Events<E>>,
#[system_param(ignore)]
Expand Down
83 changes: 82 additions & 1 deletion crates/bevy_ecs/src/system/system_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};
Expand Down Expand Up @@ -227,6 +227,87 @@ pub trait Resource: Send + Sync + 'static {}

impl<T> 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::*;
/// use bevy_ecs::system::Reads;
///
/// // New event type.
/// struct MyEvent;
///
/// // Declare a system that reads from it.
/// fn reader_system(event_reader: EventReader<MyEvent>) {
/// // ...
/// # unimplemented!()
/// }
///
/// // The system has been automatically given the label `Reads::from::<MyEvent>()`.
/// let system = IntoSystem::into_system(reader_system);
/// assert!(system.default_labels().contains(&Reads::from::<MyEvent>().as_label()));
/// ```
pub struct Reads(());

impl Reads {
/// Returns a [`SystemLabel`] for a system that can read the resource `E`.
pub fn from<E: Resource>() -> impl SystemLabel {
struct ReadSystem<E>(PhantomData<E>);

impl<E: 'static> SystemLabel for ReadSystem<E> {
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::<Self>()
}
}

ReadSystem::<E>(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::*;
/// use bevy_ecs::system::Writes;
///
/// // New event type.
/// struct MyEvent;
///
/// // Declare a system that writes to it.
/// fn writer_system(mut event_writer: EventWriter<MyEvent>) {
/// // ...
/// # unimplemented!()
/// }
///
/// // The system has automatically been given the label `Writes::to::<MyEvent>()`.
/// let system = IntoSystem::into_system(writer_system);
/// assert!(system.default_labels().contains(&Writes::to::<MyEvent>().as_label()));
/// ```
pub struct Writes(());

impl Writes {
/// Returns a [`SystemLabel`] for a system that might modify the resource `E`.
pub fn to<E: Resource>() -> impl SystemLabel {
struct WriteSystem<E>(PhantomData<E>);

impl<E: 'static> SystemLabel for WriteSystem<E> {
fn as_str(&self) -> &'static str {
std::any::type_name::<E>()
}
}

WriteSystem::<E>(PhantomData)
}
}

/// Shared borrow of a resource.
///
/// See the [`World`] documentation to see the usage of a resource.
Expand Down

0 comments on commit 2891665

Please sign in to comment.