1
0
Fork 0

remove Message api

This commit is contained in:
Micah Johnston 2020-12-08 18:37:17 -06:00 committed by glowcoil
parent cd0d5215d0
commit 8402310c88
8 changed files with 41 additions and 136 deletions

View file

@ -16,7 +16,6 @@ license = "MIT OR Apache-2.0"
[dependencies] [dependencies]
keyboard-types = { version = "0.5.0", default-features = false } keyboard-types = { version = "0.5.0", default-features = false }
raw-window-handle = "0.3.3" raw-window-handle = "0.3.3"
rtrb = "0.1.1"
static_assertions = "1.1.0" static_assertions = "1.1.0"
[target.'cfg(target_os="linux")'.dependencies] [target.'cfg(target_os="linux")'.dependencies]
@ -32,3 +31,6 @@ winapi = { version = "0.3.8", features = ["libloaderapi", "winuser", "windef", "
cocoa = "0.24.0" cocoa = "0.24.0"
objc = "0.2.7" objc = "0.2.7"
uuid = { version = "0.8", features = ["v4"] } uuid = { version = "0.8", features = ["v4"] }
[dev-dependencies]
rtrb = "0.1.1"

View file

@ -1,21 +1,24 @@
use std::time::Duration; use std::time::Duration;
use baseview::{Event, Window, WindowHandler, WindowScalePolicy}; use rtrb::{RingBuffer, Consumer};
use baseview::{Event, Window, WindowHandler, WindowScalePolicy};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Message { enum Message {
Hello Hello
} }
struct OpenWindowExample {
struct OpenWindowExample; rx: Consumer<Message>,
}
impl WindowHandler for OpenWindowExample { impl WindowHandler for OpenWindowExample {
type Message = Message; fn on_frame(&mut self) {
while let Ok(message) = self.rx.pop() {
fn on_frame(&mut self) {} println!("Message: {:?}", message);
}
}
fn on_event(&mut self, _window: &mut Window, event: Event) { fn on_event(&mut self, _window: &mut Window, event: Event) {
match event { match event {
@ -24,13 +27,8 @@ impl WindowHandler for OpenWindowExample {
Event::Window(e) => println!("Window event: {:?}", e), Event::Window(e) => println!("Window event: {:?}", e),
} }
} }
fn on_message(&mut self, _window: &mut Window, message: Self::Message) {
println!("Message: {:?}", message);
}
} }
fn main() { fn main() {
let window_open_options = baseview::WindowOpenOptions { let window_open_options = baseview::WindowOpenOptions {
title: "baseview".into(), title: "baseview".into(),
@ -39,16 +37,18 @@ fn main() {
parent: baseview::Parent::None, parent: baseview::Parent::None,
}; };
let (mut handle, opt_app_runner) = Window::open( let (mut tx, rx) = RingBuffer::new(128).split();
let (_handle, opt_app_runner) = Window::open(
window_open_options, window_open_options,
|_| OpenWindowExample |_| OpenWindowExample { rx }
); );
::std::thread::spawn(move || { ::std::thread::spawn(move || {
loop { loop {
::std::thread::sleep(Duration::from_secs(5)); ::std::thread::sleep(Duration::from_secs(5));
if let Err(_) = handle.try_send_message(Message::Hello){ if let Err(_) = tx.push(Message::Hello) {
println!("Failed sending message"); println!("Failed sending message");
} }
} }

View file

@ -20,8 +20,6 @@ pub use window::*;
pub use window_info::*; pub use window_info::*;
pub use window_open_options::*; pub use window_open_options::*;
const MESSAGE_QUEUE_LEN: usize = 128;
#[derive(Debug)] #[derive(Debug)]
pub enum Parent { pub enum Parent {
None, None,
@ -32,9 +30,6 @@ pub enum Parent {
unsafe impl Send for Parent {} unsafe impl Send for Parent {}
pub trait WindowHandler { pub trait WindowHandler {
type Message: Send + 'static;
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);
fn on_message(&mut self, window: &mut Window, message: Self::Message);
} }

View file

@ -195,7 +195,6 @@ extern "C" fn trigger_on_frame<H: WindowHandler>(
WindowState::from_field(this) WindowState::from_field(this)
}; };
state.handle_messages();
state.trigger_frame(); state.trigger_frame();
} }

View file

@ -12,11 +12,10 @@ use keyboard_types::KeyboardEvent;
use objc::{msg_send, runtime::Object, sel, sel_impl}; use objc::{msg_send, runtime::Object, sel, sel_impl};
use raw_window_handle::{macos::MacOSHandle, HasRawWindowHandle, RawWindowHandle}; use raw_window_handle::{macos::MacOSHandle, HasRawWindowHandle, RawWindowHandle};
use rtrb::{RingBuffer, Producer, Consumer, PushError};
use crate::{ use crate::{
Event, Parent, WindowHandler, WindowOpenOptions, Event, Parent, WindowHandler, WindowOpenOptions,
WindowScalePolicy, WindowInfo, MESSAGE_QUEUE_LEN WindowScalePolicy, WindowInfo
}; };
use super::view::create_view; use super::view::create_view;
@ -41,7 +40,6 @@ pub struct Window {
pub struct AppRunner; pub struct AppRunner;
impl AppRunner { impl AppRunner {
pub fn app_run_blocking(self) { pub fn app_run_blocking(self) {
unsafe { unsafe {
@ -53,27 +51,14 @@ impl AppRunner {
} }
pub struct WindowHandle<H: WindowHandler> { pub struct WindowHandle;
message_tx: Producer<H::Message>,
}
impl <H: WindowHandler>WindowHandle<H> {
pub fn try_send_message(
&mut self,
message: H::Message
) -> Result<(), H::Message> {
self.message_tx.push(message)
.map_err(|PushError::Full(message)| message)
}
}
impl Window { impl Window {
pub fn open<H, B>( pub fn open<H, B>(
options: WindowOpenOptions, options: WindowOpenOptions,
build: B build: B
) -> (crate::WindowHandle<H>, Option<crate::AppRunner>) ) -> (crate::WindowHandle, Option<crate::AppRunner>)
where H: WindowHandler, where H: WindowHandler,
B: FnOnce(&mut crate::Window) -> H, B: FnOnce(&mut crate::Window) -> H,
B: Send + 'static B: Send + 'static
@ -178,14 +163,10 @@ impl Window {
let window_handler = build(&mut crate::Window(&mut window)); let window_handler = build(&mut crate::Window(&mut window));
let (message_tx, message_rx) = RingBuffer::new(MESSAGE_QUEUE_LEN)
.split();
let window_state_arc = Arc::new(WindowState { let window_state_arc = Arc::new(WindowState {
window, window,
window_handler, window_handler,
keyboard_state: KeyboardState::new(), keyboard_state: KeyboardState::new(),
message_rx
}); });
let window_state_pointer = Arc::into_raw( let window_state_pointer = Arc::into_raw(
@ -220,9 +201,7 @@ impl Window {
) )
} }
let window_handle = crate::WindowHandle(WindowHandle { let window_handle = crate::WindowHandle(WindowHandle);
message_tx
});
(window_handle, opt_app_runner) (window_handle, opt_app_runner)
} }
@ -233,11 +212,10 @@ pub(super) struct WindowState<H: WindowHandler> {
window: Window, window: Window,
window_handler: H, window_handler: H,
keyboard_state: KeyboardState, keyboard_state: KeyboardState,
message_rx: Consumer<H::Message>,
} }
impl <H: WindowHandler>WindowState<H> { impl<H: WindowHandler> WindowState<H> {
/// 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
@ -249,15 +227,6 @@ impl <H: WindowHandler>WindowState<H> {
&mut *(state_ptr as *mut Self) &mut *(state_ptr as *mut Self)
} }
pub(super) fn handle_messages(&mut self){
while let Ok(message) = self.message_rx.pop(){
self.window_handler.on_message(
&mut crate::Window(&mut self.window),
message
)
}
}
pub(super) fn trigger_event(&mut self, event: Event){ pub(super) fn trigger_event(&mut self, event: Event){
self.window_handler.on_event( self.window_handler.on_event(
&mut crate::Window(&mut self.window), &mut crate::Window(&mut self.window),

View file

@ -195,19 +195,7 @@ pub struct Window {
hwnd: HWND, hwnd: HWND,
} }
pub struct WindowHandle<H: WindowHandler> { pub struct WindowHandle;
// FIXME: replace this with channel sender
phantom_data: std::marker::PhantomData<H::Message>,
}
impl <H: WindowHandler>WindowHandle<H> {
pub fn try_send_message(
&mut self,
message: H::Message
) -> Result<(), H::Message> {
Err(message)
}
}
pub struct AppRunner { pub struct AppRunner {
hwnd: HWND, hwnd: HWND,
@ -236,7 +224,7 @@ impl Window {
pub fn open<H, B>( pub fn open<H, B>(
options: WindowOpenOptions, options: WindowOpenOptions,
build: B build: B
) -> (crate::WindowHandle<H>, Option<crate::AppRunner>) ) -> (crate::WindowHandle, Option<crate::AppRunner>)
where H: WindowHandler, where H: WindowHandler,
B: FnOnce(&mut crate::Window) -> H, B: FnOnce(&mut crate::Window) -> H,
B: Send + 'static B: Send + 'static
@ -313,9 +301,7 @@ impl Window {
SetWindowLongPtrA(hwnd, GWLP_USERDATA, Box::into_raw(window_state) as *const _ as _); SetWindowLongPtrA(hwnd, GWLP_USERDATA, Box::into_raw(window_state) as *const _ as _);
SetTimer(hwnd, WIN_FRAME_TIMER, 15, None); SetTimer(hwnd, WIN_FRAME_TIMER, 15, None);
let window_handle = crate::WindowHandle(WindowHandle { let window_handle = crate::WindowHandle(WindowHandle);
phantom_data: std::marker::PhantomData,
});
let opt_app_runner = if let crate::Parent::None = options.parent { let opt_app_runner = if let crate::Parent::None = options.parent {
Some(crate::AppRunner(AppRunner { hwnd })) Some(crate::AppRunner(AppRunner { hwnd }))

View file

@ -10,40 +10,23 @@ use crate::x11 as platform;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
use crate::macos as platform; use crate::macos as platform;
pub struct AppRunner(pub(crate) platform::AppRunner); pub struct AppRunner(pub(crate) platform::AppRunner);
impl AppRunner { impl AppRunner {
pub fn app_run_blocking(self){ pub fn app_run_blocking(self){
self.0.app_run_blocking(); self.0.app_run_blocking();
} }
} }
pub struct WindowHandle(pub(crate) platform::WindowHandle);
pub struct WindowHandle<H: WindowHandler>(
pub(crate) platform::WindowHandle<H>
);
impl <H: WindowHandler>WindowHandle<H> {
pub fn try_send_message(
&mut self,
message: H::Message
) -> Result<(), H::Message> {
self.0.try_send_message(message)
}
}
pub struct Window<'a>(pub(crate) &'a mut platform::Window); pub struct Window<'a>(pub(crate) &'a mut platform::Window);
impl<'a> Window<'a> {
impl <'a>Window<'a> {
pub fn open<H, B>( pub fn open<H, B>(
options: WindowOpenOptions, options: WindowOpenOptions,
build: B build: B
) -> (WindowHandle<H>, Option<AppRunner>) ) -> (WindowHandle, Option<AppRunner>)
where H: WindowHandler, where H: WindowHandler,
B: FnOnce(&mut Window) -> H, B: FnOnce(&mut Window) -> H,
B: Send + 'static B: Send + 'static
@ -52,14 +35,12 @@ impl <'a>Window<'a> {
} }
} }
unsafe impl<'a> HasRawWindowHandle for Window<'a> {
unsafe impl <'a>HasRawWindowHandle for Window<'a> {
fn raw_window_handle(&self) -> RawWindowHandle { fn raw_window_handle(&self) -> RawWindowHandle {
self.0.raw_window_handle() self.0.raw_window_handle()
} }
} }
// Compile-time API assertions // Compile-time API assertions
#[doc(hidden)] #[doc(hidden)]
mod assertions { mod assertions {
@ -71,14 +52,11 @@ mod assertions {
} }
impl WindowHandler for TestWindowHandler { impl WindowHandler for TestWindowHandler {
type Message = ();
fn on_event(&mut self, _: &mut Window, _: Event) {} fn on_event(&mut self, _: &mut Window, _: Event) {}
fn on_message(&mut self, _: &mut Window, _: Self::Message) {}
fn on_frame(&mut self) {} fn on_frame(&mut self) {}
} }
// Assert that WindowHandle is Send even if WindowHandler isn't // Assert that WindowHandle is Send even if WindowHandler isn't
static_assertions::assert_not_impl_any!(TestWindowHandler: Send); static_assertions::assert_not_impl_any!(TestWindowHandler: Send);
static_assertions::assert_impl_all!(WindowHandle<TestWindowHandler>: Send); static_assertions::assert_impl_all!(WindowHandle: Send);
} }

View file

@ -8,13 +8,12 @@ use raw_window_handle::{
HasRawWindowHandle, HasRawWindowHandle,
RawWindowHandle RawWindowHandle
}; };
use rtrb::{RingBuffer, Producer, Consumer, PushError};
use super::XcbConnection; use super::XcbConnection;
use crate::{ use crate::{
Event, MouseButton, MouseCursor, MouseEvent, Parent, ScrollDelta, Event, MouseButton, MouseCursor, MouseEvent, Parent, ScrollDelta,
WindowEvent, WindowHandler, WindowInfo, WindowOpenOptions, WindowEvent, WindowHandler, WindowInfo, WindowOpenOptions,
WindowScalePolicy, PhyPoint, PhySize, MESSAGE_QUEUE_LEN, WindowScalePolicy, PhyPoint, PhySize,
}; };
use super::keyboard::{convert_key_press_event, convert_key_release_event}; use super::keyboard::{convert_key_press_event, convert_key_release_event};
@ -31,19 +30,8 @@ pub struct Window {
new_physical_size: Option<PhySize>, new_physical_size: Option<PhySize>,
} }
pub struct WindowHandle<H: WindowHandler> { pub struct WindowHandle;
message_tx: Producer<H::Message>,
}
impl <H: WindowHandler>WindowHandle<H> {
pub fn try_send_message(
&mut self,
message: H::Message
) -> Result<(), H::Message> {
self.message_tx.push(message)
.map_err(|PushError::Full(message)| message)
}
}
pub struct AppRunner { pub struct AppRunner {
thread: std::thread::JoinHandle<()>, thread: std::thread::JoinHandle<()>,
@ -61,7 +49,7 @@ impl Window {
pub fn open<H, B>( pub fn open<H, B>(
options: WindowOpenOptions, options: WindowOpenOptions,
build: B build: B
) -> (crate::WindowHandle<H>, Option<crate::AppRunner>) ) -> (crate::WindowHandle, Option<crate::AppRunner>)
where H: WindowHandler, where H: WindowHandler,
B: FnOnce(&mut crate::Window) -> H, B: FnOnce(&mut crate::Window) -> H,
B: Send + 'static B: Send + 'static
@ -70,11 +58,8 @@ impl Window {
let (tx, rx) = mpsc::sync_channel::<WindowOpenResult>(1); let (tx, rx) = mpsc::sync_channel::<WindowOpenResult>(1);
let (message_tx, message_rx) = RingBuffer::new(MESSAGE_QUEUE_LEN)
.split();
let thread = thread::spawn(move || { let thread = thread::spawn(move || {
if let Err(e) = Self::window_thread::<H, B>(options, build, tx.clone(), message_rx) { if let Err(e) = Self::window_thread::<H, B>(options, build, tx.clone()) {
let _ = tx.send(Err(e)); let _ = tx.send(Err(e));
} }
}); });
@ -82,9 +67,7 @@ impl Window {
// FIXME: placeholder types for returning errors in the future // FIXME: placeholder types for returning errors in the future
let _ = rx.recv(); let _ = rx.recv();
let window_handle = crate::WindowHandle(WindowHandle { let window_handle = crate::WindowHandle(WindowHandle);
message_tx
});
let opt_app_runner = if is_not_parented { let opt_app_runner = if is_not_parented {
Some(crate::AppRunner(AppRunner { thread })) Some(crate::AppRunner(AppRunner { thread }))
@ -95,9 +78,9 @@ impl Window {
(window_handle, opt_app_runner) (window_handle, opt_app_runner)
} }
fn window_thread<H, B>(options: WindowOpenOptions, build: B, fn window_thread<H, B>(
options: WindowOpenOptions, build: B,
tx: mpsc::SyncSender<WindowOpenResult>, tx: mpsc::SyncSender<WindowOpenResult>,
message_rx: Consumer<H::Message>,
) -> WindowOpenResult ) -> WindowOpenResult
where H: WindowHandler, where H: WindowHandler,
B: FnOnce(&mut crate::Window) -> H, B: FnOnce(&mut crate::Window) -> H,
@ -211,7 +194,7 @@ impl Window {
let _ = tx.send(Ok(())); let _ = tx.send(Ok(()));
window.run_event_loop(&mut handler, message_rx); window.run_event_loop(&mut handler);
Ok(()) Ok(())
} }
@ -269,7 +252,7 @@ impl Window {
// FIXME: poll() acts fine on linux, sometimes funky on *BSD. XCB upstream uses a define to // FIXME: poll() acts fine on linux, sometimes funky on *BSD. XCB upstream uses a define to
// switch between poll() and select() (the latter of which is fine on *BSD), and we should do // switch between poll() and select() (the latter of which is fine on *BSD), and we should do
// the same. // the same.
fn run_event_loop<H: WindowHandler>(&mut self, handler: &mut H, mut message_rx: Consumer<H::Message>) { fn run_event_loop<H: WindowHandler>(&mut self, handler: &mut H) {
use nix::poll::*; use nix::poll::*;
let xcb_fd = unsafe { let xcb_fd = unsafe {
@ -305,13 +288,6 @@ impl Window {
self.drain_xcb_events(handler); self.drain_xcb_events(handler);
} }
} }
while let Ok(message) = message_rx.pop(){
handler.on_message(
&mut crate::Window(self),
message
)
}
} }
} }