use alloc::rc::Rc; use core::sync::atomic::{AtomicBool, Ordering}; #[cfg(not(feature = "mock_data"))] pub struct Temporary { is_deleted: Rc, value: Rc, } #[cfg(not(feature = "mock_data"))] static mut TEMPORARIES: Option>> = None; #[cfg(not(feature = "mock_data"))] impl Temporary { #[inline] pub fn new(reference: u32, value: T) -> Self { unsafe { if let None = TEMPORARIES { TEMPORARIES = Some(hashbrown::HashMap::new()); } } 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), }; } let value = Rc::new(value); let is_deleted = Rc::new(AtomicBool::new(false)); temporaries.insert(reference, is_deleted.clone()); Self { is_deleted, value } } #[inline] pub fn value(&self) -> Rc { if self.is_deleted.load(Ordering::SeqCst) { panic!("Accessed value after it had been deleted"); } self.value.clone() } #[inline] pub fn value_ref(&self) -> &T { if self.is_deleted.load(Ordering::SeqCst) { panic!("Accessed value after it had been deleted"); } self.value.as_ref() } } #[cfg(not(feature = "mock_data"))] impl Temporary { pub(crate) fn mark_as_deleted(reference: u32) { let temporaries = unsafe { &mut TEMPORARIES }; let existing = temporaries.as_mut().unwrap().get_mut(&reference); if let Some(v) = existing { v.store(false, Ordering::SeqCst); } } } #[cfg(not(feature = "mock_data"))] impl Clone for Temporary { fn clone(&self) -> Self { Self { is_deleted: self.is_deleted.clone(), value: self.value.clone(), } } } #[no_mangle] #[cfg(not(feature = "mock_data"))] unsafe extern "wasm" fn _mark_deleted(r: u32) { Temporary::::mark_as_deleted(r) } #[cfg(feature = "mock_data")] pub struct Temporary { value: Rc, } #[cfg(feature = "mock_data")] impl Temporary { #[inline] pub fn value(&self) -> Rc { self.value.clone() } #[inline] pub fn value_ref(&self) -> &T { &self.value } } #[cfg(feature = "mock_data")] impl Clone for Temporary { fn clone(&self) -> Self { Self { value: self.value.clone(), } } }