tx2_core/
component.rs

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    // Map<EntityId, Map<ComponentId, Vec<Box<dyn Component>>>>
43    components: HashMap<EntityId, HashMap<ComponentId, Vec<Box<dyn Component>>>>,
44    // Map<ComponentId, Set<EntityId>>
45    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}