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}
177
178impl simdnbt::ToNbtTag for &BlockStateProvider {
179 fn to_nbt_tag(self) -> simdnbt::owned::NbtTag {
180 simdnbt::owned::NbtTag::Compound((self.nbt)())
181 }
182}
183
184pub struct BlockStateProviderRegistry {
186 providers_by_id: Vec<BlockStateProviderRef>,
187 providers_by_key: FxHashMap<Identifier, usize>,
188 allows_registering: bool,
189}
190
191impl BlockStateProviderRegistry {
192 #[must_use]
194 pub fn new() -> Self {
195 Self {
196 providers_by_id: Vec::new(),
197 providers_by_key: FxHashMap::default(),
198 allows_registering: true,
199 }
200 }
201
202 pub fn register(&mut self, entry: BlockStateProviderRef) -> usize {
204 assert!(
205 self.allows_registering,
206 "Cannot register BlockStateProvider after registry has been frozen"
207 );
208 let id = self.providers_by_id.len();
209 let cached = entry.id.get_or_init(|| id);
210 assert_eq!(
211 *cached, id,
212 "block state provider registered with conflicting id"
213 );
214 self.providers_by_id.push(entry);
215 self.providers_by_key.insert(entry.key.clone(), id);
216 id
217 }
218
219 pub fn iter(&self) -> impl Iterator<Item = (usize, BlockStateProviderRef)> + '_ {
221 self.providers_by_id
222 .iter()
223 .enumerate()
224 .map(|(id, &entry)| (id, entry))
225 }
226}
227
228impl Default for BlockStateProviderRegistry {
229 fn default() -> Self {
230 Self::new()
231 }
232}
233
234crate::impl_registry_ext!(
235 BlockStateProviderRegistry,
236 BlockStateProvider,
237 providers_by_id,
238 providers_by_key
239);
240
241crate::impl_registry_entry_eq!(BlockStateProvider);
242
243impl crate::RegistryEntry for BlockStateProvider {
244 fn key(&self) -> &Identifier {
245 &self.key
246 }
247
248 fn try_id(&self) -> Option<usize> {
249 self.id.get().copied()
250 }
251}