mc_core/block/
util.rs

1use std::sync::RwLock;
2use std::collections::{HashMap, HashSet};
3
4use once_cell::sync::OnceCell;
5
6use crate::block::{Block, BlockKey};
7
8
9/// A map structure that maps blocks (defined statically) to a value.
10#[repr(transparent)]
11pub struct BlockMap<T>(pub HashMap<BlockKey, T>);
12
13impl<T> BlockMap<T> {
14
15    pub fn new() -> Self {
16        Self(HashMap::new())
17    }
18
19    pub fn insert(&mut self, block: &'static Block, value: T) -> Option<T> {
20        self.0.insert(block.get_key(), value)
21    }
22
23    pub fn remove(&mut self, block: &'static Block) -> Option<T> {
24        self.0.remove(&block.get_key())
25    }
26
27    pub fn get(&self, block: &'static Block) -> Option<&T> {
28        self.0.get(&block.get_key())
29    }
30
31}
32
33/// A set structure that store blocks.
34#[repr(transparent)]
35pub struct BlockSet(pub HashSet<BlockKey>);
36
37impl BlockSet {
38
39    pub fn new() -> Self {
40        Self(HashSet::new())
41    }
42
43    pub fn insert(&mut self, block: &'static Block) -> bool {
44        self.0.insert(block.get_key())
45    }
46
47    pub fn extend<I: IntoIterator<Item = &'static Block>>(&mut self, iter: I) {
48        self.0.extend(iter.into_iter().map(|b| b.get_key()));
49    }
50
51    pub fn remove(&mut self, block: &'static Block) -> bool {
52        self.0.remove(&block.get_key())
53    }
54
55    pub fn contains(&self, block: &'static Block) -> bool {
56        self.0.contains(&block.get_key())
57    }
58
59}
60
61
62
63pub struct BlockStaticMap<T> {
64    inner: OnceCell<RwLock<BlockMap<T>>>
65}
66
67impl<T> BlockStaticMap<T> {
68
69    pub const fn new() -> Self {
70        Self { inner: OnceCell::new() }
71    }
72
73    pub fn inner(&self) -> &RwLock<BlockMap<T>> {
74        self.inner.get_or_init(|| RwLock::new(BlockMap::new()))
75    }
76
77    pub fn insert(&self, block: &'static Block, value: T) -> Option<T> {
78        self.inner().write().unwrap().insert(block, value)
79    }
80
81    pub fn insert_with(&self, func: impl FnOnce(&mut BlockMap<T>)) {
82        let mut map_guard = self.inner().write().unwrap();
83        (func)(&mut *map_guard);
84    }
85
86    pub fn remove(&self, block: &'static Block) -> Option<T> {
87        self.inner().write().unwrap().remove(block)
88    }
89
90    pub fn get(&self, block: &'static Block) -> Option<T>
91    where
92        T: Copy
93    {
94        self.inner().read().unwrap().get(block).copied()
95    }
96
97}
98
99
100pub struct BlockStaticSet {
101    inner: OnceCell<RwLock<BlockSet>>
102}
103
104impl BlockStaticSet {
105
106    pub const fn new() -> Self {
107        Self { inner: OnceCell::new() }
108    }
109
110    pub fn inner(&self) -> &RwLock<BlockSet> {
111        self.inner.get_or_init(|| RwLock::new(BlockSet::new()))
112    }
113
114    pub fn insert(&self, block: &'static Block) -> bool {
115        self.inner().write().unwrap().insert(block)
116    }
117
118    pub fn insert_with(&self, func: impl FnOnce(&mut BlockSet)) {
119        let mut set_guard = self.inner().write().unwrap();
120        (func)(&mut *set_guard);
121    }
122
123    pub fn extend<I: IntoIterator<Item = &'static Block>>(&self, iter: I) {
124        self.inner().write().unwrap().extend(iter);
125    }
126
127    pub fn remove(&self, block: &'static Block) -> bool {
128        self.inner().write().unwrap().remove(block)
129    }
130
131    pub fn contains(&self, block: &'static Block) -> bool {
132        self.inner().read().unwrap().contains(block)
133    }
134
135}