1
1
//! Note that this file contains two similar paths - one for [`glow`], one for [`wgpu`].
2
2
//! When making changes to one you often also want to apply it to the other.
3
3
4
- use std:: time:: Instant ;
5
-
6
- use egui_winit:: winit;
7
- use std:: sync:: Arc ;
8
- use winit:: event_loop:: { EventLoop , EventLoopProxy , EventLoopWindowTarget } ;
9
-
10
4
use super :: epi;
11
5
use crate :: common:: APP_NAME ;
12
- use crate :: run ;
6
+ use crate :: UserEvent ;
13
7
use egui_winit:: egui;
14
8
use egui_winit:: egui:: Visuals ;
15
- use egui_winit:: winit:: event:: Event ;
16
-
17
- #[ derive( Debug ) ]
18
- pub enum UserEvent {
19
- OpenWindow ,
20
- Exit ,
21
- RequestRepaint {
22
- when : Instant ,
23
- /// What the frame number was when the repaint was _requested_.
24
- frame_nr : u64 ,
25
- } ,
26
- }
9
+ use egui_winit:: winit;
10
+ use egui_winit:: winit:: event:: { Event , WindowEvent } ;
11
+ use std:: sync:: Arc ;
12
+ use std:: time:: Instant ;
13
+ use winit:: event_loop:: { EventLoop , EventLoopProxy , EventLoopWindowTarget } ;
27
14
28
15
#[ derive( Debug ) ]
29
- pub enum EventResult {
16
+ pub enum NextPaint {
17
+ /// Wait for an event
30
18
Wait ,
31
19
32
20
/// Causes a synchronous repaint inside the event handler. This should only
@@ -42,8 +30,10 @@ pub enum EventResult {
42
30
/// cause any delay like `RepaintNow`.
43
31
RepaintNext ,
44
32
33
+ /// Repaint at a particular time
45
34
RepaintAt ( Instant ) ,
46
35
36
+ /// Exit the event loop
47
37
Exit ,
48
38
}
49
39
@@ -57,6 +47,12 @@ struct WgpuWinitRunning {
57
47
egui_winit : egui_winit:: State ,
58
48
}
59
49
50
+ impl Drop for WgpuWinitRunning {
51
+ fn drop ( & mut self ) {
52
+ self . painter . destroy ( ) ;
53
+ }
54
+ }
55
+
60
56
pub type AppCreator = Box < dyn Fn ( ) -> Box < dyn epi:: App > > ;
61
57
62
58
pub struct WgpuWinitApp {
@@ -74,10 +70,10 @@ impl WgpuWinitApp {
74
70
}
75
71
}
76
72
77
- pub fn init_run_state (
73
+ pub fn launch_window (
78
74
& mut self ,
79
75
event_loop : & EventLoopWindowTarget < UserEvent > ,
80
- ) -> anyhow:: Result < ( ) > {
76
+ ) -> anyhow:: Result < NextPaint > {
81
77
let window = winit:: window:: WindowBuilder :: new ( )
82
78
. with_decorations ( true )
83
79
. with_resizable ( true )
@@ -114,7 +110,6 @@ impl WgpuWinitApp {
114
110
115
111
let event_loop_proxy = self . repaint_proxy . clone ( ) ;
116
112
egui_ctx. set_request_repaint_callback ( move |info| {
117
- log:: trace!( "request_repaint_callback: {info:?}" ) ;
118
113
let when = Instant :: now ( ) + info. after ;
119
114
let frame_nr = info. current_frame_nr ;
120
115
event_loop_proxy
@@ -134,7 +129,7 @@ impl WgpuWinitApp {
134
129
egui_winit,
135
130
} ) ;
136
131
137
- Ok ( ( ) )
132
+ Ok ( NextPaint :: RepaintNow )
138
133
}
139
134
140
135
pub fn frame_nr ( & self ) -> u64 {
@@ -145,13 +140,7 @@ impl WgpuWinitApp {
145
140
self . running . as_ref ( ) . map ( |r| & r. window )
146
141
}
147
142
148
- pub fn destroy ( & mut self ) {
149
- if let Some ( mut running) = self . running . take ( ) {
150
- running. painter . destroy ( ) ;
151
- }
152
- }
153
-
154
- pub fn run_ui_and_paint ( & mut self ) -> EventResult {
143
+ pub fn paint ( & mut self ) -> NextPaint {
155
144
if let Some ( running) = & mut self . running {
156
145
let raw_input = running. egui_winit . take_egui_input ( & running. window ) ;
157
146
@@ -178,57 +167,45 @@ impl WgpuWinitApp {
178
167
179
168
let clipped_primitives = { running. egui_ctx . tessellate ( shapes) } ;
180
169
170
+ let clear_color =
171
+ egui:: Color32 :: from_rgba_unmultiplied ( 12 , 12 , 12 , 180 ) . to_normalized_gamma_f32 ( ) ;
172
+
181
173
running. painter . paint_and_update_textures (
182
174
running. egui_ctx . pixels_per_point ( ) ,
183
- running . app . clear_color ( & running . egui_ctx . style ( ) . visuals ) ,
175
+ clear_color,
184
176
& clipped_primitives,
185
177
& textures_delta,
186
178
false ,
187
179
) ;
188
180
189
- let control_flow = if repaint_after. is_zero ( ) {
190
- EventResult :: RepaintNext
191
- } else if let Some ( repaint_after_instant) =
192
- Instant :: now ( ) . checked_add ( repaint_after)
193
- {
194
- // if repaint_after is something huge and can't be added to Instant,
195
- // we will use `ControlFlow::Wait` instead.
196
- // technically, this might lead to some weird corner cases where the user *WANTS*
197
- // winit to use `WaitUntil(MAX_INSTANT)` explicitly. they can roll their own
198
- // egui backend impl i guess.
199
- EventResult :: RepaintAt ( repaint_after_instant)
181
+ if repaint_after. is_zero ( ) {
182
+ NextPaint :: RepaintNext
183
+ } else if let Some ( repaint_after_instant) = Instant :: now ( ) . checked_add ( repaint_after) {
184
+ NextPaint :: RepaintAt ( repaint_after_instant)
200
185
} else {
201
- EventResult :: Wait
202
- } ;
203
-
204
- if running. window . is_minimized ( ) == Some ( true ) {
205
- // On Mac, a minimized Window uses up all CPU:
206
- // https://github.com/emilk/egui/issues/325
207
- // crate::profile_scope!("bg_sleep");
208
- std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 10 ) ) ;
186
+ NextPaint :: Wait
209
187
}
210
-
211
- control_flow
212
188
} else {
213
- EventResult :: Wait
189
+ NextPaint :: Wait
214
190
}
215
191
}
216
192
217
193
pub fn on_event (
218
194
& mut self ,
219
195
event_loop : & EventLoopWindowTarget < UserEvent > ,
220
196
event : & Event < ' _ , UserEvent > ,
221
- ) -> anyhow:: Result < EventResult > {
197
+ ) -> anyhow:: Result < NextPaint > {
222
198
Ok ( match event {
223
- e if matches ! ( e , Event :: Resumed )
224
- || matches ! ( e , Event :: UserEvent ( UserEvent :: OpenWindow ) ) =>
225
- {
226
- if self . running . is_none ( ) {
227
- self . init_run_state ( event_loop ) ? ;
228
- }
229
- EventResult :: RepaintNow
199
+ // When the window is closed, we destroy the Window
200
+ Event :: WindowEvent {
201
+ event : WindowEvent :: CloseRequested ,
202
+ ..
203
+ } => {
204
+ self . running = None ;
205
+ NextPaint :: Wait
230
206
}
231
- Event :: Suspended => EventResult :: Wait ,
207
+
208
+ Event :: Resumed if self . running . is_none ( ) => self . launch_window ( event_loop) ?,
232
209
233
210
Event :: WindowEvent { event, .. } => {
234
211
if let Some ( running) = & mut self . running {
@@ -248,7 +225,7 @@ impl WgpuWinitApp {
248
225
let mut repaint_asap = false ;
249
226
250
227
match & event {
251
- winit :: event :: WindowEvent :: Resized ( physical_size) => {
228
+ WindowEvent :: Resized ( physical_size) => {
252
229
repaint_asap = true ;
253
230
254
231
// Resize with 0 width and height is used by winit to signal a minimize event on Windows.
@@ -260,21 +237,17 @@ impl WgpuWinitApp {
260
237
. on_window_resized ( physical_size. width , physical_size. height ) ;
261
238
}
262
239
}
263
- winit:: event:: WindowEvent :: ScaleFactorChanged {
264
- new_inner_size, ..
265
- } => {
240
+ WindowEvent :: ScaleFactorChanged { new_inner_size, .. } => {
266
241
repaint_asap = true ;
267
242
running
268
243
. painter
269
244
. on_window_resized ( new_inner_size. width , new_inner_size. height ) ;
270
245
}
271
- winit :: event :: WindowEvent :: CloseRequested => {
246
+ WindowEvent :: CloseRequested => {
272
247
log:: debug!( "Received WindowEvent::CloseRequested" ) ;
273
- return Ok ( EventResult :: Exit ) ;
248
+ return Ok ( NextPaint :: Exit ) ;
274
249
}
275
- winit:: event:: WindowEvent :: ThemeChanged ( winit_theme)
276
- if running. follow_system_theme =>
277
- {
250
+ WindowEvent :: ThemeChanged ( winit_theme) if running. follow_system_theme => {
278
251
let visuals = visuals_from_winit_theme ( * winit_theme) ;
279
252
running. egui_ctx . set_visuals ( visuals) ;
280
253
}
@@ -285,19 +258,19 @@ impl WgpuWinitApp {
285
258
286
259
if event_response. repaint {
287
260
if repaint_asap {
288
- EventResult :: RepaintNow
261
+ NextPaint :: RepaintNow
289
262
} else {
290
- EventResult :: RepaintNext
263
+ NextPaint :: RepaintNext
291
264
}
292
265
} else {
293
- EventResult :: Wait
266
+ NextPaint :: Wait
294
267
}
295
268
} else {
296
- EventResult :: Wait
269
+ NextPaint :: Wait
297
270
}
298
271
}
299
272
300
- _ => EventResult :: Wait ,
273
+ _ => NextPaint :: Wait ,
301
274
} )
302
275
}
303
276
}
0 commit comments