use std::sync::{
atomic::{AtomicUsize, Ordering},
LazyLock,
};
use crate::context::{ACTIVE, HOVER};
pub(crate) static RUNNING: LazyLock<AtomicUsize> = LazyLock::new(|| AtomicUsize::new(1));
pub trait AppHandler: 'static {
fn running(&self) -> bool {
let running = RUNNING.swap(1, std::sync::atomic::Ordering::Acquire);
running == 1 || running == 11
}
fn stop(&self) {
let running = RUNNING.load(std::sync::atomic::Ordering::Acquire);
match running {
1 => RUNNING.store(0, std::sync::atomic::Ordering::Release),
11 => RUNNING.store(1, std::sync::atomic::Ordering::Release),
_ => panic!("Altui: Wrong 'RUNNING' value"),
}
}
fn hover(&self) -> Option<usize> {
let hover = HOVER.load(Ordering::Acquire);
match hover == 0 {
true => None,
false => Some(hover),
}
}
fn active(&self) -> Option<usize> {
let active = ACTIVE.load(Ordering::Acquire);
match active == 0 {
true => None,
false => Some(active),
}
}
fn reset_hover(&self) -> std::io::Result<usize> {
match self.active().is_some() {
true => return Err(std::io::Error::other("Failed to reset hover")),
false => {
RUNNING.store(11, std::sync::atomic::Ordering::Release);
Ok(HOVER.swap(0, Ordering::Release))
}
}
}
fn reset_active(&self) -> Option<usize> {
let prev = ACTIVE.swap(0, Ordering::Release);
match prev != 0 {
true => Some(prev),
false => None,
}
}
fn set_hover(&self, id: usize) {
ACTIVE.store(0, Ordering::Release);
HOVER.store(id, Ordering::Release);
}
fn set_active(&self) -> std::io::Result<()> {
if let Some(id) = self.hover() {
ACTIVE.store(id, Ordering::Release);
Ok(())
} else {
return Err(std::io::Error::other("Failed to set active"));
}
}
}