use std::any::type_name; use std::marker::PhantomData; use crate::World; use crate::component::{ Component, Handle as ComponentHandle, HandleMut as ComponentHandleMut, }; use crate::entity::Handle as EntityHandle; use crate::query::{ Term, TermsBuilder, TermsBuilderInterface, }; use crate::tuple::Tuple; use crate::uid::With as WithUid; pub struct With where WithUidT: WithUid, { _pd: PhantomData, } impl<'world, WithUidT> Term<'world> for With where WithUidT: WithUid, { type AddField = Fields; fn apply_to_terms_builder( terms_builder: &mut TermsBuilder, ) { terms_builder.present([WithUidT::uid()]); } fn add_field( _entity_handle: &EntityHandle<'world>, _world: &'world World, fields: Fields, ) -> Self::AddField { fields } } pub struct Without where WithUidT: WithUid, { _pd: PhantomData, } impl<'world, WithUidT> Term<'world> for Without where WithUidT: WithUid, { type AddField = Fields; fn apply_to_terms_builder( terms_builder: &mut TermsBuilder, ) { terms_builder.absent([WithUidT::uid()]); } fn add_field( _entity_handle: &EntityHandle<'world>, _world: &'world World, fields: Fields, ) -> Self::AddField { fields } } impl<'world, ComponentT: Component> Term<'world> for Option<&ComponentT> { type AddField = Fields::WithElementAtEnd>>; fn apply_to_terms_builder( _terms_builder: &mut TermsBuilder, ) { } fn add_field( entity_handle: &EntityHandle<'world>, _world: &'world World, fields: Fields, ) -> Self::AddField { let component = (|| { let comp_ref = &entity_handle .get_matching_components(ComponentT::id()) .next()?; match ComponentHandle::::from_entity_component_ref(comp_ref) { Ok(component) => Some(component), Err(err) => { panic!( "Creating handle to component {} failed: {err}", type_name::() ); } } })(); fields.with_elem(component) } } impl<'world, ComponentT: Component> Term<'world> for Option<&mut ComponentT> { type AddField = Fields::WithElementAtEnd>>; fn apply_to_terms_builder( _terms_builder: &mut TermsBuilder, ) { } fn add_field( entity_handle: &EntityHandle<'world>, world: &'world World, fields: Fields, ) -> Self::AddField { let component = (|| { let comp_ref = &entity_handle .get_matching_components(ComponentT::id()) .next()?; match ComponentHandleMut::::from_entity_component_ref(comp_ref, world) { Ok(component) => Some(component), Err(err) => { panic!( "Creating mut handle to component {} failed: {err}", type_name::() ); } } })(); fields.with_elem(component) } }