use std::sync::{
atomic::{AtomicBool, AtomicU64, Ordering},
Arc,
};
#[derive(Clone, Default)]
pub struct LiveTurnHandle {
active: Arc<AtomicBool>,
generation: Arc<AtomicU64>,
}
impl LiveTurnHandle {
pub fn begin(&self) -> LiveTurnGuard {
let generation = self.generation.fetch_add(1, Ordering::SeqCst) + 1;
self.active.store(true, Ordering::SeqCst);
LiveTurnGuard {
handle: self.clone(),
generation,
}
}
pub fn current_generation(&self) -> u64 {
self.generation.load(Ordering::SeqCst)
}
pub fn is_active(&self) -> bool {
self.active.load(Ordering::SeqCst)
}
}
pub struct LiveTurnGuard {
handle: LiveTurnHandle,
generation: u64,
}
impl LiveTurnGuard {
pub fn generation(&self) -> u64 {
self.generation
}
pub fn is_current(&self) -> bool {
self.handle.current_generation() == self.generation
}
}
impl Drop for LiveTurnGuard {
fn drop(&mut self) {
if self.is_current() {
self.handle.active.store(false, Ordering::SeqCst);
if !self.is_current() {
self.handle.active.store(true, Ordering::SeqCst);
}
}
}
}