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
use super::{ffi, DataHandle, Entity, World};
use std::collections::HashMap;
pub struct WorldReflection {
_id: DataHandle,
strings: HashMap<ffi::DataHandle, String>,
parameters: HashMap<ffi::DataHandle, Vec<ffi::ParameterMetaDataEntry>>,
components: Vec<ffi::ComponentMetaDataEntry>,
}
impl WorldReflection {
pub fn create() -> Self {
let data = World::create_data(ffi::CreateDataType::ComponentsMetaData, &[]);
let mut strings = HashMap::new();
let mut parameters_all = HashMap::new();
let root = data.read::<ffi::ComponentsMetaDataEntry>();
let components = DataHandle::from_ffi(root.components);
let components = components.read_vec::<ffi::ComponentMetaDataEntry>();
for c in &components {
let parameters = DataHandle::from_ffi(c.parameters);
let parameters = parameters.read_vec::<ffi::ParameterMetaDataEntry>();
let c_name = DataHandle::from_ffi(c.name).read_str();
let _ = strings.insert(c.name, c_name);
for p in ¶meters {
let p_name = DataHandle::from_ffi(p.name).read_str();
let _ = strings.insert(p.name, p_name);
}
let _ = parameters_all.insert(c.parameters, parameters);
}
Self {
_id: data,
strings,
parameters: parameters_all,
components,
}
}
pub fn get() -> &'static Self {
unsafe {
static mut REFLECTION: Option<WorldReflection> = None;
if REFLECTION.is_none() {
REFLECTION = Some(Self::create());
}
REFLECTION.as_ref().unwrap()
}
}
pub fn components(&self) -> &[ffi::ComponentMetaDataEntry] {
&self.components
}
pub fn components_for_entity(&self, entity: Entity) -> Vec<ffi::ComponentMetaDataEntry> {
let components = World::get_components_vec(entity);
let mut ret_components = self.components.clone();
ret_components.retain(|c| components.contains(&c.component_type));
ret_components
}
pub fn parameters(&self, data: ffi::DataHandle) -> &[ffi::ParameterMetaDataEntry] {
if let Some(parameters) = self.parameters.get(&data) {
parameters
} else {
&[]
}
}
pub fn string(&self, data: ffi::DataHandle) -> &str {
if let Some(string) = self.strings.get(&data) {
string
} else {
""
}
}
pub fn parameter(
&self,
component_type: ffi::ComponentType,
parameter_id: u32,
) -> Option<&ffi::ParameterMetaDataEntry> {
for component in self.components() {
if component_type == component.component_type {
for p in self.parameters(component.parameters) {
if p.parameter_id == parameter_id {
return Some(p);
}
}
}
}
None
}
}