@@ -104,7 +104,7 @@ impl<T> ThreadMsgTargetSubclassInput<T> {
104
104
105
105
pub struct EventLoop < T : ' static > {
106
106
thread_msg_sender : Sender < T > ,
107
- window_target : RootELW < T > ,
107
+ window_target : Rc < RootELW < T > > ,
108
108
}
109
109
110
110
pub struct EventLoopWindowTarget < T : ' static > {
@@ -113,6 +113,11 @@ pub struct EventLoopWindowTarget<T: 'static> {
113
113
pub ( crate ) runner_shared : EventLoopRunnerShared < T > ,
114
114
}
115
115
116
+ pub struct EventLoopEmbedded < ' a , T : ' static > {
117
+ window_target : Rc < RootELW < T > > ,
118
+ _function_lifetime : PhantomData < & ' a ( ) > ,
119
+ }
120
+
116
121
macro_rules! main_thread_check {
117
122
( $fn_name: literal) => { {
118
123
let thread_id = unsafe { processthreadsapi:: GetCurrentThreadId ( ) } ;
@@ -163,14 +168,14 @@ impl<T: 'static> EventLoop<T> {
163
168
164
169
EventLoop {
165
170
thread_msg_sender,
166
- window_target : RootELW {
171
+ window_target : Rc :: new ( RootELW {
167
172
p : EventLoopWindowTarget {
168
173
thread_id,
169
174
thread_msg_target,
170
175
runner_shared,
171
176
} ,
172
177
_marker : PhantomData ,
173
- } ,
178
+ } ) ,
174
179
}
175
180
}
176
181
@@ -186,49 +191,62 @@ impl<T: 'static> EventLoop<T> {
186
191
:: std:: process:: exit ( 0 ) ;
187
192
}
188
193
189
- pub fn run_return < F > ( & mut self , mut event_handler : F )
194
+ pub fn run_return < F > ( & mut self , event_handler : F )
190
195
where
191
196
F : FnMut ( Event < ' _ , T > , & RootELW < T > , & mut ControlFlow ) ,
192
197
{
193
- let event_loop_windows_ref = & self . window_target ;
194
-
195
- unsafe {
196
- self . window_target
197
- . p
198
- . runner_shared
199
- . set_event_handler ( move |event, control_flow| {
200
- event_handler ( event, event_loop_windows_ref, control_flow)
201
- } ) ;
202
- }
203
-
204
- let runner = & self . window_target . p . runner_shared ;
205
-
206
198
unsafe {
199
+ let runner = self . embedded_runner ( event_handler) ;
207
200
let mut msg = mem:: zeroed ( ) ;
208
201
209
- runner. poll ( ) ;
210
202
' main: loop {
211
203
if 0 == winuser:: GetMessageW ( & mut msg, ptr:: null_mut ( ) , 0 , 0 ) {
212
204
break ' main;
213
205
}
214
206
winuser:: TranslateMessage ( & mut msg) ;
215
207
winuser:: DispatchMessageW ( & mut msg) ;
216
208
217
- if let Err ( payload) = runner. take_panic_error ( ) {
218
- runner. reset_runner ( ) ;
219
- panic:: resume_unwind ( payload) ;
220
- }
209
+ runner. resume_panic_if_necessary ( ) ;
221
210
222
- if runner. control_flow ( ) == ControlFlow :: Exit && !runner . handling_events ( ) {
211
+ if runner. exit_requested ( ) {
223
212
break ' main;
224
213
}
225
214
}
226
215
}
216
+ }
227
217
218
+ pub fn run_embedded < ' a , F > ( mut self , event_handler : F ) -> EventLoopEmbedded < ' a , T >
219
+ where
220
+ F : ' a + FnMut ( Event < ' _ , T > , & RootELW < T > , & mut ControlFlow )
221
+ {
228
222
unsafe {
229
- runner. call_event_handler ( Event :: LoopDestroyed ) ;
223
+ self . embedded_runner ( event_handler)
224
+ }
225
+ }
226
+
227
+ unsafe fn embedded_runner < ' a , F > (
228
+ & mut self ,
229
+ mut event_handler : F
230
+ ) -> EventLoopEmbedded < ' a , T >
231
+ where
232
+ F : ' a + FnMut ( Event < ' _ , T > , & RootELW < T > , & mut ControlFlow )
233
+ {
234
+ let window_target = self . window_target . clone ( ) ;
235
+ let event_loop_windows_ptr = & * window_target as * const RootELW < T > ;
236
+
237
+ window_target
238
+ . p
239
+ . runner_shared
240
+ . set_event_handler ( move |event, control_flow| {
241
+ event_handler ( event, & * event_loop_windows_ptr, control_flow)
242
+ } ) ;
243
+
244
+ window_target. p . runner_shared . poll ( ) ;
245
+
246
+ EventLoopEmbedded {
247
+ window_target,
248
+ _function_lifetime : PhantomData ,
230
249
}
231
- runner. reset_runner ( ) ;
232
250
}
233
251
234
252
pub fn create_proxy ( & self ) -> EventLoopProxy < T > {
@@ -239,6 +257,39 @@ impl<T: 'static> EventLoop<T> {
239
257
}
240
258
}
241
259
260
+ impl < T > EventLoopEmbedded < ' _ , T > {
261
+ pub fn exit_requested ( & self ) -> bool {
262
+ let runner = & self . window_target . p . runner_shared ;
263
+ runner. control_flow ( ) == ControlFlow :: Exit && !runner. handling_events ( )
264
+ }
265
+
266
+ pub fn resume_panic_if_necessary ( & self ) {
267
+ let runner = & self . window_target . p . runner_shared ;
268
+
269
+ if let Err ( payload) = runner. take_panic_error ( ) {
270
+ runner. reset_runner ( ) ;
271
+ panic:: resume_unwind ( payload) ;
272
+ }
273
+ }
274
+ }
275
+
276
+ impl < T > Drop for EventLoopEmbedded < ' _ , T > {
277
+ fn drop ( & mut self ) {
278
+ unsafe {
279
+ self . window_target . p . runner_shared . call_event_handler ( Event :: LoopDestroyed ) ;
280
+ self . window_target . p . runner_shared . reset_runner ( ) ;
281
+ }
282
+ }
283
+ }
284
+
285
+ impl < T > Drop for EventLoopWindowTarget < T > {
286
+ fn drop ( & mut self ) {
287
+ unsafe {
288
+ winuser:: DestroyWindow ( self . thread_msg_target ) ;
289
+ }
290
+ }
291
+ }
292
+
242
293
impl < T > EventLoopWindowTarget < T > {
243
294
#[ inline( always) ]
244
295
pub ( crate ) fn create_thread_executor ( & self ) -> EventLoopThreadExecutor {
@@ -380,14 +431,6 @@ fn dur2timeout(dur: Duration) -> DWORD {
380
431
. unwrap_or ( winbase:: INFINITE )
381
432
}
382
433
383
- impl < T > Drop for EventLoop < T > {
384
- fn drop ( & mut self ) {
385
- unsafe {
386
- winuser:: DestroyWindow ( self . window_target . p . thread_msg_target ) ;
387
- }
388
- }
389
- }
390
-
391
434
pub ( crate ) struct EventLoopThreadExecutor {
392
435
thread_id : DWORD ,
393
436
target_window : HWND ,
0 commit comments