xuko_ecs/
resource.rs

1use crate::{ComponentId, component_id};
2use std::any::Any;
3
4/// A type that can attached to a [`crate::World`].
5///
6/// Only one resource can exist at a time, making it a singleton.
7pub trait Resource
8where
9    Self: Send + Sync + 'static,
10{
11}
12impl<T: Send + Sync + 'static> Resource for T {}
13
14/// Map of resources in a [`crate::World`]
15#[derive(Default)]
16pub struct ResourceMap(indexmap::IndexMap<ComponentId, Box<dyn Any + Send + Sync + 'static>>);
17
18impl ResourceMap {
19    /// Create a new [`ResourceMap`]
20    pub fn new() -> Self {
21        Self(Default::default())
22    }
23
24    /// Add a [`Resource`] to the [`ResourceMap`]
25    pub fn add<R: Resource>(&mut self, res: R) {
26        let key = component_id!(R);
27
28        if self.0.contains_key(&key) {
29            return;
30        }
31
32        self.0.insert(key, Box::new(res));
33    }
34
35    /// Get a reference to a [`Resource`] from the [`ResourceMap`]
36    pub fn get<R: Resource>(&self) -> Option<&R> {
37        self.0
38            .get(&component_id!(R))
39            .map(|r| r.downcast_ref::<R>().unwrap())
40    }
41
42    /// Get a mutable reference to a [`Resource`] from the [`ResourceMap`]
43    pub fn get_mut<R: Resource>(&mut self) -> Option<&mut R> {
44        self.0
45            .get_mut(&component_id!(R))
46            .map(|r| r.downcast_mut::<R>().unwrap())
47    }
48}