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, window_options: &WindowOpenOptions,
) -> id { ) -> id {
let class = create_view_class::<H>(); let class = create_view_class();
let view: id = msg_send![class, alloc]; 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 // Use unique class names so that there are no conflicts between different
// instances. The class is deleted when the view is released. Previously, // 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 // 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( class.add_method(
sel!(acceptsFirstResponder), sel!(acceptsFirstResponder),
property_yes::<H> as extern "C" fn(&Object, Sel) -> BOOL property_yes as extern "C" fn(&Object, Sel) -> BOOL
); );
class.add_method( class.add_method(
sel!(isFlipped), sel!(isFlipped),
property_yes::<H> as extern "C" fn(&Object, Sel) -> BOOL property_yes as extern "C" fn(&Object, Sel) -> BOOL
); );
class.add_method( class.add_method(
sel!(preservesContentInLiveResize), sel!(preservesContentInLiveResize),
property_no::<H> as extern "C" fn(&Object, Sel) -> BOOL property_no as extern "C" fn(&Object, Sel) -> BOOL
); );
class.add_method( class.add_method(
sel!(acceptsFirstMouse:), 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( class.add_method(
sel!(triggerOnFrame:), 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( class.add_method(
sel!(release), sel!(release),
release::<H> as extern "C" fn(&Object, Sel) release as extern "C" fn(&Object, Sel)
); );
class.add_method( class.add_method(
sel!(viewWillMoveToWindow:), 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( class.add_method(
sel!(updateTrackingAreas:), 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( class.add_method(
sel!(mouseMoved:), sel!(mouseMoved:),
mouse_moved::<H> as extern "C" fn(&Object, Sel, id), mouse_moved as extern "C" fn(&Object, Sel, id),
); );
class.add_method( class.add_method(
sel!(mouseDragged:), sel!(mouseDragged:),
mouse_moved::<H> as extern "C" fn(&Object, Sel, id), mouse_moved as extern "C" fn(&Object, Sel, id),
); );
class.add_method( class.add_method(
sel!(rightMouseDragged:), sel!(rightMouseDragged:),
mouse_moved::<H> as extern "C" fn(&Object, Sel, id), mouse_moved as extern "C" fn(&Object, Sel, id),
); );
class.add_method( class.add_method(
sel!(otherMouseDragged:), sel!(otherMouseDragged:),
mouse_moved::<H> as extern "C" fn(&Object, Sel, id), mouse_moved as extern "C" fn(&Object, Sel, id),
); );
class.add_method( class.add_method(
sel!(mouseEntered:), sel!(mouseEntered:),
mouse_entered::<H> as extern "C" fn(&Object, Sel, id), mouse_entered as extern "C" fn(&Object, Sel, id),
); );
class.add_method( class.add_method(
sel!(mouseExited:), sel!(mouseExited:),
mouse_exited::<H> as extern "C" fn(&Object, Sel, id), mouse_exited as extern "C" fn(&Object, Sel, id),
); );
class.add_method( class.add_method(
sel!(mouseDown:), 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( class.add_method(
sel!(mouseUp:), 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( class.add_method(
sel!(rightMouseDown:), 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( class.add_method(
sel!(rightMouseUp:), 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( class.add_method(
sel!(otherMouseDown:), 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( class.add_method(
sel!(otherMouseUp:), 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( class.add_method(
sel!(keyDown:), sel!(keyDown:),
key_down::<H> as extern "C" fn(&Object, Sel, id), key_down as extern "C" fn(&Object, Sel, id),
); );
class.add_method( class.add_method(
sel!(keyUp:), sel!(keyUp:),
key_up::<H> as extern "C" fn(&Object, Sel, id), key_up as extern "C" fn(&Object, Sel, id),
); );
class.add_method( class.add_method(
sel!(flagsChanged:), 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); 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, _this: &Object,
_sel: Sel, _sel: Sel,
) -> BOOL { ) -> 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, _this: &Object,
_sel: Sel, _sel: Sel,
) -> BOOL { ) -> 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, _this: &Object,
_sel: Sel, _sel: Sel,
_event: id _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, this: &Object,
_sel: Sel, _sel: Sel,
_event: id _event: id
){ ){
let state: &mut WindowState<H> = unsafe { let state: &mut WindowState = unsafe {
WindowState::from_field(this) 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 { unsafe {
let superclass = msg_send![this, superclass]; 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( let state_ptr: *mut c_void = *this.get_ivar(
WINDOW_STATE_IVAR_NAME WINDOW_STATE_IVAR_NAME
); );
Arc::from_raw(state_ptr as *mut WindowState<H>); Arc::from_raw(state_ptr as *mut WindowState);
// Delete class // Delete class
let class = msg_send![this, 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, this: &Object,
_self: Sel, _self: Sel,
new_window: id 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, this: &Object,
_self: Sel, _self: Sel,
_: id _: 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, this: &Object,
_sel: Sel, _sel: Sel,
event: id event: id
@ -337,7 +337,7 @@ extern "C" fn mouse_moved<H: WindowHandler>(
let event = Event::Mouse(MouseEvent::CursorMoved { position }); let event = Event::Mouse(MouseEvent::CursorMoved { position });
let state: &mut WindowState<H> = unsafe { let state: &mut WindowState = unsafe {
WindowState::from_field(this) WindowState::from_field(this)
}; };
@ -347,12 +347,12 @@ extern "C" fn mouse_moved<H: WindowHandler>(
macro_rules! mouse_simple_extern_fn { macro_rules! mouse_simple_extern_fn {
($fn:ident, $event:expr) => { ($fn:ident, $event:expr) => {
extern "C" fn $fn<H: WindowHandler>( extern "C" fn $fn(
this: &Object, this: &Object,
_sel: Sel, _sel: Sel,
_event: id, _event: id,
){ ){
let state: &mut WindowState<H> = unsafe { let state: &mut WindowState = unsafe {
WindowState::from_field(this) WindowState::from_field(this)
}; };
@ -375,8 +375,8 @@ mouse_simple_extern_fn!(mouse_entered, MouseEvent::CursorEntered);
mouse_simple_extern_fn!(mouse_exited, MouseEvent::CursorLeft); mouse_simple_extern_fn!(mouse_exited, MouseEvent::CursorLeft);
extern "C" fn key_down<H: WindowHandler>(this: &Object, _: Sel, event: id){ extern "C" fn key_down(this: &Object, _: Sel, event: id){
let state: &mut WindowState<H> = unsafe { let state: &mut WindowState = unsafe {
WindowState::from_field(this) 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){ extern "C" fn key_up(this: &Object, _: Sel, event: id){
let state: &mut WindowState<H> = unsafe { let state: &mut WindowState = unsafe {
WindowState::from_field(this) 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){ extern "C" fn flags_changed(this: &Object, _: Sel, event: id){
let state: &mut WindowState<H> = unsafe { let state: &mut WindowState = unsafe {
WindowState::from_field(this) WindowState::from_field(this)
}; };

View file

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