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
5 changed files with 85 additions and 47 deletions
|
@ -1,16 +1,5 @@
|
||||||
use baseview::{Event, Window, WindowHandler};
|
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 {}
|
struct MyProgram {}
|
||||||
|
|
||||||
impl WindowHandler for MyProgram {
|
impl WindowHandler for MyProgram {
|
||||||
|
@ -22,7 +11,7 @@ impl WindowHandler for MyProgram {
|
||||||
|
|
||||||
fn on_frame(&mut self) {}
|
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 {
|
match event {
|
||||||
Event::Mouse(e) => println!("Mouse event: {:?}", e),
|
Event::Mouse(e) => println!("Mouse event: {:?}", e),
|
||||||
Event::Keyboard(e) => println!("Keyboard 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 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),
|
WithParent(*mut c_void),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WindowOpenOptions<'a> {
|
unsafe impl Send for Parent {}
|
||||||
pub title: &'a str,
|
|
||||||
|
pub struct WindowOpenOptions {
|
||||||
|
pub title: String,
|
||||||
|
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
pub height: usize,
|
pub height: usize,
|
||||||
|
|
|
@ -20,14 +20,23 @@ pub struct Window {
|
||||||
ns_view: id,
|
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 {
|
impl Window {
|
||||||
pub fn open<H: WindowHandler>(options: WindowOpenOptions) -> WindowHandle {
|
pub fn open<H: WindowHandler>(options: WindowOpenOptions) -> WindowHandle {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _pool = NSAutoreleasePool::new(nil);
|
let _pool = NSAutoreleasePool::new(nil);
|
||||||
|
|
||||||
let app = NSApp();
|
|
||||||
app.setActivationPolicy_(NSApplicationActivationPolicyRegular);
|
|
||||||
|
|
||||||
let rect = NSRect::new(
|
let rect = NSRect::new(
|
||||||
NSPoint::new(0.0, 0.0),
|
NSPoint::new(0.0, 0.0),
|
||||||
NSSize::new(options.width as f64, options.height as f64),
|
NSSize::new(options.width as f64, options.height as f64),
|
||||||
|
@ -42,7 +51,7 @@ impl Window {
|
||||||
)
|
)
|
||||||
.autorelease();
|
.autorelease();
|
||||||
ns_window.center();
|
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);
|
ns_window.makeKeyAndOrderFront_(nil);
|
||||||
|
|
||||||
let ns_view = NSView::alloc(nil).init();
|
let ns_view = NSView::alloc(nil).init();
|
||||||
|
@ -52,9 +61,9 @@ impl Window {
|
||||||
|
|
||||||
let handler = H::build(&mut window);
|
let handler = H::build(&mut window);
|
||||||
|
|
||||||
|
// FIXME: only do this in the unparented case
|
||||||
let current_app = NSRunningApplication::currentApplication(nil);
|
let current_app = NSRunningApplication::currentApplication(nil);
|
||||||
current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps);
|
current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps);
|
||||||
app.run();
|
|
||||||
|
|
||||||
WindowHandle
|
WindowHandle
|
||||||
}
|
}
|
||||||
|
@ -70,5 +79,3 @@ unsafe impl HasRawWindowHandle for Window {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WindowHandle;
|
|
||||||
|
|
|
@ -141,6 +141,29 @@ pub struct Window {
|
||||||
hwnd: HWND,
|
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 {
|
impl Window {
|
||||||
pub fn open<H: WindowHandler>(options: WindowOpenOptions) -> WindowHandle {
|
pub fn open<H: WindowHandler>(options: WindowOpenOptions) -> WindowHandle {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -166,13 +189,17 @@ impl Window {
|
||||||
};
|
};
|
||||||
|
|
||||||
// todo: add check flags https://github.com/wrl/rutabaga/blob/f30ff67e157375cafdbafe5fb549f1790443a3a8/src/platform/win/window.c#L351
|
// todo: add check flags https://github.com/wrl/rutabaga/blob/f30ff67e157375cafdbafe5fb549f1790443a3a8/src/platform/win/window.c#L351
|
||||||
let mut parent = null_mut();
|
let parent = match options.parent {
|
||||||
if let WithParent(p) = options.parent {
|
WithParent(p) => {
|
||||||
parent = p;
|
flags = WS_CHILD | WS_VISIBLE;
|
||||||
flags = WS_CHILD | WS_VISIBLE;
|
p
|
||||||
} else {
|
},
|
||||||
AdjustWindowRectEx(&mut rect, flags, FALSE, 0);
|
|
||||||
}
|
_ => {
|
||||||
|
AdjustWindowRectEx(&mut rect, flags, FALSE, 0);
|
||||||
|
null_mut()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let hwnd = CreateWindowExA(
|
let hwnd = CreateWindowExA(
|
||||||
0,
|
0,
|
||||||
|
@ -203,24 +230,12 @@ impl Window {
|
||||||
let win = Rc::new(RefCell::new(window));
|
let win = Rc::new(RefCell::new(window));
|
||||||
|
|
||||||
SetWindowLongPtrA(hwnd, GWLP_USERDATA, Rc::into_raw(win) as *const _ as _);
|
SetWindowLongPtrA(hwnd, GWLP_USERDATA, Rc::into_raw(win) as *const _ as _);
|
||||||
|
|
||||||
SetTimer(hwnd, 4242, 13, None);
|
SetTimer(hwnd, 4242, 13, None);
|
||||||
|
|
||||||
// todo: decide what to do with the message pump
|
WindowHandle {
|
||||||
if parent.is_null() {
|
hwnd
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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::os::raw::{c_ulong, c_void};
|
||||||
use std::time::*;
|
use std::time::*;
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
use raw_window_handle::{unix::XlibHandle, HasRawWindowHandle, RawWindowHandle};
|
use raw_window_handle::{unix::XlibHandle, HasRawWindowHandle, RawWindowHandle};
|
||||||
|
|
||||||
|
@ -20,11 +21,27 @@ pub struct Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: move to outer crate context
|
// 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 {
|
impl Window {
|
||||||
pub fn open<H: WindowHandler>(options: WindowOpenOptions) -> WindowHandle {
|
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
|
// Connect to the X server
|
||||||
// FIXME: baseview error type instead of unwrap()
|
// FIXME: baseview error type instead of unwrap()
|
||||||
let xcb_connection = XcbConnection::new().unwrap();
|
let xcb_connection = XcbConnection::new().unwrap();
|
||||||
|
@ -119,8 +136,6 @@ impl Window {
|
||||||
let mut handler = H::build(&mut window);
|
let mut handler = H::build(&mut window);
|
||||||
|
|
||||||
window.run_event_loop(&mut handler);
|
window.run_event_loop(&mut handler);
|
||||||
|
|
||||||
WindowHandle
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
Loading…
Add table
Reference in a new issue