From 0a3d965bb626c8d20fd0149bb22095fec6e5ab45 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 9 Jan 2025 19:39:59 -0800 Subject: [PATCH] work --- strafe-client/src/mouse_interpolator.rs | 179 ++---------------------- 1 file changed, 11 insertions(+), 168 deletions(-) diff --git a/strafe-client/src/mouse_interpolator.rs b/strafe-client/src/mouse_interpolator.rs index f62e86c..d686309 100644 --- a/strafe-client/src/mouse_interpolator.rs +++ b/strafe-client/src/mouse_interpolator.rs @@ -3,6 +3,9 @@ use strafesnet_common::physics::{Instruction as PhysicsInputInstruction,Time as use strafesnet_common::session::{Time as SessionTime,TimeInner as SessionTimeInner}; use strafesnet_common::instruction::{self,TimedInstruction}; +type TimedPhysicsInstruction=TimedInstruction; +type TimedInterpolatorInstruction=TimedInstruction; + #[derive(Debug)] pub enum InputInstruction{ MoveMouse(glam::IVec2), @@ -17,195 +20,35 @@ pub enum InputInstruction{ ResetAndRestart, ResetAndSpawn(strafesnet_common::gameplay_modes::ModeId,strafesnet_common::gameplay_modes::StageId), PracticeFly, + Idle, } pub enum Instruction{ Input(InputInstruction), - Render, - Resize(winit::dpi::PhysicalSize), - ChangeMap(strafesnet_common::map::CompleteMap), //SetPaused is not an InputInstruction: the physics doesn't know that it's paused. SetPaused(bool), //Graphics(crate::graphics_worker::Instruction), } pub struct MouseInterpolator{ - timeline:std::collections::VecDeque>, - last_mouse_time:PhysicsTime, - mouse_blocking:bool, + timeline:std::collections::VecDeque<>, } impl instruction::InstructionConsumer for MouseInterpolator{ type Instruction=Instruction; type TimeInner=SessionTimeInner; - fn process_instruction(&mut self,ins:TimedInstruction){ - self.atomic_state_update(ins) - } -} -// InstructionEmitter does not make sense for MouseInterpolator, because it can emit multiple instructions. -impl instruction::InstructionEmitter for MouseInterpolator{ - type Instruction=PhysicsInputInstruction; - type TimeInner=PhysicsTimeInner; - fn next_instruction(&self,time_limit:PhysicsTime)->Option>{ - self.next_instruction_internal(time_limit) + fn process_instruction(&mut self,ins:TimedInterpolatorInstruction){ + self.process_instruction(ins) } } impl MouseInterpolator{ pub fn new()->MouseInterpolator{ MouseInterpolator{ - mouse_blocking:true, - last_mouse_time:physics.get_next_mouse().time, timeline:std::collections::VecDeque::new(), } } - fn push_mouse_instruction(&mut self,ins:&TimedInstruction,m:glam::IVec2){ - if self.mouse_blocking{ - //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:self.timer.time(ins.time),pos:m}), - }); - }else{ - //mouse has just started moving again after being still for longer than 10ms. - //replace the entire mouse interpolation state to avoid an intermediate state with identical m0.t m1.t timestamps which will divide by zero - self.timeline.push_front(TimedInstruction{ - time:self.last_mouse_time, - instruction:PhysicsInputInstruction::ReplaceMouse( - MouseState{time:self.last_mouse_time,pos:self.physics.get_next_mouse().pos}, - MouseState{time:self.timer.time(ins.time),pos:m} - ), - }); - //delay physics execution until we have an interpolation target - self.mouse_blocking=true; - } - self.last_mouse_time=self.timer.time(ins.time); + pub fn process_instruction(&mut self,ins:TimedInterpolatorInstruction){ + // new input } - fn push(&mut self,time:SessionTime,phys_input:PhysicsInputInstruction){ - //This is always a non-mouse event - self.timeline.push_back(TimedInstruction{ - time:self.timer.time(time), - instruction:phys_input, - }); - } - /// returns should_empty_queue - /// may or may not mutate internal state XD! - fn map_instruction(&mut self,ins:&TimedInstruction)->bool{ - let mut update_mouse_blocking=true; - match &ins.instruction{ - Instruction::Input(input_instruction)=>match input_instruction{ - &InputInstruction::MoveMouse(m)=>{ - if !self.timer.is_paused(){ - self.push_mouse_instruction(ins,m); - } - update_mouse_blocking=false; - }, - &InputInstruction::MoveForward(s)=>self.push(ins.time,PhysicsInputInstruction::SetMoveForward(s)), - &InputInstruction::MoveLeft(s)=>self.push(ins.time,PhysicsInputInstruction::SetMoveLeft(s)), - &InputInstruction::MoveBack(s)=>self.push(ins.time,PhysicsInputInstruction::SetMoveBack(s)), - &InputInstruction::MoveRight(s)=>self.push(ins.time,PhysicsInputInstruction::SetMoveRight(s)), - &InputInstruction::MoveUp(s)=>self.push(ins.time,PhysicsInputInstruction::SetMoveUp(s)), - &InputInstruction::MoveDown(s)=>self.push(ins.time,PhysicsInputInstruction::SetMoveDown(s)), - &InputInstruction::Jump(s)=>self.push(ins.time,PhysicsInputInstruction::SetJump(s)), - &InputInstruction::Zoom(s)=>self.push(ins.time,PhysicsInputInstruction::SetZoom(s)), - &InputInstruction::ResetAndSpawn(mode_id,stage_id)=>{ - self.push(ins.time,PhysicsInputInstruction::Reset); - self.push(ins.time,PhysicsInputInstruction::SetSensitivity(self.user_settings.calculate_sensitivity())); - self.push(ins.time,PhysicsInputInstruction::Spawn(mode_id,stage_id)); - }, - InputInstruction::ResetAndRestart=>{ - self.push(ins.time,PhysicsInputInstruction::Reset); - self.push(ins.time,PhysicsInputInstruction::SetSensitivity(self.user_settings.calculate_sensitivity())); - self.push(ins.time,PhysicsInputInstruction::Restart); - }, - InputInstruction::PracticeFly=>self.push(ins.time,PhysicsInputInstruction::PracticeFly), - }, - //do these really need to idle the physics? - //sending None dumps the instruction queue - Instruction::ChangeMap(_)=>self.push(ins.time,PhysicsInputInstruction::Idle), - Instruction::Resize(_)=>self.push(ins.time,PhysicsInputInstruction::Idle), - Instruction::Render=>self.push(ins.time,PhysicsInputInstruction::Idle), - &Instruction::SetPaused(paused)=>{ - if let Err(e)=self.timer.set_paused(ins.time,paused){ - println!("Cannot SetPaused: {e}"); - } - self.push(ins.time,PhysicsInputInstruction::Idle); - }, - } - if update_mouse_blocking{ - //this returns the bool for us - self.update_mouse_blocking(ins.time) - }else{ - //do flush that queue - true - } - } - /// must check if self.mouse_blocking==true before calling! - fn unblock_mouse(&mut self,time:SessionTime){ - //push an event to extrapolate no movement from - self.timeline.push_front(TimedInstruction{ - time:self.last_mouse_time, - instruction:PhysicsInputInstruction::SetNextMouse(MouseState{time:self.timer.time(time),pos:self.physics.get_next_mouse().pos}), - }); - self.last_mouse_time=self.timer.time(time); - //stop blocking. the mouse is not moving so the physics does not need to live in the past and wait for interpolation targets. - self.mouse_blocking=false; - } - fn update_mouse_blocking(&mut self,time:SessionTime)->bool{ - if self.mouse_blocking{ - //assume the mouse has stopped moving after 10ms. - //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 :( - // No, it's because the event loop thread is busy running physics. - if PhysicsTime::from_millis(10)){ - let should_empty_queue=self.map_instruction(ins); - if should_empty_queue{ - self.empty_queue(); - } - } - pub fn get_frame_state(&self,time:SessionTime)->crate::session::FrameState{ - crate::session::FrameState{ - body:self.physics.camera_body(), - camera:self.physics.camera(), - time:self.timer.time(time), - } - } - pub fn change_map(&mut self,time:SessionTime,map:&strafesnet_common::map::CompleteMap){ - //dump any pending interpolation state - if self.mouse_blocking{ - self.unblock_mouse(time); - } - self.empty_queue(); - - //doing it like this to avoid doing PhysicsInstruction::ChangeMap(Rc) - self.physics.generate_models(&map); - - //use the standard input interface so the instructions are written out to bots - self.handle_instruction(&TimedInstruction{ - time, - instruction:Instruction::Input(InputInstruction::ResetAndSpawn( - strafesnet_common::gameplay_modes::ModeId::MAIN, - strafesnet_common::gameplay_modes::StageId::FIRST, - )), - }); - } - pub const fn user_settings(&self)->&crate::settings::UserSettings{ - &self.user_settings + pub fn pop_next_instruction(&mut self)->Option{ + // read state and potentially do work to determine the next instruction } }