classicube_helpers/
shared.rs

1use std::{
2    cell::RefCell,
3    ops::DerefMut,
4    rc::Rc,
5    sync::{Arc, Mutex},
6};
7
8use futures::lock::Mutex as FutureMutex;
9
10pub struct SyncShared<T: ?Sized> {
11    inner: Rc<RefCell<T>>,
12}
13
14impl<T> SyncShared<T> {
15    pub fn new(value: T) -> Self {
16        Self {
17            inner: Rc::new(RefCell::new(value)),
18        }
19    }
20}
21
22impl<T: ?Sized> SyncShared<T> {
23    pub fn lock(&mut self) -> impl DerefMut<Target = T> + '_ {
24        self.inner.borrow_mut()
25    }
26
27    pub fn with<F, R>(&mut self, f: F) -> R
28    where
29        F: FnOnce(&mut T) -> R,
30    {
31        let mut guard = self.lock();
32        f(&mut guard)
33    }
34}
35
36impl<T: ?Sized> Clone for SyncShared<T> {
37    fn clone(&self) -> SyncShared<T> {
38        Self {
39            inner: self.inner.clone(),
40        }
41    }
42}
43
44pub struct ThreadShared<T: ?Sized> {
45    inner: Arc<Mutex<T>>,
46}
47
48impl<T> ThreadShared<T> {
49    pub fn new(value: T) -> Self {
50        Self {
51            inner: Arc::new(Mutex::new(value)),
52        }
53    }
54
55    pub fn lock(&mut self) -> impl DerefMut<Target = T> + '_ {
56        self.inner.lock().unwrap()
57    }
58
59    pub fn with<F, R>(&mut self, f: F) -> R
60    where
61        F: FnOnce(&mut T) -> R,
62    {
63        let mut guard = self.lock();
64        f(&mut guard)
65    }
66}
67
68impl<T: ?Sized> Clone for ThreadShared<T> {
69    fn clone(&self) -> ThreadShared<T> {
70        Self {
71            inner: self.inner.clone(),
72        }
73    }
74}
75
76pub struct FutureShared<T: ?Sized> {
77    inner: Arc<FutureMutex<T>>,
78}
79
80impl<T> FutureShared<T> {
81    pub fn new(value: T) -> Self {
82        Self {
83            inner: Arc::new(FutureMutex::new(value)),
84        }
85    }
86
87    pub async fn lock(&mut self) -> impl DerefMut<Target = T> + '_ {
88        self.inner.lock().await
89    }
90
91    pub async fn with<F, R>(&mut self, f: F) -> R
92    where
93        F: FnOnce(&mut T) -> R,
94    {
95        let mut guard = self.lock().await;
96        f(&mut guard)
97    }
98
99    pub async fn with_async<F, FUT, R>(&mut self, f: F) -> R
100    where
101        F: FnOnce(&mut T) -> FUT,
102        FUT: futures::Future<Output = R>,
103    {
104        let mut guard = self.lock().await;
105        f(&mut guard).await
106    }
107}
108
109impl<T: ?Sized> Clone for FutureShared<T> {
110    fn clone(&self) -> FutureShared<T> {
111        Self {
112            inner: self.inner.clone(),
113        }
114    }
115}
116
117#[test]
118fn test_shared() {
119    {
120        let mut shared = SyncShared::new(1);
121        shared.with(|v| {
122            println!("{v}");
123        });
124        let v = shared.lock();
125        println!("{}", {
126            let a: &u8 = &v;
127            a
128        });
129    }
130
131    {
132        #[derive(Debug)]
133        struct NotClone {}
134
135        let mut shared = ThreadShared::new(NotClone {});
136
137        {
138            let mut shared = shared.clone();
139            std::thread::spawn(move || {
140                shared.with(|v| {
141                    println!("{v:?}");
142                });
143                let v = shared.lock();
144                println!("{:?}", {
145                    let a: &NotClone = &v;
146                    a
147                });
148            });
149        }
150
151        shared.with(|v| {
152            println!("{v:?}");
153        });
154        let v = shared.lock();
155        println!("{:?}", {
156            let a: &NotClone = &v;
157            a
158        });
159    }
160
161    futures::executor::block_on(async {
162        let mut shared = FutureShared::new(3);
163        shared
164            .with(|v| {
165                println!("{v}");
166            })
167            .await;
168        let v = shared.lock().await;
169        println!("{}", {
170            let a: &u8 = &v;
171            a
172        });
173    });
174
175    {
176        trait Module {
177            fn load(&mut self);
178            fn unload(&mut self);
179        }
180
181        struct ModuleThing {}
182        impl Module for ModuleThing {
183            fn load(&mut self) {}
184
185            fn unload(&mut self) {}
186        }
187
188        let mut list_of_sync_shareds: Vec<Rc<Box<dyn Module>>> = Vec::new();
189        let mod_thing: Rc<Box<dyn Module>> = Rc::new(Box::new(ModuleThing {}));
190        list_of_sync_shareds.push(mod_thing);
191
192        let mut list_of_sync_shareds: Vec<SyncShared<Box<dyn Module>>> = Vec::new();
193        let mod_thing: SyncShared<Box<dyn Module>> = SyncShared::new(Box::new(ModuleThing {}));
194        list_of_sync_shareds.push(mod_thing);
195
196        for module in &mut list_of_sync_shareds {
197            module.lock().load();
198        }
199    }
200}