 04a37f722a
			
		
	
	
		04a37f722a
		
	
	
	
	
		
			
			Fixes #1809. It makes it also possible to use `derive` for `SystemParam` inside ECS and avoid manual implementation. An alternative solution to macro changes is to use `use crate as bevy_ecs;` in `event.rs`.
		
			
				
	
	
		
			1122 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			1122 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| pub mod archetype;
 | |
| pub mod bundle;
 | |
| pub mod component;
 | |
| pub mod entity;
 | |
| pub mod event;
 | |
| pub mod query;
 | |
| #[cfg(feature = "bevy_reflect")]
 | |
| pub mod reflect;
 | |
| pub mod schedule;
 | |
| pub mod storage;
 | |
| pub mod system;
 | |
| pub mod world;
 | |
| 
 | |
| pub mod prelude {
 | |
|     #[cfg(feature = "bevy_reflect")]
 | |
|     pub use crate::reflect::ReflectComponent;
 | |
|     pub use crate::{
 | |
|         bundle::Bundle,
 | |
|         entity::Entity,
 | |
|         event::{EventReader, EventWriter},
 | |
|         query::{Added, ChangeTrackers, Changed, Or, QueryState, With, WithBundle, Without},
 | |
|         schedule::{
 | |
|             AmbiguitySetLabel, ExclusiveSystemDescriptorCoercion, ParallelSystemDescriptorCoercion,
 | |
|             RunCriteria, RunCriteriaDescriptorCoercion, RunCriteriaLabel, RunCriteriaPiping,
 | |
|             Schedule, Stage, StageLabel, State, SystemLabel, SystemSet, SystemStage,
 | |
|         },
 | |
|         system::{
 | |
|             Commands, In, IntoChainSystem, IntoExclusiveSystem, IntoSystem, Local, NonSend,
 | |
|             NonSendMut, Query, QuerySet, RemovedComponents, Res, ResMut, System,
 | |
|         },
 | |
|         world::{FromWorld, Mut, World},
 | |
|     };
 | |
| }
 | |
| 
 | |
| #[cfg(test)]
 | |
| mod tests {
 | |
|     use crate::{
 | |
|         bundle::Bundle,
 | |
|         component::{Component, ComponentDescriptor, StorageType, TypeInfo},
 | |
|         entity::Entity,
 | |
|         query::{Added, ChangeTrackers, Changed, FilterFetch, With, Without, WorldQuery},
 | |
|         world::{Mut, World},
 | |
|     };
 | |
|     use bevy_tasks::TaskPool;
 | |
|     use parking_lot::Mutex;
 | |
|     use std::{any::TypeId, sync::Arc};
 | |
| 
 | |
|     #[derive(Debug, PartialEq, Eq)]
 | |
|     struct A(usize);
 | |
|     struct B(usize);
 | |
|     struct C;
 | |
| 
 | |
|     #[test]
 | |
|     fn random_access() {
 | |
|         let mut world = World::new();
 | |
|         world
 | |
|             .register_component(ComponentDescriptor::new::<i32>(StorageType::SparseSet))
 | |
|             .unwrap();
 | |
|         let e = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let f = world.spawn().insert_bundle(("def", 456, true)).id();
 | |
|         assert_eq!(*world.get::<&str>(e).unwrap(), "abc");
 | |
|         assert_eq!(*world.get::<i32>(e).unwrap(), 123);
 | |
|         assert_eq!(*world.get::<&str>(f).unwrap(), "def");
 | |
|         assert_eq!(*world.get::<i32>(f).unwrap(), 456);
 | |
| 
 | |
|         // test archetype get_mut()
 | |
|         *world.get_mut::<&'static str>(e).unwrap() = "xyz";
 | |
|         assert_eq!(*world.get::<&'static str>(e).unwrap(), "xyz");
 | |
| 
 | |
|         // test sparse set get_mut()
 | |
|         *world.get_mut::<i32>(f).unwrap() = 42;
 | |
|         assert_eq!(*world.get::<i32>(f).unwrap(), 42);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn bundle_derive() {
 | |
|         use crate as bevy_ecs;
 | |
|         #[derive(Bundle, PartialEq, Debug)]
 | |
|         struct Foo {
 | |
|             x: &'static str,
 | |
|             y: i32,
 | |
|         }
 | |
| 
 | |
|         assert_eq!(
 | |
|             <Foo as Bundle>::type_info(),
 | |
|             vec![TypeInfo::of::<&'static str>(), TypeInfo::of::<i32>(),]
 | |
|         );
 | |
| 
 | |
|         let mut world = World::new();
 | |
|         world
 | |
|             .register_component(ComponentDescriptor::new::<i32>(StorageType::SparseSet))
 | |
|             .unwrap();
 | |
|         let e1 = world.spawn().insert_bundle(Foo { x: "abc", y: 123 }).id();
 | |
|         let e2 = world.spawn().insert_bundle(("def", 456, true)).id();
 | |
|         assert_eq!(*world.get::<&str>(e1).unwrap(), "abc");
 | |
|         assert_eq!(*world.get::<i32>(e1).unwrap(), 123);
 | |
|         assert_eq!(*world.get::<&str>(e2).unwrap(), "def");
 | |
|         assert_eq!(*world.get::<i32>(e2).unwrap(), 456);
 | |
| 
 | |
|         // test archetype get_mut()
 | |
|         *world.get_mut::<&'static str>(e1).unwrap() = "xyz";
 | |
|         assert_eq!(*world.get::<&'static str>(e1).unwrap(), "xyz");
 | |
| 
 | |
|         // test sparse set get_mut()
 | |
|         *world.get_mut::<i32>(e2).unwrap() = 42;
 | |
|         assert_eq!(*world.get::<i32>(e2).unwrap(), 42);
 | |
| 
 | |
|         assert_eq!(
 | |
|             world.entity_mut(e1).remove_bundle::<Foo>().unwrap(),
 | |
|             Foo { x: "xyz", y: 123 }
 | |
|         );
 | |
| 
 | |
|         #[derive(Bundle, PartialEq, Debug)]
 | |
|         struct Nested {
 | |
|             a: usize,
 | |
|             #[bundle]
 | |
|             foo: Foo,
 | |
|             b: u8,
 | |
|         }
 | |
| 
 | |
|         assert_eq!(
 | |
|             <Nested as Bundle>::type_info(),
 | |
|             vec![
 | |
|                 TypeInfo::of::<usize>(),
 | |
|                 TypeInfo::of::<&'static str>(),
 | |
|                 TypeInfo::of::<i32>(),
 | |
|                 TypeInfo::of::<u8>(),
 | |
|             ]
 | |
|         );
 | |
| 
 | |
|         let e3 = world
 | |
|             .spawn()
 | |
|             .insert_bundle(Nested {
 | |
|                 a: 1,
 | |
|                 foo: Foo { x: "ghi", y: 789 },
 | |
|                 b: 2,
 | |
|             })
 | |
|             .id();
 | |
| 
 | |
|         assert_eq!(*world.get::<&str>(e3).unwrap(), "ghi");
 | |
|         assert_eq!(*world.get::<i32>(e3).unwrap(), 789);
 | |
|         assert_eq!(*world.get::<usize>(e3).unwrap(), 1);
 | |
|         assert_eq!(*world.get::<u8>(e3).unwrap(), 2);
 | |
|         assert_eq!(
 | |
|             world.entity_mut(e3).remove_bundle::<Nested>().unwrap(),
 | |
|             Nested {
 | |
|                 a: 1,
 | |
|                 foo: Foo { x: "ghi", y: 789 },
 | |
|                 b: 2,
 | |
|             }
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn despawn_table_storage() {
 | |
|         let mut world = World::new();
 | |
|         let e = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let f = world.spawn().insert_bundle(("def", 456)).id();
 | |
|         assert_eq!(world.entities.len(), 2);
 | |
|         assert!(world.despawn(e));
 | |
|         assert_eq!(world.entities.len(), 1);
 | |
|         assert!(world.get::<&str>(e).is_none());
 | |
|         assert!(world.get::<i32>(e).is_none());
 | |
|         assert_eq!(*world.get::<&str>(f).unwrap(), "def");
 | |
|         assert_eq!(*world.get::<i32>(f).unwrap(), 456);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn despawn_mixed_storage() {
 | |
|         let mut world = World::new();
 | |
|         world
 | |
|             .register_component(ComponentDescriptor::new::<i32>(StorageType::SparseSet))
 | |
|             .unwrap();
 | |
|         let e = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let f = world.spawn().insert_bundle(("def", 456)).id();
 | |
|         assert_eq!(world.entities.len(), 2);
 | |
|         assert!(world.despawn(e));
 | |
|         assert_eq!(world.entities.len(), 1);
 | |
|         assert!(world.get::<&str>(e).is_none());
 | |
|         assert!(world.get::<i32>(e).is_none());
 | |
|         assert_eq!(*world.get::<&str>(f).unwrap(), "def");
 | |
|         assert_eq!(*world.get::<i32>(f).unwrap(), 456);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_all() {
 | |
|         let mut world = World::new();
 | |
|         let e = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let f = world.spawn().insert_bundle(("def", 456)).id();
 | |
| 
 | |
|         let ents = world
 | |
|             .query::<(Entity, &i32, &&str)>()
 | |
|             .iter(&world)
 | |
|             .map(|(e, &i, &s)| (e, i, s))
 | |
|             .collect::<Vec<_>>();
 | |
|         assert_eq!(ents, &[(e, 123, "abc"), (f, 456, "def")]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_all_for_each() {
 | |
|         let mut world = World::new();
 | |
|         let e = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let f = world.spawn().insert_bundle(("def", 456)).id();
 | |
| 
 | |
|         let mut results = Vec::new();
 | |
|         world
 | |
|             .query::<(Entity, &i32, &&str)>()
 | |
|             .for_each(&world, |(e, &i, &s)| results.push((e, i, s)));
 | |
|         assert_eq!(results, &[(e, 123, "abc"), (f, 456, "def")]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_single_component() {
 | |
|         let mut world = World::new();
 | |
|         let e = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let f = world.spawn().insert_bundle(("def", 456, true)).id();
 | |
|         let ents = world
 | |
|             .query::<(Entity, &i32)>()
 | |
|             .iter(&world)
 | |
|             .map(|(e, &i)| (e, i))
 | |
|             .collect::<Vec<_>>();
 | |
|         assert_eq!(ents, &[(e, 123), (f, 456)]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn stateful_query_handles_new_archetype() {
 | |
|         let mut world = World::new();
 | |
|         let e = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let mut query = world.query::<(Entity, &i32)>();
 | |
| 
 | |
|         let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>();
 | |
|         assert_eq!(ents, &[(e, 123)]);
 | |
| 
 | |
|         let f = world.spawn().insert_bundle(("def", 456, true)).id();
 | |
|         let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>();
 | |
|         assert_eq!(ents, &[(e, 123), (f, 456)]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_single_component_for_each() {
 | |
|         let mut world = World::new();
 | |
|         let e = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let f = world.spawn().insert_bundle(("def", 456, true)).id();
 | |
|         let mut results = Vec::new();
 | |
|         world
 | |
|             .query::<(Entity, &i32)>()
 | |
|             .for_each(&world, |(e, &i)| results.push((e, i)));
 | |
|         assert_eq!(results, &[(e, 123), (f, 456)]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn par_for_each() {
 | |
|         let mut world = World::new();
 | |
|         let task_pool = TaskPool::default();
 | |
|         let e1 = world.spawn().insert(1).id();
 | |
|         let e2 = world.spawn().insert(2).id();
 | |
|         let e3 = world.spawn().insert(3).id();
 | |
|         let e4 = world.spawn().insert_bundle((4, true)).id();
 | |
|         let e5 = world.spawn().insert_bundle((5, true)).id();
 | |
|         let results = Arc::new(Mutex::new(Vec::new()));
 | |
|         world
 | |
|             .query::<(Entity, &i32)>()
 | |
|             .par_for_each(&world, &task_pool, 2, |(e, &i)| results.lock().push((e, i)));
 | |
|         results.lock().sort();
 | |
|         assert_eq!(
 | |
|             &*results.lock(),
 | |
|             &[(e1, 1), (e2, 2), (e3, 3), (e4, 4), (e5, 5)]
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_missing_component() {
 | |
|         let mut world = World::new();
 | |
|         world.spawn().insert_bundle(("abc", 123));
 | |
|         world.spawn().insert_bundle(("def", 456));
 | |
|         assert!(world.query::<(&bool, &i32)>().iter(&world).next().is_none());
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_sparse_component() {
 | |
|         let mut world = World::new();
 | |
|         world.spawn().insert_bundle(("abc", 123));
 | |
|         let f = world.spawn().insert_bundle(("def", 456, true)).id();
 | |
|         let ents = world
 | |
|             .query::<(Entity, &bool)>()
 | |
|             .iter(&world)
 | |
|             .map(|(e, &b)| (e, b))
 | |
|             .collect::<Vec<_>>();
 | |
|         assert_eq!(ents, &[(f, true)]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_filter_with() {
 | |
|         let mut world = World::new();
 | |
|         world.spawn().insert_bundle((123u32, 1.0f32));
 | |
|         world.spawn().insert(456u32);
 | |
|         let result = world
 | |
|             .query_filtered::<&u32, With<f32>>()
 | |
|             .iter(&world)
 | |
|             .cloned()
 | |
|             .collect::<Vec<_>>();
 | |
|         assert_eq!(result, vec![123]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_filter_with_for_each() {
 | |
|         let mut world = World::new();
 | |
|         world.spawn().insert_bundle((123u32, 1.0f32));
 | |
|         world.spawn().insert(456u32);
 | |
| 
 | |
|         let mut results = Vec::new();
 | |
|         world
 | |
|             .query_filtered::<&u32, With<f32>>()
 | |
|             .for_each(&world, |i| results.push(*i));
 | |
|         assert_eq!(results, vec![123]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_filter_with_sparse() {
 | |
|         let mut world = World::new();
 | |
|         world
 | |
|             .register_component(ComponentDescriptor::new::<f32>(StorageType::SparseSet))
 | |
|             .unwrap();
 | |
|         world.spawn().insert_bundle((123u32, 1.0f32));
 | |
|         world.spawn().insert(456u32);
 | |
|         let result = world
 | |
|             .query_filtered::<&u32, With<f32>>()
 | |
|             .iter(&world)
 | |
|             .cloned()
 | |
|             .collect::<Vec<_>>();
 | |
|         assert_eq!(result, vec![123]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_filter_with_sparse_for_each() {
 | |
|         let mut world = World::new();
 | |
|         world
 | |
|             .register_component(ComponentDescriptor::new::<f32>(StorageType::SparseSet))
 | |
|             .unwrap();
 | |
|         world.spawn().insert_bundle((123u32, 1.0f32));
 | |
|         world.spawn().insert(456u32);
 | |
|         let mut results = Vec::new();
 | |
|         world
 | |
|             .query_filtered::<&u32, With<f32>>()
 | |
|             .for_each(&world, |i| results.push(*i));
 | |
|         assert_eq!(results, vec![123]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_filter_without() {
 | |
|         let mut world = World::new();
 | |
|         world.spawn().insert_bundle((123u32, 1.0f32));
 | |
|         world.spawn().insert(456u32);
 | |
|         let result = world
 | |
|             .query_filtered::<&u32, Without<f32>>()
 | |
|             .iter(&world)
 | |
|             .cloned()
 | |
|             .collect::<Vec<_>>();
 | |
|         assert_eq!(result, vec![456]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_optional_component_table() {
 | |
|         let mut world = World::new();
 | |
|         let e = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let f = world.spawn().insert_bundle(("def", 456, true)).id();
 | |
|         // this should be skipped
 | |
|         world.spawn().insert("abc");
 | |
|         let ents = world
 | |
|             .query::<(Entity, Option<&bool>, &i32)>()
 | |
|             .iter(&world)
 | |
|             .map(|(e, b, &i)| (e, b.copied(), i))
 | |
|             .collect::<Vec<_>>();
 | |
|         assert_eq!(ents, &[(e, None, 123), (f, Some(true), 456)]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_optional_component_sparse() {
 | |
|         let mut world = World::new();
 | |
|         world
 | |
|             .register_component(ComponentDescriptor::new::<bool>(StorageType::SparseSet))
 | |
|             .unwrap();
 | |
|         let e = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let f = world.spawn().insert_bundle(("def", 456, true)).id();
 | |
|         // // this should be skipped
 | |
|         // world.spawn().insert("abc");
 | |
|         let ents = world
 | |
|             .query::<(Entity, Option<&bool>, &i32)>()
 | |
|             .iter(&world)
 | |
|             .map(|(e, b, &i)| (e, b.copied(), i))
 | |
|             .collect::<Vec<_>>();
 | |
|         assert_eq!(ents, &[(e, None, 123), (f, Some(true), 456)]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_optional_component_sparse_no_match() {
 | |
|         let mut world = World::new();
 | |
|         world
 | |
|             .register_component(ComponentDescriptor::new::<bool>(StorageType::SparseSet))
 | |
|             .unwrap();
 | |
|         let e = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let f = world.spawn().insert_bundle(("def", 456)).id();
 | |
|         // // this should be skipped
 | |
|         world.spawn().insert("abc");
 | |
|         let ents = world
 | |
|             .query::<(Entity, Option<&bool>, &i32)>()
 | |
|             .iter(&world)
 | |
|             .map(|(e, b, &i)| (e, b.copied(), i))
 | |
|             .collect::<Vec<_>>();
 | |
|         assert_eq!(ents, &[(e, None, 123), (f, None, 456)]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn add_remove_components() {
 | |
|         let mut world = World::new();
 | |
|         let e1 = world.spawn().insert(42).insert_bundle((true, "abc")).id();
 | |
|         let e2 = world.spawn().insert(0).insert_bundle((false, "xyz")).id();
 | |
| 
 | |
|         assert_eq!(
 | |
|             world
 | |
|                 .query::<(Entity, &i32, &bool)>()
 | |
|                 .iter(&world)
 | |
|                 .map(|(e, &i, &b)| (e, i, b))
 | |
|                 .collect::<Vec<_>>(),
 | |
|             &[(e1, 42, true), (e2, 0, false)]
 | |
|         );
 | |
| 
 | |
|         assert_eq!(world.entity_mut(e1).remove::<i32>(), Some(42));
 | |
|         assert_eq!(
 | |
|             world
 | |
|                 .query::<(Entity, &i32, &bool)>()
 | |
|                 .iter(&world)
 | |
|                 .map(|(e, &i, &b)| (e, i, b))
 | |
|                 .collect::<Vec<_>>(),
 | |
|             &[(e2, 0, false)]
 | |
|         );
 | |
|         assert_eq!(
 | |
|             world
 | |
|                 .query::<(Entity, &bool, &&str)>()
 | |
|                 .iter(&world)
 | |
|                 .map(|(e, &b, &s)| (e, b, s))
 | |
|                 .collect::<Vec<_>>(),
 | |
|             &[(e2, false, "xyz"), (e1, true, "abc")]
 | |
|         );
 | |
|         world.entity_mut(e1).insert(43);
 | |
|         assert_eq!(
 | |
|             world
 | |
|                 .query::<(Entity, &i32, &bool)>()
 | |
|                 .iter(&world)
 | |
|                 .map(|(e, &i, &b)| (e, i, b))
 | |
|                 .collect::<Vec<_>>(),
 | |
|             &[(e2, 0, false), (e1, 43, true)]
 | |
|         );
 | |
|         world.entity_mut(e1).insert(1.0f32);
 | |
|         assert_eq!(
 | |
|             world
 | |
|                 .query::<(Entity, &f32)>()
 | |
|                 .iter(&world)
 | |
|                 .map(|(e, &f)| (e, f))
 | |
|                 .collect::<Vec<_>>(),
 | |
|             &[(e1, 1.0)]
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn table_add_remove_many() {
 | |
|         let mut world = World::default();
 | |
|         let mut entities = Vec::with_capacity(10_000);
 | |
|         for _ in 0..1000 {
 | |
|             entities.push(world.spawn().insert(0.0f32).id());
 | |
|         }
 | |
| 
 | |
|         for (i, entity) in entities.iter().cloned().enumerate() {
 | |
|             world.entity_mut(entity).insert(i);
 | |
|         }
 | |
| 
 | |
|         for (i, entity) in entities.iter().cloned().enumerate() {
 | |
|             assert_eq!(world.entity_mut(entity).remove::<usize>(), Some(i));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn sparse_set_add_remove_many() {
 | |
|         let mut world = World::default();
 | |
|         world
 | |
|             .register_component(ComponentDescriptor::new::<usize>(StorageType::SparseSet))
 | |
|             .unwrap();
 | |
|         let mut entities = Vec::with_capacity(1000);
 | |
|         for _ in 0..4 {
 | |
|             entities.push(world.spawn().insert(0.0f32).id());
 | |
|         }
 | |
| 
 | |
|         for (i, entity) in entities.iter().cloned().enumerate() {
 | |
|             world.entity_mut(entity).insert(i);
 | |
|         }
 | |
| 
 | |
|         for (i, entity) in entities.iter().cloned().enumerate() {
 | |
|             assert_eq!(world.entity_mut(entity).remove::<usize>(), Some(i));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn remove_missing() {
 | |
|         let mut world = World::new();
 | |
|         let e = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         assert!(world.entity_mut(e).remove::<bool>().is_none());
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn spawn_batch() {
 | |
|         let mut world = World::new();
 | |
|         world.spawn_batch((0..100).map(|x| (x, "abc")));
 | |
|         let values = world
 | |
|             .query::<&i32>()
 | |
|             .iter(&world)
 | |
|             .copied()
 | |
|             .collect::<Vec<_>>();
 | |
|         let expected = (0..100).collect::<Vec<_>>();
 | |
|         assert_eq!(values, expected);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn query_get() {
 | |
|         let mut world = World::new();
 | |
|         let a = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let b = world.spawn().insert_bundle(("def", 456)).id();
 | |
|         let c = world.spawn().insert_bundle(("ghi", 789, true)).id();
 | |
| 
 | |
|         let mut i32_query = world.query::<&i32>();
 | |
|         assert_eq!(i32_query.get(&world, a).unwrap(), &123);
 | |
|         assert_eq!(i32_query.get(&world, b).unwrap(), &456);
 | |
| 
 | |
|         let mut i32_bool_query = world.query::<(&i32, &bool)>();
 | |
|         assert!(i32_bool_query.get(&world, a).is_err());
 | |
|         assert_eq!(i32_bool_query.get(&world, c).unwrap(), (&789, &true));
 | |
|         assert!(world.despawn(a));
 | |
|         assert!(i32_query.get(&world, a).is_err());
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn remove_tracking() {
 | |
|         let mut world = World::new();
 | |
|         world
 | |
|             .register_component(ComponentDescriptor::new::<&'static str>(
 | |
|                 StorageType::SparseSet,
 | |
|             ))
 | |
|             .unwrap();
 | |
|         let a = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         let b = world.spawn().insert_bundle(("abc", 123)).id();
 | |
| 
 | |
|         world.entity_mut(a).despawn();
 | |
|         assert_eq!(
 | |
|             world.removed::<i32>().collect::<Vec<_>>(),
 | |
|             &[a],
 | |
|             "despawning results in 'removed component' state for table components"
 | |
|         );
 | |
|         assert_eq!(
 | |
|             world.removed::<&'static str>().collect::<Vec<_>>(),
 | |
|             &[a],
 | |
|             "despawning results in 'removed component' state for sparse set components"
 | |
|         );
 | |
| 
 | |
|         world.entity_mut(b).insert(10.0);
 | |
|         assert_eq!(
 | |
|             world.removed::<i32>().collect::<Vec<_>>(),
 | |
|             &[a],
 | |
|             "archetype moves does not result in 'removed component' state"
 | |
|         );
 | |
| 
 | |
|         world.entity_mut(b).remove::<i32>();
 | |
|         assert_eq!(
 | |
|             world.removed::<i32>().collect::<Vec<_>>(),
 | |
|             &[a, b],
 | |
|             "removing a component results in a 'removed component' state"
 | |
|         );
 | |
| 
 | |
|         world.clear_trackers();
 | |
|         assert_eq!(
 | |
|             world.removed::<i32>().collect::<Vec<_>>(),
 | |
|             &[],
 | |
|             "clearning trackers clears removals"
 | |
|         );
 | |
|         assert_eq!(
 | |
|             world.removed::<&'static str>().collect::<Vec<_>>(),
 | |
|             &[],
 | |
|             "clearning trackers clears removals"
 | |
|         );
 | |
|         assert_eq!(
 | |
|             world.removed::<f64>().collect::<Vec<_>>(),
 | |
|             &[],
 | |
|             "clearning trackers clears removals"
 | |
|         );
 | |
| 
 | |
|         // TODO: uncomment when world.clear() is implemented
 | |
|         // let c = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         // let d = world.spawn().insert_bundle(("abc", 123)).id();
 | |
|         // world.clear();
 | |
|         // assert_eq!(
 | |
|         //     world.removed::<i32>(),
 | |
|         //     &[c, d],
 | |
|         //     "world clears result in 'removed component' states"
 | |
|         // );
 | |
|         // assert_eq!(
 | |
|         //     world.removed::<&'static str>(),
 | |
|         //     &[c, d, b],
 | |
|         //     "world clears result in 'removed component' states"
 | |
|         // );
 | |
|         // assert_eq!(
 | |
|         //     world.removed::<f64>(),
 | |
|         //     &[b],
 | |
|         //     "world clears result in 'removed component' states"
 | |
|         // );
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn added_tracking() {
 | |
|         let mut world = World::new();
 | |
|         let a = world.spawn().insert(123i32).id();
 | |
| 
 | |
|         assert_eq!(world.query::<&i32>().iter(&world).count(), 1);
 | |
|         assert_eq!(
 | |
|             world
 | |
|                 .query_filtered::<(), Added<i32>>()
 | |
|                 .iter(&world)
 | |
|                 .count(),
 | |
|             1
 | |
|         );
 | |
|         assert_eq!(world.query::<&i32>().iter(&world).count(), 1);
 | |
|         assert_eq!(
 | |
|             world
 | |
|                 .query_filtered::<(), Added<i32>>()
 | |
|                 .iter(&world)
 | |
|                 .count(),
 | |
|             1
 | |
|         );
 | |
|         assert!(world.query::<&i32>().get(&world, a).is_ok());
 | |
|         assert!(world
 | |
|             .query_filtered::<(), Added<i32>>()
 | |
|             .get(&world, a)
 | |
|             .is_ok());
 | |
|         assert!(world.query::<&i32>().get(&world, a).is_ok());
 | |
|         assert!(world
 | |
|             .query_filtered::<(), Added<i32>>()
 | |
|             .get(&world, a)
 | |
|             .is_ok());
 | |
| 
 | |
|         world.clear_trackers();
 | |
| 
 | |
|         assert_eq!(world.query::<&i32>().iter(&world).count(), 1);
 | |
|         assert_eq!(
 | |
|             world
 | |
|                 .query_filtered::<(), Added<i32>>()
 | |
|                 .iter(&world)
 | |
|                 .count(),
 | |
|             0
 | |
|         );
 | |
|         assert_eq!(world.query::<&i32>().iter(&world).count(), 1);
 | |
|         assert_eq!(
 | |
|             world
 | |
|                 .query_filtered::<(), Added<i32>>()
 | |
|                 .iter(&world)
 | |
|                 .count(),
 | |
|             0
 | |
|         );
 | |
|         assert!(world.query::<&i32>().get(&world, a).is_ok());
 | |
|         assert!(world
 | |
|             .query_filtered::<(), Added<i32>>()
 | |
|             .get(&world, a)
 | |
|             .is_err());
 | |
|         assert!(world.query::<&i32>().get(&world, a).is_ok());
 | |
|         assert!(world
 | |
|             .query_filtered::<(), Added<i32>>()
 | |
|             .get(&world, a)
 | |
|             .is_err());
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn added_queries() {
 | |
|         let mut world = World::default();
 | |
|         let e1 = world.spawn().insert(A(0)).id();
 | |
| 
 | |
|         fn get_added<Com: Component>(world: &mut World) -> Vec<Entity> {
 | |
|             world
 | |
|                 .query_filtered::<Entity, Added<Com>>()
 | |
|                 .iter(&world)
 | |
|                 .collect::<Vec<Entity>>()
 | |
|         }
 | |
| 
 | |
|         assert_eq!(get_added::<A>(&mut world), vec![e1]);
 | |
|         world.entity_mut(e1).insert(B(0));
 | |
|         assert_eq!(get_added::<A>(&mut world), vec![e1]);
 | |
|         assert_eq!(get_added::<B>(&mut world), vec![e1]);
 | |
| 
 | |
|         world.clear_trackers();
 | |
|         assert!(get_added::<A>(&mut world).is_empty());
 | |
|         let e2 = world.spawn().insert_bundle((A(1), B(1))).id();
 | |
|         assert_eq!(get_added::<A>(&mut world), vec![e2]);
 | |
|         assert_eq!(get_added::<B>(&mut world), vec![e2]);
 | |
| 
 | |
|         let added = world
 | |
|             .query_filtered::<Entity, (Added<A>, Added<B>)>()
 | |
|             .iter(&world)
 | |
|             .collect::<Vec<Entity>>();
 | |
|         assert_eq!(added, vec![e2]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn changed_trackers() {
 | |
|         let mut world = World::default();
 | |
|         let e1 = world.spawn().insert_bundle((A(0), B(0))).id();
 | |
|         let e2 = world.spawn().insert_bundle((A(0), B(0))).id();
 | |
|         let e3 = world.spawn().insert_bundle((A(0), B(0))).id();
 | |
|         world.spawn().insert_bundle((A(0), B));
 | |
| 
 | |
|         world.clear_trackers();
 | |
| 
 | |
|         for (i, mut a) in world.query::<&mut A>().iter_mut(&mut world).enumerate() {
 | |
|             if i % 2 == 0 {
 | |
|                 a.0 += 1;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         fn get_filtered<F: WorldQuery>(world: &mut World) -> Vec<Entity>
 | |
|         where
 | |
|             F::Fetch: FilterFetch,
 | |
|         {
 | |
|             world
 | |
|                 .query_filtered::<Entity, F>()
 | |
|                 .iter(&world)
 | |
|                 .collect::<Vec<Entity>>()
 | |
|         }
 | |
| 
 | |
|         assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e1, e3]);
 | |
| 
 | |
|         // ensure changing an entity's archetypes also moves its changed state
 | |
|         world.entity_mut(e1).insert(C);
 | |
| 
 | |
|         assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e3, e1], "changed entities list should not change (although the order will due to archetype moves)");
 | |
| 
 | |
|         // spawning a new A entity should not change existing changed state
 | |
|         world.entity_mut(e1).insert_bundle((A(0), B));
 | |
|         assert_eq!(
 | |
|             get_filtered::<Changed<A>>(&mut world),
 | |
|             vec![e3, e1],
 | |
|             "changed entities list should not change"
 | |
|         );
 | |
| 
 | |
|         // removing an unchanged entity should not change changed state
 | |
|         assert!(world.despawn(e2));
 | |
|         assert_eq!(
 | |
|             get_filtered::<Changed<A>>(&mut world),
 | |
|             vec![e3, e1],
 | |
|             "changed entities list should not change"
 | |
|         );
 | |
| 
 | |
|         // removing a changed entity should remove it from enumeration
 | |
|         assert!(world.despawn(e1));
 | |
|         assert_eq!(
 | |
|             get_filtered::<Changed<A>>(&mut world),
 | |
|             vec![e3],
 | |
|             "e1 should no longer be returned"
 | |
|         );
 | |
| 
 | |
|         world.clear_trackers();
 | |
| 
 | |
|         assert!(get_filtered::<Changed<A>>(&mut world).is_empty());
 | |
| 
 | |
|         let e4 = world.spawn().id();
 | |
| 
 | |
|         world.entity_mut(e4).insert(A(0));
 | |
|         assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e4]);
 | |
|         assert_eq!(get_filtered::<Added<A>>(&mut world), vec![e4]);
 | |
| 
 | |
|         world.entity_mut(e4).insert(A(1));
 | |
|         assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e4]);
 | |
| 
 | |
|         world.clear_trackers();
 | |
| 
 | |
|         // ensure inserting multiple components set changed state for all components and set added
 | |
|         // state for non existing components even when changing archetype.
 | |
|         world.entity_mut(e4).insert_bundle((A(0), B(0)));
 | |
| 
 | |
|         assert!(get_filtered::<Added<A>>(&mut world).is_empty());
 | |
|         assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e4]);
 | |
|         assert_eq!(get_filtered::<Added<B>>(&mut world), vec![e4]);
 | |
|         assert_eq!(get_filtered::<Changed<B>>(&mut world), vec![e4]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn empty_spawn() {
 | |
|         let mut world = World::default();
 | |
|         let e = world.spawn().id();
 | |
|         let mut e_mut = world.entity_mut(e);
 | |
|         e_mut.insert(A(0));
 | |
|         assert_eq!(e_mut.get::<A>().unwrap(), &A(0));
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn reserve_and_spawn() {
 | |
|         let mut world = World::default();
 | |
|         let e = world.entities().reserve_entity();
 | |
|         world.flush();
 | |
|         let mut e_mut = world.entity_mut(e);
 | |
|         e_mut.insert(A(0));
 | |
|         assert_eq!(e_mut.get::<A>().unwrap(), &A(0));
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn changed_query() {
 | |
|         let mut world = World::default();
 | |
|         let e1 = world.spawn().insert_bundle((A(0), B(0))).id();
 | |
| 
 | |
|         fn get_changed(world: &mut World) -> Vec<Entity> {
 | |
|             world
 | |
|                 .query_filtered::<Entity, Changed<A>>()
 | |
|                 .iter(&world)
 | |
|                 .collect::<Vec<Entity>>()
 | |
|         }
 | |
|         assert_eq!(get_changed(&mut world), vec![e1]);
 | |
|         world.clear_trackers();
 | |
|         assert_eq!(get_changed(&mut world), vec![]);
 | |
|         *world.get_mut(e1).unwrap() = A(1);
 | |
|         assert_eq!(get_changed(&mut world), vec![e1]);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn resource() {
 | |
|         let mut world = World::default();
 | |
|         assert!(world.get_resource::<i32>().is_none());
 | |
|         assert!(!world.contains_resource::<i32>());
 | |
| 
 | |
|         world.insert_resource(123);
 | |
|         let resource_id = world
 | |
|             .components()
 | |
|             .get_resource_id(TypeId::of::<i32>())
 | |
|             .unwrap();
 | |
|         let archetype_component_id = world
 | |
|             .archetypes()
 | |
|             .resource()
 | |
|             .get_archetype_component_id(resource_id)
 | |
|             .unwrap();
 | |
| 
 | |
|         assert_eq!(*world.get_resource::<i32>().expect("resource exists"), 123);
 | |
|         assert!(world.contains_resource::<i32>());
 | |
| 
 | |
|         world.insert_resource(456u64);
 | |
|         assert_eq!(
 | |
|             *world.get_resource::<u64>().expect("resource exists"),
 | |
|             456u64
 | |
|         );
 | |
| 
 | |
|         world.insert_resource(789u64);
 | |
|         assert_eq!(*world.get_resource::<u64>().expect("resource exists"), 789);
 | |
| 
 | |
|         {
 | |
|             let mut value = world.get_resource_mut::<u64>().expect("resource exists");
 | |
|             assert_eq!(*value, 789);
 | |
|             *value = 10;
 | |
|         }
 | |
| 
 | |
|         assert_eq!(
 | |
|             world.get_resource::<u64>(),
 | |
|             Some(&10),
 | |
|             "resource changes are preserved"
 | |
|         );
 | |
| 
 | |
|         assert_eq!(
 | |
|             world.remove_resource::<u64>(),
 | |
|             Some(10),
 | |
|             "removed resource has the correct value"
 | |
|         );
 | |
|         assert_eq!(
 | |
|             world.get_resource::<u64>(),
 | |
|             None,
 | |
|             "removed resource no longer exists"
 | |
|         );
 | |
|         assert_eq!(
 | |
|             world.remove_resource::<u64>(),
 | |
|             None,
 | |
|             "double remove returns nothing"
 | |
|         );
 | |
| 
 | |
|         world.insert_resource(1u64);
 | |
|         assert_eq!(
 | |
|             world.get_resource::<u64>(),
 | |
|             Some(&1u64),
 | |
|             "re-inserting resources works"
 | |
|         );
 | |
| 
 | |
|         assert_eq!(
 | |
|             world.get_resource::<i32>(),
 | |
|             Some(&123),
 | |
|             "other resources are unaffected"
 | |
|         );
 | |
| 
 | |
|         let current_resource_id = world
 | |
|             .components()
 | |
|             .get_resource_id(TypeId::of::<i32>())
 | |
|             .unwrap();
 | |
|         assert_eq!(
 | |
|             resource_id, current_resource_id,
 | |
|             "resource id does not change after removing / re-adding"
 | |
|         );
 | |
| 
 | |
|         let current_archetype_component_id = world
 | |
|             .archetypes()
 | |
|             .resource()
 | |
|             .get_archetype_component_id(current_resource_id)
 | |
|             .unwrap();
 | |
| 
 | |
|         assert_eq!(
 | |
|             archetype_component_id, current_archetype_component_id,
 | |
|             "resource archetype component id does not change after removing / re-adding"
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn remove_intersection() {
 | |
|         let mut world = World::default();
 | |
|         let e1 = world.spawn().insert_bundle((1, 1.0, "a")).id();
 | |
| 
 | |
|         let mut e = world.entity_mut(e1);
 | |
|         assert_eq!(e.get::<&'static str>(), Some(&"a"));
 | |
|         assert_eq!(e.get::<i32>(), Some(&1));
 | |
|         assert_eq!(e.get::<f64>(), Some(&1.0));
 | |
|         assert_eq!(
 | |
|             e.get::<usize>(),
 | |
|             None,
 | |
|             "usize is not in the entity, so it should not exist"
 | |
|         );
 | |
| 
 | |
|         e.remove_bundle_intersection::<(i32, f64, usize)>();
 | |
|         assert_eq!(
 | |
|             e.get::<&'static str>(),
 | |
|             Some(&"a"),
 | |
|             "&'static str is not in the removed bundle, so it should exist"
 | |
|         );
 | |
|         assert_eq!(
 | |
|             e.get::<i32>(),
 | |
|             None,
 | |
|             "i32 is in the removed bundle, so it should not exist"
 | |
|         );
 | |
|         assert_eq!(
 | |
|             e.get::<f64>(),
 | |
|             None,
 | |
|             "f64 is in the removed bundle, so it should not exist"
 | |
|         );
 | |
|         assert_eq!(
 | |
|             e.get::<usize>(),
 | |
|             None,
 | |
|             "usize is in the removed bundle, so it should not exist"
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn remove_bundle() {
 | |
|         let mut world = World::default();
 | |
|         world.spawn().insert_bundle((1, 1.0, 1usize)).id();
 | |
|         let e2 = world.spawn().insert_bundle((2, 2.0, 2usize)).id();
 | |
|         world.spawn().insert_bundle((3, 3.0, 3usize)).id();
 | |
| 
 | |
|         let mut query = world.query::<(&f64, &usize)>();
 | |
|         let results = query
 | |
|             .iter(&world)
 | |
|             .map(|(a, b)| (*a, *b))
 | |
|             .collect::<Vec<_>>();
 | |
|         assert_eq!(results, vec![(1.0, 1usize), (2.0, 2usize), (3.0, 3usize),]);
 | |
| 
 | |
|         let removed_bundle = world
 | |
|             .entity_mut(e2)
 | |
|             .remove_bundle::<(f64, usize)>()
 | |
|             .unwrap();
 | |
|         assert_eq!(removed_bundle, (2.0, 2usize));
 | |
| 
 | |
|         let results = query
 | |
|             .iter(&world)
 | |
|             .map(|(a, b)| (*a, *b))
 | |
|             .collect::<Vec<_>>();
 | |
|         assert_eq!(results, vec![(1.0, 1usize), (3.0, 3usize),]);
 | |
| 
 | |
|         let mut i32_query = world.query::<&i32>();
 | |
|         let results = i32_query.iter(&world).cloned().collect::<Vec<_>>();
 | |
|         assert_eq!(results, vec![1, 3, 2]);
 | |
| 
 | |
|         let entity_ref = world.entity(e2);
 | |
|         assert_eq!(
 | |
|             entity_ref.get::<i32>(),
 | |
|             Some(&2),
 | |
|             "i32 is not in the removed bundle, so it should exist"
 | |
|         );
 | |
|         assert_eq!(
 | |
|             entity_ref.get::<f64>(),
 | |
|             None,
 | |
|             "f64 is in the removed bundle, so it should not exist"
 | |
|         );
 | |
|         assert_eq!(
 | |
|             entity_ref.get::<usize>(),
 | |
|             None,
 | |
|             "usize is in the removed bundle, so it should not exist"
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn non_send_resource() {
 | |
|         let mut world = World::default();
 | |
|         world.insert_non_send(123i32);
 | |
|         world.insert_non_send(456i64);
 | |
|         assert_eq!(*world.get_non_send_resource::<i32>().unwrap(), 123);
 | |
|         assert_eq!(*world.get_non_send_resource_mut::<i64>().unwrap(), 456);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     #[should_panic]
 | |
|     fn non_send_resource_panic() {
 | |
|         let mut world = World::default();
 | |
|         world.insert_non_send(0i32);
 | |
|         std::thread::spawn(move || {
 | |
|             let _ = world.get_non_send_resource_mut::<i32>();
 | |
|         })
 | |
|         .join()
 | |
|         .unwrap();
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn trackers_query() {
 | |
|         let mut world = World::default();
 | |
|         let e1 = world.spawn().insert_bundle((A(0), B(0))).id();
 | |
|         world.spawn().insert(B(0));
 | |
| 
 | |
|         let mut trackers_query = world.query::<Option<ChangeTrackers<A>>>();
 | |
|         let trackers = trackers_query.iter(&world).collect::<Vec<_>>();
 | |
|         let a_trackers = trackers[0].as_ref().unwrap();
 | |
|         assert!(trackers[1].is_none());
 | |
|         assert!(a_trackers.is_added());
 | |
|         assert!(a_trackers.is_changed());
 | |
|         world.clear_trackers();
 | |
|         let trackers = trackers_query.iter(&world).collect::<Vec<_>>();
 | |
|         let a_trackers = trackers[0].as_ref().unwrap();
 | |
|         assert!(!a_trackers.is_added());
 | |
|         assert!(!a_trackers.is_changed());
 | |
|         *world.get_mut(e1).unwrap() = A(1);
 | |
|         let trackers = trackers_query.iter(&world).collect::<Vec<_>>();
 | |
|         let a_trackers = trackers[0].as_ref().unwrap();
 | |
|         assert!(!a_trackers.is_added());
 | |
|         assert!(a_trackers.is_changed());
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn exact_size_query() {
 | |
|         let mut world = World::default();
 | |
|         world.spawn().insert_bundle((A(0), B(0)));
 | |
|         world.spawn().insert_bundle((A(0), B(0)));
 | |
|         world.spawn().insert_bundle((A(0), B(0), C));
 | |
|         world.spawn().insert(C);
 | |
| 
 | |
|         let mut query = world.query::<(&A, &B)>();
 | |
|         assert_eq!(query.iter(&world).len(), 3);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     #[should_panic]
 | |
|     fn duplicate_components_panic() {
 | |
|         let mut world = World::new();
 | |
|         world.spawn().insert_bundle((1, 2));
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     #[should_panic]
 | |
|     fn ref_and_mut_query_panic() {
 | |
|         let mut world = World::new();
 | |
|         world.query::<(&A, &mut A)>();
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     #[should_panic]
 | |
|     fn mut_and_mut_query_panic() {
 | |
|         let mut world = World::new();
 | |
|         world.query::<(&mut A, &mut A)>();
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     #[should_panic]
 | |
|     fn multiple_worlds_same_query_iter() {
 | |
|         let mut world_a = World::new();
 | |
|         let world_b = World::new();
 | |
|         let mut query = world_a.query::<&i32>();
 | |
|         query.iter(&world_a);
 | |
|         query.iter(&world_b);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     #[should_panic]
 | |
|     fn multiple_worlds_same_query_get() {
 | |
|         let mut world_a = World::new();
 | |
|         let world_b = World::new();
 | |
|         let mut query = world_a.query::<&i32>();
 | |
|         let _ = query.get(&world_a, Entity::new(0));
 | |
|         let _ = query.get(&world_b, Entity::new(0));
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     #[should_panic]
 | |
|     fn multiple_worlds_same_query_for_each() {
 | |
|         let mut world_a = World::new();
 | |
|         let world_b = World::new();
 | |
|         let mut query = world_a.query::<&i32>();
 | |
|         query.for_each(&world_a, |_| {});
 | |
|         query.for_each(&world_b, |_| {});
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn resource_scope() {
 | |
|         let mut world = World::default();
 | |
|         world.insert_resource::<i32>(0);
 | |
|         world.resource_scope(|world: &mut World, mut value: Mut<i32>| {
 | |
|             *value += 1;
 | |
|             assert!(!world.contains_resource::<i32>());
 | |
|         });
 | |
|         assert_eq!(*world.get_resource::<i32>().unwrap(), 1);
 | |
|     }
 | |
| }
 |