extern crate alloc;
use alloc::sync::Arc;
use core::sync::atomic::{AtomicBool, Ordering};
use std::sync::Mutex;
pub struct Exchanger<T> {
new_data: Arc<AtomicBool>,
data: Arc<Mutex<Option<T>>>,
}
impl<T> Default for Exchanger<T> {
fn default() -> Exchanger<T> {
Self {
new_data: Arc::new(AtomicBool::new(false)),
data: Arc::new(Mutex::new(None)),
}
}
}
impl<T> Clone for Exchanger<T> {
fn clone(&self) -> Exchanger<T> {
Self {
new_data: self.new_data.clone(),
data: self.data.clone(),
}
}
}
impl<T> Exchanger<T> {
pub fn new_data_available(&self) -> bool {
self.new_data.load(Ordering::Relaxed)
}
pub fn set_data_changed(&self) {
self.new_data.store(true, Ordering::Relaxed);
}
pub fn replace_data(&self, new_data: T) -> Option<T> {
let mut old = None;
if let Ok(mut lock) = self.data.lock() {
old = lock.replace(new_data);
}
self.new_data.store(true, Ordering::Relaxed);
old
}
pub fn take_data(&self) -> Option<T> {
if !self.new_data_available() {
return None;
}
self.new_data.store(false, Ordering::Relaxed);
if let Ok(mut lock) = self.data.lock() {
return lock.take();
}
None
}
}