use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
use crate::{Controls, Key, Mod, Btn};
#[derive(Debug)]
pub struct Controller(Box<stick::Controller>);
impl Controller {
pub fn id(&self) -> [u16; 4] {
self.0.id()
}
pub fn name(&self) -> String {
self.0.name()
}
pub fn rumble(&mut self, power: f32) {
self.0.rumble(power)
}
}
impl Future for Controller {
type Output = Controls;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut self.get_mut().0).poll(cx)
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum Input {
Text(char),
Key(Mod, Key, bool),
Click(Mod, Btn, bool),
PointerLeave,
ScrollX(Mod, f32),
ScrollY(Mod, f32),
PointerX(f32),
PointerY(f32),
Touch(bool),
Pinch(bool),
PinchW(f32),
PinchH(f32),
PinchZ(f32),
Controller(Controller),
}
struct InputListener<T: Future<Output = (usize, Controls)> + Unpin> {
ctlr: T,
}
impl<T> Future for InputListener<T>
where
T: Future<Output = (usize, Controls)> + Unpin,
{
type Output = Input;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
if let Poll::Ready((_, Controls::Connect(new))) =
Pin::new(&mut this.ctlr).poll(cx)
{
return Poll::Ready(Input::Controller(Controller(new)));
}
#[cfg(target_arch = "wasm32")]
{
crate::web::poll(cx)
}
#[cfg(not(target_arch = "wasm32"))]
{
Poll::Pending
}
}
}
impl Input {
pub fn listener() -> impl Future<Output = Input> {
#[cfg(target_arch = "wasm32")]
crate::web::init();
InputListener {
ctlr: stick::Controller::listener(),
}
}
}