bevy_ecs/resource.rs
1//! Resources are unique, singleton-like data types that can be accessed from systems and stored in the [`World`](crate::world::World).
2
3// The derive macro for the `Resource` trait
4pub use bevy_ecs_macros::Resource;
5
6/// A type that can be inserted into a [`World`] as a singleton.
7///
8/// You can access resource data in systems using the [`Res`] and [`ResMut`] system parameters
9///
10/// Only one resource of each type can be stored in a [`World`] at any given time.
11///
12/// # Examples
13///
14/// ```
15/// # let mut world = World::default();
16/// # let mut schedule = Schedule::default();
17/// # use bevy_ecs::prelude::*;
18/// #[derive(Resource)]
19/// struct MyResource { value: u32 }
20///
21/// world.insert_resource(MyResource { value: 42 });
22///
23/// fn read_resource_system(resource: Res<MyResource>) {
24/// assert_eq!(resource.value, 42);
25/// }
26///
27/// fn write_resource_system(mut resource: ResMut<MyResource>) {
28/// assert_eq!(resource.value, 42);
29/// resource.value = 0;
30/// assert_eq!(resource.value, 0);
31/// }
32/// # schedule.add_systems((read_resource_system, write_resource_system).chain());
33/// # schedule.run(&mut world);
34/// ```
35///
36/// # `!Sync` Resources
37/// A `!Sync` type cannot implement `Resource`. However, it is possible to wrap a `Send` but not `Sync`
38/// type in [`SyncCell`] or the currently unstable [`Exclusive`] to make it `Sync`. This forces only
39/// having mutable access (`&mut T` only, never `&T`), but makes it safe to reference across multiple
40/// threads.
41///
42/// This will fail to compile since `RefCell` is `!Sync`.
43/// ```compile_fail
44/// # use std::cell::RefCell;
45/// # use bevy_ecs::resource::Resource;
46///
47/// #[derive(Resource)]
48/// struct NotSync {
49/// counter: RefCell<usize>,
50/// }
51/// ```
52///
53/// This will compile since the `RefCell` is wrapped with `SyncCell`.
54/// ```
55/// # use std::cell::RefCell;
56/// # use bevy_ecs::resource::Resource;
57/// use bevy_utils::synccell::SyncCell;
58///
59/// #[derive(Resource)]
60/// struct ActuallySync {
61/// counter: SyncCell<RefCell<usize>>,
62/// }
63/// ```
64///
65/// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
66/// [`World`]: crate::world::World
67/// [`Res`]: crate::system::Res
68/// [`ResMut`]: crate::system::ResMut
69/// [`SyncCell`]: bevy_utils::synccell::SyncCell
70#[diagnostic::on_unimplemented(
71 message = "`{Self}` is not a `Resource`",
72 label = "invalid `Resource`",
73 note = "consider annotating `{Self}` with `#[derive(Resource)]`"
74)]
75pub trait Resource: Send + Sync + 'static {}