1
0
Fork 0

store WindowHandler as trait object in cocoa backend

This commit is contained in:
Micah Johnston 2020-12-08 19:22:26 -06:00 committed by glowcoil
parent 4e70af1162
commit e9507f8d86
2 changed files with 52 additions and 52 deletions

View file

@ -25,10 +25,10 @@ use super::window::{
};
pub(super) unsafe fn create_view<H: WindowHandler>(
pub(super) unsafe fn create_view(
window_options: &WindowOpenOptions,
) -> id {
let class = create_view_class::<H>();
let class = create_view_class();
let view: id = msg_send![class, alloc];
@ -43,7 +43,7 @@ pub(super) unsafe fn create_view<H: WindowHandler>(
}
unsafe fn create_view_class<H: WindowHandler>() -> &'static Class {
unsafe fn create_view_class() -> &'static Class {
// Use unique class names so that there are no conflicts between different
// instances. The class is deleted when the view is released. Previously,
// the class was stored in a OnceCell after creation. This way, we didn't
@ -54,104 +54,104 @@ unsafe fn create_view_class<H: WindowHandler>() -> &'static Class {
class.add_method(
sel!(acceptsFirstResponder),
property_yes::<H> as extern "C" fn(&Object, Sel) -> BOOL
property_yes as extern "C" fn(&Object, Sel) -> BOOL
);
class.add_method(
sel!(isFlipped),
property_yes::<H> as extern "C" fn(&Object, Sel) -> BOOL
property_yes as extern "C" fn(&Object, Sel) -> BOOL
);
class.add_method(
sel!(preservesContentInLiveResize),
property_no::<H> as extern "C" fn(&Object, Sel) -> BOOL
property_no as extern "C" fn(&Object, Sel) -> BOOL
);
class.add_method(
sel!(acceptsFirstMouse:),
accepts_first_mouse::<H> as extern "C" fn(&Object, Sel, id) -> BOOL
accepts_first_mouse as extern "C" fn(&Object, Sel, id) -> BOOL
);
class.add_method(
sel!(triggerOnFrame:),
trigger_on_frame::<H> as extern "C" fn(&Object, Sel, id)
trigger_on_frame as extern "C" fn(&Object, Sel, id)
);
class.add_method(
sel!(release),
release::<H> as extern "C" fn(&Object, Sel)
release as extern "C" fn(&Object, Sel)
);
class.add_method(
sel!(viewWillMoveToWindow:),
view_will_move_to_window::<H> as extern "C" fn(&Object, Sel, id)
view_will_move_to_window as extern "C" fn(&Object, Sel, id)
);
class.add_method(
sel!(updateTrackingAreas:),
update_tracking_areas::<H> as extern "C" fn(&Object, Sel, id)
update_tracking_areas as extern "C" fn(&Object, Sel, id)
);
class.add_method(
sel!(mouseMoved:),
mouse_moved::<H> as extern "C" fn(&Object, Sel, id),
mouse_moved as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(mouseDragged:),
mouse_moved::<H> as extern "C" fn(&Object, Sel, id),
mouse_moved as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(rightMouseDragged:),
mouse_moved::<H> as extern "C" fn(&Object, Sel, id),
mouse_moved as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(otherMouseDragged:),
mouse_moved::<H> as extern "C" fn(&Object, Sel, id),
mouse_moved as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(mouseEntered:),
mouse_entered::<H> as extern "C" fn(&Object, Sel, id),
mouse_entered as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(mouseExited:),
mouse_exited::<H> as extern "C" fn(&Object, Sel, id),
mouse_exited as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(mouseDown:),
left_mouse_down::<H> as extern "C" fn(&Object, Sel, id),
left_mouse_down as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(mouseUp:),
left_mouse_up::<H> as extern "C" fn(&Object, Sel, id),
left_mouse_up as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(rightMouseDown:),
right_mouse_down::<H> as extern "C" fn(&Object, Sel, id),
right_mouse_down as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(rightMouseUp:),
right_mouse_up::<H> as extern "C" fn(&Object, Sel, id),
right_mouse_up as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(otherMouseDown:),
middle_mouse_down::<H> as extern "C" fn(&Object, Sel, id),
middle_mouse_down as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(otherMouseUp:),
middle_mouse_up::<H> as extern "C" fn(&Object, Sel, id),
middle_mouse_up as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(keyDown:),
key_down::<H> as extern "C" fn(&Object, Sel, id),
key_down as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(keyUp:),
key_up::<H> as extern "C" fn(&Object, Sel, id),
key_up as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(flagsChanged:),
flags_changed::<H> as extern "C" fn(&Object, Sel, id),
flags_changed as extern "C" fn(&Object, Sel, id),
);
class.add_ivar::<*mut c_void>(WINDOW_STATE_IVAR_NAME);
@ -161,7 +161,7 @@ unsafe fn create_view_class<H: WindowHandler>() -> &'static Class {
}
extern "C" fn property_yes<H: WindowHandler>(
extern "C" fn property_yes(
_this: &Object,
_sel: Sel,
) -> BOOL {
@ -169,7 +169,7 @@ extern "C" fn property_yes<H: WindowHandler>(
}
extern "C" fn property_no<H: WindowHandler>(
extern "C" fn property_no(
_this: &Object,
_sel: Sel,
) -> BOOL {
@ -177,7 +177,7 @@ extern "C" fn property_no<H: WindowHandler>(
}
extern "C" fn accepts_first_mouse<H: WindowHandler>(
extern "C" fn accepts_first_mouse(
_this: &Object,
_sel: Sel,
_event: id
@ -186,12 +186,12 @@ extern "C" fn accepts_first_mouse<H: WindowHandler>(
}
extern "C" fn trigger_on_frame<H: WindowHandler>(
extern "C" fn trigger_on_frame(
this: &Object,
_sel: Sel,
_event: id
){
let state: &mut WindowState<H> = unsafe {
let state: &mut WindowState = unsafe {
WindowState::from_field(this)
};
@ -199,7 +199,7 @@ extern "C" fn trigger_on_frame<H: WindowHandler>(
}
extern "C" fn release<H: WindowHandler>(this: &Object, _sel: Sel) {
extern "C" fn release(this: &Object, _sel: Sel) {
unsafe {
let superclass = msg_send![this, superclass];
@ -220,7 +220,7 @@ extern "C" fn release<H: WindowHandler>(this: &Object, _sel: Sel) {
let state_ptr: *mut c_void = *this.get_ivar(
WINDOW_STATE_IVAR_NAME
);
Arc::from_raw(state_ptr as *mut WindowState<H>);
Arc::from_raw(state_ptr as *mut WindowState);
// Delete class
let class = msg_send![this, class];
@ -261,7 +261,7 @@ unsafe fn reinit_tracking_area(this: &Object, tracking_area: *mut Object){
}
extern "C" fn view_will_move_to_window<H: WindowHandler>(
extern "C" fn view_will_move_to_window(
this: &Object,
_self: Sel,
new_window: id
@ -305,7 +305,7 @@ extern "C" fn view_will_move_to_window<H: WindowHandler>(
}
extern "C" fn update_tracking_areas<H: WindowHandler>(
extern "C" fn update_tracking_areas(
this: &Object,
_self: Sel,
_: id
@ -319,7 +319,7 @@ extern "C" fn update_tracking_areas<H: WindowHandler>(
}
extern "C" fn mouse_moved<H: WindowHandler>(
extern "C" fn mouse_moved(
this: &Object,
_sel: Sel,
event: id
@ -337,7 +337,7 @@ extern "C" fn mouse_moved<H: WindowHandler>(
let event = Event::Mouse(MouseEvent::CursorMoved { position });
let state: &mut WindowState<H> = unsafe {
let state: &mut WindowState = unsafe {
WindowState::from_field(this)
};
@ -347,12 +347,12 @@ extern "C" fn mouse_moved<H: WindowHandler>(
macro_rules! mouse_simple_extern_fn {
($fn:ident, $event:expr) => {
extern "C" fn $fn<H: WindowHandler>(
extern "C" fn $fn(
this: &Object,
_sel: Sel,
_event: id,
){
let state: &mut WindowState<H> = unsafe {
let state: &mut WindowState = unsafe {
WindowState::from_field(this)
};
@ -375,8 +375,8 @@ mouse_simple_extern_fn!(mouse_entered, MouseEvent::CursorEntered);
mouse_simple_extern_fn!(mouse_exited, MouseEvent::CursorLeft);
extern "C" fn key_down<H: WindowHandler>(this: &Object, _: Sel, event: id){
let state: &mut WindowState<H> = unsafe {
extern "C" fn key_down(this: &Object, _: Sel, event: id){
let state: &mut WindowState = unsafe {
WindowState::from_field(this)
};
@ -386,8 +386,8 @@ extern "C" fn key_down<H: WindowHandler>(this: &Object, _: Sel, event: id){
}
extern "C" fn key_up<H: WindowHandler>(this: &Object, _: Sel, event: id){
let state: &mut WindowState<H> = unsafe {
extern "C" fn key_up(this: &Object, _: Sel, event: id){
let state: &mut WindowState = unsafe {
WindowState::from_field(this)
};
@ -397,8 +397,8 @@ extern "C" fn key_up<H: WindowHandler>(this: &Object, _: Sel, event: id){
}
extern "C" fn flags_changed<H: WindowHandler>(this: &Object, _: Sel, event: id){
let state: &mut WindowState<H> = unsafe {
extern "C" fn flags_changed(this: &Object, _: Sel, event: id){
let state: &mut WindowState = unsafe {
WindowState::from_field(this)
};

View file

@ -71,7 +71,7 @@ impl Window {
let ns_view = handle.ns_view as *mut objc::runtime::Object;
unsafe {
let subview = create_view::<H>(&options);
let subview = create_view(&options);
let _: id = msg_send![ns_view, addSubview: subview];
@ -88,7 +88,7 @@ impl Window {
},
Parent::AsIfParented => {
let ns_view = unsafe {
create_view::<H>(&options)
create_view(&options)
};
let window = Window {
@ -147,7 +147,7 @@ impl Window {
ns_window.makeKeyAndOrderFront_(nil);
let subview = create_view::<H>(&options);
let subview = create_view(&options);
ns_window.setContentView_(subview);
@ -161,7 +161,7 @@ impl Window {
},
};
let window_handler = build(&mut crate::Window(&mut window));
let window_handler = Box::new(build(&mut crate::Window(&mut window)));
let window_state_arc = Arc::new(WindowState {
window,
@ -208,14 +208,14 @@ impl Window {
}
pub(super) struct WindowState<H: WindowHandler> {
pub(super) struct WindowState {
window: Window,
window_handler: H,
window_handler: Box<dyn WindowHandler>,
keyboard_state: KeyboardState,
}
impl<H: WindowHandler> WindowState<H> {
impl WindowState {
/// Returns a mutable reference to a WindowState from an Objective-C field
///
/// Don't use this to create two simulataneous references to a single