1use super::*;
2
3pub struct Entity {
4 pub(crate) components: HashMap<TypeId, storage::Entity>,
5}
6
7impl Default for Entity {
8 fn default() -> Self {
9 Self::new()
10 }
11}
12
13impl Entity {
14 pub fn new() -> Self {
15 Self {
16 components: HashMap::new(),
17 }
18 }
19 pub fn add<T: Component>(&mut self, component: T) {
20 self.components
21 .insert(TypeId::of::<T>(), storage::Entity::new(component));
22 }
23 pub fn has<T: Component>(&self) -> bool {
24 self.components.contains_key(&TypeId::of::<T>())
25 }
26 pub fn remove<T: Component>(&mut self) -> Option<T> {
27 unsafe {
28 self.components
29 .remove(&TypeId::of::<T>())
30 .map(|storage| storage.into_inner())
31 }
32 }
33 pub fn query<Q: Query>(&self) -> EntityQuery<Q> {
34 self.filter(()).query()
35 }
36 pub fn filter<F: Filter>(&self, filter: F) -> FilteredEntity<F> {
37 FilteredEntity {
38 entity: self,
39 filter,
40 }
41 }
42 pub fn is<F: Filter>(&mut self, filter: F) -> bool {
43 self.filter(filter).query::<()>().is_some()
44 }
45 pub unsafe fn borrow<T: Component>(&self) -> Option<storage::entity::Borrow<T>> {
46 self.components
47 .get(&TypeId::of::<T>())
48 .map(|storage| storage.borrow())
49 }
50 pub unsafe fn borrow_mut<T: Component>(&self) -> Option<storage::entity::BorrowMut<T>> {
51 self.components
52 .get(&TypeId::of::<T>())
53 .map(|storage| storage.borrow_mut())
54 }
55}
56
57pub struct FilteredEntity<'a, T> {
58 entity: &'a Entity,
59 filter: T,
60}
61
62impl<'a, F: Filter> FilteredEntity<'a, F> {
63 pub fn query<Q: Query>(self) -> EntityQuery<'a, Q> {
64 unsafe {
65 let query = Q::Fetch::default();
66 let filter = self.filter.fetch();
67 let filtered = {
68 if let Some(borrows) = filter.borrow_direct(self.entity) {
69 F::get(&filter, &borrows)
70 } else {
71 false
72 }
73 };
74 if filtered {
75 let borrows = query.borrow_direct(self.entity);
76 let item = borrows.as_ref().map(|borrows| query.get(borrows));
77 EntityQuery { borrows, item }
78 } else {
79 EntityQuery {
80 borrows: None,
81 item: None,
82 }
83 }
84 }
85 }
86}
87
88pub struct EntityQuery<'a, Q: Query> {
89 #[allow(dead_code)]
90 borrows: Option<<Q::Fetch as Fetch<'a>>::DirectBorrows>, item: Option<QueryOutput<'a, Q>>,
92}
93
94impl<'a, Q: Query> Debug for EntityQuery<'a, Q>
95where
96 QueryOutput<'a, Q>: Debug,
97{
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 write!(f, "{:?}", self.item)
100 }
101}
102
103impl<'a, Q: Query> Deref for EntityQuery<'a, Q> {
104 type Target = Option<QueryOutput<'a, Q>>;
105 fn deref(&self) -> &Self::Target {
106 &self.item
107 }
108}
109
110impl<'a, Q: Query> DerefMut for EntityQuery<'a, Q> {
111 fn deref_mut(&mut self) -> &mut Self::Target {
112 &mut self.item
113 }
114}