@@ -8,7 +8,7 @@ use crate::{
8
8
query:: {
9
9
Access , FilteredAccess , FilteredAccessSet , QueryState , ReadOnlyWorldQuery , WorldQuery ,
10
10
} ,
11
- schedule:: SystemLabelId ,
11
+ schedule:: { SystemLabel , SystemLabelId } ,
12
12
system:: { CommandQueue , Commands , Query , SystemMeta } ,
13
13
world:: { FromWorld , World } ,
14
14
} ;
@@ -227,6 +227,89 @@ pub trait Resource: Send + Sync + 'static {}
227
227
228
228
impl < T > Resource for T where T : Send + Sync + ' static { }
229
229
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
+
230
313
/// Shared borrow of a resource.
231
314
///
232
315
/// See the [`World`] documentation to see the usage of a resource.
@@ -309,6 +392,10 @@ pub struct ResState<T> {
309
392
310
393
impl < ' a , T : Resource > SystemParam for Res < ' a , T > {
311
394
type Fetch = ResState < T > ;
395
+ #[ inline]
396
+ fn auto_labels ( ) -> Vec < crate :: schedule:: SystemLabelId > {
397
+ vec ! [ Reads :: from:: <T >( ) . as_label( ) ]
398
+ }
312
399
}
313
400
314
401
// SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res
@@ -417,6 +504,10 @@ pub struct ResMutState<T> {
417
504
418
505
impl < ' a , T : Resource > SystemParam for ResMut < ' a , T > {
419
506
type Fetch = ResMutState < T > ;
507
+ #[ inline]
508
+ fn auto_labels ( ) -> Vec < crate :: schedule:: SystemLabelId > {
509
+ vec ! [ Writes :: to:: <T >( ) . as_label( ) ]
510
+ }
420
511
}
421
512
422
513
// SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res
0 commit comments