steel_registry/feature/
mod.rs1use std::sync::OnceLock;
7
8use rustc_hash::FxHashMap;
9use steel_utils::Identifier;
10
11pub mod data;
12
13pub use data::*;
14
15#[derive(Debug)]
17pub struct ConfiguredFeature {
18 pub key: Identifier,
20 pub kind: ConfiguredFeatureKind,
22 pub id: OnceLock<usize>,
24}
25
26pub type ConfiguredFeatureEntryRef = &'static ConfiguredFeature;
28
29pub struct ConfiguredFeatureRegistry {
31 features_by_id: Vec<ConfiguredFeatureEntryRef>,
32 features_by_key: FxHashMap<Identifier, usize>,
33 allows_registering: bool,
34}
35
36impl ConfiguredFeatureRegistry {
37 #[must_use]
39 pub fn new() -> Self {
40 Self {
41 features_by_id: Vec::new(),
42 features_by_key: FxHashMap::default(),
43 allows_registering: true,
44 }
45 }
46
47 pub fn register(&mut self, entry: ConfiguredFeatureEntryRef) -> usize {
49 assert!(
50 self.allows_registering,
51 "Cannot register ConfiguredFeature after registry has been frozen"
52 );
53 let id = self.features_by_id.len();
54 let cached = entry.id.get_or_init(|| id);
55 assert_eq!(
56 *cached, id,
57 "configured feature registered with conflicting id"
58 );
59 self.features_by_id.push(entry);
60 self.features_by_key.insert(entry.key.clone(), id);
61 id
62 }
63
64 pub fn iter(&self) -> impl Iterator<Item = (usize, ConfiguredFeatureEntryRef)> + '_ {
66 self.features_by_id
67 .iter()
68 .enumerate()
69 .map(|(id, &entry)| (id, entry))
70 }
71}
72
73impl Default for ConfiguredFeatureRegistry {
74 fn default() -> Self {
75 Self::new()
76 }
77}
78
79crate::impl_registry_ext!(
80 ConfiguredFeatureRegistry,
81 ConfiguredFeature,
82 features_by_id,
83 features_by_key
84);
85
86crate::impl_registry_entry_eq!(ConfiguredFeature);
87
88impl crate::RegistryEntry for ConfiguredFeature {
89 fn key(&self) -> &Identifier {
90 &self.key
91 }
92
93 fn try_id(&self) -> Option<usize> {
94 self.id.get().copied()
95 }
96}
97
98#[derive(Debug)]
100pub struct PlacedFeature {
101 pub key: Identifier,
103 pub data: PlacedFeatureData,
105 pub id: OnceLock<usize>,
107}
108
109pub type PlacedFeatureEntryRef = &'static PlacedFeature;
111
112pub struct PlacedFeatureRegistry {
114 features_by_id: Vec<PlacedFeatureEntryRef>,
115 features_by_key: FxHashMap<Identifier, usize>,
116 allows_registering: bool,
117}
118
119impl PlacedFeatureRegistry {
120 #[must_use]
122 pub fn new() -> Self {
123 Self {
124 features_by_id: Vec::new(),
125 features_by_key: FxHashMap::default(),
126 allows_registering: true,
127 }
128 }
129
130 pub fn register(&mut self, entry: PlacedFeatureEntryRef) -> usize {
132 assert!(
133 self.allows_registering,
134 "Cannot register PlacedFeature after registry has been frozen"
135 );
136 let id = self.features_by_id.len();
137 let cached = entry.id.get_or_init(|| id);
138 assert_eq!(*cached, id, "placed feature registered with conflicting id");
139 self.features_by_id.push(entry);
140 self.features_by_key.insert(entry.key.clone(), id);
141 id
142 }
143
144 pub fn iter(&self) -> impl Iterator<Item = (usize, PlacedFeatureEntryRef)> + '_ {
146 self.features_by_id
147 .iter()
148 .enumerate()
149 .map(|(id, &entry)| (id, entry))
150 }
151}
152
153impl Default for PlacedFeatureRegistry {
154 fn default() -> Self {
155 Self::new()
156 }
157}
158
159crate::impl_registry_ext!(
160 PlacedFeatureRegistry,
161 PlacedFeature,
162 features_by_id,
163 features_by_key
164);
165
166crate::impl_registry_entry_eq!(PlacedFeature);
167
168impl crate::RegistryEntry for PlacedFeature {
169 fn key(&self) -> &Identifier {
170 &self.key
171 }
172
173 fn try_id(&self) -> Option<usize> {
174 self.id.get().copied()
175 }
176}