steel_registry/entity_data/
serializer.rs1use rustc_hash::FxHashMap;
8use std::io;
9use steel_utils::Identifier;
10
11use super::EntityData;
12
13pub type EntityDataWriter = fn(&EntityData, &mut Vec<u8>) -> io::Result<()>;
18
19pub struct EntityDataSerializerEntry {
21 pub key: Identifier,
23 pub writer: EntityDataWriter,
25}
26
27pub type EntityDataSerializerEntryRef = &'static EntityDataSerializerEntry;
28
29pub struct EntityDataSerializerRegistry {
34 entries_by_id: Vec<EntityDataSerializerEntryRef>,
36 entries_by_key: FxHashMap<Identifier, usize>,
38 allows_registering: bool,
40}
41
42impl EntityDataSerializerRegistry {
43 #[must_use]
45 pub fn new() -> Self {
46 Self {
47 entries_by_id: Vec::new(),
48 entries_by_key: FxHashMap::default(),
49 allows_registering: true,
50 }
51 }
52
53 pub fn register(&mut self, key: Identifier, writer: EntityDataWriter) {
58 assert!(
59 self.allows_registering,
60 "Cannot register entity data serializers after the registry has been frozen"
61 );
62 assert!(
63 !self.entries_by_key.contains_key(&key),
64 "Serializer '{key}' already registered",
65 );
66
67 let entry = Box::leak(Box::new(EntityDataSerializerEntry {
68 key: key.clone(),
69 writer,
70 }));
71 let id = self.entries_by_id.len();
72 self.entries_by_id.push(entry);
73 self.entries_by_key.insert(key, id);
74 }
75
76 #[must_use]
78 pub fn get_writer(&self, id: i32) -> Option<EntityDataWriter> {
79 self.entries_by_id.get(id as usize).map(|e| e.writer)
80 }
81}
82
83impl Default for EntityDataSerializerRegistry {
84 fn default() -> Self {
85 Self::new()
86 }
87}
88
89crate::impl_registry!(
90 EntityDataSerializerRegistry,
91 EntityDataSerializerEntry,
92 entries_by_id,
93 entries_by_key,
94 entity_data_serializers
95);