entity_data/archetype/
component.rs

1use crate::archetype::entities::{ArchetypeEntities, EntitiesIter};
2use crate::entity::ArchEntityId;
3use crate::private::ComponentInfo;
4use std::borrow::Borrow;
5use std::cell::UnsafeCell;
6use std::marker::PhantomData;
7use std::ops::{Deref, DerefMut};
8
9#[derive(Default)]
10pub struct UnsafeVec(UnsafeCell<Vec<u8>>);
11
12pub trait Component: Send + Sync + 'static {}
13
14impl Deref for UnsafeVec {
15    type Target = UnsafeCell<Vec<u8>>;
16
17    fn deref(&self) -> &Self::Target {
18        &self.0
19    }
20}
21
22impl DerefMut for UnsafeVec {
23    fn deref_mut(&mut self) -> &mut Self::Target {
24        &mut self.0
25    }
26}
27
28impl<T> Component for T where T: Send + Sync + 'static {}
29
30pub struct ComponentStorage<'a, C, D> {
31    pub(crate) entities: &'a ArchetypeEntities,
32    pub(crate) step: usize,
33    pub(crate) info: &'a ComponentInfo,
34    pub(crate) data: D,
35    pub(crate) _ty: PhantomData<C>,
36}
37
38pub type ComponentStorageRef<'a, C> = ComponentStorage<'a, C, &'a UnsafeVec>;
39pub type ComponentStorageMut<'a, C> = ComponentStorage<'a, C, &'a mut UnsafeVec>;
40
41impl<'a, C, D: Borrow<UnsafeVec> + Copy> Clone for ComponentStorage<'a, C, D> {
42    fn clone(&self) -> Self {
43        Self {
44            entities: &self.entities,
45            step: self.step,
46            info: self.info,
47            data: self.data,
48            _ty: Default::default(),
49        }
50    }
51}
52
53impl<'a, C, D: Borrow<UnsafeVec> + Copy> Copy for ComponentStorage<'a, C, D> {}
54
55impl<'a, C: Component, D: Borrow<UnsafeVec>> ComponentStorage<'a, C, D> {
56    /// Checks whether `self` container specific entity.
57    pub fn contains(&self, entity_id: ArchEntityId) -> bool {
58        self.entities.contains(entity_id)
59    }
60
61    /// Returns a mutable reference to the component `C` of the specified entity id.
62    /// # Safety:
63    /// To not cause any undefined behavior, the following conditions must be met:
64    /// * Entity at `entity_id` must exist.
65    /// * `&mut C` must always be unique.
66    pub(crate) unsafe fn get_mut_unsafe(&self, entity_id: ArchEntityId) -> &'a mut C {
67        let ptr = ((&*self.data.borrow().get()).as_ptr())
68            .add(self.step * entity_id as usize)
69            .add(self.info.range.start);
70        &mut *(ptr as *mut C)
71    }
72
73    /// Returns a reference to the component `C` of the specified entity.
74    /// Safety: entity must exist.
75    pub unsafe fn get_unchecked(&self, entity_id: ArchEntityId) -> &'a C {
76        // Safety: the method does not mutate `self`
77        self.get_mut_unsafe(entity_id)
78    }
79
80    /// Returns a reference to component `C` of the specified entity.
81    pub fn get(&self, entity_id: ArchEntityId) -> Option<&'a C> {
82        if !self.contains(entity_id) {
83            return None;
84        }
85        unsafe { Some(self.get_unchecked(entity_id)) }
86    }
87}
88
89impl<'a, C: Component> ComponentStorageRef<'a, C> {
90    /// Returns an iterator over all components.
91    pub fn iter(self) -> Iter<'a, C, Self> {
92        Iter {
93            entities_iter: self.entities.iter(),
94            data: self,
95            _ty: Default::default(),
96        }
97    }
98}
99
100impl<'a, C: Component + 'a> IntoIterator for ComponentStorageRef<'a, C> {
101    type Item = &'a C;
102    type IntoIter = Iter<'a, C, Self>;
103
104    /// Returns an iterator over all components.
105    fn into_iter(self) -> Self::IntoIter {
106        self.iter()
107    }
108}
109
110impl<'a, C: Component> ComponentStorageMut<'a, C> {
111    /// Returns a mutable reference to the component `C` of the specified entity id.
112    /// Safety: component at `entity_id` must exist.
113    pub unsafe fn get_unchecked_mut(&mut self, entity_id: ArchEntityId) -> &'a mut C {
114        self.get_mut_unsafe(entity_id)
115    }
116
117    /// Returns a mutable reference to the component `C` of the specified entity id.
118    pub fn get_mut(&mut self, entity_id: ArchEntityId) -> Option<&'a mut C> {
119        if !self.contains(entity_id) {
120            return None;
121        }
122        unsafe { Some(self.get_unchecked_mut(entity_id)) }
123    }
124
125    /// Returns an iterator over all components.
126    pub fn iter_mut(&'a mut self) -> IterMut<'a, C, &mut Self> {
127        IterMut {
128            entities_iter: self.entities.iter(),
129            data: self,
130            _ty: Default::default(),
131        }
132    }
133}
134
135impl<'a, C: Component + 'a> IntoIterator for ComponentStorageMut<'a, C> {
136    type Item = &'a mut C;
137    type IntoIter = IterMut<'a, C, ComponentStorageRef<'a, C>>;
138
139    /// Returns an iterator over all components.
140    fn into_iter(self) -> Self::IntoIter {
141        IterMut {
142            entities_iter: self.entities.iter(),
143            data: ComponentStorageRef {
144                entities: self.entities,
145                step: self.step,
146                info: self.info,
147                data: self.data,
148                _ty: Default::default(),
149            },
150            _ty: Default::default(),
151        }
152    }
153}
154
155#[derive(Clone)]
156pub struct Iter<'a, C, D> {
157    pub(crate) entities_iter: EntitiesIter<'a>,
158    pub(crate) data: D,
159    pub(crate) _ty: PhantomData<C>,
160}
161
162impl<'a, C, D> Iterator for Iter<'a, C, D>
163where
164    C: Component + 'a,
165    D: Borrow<ComponentStorageRef<'a, C>>,
166{
167    type Item = &'a C;
168
169    fn next(&mut self) -> Option<Self::Item> {
170        self.entities_iter
171            .next()
172            .map(|entity_id| unsafe { self.data.borrow().get_unchecked(entity_id) })
173    }
174}
175
176pub struct IterMut<'a, C, D> {
177    pub(crate) entities_iter: EntitiesIter<'a>,
178    pub(crate) data: D,
179    pub(crate) _ty: PhantomData<C>,
180}
181
182impl<'a, C, D> Iterator for IterMut<'a, C, D>
183where
184    C: Component + 'a,
185    D: Borrow<ComponentStorageRef<'a, C>>,
186{
187    type Item = &'a mut C;
188
189    fn next(&mut self) -> Option<Self::Item> {
190        self.entities_iter
191            .next()
192            .map(|entity_id| unsafe { self.data.borrow().get_mut_unsafe(entity_id) })
193    }
194}