hecs_schedule/
subworld.rs1use atomic_refcell::AtomicRef;
2use std::{any::type_name, marker::PhantomData, ops::Deref};
3
4use crate::{access::*, borrow::ComponentBorrow, Error, Result};
5
6use crate::{GenericWorld, QueryOne};
7use hecs::{Component, Entity, Query, QueryBorrow, World};
8
9pub type SubWorld<'a, T> = SubWorldRaw<AtomicRef<'a, World>, T>;
12pub type SubWorldRefCell<'a, T> = SubWorldRaw<std::cell::Ref<'a, World>, T>;
14pub type SubWorldRef<'a, T> = SubWorldRaw<&'a World, T>;
16
17pub type EmptyWorld<'a> = SubWorldRef<'a, ()>;
19
20pub struct SubWorldRaw<A, T> {
30 pub(crate) world: A,
31 marker: PhantomData<T>,
32}
33
34impl<A, T> SubWorldRaw<A, T> {
35 pub fn new(world: A) -> Self {
38 Self {
39 world,
40 marker: PhantomData,
41 }
42 }
43}
44
45impl<A, T: ComponentBorrow> SubWorldRaw<A, T> {
46 pub fn has<U: IntoAccess>(&self) -> bool {
48 T::has::<U>()
49 }
50
51 pub fn has_all<U: Subset>(&self) -> bool {
53 U::is_subset::<T>()
54 }
55}
56
57impl<'w, A: 'w + Deref<Target = World>, T: ComponentBorrow> SubWorldRaw<A, T> {
58 pub fn query<Q: Query + Subset>(&self) -> QueryBorrow<'_, Q> {
62 self.try_query()
63 .expect("Failed to execute query on subworld")
64 }
65
66 pub fn query_one<Q: Query + Subset>(&'w self, entity: Entity) -> Result<QueryOne<'w, Q>> {
69 if !self.has_all::<Q>() {
70 return Err(Error::IncompatibleSubworld {
71 subworld: type_name::<T>(),
72 query: type_name::<Q>(),
73 });
74 }
75
76 let query = self
77 .world
78 .query_one(entity)
79 .map_err(|_| Error::NoSuchEntity(entity))?;
80
81 Ok(QueryOne::new(entity, query))
82 }
83
84 pub fn get<C: Component>(&self, entity: Entity) -> Result<hecs::Ref<C>> {
88 if !self.has::<&C>() {
89 return Err(Error::IncompatibleSubworld {
90 subworld: type_name::<T>(),
91 query: type_name::<&C>(),
92 });
93 }
94
95 match self.world.get::<&C>(entity) {
96 Ok(val) => Ok(val),
97 Err(hecs::ComponentError::NoSuchEntity) => Err(Error::NoSuchEntity(entity)),
98 Err(hecs::ComponentError::MissingComponent(name)) => {
99 Err(Error::MissingComponent(entity, name))
100 }
101 }
102 }
103
104 pub fn get_mut<C: Component>(&self, entity: Entity) -> Result<hecs::RefMut<C>> {
108 if !self.has::<&C>() {
109 return Err(Error::IncompatibleSubworld {
110 subworld: type_name::<T>(),
111 query: type_name::<&C>(),
112 });
113 }
114
115 match self.world.get::<&mut C>(entity) {
116 Ok(val) => Ok(val),
117 Err(hecs::ComponentError::NoSuchEntity) => Err(Error::NoSuchEntity(entity)),
118 Err(hecs::ComponentError::MissingComponent(name)) => {
119 Err(Error::MissingComponent(entity, name))
120 }
121 }
122 }
123
124 pub fn reserve_entities(&self, count: u32) -> impl Iterator<Item = Entity> + '_ {
126 self.world.reserve_entities(count)
127 }
128
129 pub fn query_par<Q: Query + Subset>(&self) -> QueryBorrow<'_, Q> {
133 self.try_query()
134 .expect("Failed to execute query on subworld")
135 }
136}