Gen7ScriptsRs/pkmn_lib_interface/src/handling/cached_value.rs

37 lines
744 B
Rust

use alloc::boxed::Box;
pub struct CachedValue<T> {
init_fn: Box<dyn Fn() -> T>,
value: Option<T>,
}
impl<T> CachedValue<T>
where
T: Clone,
{
pub fn new(init_fn: Box<dyn Fn() -> T>) -> Self {
Self {
init_fn,
value: None,
}
}
#[inline]
pub fn value(&self) -> T {
if self.value.is_none() {
unsafe {
let s = self as *const Self as *mut Self;
s.as_mut().unwrap().value.replace((self.init_fn)());
}
}
self.value.as_ref().unwrap().clone()
}
}
#[macro_export]
macro_rules! cached_value {
($init: block) => {
CachedValue::new(alloc::boxed::Box::new(move || unsafe { $init }))
};
}