steel_registry/
structure_processor.rs1use std::sync::OnceLock;
8
9use rustc_hash::FxHashMap;
10use steel_utils::Identifier;
11
12pub mod data;
13
14pub use data::*;
15
16#[derive(Debug)]
18pub struct StructureProcessorList {
19 pub key: Identifier,
21 pub data: StructureProcessorListData,
23 pub id: OnceLock<usize>,
25}
26
27pub type StructureProcessorListRef = &'static StructureProcessorList;
29
30pub struct StructureProcessorListRegistry {
32 lists_by_id: Vec<StructureProcessorListRef>,
33 lists_by_key: FxHashMap<Identifier, usize>,
34 allows_registering: bool,
35}
36
37impl StructureProcessorListRegistry {
38 #[must_use]
40 pub fn new() -> Self {
41 Self {
42 lists_by_id: Vec::new(),
43 lists_by_key: FxHashMap::default(),
44 allows_registering: true,
45 }
46 }
47
48 pub fn register(&mut self, entry: StructureProcessorListRef) -> usize {
50 assert!(
51 self.allows_registering,
52 "Cannot register StructureProcessorList after registry has been frozen"
53 );
54 let id = self.lists_by_id.len();
55 let cached = entry.id.get_or_init(|| id);
56 assert_eq!(
57 *cached, id,
58 "structure processor list registered with conflicting id"
59 );
60 self.lists_by_id.push(entry);
61 self.lists_by_key.insert(entry.key.clone(), id);
62 id
63 }
64
65 pub fn iter(&self) -> impl Iterator<Item = (usize, StructureProcessorListRef)> + '_ {
67 self.lists_by_id
68 .iter()
69 .enumerate()
70 .map(|(id, &entry)| (id, entry))
71 }
72}
73
74impl Default for StructureProcessorListRegistry {
75 fn default() -> Self {
76 Self::new()
77 }
78}
79
80crate::impl_registry_ext!(
81 StructureProcessorListRegistry,
82 StructureProcessorList,
83 lists_by_id,
84 lists_by_key
85);
86
87impl crate::RegistryEntry for StructureProcessorList {
88 fn key(&self) -> &Identifier {
89 &self.key
90 }
91
92 fn try_id(&self) -> Option<usize> {
93 self.id.get().copied()
94 }
95}