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}