stet_core/
entity_table.rs1use crate::object::EntityId;
13
14#[derive(Clone, Debug)]
16pub struct EntityMeta {
17 pub offset: u32,
19 pub len: u32,
21 pub save_level: u16,
23 pub flags: u8,
25 pub created_after_save: u32,
29}
30
31impl EntityMeta {
32 const FLAG_GLOBAL: u8 = 1;
33
34 pub fn is_global(&self) -> bool {
36 self.flags & Self::FLAG_GLOBAL != 0
37 }
38
39 pub fn set_global(&mut self, global: bool) {
41 if global {
42 self.flags |= Self::FLAG_GLOBAL;
43 } else {
44 self.flags &= !Self::FLAG_GLOBAL;
45 }
46 }
47}
48
49pub struct EntityTable {
51 entries: Vec<EntityMeta>,
52}
53
54impl EntityTable {
55 pub fn new() -> Self {
57 Self {
58 entries: Vec::new(),
59 }
60 }
61
62 pub fn allocate(
65 &mut self,
66 offset: u32,
67 len: u32,
68 save_level: u16,
69 global: bool,
70 created_after_save: u32,
71 ) -> EntityId {
72 let index = self.entries.len() as u32;
73 let id = if global {
74 EntityId::global(index)
75 } else {
76 EntityId::local(index)
77 };
78 let mut flags = 0u8;
79 if global {
80 flags |= EntityMeta::FLAG_GLOBAL;
81 }
82 self.entries.push(EntityMeta {
83 offset,
84 len,
85 save_level,
86 flags,
87 created_after_save,
88 });
89 id
90 }
91
92 #[inline]
94 pub fn get(&self, id: EntityId) -> &EntityMeta {
95 &self.entries[id.raw_index()]
96 }
97
98 pub fn get_mut(&mut self, id: EntityId) -> &mut EntityMeta {
100 &mut self.entries[id.raw_index()]
101 }
102
103 pub fn len(&self) -> usize {
105 self.entries.len()
106 }
107
108 pub fn is_empty(&self) -> bool {
110 self.entries.is_empty()
111 }
112}
113
114impl Default for EntityTable {
115 fn default() -> Self {
116 Self::new()
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn test_allocate_and_get() {
126 let mut table = EntityTable::new();
127 let id = table.allocate(0, 10, 0, false, 0);
128 assert_eq!(id, EntityId::local(0));
129 assert!(!id.is_global());
130 let meta = table.get(id);
131 assert_eq!(meta.offset, 0);
132 assert_eq!(meta.len, 10);
133 assert_eq!(meta.save_level, 0);
134 assert!(!meta.is_global());
135 }
136
137 #[test]
138 fn test_multiple_allocations() {
139 let mut table = EntityTable::new();
140 let id0 = table.allocate(0, 5, 0, false, 0);
141 let id1 = table.allocate(5, 10, 0, true, 0);
142 assert_eq!(id0, EntityId::local(0));
143 assert_eq!(id1, EntityId::global(1));
144 assert_eq!(table.len(), 2);
145 assert!(!id0.is_global());
146 assert!(id1.is_global());
147 }
148
149 #[test]
150 fn test_get_mut() {
151 let mut table = EntityTable::new();
152 let id = table.allocate(0, 5, 0, false, 0);
153 table.get_mut(id).offset = 100;
154 assert_eq!(table.get(id).offset, 100);
155 }
156
157 #[test]
158 fn test_global_flag() {
159 let mut table = EntityTable::new();
160 let id = table.allocate(0, 5, 0, false, 0);
161 assert!(!table.get(id).is_global());
162 table.get_mut(id).set_global(true);
163 assert!(table.get(id).is_global());
164 table.get_mut(id).set_global(false);
165 assert!(!table.get(id).is_global());
166 }
167
168 #[test]
169 fn test_save_level_tracking() {
170 let mut table = EntityTable::new();
171 let id = table.allocate(0, 5, 1, false, 0);
172 assert_eq!(table.get(id).save_level, 1);
173 table.get_mut(id).save_level = 2;
174 assert_eq!(table.get(id).save_level, 2);
175 }
176
177 #[test]
178 fn test_empty_table() {
179 let table = EntityTable::new();
180 assert_eq!(table.len(), 0);
181 assert!(table.is_empty());
182 }
183
184 #[test]
185 fn test_default() {
186 let table = EntityTable::default();
187 assert!(table.is_empty());
188 }
189
190 #[test]
191 fn test_len_after_allocations() {
192 let mut table = EntityTable::new();
193 table.allocate(0, 1, 0, false, 0);
194 table.allocate(1, 2, 0, false, 0);
195 table.allocate(3, 3, 0, false, 0);
196 assert_eq!(table.len(), 3);
197 assert!(!table.is_empty());
198 }
199}