use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
static ENABLE_PENDING: AtomicBool = AtomicBool::new(false);
static ENABLED: AtomicBool = AtomicBool::new(false);
static HAS_READING: AtomicBool = AtomicBool::new(false);
static READ_X: AtomicU64 = AtomicU64::new(0);
static READ_Y: AtomicU64 = AtomicU64::new(0);
pub fn request_enable() {
ENABLE_PENDING.store(true, Ordering::Relaxed);
}
pub fn take_enable_request() -> bool {
ENABLE_PENDING.swap(false, Ordering::Relaxed)
}
pub fn set_enabled(on: bool) {
ENABLED.store(on, Ordering::Relaxed);
if !on {
HAS_READING.store(false, Ordering::Relaxed);
}
}
pub fn is_enabled() -> bool {
ENABLED.load(Ordering::Relaxed)
}
pub fn set_reading(x: f64, y: f64) {
READ_X.store(x.to_bits(), Ordering::Relaxed);
READ_Y.store(y.to_bits(), Ordering::Relaxed);
HAS_READING.store(true, Ordering::Relaxed);
}
pub fn reading() -> Option<(f64, f64)> {
if !HAS_READING.load(Ordering::Relaxed) {
return None;
}
Some((
f64::from_bits(READ_X.load(Ordering::Relaxed)),
f64::from_bits(READ_Y.load(Ordering::Relaxed)),
))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn request_reading_and_state_roundtrip() {
assert!(!take_enable_request());
request_enable();
assert!(take_enable_request());
assert!(!take_enable_request(), "request must coalesce and clear");
assert_eq!(reading(), None);
set_reading(12.5, -3.25);
assert_eq!(reading(), Some((12.5, -3.25)));
set_enabled(true);
assert!(is_enabled());
set_enabled(false);
assert!(!is_enabled());
assert_eq!(reading(), None, "disable clears the stale reading");
}
}