despero_hecs/
take.rs

1use alloc::vec::Vec;
2
3use crate::{entities::Entities, Archetype, DynamicBundle, Entity, TypeInfo};
4
5/// An entity removed from a `World`
6pub struct TakenEntity<'a> {
7    entities: &'a mut Entities,
8    entity: Entity,
9    archetype: &'a mut Archetype,
10    index: u32,
11    drop: bool,
12}
13
14impl<'a> TakenEntity<'a> {
15    /// # Safety
16    /// `index` must be in bounds in `archetype`
17    pub(crate) unsafe fn new(
18        entities: &'a mut Entities,
19        entity: Entity,
20        archetype: &'a mut Archetype,
21        index: u32,
22    ) -> Self {
23        Self {
24            entities,
25            entity,
26            archetype,
27            index,
28            drop: true,
29        }
30    }
31}
32
33unsafe impl<'a> DynamicBundle for TakenEntity<'a> {
34    fn with_ids<T>(&self, f: impl FnOnce(&[core::any::TypeId]) -> T) -> T {
35        f(self.archetype.type_ids())
36    }
37
38    fn type_info(&self) -> Vec<crate::TypeInfo> {
39        self.archetype.types().to_vec()
40    }
41
42    unsafe fn put(mut self, mut f: impl FnMut(*mut u8, TypeInfo)) {
43        // Suppress dropping of moved components
44        self.drop = false;
45        for &ty in self.archetype.types() {
46            let ptr = self
47                .archetype
48                .get_dynamic(ty.id(), ty.layout().size(), self.index)
49                .unwrap();
50            f(ptr.as_ptr(), ty)
51        }
52    }
53}
54
55impl Drop for TakenEntity<'_> {
56    fn drop(&mut self) {
57        if let Some(moved) = unsafe { self.archetype.remove(self.index, self.drop) } {
58            self.entities.meta[moved as usize].location.index = self.index;
59        }
60        self.entities.free(self.entity).unwrap();
61    }
62}