use ecs::component::{Component, RefSequence as ComponentRefSequence}; use ecs::uid::Uid; use ecs::{Component, World}; use parking_lot::{Mutex, Once}; pub static SETUP: Once = Once::new(); pub static TEST_LOCK: Mutex<()> = Mutex::new(()); #[derive(Component)] struct A; #[derive(Component)] struct B; #[derive(Component)] struct C; #[derive(Component)] struct D; #[derive(Component)] struct E; #[derive(Component)] struct F; #[derive(Component)] struct G; fn setup() { SETUP.call_once(|| { assert_eq!(A::id().id(), 1); assert_eq!(B::id().id(), 2); assert_eq!(C::id().id(), 3); assert_eq!(D::id().id(), 4); assert_eq!(E::id().id(), 5); assert_eq!(F::id().id(), 6); assert_eq!(G::id().id(), 7); }); } fn assert_query_finds_ents(world: &World, mut expected_ent_ids: Vec) where Comps: ComponentRefSequence, { assert!( world .query::() .iter_with_euids() .all(|(ent_id, _)| { let Some(index) = expected_ent_ids .iter() .position(|expected_id| *expected_id == ent_id) else { return false; }; expected_ent_ids.remove(index); true }), "Unexpected entity was found. Expected entities left: {expected_ent_ids:?}" ); assert_eq!( expected_ent_ids.len(), 0, concat!( "Not all entities expected to be found was found. ", "Expected entities left: {:?}" ), expected_ent_ids ); } #[test] fn query_archetype_exists_with_edges_to_next_archetypes() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, C)); let ent_2_id = world.create_entity((A, B, C, D, E)); let ent_3_id = world.create_entity((A, B, C, E)); let ent_4_id = world.create_entity((A, B, C, G, F)); assert_query_finds_ents::<(&A, &B, &C)>( &world, vec![ent_1_id, ent_2_id, ent_3_id, ent_4_id], ); } #[test] fn query_archetype_exists_with_2_comps_diff_to_next_archetype() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, C, D, F)); let ent_2_id = world.create_entity((A, B, F)); assert_query_finds_ents::<(&A, &B, &F)>(&world, vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_exists_with_2_comps_diff_to_next_archetype_rev() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, F)); let ent_2_id = world.create_entity((A, B, C, D, F)); assert_query_finds_ents::<(&A, &B, &F)>(&world, vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_exists_with_3_comps_diff_to_next_archetype() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, C, D, E, F)); let ent_2_id = world.create_entity((A, B, F)); assert_query_finds_ents::<(&A, &B, &F)>(&world, vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_exists_with_3_comps_diff_to_next_archetype_rev() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, F)); let ent_2_id = world.create_entity((A, B, C, D, E, F)); assert_query_finds_ents::<(&A, &B, &F)>(&world, vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_exists_with_4_comps_diff_to_next_archetype() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, C, D, E, F, G)); let ent_2_id = world.create_entity((A, B, G)); assert_query_finds_ents::<(&A, &B, &G)>(&world, vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_exists_with_4_comps_diff_to_next_archetype_rev() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, G)); let ent_2_id = world.create_entity((A, B, C, D, E, F, G)); assert_query_finds_ents::<(&A, &B, &G)>(&world, vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_exists_with_4_comps_diff_to_next_archetype_and_opt_comp() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, C, D, E, F, G)); let ent_2_id = world.create_entity((A, B, G)); assert_query_finds_ents::<(&A, &Option, &G)>(&world, vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_nonexistant() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); world.create_entity((A, B, C)); let ent_2_id = world.create_entity((A, B, C, D, E)); let ent_3_id = world.create_entity((A, B, C, E)); world.create_entity((A, B, C, G, F)); assert_query_finds_ents::<(&A, &E)>(&world, vec![ent_2_id, ent_3_id]); } #[test] fn query_archetype_nonexistant_and_opt_comp() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); world.create_entity((A, B, C)); let ent_2_id = world.create_entity((A, B, C, D, E)); let ent_3_id = world.create_entity((A, B, C, E)); world.create_entity((A, B, C, G, F)); assert_query_finds_ents::<(&A, &E, &Option)>(&world, vec![ent_2_id, ent_3_id]); }