1use crate::prelude::*;
4
5#[derive(Clone)]
13pub struct World {
14 pub resources: Resources,
16 pub components: ComponentStores,
18}
19impl std::fmt::Debug for World {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 f.debug_struct("World").finish()
22 }
23}
24
25impl Default for World {
26 fn default() -> Self {
27 let resources = Resources::new();
28
29 resources.insert(Entities::default());
31
32 Self {
33 resources,
34 components: Default::default(),
35 }
36 }
37}
38
39impl World {
40 pub fn new() -> Self {
42 Self::default()
43 }
44
45 pub fn with_entities(entities: AtomicResource<Entities>) -> Self {
49 let resources = Resources::new();
50 resources
51 .untyped()
52 .insert_cell(entities.into_untyped())
53 .unwrap();
54 World {
55 resources,
56 components: default(),
57 }
58 }
59
60 pub fn maintain(&self) {
67 let mut entities = self.resource_mut::<Entities>();
68 for components in self.components.components.read_only_view().values() {
69 let mut components = components.borrow_mut();
70 let killed = entities.killed();
71 for &entity in killed {
72 unsafe {
75 components.remove_raw(entity, None);
76 }
77 }
78 }
79 entities.clear_killed();
80 }
81
82 pub fn run_system<'system, R, In, Out, S>(&self, system: S, input: In) -> Out
86 where
87 In: 'system,
88 Out: 'system,
89 S: IntoSystem<R, In, Out>,
90 S::Sys: 'system,
91 {
92 let mut s = system.system();
93 s.run(self, input)
94 }
95
96 pub fn entity_components<Q: QueryItem>(
102 &self,
103 entity: Entity,
104 query: Q,
105 ) -> <Q::Iter as Iterator>::Item {
106 self.get_entity_components(entity, query).unwrap()
107 }
108
109 pub fn get_entity_components<Q: QueryItem>(
111 &self,
112 entity: Entity,
113 query: Q,
114 ) -> Option<<Q::Iter as Iterator>::Item> {
115 let mut bitset = BitSetVec::default();
116 if self.resource::<Entities>().bitset().contains(entity) {
117 bitset.set(entity);
118 }
119 query.apply_bitset(&mut bitset);
120 match query.get_single_with_bitset(bitset.into()) {
121 Ok(components) => Some(components),
122 Err(QuerySingleError::NoEntities) => None,
123 Err(QuerySingleError::MultipleEntities) => {
124 panic!(
125 "Query returned a MultipleEntities error for a bitset that \
126 contains at most one enabled bit"
127 )
128 }
129 }
130 }
131
132 pub fn init_resource<R: HasSchema + FromWorld>(&self) -> RefMut<'_, R> {
134 if unlikely(!self.resources.contains::<R>()) {
135 let value = R::from_world(self);
136 self.resources.insert(value);
137 }
138 self.resource_mut()
139 }
140
141 pub fn insert_resource<R: HasSchema>(&self, resource: R) -> Option<R> {
143 self.resources.insert(resource)
144 }
145
146 #[track_caller]
150 pub fn resource<T: HasSchema>(&self) -> Ref<'_, T> {
151 match self.resources.get::<T>() {
152 Some(r) => r,
153 None => panic!(
154 "Requested resource {} does not exist in the `World`. \
155 Did you forget to add it using `world.insert_resource` / `world.init_resource`?",
156 std::any::type_name::<T>()
157 ),
158 }
159 }
160
161 #[track_caller]
165 pub fn resource_mut<T: HasSchema>(&self) -> RefMut<'_, T> {
166 match self.resources.get_mut::<T>() {
167 Some(r) => r,
168 None => panic!(
169 "Requested resource {} does not exist in the `World`. \
170 Did you forget to add it using `world.insert_resource` / `world.init_resource`?",
171 std::any::type_name::<T>()
172 ),
173 }
174 }
175
176 pub fn get_resource<T: HasSchema>(&self) -> Option<Ref<'_, T>> {
178 self.resources.get()
179 }
180
181 pub fn get_resource_mut<T: HasSchema>(&self) -> Option<RefMut<'_, T>> {
183 self.resources.get_mut()
184 }
185
186 pub fn clear_owned_resources(&self) {
188 self.resources.clear_owned_resources();
189 }
190
191 pub fn retain_resources<F>(&self, predicate: F)
195 where
196 F: FnMut(SchemaId) -> bool,
197 {
198 self.resources.untyped().retain_resources(predicate);
199 }
200
201 pub fn retain_owned_resources<F>(&self, predicate: F)
205 where
206 F: FnMut(SchemaId) -> bool,
207 {
208 self.resources.untyped().retain_owned_resources(predicate);
209 }
210
211 #[track_caller]
215 pub fn component<T: HasSchema>(&self) -> Ref<'_, ComponentStore<T>> {
216 self.components.get::<T>().borrow()
217 }
218
219 #[track_caller]
223 pub fn component_mut<T: HasSchema>(&self) -> RefMut<'_, ComponentStore<T>> {
224 self.components.get::<T>().borrow_mut()
225 }
226
227 pub fn load_snapshot(&mut self, snapshot: World) {
229 self.components = snapshot.components;
230 self.resources = snapshot.resources;
231 }
232}
233
234pub trait FromWorld {
239 fn from_world(world: &World) -> Self;
241}
242
243impl<T: Default> FromWorld for T {
244 fn from_world(_world: &World) -> Self {
245 T::default()
246 }
247}
248
249#[cfg(test)]
250mod tests {
251 use crate::prelude::*;
252
253 use super::FromWorld;
254
255 #[derive(Clone, Copy, HasSchema, Debug, Eq, PartialEq, Default)]
256 #[repr(C)]
257 struct C(u32);
258
259 #[derive(Clone, HasSchema, Debug, Eq, PartialEq, Default)]
260 #[repr(C)]
261 struct Pos(i32, i32);
262
263 #[derive(Clone, HasSchema, Debug, Eq, PartialEq, Default)]
264 #[repr(C)]
265 struct Vel(i32, i32);
266
267 #[derive(Clone, HasSchema, Debug, Eq, PartialEq, Default)]
268 struct Marker;
269
270 fn setup_world(
272 mut entities: ResMut<Entities>,
273 mut pos_comps: CompMut<Pos>,
274 mut vel_comps: CompMut<Vel>,
275 mut marker_comps: CompMut<Marker>,
276 ) {
277 let ent1 = entities.create();
278 pos_comps.insert(ent1, Pos(0, 100));
279 vel_comps.insert(ent1, Vel(0, -1));
280
281 let ent2 = entities.create();
282 pos_comps.insert(ent2, Pos(0, 0));
283 vel_comps.insert(ent2, Vel(1, 1));
284 marker_comps.insert(ent2, Marker);
285 }
286
287 fn pos_vel_system(entities: Res<Entities>, mut pos: CompMut<Pos>, vel: Comp<Vel>) {
289 for (_, (pos, vel)) in entities.iter_with((&mut pos, &vel)) {
290 pos.0 += vel.0;
291 pos.1 += vel.1;
292 }
293 }
294
295 fn test_after_setup_state(
297 entities: Res<Entities>,
298 pos: Comp<Pos>,
299 vel: Comp<Vel>,
300 marker: Comp<Marker>,
301 ) {
302 let mut i = 0;
303 for (entity, (pos, vel)) in entities.iter_with((&pos, &vel)) {
304 let marker = marker.get(entity);
305 match (i, pos, vel, marker) {
306 (0, Pos(0, 100), Vel(0, -1), None) | (1, Pos(0, 0), Vel(1, 1), Some(Marker)) => (),
307 x => unreachable!("{:?}", x),
308 }
309 i += 1;
310 }
311 assert_eq!(i, 2);
312 }
313
314 fn test_pos_vel_1_run(
317 entities: Res<Entities>,
318 pos: Comp<Pos>,
319 vel: Comp<Vel>,
320 marker: Comp<Marker>,
321 ) {
322 let mut i = 0;
323 for (entity, (pos, vel)) in entities.iter_with((&pos, &vel)) {
324 let marker = marker.get(entity);
325 match (i, pos, vel, marker) {
326 (0, Pos(0, 99), Vel(0, -1), None) | (1, Pos(1, 1), Vel(1, 1), Some(Marker)) => (),
327 x => unreachable!("{:?}", x),
328 }
329 i += 1;
330 }
331 assert_eq!(i, 2);
332 }
333
334 #[test]
335 fn sanity_check() {
336 let world = World::new();
337
338 world.run_system(setup_world, ());
339
340 let test = || {};
342 world.run_system(test, ());
343
344 world.run_system(pos_vel_system, ());
346
347 world.run_system(test_pos_vel_1_run, ());
349 }
350
351 #[test]
352 fn snapshot() {
353 let world1 = World::new();
354 world1.run_system(setup_world, ());
355
356 let snap = world1.clone();
358
359 snap.run_system(test_after_setup_state, ());
361
362 world1.run_system(pos_vel_system, ());
364
365 world1.run_system(test_pos_vel_1_run, ());
367
368 snap.run_system(test_after_setup_state, ());
370
371 snap.run_system(pos_vel_system, ());
373
374 world1.run_system(test_pos_vel_1_run, ());
376 }
377
378 #[test]
379 fn world_is_send() {
380 fn send<T: Send>(_: T) {}
381 send(World::new())
382 }
383
384 #[test]
385 fn get_entity_components() {
386 let w = World::default();
387
388 let (e1, e2) = {
389 let mut entities = w.resource_mut::<Entities>();
390 (entities.create(), entities.create())
391 };
392
393 let state = w.components.get::<C>();
394 let mut comp = state.borrow_mut();
395
396 let c2 = C(2);
397 comp.insert(e2, c2);
398
399 assert_eq!(w.get_entity_components(e1, &comp), None);
400 assert_eq!(w.get_entity_components(e2, &comp), Some(&c2));
401 }
402
403 #[derive(Clone, HasSchema, Default)]
408 struct TestResource(u32);
409
410 #[derive(Clone, HasSchema)]
411 #[schema(opaque, no_default)]
412 struct TestFromWorld(u32);
413 impl FromWorld for TestFromWorld {
414 fn from_world(world: &World) -> Self {
415 let b = world.resource::<TestResource>();
416 Self(b.0)
417 }
418 }
419
420 #[test]
421 fn init_resource_does_not_overwrite() {
422 let w = World::default();
423 w.insert_resource(TestResource(0));
424 w.init_resource::<TestFromWorld>();
425 w.insert_resource(TestResource(1));
426
427 let resource = w.resource::<TestFromWorld>();
428 assert_eq!(resource.0, 0);
429 }
430}