winit-async 0.1.0

An async runtime based on the winit event loop.
Documentation
use crate::tls::{runtime, try_runtime};
use async_local_channel::spsc;
use std::pin::{Pin, pin};
use std::task::{Context, Poll};
use winit::event::{DeviceEvent, DeviceId};

pub struct DeviceEventListener {
    rx: spsc::Receiver<(DeviceId, DeviceEvent)>,
}

impl DeviceEventListener {
    pub(crate) fn new() -> Option<Self> {
        let rx = runtime().device_event_receiver()?;
        Some(Self { rx })
    }

    #[inline]
    pub const fn next_event(&mut self) -> DeviceEventFuture<'_> {
        DeviceEventFuture { inner: self }
    }
}

pub struct DeviceEventFuture<'a> {
    inner: &'a DeviceEventListener,
}

impl Future for DeviceEventFuture<'_> {
    type Output = Option<(DeviceId, DeviceEvent)>;

    #[inline]
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        pin!(self.inner.rx.recv()).poll(cx).map(Result::ok)
    }
}

impl Drop for DeviceEventListener {
    #[inline]
    fn drop(&mut self) {
        if let Some(mut runtime) = try_runtime() {
            runtime.device_event_receiver_dropped();
        }
    }
}