1use std::any::Any;
2use std::collections::{HashMap, HashSet};
3use crate::entity::EntityId;
4use serde::{Serialize, de::DeserializeOwned};
5
6pub type ComponentId = String;
7
8pub trait Component: Any + Send + Sync {
9 fn as_any(&self) -> &dyn Any;
10 fn as_any_mut(&mut self) -> &mut dyn Any;
11 fn component_id(&self) -> ComponentId;
12 fn clone_box(&self) -> Box<dyn Component>;
13 fn to_json(&self) -> serde_json::Value;
14}
15
16impl<T> Component for T
17where
18 T: Any + Send + Sync + Clone + Serialize + DeserializeOwned + 'static,
19{
20 fn as_any(&self) -> &dyn Any {
21 self
22 }
23
24 fn as_any_mut(&mut self) -> &mut dyn Any {
25 self
26 }
27
28 fn component_id(&self) -> ComponentId {
29 std::any::type_name::<T>().to_string()
30 }
31
32 fn clone_box(&self) -> Box<dyn Component> {
33 Box::new(self.clone())
34 }
35
36 fn to_json(&self) -> serde_json::Value {
37 serde_json::to_value(self).unwrap_or(serde_json::Value::Null)
38 }
39}
40
41pub struct ComponentStore {
42 components: HashMap<EntityId, HashMap<ComponentId, Vec<Box<dyn Component>>>>,
44 component_index: HashMap<ComponentId, HashSet<EntityId>>,
46}
47
48impl ComponentStore {
49 pub fn new() -> Self {
50 Self {
51 components: HashMap::new(),
52 component_index: HashMap::new(),
53 }
54 }
55
56 pub fn add(&mut self, entity_id: EntityId, component: Box<dyn Component>) {
57 let component_id = component.component_id();
58
59 let entity_components = self.components.entry(entity_id).or_insert_with(HashMap::new);
60 let list = entity_components.entry(component_id.clone()).or_insert_with(Vec::new);
61 list.push(component);
62
63 let index = self.component_index.entry(component_id).or_insert_with(HashSet::new);
64 index.insert(entity_id);
65 }
66
67 pub fn remove(&mut self, entity_id: EntityId, component_id: &str) -> bool {
68 if let Some(entity_components) = self.components.get_mut(&entity_id) {
69 if entity_components.remove(component_id).is_some() {
70 if let Some(index) = self.component_index.get_mut(component_id) {
71 index.remove(&entity_id);
72 if index.is_empty() {
73 self.component_index.remove(component_id);
74 }
75 }
76 return true;
77 }
78 }
79 false
80 }
81
82 pub fn get<T: Component>(&self, entity_id: EntityId) -> Option<&T> {
83 let component_id = std::any::type_name::<T>().to_string();
84 if let Some(entity_components) = self.components.get(&entity_id) {
85 if let Some(list) = entity_components.get(&component_id) {
86 if let Some(comp) = list.first() {
87 return comp.as_any().downcast_ref::<T>();
88 }
89 }
90 }
91 None
92 }
93
94 pub fn get_all_by_type<T: Component>(&self, entity_id: EntityId) -> Vec<&T> {
95 let component_id = std::any::type_name::<T>().to_string();
96 let mut result = Vec::new();
97 if let Some(entity_components) = self.components.get(&entity_id) {
98 if let Some(list) = entity_components.get(&component_id) {
99 for comp in list {
100 if let Some(typed) = comp.as_any().downcast_ref::<T>() {
101 result.push(typed);
102 }
103 }
104 }
105 }
106 result
107 }
108
109 pub fn has(&self, entity_id: EntityId, component_id: &str) -> bool {
110 if let Some(entity_components) = self.components.get(&entity_id) {
111 return entity_components.contains_key(component_id);
112 }
113 false
114 }
115
116 pub fn get_all(&self, entity_id: EntityId) -> Vec<&Box<dyn Component>> {
117 let mut result = Vec::new();
118 if let Some(entity_components) = self.components.get(&entity_id) {
119 for list in entity_components.values() {
120 result.extend(list);
121 }
122 }
123 result
124 }
125
126 pub fn get_entities_with_component(&self, component_id: &str) -> HashSet<EntityId> {
127 self.component_index.get(component_id).cloned().unwrap_or_default()
128 }
129
130 pub fn remove_all_components(&mut self, entity_id: EntityId) {
131 if let Some(entity_components) = self.components.remove(&entity_id) {
132 for component_id in entity_components.keys() {
133 if let Some(index) = self.component_index.get_mut(component_id) {
134 index.remove(&entity_id);
135 if index.is_empty() {
136 self.component_index.remove(component_id);
137 }
138 }
139 }
140 }
141 }
142
143 pub fn clear(&mut self) {
144 self.components.clear();
145 self.component_index.clear();
146 }
147
148 pub fn get_all_entities(&self) -> HashSet<EntityId> {
149 self.components.keys().cloned().collect()
150 }
151}