1use super::{
2 entry::{Entry, EntryId},
3 registry::RegistryInterface,
4};
5use std::{
6 any::Any,
7 cmp::Ord,
8 collections::BTreeMap,
9 fmt::{self, Debug},
10 sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard, Weak},
11};
12
13#[derive(Debug)]
14pub enum RegistryMapError {
15 KeyAlreadyExists,
16}
17
18impl fmt::Display for RegistryMapError {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 write!(f, "Key already exists in registry!")
21 }
22}
23
24impl std::error::Error for RegistryMapError {}
25
26pub struct RegistryMap<K, T>
28where
29 T: Send + Sync + 'static,
30 K: Ord,
31{
32 inner: Arc<RwLock<Inner<K, T>>>,
33}
34
35impl<K, T> Default for RegistryMap<K, T>
37where
38 T: Send + Sync,
39 K: Ord + Send + Sync + Clone + 'static,
40{
41 fn default() -> Self {
42 RegistryMap::new()
43 }
44}
45
46impl<K, T> Clone for RegistryMap<K, T>
48where
49 T: Send + Sync,
50 K: Ord,
51{
52 fn clone(&self) -> Self {
53 Self {
54 inner: self.inner.clone(),
55 }
56 }
57}
58
59impl<K, T> Debug for RegistryMap<K, T>
60where
61 T: Send + Sync + Debug,
62 K: Send + Sync + Clone + Ord + Debug + 'static,
63{
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 self.read().guard.map.fmt(f)
66 }
67}
68
69impl<K, T> RegistryMap<K, T>
70where
71 T: Send + Sync,
72 K: Ord + Send + Sync + Clone + 'static,
73{
74 pub fn new() -> Self {
76 RegistryMap {
77 inner: Arc::new(RwLock::new(Inner {
78 map: BTreeMap::new(),
79 entry_map: BTreeMap::new(),
80 next_id: 0,
81 remove_callback: None,
82 })),
83 }
84 }
85
86 #[must_use = "Entry will be immediately revoked if not used"]
91 pub fn register(&self, key: K, value: T) -> Result<Entry<T>, RegistryMapError> {
92 let mut lock = self.inner.write().unwrap();
93
94 if lock.map.contains_key(&key) {
95 return Err(RegistryMapError::KeyAlreadyExists);
96 }
97
98 let entry_id = lock.next_id;
99 lock.map.insert(key.clone(), value);
100 lock.entry_map.insert(entry_id, key);
101 lock.next_id += 1;
102
103 Ok(Entry::<T>::new(
104 Arc::downgrade(&self.inner) as Weak<RwLock<dyn RegistryInterface + 'static>>,
105 entry_id,
106 ))
107 }
108
109 pub fn read(&self) -> RegistryMapReadGuard<K, T> {
111 RegistryMapReadGuard::<K, T> {
112 guard: self.inner.read().unwrap(),
113 }
114 }
115
116 pub fn write(&self) -> RegistryMapWriteGuard<K, T> {
118 RegistryMapWriteGuard::<K, T> {
119 guard: self.inner.write().unwrap(),
120 }
121 }
122
123 pub fn len(&self) -> usize {
125 self.inner.read().unwrap().map.len()
126 }
127
128 pub fn is_empty(&self) -> bool {
130 self.inner.read().unwrap().map.is_empty()
131 }
132
133 pub fn set_remove_callback<C>(&self, callback: C)
136 where
137 C: FnMut(EntryId, K, T) + Send + Sync + 'static,
138 {
139 self.inner.write().unwrap().remove_callback = Some(Box::new(callback))
140 }
141}
142
143#[derive(Default)]
144struct Inner<K, T>
145where
146 T: Send + Sync,
147{
148 map: BTreeMap<K, T>,
149 entry_map: BTreeMap<EntryId, K>,
150 next_id: EntryId,
151 remove_callback: Option<Box<dyn FnMut(EntryId, K, T) + Send + Sync>>,
152}
153
154impl<K, T> RegistryInterface for Inner<K, T>
155where
156 T: Send + Sync + 'static,
157 K: Send + Sync + Ord,
158{
159 fn get(&self, entry_id: u32) -> Option<&dyn Any> {
160 let Some(key) = self.entry_map.get(&entry_id) else {
161 return None;
162 };
163 if let Some(value) = self.map.get(key) {
164 Some(value)
165 } else {
166 None
167 }
168 }
169 fn get_mut(&mut self, entry_id: EntryId) -> Option<&mut dyn Any> {
170 let Some(key) = self.entry_map.get(&entry_id) else {
171 return None;
172 };
173 if let Some(value) = self.map.get_mut(key) {
174 Some(value)
175 } else {
176 None
177 }
178 }
179 fn remove(&mut self, entry_id: EntryId) {
180 let key = self
181 .entry_map
182 .remove(&entry_id)
183 .expect("Failed to find key for EntryId during removal!");
184 if let Some(value) = self.map.remove(&key) {
185 if let Some(callback) = &mut self.remove_callback {
186 callback(entry_id, key, value);
187 }
188 }
189 }
190}
191
192pub struct RegistryMapReadGuard<'a, K, T>
194where
195 T: Send + Sync,
196{
197 guard: RwLockReadGuard<'a, Inner<K, T>>,
198}
199
200impl<'a, K, T> RegistryMapReadGuard<'a, K, T>
201where
202 T: Send + Sync,
203 K: Ord,
204{
205 pub fn iter(&'a self) -> std::collections::btree_map::Iter<'a, K, T> {
207 self.guard.map.iter()
208 }
209
210 pub fn get(&self, key: &K) -> Option<&T> {
212 self.guard.map.get(key)
213 }
214}
215
216pub struct RegistryMapWriteGuard<'a, K, T>
218where
219 T: Send + Sync,
220{
221 guard: RwLockWriteGuard<'a, Inner<K, T>>,
222}
223
224impl<'a, K, T> RegistryMapWriteGuard<'a, K, T>
225where
226 T: Send + Sync,
227 K: Ord,
228{
229 pub fn iter(&'a self) -> std::collections::btree_map::Iter<'a, K, T> {
231 self.guard.map.iter()
232 }
233
234 pub fn iter_mut(&mut self) -> std::collections::btree_map::IterMut<'_, K, T> {
236 self.guard.map.iter_mut()
237 }
238
239 pub fn get(&self, key: &K) -> Option<&T> {
241 self.guard.map.get(key)
242 }
243
244 pub fn get_mut(&mut self, key: &K) -> Option<&mut T> {
246 self.guard.map.get_mut(key)
247 }
248}