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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use crate::archetype::{Archetype, ArchetypeLayout, Component};
use crate::{HashMap};
use std::any::TypeId;
use std::collections::hash_map;
use crate::{ArchetypeState, StaticArchetype};
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct EntityId {
pub archetype_id: u32,
pub id: u32,
}
impl EntityId {
pub const NULL: Self = EntityId {
archetype_id: u32::MAX,
id: u32::MAX,
};
pub fn new(archetype_id: u32, id: u32) -> EntityId {
EntityId { archetype_id, id }
}
}
impl Default for EntityId {
fn default() -> Self {
EntityId::NULL
}
}
pub struct EntityStorage {
archetypes: Vec<Archetype>,
archetypes_by_types: HashMap<TypeId, usize>,
archetypes_by_layout: HashMap<ArchetypeLayout, usize>,
}
impl EntityStorage {
pub fn new() -> EntityStorage {
EntityStorage {
archetypes: Vec::new(),
archetypes_by_types: Default::default(),
archetypes_by_layout: Default::default(),
}
}
fn get_or_create_archetype<S: ArchetypeState>(&mut self, state: &S) -> usize {
match self.archetypes_by_types.entry(state.ty()) {
hash_map::Entry::Vacant(e) => {
let meta = state.metadata()();
let layout = ArchetypeLayout::new((meta.component_type_ids)().into_vec());
let arch_id = match self.archetypes_by_layout.entry(layout) {
hash_map::Entry::Vacant(e) => {
let new_arch_id = self.archetypes.len();
self.archetypes
.push(Archetype::new(&(meta.component_infos)()));
e.insert(new_arch_id);
new_arch_id
}
hash_map::Entry::Occupied(e) => *e.get(),
};
e.insert(arch_id);
arch_id
}
hash_map::Entry::Occupied(e) => *e.get(),
}
}
pub fn add_entity<S>(&mut self, state: S) -> EntityId
where
S: ArchetypeState,
{
let arch_id = self.get_or_create_archetype::<S>(&state);
let arch = unsafe { self.archetypes.get_unchecked_mut(arch_id) };
let entity_id = unsafe { arch.add_entity_raw(state.as_ptr()) };
state.forget();
EntityId {
archetype_id: arch_id as u32,
id: entity_id,
}
}
pub fn get_archetype<A: StaticArchetype>(&self) -> Option<&Archetype> {
let arch_id = *self.archetypes_by_types.get(&TypeId::of::<A>())?;
unsafe { Some(self.archetypes.get_unchecked(arch_id)) }
}
pub fn get_archetype_mut<A: StaticArchetype>(&mut self) -> Option<&mut Archetype> {
let arch_id = *self.archetypes_by_types.get(&TypeId::of::<A>())?;
unsafe { Some(self.archetypes.get_unchecked_mut(arch_id)) }
}
pub fn get<C: Component>(&self, entity: &EntityId) -> Option<&C> {
let arch = self.archetypes.get(entity.archetype_id as usize)?;
arch.get(entity.id)
}
pub fn get_mut<C: Component>(&mut self, entity: &EntityId) -> Option<&mut C> {
let arch = self.archetypes.get_mut(entity.archetype_id as usize)?;
arch.get_mut(entity.id)
}
pub fn remove(&mut self, entity: &EntityId) -> bool {
if let Some(arch) = self.archetypes.get_mut(entity.archetype_id as usize) {
arch.remove(entity.id)
} else {
false
}
}
pub fn n_archetypes(&mut self) -> usize {
self.archetypes.len()
}
pub fn count_entities(&mut self) -> usize {
self.archetypes.iter().fold(0, |acc, arch| acc + arch.len())
}
}