my_ecs/ecs/ent/
entity.rs

1use super::component::{ComponentKey, Components};
2use crate::{
3    ds::{BorrowResult, RawGetter, TypeInfo},
4    util::{macros::impl_from_for_enum, With},
5};
6use std::{any::TypeId, fmt, mem, mem::MaybeUninit, ops::Deref, ptr::NonNull, sync::Arc};
7
8/// A set of components.
9///
10/// Implementing this trait is not mandatory, but by doing so, the crate can
11/// provide you more easy to use APIs. Plus, there is a derive macro that have
12/// the same name, which help you implement this trait. As a consequence, it's
13/// encouraged to implement this trait by the derive macro about entity types
14/// that you know.
15#[allow(private_interfaces)]
16pub trait Entity: Components + Send + 'static {
17    type Ref<'cont>;
18    type Mut<'cont>;
19
20    /// Offsets in bytes of each field.
21    ///
22    /// See example below.
23    /// ```ignore
24    /// struct Entity {
25    ///     a: i32, // offset may be 0
26    ///     b: i8,  // offset may be 6
27    ///     c: i16, // offset may be 4
28    /// }
29    ///
30    /// // Implementors must define offsets like this.
31    /// // OFFSETS_BY_FIELD_INDEX = &[0, 6, 4]
32    /// ```
33    ///
34    /// # Safety
35    ///
36    /// Must be implemented correctly. Other methods depend on this offset with
37    /// unsafe blocks.
38    const OFFSETS_BY_FIELD_INDEX: &'static [usize];
39
40    /// Turns field index into column index.
41    ///
42    /// This function could be called frequently, so that it's recommended to
43    /// cache the mapping from field index to column index in a way.
44    ///
45    /// # Field index
46    ///
47    /// Field index is an index assigned to a field in the order it is declared.
48    ///
49    /// # Column index
50    ///
51    /// Column index is a terminology used in [`ContainEntity`]. In short, it is
52    /// an index sorted by [`ComponentKey`].
53    ///
54    /// # Safety
55    ///
56    /// Must be implemented correctly. Other methods depend on this offset with
57    /// unsafe blocks.
58    fn field_to_column_index(fi: usize) -> usize;
59
60    /// Turns column index into field index.
61    ///
62    /// This function would be called infrequently, so that simple
63    /// implementations would be good enough.
64    fn column_to_field_index(ci: usize) -> usize {
65        // Safety: Field index matches column index 1 by 1.
66        unsafe {
67            (0..Self::num_components())
68                .find(|&fi| Self::field_to_column_index(fi) == ci)
69                .unwrap_unchecked()
70        }
71    }
72
73    /// Returns a struct holding shared references to components that belong
74    /// to an entity for the given value index.
75    ///
76    /// Note, however, that entity is not stored as it is. It is split up into
77    /// its components then stored in each component container. That means
78    /// collecting those references like this function is inefficient because it
79    /// requires random access to memory.
80    ///
81    /// `derive(Entity)` macro gives us a similar struct to `Self`. You can
82    /// access each field via dot operator. Plus, it implements [`Debug`], so
83    /// that you can see how the entity looks like. But it will show some
84    /// components only that implement `Debug`. See examples below.
85    ///
86    /// # Panics
87    ///
88    /// Panics if the given value index is out of bounds.
89    ///
90    /// # Examples
91    ///
92    /// ```
93    /// use my_ecs::prelude::*;
94    /// use std::hash::RandomState;
95    ///
96    /// #[derive(Entity, Debug, PartialEq)]
97    /// struct Ea {
98    ///     ca: Ca,
99    ///     cb: Cb,
100    /// }
101    /// #[derive(Component, Debug, PartialEq)]
102    /// struct Ca(i32);
103    /// #[derive(Component, Debug, PartialEq)]
104    /// struct Cb(String);
105    ///
106    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
107    /// Ea::register_to(&mut cont);
108    /// Ea { ca: Ca(42), cb: Cb("cb".to_owned()) }.move_to(&mut cont);
109    ///
110    /// let e = Ea::get_ref_from(&cont, 0);
111    /// println!("{e:?}");
112    /// assert_eq!(e.ca, &Ca(42));
113    /// assert_eq!(e.cb, &Cb("cb".to_owned()));
114    /// ```
115    fn get_ref_from<Cont: ContainEntity + ?Sized>(cont: &Cont, vi: usize) -> Self::Ref<'_>;
116
117    /// Returns a struct holding mutable references to components that belong
118    /// to an entity for the given value index.
119    ///
120    /// Note, however, that entity is not stored as it is. It is split up into
121    /// its components then stored in each component container. That means
122    /// collecting those references like this function is inefficient because it
123    /// requires random access to memory.
124    ///
125    /// `derive(Entity)` macro gives us a similar struct to `Self`. You can
126    /// access each field via dot operator. Plus, it implements [`Debug`], so
127    /// that you can see how the entity looks like. But it will show some
128    /// components only that implement `Debug`. See examples below.
129    ///
130    /// # Panics
131    ///
132    /// Panics if the given value index is out of bounds.
133    ///
134    /// # Examples
135    ///
136    /// ```
137    /// use my_ecs::prelude::*;
138    /// use std::hash::RandomState;
139    ///
140    /// #[derive(Entity, Debug, PartialEq)]
141    /// struct Ea {
142    ///     ca: Ca,
143    ///     cb: Cb,
144    /// }
145    /// #[derive(Component, Debug, PartialEq)]
146    /// struct Ca(i32);
147    /// #[derive(Component, Debug, PartialEq)]
148    /// struct Cb(String);
149    ///
150    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
151    /// Ea::register_to(&mut cont);
152    /// Ea { ca: Ca(1), cb: Cb("2".to_owned()) }.move_to(&mut cont);
153    ///
154    /// let e = Ea::get_mut_from(&mut cont, 0);
155    /// println!("{e:?}");
156    /// assert_eq!(e.ca, &Ca(1));
157    /// assert_eq!(e.cb, &Cb("2".to_owned()));
158    ///
159    /// *e.ca = Ca(3);
160    /// *e.cb = Cb("4".to_owned());
161    ///
162    /// let e = Ea::get_ref_from(&cont, 0);
163    /// assert_eq!(e.ca, &Ca(3));
164    /// assert_eq!(e.cb, &Cb("4".to_owned()));
165    /// ```
166    fn get_mut_from<Cont: ContainEntity + ?Sized>(cont: &mut Cont, vi: usize) -> Self::Mut<'_>;
167
168    /// Returns entity key of the entity type.
169    //
170    // TODO: Arc is not shared with the Arc inside of entity container.
171    // But we need to generate sorted component keys as an entity key.
172    #[doc(hidden)]
173    fn key() -> EntityKey {
174        let ckeys: Arc<[ComponentKey]> = (0..Self::num_components())
175            .map(|ci| {
176                let fi = Self::column_to_field_index(ci);
177                Self::keys().as_ref()[fi]
178            })
179            .collect();
180        EntityKey::Ckeys(ckeys)
181    }
182
183    /// Returns number of components.
184    fn num_components() -> usize {
185        Self::LEN
186    }
187
188    /// Returns a pointer to a component in this entity for the given field
189    /// index.
190    ///
191    /// # Panics
192    ///
193    /// Panics if the given index is out of bounds.
194    fn component_ptr(&self, fi: usize) -> NonNull<u8> {
195        let base_ptr = (self as *const Self as *const u8).cast_mut();
196        // Safety: Calculated from OFFSETS_BY_FIELD_INDEX.
197        unsafe {
198            let ptr = base_ptr.add(Self::OFFSETS_BY_FIELD_INDEX[fi]);
199            NonNull::new_unchecked(ptr)
200        }
201    }
202
203    /// Registers components in this entity to an entity container.
204    ///
205    /// # Panics
206    ///
207    /// Panics if the given entity container has registered columns in it.
208    fn register_to<Cont: ContainEntity + ?Sized>(cont: &mut Cont) {
209        assert_eq!(cont.num_columns(), 0);
210
211        // Registers component column in the sorted order by component key.
212        for ci in 0..Self::num_components() {
213            let fi = Self::column_to_field_index(ci);
214            let tinfo = Self::infos().as_ref()[fi];
215            cont.add_column(tinfo);
216        }
217    }
218
219    /// Moves the entity to an entity container then returns row index to the
220    /// moved entity.
221    ///
222    /// # How to move
223    ///
224    /// Use [`AddEntity::begin_add_row`], [`AddEntity::add_value`], and
225    /// [`AddEntity::end_add_row`], then forget self.
226    ///
227    /// # Examples
228    ///
229    /// ```
230    /// use my_ecs::prelude::*;
231    /// use std::hash::RandomState;
232    ///
233    /// #[derive(Entity, Debug, PartialEq)]
234    /// struct Ea {
235    ///     ca: Ca,
236    ///     cb: Cb,
237    /// }
238    /// #[derive(Component, Debug, PartialEq)]
239    /// struct Ca(i32);
240    /// #[derive(Component, Debug, PartialEq)]
241    /// struct Cb(String);
242    ///
243    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
244    /// Ea::register_to(&mut cont);
245    /// Ea { ca: Ca(42), cb: Cb("cb".to_owned()) }.move_to(&mut cont);
246    /// assert_eq!(cont.len(), 1);
247    /// ```
248    fn move_to<Cont: ContainEntity + ?Sized>(self, cont: &mut Cont) -> usize
249    where
250        Self: Sized,
251    {
252        cont.begin_add_row();
253
254        for fi in 0..Self::num_components() {
255            let ci = Self::field_to_column_index(fi);
256            // Safety:
257            // - Column index and value pointer are gotten client impl.
258            // - We're going to forget `self`.
259            unsafe { cont.add_value(ci, self.component_ptr(fi)) };
260        }
261
262        #[allow(clippy::forget_non_drop)]
263        mem::forget(self);
264
265        // Safety: Inserted all columns.
266        unsafe { cont.end_add_row() }
267    }
268
269    /// Removes an entity for the given value index from an entity container
270    /// then returns the entity.
271    ///
272    /// See [`ContainEntity`] document when you need to know what value index
273    /// is.
274    ///
275    /// # Panics
276    ///
277    /// Panics if the given value index is out of bounds.
278    ///
279    /// # Examples
280    ///
281    /// ```
282    /// use my_ecs::prelude::*;
283    /// use std::hash::RandomState;
284    ///
285    /// #[derive(Entity, Debug, PartialEq)]
286    /// struct Ea {
287    ///     ca: Ca,
288    ///     cb: Cb,
289    /// }
290    /// #[derive(Component, Debug, PartialEq)]
291    /// struct Ca(i32);
292    /// #[derive(Component, Debug, PartialEq)]
293    /// struct Cb(String);
294    ///
295    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
296    /// Ea::register_to(&mut cont);
297    /// Ea { ca: Ca(42), cb: Cb("cb".to_owned()) }.move_to(&mut cont);
298    /// let e = Ea::take_from(&mut cont, 0);
299    /// assert_eq!(e, Ea { ca: Ca(42), cb: Cb("cb".to_owned()) });
300    /// ```
301    fn take_from<Cont: ContainEntity + ?Sized>(cont: &mut Cont, vi: usize) -> Self
302    where
303        Self: Sized,
304    {
305        assert!(vi < cont.len());
306
307        let mut this: MaybeUninit<Self> = MaybeUninit::uninit();
308        let base_ptr = this.as_mut_ptr() as *mut u8;
309
310        unsafe {
311            cont.begin_remove_row_by_value_index(vi);
312            for fi in 0..Self::num_components() {
313                let comp_ptr = base_ptr.add(Self::OFFSETS_BY_FIELD_INDEX[fi]);
314                let comp_ptr = NonNull::new_unchecked(comp_ptr);
315                let ci = Self::field_to_column_index(fi);
316                cont.remove_value_by_value_index(ci, vi, comp_ptr);
317            }
318            cont.end_remove_row_by_value_index(vi);
319
320            this.assume_init()
321        }
322    }
323}
324
325/// A trait for collecting heterogeneous component types.
326///
327/// In this trait, each component type is gathered in each component column and
328/// all columns have the same length so that it looks like 2d matrix.
329///
330/// When it comes to in & out types, this trait has intentionally raw pointer
331/// parameters not to use generic for object safety. So that you can hold
332/// various sorts of entity container in a single variable.
333///
334/// # Index system
335///
336/// There are three index systems for this trait.
337///
338/// The first one is 'column index' which is for pointing a certain component
339/// column. When you add or remove component column from an entity container,
340/// you will get or need this column index. Column indices starts with 0 and
341/// increases by 1 as you put in a component column. To avoid confusion, column
342/// must be added in a sorted order by [`ComponentKey`].
343///
344/// The second and third index systems are related to pointing a certain entity
345/// in an entity container. In other words, you need one of those index systems
346/// when you need access to a single entity.
347///
348/// Second one is 'row index' which is a kind of outer index for each entity.
349/// You will get this row index when you put your entity in an entity container.
350/// Also, you can remove an entity using the row index. Row indices may not be
351/// in order and not consecutive.
352///
353/// The last one is 'value index' which is inner index for each entity. In
354/// contrast to former one, value indices are in order and consecutive like
355/// indices on a slice. Plus, all component columns follows the same value
356/// indices in an entity container.
357///
358/// Take a look at example below.
359///
360/// ```text
361///              column index      0        1
362/// --------------------------------------------
363/// | row index | value index | comp_a | comp_b |
364/// |     0     |      0      |    .   |    .   |
365/// |     4     |      1      |    .   |    .   |
366/// |     2     |      2      |    .   |    .   |
367/// ```
368///
369/// # Examples
370///
371/// ```
372/// use my_ecs::prelude::*;
373/// use std::{hash::RandomState, ptr::NonNull};
374///
375/// #[derive(Entity)]
376/// struct Entity {
377///     a: Ca,
378///     b: Cb,
379/// }
380/// #[derive(Component)]
381/// struct Ca(i32);
382/// #[derive(Component)]
383/// struct Cb(i32);
384///
385/// let mut cont: SparseSet<RandomState> = SparseSet::new();
386///
387/// // Adds component columns.
388/// let ci_a = cont.add_column(tinfo!(Ca)).unwrap();
389/// let ci_b = cont.add_column(tinfo!(Cb)).unwrap();
390///
391/// // Adds component values for the entity.
392/// cont.begin_add_row();
393/// let ri = unsafe {
394///     let ptr = NonNull::new(&mut Ca(4) as *mut Ca as *mut u8).unwrap();
395///     cont.add_value(ci_a, ptr);
396///     let ptr = NonNull::new(&mut Cb(2) as *mut Cb as *mut u8).unwrap();
397///     cont.add_value(ci_b, ptr);
398///     cont.end_add_row()
399/// };
400/// assert_eq!(cont.len(), 1);
401///
402/// // Borrows component columns and test them if they are as we expected.
403/// let col_a = cont.borrow_column(ci_a).unwrap();
404/// let col_b = cont.borrow_column(ci_b).unwrap();
405/// unsafe {
406///     let ptr = col_a.get(0).unwrap();
407///     assert_eq!(*ptr.as_ref(), 4);
408///     let ptr = col_b.get(0).unwrap();
409///     assert_eq!(*ptr.as_ref(), 2);
410/// }
411/// drop(col_a);
412/// drop(col_b);
413///
414/// // Removes the entity we just put.
415/// let is_removed = cont.remove_row(ri);
416/// assert!(is_removed);
417/// assert_eq!(cont.len(), 0);
418/// ```
419//
420// Must object safe.
421#[allow(clippy::len_without_is_empty)]
422pub trait ContainEntity: RegisterComponent + BorrowComponent + AddEntity {
423    /// Creates a new entity container that has the same component types without
424    /// component values.
425    ///
426    /// In other words, the copied container doesn't have any entities in it. So
427    /// it's empty.
428    ///
429    /// # Examples
430    ///
431    /// ```
432    /// use my_ecs::prelude::*;
433    /// use std::{hash::RandomState, ptr::NonNull, any::TypeId};
434    ///
435    /// #[derive(Entity)]
436    /// struct Entity {
437    ///     a: Ca,
438    /// }
439    /// #[derive(Component)]
440    /// struct Ca(i32);
441    ///
442    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
443    /// let ci = cont.add_column(tinfo!(Ca)).unwrap();
444    ///
445    /// // Adds component values for an entity.
446    /// cont.begin_add_row();
447    /// unsafe {
448    ///     let ptr = NonNull::new(&mut Ca(0) as *mut Ca as *mut u8).unwrap();
449    ///     cont.add_value(ci, ptr);
450    ///     cont.end_add_row();
451    /// }
452    /// assert_eq!(cont.len(), 1);
453    ///
454    /// let twin = cont.create_twin();
455    /// assert_eq!(twin.len(), 0);
456    /// assert!(twin.contains_column(&TypeId::of::<Ca>()));
457    /// ```
458    fn create_twin(&self) -> Box<dyn ContainEntity>;
459
460    /// Retrieves an entity for the given component column index and row index
461    /// from the entity container.
462    ///
463    /// If one of two indices is out of bounds, returns `None`.
464    fn get_item_mut(&mut self, ci: usize, ri: usize) -> Option<NonNull<u8>>;
465
466    /// Returns number of entities in the entity container.
467    ///
468    /// # Examples
469    ///
470    /// See [`ContainEntity`] document.
471    fn len(&self) -> usize;
472
473    /// Returns capacity of the entity container.
474    ///
475    /// But if entity container doesn't support getting capacity, it returns
476    /// number of entities instead.
477    ///
478    /// # Examples
479    ///
480    /// See [`ContainEntity::reserve`] document.
481    fn capacity(&self) -> usize;
482
483    /// May reserve at least `additional` extra capacity.
484    ///
485    /// This method doesn't guarantee definite extension of capacity. It depends
486    /// on implementations.
487    ///
488    /// # Examples
489    ///
490    /// ```
491    /// use my_ecs::prelude::*;
492    /// use std::{hash::RandomState, ptr::NonNull, any::TypeId};
493    ///
494    /// #[derive(Entity)]
495    /// struct Entity {
496    ///     a: Ca,
497    /// }
498    /// #[derive(Component)]
499    /// struct Ca(i32);
500    ///
501    /// // SparseSet supports capacity.
502    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
503    /// cont.add_column(tinfo!(Ca)).unwrap();
504    /// assert_eq!(cont.capacity(), 0);
505    ///
506    /// cont.reserve(10);
507    /// assert!(cont.capacity() >= 10);
508    ///
509    /// cont.shrink_to_fit();
510    /// assert_eq!(cont.capacity(), 0);
511    /// ```
512    fn reserve(&mut self, additional: usize);
513
514    /// May shrink capacity of the entity container as much as possible.
515    ///
516    /// This method doesn't guarantee definite removal of extra capacity. It
517    /// depends on implementations.
518    ///
519    /// # Examples
520    ///
521    /// See [`ContainEntity::reserve`] document.
522    fn shrink_to_fit(&mut self);
523
524    /// # Panics
525    ///
526    /// Panics if
527    /// - Column index `ci` is out of bounds.
528    /// - Column type is not [`Clone`].
529    ///
530    /// # Safety
531    ///
532    /// Undefined behavior if
533    /// - Pointer to a value `val_ptr` is not a valid pointer for the column's
534    ///   type.
535    /// - After calling this method on columns in an entity container, any of
536    ///   columns doesn't have the same length.
537    unsafe fn resize_column(&mut self, ci: usize, new_len: usize, val_ptr: NonNull<u8>);
538}
539
540/// A trait for adding or removing component types from an entity container.
541///
542/// See [`ContainEntity`] for more information.
543//
544// Must object safe.
545pub trait RegisterComponent {
546    /// Adds a component column to the entity container then returns column
547    /// index.
548    ///
549    /// But the entity container failed to add new entity for some reason,
550    /// returns `None`. You can get [`TypeInfo`] from any static types using
551    /// [`tinfo`](crate::tinfo) macro.
552    ///
553    /// Column index is guaranteed to be increased one by one from zero
554    /// whenever you call this method, which means you can get column index
555    /// from order you added components.
556    ///
557    /// # Examples
558    ///
559    /// ```
560    /// use my_ecs::prelude::*;
561    /// use std::{hash::RandomState, any::TypeId};
562    ///
563    /// #[derive(Component)]
564    /// struct Ca;
565    ///
566    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
567    ///
568    /// cont.add_column(tinfo!(Ca));
569    /// assert!(cont.contains_column(&TypeId::of::<Ca>()));
570    ///
571    /// // Duplicated component columns are not allowed.
572    /// let ret = cont.add_column(tinfo!(Ca));
573    /// assert!(ret.is_none());
574    /// ```
575    fn add_column(&mut self, tinfo: TypeInfo) -> Option<usize>;
576
577    /// Removes the component column from the entity container.
578    ///
579    /// If removal is successful, returns [`TypeInfo`] of the removed component
580    /// column. But if the entity container doesn't have component column for
581    /// the given column index, returns `None`.
582    ///
583    /// # Examples
584    ///
585    /// ```
586    /// use my_ecs::prelude::*;
587    /// use std::{hash::RandomState, any::TypeId};
588    ///
589    /// #[derive(Component)]
590    /// struct Ca;
591    ///
592    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
593    ///
594    /// let col_idx = cont.add_column(tinfo!(Ca)).unwrap();
595    /// assert!(cont.contains_column(&TypeId::of::<Ca>()));
596    ///
597    /// let tinfo = cont.remove_column(col_idx);
598    /// assert_eq!(tinfo, Some(tinfo!(Ca)));
599    /// assert!(!cont.contains_column(&TypeId::of::<Ca>()));
600    /// ```
601    fn remove_column(&mut self, ci: usize) -> Option<TypeInfo>;
602
603    /// Retrieves column index for the given component type.
604    ///
605    /// If there is not the component column in the entity container, returns
606    /// `None`
607    ///
608    /// # Examples
609    ///
610    /// ```
611    /// use my_ecs::prelude::*;
612    /// use std::{hash::RandomState, any::TypeId};
613    ///
614    /// #[derive(Component)]
615    /// struct Ca;
616    /// #[derive(Component)]
617    /// struct Cb;
618    ///
619    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
620    ///
621    /// let col_idx = cont.add_column(tinfo!(Ca)).unwrap();
622    /// assert_eq!(cont.get_column_index(&TypeId::of::<Ca>()).unwrap(), col_idx);
623    ///
624    /// assert!(cont.get_column_index(&TypeId::of::<Cb>()).is_none());
625    /// ```
626    fn get_column_index(&self, ty: &TypeId) -> Option<usize>;
627
628    /// Retrieves [`TypeInfo`] of the component for the given column index.
629    ///
630    /// If there is not the component column in the entity container, returns
631    /// `None`
632    ///
633    /// # Examples
634    ///
635    /// ```
636    /// use my_ecs::prelude::*;
637    /// use std::hash::RandomState;
638    ///
639    /// #[derive(Component)]
640    /// struct Ca;
641    ///
642    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
643    ///
644    /// let col_idx = cont.add_column(tinfo!(Ca)).unwrap();
645    /// let tinfo = cont.get_column_info(col_idx);
646    /// assert_eq!(tinfo, Some(&tinfo!(Ca)));
647    /// ```
648    fn get_column_info(&self, ci: usize) -> Option<&TypeInfo>;
649
650    /// Retrieves number of component columns in the entity container.
651    ///
652    /// # Examples
653    ///
654    /// ```
655    /// use my_ecs::prelude::*;
656    /// use std::hash::RandomState;
657    ///
658    /// #[derive(Component)]
659    /// struct Ca;
660    /// #[derive(Component)]
661    /// struct Cb;
662    ///
663    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
664    /// assert_eq!(cont.num_columns(), 0);
665    ///
666    /// cont.add_column(tinfo!(Ca));
667    /// assert_eq!(cont.num_columns(), 1);
668    /// cont.add_column(tinfo!(Cb));
669    /// assert_eq!(cont.num_columns(), 2);
670    /// ```
671    fn num_columns(&self) -> usize;
672
673    /// Returns true if the entity container contains given component type.
674    ///
675    /// # Examples
676    ///
677    /// ```
678    /// use my_ecs::prelude::*;
679    /// use std::{hash::RandomState, any::TypeId};
680    ///
681    /// #[derive(Component)]
682    /// struct Ca;
683    ///
684    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
685    /// assert!(!cont.contains_column(&TypeId::of::<Ca>()));
686    ///
687    /// cont.add_column(tinfo!(Ca));
688    /// assert!(cont.contains_column(&TypeId::of::<Ca>()));
689    /// ```
690    fn contains_column(&self, ty: &TypeId) -> bool {
691        self.get_column_index(ty).is_some()
692    }
693}
694
695/// A trait for borrowing a component column from an entity container.
696///
697/// See [`ContainEntity`] for more information.
698//
699// Must object safe.
700pub trait BorrowComponent {
701    /// Borrows component column for the given column index.
702    ///
703    /// If borrow is successful, returns [`RawGetter`] of the component column.
704    /// Otherwise, returns [`BorrowError`](crate::ds::BorrowError).
705    ///
706    /// # Examples
707    ///
708    /// ```
709    /// use my_ecs::prelude::*;
710    /// use std::{hash::RandomState, any::TypeId};
711    ///
712    /// #[derive(Component)]
713    /// struct Ca;
714    ///
715    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
716    /// cont.add_column(tinfo!(Ca));
717    ///
718    /// let col_idx = cont.get_column_index(&TypeId::of::<Ca>()).unwrap();
719    /// let getter = cont.borrow_column(col_idx).unwrap();
720    /// ```
721    fn borrow_column(&self, ci: usize) -> BorrowResult<RawGetter>;
722
723    /// Borrows component column mutably for the given column index.
724    ///
725    /// If borrow is successful, returns [`RawGetter`] of the component column.
726    /// Otherwise, returns [`BorrowError`](crate::ds::BorrowError).
727    ///
728    /// # Examples
729    ///
730    /// ```
731    /// use my_ecs::prelude::*;
732    /// use std::{hash::RandomState, any::TypeId};
733    ///
734    /// #[derive(Component)]
735    /// struct Ca;
736    ///
737    /// let mut cont: SparseSet<RandomState> = SparseSet::new();
738    /// cont.add_column(tinfo!(Ca));
739    ///
740    /// let col_idx = cont.get_column_index(&TypeId::of::<Ca>()).unwrap();
741    /// let getter = cont.borrow_column_mut(col_idx).unwrap();
742    /// ```
743    fn borrow_column_mut(&mut self, ci: usize) -> BorrowResult<RawGetter>;
744
745    /// Retrieves component column pointer for the given column index.
746    ///
747    /// If there is not the component column in the entity container, returns
748    /// `None`
749    ///
750    /// # Safety
751    ///
752    /// Undefined behavior if exclusive borrow happened before.
753    unsafe fn get_column(&self, ci: usize) -> Option<NonNull<u8>>;
754}
755
756/// A trait for adding or removing component values from an entity container.
757///
758/// See [`ContainEntity`] for more information.
759//
760// Must object safe.
761pub trait AddEntity: RegisterComponent {
762    /// Converts given row index to value index.
763    fn to_value_index(&self, ri: usize) -> Option<usize>;
764
765    /// Starts inserting component values of an entity to the entity container.
766    ///
767    /// # Panics
768    ///
769    /// May panic if any component columns were borrowed and not returned yet.
770    /// But implementations must guarantee that one of
771    /// [`AddEntity::begin_add_row`], [`AddEntity::add_value`], and
772    /// [`AddEntity::end_add_row`] panics if borrowed component column is
773    /// detected.
774    ///
775    /// # Safety
776    ///
777    /// This method must be followed by [`AddEntity::add_value`] and
778    /// [`AddEntity::end_add_row`].
779    ///
780    /// # Examples
781    ///
782    /// See [`ContainEntity`] document.
783    fn begin_add_row(&mut self);
784
785    /// Inserts a component value of an entity in the entity container.
786    ///
787    /// This method creates a bitwise copy of the value, so that caller must not
788    /// access the value in any ways including its drop procedure after calling
789    /// this method.
790    ///
791    /// # Panics
792    ///
793    /// See [`AddEntity::begin_add_row`] document.
794    ///
795    /// # Safety
796    ///
797    /// Caller must guarantee
798    /// - This method must be called between [`AddEntity::begin_add_row`] and
799    ///   [`AddEntity::end_add_row`] for all components.
800    /// - Column index `ci` is not out of bounds.
801    /// - Value pointer `val_ptr` is valid for the component column type.
802    /// - Value must not be accessed after calling this method even `drop()`.
803    ///
804    /// # Examples
805    ///
806    /// See [`ContainEntity`] document.
807    unsafe fn add_value(&mut self, ci: usize, val_ptr: NonNull<u8>);
808
809    /// Finishes inserting component values of an entity in the entity
810    /// container then returns row index to the inserted entity.
811    ///
812    /// # Panics
813    ///
814    /// See [`AddEntity::begin_add_row`] document.
815    ///
816    /// # Safety
817    ///
818    /// Caller must have called [`AddEntity::begin_add_row`] once and
819    /// [`AddEntity::add_value`] number of component columns times before
820    /// calling to this method for just one entity.
821    ///
822    /// # Examples
823    ///
824    /// See [`ContainEntity`] document.
825    unsafe fn end_add_row(&mut self) -> usize;
826
827    /// Retrieves a pointer to a component value for the given column and value
828    /// indices.
829    ///
830    /// If the given index is out of bounds, returns None.
831    fn value_ptr_by_value_index(&self, ci: usize, vi: usize) -> Option<NonNull<u8>>;
832
833    /// Removes an entity for the given row index from the entity container.
834    ///
835    /// If removal is successful, returns true. Otherwise, for instance index
836    /// is out of bounds, returns false.
837    ///
838    /// # Examples
839    ///
840    /// See [`ContainEntity`] document.
841    fn remove_row(&mut self, ri: usize) -> bool {
842        if let Some(vi) = self.to_value_index(ri) {
843            self.remove_row_by_value_index(vi);
844            true
845        } else {
846            false
847        }
848    }
849
850    /// Removes an entity for the given value index from the entity container.
851    ///
852    /// # Panics
853    ///
854    /// Panics if the given value index is out of bounds.
855    fn remove_row_by_value_index(&mut self, vi: usize) {
856        unsafe {
857            self.begin_remove_row_by_value_index(vi);
858            for ci in 0..self.num_columns() {
859                self.drop_value_by_value_index(ci, vi);
860            }
861            self.end_remove_row_by_value_index(vi);
862        }
863    }
864
865    /// Starts removing component values of an entity from the entity container.
866    ///
867    /// # Panics
868    ///
869    /// May panic if any component columns were borrowed and not returned yet.
870    /// But implementations must guarantee that one of methods below panic if
871    /// borrowed component column is detected.
872    /// - [`AddEntity::begin_remove_row_by_value_index`]
873    /// - [`AddEntity::remove_value_by_value_index`]
874    /// - [`AddEntity::drop_value_by_value_index`]
875    /// - [`AddEntity::forget_value_by_value_index`]
876    /// - [`AddEntity::end_remove_row_by_value_index`]
877    ///
878    /// # Safety
879    ///
880    /// Caller must guarantee
881    /// - This method must be followed by
882    ///   [`AddEntity::remove_value_by_value_index`] and
883    ///   [`AddEntity::end_remove_row_by_value_index`].
884    ///   [`AddEntity::remove_value_by_value_index`] can be replaced by
885    ///   [`AddEntity::drop_value_by_value_index`] or
886    ///   [`AddEntity::forget_value_by_value_index`].
887    /// - Value index `vi` is not out of bounds.
888    unsafe fn begin_remove_row_by_value_index(&mut self, vi: usize);
889
890    /// Removes a component value of an entity in the entity container then
891    /// write it to the given buffer.
892    ///
893    /// Caller must choose one of methods below to take a component value out.
894    /// - [`AddEntity::remove_value_by_value_index`].
895    /// - [`AddEntity::drop_value_by_value_index`].
896    /// - [`AddEntity::forget_value_by_value_index`].
897    ///
898    /// # Panics
899    ///
900    /// See [`AddEntity::begin_remove_row_by_value_index`] document.
901    ///
902    /// # Safety
903    ///
904    /// Caller must guarantee
905    /// - This method must be called between
906    ///   [`AddEntity::remove_value_by_value_index`] and
907    ///   [`AddEntity::end_remove_row_by_value_index`] for all components.
908    /// - Column index `ci` is not out of bounds.
909    /// - Value index `vi` is not out of bounds.
910    /// - Buffer `buf` has sufficient capacity for the component value.
911    unsafe fn remove_value_by_value_index(&mut self, ci: usize, vi: usize, buf: NonNull<u8>);
912
913    /// Drops a component value of an entity in the entity container.
914    ///
915    /// Caller must choose one of methods below to take a component value out.
916    /// - [`AddEntity::remove_value_by_value_index`].
917    /// - [`AddEntity::drop_value_by_value_index`].
918    /// - [`AddEntity::forget_value_by_value_index`].
919    ///
920    /// # Panics
921    ///
922    /// See [`AddEntity::begin_remove_row_by_value_index`] document.
923    ///
924    /// # Safety
925    ///
926    /// Caller must guarantee
927    /// - This method must be called between
928    ///   [`AddEntity::remove_value_by_value_index`] and
929    ///   [`AddEntity::end_remove_row_by_value_index`] for all components.
930    /// - Column index `ci` is not out of bounds.
931    /// - Value index `vi` is not out of bounds.
932    unsafe fn drop_value_by_value_index(&mut self, ci: usize, vi: usize);
933
934    /// Removes and forgets a component value of an entity in the entity
935    /// container.
936    ///
937    /// Caller must choose one of methods below to take a component value out.
938    /// - [`AddEntity::remove_value_by_value_index`].
939    /// - [`AddEntity::drop_value_by_value_index`].
940    /// - [`AddEntity::forget_value_by_value_index`].
941    ///
942    /// # Panics
943    ///
944    /// See [`AddEntity::begin_remove_row_by_value_index`] document.
945    ///
946    /// # Safety
947    ///
948    /// See [`AddEntity::drop_value_by_value_index`].
949    unsafe fn forget_value_by_value_index(&mut self, ci: usize, vi: usize);
950
951    /// Finishes removing component values of an entity in the entity container.
952    ///
953    /// # Panics
954    ///
955    /// See [`AddEntity::begin_remove_row_by_value_index`] document.
956    ///
957    /// # Safety
958    ///
959    /// Caller must guarantee
960    /// - Caller must have called [`AddEntity::begin_remove_row_by_value_index`]
961    ///   once and [`AddEntity::remove_value_by_value_index`] number of
962    ///   component columns times before calling to this method for just one
963    ///   entity.
964    /// - Value index `vi` is not out of bounds.
965    unsafe fn end_remove_row_by_value_index(&mut self, vi: usize);
966}
967
968/// A specific entity identifier.
969#[derive(Clone, Copy, PartialEq, Eq, Hash)]
970pub struct EntityId {
971    /// Index to a specific entity container.
972    ei: EntityIndex,
973
974    /// Row index to an entity in an entity container.
975    ///
976    /// Row index is defined in [`ContainEntity`] document.
977    ri: usize,
978}
979
980impl EntityId {
981    pub const fn new(ei: EntityIndex, ri: usize) -> Self {
982        Self { ei, ri }
983    }
984
985    pub const fn container_index(&self) -> EntityIndex {
986        self.ei
987    }
988
989    pub const fn row_index(&self) -> usize {
990        self.ri
991    }
992}
993
994impl fmt::Display for EntityId {
995    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
996        write!(f, "({}, {})", self.ei.index(), self.ri)
997    }
998}
999
1000impl fmt::Debug for EntityId {
1001    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1002        f.debug_struct("EntityId")
1003            .field("gen", &self.ei.generation())
1004            .field("ei", &self.ei.index())
1005            .field("ri", &self.ri)
1006            .finish()
1007    }
1008}
1009
1010/// Key for the map [`EntityStorage`] in order to get value [`EntityContainer`].
1011/// `EntityStorage` provides some access ways shown below.
1012/// - Index: Entity container index and generation when the container is generated.
1013/// - Name: Unique name for the entity. Each entity must have its name.
1014/// - Type: If the entity is declared statically, it has its own type.
1015#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1016pub(crate) enum EntityKey {
1017    /// Component keys, another type of [`TypeId`], that belong to an entity.
1018    ///
1019    /// Searching an entity container using component keys always succeeds if
1020    /// the keys are valid. In searching, component keys must be sorted and
1021    /// deduplicated.
1022    Ckeys(Arc<[ComponentKey]>),
1023
1024    /// Index to an entity container.
1025    ///
1026    /// Searching an entity container using entity index always succeeds if
1027    /// the index is valid.
1028    Index(EntityIndex),
1029
1030    /// Name of an entity container.
1031    ///
1032    /// Entity container may not have its name. In this casa, it fails to search
1033    /// an entity container using entity name.
1034    Name(EntityName),
1035}
1036
1037impl_from_for_enum!("outer" = EntityKey; "var" = Ckeys; "inner" = Arc<[ComponentKey]>);
1038impl_from_for_enum!("outer" = EntityKey; "var" = Index; "inner" = EntityIndex);
1039impl_from_for_enum!("outer" = EntityKey; "var" = Name; "inner" = EntityName);
1040
1041impl EntityKey {
1042    pub(crate) fn index(&self) -> &EntityIndex {
1043        self.try_into().unwrap()
1044    }
1045
1046    pub(crate) fn get_ref(&self) -> EntityKeyRef<'_> {
1047        match self {
1048            Self::Index(ei) => EntityKeyRef::Index(ei),
1049            Self::Ckeys(ckeys) => EntityKeyRef::Ckeys(ckeys),
1050            Self::Name(name) => EntityKeyRef::Name(name),
1051        }
1052    }
1053}
1054
1055impl<'r> From<&'r EntityKey> for EntityKeyRef<'r> {
1056    fn from(value: &'r EntityKey) -> Self {
1057        value.get_ref()
1058    }
1059}
1060
1061#[derive(Debug, Clone, Copy)]
1062pub(crate) enum EntityKeyRef<'r> {
1063    Ckeys(&'r [ComponentKey]),
1064    Index(&'r EntityIndex),
1065    Name(&'r str),
1066}
1067
1068impl_from_for_enum!(
1069    "lifetimes" = 'r;
1070    "outer" = EntityKeyRef; "var" = Ckeys; "inner" = &'r [ComponentKey]
1071);
1072impl_from_for_enum!(
1073    "lifetimes" = 'r;
1074    "outer" = EntityKeyRef; "var" = Index; "inner" = &'r EntityIndex
1075);
1076impl_from_for_enum!(
1077    "lifetimes" = 'r;
1078    "outer" = EntityKeyRef; "var" = Name; "inner" = &'r str
1079);
1080
1081/// Index to a specific entity container.
1082#[derive(Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
1083#[repr(transparent)]
1084pub struct EntityIndex(With<usize, u64>);
1085
1086impl EntityIndex {
1087    const DUMMY: Self = Self(With::new(usize::MAX, u64::MAX));
1088
1089    pub(crate) const fn new(index: With<usize, u64>) -> Self {
1090        Self(index)
1091    }
1092
1093    pub(crate) const fn dummy() -> Self {
1094        Self::DUMMY
1095    }
1096
1097    pub fn index(&self) -> usize {
1098        self.0.value
1099    }
1100
1101    pub fn generation(&self) -> u64 {
1102        self.0.with
1103    }
1104}
1105
1106impl Default for EntityIndex {
1107    fn default() -> Self {
1108        Self::dummy()
1109    }
1110}
1111
1112impl fmt::Display for EntityIndex {
1113    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1114        self.0.fmt(f)
1115    }
1116}
1117
1118/// Unique entity name.
1119///
1120/// An entity container can be distinguished by its name, so in other words, it
1121/// must be unique.
1122#[derive(Hash, PartialEq, Eq, Clone, Debug)]
1123#[repr(transparent)]
1124pub struct EntityName(Arc<str>);
1125
1126impl EntityName {
1127    pub const fn new(name: Arc<str>) -> Self {
1128        Self(name)
1129    }
1130}
1131
1132impl Deref for EntityName {
1133    type Target = str;
1134
1135    fn deref(&self) -> &Self::Target {
1136        &self.0
1137    }
1138}
1139
1140impl std::borrow::Borrow<str> for EntityName {
1141    fn borrow(&self) -> &str {
1142        self
1143    }
1144}
1145
1146impl fmt::Display for EntityName {
1147    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1148        (**self).fmt(f)
1149    }
1150}
1151
1152#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
1153pub(crate) enum EntityKeyKind {
1154    /// Corresponds to [`EntityKey::Index`].
1155    Index,
1156    /// Corresponds to [`EntityKey::Ckeys`].
1157    Ckeys,
1158    /// Corresponds to [`EntityKey::Name`].
1159    Name,
1160}
1161
1162impl From<&EntityKey> for EntityKeyKind {
1163    fn from(value: &EntityKey) -> Self {
1164        match value {
1165            EntityKey::Index(..) => Self::Index,
1166            EntityKey::Ckeys(..) => Self::Ckeys,
1167            EntityKey::Name(..) => Self::Name,
1168        }
1169    }
1170}
1171
1172/// A piece of information about an entity such as entity index, name, and its components.
1173#[derive(Eq)]
1174pub struct EntityTag {
1175    index: EntityIndex,
1176
1177    /// Optional entity name.
1178    name: Option<EntityName>,
1179
1180    /// Sorted component keys.
1181    ///
1182    /// Note that this is sorted, so that index may be different with colum
1183    /// index used in [`Self::cont`].
1184    ckeys: Arc<[ComponentKey]>,
1185
1186    /// Corresponding component names to component keys.
1187    cnames: Box<[&'static str]>,
1188}
1189
1190impl fmt::Debug for EntityTag {
1191    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1192        f.debug_struct("EntityTag")
1193            .field("index", &self.index())
1194            .field("name", &self.get_name())
1195            .field("ckeys", &self.get_component_keys())
1196            .field("cnames", &self.get_component_names())
1197            .finish()
1198    }
1199}
1200
1201impl EntityTag {
1202    pub(crate) fn new(
1203        index: EntityIndex,
1204        name: Option<EntityName>,
1205        ckeys: Arc<[ComponentKey]>,
1206        cnames: Box<[&'static str]>,
1207    ) -> Self {
1208        assert_eq!(ckeys.len(), ckeys.len());
1209
1210        Self {
1211            index,
1212            name,
1213            ckeys,
1214            cnames,
1215        }
1216    }
1217
1218    pub(crate) const fn index(&self) -> EntityIndex {
1219        self.index
1220    }
1221
1222    pub const fn get_name(&self) -> Option<&EntityName> {
1223        self.name.as_ref()
1224    }
1225
1226    pub(crate) const fn get_component_keys(&self) -> &Arc<[ComponentKey]> {
1227        &self.ckeys
1228    }
1229
1230    pub const fn get_component_names(&self) -> &[&'static str] {
1231        &self.cnames
1232    }
1233}
1234
1235impl PartialEq for EntityTag {
1236    fn eq(&self, other: &Self) -> bool {
1237        self.index() == other.index()
1238    }
1239}