shipyard/
remove.rs

1use crate::component::Component;
2use crate::entity_id::EntityId;
3use crate::views::ViewMut;
4
5/// Removes component from entities.
6pub trait Remove {
7    /// Type of the removed component.
8    type Out;
9    /// Removes component in `entity`, if the entity had a component, they will be returned.  
10    /// Multiple components can be removed at the same time using a tuple.
11    ///
12    /// ### Example
13    /// ```
14    /// use shipyard::{Component, Remove, ViewMut, World};
15    ///
16    /// #[derive(Component, Debug, PartialEq, Eq)]
17    /// struct U32(u32);
18    ///
19    /// #[derive(Component, Debug, PartialEq, Eq)]
20    /// struct USIZE(usize);
21    ///
22    /// let mut world = World::new();
23    ///
24    /// let entity = world.add_entity((USIZE(0), U32(1)));
25    ///
26    /// let (mut usizes, mut u32s) = world.borrow::<(ViewMut<USIZE>, ViewMut<U32>)>().unwrap();
27    ///
28    /// let old = (&mut usizes, &mut u32s).remove(entity);
29    /// assert_eq!(old, (Some(USIZE(0)), Some(U32(1))));
30    /// ```
31    fn remove(&mut self, entity: EntityId) -> Self::Out;
32}
33
34impl Remove for () {
35    type Out = ();
36
37    #[inline]
38    fn remove(&mut self, _: EntityId) -> Self::Out {}
39}
40
41impl<T: Component, TRACK> Remove for ViewMut<'_, T, TRACK> {
42    type Out = Option<T>;
43
44    #[inline]
45    fn remove(&mut self, entity: EntityId) -> Self::Out {
46        let current = self.current;
47        self.dyn_remove(entity, current)
48    }
49}
50
51impl<T: Component, TRACK> Remove for &mut ViewMut<'_, T, TRACK> {
52    type Out = Option<T>;
53
54    #[inline]
55    fn remove(&mut self, entity: EntityId) -> Self::Out {
56        let current = self.current;
57        self.dyn_remove(entity, current)
58    }
59}
60
61macro_rules! impl_remove_component {
62    ($(($storage: ident, $index: tt))+) => {
63        impl<$($storage: Remove),+> Remove for ($($storage,)+) {
64            type Out = ($($storage::Out,)+);
65
66            #[inline]
67            fn remove(&mut self, entity: EntityId) -> Self::Out {
68                ($(
69                    self.$index.remove(entity),
70                )+)
71            }
72        }
73    }
74}
75
76macro_rules! remove_component {
77    ($(($storage: ident, $index: tt))+; ($storage1: ident, $index1: tt) $(($queue_type: ident, $queue_index: tt))*) => {
78        impl_remove_component![$(($storage, $index))*];
79        remove_component![$(($storage, $index))* ($storage1, $index1); $(($queue_type, $queue_index))*];
80    };
81    ($(($storage: ident, $index: tt))+;) => {
82        impl_remove_component![$(($storage, $index))*];
83    }
84}
85
86#[cfg(not(feature = "extended_tuple"))]
87remove_component![(ViewA, 0); (ViewB, 1) (ViewC, 2) (ViewD, 3) (ViewE, 4) (ViewF, 5) (ViewG, 6) (ViewH, 7) (ViewI, 8) (ViewJ, 9)];
88#[cfg(feature = "extended_tuple")]
89remove_component![
90    (ViewA, 0); (ViewB, 1) (ViewC, 2) (ViewD, 3) (ViewE, 4) (ViewF, 5) (ViewG, 6) (ViewH, 7) (ViewI, 8) (ViewJ, 9)
91    (ViewK, 10) (ViewL, 11) (ViewM, 12) (ViewN, 13) (ViewO, 14) (ViewP, 15) (ViewQ, 16) (ViewR, 17) (ViewS, 18) (ViewT, 19)
92    (ViewU, 20) (ViewV, 21) (ViewW, 22) (ViewX, 23) (ViewY, 24) (ViewZ, 25) (ViewAA, 26) (ViewBB, 27) (ViewCC, 28) (ViewDD, 29)
93    (ViewEE, 30) (ViewFF, 31)
94];