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}