steel_registry/
feature.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
86impl crate::RegistryEntry for ConfiguredFeature {
87 fn key(&self) -> &Identifier {
88 &self.key
89 }
90
91 fn try_id(&self) -> Option<usize> {
92 self.id.get().copied()
93 }
94}
95
96#[derive(Debug)]
98pub struct PlacedFeature {
99 pub key: Identifier,
101 pub data: PlacedFeatureData,
103 pub id: OnceLock<usize>,
105}
106
107pub type PlacedFeatureEntryRef = &'static PlacedFeature;
109
110pub struct PlacedFeatureRegistry {
112 features_by_id: Vec<PlacedFeatureEntryRef>,
113 features_by_key: FxHashMap<Identifier, usize>,
114 allows_registering: bool,
115}
116
117impl PlacedFeatureRegistry {
118 #[must_use]
120 pub fn new() -> Self {
121 Self {
122 features_by_id: Vec::new(),
123 features_by_key: FxHashMap::default(),
124 allows_registering: true,
125 }
126 }
127
128 pub fn register(&mut self, entry: PlacedFeatureEntryRef) -> usize {
130 assert!(
131 self.allows_registering,
132 "Cannot register PlacedFeature after registry has been frozen"
133 );
134 let id = self.features_by_id.len();
135 let cached = entry.id.get_or_init(|| id);
136 assert_eq!(*cached, id, "placed feature registered with conflicting id");
137 self.features_by_id.push(entry);
138 self.features_by_key.insert(entry.key.clone(), id);
139 id
140 }
141
142 pub fn iter(&self) -> impl Iterator<Item = (usize, PlacedFeatureEntryRef)> + '_ {
144 self.features_by_id
145 .iter()
146 .enumerate()
147 .map(|(id, &entry)| (id, entry))
148 }
149}
150
151impl Default for PlacedFeatureRegistry {
152 fn default() -> Self {
153 Self::new()
154 }
155}
156
157crate::impl_registry_ext!(
158 PlacedFeatureRegistry,
159 PlacedFeature,
160 features_by_id,
161 features_by_key
162);
163
164impl crate::RegistryEntry for PlacedFeature {
165 fn key(&self) -> &Identifier {
166 &self.key
167 }
168
169 fn try_id(&self) -> Option<usize> {
170 self.id.get().copied()
171 }
172}