Skip to main content

steel_registry/
structure_processor.rs

1//! Structure processor-list registry data.
2//!
3//! Processor lists are registry data in vanilla and in datapacks. Steel stores
4//! them typed but leaves registry references as identifiers so future modded
5//! registries can resolve or replace them without reshaping configured features.
6
7use std::sync::OnceLock;
8
9use rustc_hash::FxHashMap;
10use steel_utils::Identifier;
11
12pub mod data;
13
14pub use data::*;
15
16/// A registered structure processor list.
17#[derive(Debug)]
18pub struct StructureProcessorList {
19    /// Registry key.
20    pub key: Identifier,
21    /// Typed processor-list payload.
22    pub data: StructureProcessorListData,
23    /// Cached registry ID.
24    pub id: OnceLock<usize>,
25}
26
27/// Read-only structure processor-list reference.
28pub type StructureProcessorListRef = &'static StructureProcessorList;
29
30/// Registry of structure processor lists.
31pub struct StructureProcessorListRegistry {
32    lists_by_id: Vec<StructureProcessorListRef>,
33    lists_by_key: FxHashMap<Identifier, usize>,
34    allows_registering: bool,
35}
36
37impl StructureProcessorListRegistry {
38    /// Creates an empty registry.
39    #[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    /// Registers a processor list and returns its numeric ID.
49    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    /// Iterates over all processor lists.
66    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}