geng_ecs/
world.rs

1use super::*;
2
3pub struct World {
4    pub(crate) components: HashMap<TypeId, storage::World>,
5    ids: HashSet<Id>,
6    next_id: u32,
7}
8
9impl Default for World {
10    fn default() -> Self {
11        Self::new()
12    }
13}
14
15impl World {
16    pub fn new() -> Self {
17        Self {
18            components: HashMap::new(),
19            ids: HashSet::new(),
20            next_id: 0,
21        }
22    }
23    pub fn spawn(&mut self, entity: Entity) {
24        let id = Id(self.next_id);
25        self.next_id += 1;
26        for (type_id, value) in entity.components {
27            self.components
28                .entry(type_id)
29                .or_insert_with(storage::World::new)
30                .insert_any(id, value.into_inner_any());
31        }
32        self.ids.insert(id);
33    }
34    pub fn query<Q: Query>(&self) -> WorldQuery<Q> {
35        self.filter(()).query()
36    }
37    pub fn filter<F: Filter>(&self, filter: F) -> FilteredWorld<F> {
38        FilteredWorld {
39            world: self,
40            filter,
41        }
42    }
43    pub fn remove<F: Filter>(&mut self, filter: F) -> WorldRemove<F> {
44        let filter = filter.fetch();
45        let iter = self.ids.clone().into_iter();
46        WorldRemove {
47            world: self,
48            filter,
49            id_iter: iter,
50        }
51    }
52    pub unsafe fn borrow<T: Component>(&self) -> Option<storage::world::Borrow<T>> {
53        self.components
54            .get(&TypeId::of::<T>())
55            .map(|storage| storage.borrow())
56    }
57    pub unsafe fn borrow_mut<T: Component>(&self) -> Option<storage::world::BorrowMut<T>> {
58        self.components
59            .get(&TypeId::of::<T>())
60            .map(|storage| storage.borrow_mut())
61    }
62}
63
64pub struct FilteredWorld<'a, T> {
65    world: &'a World,
66    filter: T,
67}
68
69impl<'a, F: Filter> FilteredWorld<'a, F> {
70    pub fn query<Q: Query>(self) -> WorldQuery<'a, Q, F> {
71        unsafe fn borrow<'a, Q: Query, F: Filter>(
72            query: &Q::Fetch,
73            filter: &F::Fetch,
74            world: &'a World,
75        ) -> Option<Borrows<'a, Q, F>> {
76            Some((query.borrow_world(world)?, filter.borrow_world(world)?))
77        }
78        unsafe {
79            let query = Q::Fetch::default();
80            let filter = self.filter.fetch();
81            WorldQuery {
82                borrows: borrow::<Q, F>(&query, &filter, self.world),
83                query,
84                filter,
85                world: self.world,
86            }
87        }
88    }
89    pub fn filter<F2: Filter>(self, filter: F2) -> FilteredWorld<'a, (F, F2)> {
90        FilteredWorld {
91            world: self.world,
92            filter: (self.filter, filter),
93        }
94    }
95}
96
97type Borrows<'a, Q, F> = (
98    <<Q as Query>::Fetch as Fetch<'a>>::WorldBorrows,
99    <<F as Filter>::Fetch as Fetch<'a>>::WorldBorrows,
100);
101
102pub struct WorldQuery<'a, Q: Query, F: Filter = ()> {
103    #[allow(dead_code)]
104    borrows: Option<Borrows<'a, Q, F>>, // This is here for the Drop impl
105    query: Q::Fetch,
106    filter: F::Fetch,
107    world: &'a World,
108}
109
110impl<'a, Q: Query, F: Filter> WorldQuery<'a, Q, F> {
111    pub fn iter<'q>(&'q mut self) -> WorldQueryIter<'q, Q, F> {
112        WorldQueryIter::<'q, Q, F> {
113            borrows: unsafe { std::mem::transmute(self.borrows.as_ref()) }, // TODO: WTF
114            query: &self.query,
115            filter: &self.filter,
116            id_iter: self.world.ids.iter(),
117        }
118    }
119}
120
121pub struct WorldQueryIter<'a, Q: Query, F: Filter> {
122    borrows: Option<&'a Borrows<'a, Q, F>>,
123    query: &'a Q::Fetch,
124    filter: &'a F::Fetch,
125    id_iter: std::collections::hash_set::Iter<'a, Id>,
126}
127
128impl<'a, Q: Query, F: Filter> Iterator for WorldQueryIter<'a, Q, F> {
129    type Item = QueryOutput<'a, Q>;
130    fn next(&mut self) -> Option<Self::Item> {
131        unsafe {
132            for &id in &mut self.id_iter {
133                let (querry_borrows, filter_borrows) = self.borrows?;
134                if !F::get_world(self.filter, filter_borrows, id) {
135                    continue;
136                }
137                if let Some(item) = self.query.get_world(querry_borrows, id) {
138                    return Some(item);
139                }
140            }
141            None
142        }
143    }
144}
145
146pub struct WorldRemove<'a, F: Filter> {
147    world: &'a mut World,
148    filter: F::Fetch,
149    id_iter: std::collections::hash_set::IntoIter<Id>,
150}
151
152impl<'a, F: Filter> Iterator for WorldRemove<'a, F> {
153    type Item = Entity;
154    fn next(&mut self) -> Option<Entity> {
155        for id in &mut self.id_iter {
156            unsafe {
157                if let Some(filter_borrows) = self.filter.borrow_world(self.world) {
158                    if !F::get_world(&self.filter, &filter_borrows, id) {
159                        continue;
160                    }
161                }
162            }
163            let mut entity = Entity::new();
164            for (&type_id, storage) in &mut self.world.components {
165                if let Some(value) = storage.remove_any(id) {
166                    entity
167                        .components
168                        .insert(type_id, storage::Entity::new_any(value));
169                }
170            }
171            self.world.ids.remove(&id);
172            return Some(entity);
173        }
174        None
175    }
176}