diff --git a/src/physics_worker.rs b/src/physics_worker.rs index 24587ae..3981e1e 100644 --- a/src/physics_worker.rs +++ b/src/physics_worker.rs @@ -1,6 +1,8 @@ use crate::physics::{MouseState,PhysicsInputInstruction}; use strafesnet_common::integer::Time; -use strafesnet_common::instruction::{TimedInstruction,InstructionConsumer}; +use strafesnet_common::instruction::TimedInstruction; +use strafesnet_common::timer::{Scaled,Timer,TimerState}; + #[derive(Debug)] pub enum InputInstruction{ MoveMouse(glam::IVec2), @@ -22,12 +24,14 @@ pub enum Instruction{ Resize(winit::dpi::PhysicalSize,crate::settings::UserSettings), GenerateModels(strafesnet_common::map::CompleteMap), ClearModels, + SetPaused(bool), //Graphics(crate::graphics_worker::Instruction), } pub struct MouseInterpolator{ timeline:std::collections::VecDeque>, last_mouse_time:Time, mouse_blocking:bool, + timer:Timer, } impl MouseInterpolator{ fn push_mouse_instruction(&mut self,physics:&crate::physics::PhysicsContext,ins:&TimedInstruction,m:glam::IVec2){ @@ -35,7 +39,7 @@ impl MouseInterpolator{ //tell the game state which is living in the past about its future self.timeline.push_front(TimedInstruction{ time:self.last_mouse_time, - instruction:PhysicsInputInstruction::SetNextMouse(MouseState{time:ins.time,pos:m}), + instruction:PhysicsInputInstruction::SetNextMouse(MouseState{time:self.timer.time(ins.time),pos:m}), }); }else{ //mouse has just started moving again after being still for longer than 10ms. @@ -44,7 +48,7 @@ impl MouseInterpolator{ time:self.last_mouse_time, instruction:PhysicsInputInstruction::ReplaceMouse( MouseState{time:self.last_mouse_time,pos:physics.get_next_mouse().pos}, - MouseState{time:ins.time,pos:m} + MouseState{time:self.timer.time(ins.time),pos:m} ), }); //delay physics execution until we have an interpolation target @@ -56,27 +60,38 @@ impl MouseInterpolator{ /// may or may not mutate internal state XD! fn map_instruction(&mut self,physics:&crate::physics::PhysicsContext,ins:&TimedInstruction)->Option{ match &ins.instruction{ - Instruction::Input(input_instruction)=>match input_instruction{ - &InputInstruction::MoveMouse(m)=>{ - self.push_mouse_instruction(physics,ins,m); - None + Instruction::Input(input_instruction)=>match self.timer.is_paused(){ + true=>None, + false=>match input_instruction{ + &InputInstruction::MoveMouse(m)=>{ + self.push_mouse_instruction(physics,ins,m); + None + }, + &InputInstruction::MoveForward(s)=>Some(PhysicsInputInstruction::SetMoveForward(s)), + &InputInstruction::MoveLeft(s)=>Some(PhysicsInputInstruction::SetMoveLeft(s)), + &InputInstruction::MoveBack(s)=>Some(PhysicsInputInstruction::SetMoveBack(s)), + &InputInstruction::MoveRight(s)=>Some(PhysicsInputInstruction::SetMoveRight(s)), + &InputInstruction::MoveUp(s)=>Some(PhysicsInputInstruction::SetMoveUp(s)), + &InputInstruction::MoveDown(s)=>Some(PhysicsInputInstruction::SetMoveDown(s)), + &InputInstruction::Jump(s)=>Some(PhysicsInputInstruction::SetJump(s)), + &InputInstruction::Zoom(s)=>Some(PhysicsInputInstruction::SetZoom(s)), + &InputInstruction::Spawn(mode_id,stage_id)=>Some(PhysicsInputInstruction::Spawn(mode_id,stage_id)), + InputInstruction::Restart=>Some(PhysicsInputInstruction::Restart), + InputInstruction::PracticeFly=>Some(PhysicsInputInstruction::PracticeFly), }, - &InputInstruction::MoveForward(s)=>Some(PhysicsInputInstruction::SetMoveForward(s)), - &InputInstruction::MoveLeft(s)=>Some(PhysicsInputInstruction::SetMoveLeft(s)), - &InputInstruction::MoveBack(s)=>Some(PhysicsInputInstruction::SetMoveBack(s)), - &InputInstruction::MoveRight(s)=>Some(PhysicsInputInstruction::SetMoveRight(s)), - &InputInstruction::MoveUp(s)=>Some(PhysicsInputInstruction::SetMoveUp(s)), - &InputInstruction::MoveDown(s)=>Some(PhysicsInputInstruction::SetMoveDown(s)), - &InputInstruction::Jump(s)=>Some(PhysicsInputInstruction::SetJump(s)), - &InputInstruction::Zoom(s)=>Some(PhysicsInputInstruction::SetZoom(s)), - &InputInstruction::Spawn(mode_id,stage_id)=>Some(PhysicsInputInstruction::Spawn(mode_id,stage_id)), - InputInstruction::Restart=>Some(PhysicsInputInstruction::Restart), - InputInstruction::PracticeFly=>Some(PhysicsInputInstruction::PracticeFly), }, + //do these really need to idle the physics? + //sending None dumps the instruction queue Instruction::GenerateModels(_)=>Some(PhysicsInputInstruction::Idle), Instruction::ClearModels=>Some(PhysicsInputInstruction::Idle), Instruction::Resize(_,_)=>Some(PhysicsInputInstruction::Idle), Instruction::Render=>Some(PhysicsInputInstruction::Idle), + &Instruction::SetPaused(paused)=>{ + if let Err(e)=self.timer.set_paused(ins.time,paused){ + println!("Cannot pause: {e}"); + } + Some(PhysicsInputInstruction::Idle) + }, } } fn update_mouse_blocking(&mut self,physics:&crate::physics::PhysicsContext,ins:&TimedInstruction)->bool{ @@ -85,11 +100,11 @@ impl MouseInterpolator{ //shitty mice are 125Hz which is 8ms so this should cover that. //setting this to 100us still doesn't print even though it's 10x lower than the polling rate, //so mouse events are probably not handled separately from drawing and fire right before it :( - if Time::from_millis(10)not moving when the mouse starts moving again self.last_mouse_time=ins.time; true } @@ -122,8 +137,11 @@ impl MouseInterpolator{ } } fn empty_queue(&mut self,physics:&mut crate::physics::PhysicsContext){ - while let Some(instruction)=self.timeline.pop_front(){ - physics.run_input_instruction(instruction); + while let Some(TimedInstruction{time,instruction})=self.timeline.pop_front(){ + physics.run_input_instruction(TimedInstruction{ + time:self.timer.time(time), + instruction, + }); } } fn handle_instruction(&mut self,physics:&mut crate::physics::PhysicsContext,ins:&TimedInstruction){ @@ -140,12 +158,13 @@ pub fn new(mut physics:crate::physics::PhysicsContext,mut graphics_worker:crate: mouse_blocking:true, last_mouse_time:physics.get_next_mouse().time, timeline:std::collections::VecDeque::new(), + timer:Timer::from_state(Scaled::identity(),false), }; crate::compat_worker::QNWorker::new(move |ins:TimedInstruction|{ interpolator.handle_instruction(&mut physics,&ins); match ins.instruction{ Instruction::Render=>{ - graphics_worker.send(crate::graphics_worker::Instruction::Render(physics.output(),ins.time,physics.get_next_mouse().pos)).unwrap(); + graphics_worker.send(crate::graphics_worker::Instruction::Render(physics.output(),interpolator.timer.time(ins.time),physics.get_next_mouse().pos)).unwrap(); }, Instruction::Resize(size,user_settings)=>{ graphics_worker.send(crate::graphics_worker::Instruction::Resize(size,user_settings)).unwrap(); diff --git a/src/window.rs b/src/window.rs index 54ff59a..a75fa3f 100644 --- a/src/window.rs +++ b/src/window.rs @@ -35,8 +35,12 @@ impl WindowContext<'_>{ Err(e)=>println!("Failed to load map: {e}"), } }, - winit::event::WindowEvent::Focused(_state)=>{ + winit::event::WindowEvent::Focused(state)=>{ //pause unpause + self.physics_thread.send(TimedInstruction{ + time, + instruction:crate::physics_worker::Instruction::SetPaused(!state), + }).unwrap(); //recalculate pressed keys on focus }, winit::event::WindowEvent::KeyboardInput{