Clean up some pointer shuffling stuff
This commit is contained in:
parent
f49eff24f9
commit
8a5af12b47
|
@ -2,6 +2,8 @@
|
||||||
//! belong to. These are typically internal, and if you rely on them... well, don't be surprised if
|
//! belong to. These are typically internal, and if you rely on them... well, don't be surprised if
|
||||||
//! they go away one day.
|
//! they go away one day.
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::{slice, str};
|
use std::{slice, str};
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
|
|
||||||
|
@ -9,6 +11,7 @@ use cocoa::base::id;
|
||||||
use cocoa::foundation::NSString;
|
use cocoa::foundation::NSString;
|
||||||
|
|
||||||
use objc::{msg_send, sel, sel_impl};
|
use objc::{msg_send, sel, sel_impl};
|
||||||
|
use objc::runtime::Object;
|
||||||
|
|
||||||
/// A utility method for taking an `NSString` and bridging it to a Rust `&str`.
|
/// A utility method for taking an `NSString` and bridging it to a Rust `&str`.
|
||||||
pub fn str_from(nsstring: id) -> &'static str {
|
pub fn str_from(nsstring: id) -> &'static str {
|
||||||
|
@ -23,3 +26,14 @@ pub fn str_from(nsstring: id) -> &'static str {
|
||||||
str::from_utf8(bytes).unwrap()
|
str::from_utf8(bytes).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used for moving a pointer back into an Rc, so we can work with the object held behind it. Note
|
||||||
|
/// that it's very important to make sure you reverse this when you're done (using
|
||||||
|
/// `Rc::into_raw()`) otherwise you'll cause problems due to the `Drop` logic.
|
||||||
|
pub fn load<T>(this: &Object, ptr: &str) -> Rc<RefCell<T>> {
|
||||||
|
unsafe {
|
||||||
|
let ptr: usize = *this.get_ivar(ptr);
|
||||||
|
let view_ptr = ptr as *const RefCell<T>;
|
||||||
|
Rc::from_raw(view_ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
//! for in the modern era. It also implements a few helpers for things like setting a background
|
//! for in the modern era. It also implements a few helpers for things like setting a background
|
||||||
//! color, and enforcing layer backing by default.
|
//! color, and enforcing layer backing by default.
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
|
|
||||||
|
@ -22,6 +21,8 @@ use objc_id::Id;
|
||||||
use crate::constants::{BACKGROUND_COLOR, VIEW_CONTROLLER_PTR};
|
use crate::constants::{BACKGROUND_COLOR, VIEW_CONTROLLER_PTR};
|
||||||
use crate::dragdrop::DragInfo;
|
use crate::dragdrop::DragInfo;
|
||||||
use crate::view::traits::ViewController;
|
use crate::view::traits::ViewController;
|
||||||
|
use crate::utils::load;
|
||||||
|
|
||||||
|
|
||||||
/// Enforces normalcy, or: a needlessly cruel method in terms of the name. You get the idea though.
|
/// Enforces normalcy, or: a needlessly cruel method in terms of the name. You get the idea though.
|
||||||
extern fn enforce_normalcy(_: &Object, _: Sel) -> BOOL {
|
extern fn enforce_normalcy(_: &Object, _: Sel) -> BOOL {
|
||||||
|
@ -42,106 +43,84 @@ extern fn update_layer(this: &Object, _: Sel) {
|
||||||
|
|
||||||
/// Called when a drag/drop operation has entered this view.
|
/// Called when a drag/drop operation has entered this view.
|
||||||
extern fn dragging_entered<T: ViewController>(this: &mut Object, _: Sel, info: id) -> NSUInteger {
|
extern fn dragging_entered<T: ViewController>(this: &mut Object, _: Sel, info: id) -> NSUInteger {
|
||||||
unsafe {
|
let view = load::<T>(this, VIEW_CONTROLLER_PTR);
|
||||||
let ptr: usize = *this.get_ivar(VIEW_CONTROLLER_PTR);
|
|
||||||
let view_ptr = ptr as *const RefCell<T>;
|
|
||||||
let view = Rc::from_raw(view_ptr);
|
|
||||||
|
|
||||||
let response = {
|
|
||||||
let v = view.borrow();
|
|
||||||
|
|
||||||
(*v).dragging_entered(DragInfo {
|
|
||||||
info: Id::from_ptr(info)
|
|
||||||
}).into()
|
|
||||||
};
|
|
||||||
|
|
||||||
Rc::into_raw(view);
|
let response = {
|
||||||
response
|
let v = view.borrow();
|
||||||
}
|
|
||||||
|
(*v).dragging_entered(DragInfo {
|
||||||
|
info: unsafe { Id::from_ptr(info) }
|
||||||
|
}).into()
|
||||||
|
};
|
||||||
|
|
||||||
|
Rc::into_raw(view);
|
||||||
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when a drag/drop operation has entered this view.
|
/// Called when a drag/drop operation has entered this view.
|
||||||
extern fn prepare_for_drag_operation<T: ViewController>(this: &mut Object, _: Sel, info: id) -> BOOL {
|
extern fn prepare_for_drag_operation<T: ViewController>(this: &mut Object, _: Sel, info: id) -> BOOL {
|
||||||
unsafe {
|
let view = load::<T>(this, VIEW_CONTROLLER_PTR);
|
||||||
let ptr: usize = *this.get_ivar(VIEW_CONTROLLER_PTR);
|
|
||||||
let view_ptr = ptr as *const RefCell<T>;
|
let response = {
|
||||||
let view = Rc::from_raw(view_ptr);
|
let v = view.borrow();
|
||||||
|
|
||||||
let response = {
|
match (*v).prepare_for_drag_operation(DragInfo {
|
||||||
let v = view.borrow();
|
info: unsafe { Id::from_ptr(info) }
|
||||||
|
}) {
|
||||||
match (*v).prepare_for_drag_operation(DragInfo {
|
true => YES,
|
||||||
info: Id::from_ptr(info)
|
false => NO
|
||||||
}) {
|
}
|
||||||
true => YES,
|
};
|
||||||
false => NO
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Rc::into_raw(view);
|
Rc::into_raw(view);
|
||||||
response
|
response
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when a drag/drop operation has entered this view.
|
/// Called when a drag/drop operation has entered this view.
|
||||||
extern fn perform_drag_operation<T: ViewController>(this: &mut Object, _: Sel, info: id) -> BOOL {
|
extern fn perform_drag_operation<T: ViewController>(this: &mut Object, _: Sel, info: id) -> BOOL {
|
||||||
unsafe {
|
let view = load::<T>(this, VIEW_CONTROLLER_PTR);
|
||||||
let ptr: usize = *this.get_ivar(VIEW_CONTROLLER_PTR);
|
|
||||||
let view_ptr = ptr as *const RefCell<T>;
|
|
||||||
let view = Rc::from_raw(view_ptr);
|
|
||||||
|
|
||||||
let response = {
|
let response = {
|
||||||
let v = view.borrow();
|
let v = view.borrow();
|
||||||
|
|
||||||
match (*v).perform_drag_operation(DragInfo {
|
match (*v).perform_drag_operation(DragInfo {
|
||||||
info: Id::from_ptr(info)
|
info: unsafe { Id::from_ptr(info) }
|
||||||
}) {
|
}) {
|
||||||
true => YES,
|
true => YES,
|
||||||
false => NO
|
false => NO
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Rc::into_raw(view);
|
Rc::into_raw(view);
|
||||||
response
|
response
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when a drag/drop operation has entered this view.
|
/// Called when a drag/drop operation has entered this view.
|
||||||
extern fn conclude_drag_operation<T: ViewController>(this: &mut Object, _: Sel, info: id) {
|
extern fn conclude_drag_operation<T: ViewController>(this: &mut Object, _: Sel, info: id) {
|
||||||
unsafe {
|
let view = load::<T>(this, VIEW_CONTROLLER_PTR);
|
||||||
let ptr: usize = *this.get_ivar(VIEW_CONTROLLER_PTR);
|
|
||||||
let view_ptr = ptr as *const RefCell<T>;
|
|
||||||
let view = Rc::from_raw(view_ptr);
|
|
||||||
|
|
||||||
let response = {
|
|
||||||
let v = view.borrow();
|
|
||||||
(*v).conclude_drag_operation(DragInfo {
|
|
||||||
info: Id::from_ptr(info)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Rc::into_raw(view);
|
{
|
||||||
response
|
let v = view.borrow();
|
||||||
|
(*v).conclude_drag_operation(DragInfo {
|
||||||
|
info: unsafe { Id::from_ptr(info) }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rc::into_raw(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when a drag/drop operation has entered this view.
|
/// Called when a drag/drop operation has entered this view.
|
||||||
extern fn dragging_exited<T: ViewController>(this: &mut Object, _: Sel, info: id) {
|
extern fn dragging_exited<T: ViewController>(this: &mut Object, _: Sel, info: id) {
|
||||||
unsafe {
|
let view = load::<T>(this, VIEW_CONTROLLER_PTR);
|
||||||
let ptr: usize = *this.get_ivar(VIEW_CONTROLLER_PTR);
|
|
||||||
let view_ptr = ptr as *const RefCell<T>;
|
|
||||||
let view = Rc::from_raw(view_ptr);
|
|
||||||
|
|
||||||
let response = {
|
{
|
||||||
let v = view.borrow();
|
let v = view.borrow();
|
||||||
(*v).dragging_exited(DragInfo {
|
(*v).dragging_exited(DragInfo {
|
||||||
info: Id::from_ptr(info)
|
info: unsafe { Id::from_ptr(info) }
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
Rc::into_raw(view);
|
|
||||||
response
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rc::into_raw(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Injects an `NSView` subclass, with some callback and pointer ivars for what we
|
/// Injects an `NSView` subclass, with some callback and pointer ivars for what we
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Everything useful for the `WindowController`. Handles injecting an `NSWindowController` subclass
|
//! Everything useful for the `WindowController`. Handles injecting an `NSWindowController` subclass
|
||||||
//! into the Objective C runtime, which loops back to give us lifecycle methods.
|
//! into the Objective C runtime, which loops back to give us lifecycle methods.
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
|
|
||||||
use cocoa::base::id;
|
use cocoa::base::id;
|
||||||
|
@ -9,18 +10,21 @@ use objc::declare::ClassDecl;
|
||||||
use objc::runtime::{Class, Object, Sel};
|
use objc::runtime::{Class, Object, Sel};
|
||||||
use objc::{class, sel, sel_impl};
|
use objc::{class, sel, sel_impl};
|
||||||
|
|
||||||
|
use crate::constants::WINDOW_CONTROLLER_PTR;
|
||||||
|
use crate::utils::load;
|
||||||
use crate::window::WindowController;
|
use crate::window::WindowController;
|
||||||
|
|
||||||
static WINDOW_CONTROLLER_PTR: &str = "rstWindowController";
|
|
||||||
|
|
||||||
/// Called when an `NSWindow` receives a `windowWillClose:` event.
|
/// Called when an `NSWindow` receives a `windowWillClose:` event.
|
||||||
/// Good place to clean up memory and what not.
|
/// Good place to clean up memory and what not.
|
||||||
extern fn will_close<T: WindowController>(this: &Object, _: Sel, _: id) {
|
extern fn will_close<T: WindowController>(this: &Object, _: Sel, _: id) {
|
||||||
unsafe {
|
let window = load::<T>(this, WINDOW_CONTROLLER_PTR);
|
||||||
let window_ptr: usize = *this.get_ivar(WINDOW_CONTROLLER_PTR);
|
|
||||||
let window = window_ptr as *const T;
|
{
|
||||||
|
let window = window.borrow();
|
||||||
(*window).will_close();
|
(*window).will_close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rc::into_raw(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Injects an `NSWindowController` subclass, with some callback and pointer ivars for what we
|
/// Injects an `NSWindowController` subclass, with some callback and pointer ivars for what we
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use cocoa::base::{id, nil, YES, NO};
|
use cocoa::base::{id, nil};
|
||||||
use cocoa::foundation::{NSSize, NSString};
|
|
||||||
|
|
||||||
use objc::{msg_send, sel, sel_impl};
|
use objc::{msg_send, sel, sel_impl};
|
||||||
use objc_id::ShareId;
|
use objc_id::ShareId;
|
||||||
|
|
Loading…
Reference in a new issue