Skip to main content

winit_async/
device.rs

1use crate::tls::{runtime, try_runtime};
2use async_local_channel::spsc;
3use std::pin::{Pin, pin};
4use std::task::{Context, Poll};
5use winit::event::{DeviceEvent, DeviceId};
6
7pub struct DeviceEventListener {
8    rx: spsc::Receiver<(DeviceId, DeviceEvent)>,
9}
10
11impl DeviceEventListener {
12    pub(crate) fn new() -> Option<Self> {
13        let rx = runtime().device_event_receiver()?;
14        Some(Self { rx })
15    }
16
17    #[inline]
18    pub const fn next_event(&mut self) -> DeviceEventFuture<'_> {
19        DeviceEventFuture { inner: self }
20    }
21}
22
23pub struct DeviceEventFuture<'a> {
24    inner: &'a DeviceEventListener,
25}
26
27impl Future for DeviceEventFuture<'_> {
28    type Output = Option<(DeviceId, DeviceEvent)>;
29
30    #[inline]
31    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
32        pin!(self.inner.rx.recv()).poll(cx).map(Result::ok)
33    }
34}
35
36impl Drop for DeviceEventListener {
37    #[inline]
38    fn drop(&mut self) {
39        if let Some(mut runtime) = try_runtime() {
40            runtime.device_event_receiver_dropped();
41        }
42    }
43}