conniecs/
component.rs

1//! TODO: Add documentation including describing how the derive macros work
2
3use fnv::FnvHashMap;
4use vec_map::VecMap;
5
6use std::collections::HashMap;
7use std::marker::PhantomData;
8use std::ops::{Index, IndexMut};
9
10use self::InnerComponentList::{Cold, Hot};
11use crate::entity::{BuildData, EditData, IndexedEntity, ModifyData};
12
13/// Marks types which are suitable for being components. It is implemented for all
14/// types which are `'static`.
15pub trait Component: 'static {}
16impl<T: 'static> Component for T {}
17
18/// This is the trait implemented for your struct containing all of your
19/// component lists. You should not try to implement this manually. Use
20/// `#[derive(Components)]` instead. See the module documentation for more
21/// information.
22pub trait ComponentManager: 'static {
23    fn build_manager() -> Self;
24
25    #[doc(hidden)]
26    fn __wipe_all(&mut self);
27
28    #[doc(hidden)]
29    fn __please_use_the_derive_attribute();
30}
31
32#[derive(Debug)]
33pub struct ComponentList<C, T>
34where
35    C: ComponentManager,
36    T: Component,
37{
38    pub(crate) inner: InnerComponentList<T>,
39    _marker: PhantomData<C>,
40}
41
42#[derive(Debug)]
43pub(crate) enum InnerComponentList<T>
44where
45    T: Component,
46{
47    Hot(VecMap<T>),
48    Cold(FnvHashMap<usize, T>),
49}
50
51impl<C, T> ComponentList<C, T>
52where
53    C: ComponentManager,
54    T: Component,
55{
56    pub fn hot() -> Self {
57        ComponentList {
58            inner: Hot(VecMap::new()),
59            _marker: PhantomData,
60        }
61    }
62
63    pub fn cold() -> Self {
64        ComponentList {
65            inner: Cold(HashMap::with_hasher(Default::default())),
66            _marker: PhantomData,
67        }
68    }
69
70    pub fn add(&mut self, entity: BuildData<C>, component: T) -> Option<T> {
71        self.inner.insert(entity.0.index(), component)
72    }
73
74    pub fn remove(&mut self, entity: ModifyData<C>) -> Option<T> {
75        self.inner.remove(entity.0.index())
76    }
77
78    pub fn set<E>(&mut self, entity: E, component: T) -> Option<T>
79    where
80        E: EditData<C>,
81    {
82        let result = self.inner.insert(entity.entity().index(), component);
83        if result.is_none() && !E::can_insert_components() {
84            panic!("ComponentList::set was used to insert a new component when modification of activated components was not allowed");
85        }
86        result
87    }
88
89    pub fn get<E>(&self, entity: E) -> Option<T>
90    where
91        E: EditData<C>,
92        T: Clone,
93    {
94        self.inner.get(entity.entity().index()).cloned()
95    }
96
97    pub fn has<E>(&self, entity: E) -> bool
98    where
99        E: EditData<C>,
100    {
101        self.inner.contains_key(entity.entity().index())
102    }
103
104    pub fn borrow<E>(&mut self, entity: E) -> Option<&mut T>
105    where
106        E: EditData<C>,
107    {
108        self.inner.get_mut(entity.entity().index())
109    }
110
111    #[doc(hidden)]
112    pub fn __clear(&mut self, entity: &IndexedEntity<C>) {
113        self.inner.remove(entity.index());
114    }
115
116    #[doc(hidden)]
117    pub fn __wipe(&mut self) {
118        self.inner.clear();
119    }
120}
121
122impl<C, T, E> Index<E> for ComponentList<C, T>
123where
124    C: ComponentManager,
125    T: Component,
126    E: EditData<C>,
127{
128    type Output = T;
129    fn index(&self, entity: E) -> &T {
130        self.inner.index(entity.entity().index())
131    }
132}
133
134impl<C, T, E> IndexMut<E> for ComponentList<C, T>
135where
136    C: ComponentManager,
137    T: Component,
138    E: EditData<C>,
139{
140    fn index_mut(&mut self, entity: E) -> &mut T {
141        self.inner.index_mut(entity.entity().index())
142    }
143}
144
145impl<T> InnerComponentList<T>
146where
147    T: Component,
148{
149    pub(crate) fn insert(&mut self, index: usize, component: T) -> Option<T> {
150        match *self {
151            Hot(ref mut map) => map.insert(index, component),
152            Cold(ref mut map) => map.insert(index, component),
153        }
154    }
155
156    pub(crate) fn remove(&mut self, index: usize) -> Option<T> {
157        match *self {
158            Hot(ref mut map) => map.remove(index),
159            Cold(ref mut map) => map.remove(&index),
160        }
161    }
162
163    pub(crate) fn contains_key(&self, index: usize) -> bool {
164        match *self {
165            Hot(ref map) => map.contains_key(index),
166            Cold(ref map) => map.contains_key(&index),
167        }
168    }
169
170    pub(crate) fn index(&self, index: usize) -> &T {
171        self.get(index)
172            .unwrap_or_else(|| panic!("Entity at index {} does not have this component attached"))
173    }
174
175    pub(crate) fn index_mut(&mut self, index: usize) -> &mut T {
176        self.get_mut(index)
177            .unwrap_or_else(|| panic!("Entity at index {} does not have this component attached"))
178    }
179
180    pub(crate) fn get(&self, index: usize) -> Option<&T> {
181        match *self {
182            Hot(ref map) => map.get(index),
183            Cold(ref map) => map.get(&index),
184        }
185    }
186
187    pub(crate) fn get_mut(&mut self, index: usize) -> Option<&mut T> {
188        match *self {
189            Hot(ref mut map) => map.get_mut(index),
190            Cold(ref mut map) => map.get_mut(&index),
191        }
192    }
193
194    pub(crate) fn clear(&mut self) {
195        match *self {
196            Hot(ref mut map) => map.clear(),
197            Cold(ref mut map) => map.clear(),
198        }
199    }
200}