1
1
use std:: {
2
- collections:: VecDeque , hint:: unreachable_unchecked, marker:: PhantomData ,
3
- mem, os:: raw:: * , process:: exit, sync:: { Arc , Mutex , Weak } ,
2
+ collections:: VecDeque , fmt:: { self , Debug , Formatter } ,
3
+ hint:: unreachable_unchecked, marker:: PhantomData , mem, os:: raw:: * ,
4
+ process:: exit, sync:: { Arc , Mutex , Weak } ,
4
5
} ;
5
6
6
7
use cocoa:: {
21
22
window,
22
23
} ;
23
24
use platform_impl:: platform:: {
24
- DEVICE_ID , monitor:: { self , MonitorHandle } , window:: UnownedWindow ,
25
+ app_delegate:: APP_DELEGATE_CLASS , DEVICE_ID , monitor:: { self , MonitorHandle } ,
26
+ observer:: { EventLoopWaker , setup_control_flow_observers} ,
27
+ util:: IdRef , window:: UnownedWindow ,
25
28
} ;
26
29
27
30
#[ derive( Default ) ]
@@ -87,6 +90,118 @@ impl WindowList {
87
90
}
88
91
}
89
92
93
+ lazy_static ! {
94
+ pub static ref HANDLER : Mutex <Handler > = Default :: default ( ) ;
95
+ }
96
+
97
+ #[ derive( Default ) ]
98
+ pub struct Handler {
99
+ control_flow : ControlFlow ,
100
+ control_flow_prev : ControlFlow ,
101
+ callback : Option < Box < dyn EventHandler > > ,
102
+ waker : EventLoopWaker ,
103
+ }
104
+
105
+ unsafe impl Send for Handler { }
106
+ unsafe impl Sync for Handler { }
107
+
108
+ impl Handler {
109
+ pub fn launched ( & mut self ) {
110
+ self . waker . start ( ) ;
111
+ if let Some ( ref mut callback) = self . callback {
112
+ callback. handle_nonuser_event ( Event :: NewEvents ( StartCause :: Init ) , & mut self . control_flow ) ;
113
+ }
114
+ }
115
+
116
+ pub fn wakeup ( & mut self ) {
117
+ self . control_flow_prev = self . control_flow ;
118
+ let cause = match self . control_flow {
119
+ ControlFlow :: Poll => StartCause :: Poll ,
120
+ /*ControlFlow::Wait => StartCause::WaitCancelled {
121
+ start,
122
+ requested_resume: None,
123
+ },
124
+ ControlFlow::WaitUntil(requested_resume) => {
125
+ if Instant::now() >= requested_resume {
126
+ StartCause::ResumeTimeReached {
127
+ start,
128
+ requested_resume,
129
+ }
130
+ } else {
131
+ StartCause::WaitCancelled {
132
+ start,
133
+ requested_resume: Some(requested_resume),
134
+ }
135
+ }
136
+ },*/
137
+ ControlFlow :: Exit => panic ! ( "unexpected `ControlFlow::Exit`" ) ,
138
+ _ => unimplemented ! ( ) ,
139
+ } ;
140
+ if let Some ( ref mut callback) = self . callback {
141
+ callback. handle_nonuser_event ( Event :: NewEvents ( cause) , & mut self . control_flow ) ;
142
+ }
143
+ }
144
+
145
+ pub fn cleared ( & mut self ) {
146
+ if let Some ( ref mut callback) = self . callback {
147
+ callback. handle_nonuser_event ( Event :: EventsCleared , & mut self . control_flow ) ;
148
+ }
149
+ let old = self . control_flow_prev ;
150
+ let new = self . control_flow ;
151
+ match ( old, new) {
152
+ ( ControlFlow :: Poll , ControlFlow :: Poll ) => ( ) ,
153
+ ( ControlFlow :: Wait , ControlFlow :: Wait ) => ( ) ,
154
+ ( ControlFlow :: WaitUntil ( old_instant) , ControlFlow :: WaitUntil ( new_instant) ) if old_instant == new_instant => ( ) ,
155
+ ( _, ControlFlow :: Wait ) => self . waker . stop ( ) ,
156
+ ( _, ControlFlow :: WaitUntil ( new_instant) ) => self . waker . start_at ( new_instant) ,
157
+ ( _, ControlFlow :: Poll ) => self . waker . start ( ) ,
158
+ ( _, ControlFlow :: Exit ) => ( ) ,
159
+ }
160
+ }
161
+ }
162
+
163
+ pub trait EventHandler : Debug {
164
+ fn handle_nonuser_event ( & mut self , event : Event < Never > , control_flow : & mut ControlFlow ) ;
165
+ //fn handle_user_events(&mut self, control_flow: &mut ControlFlow);
166
+ }
167
+
168
+ struct EventLoopHandler < F , T : ' static > {
169
+ callback : F ,
170
+ event_loop : RootELW < T > ,
171
+ }
172
+
173
+ impl < F , T : ' static > Debug for EventLoopHandler < F , T > {
174
+ fn fmt ( & self , formatter : & mut Formatter ) -> fmt:: Result {
175
+ formatter. debug_struct ( "EventLoopHandler" )
176
+ . field ( "event_loop" , & self . event_loop )
177
+ . finish ( )
178
+ }
179
+ }
180
+
181
+ impl < F , T > EventHandler for EventLoopHandler < F , T >
182
+ where
183
+ F : ' static + FnMut ( Event < T > , & RootELW < T > , & mut ControlFlow ) ,
184
+ T : ' static ,
185
+ {
186
+ fn handle_nonuser_event ( & mut self , event : Event < Never > , control_flow : & mut ControlFlow ) {
187
+ ( self . callback ) (
188
+ event. userify ( ) ,
189
+ & self . event_loop ,
190
+ control_flow,
191
+ ) ;
192
+ }
193
+
194
+ /*fn handle_user_events(&mut self, control_flow: &mut ControlFlow) {
195
+ for event in self.event_loop.inner.receiver.try_iter() {
196
+ (self.callback)(
197
+ Event::UserEvent(event),
198
+ &self.event_loop,
199
+ control_flow,
200
+ );
201
+ }
202
+ }*/
203
+ }
204
+
90
205
pub struct EventLoopWindowTarget < T : ' static > {
91
206
pub pending_events : Arc < Mutex < PendingEvents > > ,
92
207
pub window_list : Arc < Mutex < WindowList > > ,
@@ -105,19 +220,35 @@ impl<T> Default for EventLoopWindowTarget<T> {
105
220
106
221
pub struct EventLoop < T : ' static > {
107
222
elw_target : RootELW < T > ,
223
+ delegate : IdRef ,
108
224
modifiers : Modifiers ,
109
225
}
110
226
111
227
impl < T > EventLoop < T > {
112
228
pub fn new ( ) -> Self {
113
- // Mark this thread as the main thread of the Cocoa event system.
114
- //
115
- // This must be done before any worker threads get a chance to call it
116
- // (e.g., via `EventLoopProxy::wakeup()`), causing a wrong thread to be
117
- // marked as the main thread.
118
- unsafe { NSApp ( ) } ;
229
+ let delegate = unsafe {
230
+ if !msg_send ! [ class!( NSThread ) , isMainThread] {
231
+ // This check should be in `new` instead
232
+ panic ! ( "Events can only be polled from the main thread on macOS" ) ;
233
+ }
234
+
235
+ // Mark this thread as the main thread of the Cocoa event system.
236
+ //
237
+ // This must be done before any worker threads get a chance to call it
238
+ // (e.g., via `EventLoopProxy::wakeup()`), causing a wrong thread to be
239
+ // marked as the main thread.
240
+ let app = NSApp ( ) ;
241
+
242
+ let delegate = IdRef :: new ( msg_send ! [ APP_DELEGATE_CLASS . 0 , new] ) ;
243
+ let pool = NSAutoreleasePool :: new ( nil) ;
244
+ let _: ( ) = msg_send ! [ app, setDelegate: * delegate] ;
245
+ let _: ( ) = msg_send ! [ pool, drain] ;
246
+ delegate
247
+ } ;
248
+ setup_control_flow_observers ( ) ;
119
249
EventLoop {
120
250
elw_target : RootELW :: new ( Default :: default ( ) ) ,
251
+ delegate, // is this necessary?
121
252
modifiers : Default :: default ( ) ,
122
253
}
123
254
}
@@ -139,18 +270,8 @@ impl<T> EventLoop<T> {
139
270
pub fn run < F > ( mut self , mut callback : F ) -> !
140
271
where F : ' static + FnMut ( Event < T > , & RootELW < T > , & mut ControlFlow ) ,
141
272
{
142
- unsafe {
143
- if !msg_send ! [ class!( NSThread ) , isMainThread] {
144
- panic ! ( "Events can only be polled from the main thread on macOS" ) ;
145
- }
146
- }
147
-
148
- let mut control_flow = Default :: default ( ) ;
149
- let mut cause = StartCause :: Init ;
150
-
273
+ /*
151
274
loop {
152
- callback ( Event :: NewEvents ( cause) , self . window_target ( ) , & mut control_flow) ;
153
-
154
275
{
155
276
trace!("Locked pending events in `run`");
156
277
let mut pending = self.elw_target
@@ -169,38 +290,24 @@ impl<T> EventLoop<T> {
169
290
}
170
291
}
171
292
172
- let maybe_event = unsafe {
173
- let pool = NSAutoreleasePool :: new ( nil) ;
174
-
175
- // Wait for the next event. Note that this function blocks during resize.
176
- let ns_event = NSApp ( ) . nextEventMatchingMask_untilDate_inMode_dequeue_ (
177
- NSEventMask :: NSAnyEventMask . bits ( ) | NSEventMask :: NSEventMaskPressure . bits ( ) ,
178
- NSDate :: distantFuture ( nil) ,
179
- NSDefaultRunLoopMode ,
180
- YES ,
181
- ) ;
182
-
183
- let maybe_event = self . translate_event ( ns_event) ;
184
-
185
- // Release the pool before calling the top callback in case the user calls either
186
- // `run_forever` or `poll_events` within the callback.
187
- let _: ( ) = msg_send ! [ pool, release] ;
188
-
189
- maybe_event
190
- } ;
191
-
192
- if let Some ( event) = maybe_event {
193
- callback ( event. userify ( ) , self . window_target ( ) , & mut control_flow) ;
194
- }
195
-
196
- callback ( Event :: EventsCleared , self . window_target ( ) , & mut control_flow) ;
197
-
198
293
if let ControlFlow::Exit = control_flow {
199
294
callback(Event::LoopDestroyed, self.window_target(), &mut control_flow);
200
295
exit(0);
201
296
}
297
+ }
298
+ */
202
299
203
- cause = StartCause :: Poll ;
300
+ unsafe {
301
+ let _pool = NSAutoreleasePool :: new ( nil) ;
302
+ let app = NSApp ( ) ;
303
+ assert ! ( !app. is_null( ) ) ;
304
+ HANDLER . lock ( ) . unwrap ( ) . callback = Some ( Box :: new ( EventLoopHandler {
305
+ callback,
306
+ event_loop : self . elw_target ,
307
+ } ) ) ;
308
+ let _: ( ) = msg_send ! [ app, run] ;
309
+ // This is probably wrong
310
+ unreachable_unchecked ( )
204
311
}
205
312
}
206
313
0 commit comments