est_render/utils/
arcref.rs1use std::{cell::RefCell, sync::Arc};
2
3#[cfg(any(debug_assertions, feature = "enable-release-validation"))]
4use std::time::{Duration, Instant};
5
6pub struct ArcRef<T> {
10 inner: Arc<RefCell<T>>,
11}
12
13impl<T> ArcRef<T> {
14 pub fn new(value: T) -> ArcRef<T> {
16 ArcRef {
17 inner: Arc::new(RefCell::new(value)),
18 }
19 }
20
21 pub fn clone(&self) -> ArcRef<T> {
23 ArcRef {
24 inner: self.inner.clone(),
25 }
26 }
27
28 pub fn wait_borrow(&self) -> std::cell::Ref<T> {
32 #[cfg(any(debug_assertions, feature = "enable-release-validation"))]
33 let start = Instant::now();
34
35 loop {
36 if let Ok(borrow) = self.inner.try_borrow() {
37 return borrow;
38 }
39
40 #[cfg(any(debug_assertions, feature = "enable-release-validation"))]
41 if start.elapsed() > Duration::from_secs(5) {
42 panic!("wait_borrow: waited more than 5 seconds to acquire immutable borrow");
43 }
44 }
45 }
46
47 pub fn wait_borrow_mut(&self) -> std::cell::RefMut<T> {
51 #[cfg(any(debug_assertions, feature = "enable-release-validation"))]
52 let start = Instant::now();
53
54 loop {
55 if let Ok(borrow) = self.inner.try_borrow_mut() {
56 return borrow;
57 }
58
59 #[cfg(any(debug_assertions, feature = "enable-release-validation"))]
60 if start.elapsed() > Duration::from_secs(5) {
61 panic!("wait_borrow_mut: waited more than 5 seconds to acquire mutable borrow");
62 }
63 }
64 }
65
66 pub fn borrow(&self) -> std::cell::Ref<T> {
69 self.inner.borrow()
70 }
71
72 pub fn borrow_mut(&self) -> std::cell::RefMut<T> {
75 self.inner.borrow_mut()
76 }
77
78 pub fn try_borrow(&self) -> Option<std::cell::Ref<T>> {
81 self.inner.try_borrow().ok()
82 }
83
84 pub fn try_borrow_mut(&self) -> Option<std::cell::RefMut<T>> {
87 self.inner.try_borrow_mut().ok()
88 }
89
90 pub fn try_unwrap(self) -> Result<T, Self> {
93 let refcelled = Arc::try_unwrap(self.inner).map_err(|arc| ArcRef { inner: arc })?;
94
95 let inner = refcelled.into_inner();
96 Ok(inner)
97 }
98
99 pub fn ptr_eq(&self, other: &Self) -> bool {
100 Arc::ptr_eq(&self.inner, &other.inner)
101 }
102
103 pub fn as_ptr(_self: &Self) -> *const T {
104 Arc::as_ptr(&_self.inner) as *const T
105 }
106}
107
108pub mod hasher {
109 use super::ArcRef;
110 use std::hash::Hash;
111 use std::sync::Arc;
112
113 impl<T: std::hash::Hash> Hash for ArcRef<T> {
114 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
115 Arc::as_ptr(&self.inner).hash(state);
116 }
117 }
118}
119
120impl<T> std::fmt::Debug for ArcRef<T> {
121 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122 f.debug_struct("ArcRef").finish()
123 }
124}
125
126impl<T> Clone for ArcRef<T> {
127 fn clone(&self) -> Self {
128 Self {
129 inner: self.inner.clone(),
130 }
131 }
132}
133
134impl<T: PartialEq> PartialEq for ArcRef<T> {
135 fn eq(&self, other: &Self) -> bool {
136 Arc::ptr_eq(&self.inner, &other.inner)
137 }
138}
139
140impl<T: PartialEq> Eq for ArcRef<T> {}