1use indexmap::{IndexMap, IndexSet};
2
3use crate::{
4 Entity,
5 component::{Bundle, Component, ComponentBox, ComponentKey},
6};
7
8pub struct World {
10 pub(crate) entities: IndexSet<Entity>,
11 pub(crate) components: IndexMap<Entity, IndexMap<ComponentKey, ComponentBox>>,
12 pub(crate) resources: IndexMap<ComponentKey, ComponentBox>,
13}
14
15impl World {
16 pub fn new() -> Self {
18 let entities = 100;
19 Self {
20 entities: IndexSet::with_capacity(entities),
21 components: IndexMap::with_capacity(entities),
22 resources: IndexMap::with_capacity(5),
23 }
24 }
25
26 pub fn spawn(&mut self) -> Entity {
28 let id = self.entities.len();
29 self.entities.insert(id);
30 self.components.insert(id, IndexMap::with_capacity(1000));
31 id
32 }
33
34 pub fn despawn(&mut self, entity: Entity) {
36 self.entities.swap_remove(&entity);
37 self.components.swap_remove(&entity);
38 }
39
40 pub fn add<B: Bundle>(&mut self, entity: Entity, bundle: B) {
42 let boxes = bundle.into_boxes();
43
44 for (key, boxed) in boxes {
45 if !self.has_key(entity, &key) {
46 self.components
47 .entry(entity)
48 .or_default()
49 .insert(key, boxed);
50 }
51 }
52 }
53
54 pub fn has<C: Component>(&self, entity: Entity) -> bool {
56 self.has_key(entity, &ComponentKey::of::<C>())
57 }
58
59 pub fn has_key(&self, entity: Entity, key: &ComponentKey) -> bool {
61 let Some(components) = self.components.get(&entity) else {
62 return false;
63 };
64 components.contains_key(key)
65 }
66
67 pub fn get<C: Component>(&self, entity: Entity) -> Option<&C> {
69 let c = self
70 .components
71 .get(&entity)?
72 .get(&ComponentKey::of::<C>())?;
73 c.downcast_ref::<C>()
74 }
75
76 pub fn get_mut<C: Component>(&mut self, entity: Entity) -> Option<&mut C> {
78 let c = self
79 .components
80 .get_mut(&entity)?
81 .get_mut(&ComponentKey::of::<C>())?;
82 c.downcast_mut::<C>()
83 }
84
85 pub fn del<C: Component>(&mut self, entity: Entity) -> Option<Box<C>> {
87 let c = self
88 .components
89 .get_mut(&entity)?
90 .swap_remove(&ComponentKey::of::<C>())?;
91 c.downcast().ok()
92 }
93
94 pub fn add_res<C: Component>(&mut self, resource: C) {
103 if !self.has_res::<C>() {
104 self.resources
105 .insert(ComponentKey::of::<C>(), Box::new(resource));
106 }
107 }
108
109 pub fn has_res<C: Component>(&self) -> bool {
111 self.has_res_key(&ComponentKey::of::<C>())
112 }
113
114 pub fn has_res_key(&self, key: &ComponentKey) -> bool {
116 self.resources.contains_key(key)
117 }
118
119 pub fn get_res<C: Component>(&self) -> Option<&C> {
123 self.resources.get(&ComponentKey::of::<C>())?.downcast_ref()
124 }
125
126 pub fn get_res_mut<C: Component>(&mut self) -> Option<&mut C> {
130 self.resources
131 .get_mut(&ComponentKey::of::<C>())?
132 .downcast_mut()
133 }
134
135 pub fn del_res<C: Component>(&mut self) -> Option<Box<C>> {
137 self.resources
138 .swap_remove(&ComponentKey::of::<C>())
139 .map(|c| c.downcast().ok())
140 .flatten()
141 }
142}
143
144impl Default for World {
145 fn default() -> Self {
146 World::new()
147 }
148}