use a7n_proto::v1::Edge;
use tokio::sync::mpsc;
use crate::input::Bounds;
#[cfg(target_os = "macos")]
mod macos;
#[cfg(windows)]
mod windows;
#[cfg(all(test, not(windows)))]
#[path = "feedback/windows/geometry.rs"]
mod windows_geometry;
#[cfg(all(unix, not(target_os = "macos")))]
mod x11;
const COMMAND_CAPACITY: usize = 16;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Command {
Edge {
display: Bounds,
edge: Edge,
progress: u16,
},
Clear,
Landing {
x: i32,
y: i32,
},
Tick,
}
#[derive(Debug, Clone)]
pub struct Feedback {
commands: mpsc::Sender<Command>,
}
impl Feedback {
pub fn send(&self, command: Command) {
let _ = self.commands.try_send(command);
}
}
#[must_use]
pub fn channel() -> (Feedback, mpsc::Receiver<Command>) {
let (commands, receiver) = mpsc::channel(COMMAND_CAPACITY);
(Feedback { commands }, receiver)
}
#[must_use]
pub fn supported() -> bool {
#[cfg(any(windows, target_os = "macos"))]
{
true
}
#[cfg(all(unix, not(target_os = "macos")))]
{
crate::input::detect_backend() == crate::input::Backend::X11
}
#[cfg(not(any(windows, unix)))]
{
false
}
}
#[must_use]
pub fn start() -> Option<Feedback> {
supported().then(platform_start).flatten()
}
#[must_use]
pub const fn haptics_supported() -> bool {
cfg!(target_os = "macos")
}
#[cfg(target_os = "macos")]
use macos::start as platform_start;
#[cfg(windows)]
use windows::start as platform_start;
#[cfg(all(unix, not(target_os = "macos")))]
use x11::start as platform_start;
#[cfg(not(any(windows, unix)))]
fn platform_start() -> Option<Feedback> {
None
}