summaryrefslogtreecommitdiff
path: root/src/lib.rs
blob: be4c2bfa7f1187da29a0e602d7cc329183d5ff17 (plain)
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
pub mod bundle;
pub mod component;
pub mod query;
pub mod sparse_set;

pub mod prelude {
    pub use super::component::Component;
    pub use super::component::ComponentStorage;
    pub use super::sparse_set::SparseSet;
    pub use super::Entity;
    pub use super::bundle::ComponentBundle;
    pub use super::query::Query;
    pub use super::query::QueryMut;
}

pub type Entity = usize;

#[macro_export]
macro_rules! ecs {
    ($name:ident {
        context: $ctx:ty,
        components: {
            $($comp:ident),* $(,)?
        },
        systems: {
            $($sys:path),* $(,)?
        }$(,)?
    }) => {
        #[allow(non_snake_case)]
        struct $name {
            next_entity: Entity,
            $($comp: SparseSet<$comp>),*
        }

        impl $name {
            pub fn new() -> Self {
                Self {
                    next_entity: 0,
                    $($comp: SparseSet::new()),*
                }
            }

            pub fn update(&mut self, ctx: &mut $ctx) {
                $($sys(self, ctx));*
            }

            pub fn insert<T: ComponentBundle<Self>>(&mut self, entity: Entity, bundle: T) {
                bundle.insert(self, entity);
            }

            pub fn spawn<T: ComponentBundle<Self>>(&mut self, bundle:T) -> Entity {
                let e = self.next_entity;
                self.next_entity += 1;
                bundle.insert(self, e);
                e
            }

            pub fn remove<T: Component>(&mut self, entity: Entity)
            where
                Self: ComponentStorage<T>,
            {
                self.storage_mut().remove(entity);
            }

            pub fn delete(&mut self, entity: Entity) {
                $(self.$comp.remove(entity);)*
            }

            pub fn get<T: Component>(&self, entity: Entity) -> Option<&T>
            where
                Self: ComponentStorage<T>,
            {
                self.storage().get(entity)
            }

            pub fn get_mut<T: Component>(&mut self, entity: Entity) -> Option<&mut T>
            where
                Self: ComponentStorage<T>,
            {
                self.storage_mut().get_mut(entity)
            }

        }

        impl<'a> $name {
            pub fn query<Q: Query<'a, Self>>(&'a self) -> impl Iterator<Item = Q::Item> {
                Q::run(self)
            }

            pub fn query_mut<Q: QueryMut<'a, Self>>(&'a mut self)
                                                    -> impl Iterator<Item = Q::Item> {
                Q::run_mut(self)
            }
        }

        $(impl ComponentStorage<$comp> for $name {
            fn storage(&self) -> &SparseSet<$comp> {
                &self.$comp
            }

            fn storage_mut(&mut self) -> &mut SparseSet<$comp> {
                &mut self.$comp
            }

            fn storage_ptr(&mut self) -> *mut SparseSet<$comp> {
                &mut self.$comp
            }
        })+
    };
}