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
use component::*;
use entity::*;
use std::any::{Any, TypeId};

/// data for systems, storing which components they should be intrested in
pub struct Aspect {
    pub accept_types     : Vec<TypeId>,
    pub not_accept_types : Vec<TypeId>
}
impl Aspect {
    pub fn check(&self, entity : &Entity) -> bool {
        self.accept_types.iter().all(|ty| { entity.components.borrow().keys().any(|t| t == ty )}) &&
            self.not_accept_types.iter().any(|ty| { entity.components.borrow().keys().any(|t| t == ty) }) == false
    }
}

/// make aspect for all of this types
#[macro_export]
macro_rules! aspect_all{( $ ($aspect:ty), * ) => {
    {
        use std::any::TypeId;
        Aspect {
            accept_types : vec![$( TypeId::of::<$aspect>() ),*],
            not_accept_types : Vec::new()
        }
    }
}}

impl Aspect {
    pub fn all<T : Any + Component>() -> Aspect {
        Aspect {
            accept_types : vec![TypeId::of::<T>()],
            not_accept_types : Vec::new()
        }
    }
    pub fn all2<T : Any + Component, T1 : Any + Component>() -> Aspect {
        Aspect {
            accept_types : vec![TypeId::of::<T>(), TypeId::of::<T1>()],
            not_accept_types : Vec::new()
        }
    }
    pub fn all3<T : Any + Component, T1 : Any + Component, T2 : Any + Component>() -> Aspect {
        Aspect {
            accept_types : vec![TypeId::of::<T>(), TypeId::of::<T1>(), TypeId::of::<T2>()],
            not_accept_types : Vec::new()
        }
    }
    pub fn all4<T : Any + Component,
                T1 : Any + Component,
                T2 : Any + Component,
                T3 : Any + Component>() -> Aspect {
        Aspect {
            accept_types : vec![TypeId::of::<T>(), TypeId::of::<T1>(), TypeId::of::<T2>(), TypeId::of::<T3>()],
            not_accept_types : Vec::new()
        }
    }

    pub fn all5<T : Any + Component,
                T1 : Any + Component,
                T2 : Any + Component,
                T3 : Any + Component,
                T4 : Any + Component>() -> Aspect {
        Aspect {
            accept_types : vec![TypeId::of::<T>(), TypeId::of::<T1>(), TypeId::of::<T2>(), TypeId::of::<T3>(), TypeId::of::<T4>()],
            not_accept_types : Vec::new()
        }
    }

    pub fn except<T : Any + Component>(mut self) -> Aspect {
        self.not_accept_types.push(TypeId::of::<T>());
        Aspect {
            accept_types : self.accept_types,
            not_accept_types : self.not_accept_types
        }
    }
    pub fn except2<T : Any + Component, T1 : Any + Component>(mut self) -> Aspect {
        self.not_accept_types.push(TypeId::of::<T>());
        self.not_accept_types.push(TypeId::of::<T1>());
        Aspect {
            accept_types : self.accept_types,
            not_accept_types : self.not_accept_types
        }
    }
    pub fn except3<T : Any + Component, T1 : Any + Component, T2 : Any + Component>(mut self) -> Aspect {
        self.not_accept_types.push(TypeId::of::<T>());
        self.not_accept_types.push(TypeId::of::<T1>());
        self.not_accept_types.push(TypeId::of::<T2>());
        Aspect {
            accept_types : self.accept_types,
            not_accept_types : self.not_accept_types
        }
    }
}