use crate::types::sync::Arc;
use crate::{ Fuse, Bomb, Flame };
pub type MultiFuze<T> = MultiFuse<T>;
#[derive(Clone)]
pub struct MultiBomb<T: Clone> {
inner: Bomb<(MultiBomb<T>, T)>
}
pub struct MultiFuse<T: Clone> {
inner: Fuse<(MultiBomb<T>, T)>
}
impl<T: Clone> MultiBomb<T> {
pub fn new() -> (MultiFuse<T>, MultiBomb<T>) {
#[cfg(not(loom))] let _counter = Arc::new(());
let fuse = MultiFuse::new(#[cfg(not(loom))] &_counter);
let bomb = Self {
inner: Bomb {
data: fuse.inner.data.clone(),
#[cfg(not(loom))] _counter,
}
};
(fuse, bomb)
}
pub fn exploded(&mut self) -> Option<T> {
let (new_bomb, value) = match self.inner.exploded() {
None => return None,
Some(data) => data.clone()
};
self.inner = new_bomb.inner;
Some(value)
}
}
impl<T: Clone> MultiFuse<T> {
fn new(#[cfg(not(loom))] _counter: &Arc<()>) -> Self {
Self {
inner: Fuse::new(#[cfg(not(loom))] _counter),
}
}
pub fn ignite(&mut self, value: T) -> Flame {
self.light(value)
}
pub fn light(&mut self, value: T) -> Flame {
let (fuse, bomb) = MultiBomb::new();
let old_fuse = std::mem::replace(&mut self.inner, fuse.inner);
old_fuse.light((bomb, value))
}
}