Skip to content

Commit 0079af0

Browse files
committed
generalize Reads/Writes to resources
1 parent 862ad96 commit 0079af0

File tree

2 files changed

+95
-88
lines changed

2 files changed

+95
-88
lines changed

crates/bevy_ecs/src/event.rs

Lines changed: 3 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
//! Event handling types.
22
33
use crate as bevy_ecs;
4-
use crate::{
5-
schedule::SystemLabel,
6-
system::{Local, Res, ResMut, SystemParam},
7-
};
4+
use crate::system::{Local, Res, ResMut, SystemParam};
85
use bevy_utils::tracing::trace;
96
use std::ops::{Deref, DerefMut};
107
use std::{
@@ -182,52 +179,9 @@ impl<E: Event> DerefMut for EventSequence<E> {
182179
}
183180
}
184181

185-
/// [Label](SystemLabel) for a [`System`](crate::system::System) that reads events of type `E`.
186-
/// This is automatically applied to any system that contains an [`EventReader`].
187-
///
188-
/// # Examples
189-
/// ```
190-
/// # use bevy_ecs::prelude::*;
191-
/// use bevy_ecs::event::Reads;
192-
///
193-
/// // New event type.
194-
/// struct MyEvent;
195-
///
196-
/// // Declare a system that reads from it.
197-
/// fn reader_system(event_reader: EventReader<MyEvent>) {
198-
/// // ...
199-
/// # unimplemented!()
200-
/// }
201-
///
202-
/// // The system has been automatically given the label `Reads::from::<MyEvent>()`.
203-
/// let system = IntoSystem::into_system(reader_system);
204-
/// assert!(system.default_labels().contains(&Reads::from::<MyEvent>().as_label()));
205-
/// ```
206-
pub struct Reads(());
207-
208-
impl Reads {
209-
/// Returns a [`SystemLabel`] for a system that reads events of type `E`.
210-
pub fn from<E: Event>() -> impl SystemLabel {
211-
struct ReadSystem<E>(PhantomData<E>);
212-
213-
impl<E: 'static> SystemLabel for ReadSystem<E> {
214-
fn as_str(&self) -> &'static str {
215-
// FIXME: using `type_name` for equality is kinda sketchy,
216-
// but we won't need it after https://github.com/bevyengine/bevy/pull/5377.
217-
// This *should* be fine for the time being though, as the behavior
218-
// of `type_name` is only subject to change between compiler versions,
219-
// so the only place it might be able to cause issues is with dynamic plugins.
220-
std::any::type_name::<Self>()
221-
}
222-
}
223-
224-
ReadSystem::<E>(PhantomData)
225-
}
226-
}
227-
228182
/// Reads events of type `T` in order and tracks which events have already been read.
229183
#[derive(SystemParam)]
230-
#[system_param(label = Reads::from::<E>())]
184+
#[system_param(label = crate::system::Reads::from::<E>())]
231185
pub struct EventReader<'w, 's, E: Event> {
232186
reader: Local<'s, ManualEventReader<E>>,
233187
events: Res<'w, Events<E>>,
@@ -295,44 +249,6 @@ impl<'w, 's, E: Event> EventReader<'w, 's, E> {
295249
}
296250
}
297251

298-
/// [Label](SystemLabel) for a [`System`](crate::system::System) that can write events of type `E`.
299-
/// This is automatically applied to any system that contains an [`EventWriter`].
300-
///
301-
/// # Examples
302-
/// ```
303-
/// # use bevy_ecs::prelude::*;
304-
/// use bevy_ecs::event::Writes;
305-
///
306-
/// // New event type.
307-
/// struct MyEvent;
308-
///
309-
/// // Declare a system that writes to it.
310-
/// fn writer_system(mut event_writer: EventWriter<MyEvent>) {
311-
/// // ...
312-
/// # unimplemented!()
313-
/// }
314-
///
315-
/// // The system has automatically been given the label `Writes::to::<MyEvent>()`.
316-
/// let system = IntoSystem::into_system(writer_system);
317-
/// assert!(system.default_labels().contains(&Writes::to::<MyEvent>().as_label()));
318-
/// ```
319-
pub struct Writes(());
320-
321-
impl Writes {
322-
/// Returns a [`SystemLabel`] for a system that can write events of type `E`.
323-
pub fn to<E: Event>() -> impl SystemLabel {
324-
struct WriteSystem<E>(PhantomData<E>);
325-
326-
impl<E: 'static> SystemLabel for WriteSystem<E> {
327-
fn as_str(&self) -> &'static str {
328-
std::any::type_name::<E>()
329-
}
330-
}
331-
332-
WriteSystem::<E>(PhantomData)
333-
}
334-
}
335-
336252
/// Sends events of type `T`.
337253
///
338254
/// # Usage
@@ -377,7 +293,7 @@ impl Writes {
377293
/// ```
378294
/// Note that this is considered *non-idiomatic*, and should only be used when `EventWriter` will not work.
379295
#[derive(SystemParam)]
380-
#[system_param(label = Writes::to::<E>())]
296+
#[system_param(label = crate::system::Writes::to::<E>())]
381297
pub struct EventWriter<'w, 's, E: Event> {
382298
events: ResMut<'w, Events<E>>,
383299
#[system_param(ignore)]

crates/bevy_ecs/src/system/system_param.rs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
query::{
99
Access, FilteredAccess, FilteredAccessSet, QueryState, ReadOnlyWorldQuery, WorldQuery,
1010
},
11-
schedule::SystemLabelId,
11+
schedule::{SystemLabel, SystemLabelId},
1212
system::{CommandQueue, Commands, Query, SystemMeta},
1313
world::{FromWorld, World},
1414
};
@@ -227,6 +227,89 @@ pub trait Resource: Send + Sync + 'static {}
227227

228228
impl<T> Resource for T where T: Send + Sync + 'static {}
229229

230+
/// [Label](SystemLabel) for a [`System`](crate::system::System) that reads events of type `E`.
231+
/// This is automatically applied to any system that contains an [`EventReader`].
232+
///
233+
/// # Examples
234+
/// ```
235+
/// # use bevy_ecs::{prelude::*, event::Events};
236+
/// use bevy_ecs::system::Reads;
237+
///
238+
/// // New event type.
239+
/// struct MyEvent;
240+
///
241+
/// // Declare a system that reads from it.
242+
/// fn reader_system(event_reader: EventReader<MyEvent>) {
243+
/// // ...
244+
/// # unimplemented!()
245+
/// }
246+
///
247+
/// // The system has been automatically given the label `Reads::from::<MyEvent>()`.
248+
/// let system = IntoSystem::into_system(reader_system);
249+
/// assert!(system.default_labels().contains(&Reads::from::<MyEvent>().as_label()));
250+
/// # assert!(system.default_labels().contains(&Reads::from::<Events<MyEvent>>().as_label()));
251+
/// ```
252+
pub struct Reads(());
253+
254+
impl Reads {
255+
/// Returns a [`SystemLabel`] for a system that can read the resource `E`.
256+
pub fn from<E: Resource>() -> impl SystemLabel {
257+
struct ReadSystem<E>(PhantomData<E>);
258+
259+
impl<E: 'static> SystemLabel for ReadSystem<E> {
260+
fn as_str(&self) -> &'static str {
261+
// FIXME: using `type_name` for equality is kinda sketchy,
262+
// but we won't need it after https://github.com/bevyengine/bevy/pull/5377.
263+
// This *should* be fine for the time being though, as the behavior
264+
// of `type_name` is only subject to change between compiler versions,
265+
// so the only place it might be able to cause issues is with dynamic plugins.
266+
std::any::type_name::<Self>()
267+
}
268+
}
269+
270+
ReadSystem::<E>(PhantomData)
271+
}
272+
}
273+
274+
/// [Label](SystemLabel) for a [`System`](crate::system::System) that can write events of type `E`.
275+
/// This is automatically applied to any system that contains an [`EventWriter`].
276+
///
277+
/// # Examples
278+
/// ```
279+
/// # use bevy_ecs::{prelude::*, event::Events};
280+
/// use bevy_ecs::system::Writes;
281+
///
282+
/// // New event type.
283+
/// struct MyEvent;
284+
///
285+
/// // Declare a system that writes to it.
286+
/// fn writer_system(mut event_writer: EventWriter<MyEvent>) {
287+
/// // ...
288+
/// # unimplemented!()
289+
/// }
290+
///
291+
/// // The system has automatically been given the label `Writes::to::<MyEvent>()`.
292+
/// let system = IntoSystem::into_system(writer_system);
293+
/// assert!(system.default_labels().contains(&Writes::to::<MyEvent>().as_label()));
294+
/// # assert!(system.default_labels().contains(&Writes::to::<Events<MyEvent>>().as_label()));
295+
/// ```
296+
pub struct Writes(());
297+
298+
impl Writes {
299+
/// Returns a [`SystemLabel`] for a system that might modify the resource `E`.
300+
pub fn to<E: Resource>() -> impl SystemLabel {
301+
struct WriteSystem<E>(PhantomData<E>);
302+
303+
impl<E: 'static> SystemLabel for WriteSystem<E> {
304+
fn as_str(&self) -> &'static str {
305+
std::any::type_name::<E>()
306+
}
307+
}
308+
309+
WriteSystem::<E>(PhantomData)
310+
}
311+
}
312+
230313
/// Shared borrow of a resource.
231314
///
232315
/// See the [`World`] documentation to see the usage of a resource.
@@ -309,6 +392,10 @@ pub struct ResState<T> {
309392

310393
impl<'a, T: Resource> SystemParam for Res<'a, T> {
311394
type Fetch = ResState<T>;
395+
#[inline]
396+
fn auto_labels() -> Vec<crate::schedule::SystemLabelId> {
397+
vec![Reads::from::<T>().as_label()]
398+
}
312399
}
313400

314401
// SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res
@@ -417,6 +504,10 @@ pub struct ResMutState<T> {
417504

418505
impl<'a, T: Resource> SystemParam for ResMut<'a, T> {
419506
type Fetch = ResMutState<T>;
507+
#[inline]
508+
fn auto_labels() -> Vec<crate::schedule::SystemLabelId> {
509+
vec![Writes::to::<T>().as_label()]
510+
}
420511
}
421512

422513
// SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res

0 commit comments

Comments
 (0)