Skip to content

Commit 8e6b986

Browse files
committed
Dump (encapsulate) everything into AppState
1 parent d2dc83d commit 8e6b986

14 files changed

+546
-701
lines changed

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,5 @@ mod icon;
114114
mod platform_impl;
115115
pub mod window;
116116
pub mod monitor;
117-
118117
pub mod platform;
118+
mod util;

src/platform_impl/macos/app.rs

+45-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
use cocoa::{appkit, base::id};
1+
use std::collections::VecDeque;
2+
3+
use cocoa::{appkit::{self, NSEvent}, base::id};
24
use objc::{declare::ClassDecl, runtime::{Class, Object, Sel}};
35

4-
use platform_impl::platform::util;
6+
use event::{DeviceEvent, Event};
7+
use platform_impl::platform::{app_state::AppState, DEVICE_ID, util};
58

69
pub struct AppClass(pub *const Class);
710
unsafe impl Send for AppClass {}
@@ -26,7 +29,6 @@ lazy_static! {
2629
// Fun fact: Firefox still has this bug! (https://bugzilla.mozilla.org/show_bug.cgi?id=1299553)
2730
extern fn send_event(this: &Object, _sel: Sel, event: id) {
2831
unsafe {
29-
use self::appkit::NSEvent;
3032
// For posterity, there are some undocumented event types
3133
// (https://github.com/servo/cocoa-rs/issues/155)
3234
// but that doesn't really matter here.
@@ -39,8 +41,48 @@ extern fn send_event(this: &Object, _sel: Sel, event: id) {
3941
let key_window: id = msg_send![this, keyWindow];
4042
let _: () = msg_send![key_window, sendEvent:event];
4143
} else {
44+
maybe_dispatch_device_event(event);
4245
let superclass = util::superclass(this);
4346
let _: () = msg_send![super(this, superclass), sendEvent:event];
4447
}
4548
}
4649
}
50+
51+
unsafe fn maybe_dispatch_device_event(event: id) {
52+
let event_type = event.eventType();
53+
match event_type {
54+
appkit::NSMouseMoved |
55+
appkit::NSLeftMouseDragged |
56+
appkit::NSOtherMouseDragged |
57+
appkit::NSRightMouseDragged => {
58+
let mut events = VecDeque::with_capacity(3);
59+
60+
let delta_x = event.deltaX() as f64;
61+
let delta_y = event.deltaY() as f64;
62+
63+
if delta_x != 0.0 {
64+
events.push_back(Event::DeviceEvent {
65+
device_id: DEVICE_ID,
66+
event: DeviceEvent::Motion { axis: 0, value: delta_x },
67+
});
68+
}
69+
70+
if delta_y != 0.0 {
71+
events.push_back(Event::DeviceEvent {
72+
device_id: DEVICE_ID,
73+
event: DeviceEvent::Motion { axis: 1, value: delta_y },
74+
});
75+
}
76+
77+
if delta_x != 0.0 || delta_y != 0.0 {
78+
events.push_back(Event::DeviceEvent {
79+
device_id: DEVICE_ID,
80+
event: DeviceEvent::MouseMotion { delta: (delta_x, delta_y) },
81+
});
82+
}
83+
84+
AppState::queue_events(events);
85+
},
86+
_ => (),
87+
}
88+
}

src/platform_impl/macos/app_delegate.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use cocoa::base::id;
22
use objc::{runtime::{Class, Object, Sel, BOOL, YES}, declare::ClassDecl};
33

4-
use platform_impl::platform::event_loop::HANDLER;
4+
use platform_impl::platform::app_state::AppState;
55

66
pub struct AppDelegateClass(pub *const Class);
77
unsafe impl Send for AppDelegateClass {}
@@ -43,7 +43,7 @@ lazy_static! {
4343

4444
extern fn did_finish_launching(_: &Object, _: Sel, _: id) -> BOOL {
4545
trace!("Triggered `didFinishLaunching`");
46-
HANDLER.lock().unwrap().launched();
46+
AppState::launched();
4747
trace!("Completed `didFinishLaunching`");
4848
YES
4949
}

src/platform_impl/macos/app_state.rs

+186
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
use std::{
2+
self, collections::VecDeque, fmt::{self, Debug, Formatter},
3+
hint::unreachable_unchecked, mem, sync::{Mutex, MutexGuard},
4+
};
5+
6+
use cocoa::{appkit::NSApp, base::nil};
7+
8+
use {
9+
event::{Event, StartCause},
10+
event_loop::{ControlFlow, EventLoopWindowTarget as RootWindowTarget},
11+
};
12+
use platform_impl::platform::{observer::EventLoopWaker, util::Never};
13+
14+
lazy_static! {
15+
static ref HANDLER: Mutex<Handler> = Default::default();
16+
static ref EVENTS: Mutex<VecDeque<Event<Never>>> = Default::default();
17+
}
18+
19+
impl Event<Never> {
20+
fn userify<T: 'static>(self) -> Event<T> {
21+
self.map_nonuser_event()
22+
// `Never` can't be constructed, so the `UserEvent` variant can't
23+
// be present here.
24+
.unwrap_or_else(|_| unsafe { unreachable_unchecked() })
25+
}
26+
}
27+
28+
pub trait EventHandler: Debug {
29+
fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: *mut ControlFlow);
30+
//fn handle_user_events(&mut self, control_flow: &mut ControlFlow);
31+
}
32+
33+
struct EventLoopHandler<F, T: 'static> {
34+
callback: F,
35+
window_target: RootWindowTarget<T>,
36+
}
37+
38+
impl<F, T: 'static> Debug for EventLoopHandler<F, T> {
39+
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
40+
formatter.debug_struct("EventLoopHandler")
41+
.field("window_target", &self.window_target)
42+
.finish()
43+
}
44+
}
45+
46+
impl<F, T> EventHandler for EventLoopHandler<F, T>
47+
where
48+
F: 'static + FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
49+
T: 'static,
50+
{
51+
fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: *mut ControlFlow) {
52+
(self.callback)(
53+
event.userify(),
54+
&self.window_target,
55+
unsafe { &mut *control_flow },
56+
);
57+
}
58+
59+
/*fn handle_user_events(&mut self, control_flow: &mut ControlFlow) {
60+
for event in self.event_loop.inner.receiver.try_iter() {
61+
(self.callback)(
62+
Event::UserEvent(event),
63+
&self.event_loop,
64+
control_flow,
65+
);
66+
}
67+
}*/
68+
}
69+
70+
#[derive(Default)]
71+
struct Handler {
72+
control_flow: ControlFlow,
73+
control_flow_prev: ControlFlow,
74+
callback: Option<Box<dyn EventHandler>>,
75+
waker: EventLoopWaker,
76+
}
77+
78+
unsafe impl Send for Handler {}
79+
unsafe impl Sync for Handler {}
80+
81+
impl Handler {
82+
fn handle_nonuser_event(&mut self, event: Event<Never>) {
83+
let control_flow = &mut self.control_flow;
84+
if let Some(ref mut callback) = self.callback {
85+
callback.handle_nonuser_event(event, control_flow);
86+
}
87+
}
88+
}
89+
90+
pub enum AppState {}
91+
92+
impl AppState {
93+
fn handler() -> MutexGuard<'static, Handler> {
94+
HANDLER.lock().unwrap()
95+
}
96+
97+
fn events() -> MutexGuard<'static, VecDeque<Event<Never>>> {
98+
EVENTS.lock().unwrap()
99+
}
100+
101+
pub fn set_callback<F, T>(callback: F, window_target: RootWindowTarget<T>)
102+
where
103+
F: 'static + FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
104+
T: 'static,
105+
{
106+
Self::handler().callback = Some(Box::new(EventLoopHandler {
107+
callback,
108+
window_target,
109+
}));
110+
}
111+
112+
pub fn exit() -> ! {
113+
let mut handler = Self::handler();
114+
if let Some(mut callback) = handler.callback.take() {
115+
callback.handle_nonuser_event(
116+
Event::LoopDestroyed,
117+
&mut handler.control_flow,
118+
);
119+
}
120+
std::process::exit(0)
121+
}
122+
123+
pub fn launched() {
124+
let mut handler = Self::handler();
125+
handler.waker.start();
126+
handler.handle_nonuser_event(Event::NewEvents(StartCause::Init));
127+
}
128+
129+
pub fn wakeup() {
130+
let mut handler = Self::handler();
131+
handler.control_flow_prev = handler.control_flow;
132+
let cause = match handler.control_flow {
133+
ControlFlow::Poll => StartCause::Poll,
134+
/*ControlFlow::Wait => StartCause::WaitCancelled {
135+
start,
136+
requested_resume: None,
137+
},
138+
ControlFlow::WaitUntil(requested_resume) => {
139+
if Instant::now() >= requested_resume {
140+
StartCause::ResumeTimeReached {
141+
start,
142+
requested_resume,
143+
}
144+
} else {
145+
StartCause::WaitCancelled {
146+
start,
147+
requested_resume: Some(requested_resume),
148+
}
149+
}
150+
},*/
151+
ControlFlow::Exit => StartCause::Poll,//panic!("unexpected `ControlFlow::Exit`"),
152+
_ => unimplemented!(),
153+
};
154+
handler.handle_nonuser_event(Event::NewEvents(cause));
155+
}
156+
157+
pub fn queue_event(event: Event<Never>) {
158+
Self::events().push_back(event);
159+
}
160+
161+
pub fn queue_events(mut events: VecDeque<Event<Never>>) {
162+
Self::events().append(&mut events);
163+
}
164+
165+
pub fn cleared() {
166+
let mut handler = Self::handler();
167+
handler.handle_nonuser_event(Event::EventsCleared);
168+
let events = mem::replace(&mut *Self::events(), Default::default());
169+
for event in events {
170+
handler.handle_nonuser_event(event);
171+
}
172+
let old = handler.control_flow_prev;
173+
let new = handler.control_flow;
174+
match (old, new) {
175+
(ControlFlow::Poll, ControlFlow::Poll) => (),
176+
(ControlFlow::Wait, ControlFlow::Wait) => (),
177+
(ControlFlow::WaitUntil(old_instant), ControlFlow::WaitUntil(new_instant)) if old_instant == new_instant => (),
178+
(_, ControlFlow::Wait) => handler.waker.stop(),
179+
(_, ControlFlow::WaitUntil(new_instant)) => handler.waker.start_at(new_instant),
180+
(_, ControlFlow::Poll) => handler.waker.start(),
181+
(_, ControlFlow::Exit) => {
182+
let _: () = unsafe { msg_send![NSApp(), stop:nil] };
183+
},
184+
}
185+
}
186+
}

0 commit comments

Comments
 (0)