1
0
Fork 0

implement try_send_message for Linux

This commit is contained in:
Billy Messenger 2020-12-04 15:29:55 -06:00
parent 72d55c9dba
commit f696c7d14d
2 changed files with 24 additions and 11 deletions

View file

@ -32,7 +32,7 @@ pub enum Parent {
unsafe impl Send for Parent {} unsafe impl Send for Parent {}
pub trait WindowHandler { pub trait WindowHandler {
type Message: Send; 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);

View file

@ -8,12 +8,13 @@ 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, WindowScalePolicy, PhyPoint, PhySize, MESSAGE_QUEUE_LEN,
}; };
use super::keyboard::{convert_key_press_event, convert_key_release_event}; use super::keyboard::{convert_key_press_event, convert_key_release_event};
@ -27,12 +28,11 @@ pub struct Window {
frame_interval: Duration, frame_interval: Duration,
event_loop_running: bool, event_loop_running: bool,
new_physical_size: Option<PhySize> new_physical_size: Option<PhySize>,
} }
pub struct WindowHandle<H: WindowHandler> { pub struct WindowHandle<H: WindowHandler> {
// FIXME: replace this with channel sender message_tx: Producer<H::Message>,
phantom_data: std::marker::PhantomData<H::Message>,
} }
impl <H: WindowHandler>WindowHandle<H> { impl <H: WindowHandler>WindowHandle<H> {
@ -40,7 +40,8 @@ impl <H: WindowHandler>WindowHandle<H> {
&mut self, &mut self,
message: H::Message message: H::Message
) -> Result<(), H::Message> { ) -> Result<(), H::Message> {
Err(message) self.message_tx.push(message)
.map_err(|PushError::Full(message)| message)
} }
} }
@ -69,8 +70,11 @@ 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()) { if let Err(e) = Self::window_thread::<H, B>(options, build, tx.clone(), message_rx) {
let _ = tx.send(Err(e)); let _ = tx.send(Err(e));
} }
}); });
@ -79,7 +83,7 @@ impl Window {
let _ = rx.recv(); let _ = rx.recv();
let window_handle = crate::WindowHandle(WindowHandle { let window_handle = crate::WindowHandle(WindowHandle {
phantom_data: std::marker::PhantomData message_tx
}); });
let opt_app_runner = if is_not_parented { let opt_app_runner = if is_not_parented {
@ -92,7 +96,9 @@ impl Window {
} }
fn window_thread<H, B>(options: WindowOpenOptions, build: B, fn window_thread<H, B>(options: WindowOpenOptions, build: B,
tx: mpsc::SyncSender<WindowOpenResult>) -> WindowOpenResult tx: mpsc::SyncSender<WindowOpenResult>,
message_rx: Consumer<H::Message>,
) -> WindowOpenResult
where H: WindowHandler, where H: WindowHandler,
B: FnOnce(&mut crate::Window) -> H, B: FnOnce(&mut crate::Window) -> H,
B: Send + 'static B: Send + 'static
@ -205,7 +211,7 @@ impl Window {
let _ = tx.send(Ok(())); let _ = tx.send(Ok(()));
window.run_event_loop(&mut handler); window.run_event_loop(&mut handler, message_rx);
Ok(()) Ok(())
} }
@ -263,7 +269,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) { fn run_event_loop<H: WindowHandler>(&mut self, handler: &mut H, mut message_rx: Consumer<H::Message>) {
use nix::poll::*; use nix::poll::*;
let xcb_fd = unsafe { let xcb_fd = unsafe {
@ -299,6 +305,13 @@ 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
)
}
} }
} }