flax/archetype/
mod.rs

1use alloc::{
2    boxed::Box,
3    collections::{btree_map, BTreeMap},
4    sync::Arc,
5    vec::Vec,
6};
7use core::{fmt::Debug, mem};
8
9use atomic_refcell::{AtomicRef, AtomicRefCell, BorrowError, BorrowMutError};
10use itertools::Itertools;
11
12use crate::{
13    component::{ComponentDesc, ComponentKey, ComponentValue},
14    events::{EventData, EventSubscriber},
15    writer::ComponentUpdater,
16    Component, Entity,
17};
18
19/// Unique archetype id
20pub type ArchetypeId = Entity;
21/// Represents a slot in the archetype
22pub type Slot = usize;
23
24mod batch;
25mod changes;
26mod guard;
27mod slice;
28mod storage;
29
30pub use batch::*;
31pub use changes::*;
32pub use slice::*;
33pub use storage::Storage;
34
35pub use guard::*;
36
37#[derive(Debug, Clone)]
38/// Holds information of a single component storage buffer
39pub struct StorageInfo {
40    cap: usize,
41    len: usize,
42}
43
44impl StorageInfo {
45    /// Returns the storage capacity
46    pub fn cap(&self) -> usize {
47        self.cap
48    }
49
50    /// Returns the length of the buffer
51    pub fn len(&self) -> usize {
52        self.len
53    }
54
55    #[must_use]
56    /// Returns true if the storage is empty
57    pub fn is_empty(&self) -> bool {
58        self.len() == 0
59    }
60}
61
62/// Human friendly archetype inspection
63#[derive(Default, Clone)]
64pub struct ArchetypeInfo {
65    storage: Vec<StorageInfo>,
66    components: Vec<ComponentDesc>,
67    entities: usize,
68}
69
70impl Debug for ArchetypeInfo {
71    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
72        f.debug_struct("ArchetypeInfo")
73            .field("components", &self.components)
74            .field("entities", &self.entities)
75            .finish()
76    }
77}
78
79impl ArchetypeInfo {
80    /// Returns information about archetype storages
81    pub fn storage(&self) -> &[StorageInfo] {
82        self.storage.as_ref()
83    }
84
85    /// Returns the components in the archetype
86    pub fn components(&self) -> &[ComponentDesc] {
87        self.components.as_ref()
88    }
89}
90
91pub(crate) struct CellData {
92    pub(crate) storage: Storage,
93    pub(crate) changes: Changes,
94    subscribers: Vec<Arc<dyn EventSubscriber>>,
95    pub(crate) key: ComponentKey,
96}
97
98impl CellData {
99    /// Sets the specified entities and slots as modified and invokes subscribers
100    /// **Note**: `ids` must be the slice of entities pointed to by `slice`
101    pub(crate) fn set_modified(&mut self, ids: &[Entity], slots: Slice, change_tick: u32) {
102        debug_assert_eq!(ids.len(), slots.len());
103        self.changes
104            .set_modified_if_tracking(Change::new(slots, change_tick));
105
106        let event = EventData {
107            ids,
108            slots,
109            key: self.key,
110        };
111
112        for handler in self.subscribers.iter() {
113            handler.on_modified(&event)
114        }
115    }
116
117    /// Sets the specified entities and slots as modified and invokes subscribers
118    /// **Note**: `ids` must be the slice of entities pointed to by `slice`
119    pub(crate) fn set_added(&mut self, ids: &[Entity], slots: Slice, change_tick: u32) {
120        self.changes.set_added(Change::new(slots, change_tick));
121
122        let event = EventData {
123            ids,
124            slots,
125            key: self.key,
126        };
127
128        for handler in self.subscribers.iter() {
129            handler.on_added(&self.storage, &event);
130        }
131    }
132
133    #[inline]
134    pub(crate) fn set_removed(&mut self, ids: &[Entity], slots: Slice) {
135        let event = EventData {
136            ids,
137            slots,
138            key: self.key,
139        };
140
141        for handler in self.subscribers.iter() {
142            handler.on_removed(&self.storage, &event);
143        }
144    }
145}
146
147/// Stores a list of component values, changes, and subscribers
148pub(crate) struct Cell {
149    pub(crate) data: AtomicRefCell<CellData>,
150    desc: ComponentDesc,
151}
152
153impl Cell {
154    pub(crate) fn new(desc: ComponentDesc) -> Self {
155        Self {
156            data: AtomicRefCell::new(CellData {
157                storage: Storage::new(desc),
158                changes: Changes::new(),
159                subscribers: Vec::new(),
160                key: desc.key,
161            }),
162            desc,
163        }
164    }
165
166    /// Moves a slot in the cell to another cell and slot while migrating all changes.
167    fn move_to(&mut self, slot: Slot, dst: &mut Self, dst_slot: Slot) {
168        let data = self.data.get_mut();
169
170        let last = data.storage.len() - 1;
171
172        let dst = dst.data.get_mut();
173
174        data.storage.swap_remove(slot, |p| unsafe {
175            dst.storage.extend(p, 1);
176        });
177
178        // Replace this slot with the last slot and move everything to the dst archetype
179        data.changes.swap_remove(slot, last, |kind, v| {
180            dst.changes.set_slot(kind, dst_slot, v.tick);
181        });
182
183        // Do not notify of removal, since the component is still intact, but in another archetype
184    }
185
186    /// Moves all slots to another cell
187    fn move_all(&mut self, dst: &mut Self, dst_start: Slot) {
188        let data = self.data.get_mut();
189
190        let dst = dst.data.get_mut();
191
192        debug_assert_eq!(dst.storage.len(), dst_start);
193        unsafe { dst.storage.append(&mut data.storage) }
194
195        data.changes.zip_map(&mut dst.changes, |_, a, b| {
196            a.inner.drain(..).for_each(|mut change| {
197                change.slice.start += dst_start;
198                change.slice.end += dst_start;
199
200                b.set(change);
201            })
202        });
203    }
204
205    /// Move a slot out of the cell by swapping with the last
206    fn take(&mut self, slot: Slot, mut on_move: impl FnMut(ComponentDesc, *mut u8)) {
207        let data = self.data.get_mut();
208
209        let last = data.storage.len() - 1;
210
211        data.storage.swap_remove(slot, |p| on_move(self.desc, p));
212        data.changes.swap_remove(slot, last, |_, _| {});
213    }
214
215    /// Silently clears (and drops) all components and changes.
216    fn clear(&mut self) {
217        let data = self.data.get_mut();
218
219        data.storage.clear();
220        data.changes.clear();
221    }
222
223    /// Drain the values in the cell.
224    pub(crate) fn drain(&mut self) -> Storage {
225        let data = self.data.get_mut();
226        let storage = mem::replace(&mut data.storage, Storage::new(self.desc));
227        data.changes.clear();
228
229        storage
230    }
231
232    /// # Safety
233    ///
234    /// Assumes `self` is of type `T`
235    pub(crate) unsafe fn get<T: ComponentValue>(&self, slot: Slot) -> Option<AtomicRef<T>> {
236        let data = self.data.borrow();
237        AtomicRef::filter_map(data, |v| v.storage.downcast_ref::<T>().get(slot))
238    }
239
240    /// # Safety
241    ///
242    /// Assumes `self` is of type `T`
243    pub(crate) unsafe fn try_get<T: ComponentValue>(
244        &self,
245        slot: Slot,
246    ) -> Result<Option<AtomicRef<T>>, BorrowError> {
247        let data = self.data.try_borrow()?;
248        Ok(AtomicRef::filter_map(data, |v| {
249            v.storage.downcast_ref::<T>().get(slot)
250        }))
251    }
252
253    #[inline]
254    pub fn borrow<T: ComponentValue>(&self) -> CellGuard<[T]> {
255        CellGuard::new(self.data.borrow())
256    }
257
258    #[inline]
259    pub fn borrow_mut<T: ComponentValue>(&self) -> CellMutGuard<[T]> {
260        CellMutGuard::new(self.data.borrow_mut())
261    }
262
263    // #[inline]
264    // pub fn try_borrow<T: ComponentValue>(&self) -> Result<CellGuard<[T]>, BorrowError> {
265    //     Ok(CellGuard::new(self.data.try_borrow()?))
266    // }
267
268    // #[inline]
269    // pub fn try_borrow_mut<T: ComponentValue>(&self) -> Result<CellMutGuard<[T]>, BorrowMutError> {
270    //     Ok(CellMutGuard::new(self.data.try_borrow_mut()?))
271    // }
272
273    #[inline]
274    pub fn get_mut<T: ComponentValue>(
275        &self,
276        id: Entity,
277        slot: Slot,
278        tick: u32,
279    ) -> Option<RefMut<T>> {
280        RefMut::new(self.borrow_mut(), id, slot, tick)
281    }
282
283    pub(crate) fn desc(&self) -> ComponentDesc {
284        self.desc
285    }
286}
287
288// #[derive(Debug)]
289#[doc(hidden)]
290/// A collection of entities with the same components.
291/// Stored as columns of contiguous component data.
292pub struct Archetype {
293    components: BTreeMap<ComponentKey, usize>,
294    cells: Box<[Cell]>,
295    /// Slot to entity id
296    pub(crate) entities: Vec<Entity>,
297
298    // ComponentId => ArchetypeId
299    pub(crate) children: BTreeMap<ComponentKey, ArchetypeId>,
300    pub(crate) outgoing: BTreeMap<ComponentKey, ArchetypeId>,
301    pub(crate) incoming: BTreeMap<ComponentKey, ArchetypeId>,
302}
303
304/// Since all components are Send + Sync, the cells are as well
305unsafe impl Send for Cell {}
306unsafe impl Sync for Cell {}
307
308impl Archetype {
309    pub(crate) fn empty() -> Self {
310        Self {
311            cells: Box::new([]),
312            components: BTreeMap::new(),
313            incoming: BTreeMap::new(),
314            entities: Vec::new(),
315            children: Default::default(),
316            outgoing: Default::default(),
317        }
318    }
319
320    /// Create a new archetype.
321    /// Assumes `components` are sorted by id.
322    pub(crate) fn new<I>(components: I) -> Self
323    where
324        I: IntoIterator<Item = ComponentDesc>,
325    {
326        let (components, cells): (_, Vec<_>) = components
327            .into_iter()
328            .enumerate()
329            .map(|(i, desc)| ((desc.key(), i), Cell::new(desc)))
330            .unzip();
331
332        Self {
333            components,
334            cells: cells.into_boxed_slice(),
335            incoming: BTreeMap::new(),
336            entities: Vec::new(),
337            children: Default::default(),
338            outgoing: Default::default(),
339        }
340    }
341
342    /// Returns all the relation components in the archetype
343    pub fn relations(&self) -> impl Iterator<Item = ComponentKey> + '_ {
344        self.components.keys().filter(|v| v.is_relation()).copied()
345    }
346
347    pub(crate) fn relations_like(&self, relation: Entity) -> btree_map::Range<ComponentKey, usize> {
348        self.components.range(
349            ComponentKey::new(relation, Some(Entity::MIN))
350                ..=ComponentKey::new(relation, Some(Entity::MAX)),
351        )
352    }
353
354    /// Returns all the slots in the archetype
355    pub fn slots(&self) -> Slice {
356        Slice::new(0, self.len())
357    }
358
359    /// Returns true if the archtype has `component`
360    pub fn has(&self, component: ComponentKey) -> bool {
361        self.components.contains_key(&component)
362    }
363
364    pub(crate) fn incoming(&self, component: ComponentKey) -> Option<ArchetypeId> {
365        self.incoming.get(&component).copied()
366    }
367
368    pub(crate) fn add_incoming(&mut self, component: ComponentKey, dst_id: ArchetypeId) {
369        debug_assert!(self.has(component), "Archetype has the incoming component");
370
371        let existing = self.incoming.insert(component, dst_id);
372
373        debug_assert!(
374            existing.is_none() || existing == Some(dst_id),
375            "Insert incoming for {component:?} => {dst_id}. Existing: {existing:?}"
376        )
377    }
378
379    pub(crate) fn add_outgoing(&mut self, component: ComponentKey, dst_id: ArchetypeId) {
380        self.outgoing.insert(component, dst_id);
381    }
382
383    pub(crate) fn add_child(&mut self, component: ComponentKey, id: ArchetypeId) {
384        self.outgoing.insert(component, id);
385
386        let existing = self.children.insert(component, id);
387        debug_assert!(existing.is_none());
388    }
389
390    pub(crate) fn borrow<T: ComponentValue>(
391        &self,
392        component: ComponentKey,
393    ) -> Option<CellGuard<[T]>> {
394        Some(self.cell(component)?.borrow())
395    }
396
397    /// Access a component storage mutably.
398    ///
399    /// Return a reference to the change list, which must be used to push the slots which where
400    /// modified.
401    ///
402    /// # Panics
403    /// If the storage or changes is already borrowed
404    pub(crate) fn borrow_mut<T: ComponentValue>(
405        &self,
406        component: ComponentKey,
407    ) -> Option<CellMutGuard<[T]>> {
408        let cell = self.cell(component)?;
409        let data = cell.borrow_mut();
410        Some(data)
411    }
412
413    /// Removes a slot and swaps in the last slot
414    #[inline(always)]
415    unsafe fn remove_slot(&mut self, slot: Slot) -> Option<(Entity, Slot)> {
416        let last = self.len() - 1;
417        if slot != last {
418            self.entities[slot] = self.entities[last];
419            Some((self.entities.pop().unwrap(), slot))
420        } else {
421            self.entities.pop().expect("Non empty");
422
423            None
424        }
425    }
426
427    /// Returns human friendly debug info
428    pub fn desc(&self) -> ArchetypeInfo {
429        let (components, storage) = self
430            .cells
431            .iter()
432            .map(|v| {
433                let data = v.data.borrow();
434                (
435                    v.desc,
436                    StorageInfo {
437                        cap: data.storage.capacity(),
438                        len: data.storage.len(),
439                    },
440                )
441            })
442            .unzip();
443
444        ArchetypeInfo {
445            components,
446            storage,
447            entities: self.entities.len(),
448        }
449    }
450
451    /// Get a component from the entity at `slot`
452    pub(crate) fn get_mut<T: ComponentValue>(
453        &self,
454        slot: Slot,
455        component: Component<T>,
456        tick: u32,
457    ) -> Option<RefMut<T>> {
458        self.cell(component.key())?
459            .get_mut(self.entities[slot], slot, tick)
460    }
461
462    /// Get a component from the entity at `slot`
463    pub(crate) fn try_get_mut<T: ComponentValue>(
464        &self,
465        slot: Slot,
466        component: Component<T>,
467        tick: u32,
468    ) -> Result<Option<RefMut<T>>, BorrowMutError> {
469        let cell = match self.cell(component.key()) {
470            Some(v) => v,
471            None => return Ok(None),
472        };
473
474        Ok(cell.get_mut(self.entities[slot], slot, tick))
475    }
476
477    /// Get a component from the entity at `slot`
478    #[inline]
479    pub fn mutate_in_place<T>(
480        &mut self,
481        slot: Slot,
482        cell: usize,
483        change_tick: u32,
484        modify: impl FnOnce(*mut u8) -> T,
485    ) -> Option<T> {
486        let cell = self.cells.get_mut(cell)?;
487
488        let data = cell.data.get_mut();
489
490        let value = unsafe { data.storage.at_mut(slot)? };
491        let value = (modify)(value);
492
493        data.set_modified(
494            &self.entities[slot..=slot],
495            Slice::single(slot),
496            change_tick,
497        );
498
499        Some(value)
500    }
501
502    /// Get a component from the entity at `slot`
503    #[inline]
504    pub(crate) fn update<T: ComponentValue, U: ComponentUpdater>(
505        &self,
506        slot: Slot,
507        component: Component<T>,
508        writer: U,
509        tick: u32,
510    ) -> Option<U::Updated> {
511        let cell = self.cell(component.key())?;
512
513        let mut data = cell.data.borrow_mut();
514
515        let res = unsafe { writer.update(&mut data, slot, self.entities[slot], tick) };
516
517        Some(res)
518    }
519
520    /// Get a component from the entity at `slot`.
521    pub(crate) fn get<T: ComponentValue>(
522        &self,
523        slot: Slot,
524        component: Component<T>,
525    ) -> Option<AtomicRef<T>> {
526        let cell = self.cell(component.key())?;
527        unsafe { cell.get(slot) }
528    }
529
530    /// Get a component from the entity at `slot`.
531    pub(crate) fn try_get<T: ComponentValue>(
532        &self,
533        slot: Slot,
534        component: Component<T>,
535    ) -> Result<Option<AtomicRef<T>>, BorrowError> {
536        let cell = match self.cell(component.key()) {
537            Some(v) => v,
538            None => return Ok(None),
539        };
540        unsafe { cell.try_get(slot) }
541    }
542
543    /// Insert a new entity into the archetype.
544    /// The components must match exactly.
545    ///
546    /// Returns the index of the entity
547    /// Entity must not exist in archetype
548    #[cfg(test)]
549    pub(crate) fn insert(
550        &mut self,
551        id: Entity,
552        buffer: &mut crate::buffer::ComponentBuffer,
553    ) -> Slot {
554        let slot = self.allocate(id);
555        for (desc, src) in buffer.drain() {
556            unsafe {
557                let cell = &mut self.cells[self.components[&desc.key]];
558                let data = cell.data.get_mut();
559
560                data.storage.extend(src, 1);
561            }
562        }
563
564        slot
565    }
566
567    /// Allocated space for a new slot.
568    /// The slot will always be greater than any previous call.
569    /// # Safety
570    /// All components of slot are uninitialized. Must be followed by `push`
571    /// all components in archetype.
572    pub(crate) fn allocate(&mut self, id: Entity) -> Slot {
573        self.reserve(1);
574
575        #[cfg(debug_assertions)]
576        {
577            if self.entities.iter().any(|&v| v == id) {
578                panic!("Entity already in archetype");
579            }
580        }
581        let slot = self.len();
582
583        self.entities.push(id);
584
585        slot
586    }
587
588    /// Allocates consecutive slots.
589    /// Returns the new slots
590    ///
591    /// # Safety
592    /// All components of the new slots are left uninitialized.
593    /// Must be followed by `extend`
594    pub(crate) fn allocate_n(&mut self, ids: &[Entity]) -> Slice {
595        self.reserve(ids.len());
596
597        let last = self.len();
598
599        self.entities.extend_from_slice(ids);
600
601        Slice::new(last, self.len())
602    }
603
604    /// Push a type erased component into the new slot
605    /// The component must match the type of data.
606    /// # Safety
607    /// Must be called only **ONCE**. Returns Err(src) if move was unsuccessful
608    /// The component must be Send + Sync
609    pub unsafe fn push(&mut self, component: ComponentKey, src: *mut u8, tick: u32) {
610        let len = self.len();
611        let cell = &mut self.cells[self.components[&component]];
612        let data = cell.data.get_mut();
613
614        let slot = data.storage.len();
615        assert_eq!(slot, len - 1, "Not inserting at end");
616        data.storage.extend(src, 1);
617
618        // TODO remove and make internal
619        assert!(
620            data.storage.len() <= len,
621            "Attempt to insert more values than entities {} > {}",
622            data.storage.len(),
623            self.entities.len()
624        );
625
626        data.set_added(&self.entities[slot..=slot], Slice::single(slot), tick);
627    }
628
629    /// Moves the components in `storage` to the not yet initialized space in a
630    /// new allocation.
631    /// # Safety
632    /// The length of the passed data must be equal to the slice and the slice
633    /// must point to a currently uninitialized region in the archetype.
634    pub(crate) unsafe fn extend(&mut self, src: &mut Storage, tick: u32) {
635        if src.is_empty() {
636            return;
637        }
638
639        let len = self.len();
640        let cell = &mut self.cells[self.components[&src.desc().key()]];
641        let data = cell.data.get_mut();
642
643        let slots = Slice::new(data.storage.len(), data.storage.len() + src.len());
644        debug_assert!(slots.start <= len);
645
646        data.storage.append(src);
647        debug_assert!(data.storage.len() <= len);
648
649        data.set_added(&self.entities[slots.as_range()], slots, tick);
650    }
651
652    /// Move all components in `slot` to archetype of `dst`. The components not
653    /// in self will be left uninitialized.
654    /// # Safety
655    /// `dst.put_dyn` must be called immediately after for each missing
656    /// component.
657    ///
658    /// Returns the slot in dst and entity which was moved into current `slot`, if any.
659    ///
660    /// Generates change events for removed components
661    pub unsafe fn move_to(
662        &mut self,
663        dst: &mut Self,
664        slot: Slot,
665        mut on_drop: impl FnMut(ComponentDesc, *mut u8),
666    ) -> (Slot, Option<(Entity, Slot)>) {
667        let id = self.entity(slot).expect("Invalid entity");
668
669        let dst_slot = dst.allocate(id);
670
671        for cell in &mut *self.cells {
672            let key = cell.desc.key();
673            let data = cell.data.get_mut();
674
675            let dst_cell = dst.cell_mut(key);
676
677            if let Some(dst_cell) = dst_cell {
678                cell.move_to(slot, dst_cell, dst_slot);
679            } else {
680                // Notify the subscribers that the component was removed
681                data.set_removed(&[id], Slice::single(slot));
682
683                cell.take(slot, &mut on_drop);
684            }
685        }
686
687        let swapped = self.remove_slot(slot);
688
689        (dst_slot, swapped)
690    }
691
692    /// Move all components of an entity out of an archetype
693    ///
694    /// Returns the entity which filled the now empty slot
695    ///
696    /// # Safety
697    /// The callee is responsible to store or drop the returned components using
698    /// the `on_take` function.
699    /// TODO: test with change query
700    pub unsafe fn take(
701        &mut self,
702        slot: Slot,
703        mut on_move: impl FnMut(ComponentDesc, *mut u8),
704    ) -> Option<(Entity, Slot)> {
705        let id = self.entity(slot).expect("Invalid entity");
706
707        // for subscriber in &self.subscribers {
708        //     subscriber.on_despawned(id, slot, self);
709        // }
710
711        for cell in &mut *self.cells {
712            let data = cell.data.get_mut();
713            // data.on_event(&self.entities, Slice::single(slot), EventKind::Removed);
714            data.set_removed(&[id], Slice::single(slot));
715
716            cell.take(slot, &mut on_move)
717        }
718
719        self.remove_slot(slot)
720    }
721
722    /// Removes the last entity
723    /// Returns the popped entity id
724    ///
725    /// # Safety
726    /// The callee is responsible to store or drop the returned components using
727    /// the `on_take` function.
728    pub(crate) unsafe fn pop_last(
729        &mut self,
730        on_take: impl FnMut(ComponentDesc, *mut u8),
731    ) -> Option<Entity> {
732        let last = self.last();
733        if let Some(last) = last {
734            self.take(self.len() - 1, on_take);
735            Some(last)
736        } else {
737            None
738        }
739    }
740
741    /// Move all entities from one archetype to another.
742    ///
743    /// Leaves `self` empty.
744    /// Returns the new location of all entities
745    pub fn move_all(&mut self, dst: &mut Self) -> Vec<(Entity, Slot)> {
746        let len = self.len();
747        if len == 0 {
748            return Vec::new();
749        }
750
751        let slots = self.slots();
752        let entities = mem::take(&mut self.entities);
753
754        let dst_slots = dst.allocate_n(&entities);
755
756        for cell in &mut *self.cells {
757            let key = cell.desc.key();
758            let data = cell.data.get_mut();
759
760            let dst_cell = dst.cell_mut(key);
761
762            if let Some(dst) = dst_cell {
763                assert_eq!(data.storage.len(), len);
764                cell.move_all(dst, dst_slots.start);
765                // let dst_changes = dst.changes.get_mut();
766
767                // // Move the changes of all slots
768                // for (src, dst) in self.slots().iter().zip(dst_slots) {
769                //     changes.zip_map(dst_changes, |kind, a, b| {
770                //         a.drain(..).for_each(|change| {
771                //             change.slice.start += dst_slots.start;
772                //             change.slice.end += dst_slots.start;
773
774                //             dst_changes.set(kind, change);
775                //         })
776                //     })
777                // }
778
779                // // Copy this storage to the end of dst
780                // unsafe { dst.storage.get_mut().append(storage) }
781            } else {
782                // Notify the subscribers that the component was removed
783                data.set_removed(&entities[slots.as_range()], slots);
784
785                cell.clear();
786            }
787        }
788
789        debug_assert_eq!(self.len(), 0);
790
791        entities.into_iter().zip_eq(dst_slots.iter()).collect_vec()
792    }
793
794    /// Reserves space for at least `additional` entities.
795    /// Does nothing if the remaining capacity < additional.
796    /// len remains unchanged, as does the internal order
797    pub fn reserve(&mut self, additional: usize) {
798        for cell in &mut *self.cells {
799            let data = cell.data.get_mut();
800            data.storage.reserve(additional);
801        }
802    }
803
804    /// Returns the entity at `slot`
805    pub fn entity(&self, slot: Slot) -> Option<Entity> {
806        self.entities.get(slot).copied()
807    }
808
809    /// Drops all components and entities, including changes.
810    pub(crate) fn clear(&mut self) {
811        let slots = self.slots();
812        for cell in &mut *self.cells {
813            let data = cell.data.get_mut();
814            // Notify the subscribers that the component was removed
815            // data.on_event(&self.entities, slots, EventKind::Removed);
816            data.set_removed(&self.entities[slots.as_range()], slots);
817
818            cell.clear()
819        }
820
821        self.entities.clear();
822    }
823
824    #[must_use]
825    /// Number of entities in the archetype
826    pub fn len(&self) -> usize {
827        self.entities.len()
828    }
829
830    #[must_use]
831    /// Returns true if the archetype contains no entities
832    pub fn is_empty(&self) -> bool {
833        self.entities.is_empty()
834    }
835
836    /// Get a reference to the archetype's components.
837    pub(crate) fn components_desc(&self) -> impl Iterator<Item = ComponentDesc> + '_ {
838        self.cells.iter().map(|v| v.desc)
839    }
840
841    #[allow(dead_code)]
842    pub(crate) fn component_names(&self) -> impl Iterator<Item = &str> {
843        self.cells.iter().map(|v| v.desc.name())
844    }
845
846    /// Returns a iterator which attempts to borrows each storage in the archetype
847    pub(crate) fn try_borrow_all(&self) -> impl Iterator<Item = Option<AtomicRef<CellData>>> {
848        self.cells.iter().map(|v| v.data.try_borrow().ok())
849    }
850    /// Access the entities in the archetype for each slot. Entity is None if
851    /// the slot is not occupied, only for the last slots.
852    #[inline]
853    pub fn entities(&self) -> &[Entity] {
854        self.entities.as_ref()
855    }
856
857    pub(crate) fn cells(&self) -> &[Cell] {
858        &self.cells
859    }
860
861    pub(crate) fn drain(&mut self) -> ArchetypeDrain {
862        let slots = self.slots();
863        for cell in &mut *self.cells {
864            let data = cell.data.get_mut();
865            data.set_removed(&self.entities[slots.as_range()], slots)
866        }
867
868        ArchetypeDrain {
869            entities: mem::take(&mut self.entities),
870            cells: mem::take(&mut self.cells),
871        }
872    }
873
874    pub(crate) fn entities_mut(&mut self) -> &mut [Entity] {
875        &mut self.entities
876    }
877
878    pub(crate) fn component(&self, key: ComponentKey) -> Option<ComponentDesc> {
879        self.cell(key).map(|v| v.desc)
880    }
881
882    /// Add a new subscriber. The subscriber must be interested in this archetype
883    pub(crate) fn add_handler(&mut self, s: Arc<dyn EventSubscriber>) {
884        // For component changes
885        for cell in &mut *self.cells {
886            let data = cell.data.get_mut();
887            if s.matches_component(cell.desc) {
888                data.subscribers.push(s.clone());
889            }
890
891            data.subscribers.retain(|v| v.is_connected())
892        }
893    }
894
895    #[inline(always)]
896    pub(crate) fn cell(&self, key: ComponentKey) -> Option<&Cell> {
897        Some(&self.cells[*self.components.get(&key)?])
898    }
899
900    #[inline(always)]
901    pub(crate) fn cell_mut(&mut self, key: ComponentKey) -> Option<&mut Cell> {
902        Some(&mut self.cells[*self.components.get(&key)?])
903    }
904
905    fn last(&self) -> Option<Entity> {
906        self.entities.last().copied()
907    }
908
909    pub(crate) fn remove_link(&mut self, component: ComponentKey) {
910        let linked = self.outgoing.remove(&component);
911        assert!(linked.is_some());
912
913        self.children.remove(&component);
914    }
915
916    /// Borrow the change list mutably
917    #[cfg(test)]
918    pub(crate) fn changes_mut(&mut self, component: ComponentKey) -> Option<&mut Changes> {
919        Some(&mut self.cell_mut(component)?.data.get_mut().changes)
920    }
921
922    pub fn components(&self) -> &BTreeMap<ComponentKey, usize> {
923        &self.components
924    }
925}
926
927impl Drop for Archetype {
928    fn drop(&mut self) {
929        self.clear();
930    }
931}
932
933pub(crate) struct ArchetypeDrain {
934    pub(crate) entities: Vec<Entity>,
935    pub(crate) cells: Box<[Cell]>,
936}
937
938#[cfg(test)]
939mod tests {
940
941    use crate::buffer::ComponentBuffer;
942    use crate::entity::DEFAULT_GEN;
943    use crate::{component, entity::EntityKind};
944    use alloc::string::{String, ToString};
945    use alloc::sync::Arc;
946
947    use super::*;
948
949    component! {
950        a: i32,
951        b: String,
952        c: Arc<String>,
953    }
954
955    #[test]
956    pub fn test_archetype() {
957        let mut arch = Archetype::new([
958            ComponentDesc::of(a()),
959            ComponentDesc::of(b()),
960            ComponentDesc::of(c()),
961        ]);
962
963        let shared = Arc::new("abc".to_string());
964
965        let mut buffer = ComponentBuffer::new();
966        buffer.set(a(), 7);
967        buffer.set(b(), "Foo".to_string());
968        buffer.set(c(), shared.clone());
969
970        let id = Entity::from_parts(6, DEFAULT_GEN.saturating_add(1), EntityKind::empty());
971        let id_2 = Entity::from_parts(5, DEFAULT_GEN.saturating_add(1), EntityKind::empty());
972
973        let slot = arch.insert(id, &mut buffer);
974
975        // Reuse buffer and insert again
976        buffer.set(a(), 9);
977        buffer.set(b(), "Bar".to_string());
978        buffer.set(c(), shared.clone());
979
980        let slot_2 = arch.insert(id_2, &mut buffer);
981
982        assert_eq!(slot, 0);
983        assert_eq!(arch.get(slot, a()).as_deref(), Some(&7));
984        assert_eq!(arch.get(slot, b()).as_deref(), Some(&"Foo".to_string()));
985        assert_eq!(arch.get(slot_2, b()).as_deref(), Some(&"Bar".to_string()));
986
987        arch.get_mut(slot, b(), 0).unwrap().push_str("Bar");
988
989        assert_eq!(arch.get(slot, b()).as_deref(), Some(&"FooBar".to_string()));
990        assert_eq!(arch.entity(slot), Some(id));
991        assert_eq!(arch.entity(slot_2), Some(id_2));
992
993        drop(arch);
994
995        assert_eq!(Arc::strong_count(&shared), 1);
996    }
997}