basin2_lib/ilib/
registry.rs

1use std::collections::HashMap;
2use std::sync::Arc;
3
4pub trait RegistryItem: Send + Sync {
5    fn registered(&self, key: &str, id: u32);
6}
7
8// we don't use a linked hashmap here due to indexing requirements
9pub struct Registry<T: RegistryItem> {
10    indexed: Vec<Arc<T>>,
11    name_index_map: HashMap<String, usize>,
12}
13
14fn namespace_normalize(key: &str) -> String {
15    let split_index = key.find(":");
16    let (namespace, name) = match split_index {
17        Some(split_index) => {
18            let (namespace, name) = key.split_at(split_index);
19            (namespace, &name[1..])
20        },
21        None => ("minecraft", key),
22    };
23    format!("{}:{}", namespace, name)
24}
25
26impl<T: RegistryItem> Registry<T> {
27
28    pub fn new() -> Registry<T> {
29        return Registry {
30            indexed: vec![],
31            name_index_map: HashMap::new(),
32        };
33    }
34
35    pub fn insert(&mut self, key: &str, item: Arc<T>) {
36        let key = namespace_normalize(key);
37        let index = self.indexed.len();
38        item.registered(&key, index as u32);
39        self.name_index_map.insert(key, index);
40        self.indexed.push(item);
41    }
42
43    pub fn get(&self, index: u32) -> Option<Arc<T>> {
44        self.indexed.get(index as usize).map(|arc| arc.clone())
45    }
46
47    pub fn get_str(&self, key: &str) -> Option<Arc<T>> {
48        let key = namespace_normalize(key);
49        return self.name_index_map.get(&key).map(|index| self.indexed[*index].clone());
50    }
51
52}