diff options
Diffstat (limited to 'engine/src/windowing.rs')
| -rw-r--r-- | engine/src/windowing.rs | 139 |
1 files changed, 60 insertions, 79 deletions
diff --git a/engine/src/windowing.rs b/engine/src/windowing.rs index be8dc39..dc378fa 100644 --- a/engine/src/windowing.rs +++ b/engine/src/windowing.rs @@ -1,14 +1,15 @@ use std::hint::cold_path; -use std::panic::catch_unwind; +use std::panic::{catch_unwind, AssertUnwindSafe}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Condvar, Mutex, Weak}; use std::thread::Builder as ThreadBuilder; +use std::time::Duration; use crossbeam_queue::ArrayQueue; use raw_window_handle::{DisplayHandle, HandleError, HasDisplayHandle, WindowHandle}; use winit::application::ApplicationHandler; use winit::error::EventLoopError; -use winit::event::{DeviceEvent, DeviceId, MouseScrollDelta, StartCause, WindowEvent}; +use winit::event::{DeviceEvent, DeviceId, StartCause, WindowEvent}; use winit::event_loop::{ ActiveEventLoop, ControlFlow as EventLoopControlFlow, @@ -29,7 +30,8 @@ use crate::ecs::sole::Single; use crate::ecs::system::observer::Observe; use crate::ecs::uid::Uid; use crate::ecs::{declare_entity, Query, Sole}; -use crate::util::{AtomicTwoF64, MapVec}; +use crate::util::MapVec; +use crate::vector::Vec2; use crate::windowing::dpi::{PhysicalPosition, PhysicalSize, Position}; use crate::windowing::keyboard::{Key, KeyState, Keyboard, UnknownKeyCodeError}; use crate::windowing::monitor::Handle as MonitorHandle; @@ -38,6 +40,7 @@ use crate::windowing::mouse::{ ButtonState as MouseButtonState, Buttons as MouseButtons, Mouse, + ScrollDelta as MouseScrollDelta, }; use crate::windowing::window::{ Closed as WindowClosed, @@ -156,29 +159,22 @@ fn update_stuff( keyboard.make_key_states_previous(); mouse_buttons.make_states_previous(); - mouse.curr_tick_position_delta = context - .shared_state - .relative_mouse_pos_delta - .swap((0.0, 0.0), Ordering::Relaxed) - .into(); - - let absolute_mouse_pos = context - .shared_state - .absolute_mouse_pos - .load(Ordering::Relaxed); + let input = { + let Some(mut input) = context + .shared_state + .input + .try_lock_for(Duration::from_millis(100)) + else { + tracing::error!("Locking input mutex timed out after 100ms"); + return Ok(()); + }; - mouse.position = PhysicalPosition { - x: absolute_mouse_pos.0, - y: absolute_mouse_pos.1, + std::mem::take(&mut *input) }; - let mouse_scroll_delta = context - .shared_state - .mouse_scroll_delta - .swap((0.0, 0.0), Ordering::Relaxed); - - mouse.scroll_delta.hor_lines = mouse_scroll_delta.0 as f32; - mouse.scroll_delta.vert_lines = mouse_scroll_delta.1 as f32; + mouse.curr_tick_position_delta = input.relative_mouse_pos_delta; + mouse.position = input.absolute_mouse_pos; + mouse.curr_tick_scroll_delta = input.mouse_scroll_delta; keyboard.set_text_keys(iter_array_queue(&context.shared_state.text_keys)); @@ -655,9 +651,7 @@ struct SharedState { message_from_app_queue: ArrayQueue<MessageFromApp>, message_to_app_queue: ArrayQueue<MessageToApp>, - relative_mouse_pos_delta: AtomicTwoF64, - absolute_mouse_pos: AtomicTwoF64, - mouse_scroll_delta: AtomicTwoF64, + input: AssertUnwindSafe<parking_lot::Mutex<Input>>, text_keys: ArrayQueue<char>, is_dropped: AtomicBool, thread_panicked: AtomicBool, @@ -674,9 +668,7 @@ impl Default for SharedState Self { message_from_app_queue: ArrayQueue::new(MESSAGE_FROM_APP_QUEUE_SIZE), message_to_app_queue: ArrayQueue::new(MESSAGE_TO_APP_QUEUE_SIZE), - relative_mouse_pos_delta: AtomicTwoF64::new((0.0, 0.0)), - absolute_mouse_pos: AtomicTwoF64::new((0.0, 0.0)), - mouse_scroll_delta: AtomicTwoF64::new((0.0, 0.0)), + input: AssertUnwindSafe(parking_lot::Mutex::default()), text_keys: ArrayQueue::new(TEXT_KEY_QUEUE_SIZE), is_dropped: AtomicBool::new(false), thread_panicked: AtomicBool::new(false), @@ -688,6 +680,14 @@ impl Default for SharedState } } +#[derive(Debug, Default, Clone)] +struct Input +{ + relative_mouse_pos_delta: Vec2<f64>, + absolute_mouse_pos: PhysicalPosition<f64>, + mouse_scroll_delta: MouseScrollDelta, +} + #[derive(Debug)] struct InitData { @@ -774,6 +774,13 @@ impl App self.shared_state.message_from_app_queue.force_push(message); } + + fn lock_input(&self) -> Option<parking_lot::MutexGuard<'_, Input>> + { + self.shared_state + .input + .try_lock_for(Duration::from_millis(100)) + } } impl ApplicationHandler for App @@ -900,9 +907,14 @@ impl ApplicationHandler for App )); } WindowEvent::CursorMoved { device_id: _, position } => { - self.shared_state - .absolute_mouse_pos - .store((position.x, position.y), Ordering::Relaxed); + { + let Some(mut input) = self.lock_input() else { + tracing::error!("Locking input mutex timed out after 100ms"); + return; + }; + + input.absolute_mouse_pos = position.into(); + } let Some((window, window_settings)) = self.windows.get(&WindowId::from_inner(window_id)) @@ -965,36 +977,19 @@ impl ApplicationHandler for App { match device_event { DeviceEvent::MouseMotion { delta } => { - let curr_mouse_pos_delta = self - .shared_state - .relative_mouse_pos_delta - .load(Ordering::Relaxed); - - if self - .shared_state - .relative_mouse_pos_delta - .compare_exchange( - curr_mouse_pos_delta, - ( - curr_mouse_pos_delta.0 + delta.0, - curr_mouse_pos_delta.1 + delta.1, - ), - Ordering::Relaxed, - Ordering::Relaxed, - ) - .is_err() - { - self.shared_state - .relative_mouse_pos_delta - .store(delta, Ordering::Relaxed); - } + let Some(mut input) = self.lock_input() else { + tracing::error!("Locking input mutex timed out after 100ms"); + return; + }; + + input.relative_mouse_pos_delta += Vec2::from(delta); } DeviceEvent::MouseWheel { delta } => { - let line_delta = match delta { - MouseScrollDelta::LineDelta(hor_lines, vert_lines) => { - (hor_lines as f64, vert_lines as f64) + let (hor_lines, vert_lines) = match delta { + winit::event::MouseScrollDelta::LineDelta(hor_lines, vert_lines) => { + (hor_lines, vert_lines) } - MouseScrollDelta::PixelDelta(pos_delta) => { + winit::event::MouseScrollDelta::PixelDelta(pos_delta) => { let hor_lines = match pos_delta.x.partial_cmp(&0.0) { Some(std::cmp::Ordering::Greater) => 1.0, Some(std::cmp::Ordering::Less) => -1.0, @@ -1011,27 +1006,13 @@ impl ApplicationHandler for App } }; - let curr_mouse_scroll_delta = - self.shared_state.mouse_scroll_delta.load(Ordering::Relaxed); + let Some(mut input) = self.lock_input() else { + tracing::error!("Locking input mutex timed out after 100ms"); + return; + }; - if self - .shared_state - .mouse_scroll_delta - .compare_exchange( - curr_mouse_scroll_delta, - ( - curr_mouse_scroll_delta.0 + line_delta.0, - curr_mouse_scroll_delta.1 + line_delta.1, - ), - Ordering::Relaxed, - Ordering::Relaxed, - ) - .is_err() - { - self.shared_state - .mouse_scroll_delta - .store(line_delta, Ordering::Relaxed); - } + input.mouse_scroll_delta.hor_lines += hor_lines; + input.mouse_scroll_delta.vert_lines += vert_lines; } _ => {} } |
