hobo_core/
entity.rs

1use crate::{prelude::*, query, storage::StorageGuard, StorageRef, StorageRefMut};
2pub use hobo_derive::AsEntity;
3use owning_ref::{OwningRef, OwningRefMut};
4use std::any::type_name;
5
6/// An opaque copyable identifier that is used to attach and fetch components
7#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
8pub struct Entity(pub(crate) u64);
9
10impl Entity {
11	pub(crate) fn root() -> Self { Self(0) }
12}
13
14pub trait AsEntity {
15	fn as_entity(&self) -> Entity;
16	#[inline] fn try_get_cmp<'a, C: 'static>(&self) -> Option<OwningRef<StorageRef<'a, C>, C>> where Self: Sized {
17		World::mark_borrow_mut();
18		let world = unsafe { &mut *WORLD.get() as &mut World };
19		let entity = self.as_entity();
20		let storage = world.storage::<C>();
21		if !storage.has(entity) {
22			World::unmark_borrow_mut();
23			return None;
24		}
25		let res = Some(OwningRef::new(storage).map(|x| x.get(entity).unwrap()));
26		World::unmark_borrow_mut();
27		res
28	}
29	#[inline] fn try_get_cmp_mut<'a, C: 'static>(&self) -> Option<OwningRefMut<StorageGuard<'a, C, StorageRefMut<'a, C>>, C>> where Self: Sized {
30		World::mark_borrow_mut();
31		let world = unsafe { &mut *WORLD.get() as &mut World };
32		let entity = self.as_entity();
33		if !world.storage::<C>().has(entity) {
34			World::unmark_borrow_mut();
35			return None;
36		}
37		let res = Some(OwningRefMut::new(world.storage_mut::<C>()).map_mut(|x| x.get_mut(entity).unwrap()));
38		World::unmark_borrow_mut();
39		res
40	}
41	#[inline]
42	#[track_caller]
43	fn get_cmp<'a, C: 'static>(&self) -> OwningRef<StorageRef<'a, C>, C> where Self: Sized {
44		World::mark_borrow_mut();
45		let world = unsafe { &mut *WORLD.get() as &mut World };
46		let res = OwningRef::new(world.storage::<C>()).try_map(|x| x.get(self).ok_or_else(|| type_name::<C>())).expect("entity does not have component");
47		World::unmark_borrow_mut();
48		res
49	}
50	#[inline]
51	#[track_caller]
52	fn get_cmp_mut<'a, C: 'static>(&self) -> OwningRefMut<StorageGuard<'a, C, StorageRefMut<'a, C>>, C> where Self: Sized {
53		World::mark_borrow_mut();
54		let world = unsafe { &mut *WORLD.get() as &mut World };
55		let res = OwningRefMut::new(world.storage_mut::<C>()).try_map_mut(|x| x.get_mut(self).ok_or_else(|| type_name::<C>())).expect("entity does not have component");
56		World::unmark_borrow_mut();
57		res
58	}
59	#[inline] fn get_cmp_mut_or<'a, C: 'static>(&self, f: impl FnOnce() -> C) -> OwningRefMut<StorageGuard<'a, C, StorageRefMut<'a, C>>, C> where Self: Sized {
60		World::mark_borrow_mut();
61		let world = unsafe { &mut *WORLD.get() as &mut World };
62		let res = OwningRefMut::new(world.storage_mut::<C>()).map_mut(move |x| x.get_mut_or(self, f));
63		World::unmark_borrow_mut();
64		res
65	}
66	#[inline] fn get_cmp_mut_or_default<'a, C: 'static + Default>(&self) -> OwningRefMut<StorageGuard<'a, C, StorageRefMut<'a, C>>, C> where Self: Sized {
67		self.get_cmp_mut_or(Default::default)
68	}
69	#[inline] fn remove_cmp<C: 'static>(&self) where Self: Sized {
70		World::mark_borrow_mut();
71		let world = unsafe { &mut *WORLD.get() as &mut World };
72		world.storage_mut::<C>().remove(self);
73		World::unmark_borrow_mut();
74	}
75	fn find_in_ancestors<Q: query::Query>(&self) -> Vec<Q::Fetch> {
76		let mut entities = Some(Parent::ancestors(self.as_entity()).into_iter().collect());
77		World::mark_borrow_mut();
78		let world = unsafe { &mut *WORLD.get() as &mut World };
79		Q::filter(world, &mut entities);
80		let res = entities.unwrap_or_default().into_iter().map(|entity| Q::fetch(world, entity)).collect::<Vec<_>>();
81		World::unmark_borrow_mut();
82		res
83	}
84	fn try_find_first_in_ancestors<Q: query::Query>(&self) -> Option<Q::Fetch> {
85		let mut entities = Some(Parent::ancestors(self.as_entity()).into_iter().collect());
86		World::mark_borrow_mut();
87		let world = unsafe { &mut *WORLD.get() as &mut World };
88		Q::filter(world, &mut entities);
89		let res = entities.unwrap_or_default().into_iter().next().map(|e| Q::fetch(world, e));
90		World::unmark_borrow_mut();
91		res
92	}
93	#[inline]
94	#[track_caller]
95	fn find_first_in_ancestors<Q: query::Query>(&self) -> Q::Fetch { self.try_find_first_in_ancestors::<Q>().expect("could not find query in ancestor") }
96	fn find_in_descendants<Q: query::Query>(&self) -> Vec<Q::Fetch> {
97		let mut entities = Some(Children::descendants(self.as_entity()).into_iter().collect());
98		World::mark_borrow_mut();
99		let world = unsafe { &mut *WORLD.get() as &mut World };
100		Q::filter(world, &mut entities);
101		let res = entities.unwrap_or_default().into_iter().map(|entity| Q::fetch(world, entity)).collect::<Vec<_>>();
102		World::unmark_borrow_mut();
103		res
104	}
105	fn find_in_children<Q: query::Query>(&self) -> Vec<Q::Fetch> {
106		let mut entities = Some(self.as_entity().try_get_cmp::<Children>().map_or_else(default, |x| x.0.iter().copied().collect()));
107		World::mark_borrow_mut();
108		let world = unsafe { &mut *WORLD.get() as &mut World };
109		Q::filter(world, &mut entities);
110		let res = entities.unwrap_or_default().into_iter().map(|entity| Q::fetch(world, entity)).collect::<Vec<_>>();
111		World::unmark_borrow_mut();
112		res
113	}
114	fn try_find_first_in_descendants<Q: query::Query>(&self) -> Option<Q::Fetch> {
115		let mut entities = Some(Children::descendants(self.as_entity()).into_iter().collect());
116		World::mark_borrow_mut();
117		let world = unsafe { &mut *WORLD.get() as &mut World };
118		Q::filter(world, &mut entities);
119		let res = entities.unwrap_or_default().into_iter().next().map(|e| Q::fetch(world, e));
120		World::unmark_borrow_mut();
121		res
122	}
123	fn try_find_first_in_children<Q: query::Query>(&self) -> Option<Q::Fetch> {
124		let mut entities = Some(self.as_entity().try_get_cmp::<Children>().map_or_else(default, |x| x.0.iter().copied().collect()));
125		World::mark_borrow_mut();
126		let world = unsafe { &mut *WORLD.get() as &mut World };
127		Q::filter(world, &mut entities);
128		let res = entities.unwrap_or_default().into_iter().next().map(|e| Q::fetch(world, e));
129		World::unmark_borrow_mut();
130		res
131	}
132	#[inline]
133	#[track_caller]
134	fn find_first_in_descendants<Q: query::Query>(&self) -> Q::Fetch { self.try_find_first_in_descendants::<Q>().expect("could not find query in descendant") }
135	#[inline]
136	#[track_caller]
137	fn find_first_in_children<Q: query::Query>(&self) -> Q::Fetch { self.try_find_first_in_children::<Q>().expect("could not find child") }
138	#[inline] fn has_cmp<C: 'static>(&self) -> bool where Self: Sized {
139		World::mark_borrow_mut();
140		let world = unsafe { &mut *WORLD.get() as &mut World };
141		let res = world.storage::<C>().has(self.as_entity());
142		World::unmark_borrow_mut();
143		res
144	}
145
146	#[inline] fn remove(&self) {
147		World::mark_borrow_mut();
148		let world = unsafe { &mut *WORLD.get() as &mut World };
149		let res = world.remove_entity(self.as_entity());
150		World::unmark_borrow_mut();
151		res
152	}
153	#[inline] fn is_dead(&self)  -> bool {
154		World::mark_borrow();
155		let world = unsafe { &*WORLD.get() as &World };
156		let res = world.is_dead(self.as_entity());
157		World::unmark_borrow();
158		res
159	}
160	#[inline] fn add_component<T: 'static>(&self, component: T) {
161		World::mark_borrow_mut();
162		let world = unsafe { &mut *WORLD.get() as &mut World };
163		let res = world.storage_mut::<T>().add(self.as_entity(), component);
164		World::unmark_borrow_mut();
165		res
166	}
167	#[inline] fn component<T: 'static>(self, component: T) -> Self where Self: Sized { self.add_component(component); self }
168}
169
170impl AsEntity for Entity {
171	fn as_entity(&self) -> Entity { *self }
172}
173
174impl<T: AsEntity> AsEntity for &T {
175	fn as_entity(&self) -> Entity { T::as_entity(*self) }
176}
177impl<T: AsEntity> AsEntity for &mut T {
178	fn as_entity(&self) -> Entity { T::as_entity(*self) }
179}