1use core::any::TypeId;
2use core::ops::{Deref, DerefMut};
3use core::ptr::NonNull;
4
5use crate::archetype::Archetype;
6use crate::{Component, Entity, MissingComponent, Query, QueryOne};
7
8#[derive(Copy, Clone)]
10pub struct EntityRef<'a> {
11 archetype: &'a Archetype,
12 entity: Entity,
13 index: u32,
14}
15
16impl<'a> EntityRef<'a> {
17 pub(crate) unsafe fn new(archetype: &'a Archetype, entity: Entity, index: u32) -> Self {
18 Self {
19 archetype,
20 entity,
21 index,
22 }
23 }
24
25 #[inline]
27 pub fn entity(&self) -> Entity {
28 self.entity
29 }
30
31 pub fn has<T: Component>(&self) -> bool {
33 self.archetype.has::<T>()
34 }
35
36 pub fn get<T: Component>(&self) -> Option<Ref<'a, T>> {
41 Some(unsafe { Ref::new(self.archetype, self.index).ok()? })
42 }
43
44 pub fn get_mut<T: Component>(&self) -> Option<RefMut<'a, T>> {
48 Some(unsafe { RefMut::new(self.archetype, self.index).ok()? })
49 }
50
51 pub fn query<Q: Query>(&self) -> QueryOne<'a, Q> {
68 unsafe { QueryOne::new(self.archetype, self.index) }
69 }
70
71 pub fn component_types(&self) -> impl Iterator<Item = TypeId> + 'a {
78 self.archetype.types().iter().map(|ty| ty.id())
79 }
80
81 pub fn len(&self) -> usize {
83 self.archetype.types().len()
84 }
85
86 pub fn is_empty(&self) -> bool {
88 self.len() == 0
89 }
90}
91
92unsafe impl<'a> Send for EntityRef<'a> {}
93unsafe impl<'a> Sync for EntityRef<'a> {}
94
95#[derive(Clone)]
97pub struct Ref<'a, T: Component> {
98 archetype: &'a Archetype,
99 state: usize,
101 target: NonNull<T>,
102}
103
104impl<'a, T: Component> Ref<'a, T> {
105 pub(crate) unsafe fn new(
106 archetype: &'a Archetype,
107 index: u32,
108 ) -> Result<Self, MissingComponent> {
109 let state = archetype
110 .get_state::<T>()
111 .ok_or_else(MissingComponent::new::<T>)?;
112 let target =
113 NonNull::new_unchecked(archetype.get_base::<T>(state).as_ptr().add(index as usize));
114 archetype.borrow::<T>(state);
115 Ok(Self {
116 archetype,
117 state,
118 target,
119 })
120 }
121}
122
123unsafe impl<T: Component> Send for Ref<'_, T> {}
124unsafe impl<T: Component> Sync for Ref<'_, T> {}
125
126impl<'a, T: Component> Drop for Ref<'a, T> {
127 fn drop(&mut self) {
128 self.archetype.release::<T>(self.state);
129 }
130}
131
132impl<'a, T: Component> Deref for Ref<'a, T> {
133 type Target = T;
134 fn deref(&self) -> &T {
135 unsafe { self.target.as_ref() }
136 }
137}
138
139pub struct RefMut<'a, T: Component> {
141 archetype: &'a Archetype,
142 state: usize,
144 target: NonNull<T>,
145}
146
147impl<'a, T: Component> RefMut<'a, T> {
148 pub(crate) unsafe fn new(
149 archetype: &'a Archetype,
150 index: u32,
151 ) -> Result<Self, MissingComponent> {
152 let state = archetype
153 .get_state::<T>()
154 .ok_or_else(MissingComponent::new::<T>)?;
155 let target =
156 NonNull::new_unchecked(archetype.get_base::<T>(state).as_ptr().add(index as usize));
157 archetype.borrow_mut::<T>(state);
158 Ok(Self {
159 archetype,
160 state,
161 target,
162 })
163 }
164}
165
166unsafe impl<T: Component> Send for RefMut<'_, T> {}
167unsafe impl<T: Component> Sync for RefMut<'_, T> {}
168
169impl<'a, T: Component> Drop for RefMut<'a, T> {
170 fn drop(&mut self) {
171 self.archetype.release_mut::<T>(self.state);
172 }
173}
174
175impl<'a, T: Component> Deref for RefMut<'a, T> {
176 type Target = T;
177 fn deref(&self) -> &T {
178 unsafe { self.target.as_ref() }
179 }
180}
181
182impl<'a, T: Component> DerefMut for RefMut<'a, T> {
183 fn deref_mut(&mut self) -> &mut T {
184 unsafe { self.target.as_mut() }
185 }
186}