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>>, 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()) }, 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}