Merge pull request #44 from RustAudio/nonblocking-event-loop
Non-blocking Event Loop, separate WindowHandle::app_run_blocking() call
This commit is contained in:
commit
ce708a8515
|
@ -1,16 +1,5 @@
|
|||
use baseview::{Event, Window, WindowHandler};
|
||||
|
||||
fn main() {
|
||||
let window_open_options = baseview::WindowOpenOptions {
|
||||
title: "baseview",
|
||||
width: 512,
|
||||
height: 512,
|
||||
parent: baseview::Parent::None,
|
||||
};
|
||||
|
||||
let _handle = Window::open::<MyProgram>(window_open_options);
|
||||
}
|
||||
|
||||
struct MyProgram {}
|
||||
|
||||
impl WindowHandler for MyProgram {
|
||||
|
@ -22,7 +11,7 @@ impl WindowHandler for MyProgram {
|
|||
|
||||
fn on_frame(&mut self) {}
|
||||
|
||||
fn on_event(&mut self, window: &mut Window, event: Event) {
|
||||
fn on_event(&mut self, _window: &mut Window, event: Event) {
|
||||
match event {
|
||||
Event::Mouse(e) => println!("Mouse event: {:?}", e),
|
||||
Event::Keyboard(e) => println!("Keyboard event: {:?}", e),
|
||||
|
@ -33,3 +22,15 @@ impl WindowHandler for MyProgram {
|
|||
|
||||
fn on_message(&mut self, _window: &mut Window, _message: Self::Message) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let window_open_options = baseview::WindowOpenOptions {
|
||||
title: "baseview".into(),
|
||||
width: 512,
|
||||
height: 512,
|
||||
parent: baseview::Parent::None,
|
||||
};
|
||||
|
||||
let handle = Window::open::<MyProgram>(window_open_options);
|
||||
handle.app_run_blocking();
|
||||
}
|
||||
|
|
|
@ -28,8 +28,10 @@ pub enum Parent {
|
|||
WithParent(*mut c_void),
|
||||
}
|
||||
|
||||
pub struct WindowOpenOptions<'a> {
|
||||
pub title: &'a str,
|
||||
unsafe impl Send for Parent {}
|
||||
|
||||
pub struct WindowOpenOptions {
|
||||
pub title: String,
|
||||
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
|
|
|
@ -20,14 +20,23 @@ pub struct Window {
|
|||
ns_view: id,
|
||||
}
|
||||
|
||||
pub struct WindowHandle;
|
||||
|
||||
impl WindowHandle {
|
||||
pub fn app_run_blocking(self) {
|
||||
unsafe {
|
||||
let app = NSApp();
|
||||
app.setActivationPolicy_(NSApplicationActivationPolicyRegular);
|
||||
app.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub fn open<H: WindowHandler>(options: WindowOpenOptions) -> WindowHandle {
|
||||
unsafe {
|
||||
let _pool = NSAutoreleasePool::new(nil);
|
||||
|
||||
let app = NSApp();
|
||||
app.setActivationPolicy_(NSApplicationActivationPolicyRegular);
|
||||
|
||||
let rect = NSRect::new(
|
||||
NSPoint::new(0.0, 0.0),
|
||||
NSSize::new(options.width as f64, options.height as f64),
|
||||
|
@ -42,7 +51,7 @@ impl Window {
|
|||
)
|
||||
.autorelease();
|
||||
ns_window.center();
|
||||
ns_window.setTitle_(NSString::alloc(nil).init_str(options.title));
|
||||
ns_window.setTitle_(NSString::alloc(nil).init_str(&options.title));
|
||||
ns_window.makeKeyAndOrderFront_(nil);
|
||||
|
||||
let ns_view = NSView::alloc(nil).init();
|
||||
|
@ -52,9 +61,9 @@ impl Window {
|
|||
|
||||
let handler = H::build(&mut window);
|
||||
|
||||
// FIXME: only do this in the unparented case
|
||||
let current_app = NSRunningApplication::currentApplication(nil);
|
||||
current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps);
|
||||
app.run();
|
||||
|
||||
WindowHandle
|
||||
}
|
||||
|
@ -70,5 +79,3 @@ unsafe impl HasRawWindowHandle for Window {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WindowHandle;
|
||||
|
|
|
@ -141,6 +141,29 @@ pub struct Window {
|
|||
hwnd: HWND,
|
||||
}
|
||||
|
||||
pub struct WindowHandle {
|
||||
hwnd: HWND
|
||||
}
|
||||
|
||||
impl WindowHandle {
|
||||
pub fn app_run_blocking(self) {
|
||||
unsafe {
|
||||
let mut msg: MSG = std::mem::zeroed();
|
||||
|
||||
loop {
|
||||
let status = GetMessageA(&mut msg, self.hwnd, 0, 0);
|
||||
|
||||
if status == -1 {
|
||||
break;
|
||||
}
|
||||
|
||||
TranslateMessage(&mut msg);
|
||||
DispatchMessageA(&mut msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub fn open<H: WindowHandler>(options: WindowOpenOptions) -> WindowHandle {
|
||||
unsafe {
|
||||
|
@ -166,13 +189,17 @@ impl Window {
|
|||
};
|
||||
|
||||
// todo: add check flags https://github.com/wrl/rutabaga/blob/f30ff67e157375cafdbafe5fb549f1790443a3a8/src/platform/win/window.c#L351
|
||||
let mut parent = null_mut();
|
||||
if let WithParent(p) = options.parent {
|
||||
parent = p;
|
||||
flags = WS_CHILD | WS_VISIBLE;
|
||||
} else {
|
||||
AdjustWindowRectEx(&mut rect, flags, FALSE, 0);
|
||||
}
|
||||
let parent = match options.parent {
|
||||
WithParent(p) => {
|
||||
flags = WS_CHILD | WS_VISIBLE;
|
||||
p
|
||||
},
|
||||
|
||||
_ => {
|
||||
AdjustWindowRectEx(&mut rect, flags, FALSE, 0);
|
||||
null_mut()
|
||||
}
|
||||
};
|
||||
|
||||
let hwnd = CreateWindowExA(
|
||||
0,
|
||||
|
@ -203,24 +230,12 @@ impl Window {
|
|||
let win = Rc::new(RefCell::new(window));
|
||||
|
||||
SetWindowLongPtrA(hwnd, GWLP_USERDATA, Rc::into_raw(win) as *const _ as _);
|
||||
|
||||
SetTimer(hwnd, 4242, 13, None);
|
||||
|
||||
// todo: decide what to do with the message pump
|
||||
if parent.is_null() {
|
||||
let mut msg: MSG = std::mem::zeroed();
|
||||
loop {
|
||||
let status = GetMessageA(&mut msg, hwnd, 0, 0);
|
||||
if status == -1 {
|
||||
break;
|
||||
}
|
||||
TranslateMessage(&mut msg);
|
||||
DispatchMessageA(&mut msg);
|
||||
}
|
||||
WindowHandle {
|
||||
hwnd
|
||||
}
|
||||
}
|
||||
|
||||
WindowHandle
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,5 +247,3 @@ unsafe impl HasRawWindowHandle for Window {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WindowHandle;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::os::raw::{c_ulong, c_void};
|
||||
use std::time::*;
|
||||
use std::thread;
|
||||
|
||||
use raw_window_handle::{unix::XlibHandle, HasRawWindowHandle, RawWindowHandle};
|
||||
|
||||
|
@ -20,11 +21,27 @@ pub struct Window {
|
|||
}
|
||||
|
||||
// FIXME: move to outer crate context
|
||||
pub struct WindowHandle;
|
||||
pub struct WindowHandle {
|
||||
thread: std::thread::JoinHandle<()>
|
||||
}
|
||||
|
||||
impl WindowHandle {
|
||||
pub fn app_run_blocking(self) {
|
||||
let _ = self.thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Window {
|
||||
pub fn open<H: WindowHandler>(options: WindowOpenOptions) -> WindowHandle {
|
||||
WindowHandle {
|
||||
thread: thread::spawn(move || {
|
||||
Self::window_thread::<H>(options);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn window_thread<H: WindowHandler>(options: WindowOpenOptions) {
|
||||
// Connect to the X server
|
||||
// FIXME: baseview error type instead of unwrap()
|
||||
let xcb_connection = XcbConnection::new().unwrap();
|
||||
|
@ -119,8 +136,6 @@ impl Window {
|
|||
let mut handler = H::build(&mut window);
|
||||
|
||||
window.run_event_loop(&mut handler);
|
||||
|
||||
WindowHandle
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
Loading…
Reference in a new issue