1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
pub mod future;
use std::{
cell::RefCell,
future::Future,
ptr,
rc::Rc,
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
time::Instant,
};
use winit::{
event::{DeviceEvent, DeviceId, Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::WindowId,
};
pub struct EventLoopRunnerAsync<E: 'static> {
shared_state: Rc<RefCell<SharedState<E>>>,
}
pub struct SharedState<E: 'static> {
next_event: Option<Event<'static, E>>,
control_flow: Option<ptr::NonNull<ControlFlow>>,
}
#[must_use]
pub enum WaitCanceledCause {
ResumeTimeReached,
EventsReceived,
}
#[derive(Clone, Debug, PartialEq)]
pub enum EventAsync<E: 'static> {
WindowEvent {
window_id: WindowId,
event: WindowEvent<'static>,
},
DeviceEvent {
device_id: DeviceId,
event: DeviceEvent,
},
UserEvent(E),
Suspended,
Resumed,
}
pub trait EventLoopAsync {
type Event: 'static;
fn run_async<Fn, Fu>(self, event_handler: Fn) -> !
where
Fn: 'static + FnOnce(EventLoopRunnerAsync<Self::Event>) -> Fu,
Fu: Future<Output = ()>;
}
impl<E: 'static + std::fmt::Debug> EventLoopAsync for EventLoop<E> {
type Event = E;
fn run_async<Fn, Fu>(self, event_handler: Fn) -> !
where
Fn: 'static + FnOnce(EventLoopRunnerAsync<E>) -> Fu,
Fu: Future<Output = ()>,
{
let shared_state = Rc::new(RefCell::new(SharedState {
next_event: None,
control_flow: None,
}));
let shared_state_clone = shared_state.clone();
let mut future = Box::pin(async move {
let runner = EventLoopRunnerAsync {
shared_state: shared_state_clone,
};
event_handler(runner).await
});
let waker = unsafe { Waker::from_raw(null_waker()) };
self.run(move |event, _, control_flow| {
let control_flow_ptr = control_flow as *mut ControlFlow;
drop(control_flow);
{
let mut shared_state = shared_state.borrow_mut();
shared_state.control_flow = ptr::NonNull::new(control_flow_ptr);
shared_state.next_event = event.to_static();
}
if unsafe { *control_flow_ptr } != ControlFlow::Exit {
let mut context = Context::from_waker(&waker);
match future.as_mut().poll(&mut context) {
Poll::Ready(()) => unsafe { *control_flow_ptr = ControlFlow::Exit },
Poll::Pending => (),
}
}
shared_state.borrow_mut().control_flow = None;
});
}
}
impl<E> EventLoopRunnerAsync<E> {
pub fn wait(&mut self) -> future::WaitFuture<'_, E> {
future::WaitFuture {
shared_state: &self.shared_state,
}
}
pub fn wait_until(&mut self, timeout: Instant) -> future::WaitUntilFuture<'_, E> {
future::WaitUntilFuture {
timeout,
shared_state: &self.shared_state,
}
}
pub fn recv_events(&mut self) -> impl '_ + Future<Output = future::EventReceiver<'_, E>> {
future::EventReceiverBuilder {
shared_state: &self.shared_state,
}
}
}
fn null_waker() -> RawWaker {
RawWaker::new(ptr::null(), VTABLE)
}
const VTABLE: &RawWakerVTable = &RawWakerVTable::new(null_waker_clone, null_fn, null_fn, null_fn);
unsafe fn null_waker_clone(_: *const ()) -> RawWaker {
null_waker()
}
unsafe fn null_fn(_: *const ()) {}