geng_ecs/
entity.rs

1use super::*;
2
3pub struct Entity {
4    pub(crate) components: HashMap<TypeId, storage::Entity>,
5}
6
7impl Default for Entity {
8    fn default() -> Self {
9        Self::new()
10    }
11}
12
13impl Entity {
14    pub fn new() -> Self {
15        Self {
16            components: HashMap::new(),
17        }
18    }
19    pub fn add<T: Component>(&mut self, component: T) {
20        self.components
21            .insert(TypeId::of::<T>(), storage::Entity::new(component));
22    }
23    pub fn has<T: Component>(&self) -> bool {
24        self.components.contains_key(&TypeId::of::<T>())
25    }
26    pub fn remove<T: Component>(&mut self) -> Option<T> {
27        unsafe {
28            self.components
29                .remove(&TypeId::of::<T>())
30                .map(|storage| storage.into_inner())
31        }
32    }
33    pub fn query<Q: Query>(&self) -> EntityQuery<Q> {
34        self.filter(()).query()
35    }
36    pub fn filter<F: Filter>(&self, filter: F) -> FilteredEntity<F> {
37        FilteredEntity {
38            entity: self,
39            filter,
40        }
41    }
42    pub fn is<F: Filter>(&mut self, filter: F) -> bool {
43        self.filter(filter).query::<()>().is_some()
44    }
45    pub unsafe fn borrow<T: Component>(&self) -> Option<storage::entity::Borrow<T>> {
46        self.components
47            .get(&TypeId::of::<T>())
48            .map(|storage| storage.borrow())
49    }
50    pub unsafe fn borrow_mut<T: Component>(&self) -> Option<storage::entity::BorrowMut<T>> {
51        self.components
52            .get(&TypeId::of::<T>())
53            .map(|storage| storage.borrow_mut())
54    }
55}
56
57pub struct FilteredEntity<'a, T> {
58    entity: &'a Entity,
59    filter: T,
60}
61
62impl<'a, F: Filter> FilteredEntity<'a, F> {
63    pub fn query<Q: Query>(self) -> EntityQuery<'a, Q> {
64        unsafe {
65            let query = Q::Fetch::default();
66            let filter = self.filter.fetch();
67            let filtered = {
68                if let Some(borrows) = filter.borrow_direct(self.entity) {
69                    F::get(&filter, &borrows)
70                } else {
71                    false
72                }
73            };
74            if filtered {
75                let borrows = query.borrow_direct(self.entity);
76                let item = borrows.as_ref().map(|borrows| query.get(borrows));
77                EntityQuery { borrows, item }
78            } else {
79                EntityQuery {
80                    borrows: None,
81                    item: None,
82                }
83            }
84        }
85    }
86}
87
88pub struct EntityQuery<'a, Q: Query> {
89    #[allow(dead_code)]
90    borrows: Option<<Q::Fetch as Fetch<'a>>::DirectBorrows>, // This is here for the Drop impl
91    item: Option<QueryOutput<'a, Q>>,
92}
93
94impl<'a, Q: Query> Debug for EntityQuery<'a, Q>
95where
96    QueryOutput<'a, Q>: Debug,
97{
98    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99        write!(f, "{:?}", self.item)
100    }
101}
102
103impl<'a, Q: Query> Deref for EntityQuery<'a, Q> {
104    type Target = Option<QueryOutput<'a, Q>>;
105    fn deref(&self) -> &Self::Target {
106        &self.item
107    }
108}
109
110impl<'a, Q: Query> DerefMut for EntityQuery<'a, Q> {
111    fn deref_mut(&mut self) -> &mut Self::Target {
112        &mut self.item
113    }
114}