winit_runtime/executor/
mod.rs1pub mod event;
10pub mod handle;
11
12use std::sync::OnceLock;
13
14use async_task::Task;
15use event_source::emit;
16use futures_lite::Future;
17use instant::Duration;
18use scoped_tls_hkt::scoped_thread_local;
19use winit::{
20 error::EventLoopError,
21 event::Event,
22 event_loop::{ControlFlow, EventLoopBuilder, EventLoopWindowTarget},
23};
24
25use crate::{device, resumed, suspended, timer::UpdateState, window};
26
27use self::{event::ExecutorEvent, handle::ExecutorHandle};
28
29pub type EventLoopTarget = EventLoopWindowTarget<ExecutorEvent>;
30
31static HANDLE: OnceLock<ExecutorHandle> = OnceLock::new();
32
33pub fn executor_handle() -> &'static ExecutorHandle {
37 HANDLE.get().expect("Executor is not started")
38}
39
40scoped_thread_local!(static EL_TARGET: EventLoopTarget);
41
42pub fn with_eventloop_target<R>(func: impl FnOnce(&EventLoopTarget) -> R) -> R {
46 EL_TARGET.with(func)
47}
48
49#[derive(Debug)]
50struct Executor {
51 _main: Task<()>,
52 handle: &'static ExecutorHandle,
53}
54
55impl Executor {
56 fn on_event(&mut self, event: Event<ExecutorEvent>, target: &EventLoopTarget) {
57 EL_TARGET.set(target, move || match event {
58 Event::UserEvent(ExecutorEvent::Wake) => {}
59
60 Event::UserEvent(ExecutorEvent::PollTask(runnable)) => {
61 runnable.run();
62 }
63
64 Event::UserEvent(ExecutorEvent::Exit) => target.exit(),
65
66 Event::DeviceEvent { device_id, event } => {
67 emit!(device(), (device_id, &event));
68 }
69
70 Event::WindowEvent {
71 window_id,
72 mut event,
73 } => {
74 emit!(window(), (window_id, &mut event));
75 }
76
77 Event::Resumed => {
78 emit!(resumed(), ());
79 }
80
81 Event::Suspended => {
82 emit!(suspended(), ());
83 }
84
85 Event::AboutToWait => {
86 if let UpdateState::WaitTimeout(next_delay) = self.handle.timer.update_next() {
87 target.set_control_flow(ControlFlow::wait_duration(Duration::from_millis(
88 next_delay.get(),
89 )));
90 } else if target.control_flow() == ControlFlow::Poll {
91 target.set_control_flow(ControlFlow::Wait);
92 }
93 }
94
95 _ => {}
96 });
97 }
98}
99
100pub fn run(main: impl Future<Output = ()>) -> Result<(), EventLoopError> {
102 let event_loop = EventLoopBuilder::with_user_event().build()?;
103
104 let handle = {
105 if HANDLE.set(ExecutorHandle::new(&event_loop)).is_err() {
106 panic!("This cannot be happen");
107 }
108
109 HANDLE.get().unwrap()
110 };
111
112 let (runnable, task) = {
113 let proxy = event_loop.create_proxy();
114
115 let main = async move {
116 main.await;
117 let _ = proxy.send_event(ExecutorEvent::Exit);
118 };
119
120 unsafe { handle.spawn_raw_unchecked(main) }
122 };
123
124 let mut executor = Executor {
125 _main: task,
126 handle,
127 };
128
129 EL_TARGET.set(&event_loop, move || runnable.run());
130
131 event_loop.run(move |event, target| executor.on_event(event, target))
132}