1#![deny(missing_docs)]
4
5#[macro_use]
6extern crate serde_derive;
7extern crate serde;
8
9use std::default::Default;
10use std::ops;
11use std::slice;
12
13use serde::{Serialize, Deserialize};
14
15#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
17pub struct Entity {
18 uid: u32,
19 idx: u32,
20}
21
22#[derive(Copy, Clone, PartialEq, Eq, Default, Debug, Serialize, Deserialize)]
24struct Index {
25 uid: u32,
27 data_idx: u32,
29}
30
31pub trait AnyComponent {
33 fn remove(&mut self, e: Entity);
35}
36
37#[derive(Serialize, Deserialize)]
39struct DenseComponentData<C> {
40 data: Vec<C>,
42 entities: Vec<Entity>,
44}
45
46pub struct ComponentData<C> {
48 inner: DenseComponentData<C>,
49 entity_idx_to_data: Vec<Index>,
53}
54
55impl<C> ComponentData<C> {
56 pub fn new() -> ComponentData<C> {
58 ComponentData {
59 inner: DenseComponentData {
60 data: Vec::new(),
61 entities: Vec::new(),
62 },
63 entity_idx_to_data: Vec::new(),
64 }
65 }
66
67 pub fn insert(&mut self, e: Entity, comp: C) {
69 debug_assert_eq!(self.inner.data.len(), self.inner.entities.len());
70
71 if self.contains(e) {
72 self.inner.data[self.entity_idx_to_data[e.idx as usize].data_idx as usize] = comp;
74 } else {
75 if e.idx as usize >= self.entity_idx_to_data.len() {
77 self.entity_idx_to_data.resize(
78 e.idx as usize + 1,
79 Default::default(),
80 );
81 }
82
83 let data_idx = self.inner.data.len() as u32;
85 self.inner.data.push(comp);
86 self.inner.entities.push(e);
87 self.entity_idx_to_data[e.idx as usize] = Index {
88 uid: e.uid,
89 data_idx: data_idx,
90 };
91 }
92 }
93
94 pub fn contains(&self, e: Entity) -> bool {
96 debug_assert_ne!(e.uid, 0);
97
98 (e.idx as usize) < self.entity_idx_to_data.len() &&
99 self.entity_idx_to_data[e.idx as usize].uid == e.uid
100 }
101
102 pub fn get(&self, e: Entity) -> Option<&C> {
104 if self.contains(e) {
105 Some(
106 &self.inner.data[self.entity_idx_to_data[e.idx as usize].data_idx as usize],
107 )
108 } else {
109 None
110 }
111 }
112
113 pub fn get_mut(&mut self, e: Entity) -> Option<&mut C> {
115 if self.contains(e) {
116 Some(
117 &mut self.inner.data[self.entity_idx_to_data[e.idx as usize].data_idx as usize],
118 )
119 } else {
120 None
121 }
122 }
123
124 pub fn ent_iter(&self) -> slice::Iter<Entity> {
126 self.inner.entities.iter()
127 }
128
129 pub fn iter(&self) -> slice::Iter<C> {
131 self.inner.data.iter()
132 }
133
134 pub fn iter_mut(&mut self) -> slice::IterMut<C> {
136 self.inner.data.iter_mut()
137 }
138}
139
140impl<C> ops::Index<Entity> for ComponentData<C> {
141 type Output = C;
142
143 fn index(&self, e: Entity) -> &C {
144 self.get(e).unwrap()
145 }
146}
147
148impl<C> ops::IndexMut<Entity> for ComponentData<C> {
149 fn index_mut(&mut self, e: Entity) -> &mut C {
150 self.get_mut(e).unwrap()
151 }
152}
153
154impl<C> AnyComponent for ComponentData<C> {
155 fn remove(&mut self, e: Entity) {
156 debug_assert_eq!(self.inner.data.len(), self.inner.entities.len());
157 if self.contains(e) {
158 let removed_index = self.entity_idx_to_data[e.idx as usize];
159 self.entity_idx_to_data[e.idx as usize] = Default::default();
160
161 if removed_index.data_idx as usize != self.inner.entities.len() - 1 {
165 let last_entity = self.inner.entities[self.inner.entities.len() - 1];
166 self.inner.entities.swap_remove(
167 removed_index.data_idx as usize,
168 );
169 self.entity_idx_to_data[last_entity.idx as usize] = Index {
170 uid: last_entity.uid,
171 data_idx: removed_index.data_idx,
172 };
173 } else {
174 self.inner.entities.swap_remove(
175 removed_index.data_idx as usize,
176 );
177 }
178
179 self.inner.data.swap_remove(removed_index.data_idx as usize);
180 }
181 }
182}
183
184#[derive(Serialize, Deserialize)]
185struct Packed<C> {
186 entity_count: u32,
187 data: Vec<C>,
188 entities: Vec<Entity>,
189}
190
191impl<C: Serialize + Clone> serde::Serialize for ComponentData<C> {
192 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
193 self.inner.serialize(s)
194 }
195}
196
197impl<'a, C: Deserialize<'a>> serde::Deserialize<'a> for ComponentData<C> {
198 fn deserialize<D: serde::Deserializer<'a>>(d: D) -> Result<Self, D::Error> {
199 let inner: DenseComponentData<C> = serde::Deserialize::deserialize(d)?;
200
201 let mut entity_idx_to_data = Vec::new();
203 for (i, e) in inner.entities.iter().enumerate() {
204 if e.idx as usize >= entity_idx_to_data.len() {
205 entity_idx_to_data.resize(e.idx as usize + 1, Default::default());
206 }
207 entity_idx_to_data[e.idx as usize] = Index {
208 uid: e.uid,
209 data_idx: i as u32,
210 };
211 }
212
213 Ok(ComponentData {
214 inner: inner,
215 entity_idx_to_data: entity_idx_to_data,
216 })
217 }
218}
219
220pub trait Store {
222 fn for_each_component<F>(&mut self, f: F)
224 where
225 F: FnMut(&mut AnyComponent);
226}
227
228#[derive(Serialize, Deserialize)]
233pub struct Ecs<ST> {
234 next_uid: u32,
235 next_idx: u32,
236 free_indices: Vec<u32>,
237 active: ComponentData<bool>,
238 store: ST,
239}
240
241impl<ST: Default + Store> Ecs<ST> {
242 pub fn new() -> Ecs<ST> {
244 Ecs {
245 next_uid: 1,
246 next_idx: 0,
247 free_indices: Vec::new(),
248 active: ComponentData::new(),
249 store: Default::default(),
250 }
251 }
252
253 pub fn make(&mut self) -> Entity {
255 let uid = self.next_uid;
256 self.next_uid += 1;
257
258 let idx = if let Some(idx) = self.free_indices.pop() {
259 idx
260 } else {
261 self.next_idx += 1;
262 self.next_idx - 1
263 };
264
265 let ret = Entity { uid: uid, idx: idx };
266 self.active.insert(ret, true);
267 ret
268 }
269
270 pub fn remove(&mut self, e: Entity) {
272 if self.contains(e) {
273 self.free_indices.push(e.idx);
274 self.active.remove(e);
275 self.store.for_each_component(|c| c.remove(e));
276 }
277 }
278
279 pub fn contains(&self, e: Entity) -> bool {
281 self.active.contains(e)
282 }
283
284 pub fn iter(&self) -> slice::Iter<Entity> {
286 self.active.ent_iter()
287 }
288}
289
290impl<ST> ops::Deref for Ecs<ST> {
291 type Target = ST;
292
293 fn deref(&self) -> &ST {
294 &self.store
295 }
296}
297
298impl<ST> ops::DerefMut for Ecs<ST> {
299 fn deref_mut(&mut self) -> &mut ST {
300 &mut self.store
301 }
302}
303
304#[macro_export]
310macro_rules! Ecs {
311 {
312 $($compname:ident: $comptype:ty,)+
315 } => {
316 mod _ecs_inner {
317 #[allow(non_camel_case_types, dead_code)]
319 pub enum ComponentNum {
320 $($compname,)+
321 }
322
323 }
324
325 pub use self::_ecs_inner::ComponentNum;
326
327 #[derive(Serialize, Deserialize)]
328 pub struct _ComponentStore {
329 $(pub $compname: $crate::ComponentData<$comptype>),+
330 }
331
332 impl ::std::default::Default for _ComponentStore {
333 fn default() -> _ComponentStore {
334 _ComponentStore {
335 $($compname: $crate::ComponentData::new()),+
336 }
337 }
338 }
339
340 impl $crate::Store for _ComponentStore {
341 fn for_each_component<F>(&mut self, mut f: F)
342 where F: FnMut(&mut $crate::AnyComponent)
343 {
344 $(f(&mut self.$compname as &mut $crate::AnyComponent);)+
345 }
346 }
347
348 #[allow(dead_code)]
349 pub fn matches_mask(ecs: &$crate::Ecs<_ComponentStore>, e: $crate::Entity, mask: u64) -> bool {
350 $(if mask & (1 << ComponentNum::$compname as u8) != 0 && !ecs.$compname.contains(e) {
351 return false;
352 })+
353 return true;
354 }
355
356 pub trait Component {
358 fn add_to_ecs(&self, ecs: &mut $crate::Ecs<_ComponentStore>, e: $crate::Entity);
363
364 fn add_to_loadout(self, loadout: &mut Loadout);
366 }
367
368 $(impl Component for $comptype {
369 fn add_to_ecs(&self, ecs: &mut $crate::Ecs<_ComponentStore>, e: $crate::Entity) {
370 ecs.$compname.insert(e, self.clone());
371 }
372
373 fn add_to_loadout(self, loadout: &mut Loadout) {
374 loadout.$compname = Some(self);
375 }
376 })+
377
378 pub type Ecs = $crate::Ecs<_ComponentStore>;
379
380 #[derive(Clone, Debug, Serialize, Deserialize)]
383 pub struct Loadout {
384 $(pub $compname: Option<$comptype>),+
385 }
386
387 impl ::std::default::Default for Loadout {
388 fn default() -> Loadout {
389 Loadout {
390 $($compname: None),+
391 }
392 }
393 }
394
395 #[allow(dead_code)]
396 impl Loadout {
397 pub fn new() -> Loadout { Default::default() }
399
400 pub fn get(ecs: &Ecs, e: $crate::Entity) -> Loadout {
402 Loadout {
403 $($compname: ecs.$compname.get(e).cloned()),+
404 }
405 }
406
407 pub fn make(&self, ecs: &mut Ecs) -> $crate::Entity {
409 let e = ecs.make();
410 $(self.$compname.as_ref().map(|c| ecs.$compname.insert(e, c.clone()));)+
411 e
412 }
413
414 pub fn c<C: Component>(mut self, comp: C) -> Loadout {
416 comp.add_to_loadout(&mut self);
417 self
418 }
419 }
420 }
421}
422
423#[macro_export]
428macro_rules! build_mask {
429 ( $($compname:ident),+ ) => {
430 0u64 $(| (1u64 << ComponentNum::$compname as u8))+
431 }
432}