diff --git a/strafe-client/src/mouse_interpolator.rs b/strafe-client/src/mouse_interpolator.rs index d5fd15b..0c61089 100644 --- a/strafe-client/src/mouse_interpolator.rs +++ b/strafe-client/src/mouse_interpolator.rs @@ -36,7 +36,8 @@ enum BufferState{ pub struct MouseInterpolator{ buffer_state:BufferState, // double timestamped timeline? - physics_timeline:std::collections::VecDeque, + buffer:std::collections::VecDeque, + output:std::collections::VecDeque, } // Maybe MouseInterpolator manipulation is better expressed using impls // and called from Instruction trait impls in session @@ -56,7 +57,22 @@ impl MouseInterpolator{ pub fn new()->MouseInterpolator{ MouseInterpolator{ buffer_state:BufferState::Unbuffered, - physics_timeline:std::collections::VecDeque::new(), + buffer:std::collections::VecDeque::new(), + output:std::collections::VecDeque::new(), + } + } + fn push_mouse(&mut self,ins:TimedInstruction){ + self.buffer.push_front(TimedInstruction{ + time:ins.time, + instruction:PhysicsInputInstruction::Mouse(ins.instruction), + }); + // flush buffer to output + if self.output.len()==0{ + // swap buffers + core::mem::swap(&mut self.buffer,&mut self.output); + }else{ + // append buffer contents to output + self.output.append(&mut self.buffer); } } pub fn push_unbuffered_input(&mut self,ins:DoubleTimedUnbufferedInstruction){ @@ -140,27 +156,26 @@ impl MouseInterpolator{ ((None,ins_other),next_state) }); if let Some(ins)=ins_mouse{ - self.physics_timeline.push_front(TimedInstruction{ - time:ins.time, - instruction:PhysicsInputInstruction::Mouse(ins.instruction), - }); + self.push_mouse(ins); } if let Some(ins)=ins_other{ - self.physics_timeline.push_back(TimedInstruction{ + let instruction=TimedInstruction{ time:ins.time, instruction:PhysicsInputInstruction::Other(ins.instruction), - }); + }; + if matches!(self.buffer_state,BufferState::Unbuffered){ + self.output.push_back(instruction); + }else{ + self.buffer.push_back(instruction); + } } } - fn is_first_ready(&self)->bool{ - matches!(self.physics_timeline.back(),Some(TimedInstruction{ - instruction:PhysicsInputInstruction::Mouse(_), - .. - })) + fn has_output(&self)->bool{ + self.output.len()!=0 } pub fn buffered_instruction_with_timeout(&self,time_limit:SessionTime)->Option>{ match &self.buffer_state{ - BufferState::Unbuffered=>self.physics_timeline.front().map(|_|TimedInstruction{ + BufferState::Unbuffered=>self.has_output().then_some(TimedInstruction{ time:time_limit, instruction:StepInstruction::Pop, }), @@ -173,7 +188,7 @@ impl MouseInterpolator{ time:timeout, instruction:StepInstruction::Timeout, }) - }else if self.is_first_ready(){ + }else if self.has_output(){ // emit Step Some(TimedInstruction{ // this timestamp should not matter @@ -191,31 +206,30 @@ impl MouseInterpolator{ pub fn pop_buffered_instruction(&mut self,ins:StepInstruction)->Option>{ match ins{ // could check if self.is_first_ready() - StepInstruction::Pop=>self.physics_timeline.pop_front(), + StepInstruction::Pop=>(), StepInstruction::Timeout=>{ let buffer_state=core::mem::replace(&mut self.buffer_state,BufferState::Unbuffered); match buffer_state{ - BufferState::Unbuffered=>None, + BufferState::Unbuffered=>(), BufferState::Initializing(_time,mouse_state) |BufferState::Buffered(_time,mouse_state)=>{ // convert to BufferState::Unbuffered // use the first instruction which should be a mouse instruction // to push a ReplaceMouse instruction // duplicate the current mouse - Some(TimedInstruction{ + self.push_mouse(TimedInstruction{ // This should be simulation_timer.time(timeout) // but the timer is not accessible from this scope // and it's just here to say that the mouse isn't moving anyways. // I think this is a divide by zero bug, two identical mouse_states will occupy the interpolation state time:mouse_state.time, - instruction:PhysicsInputInstruction::Mouse( - MouseInstruction::SetNextMouse(mouse_state) - ), - }) + instruction:MouseInstruction::SetNextMouse(mouse_state), + }); }, } }, } + self.output.pop_front() } }