218 lines
7.9 KiB
Rust
Raw Normal View History

use crate::physics_worker::InputInstruction;
2024-01-29 16:19:41 -08:00
use strafesnet_common::integer;
use strafesnet_common::instruction::TimedInstruction;
use strafesnet_common::session::{Time as SessionTime,TimeInner as SessionTimeInner};
pub enum WindowInstruction{
Resize(winit::dpi::PhysicalSize<u32>),
WindowEvent(winit::event::WindowEvent),
DeviceEvent(winit::event::DeviceEvent),
RequestRedraw,
Render,
}
//holds thread handles to dispatch to
struct WindowContext<'a>{
manual_mouse_lock:bool,
mouse:strafesnet_common::mouse::MouseState<SessionTimeInner>,//std::sync::Arc<std::sync::Mutex<>>
screen_size:glam::UVec2,
window:&'a winit::window::Window,
physics_thread:crate::compat_worker::QNWorker<'a,TimedInstruction<crate::physics_worker::Instruction,SessionTimeInner>>,
}
impl WindowContext<'_>{
fn get_middle_of_screen(&self)->winit::dpi::PhysicalPosition<u32>{
winit::dpi::PhysicalPosition::new(self.screen_size.x/2,self.screen_size.y/2)
}
fn window_event(&mut self,time:SessionTime,event:winit::event::WindowEvent){
2025-01-03 02:31:43 -08:00
match event{
winit::event::WindowEvent::DroppedFile(path)=>{
2024-02-13 21:56:11 -08:00
match crate::file::load(path.as_path()){
2024-08-06 11:26:27 -07:00
Ok(map)=>self.physics_thread.send(TimedInstruction{time,instruction:crate::physics_worker::Instruction::ChangeMap(map)}).unwrap(),
2024-02-13 21:56:11 -08:00
Err(e)=>println!("Failed to load map: {e}"),
}
},
2024-08-02 10:41:42 -07:00
winit::event::WindowEvent::Focused(state)=>{
//pause unpause
2024-08-02 10:41:42 -07:00
self.physics_thread.send(TimedInstruction{
time,
instruction:crate::physics_worker::Instruction::SetPaused(!state),
}).unwrap();
//recalculate pressed keys on focus
},
winit::event::WindowEvent::KeyboardInput{
event:winit::event::KeyEvent{state,logical_key,repeat:false,..},
..
}=>{
2025-01-03 02:20:09 -08:00
match (logical_key,state){
(winit::keyboard::Key::Named(winit::keyboard::NamedKey::Tab),winit::event::ElementState::Pressed)=>{
self.manual_mouse_lock=false;
match self.window.set_cursor_position(self.get_middle_of_screen()){
Ok(())=>(),
Err(e)=>println!("Could not set cursor position: {:?}",e),
}
match self.window.set_cursor_grab(winit::window::CursorGrabMode::None){
Ok(())=>(),
Err(e)=>println!("Could not release cursor: {:?}",e),
}
self.window.set_cursor_visible(state.is_pressed());
},
(winit::keyboard::Key::Named(winit::keyboard::NamedKey::Tab),winit::event::ElementState::Released)=>{
//if cursor is outside window don't lock but apparently there's no get pos function
//let pos=window.get_cursor_pos();
match self.window.set_cursor_grab(winit::window::CursorGrabMode::Locked){
Ok(())=>(),
Err(_)=>{
match self.window.set_cursor_grab(winit::window::CursorGrabMode::Confined){
Ok(())=>(),
Err(e)=>{
self.manual_mouse_lock=true;
println!("Could not confine cursor: {:?}",e)
},
}
}
}
2025-01-03 02:20:09 -08:00
self.window.set_cursor_visible(state.is_pressed());
},
2025-01-03 02:20:09 -08:00
(winit::keyboard::Key::Named(winit::keyboard::NamedKey::F11),winit::event::ElementState::Pressed)=>{
if self.window.fullscreen().is_some(){
self.window.set_fullscreen(None);
}else{
self.window.set_fullscreen(Some(winit::window::Fullscreen::Borderless(None)));
}
},
2025-01-03 02:20:09 -08:00
(winit::keyboard::Key::Named(winit::keyboard::NamedKey::Escape),winit::event::ElementState::Pressed)=>{
self.manual_mouse_lock=false;
match self.window.set_cursor_grab(winit::window::CursorGrabMode::None){
Ok(())=>(),
Err(e)=>println!("Could not release cursor: {:?}",e),
}
2025-01-03 02:20:09 -08:00
self.window.set_cursor_visible(true);
},
2025-01-03 02:20:09 -08:00
(keycode,state)=>{
let s=state.is_pressed();
if let Some(input_instruction)=match keycode{
winit::keyboard::Key::Named(winit::keyboard::NamedKey::Space)=>Some(InputInstruction::Jump(s)),
winit::keyboard::Key::Character(key)=>match key.as_str(){
"W"|"w"=>Some(InputInstruction::MoveForward(s)),
"A"|"a"=>Some(InputInstruction::MoveLeft(s)),
"S"|"s"=>Some(InputInstruction::MoveBack(s)),
"D"|"d"=>Some(InputInstruction::MoveRight(s)),
"E"|"e"=>Some(InputInstruction::MoveUp(s)),
"Q"|"q"=>Some(InputInstruction::MoveDown(s)),
"Z"|"z"=>Some(InputInstruction::Zoom(s)),
"R"|"r"=>if s{
//mouse needs to be reset since the position is absolute
2024-08-06 11:10:43 -07:00
self.mouse=strafesnet_common::mouse::MouseState::default();
2024-08-06 11:26:27 -07:00
Some(InputInstruction::ResetAndRestart)
}else{None},
"F"|"f"=>if s{Some(InputInstruction::PracticeFly)}else{None},
_=>None,
},
_=>None,
}{
self.physics_thread.send(TimedInstruction{
time,
instruction:crate::physics_worker::Instruction::Input(input_instruction),
}).unwrap();
}
},
}
},
_=>(),
}
}
fn device_event(&mut self,time:SessionTime,event: winit::event::DeviceEvent){
2025-01-03 02:31:43 -08:00
match event{
winit::event::DeviceEvent::MouseMotion{
delta,//these (f64,f64) are integers on my machine
2025-01-03 02:31:43 -08:00
}=>{
if self.manual_mouse_lock{
match self.window.set_cursor_position(self.get_middle_of_screen()){
Ok(())=>(),
Err(e)=>println!("Could not set cursor position: {:?}",e),
}
}
//do not step the physics because the mouse polling rate is higher than the physics can run.
//essentially the previous input will be overwritten until a true step runs
//which is fine because they run all the time.
let delta=glam::ivec2(delta.0 as i32,delta.1 as i32);
self.mouse.pos+=delta;
self.physics_thread.send(TimedInstruction{
time,
instruction:crate::physics_worker::Instruction::Input(InputInstruction::MoveMouse(self.mouse.pos)),
}).unwrap();
},
winit::event::DeviceEvent::MouseWheel {
delta,
2025-01-03 02:31:43 -08:00
}=>{
println!("mousewheel {:?}",delta);
if false{//self.physics.style.use_scroll{
self.physics_thread.send(TimedInstruction{
time,
instruction:crate::physics_worker::Instruction::Input(InputInstruction::Jump(true)),//activates the immediate jump path, but the style modifier prevents controls&CONTROL_JUMP bit from being set to auto jump
}).unwrap();
}
2025-01-03 02:31:43 -08:00
},
_=>(),
}
}
}
2024-08-06 11:26:27 -07:00
pub fn worker<'a>(
window:&'a winit::window::Window,
2024-08-06 11:26:27 -07:00
setup_context:crate::setup::SetupContext<'a>,
)->crate::compat_worker::QNWorker<'a,TimedInstruction<WindowInstruction,SessionTimeInner>>{
2024-08-06 11:26:27 -07:00
// WindowContextSetup::new
2025-01-03 02:31:43 -08:00
let user_settings=crate::settings::read_user_settings();
2025-01-03 02:31:43 -08:00
let mut graphics=crate::graphics::GraphicsState::new(&setup_context.device,&setup_context.queue,&setup_context.config);
graphics.load_user_settings(&user_settings);
2024-08-06 11:26:27 -07:00
//WindowContextSetup::into_context
2025-01-03 02:31:43 -08:00
let screen_size=glam::uvec2(setup_context.config.width,setup_context.config.height);
let graphics_thread=crate::graphics_worker::new(graphics,setup_context.config,setup_context.surface,setup_context.device,setup_context.queue);
let mut window_context=WindowContext{
manual_mouse_lock:false,
mouse:strafesnet_common::mouse::MouseState::default(),
//make sure to update this!!!!!
screen_size,
window,
physics_thread:crate::physics_worker::new(
graphics_thread,
user_settings,
),
};
2024-08-06 11:26:27 -07:00
//WindowContextSetup::into_worker
crate::compat_worker::QNWorker::new(move |ins:TimedInstruction<WindowInstruction,SessionTimeInner>|{
2025-01-03 02:31:43 -08:00
match ins.instruction{
WindowInstruction::RequestRedraw=>{
window_context.window.request_redraw();
}
WindowInstruction::WindowEvent(window_event)=>{
window_context.window_event(ins.time,window_event);
},
WindowInstruction::DeviceEvent(device_event)=>{
window_context.device_event(ins.time,device_event);
},
WindowInstruction::Resize(size)=>{
window_context.physics_thread.send(
TimedInstruction{
time:ins.time,
instruction:crate::physics_worker::Instruction::Resize(size)
}
).unwrap();
}
WindowInstruction::Render=>{
window_context.physics_thread.send(
TimedInstruction{
time:ins.time,
instruction:crate::physics_worker::Instruction::Render
}
).unwrap();
}
2025-01-03 02:31:43 -08:00
}
})
}