async_ecs/access/
read.rs

1use std::marker::PhantomData;
2use std::ops::Deref;
3
4use crate::{
5    resource::{Ref, Resource, ResourceId},
6    system::SystemData,
7    world::{DefaultSetupHandler, PanicHandler, SetupHandler, World},
8};
9
10/// Allows to fetch a resource in a system immutably.
11/// **This will panic if the resource does not exist.**
12/// Usage of `Read` or `Option<Read>` is therefore recommended.
13pub type ReadExpect<'a, T> = Read<'a, T, PanicHandler>;
14
15/// Allows to fetch a resource in a system immutably.
16///
17/// If the resource isn't strictly required, you should use `Option<Read<T>>`.
18///
19/// # Type parameters
20///
21/// * `T`: The type of the resource
22/// * `F`: The setup handler (default: `DefaultProvider`)
23pub struct Read<'a, T: 'a, F = DefaultSetupHandler> {
24    inner: Ref<'a, T>,
25    marker: PhantomData<F>,
26}
27
28impl<'a, T, F> Read<'a, T, F> {
29    pub fn new(inner: Ref<'a, T>) -> Self {
30        Self {
31            inner,
32            marker: PhantomData,
33        }
34    }
35}
36
37impl<'a, T, F> From<Ref<'a, T>> for Read<'a, T, F> {
38    fn from(inner: Ref<'a, T>) -> Self {
39        Read {
40            inner,
41            marker: PhantomData,
42        }
43    }
44}
45
46impl<'a, T, F> Deref for Read<'a, T, F>
47where
48    T: Resource,
49{
50    type Target = T;
51
52    fn deref(&self) -> &T {
53        &*self.inner
54    }
55}
56
57impl<'a, T, F> SystemData<'a> for Read<'a, T, F>
58where
59    T: Resource,
60    F: SetupHandler<T>,
61{
62    fn setup(world: &mut World) {
63        F::setup(world)
64    }
65
66    fn fetch(world: &'a World) -> Self {
67        Self::new(world.borrow())
68    }
69
70    fn reads() -> Vec<ResourceId> {
71        vec![ResourceId::new::<T>()]
72    }
73
74    fn writes() -> Vec<ResourceId> {
75        vec![]
76    }
77}
78
79impl<'a, T, F> SystemData<'a> for Option<Read<'a, T, F>>
80where
81    T: Resource,
82{
83    fn setup(_: &mut World) {}
84
85    fn fetch(world: &'a World) -> Self {
86        world.try_borrow().map(Into::into)
87    }
88
89    fn reads() -> Vec<ResourceId> {
90        vec![ResourceId::new::<T>()]
91    }
92
93    fn writes() -> Vec<ResourceId> {
94        vec![]
95    }
96}