amethyst_ecs/
world.rs

1//! The game world in which entities reside.
2
3use super::dynvec::DynVec;
4use super::entity::{Entity, Entities};
5
6use std::any::{Any, TypeId};
7use std::collections::{HashMap, BTreeMap};
8
9type Components = HashMap<TypeId, DynVec>;
10type EntityData = HashMap<TypeId, usize>;
11
12/// A collection of entities and their respective components.
13#[derive(Debug)]
14pub struct World {
15    components: Components,
16    entities: Entities,
17    ent_data: BTreeMap<Entity, EntityData>,
18}
19
20impl World {
21    /// Creates a new empty world.
22    pub fn new() -> World {
23        World {
24            components: Components::new(),
25            entities: Entities::new(),
26            ent_data: BTreeMap::new(),
27        }
28    }
29
30    /// Creates a new entity in the world and returns a handle to it.
31    pub fn create_entity(&mut self) -> Entity {
32        let id = self.entities.create();
33        self.ent_data.insert(id, EntityData::new());
34        id
35    }
36
37    /// Destroys a given entity and removes its components.
38    pub fn destroy_entity(&mut self, entity: Entity) {
39        self.entities.destroy(entity);
40        if let Some(data) = self.ent_data.remove(&entity) {
41            for (a, b) in data {
42                self.remove_component_type(a, entity);
43            }
44        }
45    }
46
47    /// Attaches a component to an entity and returns the component's index.
48    pub fn insert_component<T: Any>(&mut self, entity: Entity, comp: T) -> Option<usize> {
49        let ent_data: &mut EntityData = match self.ent_data.get_mut(&entity) {
50            Some(s) => s,
51            None => return None,
52        };
53        let t = TypeId::of::<(Entity, T)>();
54        // is_alive check may be redundant, as we already check availability of EntityData.
55        if self.entities.is_alive(entity) && !ent_data.contains_key(&t) {
56            if let Some(c) = self.components.get_mut(&t) {
57                let id = c.add((entity, comp));
58                ent_data.insert(t, id);
59                return Some(id);
60            }
61            let mut vec = DynVec::new::<(Entity, T)>();
62            vec.add((entity, comp));
63            self.components.insert(t, vec);
64            ent_data.insert(t, 0);
65            Some(0)
66        } else {
67            None
68        }
69    }
70
71    pub fn remove_component<T: Any>(&mut self, entity: Entity) {
72        let t = TypeId::of::<(Entity, T)>();
73        self.remove_component_type(t, entity);
74    }
75
76    pub fn remove_component_type(&mut self, t: TypeId, entity: Entity) {
77        let id = self.ent_data[&entity][&t];
78        if let Some(c) = self.components.get_mut(&t) {
79            c.remove(id);
80        }
81    }
82
83    /// Returns ith component of selected type
84    pub fn component<T: Any>(&self, index: usize) -> Option<&(Entity, T)> {
85        if let Some(c) = self.components.get(&TypeId::of::<(Entity, T)>()) {
86            c.get_component(index)
87        } else {
88            None
89        }
90    }
91
92    /// Returns ith mutable component of selected type
93    pub fn component_mut<T: Any>(&mut self, index: usize) -> Option<&mut (Entity, T)> {
94        if let Some(mut c) = self.components.get_mut(&TypeId::of::<(Entity, T)>()) {
95            c.get_component_mut(index)
96        } else {
97            None
98        }
99    }
100}