eframe/native/
event_loop_context.rs1use std::cell::Cell;
2use winit::event_loop::ActiveEventLoop;
3
4thread_local! {
5 static CURRENT_EVENT_LOOP: Cell<Option<*const ActiveEventLoop>> = const { Cell::new(None) };
6}
7
8struct EventLoopGuard;
9
10impl EventLoopGuard {
11 fn new(event_loop: &ActiveEventLoop) -> Self {
12 CURRENT_EVENT_LOOP.with(|cell| {
13 assert!(
14 cell.get().is_none(),
15 "Attempted to set a new event loop while one is already set"
16 );
17 cell.set(Some(std::ptr::from_ref::<ActiveEventLoop>(event_loop)));
18 });
19 Self
20 }
21}
22
23impl Drop for EventLoopGuard {
24 fn drop(&mut self) {
25 CURRENT_EVENT_LOOP.with(|cell| cell.set(None));
26 }
27}
28
29#[allow(unsafe_code)]
31pub fn with_current_event_loop<F, R>(f: F) -> Option<R>
32where
33 F: FnOnce(&ActiveEventLoop) -> R,
34{
35 CURRENT_EVENT_LOOP.with(|cell| {
36 cell.get().map(|ptr| {
37 let event_loop = unsafe { &*ptr };
44 f(event_loop)
45 })
46 })
47}
48
49pub fn with_event_loop_context(event_loop: &ActiveEventLoop, f: impl FnOnce()) {
51 let _guard = EventLoopGuard::new(event_loop);
53 f();
54}