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
|
use std::any::{type_name, TypeId};
use std::collections::HashSet;
use crate::component::{Component, IsOptional as ComponentIsOptional};
use crate::lock::Lock;
use crate::type_name::TypeName;
use crate::EntityComponent;
#[derive(Debug, Default)]
pub struct ComponentStorage
{
entities: Vec<Entity>,
}
impl ComponentStorage
{
pub fn find_entity_with_components(
&self,
start_index: usize,
component_type_ids: &[(TypeId, ComponentIsOptional)],
) -> Option<(usize, &[EntityComponent])>
{
// TODO: This is a really dumb and slow way to do this. Refactor the world
// to store components in archetypes
self.entities
.iter()
.enumerate()
.skip(start_index)
.find(move |(_index, entity)| {
let entity_components = entity
.components
.iter()
.map(|component| component.id)
.collect::<HashSet<_>>();
if component_type_ids
.iter()
.filter(|(_, is_optional)| *is_optional == ComponentIsOptional::No)
.all(|(component_type_id, _)| {
entity_components.contains(component_type_id)
})
{
return true;
}
false
})
.map(|(index, entity)| (index, &*entity.components))
}
pub fn push_entity(
&mut self,
components: impl IntoIterator<Item = Box<dyn Component>>,
)
{
self.entities.push(Entity {
components: components
.into_iter()
.map(|component| EntityComponent {
id: (*component).type_id(),
name: component.type_name(),
component: Lock::new(component),
})
.collect(),
});
}
}
impl TypeName for ComponentStorage
{
fn type_name(&self) -> &'static str
{
type_name::<Self>()
}
}
#[derive(Debug, Default)]
struct Entity
{
components: Vec<EntityComponent>,
}
|