y_engine/util/
registry.rs

1use core::panic;
2use std::hash::Hash;
3
4use rustc_hash::FxHashMap;
5
6/// A registry is just like a map but supposed to be
7/// used with an enum of IDs. It panics in many cases
8/// to make sure items are created and deleted in a planned manner.
9/// You can also think of it as a cache.
10///
11/// Use-cases: Registering and caching bindgroups, shaders, audio, etc..
12///
13/// The user is heavily adviced to do something like:
14/// ```rust,no_run
15/// #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16/// enum ExampleId {
17///     A,
18///     B,
19///     C,
20/// }
21/// type ExampleRegistry = Registry<ExampleId, BindGroup>;
22/// ```
23pub struct Registry<ID: Hash + Eq, T> {
24    items: FxHashMap<ID, T>,
25}
26
27impl<ID: Hash + Eq, T> Default for Registry<ID, T> {
28    fn default() -> Self {
29        Self {
30            items: FxHashMap::default(),
31        }
32    }
33}
34
35impl<ID: Hash + Eq, T> Registry<ID, T> {
36    pub fn new() -> Self {
37        Self::default()
38    }
39
40    /// Panics if the item already exists.
41    pub fn insert(&mut self, id: ID, item: T) {
42        if self.items.insert(id, item).is_some() {
43            panic!("Item collision in registry.");
44        }
45    }
46
47    /// Panics if the item does not yet exist.
48    pub fn overwrite(&mut self, id: ID, item: T) {
49        if self.items.insert(id, item).is_none() {
50            panic!("Item not found in registry but overwrite was called.");
51        }
52    }
53
54    /// Does not panic.
55    pub fn insert_or_overwrite(&mut self, id: ID, item: T) {
56        self.items.insert(id, item);
57    }
58
59    /// Panics if the item does not exist.
60    pub fn remove(&mut self, id: &ID) -> T {
61        self.items.remove(id).expect("Item not found in registry.")
62    }
63
64    /// Does not panic.
65    pub fn try_remove(&mut self, id: &ID) -> Option<T> {
66        self.items.remove(id)
67    }
68
69    /// Panics if the item does not exist.
70    pub fn get(&self, id: &ID) -> &T {
71        self.items.get(id).expect("Item not found in registry.")
72    }
73
74    /// Does not panic.
75    pub fn try_get(&self, id: &ID) -> Option<&T> {
76        self.items.get(id)
77    }
78
79    /// Does not panic
80    pub fn exists(&self, id: &ID) -> bool {
81        self.items.contains_key(id)
82    }
83}