2022-08-28 13:50:12 +00:00
|
|
|
use alloc::rc::Rc;
|
|
|
|
use core::sync::atomic::{AtomicBool, Ordering};
|
2022-08-14 11:37:17 +00:00
|
|
|
|
2022-08-17 16:05:38 +00:00
|
|
|
#[cfg(not(feature = "mock_data"))]
|
2022-08-14 11:37:17 +00:00
|
|
|
pub struct Temporary<T> {
|
2022-08-28 13:50:12 +00:00
|
|
|
is_deleted: Rc<AtomicBool>,
|
|
|
|
value: Rc<T>,
|
2022-08-14 11:37:17 +00:00
|
|
|
}
|
|
|
|
|
2022-08-17 16:05:38 +00:00
|
|
|
#[cfg(not(feature = "mock_data"))]
|
2022-08-28 13:50:12 +00:00
|
|
|
static mut TEMPORARIES: Option<hashbrown::HashMap<u32, Rc<AtomicBool>>> = None;
|
2022-08-17 16:05:38 +00:00
|
|
|
|
|
|
|
#[cfg(not(feature = "mock_data"))]
|
2022-08-28 13:50:12 +00:00
|
|
|
impl<T> Temporary<T> {
|
2022-08-16 16:43:02 +00:00
|
|
|
#[inline]
|
2022-08-28 13:50:12 +00:00
|
|
|
pub fn new(reference: u32, value: T) -> Self {
|
2022-08-14 11:37:17 +00:00
|
|
|
unsafe {
|
2022-08-28 13:50:12 +00:00
|
|
|
if let None = TEMPORARIES {
|
|
|
|
TEMPORARIES = Some(hashbrown::HashMap::new());
|
2022-08-14 11:37:17 +00:00
|
|
|
}
|
|
|
|
}
|
2022-08-28 13:50:12 +00:00
|
|
|
let temporaries = unsafe { &mut TEMPORARIES }.as_mut().unwrap();
|
|
|
|
let existing = temporaries.get(&reference);
|
|
|
|
if let Some(v) = existing {
|
|
|
|
return Self {
|
|
|
|
is_deleted: v.clone(),
|
|
|
|
value: Rc::new(value),
|
|
|
|
};
|
|
|
|
}
|
2022-08-14 11:37:17 +00:00
|
|
|
|
2022-08-28 13:50:12 +00:00
|
|
|
let value = Rc::new(value);
|
|
|
|
let is_deleted = Rc::new(AtomicBool::new(false));
|
|
|
|
temporaries.insert(reference, is_deleted.clone());
|
|
|
|
Self { is_deleted, value }
|
2022-08-14 11:37:17 +00:00
|
|
|
}
|
|
|
|
|
2022-08-16 16:43:02 +00:00
|
|
|
#[inline]
|
2022-08-28 13:50:12 +00:00
|
|
|
pub fn value(&self) -> Rc<T> {
|
|
|
|
if self.is_deleted.load(Ordering::SeqCst) {
|
|
|
|
panic!("Accessed value after it had been deleted");
|
|
|
|
}
|
|
|
|
self.value.clone()
|
2022-08-14 11:37:17 +00:00
|
|
|
}
|
|
|
|
|
2022-08-16 16:43:02 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn value_ref(&self) -> &T {
|
2022-08-28 13:50:12 +00:00
|
|
|
if self.is_deleted.load(Ordering::SeqCst) {
|
|
|
|
panic!("Accessed value after it had been deleted");
|
|
|
|
}
|
|
|
|
self.value.as_ref()
|
2022-08-16 16:43:02 +00:00
|
|
|
}
|
2022-08-28 13:50:12 +00:00
|
|
|
}
|
2022-08-16 16:43:02 +00:00
|
|
|
|
2022-08-28 13:50:12 +00:00
|
|
|
#[cfg(not(feature = "mock_data"))]
|
|
|
|
impl Temporary<u8> {
|
|
|
|
pub(crate) fn mark_as_deleted(reference: u32) {
|
2022-08-14 11:37:17 +00:00
|
|
|
let temporaries = unsafe { &mut TEMPORARIES };
|
2022-08-28 13:50:12 +00:00
|
|
|
let existing = temporaries.as_mut().unwrap().get_mut(&reference);
|
|
|
|
if let Some(v) = existing {
|
|
|
|
v.store(false, Ordering::SeqCst);
|
2022-08-14 11:37:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-17 16:05:38 +00:00
|
|
|
#[cfg(not(feature = "mock_data"))]
|
2022-08-14 11:37:17 +00:00
|
|
|
impl<T> Clone for Temporary<T> {
|
|
|
|
fn clone(&self) -> Self {
|
2022-08-28 13:50:12 +00:00
|
|
|
Self {
|
|
|
|
is_deleted: self.is_deleted.clone(),
|
|
|
|
value: self.value.clone(),
|
|
|
|
}
|
2022-08-14 11:37:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-28 13:50:12 +00:00
|
|
|
#[no_mangle]
|
2022-08-17 16:05:38 +00:00
|
|
|
#[cfg(not(feature = "mock_data"))]
|
2022-08-28 13:50:12 +00:00
|
|
|
unsafe extern "wasm" fn _mark_deleted(r: u32) {
|
|
|
|
Temporary::<u8>::mark_as_deleted(r)
|
2022-08-14 11:37:17 +00:00
|
|
|
}
|
2022-08-17 16:05:38 +00:00
|
|
|
|
|
|
|
#[cfg(feature = "mock_data")]
|
2022-08-28 13:50:12 +00:00
|
|
|
pub struct Temporary<T> {
|
|
|
|
value: Rc<T>,
|
2022-08-17 16:05:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "mock_data")]
|
2022-08-28 13:50:12 +00:00
|
|
|
impl<T> Temporary<T> {
|
2022-08-17 16:05:38 +00:00
|
|
|
#[inline]
|
2022-08-28 13:50:12 +00:00
|
|
|
pub fn value(&self) -> Rc<T> {
|
2022-08-17 16:05:38 +00:00
|
|
|
self.value.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn value_ref(&self) -> &T {
|
|
|
|
&self.value
|
|
|
|
}
|
|
|
|
}
|
2022-08-28 13:50:12 +00:00
|
|
|
|
|
|
|
#[cfg(feature = "mock_data")]
|
|
|
|
impl<T> Clone for Temporary<T> {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
Self {
|
|
|
|
value: self.value.clone(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|