1use std::{
2 any::{Any, TypeId},
3 cell::UnsafeCell,
4 collections::HashMap,
5 hash::Hash,
6 marker::PhantomData,
7 ops::{Deref, DerefMut},
8 sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
9};
10
11struct MapField<T> {
12 data: T,
13 lock: RwLock<()>,
14}
15impl<T> MapField<T> {
16 fn new(data: T) -> Self {
17 Self {
18 data,
19 lock: RwLock::new(()),
20 }
21 }
22}
23
24pub struct RwHashMap<Key: Hash + Eq> {
25 #[allow(clippy::type_complexity)]
26 table: UnsafeCell<HashMap<Key, MapField<Box<UnsafeCell<dyn Any + Send>>>>>,
27 table_rw: RwLock<()>,
28}
29unsafe impl<T: Hash + Eq> Send for RwHashMap<T> {}
30unsafe impl<T: Hash + Eq> Sync for RwHashMap<T> {}
31impl<Key: Hash + Eq> RwHashMap<Key> {
32 #[allow(clippy::new_without_default)]
33 pub fn new() -> Self {
34 Self {
35 table: UnsafeCell::new(HashMap::new()),
36 table_rw: RwLock::new(()),
37 }
38 }
39 pub fn get<T: 'static + Any + Send>(&'_ self, key: &Key) -> Option<MapReader<'_, T>> {
40 let field = unsafe { self.table.get().as_ref().unwrap() }.get(key)?;
41
42 Some(MapReader::<T>::new(
43 self.table_rw.read().ok()?,
44 field.lock.read().ok()?,
45 unsafe { field.data.get().as_ref().unwrap() },
46 ))
47 }
48 pub fn get_mut<T: 'static + Any + Send>(&'_ self, key: &Key) -> Option<MapWriter<'_, T>> {
49 let field = unsafe { self.table.get().as_ref().unwrap() }.get(key)?;
50
51 Some(MapWriter::<T>::new(
52 self.table_rw.read().ok()?,
53 field.lock.write().ok()?,
54 unsafe { field.data.get().as_mut().unwrap() },
55 ))
56 }
57 pub fn insert<T: 'static + Any + Send>(&self, key: Key, value: T) -> Option<()> {
58 let lock = self.table_rw.write().ok()?;
59 unsafe { self.table.get().as_mut().unwrap() }
60 .insert(key, MapField::new(Box::new(UnsafeCell::new(value))));
61 drop(lock);
62 Some(())
63 }
64 #[allow(clippy::mut_from_ref)]
69 pub unsafe fn get_mut_nonlock<T: 'static + Any + Send>(
70 &'_ self,
71 key: &Key,
72 ) -> Option<&'_ mut T> {
73 let field = unsafe { self.table.get().as_ref().unwrap() }.get(key)?;
74
75 field.data.get().as_mut().unwrap().downcast_mut::<T>()
76 }
77}
78
79pub struct RwTypedMap(RwHashMap<TypeId>);
80unsafe impl Send for RwTypedMap {}
81unsafe impl Sync for RwTypedMap {}
82impl RwTypedMap {
83 #[allow(clippy::new_without_default)]
84 pub fn new() -> Self {
85 Self(RwHashMap::new())
86 }
87 #[inline]
88 pub fn get_of<T: 'static + Send>(&'_ self) -> Option<MapReader<'_, T>> {
89 self.0.get(&TypeId::of::<T>())
90 }
91 #[inline]
92 pub fn get_of_mut<T: 'static + Send>(&'_ self) -> Option<MapWriter<'_, T>> {
93 self.0.get_mut(&TypeId::of::<T>())
94 }
95 #[allow(clippy::mut_from_ref)]
100 #[inline]
101 pub unsafe fn get_of_mut_nonlock<T: 'static + Send>(&'_ self) -> Option<&'_ mut T> {
102 self.0.get_mut_nonlock(&TypeId::of::<T>())
103 }
104 #[inline]
105 pub fn insert_of<T: 'static + Send>(&self, value: T) {
106 self.0.insert(TypeId::of::<T>(), value);
107 }
108}
109
110pub struct RwMap {
111 named: RwHashMap<String>,
112 typed: RwTypedMap,
113}
114unsafe impl Send for RwMap {}
115unsafe impl Sync for RwMap {}
116impl RwMap {
117 #[allow(clippy::new_without_default)]
118 pub fn new() -> Self {
119 Self {
120 named: RwHashMap::<String>::new(),
121 typed: RwTypedMap::new(),
122 }
123 }
124 #[inline]
125 pub fn get_of<T: 'static + Send + Sync>(&'_ self) -> Option<MapReader<'_, T>> {
126 self.typed.get_of::<T>()
127 }
128 #[inline]
129 pub fn get_of_mut<T: 'static + Send + Sync>(&'_ self) -> Option<MapWriter<'_, T>> {
130 self.typed.get_of_mut::<T>()
131 }
132 #[allow(clippy::mut_from_ref)]
137 #[inline]
138 pub unsafe fn get_of_mut_nonlock<T: 'static + Send>(&'_ self) -> Option<&'_ mut T> {
139 self.typed.get_of_mut_nonlock::<T>()
140 }
141 #[inline]
142 pub fn insert_of<T: 'static + Send + Sync>(&self, value: T) {
143 self.typed.insert_of::<T>(value);
144 }
145 #[inline]
146 pub fn get<T: 'static + Send + Sync>(
147 &'_ self,
148 key: impl Into<String>,
149 ) -> Option<MapReader<'_, T>> {
150 self.named.get::<T>(&key.into())
151 }
152 #[inline]
153 pub fn get_mut<T: 'static + Send + Sync>(
154 &'_ self,
155 key: impl Into<String>,
156 ) -> Option<MapWriter<'_, T>> {
157 self.named.get_mut::<T>(&key.into())
158 }
159 #[allow(clippy::mut_from_ref)]
164 #[inline]
165 pub unsafe fn get_mut_nonlock<T: 'static + Send + Sync>(
166 &'_ self,
167 key: impl Into<String>,
168 ) -> Option<&'_ mut T> {
169 self.named.get_mut_nonlock::<T>(&key.into())
170 }
171 #[inline]
172 pub fn insert<T: 'static + Send + Sync>(&self, key: impl Into<String>, value: T) {
173 self.named.insert(key.into(), value);
174 }
175}
176
177pub struct MapReader<'a, T> {
178 data: &'a T,
179 _table_lock: RwLockReadGuard<'a, ()>,
180 _field_lock: RwLockReadGuard<'a, ()>,
181 _p: PhantomData<T>,
182}
183unsafe impl<'a, T> Send for MapReader<'a, T> {}
184impl<'a, T: 'static> Deref for MapReader<'a, T> {
185 type Target = T;
186 fn deref(&self) -> &Self::Target {
187 self.data
188 }
189}
190impl<'a, T: 'static> MapReader<'a, T> {
191 fn new(
192 table_lock: RwLockReadGuard<'a, ()>,
193 field_lock: RwLockReadGuard<'a, ()>,
194 data: &'a (dyn Any + Send),
195 ) -> Self {
196 Self {
197 data: data.downcast_ref::<T>().unwrap(),
198 _field_lock: field_lock,
199 _table_lock: table_lock,
200 _p: PhantomData,
201 }
202 }
203}
204
205pub struct MapWriter<'a, T> {
206 data: &'a mut T,
207 _table_lock: RwLockReadGuard<'a, ()>,
208 _field_lock: RwLockWriteGuard<'a, ()>,
209 _p: PhantomData<T>,
210}
211unsafe impl<'a, T> Send for MapWriter<'a, T> {}
212impl<'a, T: 'static> Deref for MapWriter<'a, T> {
213 type Target = T;
214 fn deref(&self) -> &Self::Target {
215 self.data
216 }
217}
218impl<'a, T: 'static> DerefMut for MapWriter<'a, T> {
219 fn deref_mut(&mut self) -> &mut Self::Target {
220 self.data
221 }
222}
223impl<'a, T: 'static> MapWriter<'a, T> {
224 fn new(
225 table_lock: RwLockReadGuard<'a, ()>,
226 field_lock: RwLockWriteGuard<'a, ()>,
227 data: &'a mut (dyn Any + Send),
228 ) -> Self {
229 Self {
230 data: data.downcast_mut::<T>().unwrap(),
231 _field_lock: field_lock,
232 _table_lock: table_lock,
233 _p: PhantomData,
234 }
235 }
236}
237
238#[derive(Clone)]
239pub struct ArcRwMap(Arc<RwMap>);
240unsafe impl Send for ArcRwMap {}
241impl Deref for ArcRwMap {
242 type Target = RwMap;
243 fn deref(&self) -> &Self::Target {
244 &self.0
245 }
246}
247impl DerefMut for ArcRwMap {
248 fn deref_mut(&mut self) -> &mut Self::Target {
249 Arc::get_mut(&mut self.0).unwrap()
250 }
251}
252impl ArcRwMap {
253 #[allow(clippy::new_without_default)]
254 pub fn new() -> Self {
255 Self(Arc::new(RwMap::new()))
256 }
257}
258
259#[macro_export]
260macro_rules! write_map {
261 ($map:expr, { $($key:expr => $val:expr),* $(,)? }) => {
262 {
263 #[allow(non_snake_case)]
264 let mut WRITE_MAP_HANDLE = $map;
265
266 $(WRITE_MAP_HANDLE.insert($key, $val);)*;
267
268 WRITE_MAP_HANDLE
269 }
270 };
271}