1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use crate::entity_id::EntityId;
use crate::ViewMut;

/// Defines how components are added to an existing entity.
pub trait AddComponent {
    #[allow(missing_docs)]
    type Component;
    /// Adds `component` to `entity`, multiple components can be added at the same time using a tuple.  
    /// This function does not check `entity` is alive. It's possible to add components to removed entities.  
    /// Use [`Entities::add_component`] if you're unsure.
    ///
    /// ### Example
    /// ```
    /// use shipyard::{World, EntitiesViewMut, ViewMut, AddComponent};
    ///
    /// let world = World::new();
    ///
    /// let (mut entities, mut u32s) = world.borrow::<(EntitiesViewMut, ViewMut<u32>)>().unwrap();
    /// let entity = entities.add_entity((), ());
    ///
    /// u32s.add_component_unchecked(entity, 0);
    /// ```
    ///
    /// [`Entities::add_component`]: crate::Entities::add_component()
    fn add_component_unchecked(&mut self, entity: EntityId, component: Self::Component);
}

impl AddComponent for () {
    type Component = ();

    #[inline]
    fn add_component_unchecked(&mut self, _: EntityId, _: Self::Component) {}
}

impl<T: 'static> AddComponent for ViewMut<'_, T> {
    type Component = T;

    #[inline]
    fn add_component_unchecked(&mut self, entity: EntityId, component: Self::Component) {
        self.insert(entity, component);
    }
}

impl<T: 'static> AddComponent for &mut ViewMut<'_, T> {
    type Component = T;

    #[inline]
    fn add_component_unchecked(&mut self, entity: EntityId, component: Self::Component) {
        self.insert(entity, component);
    }
}

macro_rules! impl_add_component {
    ($(($storage: ident, $index: tt))+) => {
        impl<$($storage: AddComponent,)+> AddComponent for ($($storage,)+) {
            type Component = ($($storage::Component,)+);

            #[inline]
            fn add_component_unchecked(&mut self, entity: EntityId, component: Self::Component) {
                $(
                    self.$index.add_component_unchecked(entity, component.$index);
                )+
            }
        }
    }
}

macro_rules! add_component {
    ($(($storage: ident, $index: tt))+; ($storage1: ident, $index1: tt) $(($queue_storage: ident, $queue_index: tt))*) => {
        impl_add_component![$(($storage, $index))*];
        add_component![$(($storage, $index))* ($storage1, $index1); $(($queue_storage, $queue_index))*];
    };
    ($(($storage: ident, $index: tt))+;) => {
        impl_add_component![$(($storage, $index))*];
    }
}

add_component![(ViewA, 0); (ViewB, 1) (ViewC, 2) (ViewD, 3) (ViewE, 4) (ViewF, 5) (ViewG, 6) (ViewH, 7) (ViewI, 8) (ViewJ, 9)];