use anyhow::{Result, bail};
#[cfg(feature = "locktick")]
use locktick::{LockGuard, parking_lot::RwLock};
#[cfg(not(feature = "locktick"))]
use parking_lot::RwLock;
use parking_lot::RwLockReadGuard;
pub struct CallbackHandle<C: Clone + Send + Sync> {
callback: RwLock<Option<C>>,
}
impl<C: Send + Sync + Clone> Default for CallbackHandle<C> {
fn default() -> Self {
Self { callback: RwLock::new(None) }
}
}
impl<C: Send + Sync + Clone> CallbackHandle<C> {
pub fn set(&self, callback: C) -> Result<()> {
let prev = self.callback.write().replace(callback);
if prev.is_some() {
bail!("Callback was already set");
}
Ok(())
}
#[inline]
pub fn get(&self) -> Option<C> {
self.callback.read().clone()
}
#[cfg(feature = "locktick")]
#[inline]
pub fn get_ref(&self) -> LockGuard<RwLockReadGuard<'_, Option<C>>> {
self.callback.read()
}
#[cfg(not(feature = "locktick"))]
#[inline]
pub fn get_ref(&self) -> RwLockReadGuard<'_, Option<C>> {
self.callback.read()
}
pub fn clear(&self) {
let _ = self.callback.write().take();
}
}