delete ReplaceMouse instruction

This commit is contained in:
Quaternions 2025-01-10 20:59:25 -08:00
parent fe43ce9df6
commit ceb2499ad2
4 changed files with 69 additions and 35 deletions

View File

@ -4,7 +4,6 @@ pub type Time=crate::integer::Time<TimeInner>;
#[derive(Clone,Debug)] #[derive(Clone,Debug)]
pub enum Instruction{ pub enum Instruction{
ReplaceMouse(crate::mouse::MouseState<TimeInner>,crate::mouse::MouseState<TimeInner>),
SetNextMouse(crate::mouse::MouseState<TimeInner>), SetNextMouse(crate::mouse::MouseState<TimeInner>),
SetMoveRight(bool), SetMoveRight(bool),
SetMoveUp(bool), SetMoveUp(bool),

View File

@ -3,10 +3,11 @@ use strafesnet_common::physics::{Instruction as PhysicsInputInstruction,Time as
use strafesnet_common::session::{Time as SessionTime,TimeInner as SessionTimeInner}; use strafesnet_common::session::{Time as SessionTime,TimeInner as SessionTimeInner};
use strafesnet_common::instruction::{InstructionConsumer,InstructionEmitter,TimedInstruction}; use strafesnet_common::instruction::{InstructionConsumer,InstructionEmitter,TimedInstruction};
use crate::session::StepInstruction as SessionInternalInstruction;
type TimedPhysicsInstruction=TimedInstruction<PhysicsInputInstruction,PhysicsTimeInner>; type TimedPhysicsInstruction=TimedInstruction<PhysicsInputInstruction,PhysicsTimeInner>;
type TimedInterpolatorInstruction=TimedInstruction<UnbufferedInputInstruction,SessionTimeInner>; type PhysicsTimedUnbufferedInstruction=TimedInstruction<UnbufferedInputInstruction,PhysicsTimeInner>;
type DoubleTimedUnbufferedInstruction=TimedInstruction<PhysicsTimedUnbufferedInstruction,SessionTimeInner>;
const MOUSE_TIMEOUT:SessionTime=SessionTime::from_millis(10);
#[derive(Debug)] #[derive(Debug)]
pub enum UnbufferedInputInstruction{ pub enum UnbufferedInputInstruction{
@ -25,41 +26,84 @@ pub enum UnbufferedInputInstruction{
Idle, Idle,
} }
pub enum StepInstruction{
Other,
ReplaceMouse,
}
pub struct MouseInterpolator{ pub struct MouseInterpolator{
last_mouse_state:MouseState<SessionTimeInner>,
// double timestamped timeline?
physics_timeline:std::collections::VecDeque<TimedPhysicsInstruction>, physics_timeline:std::collections::VecDeque<TimedPhysicsInstruction>,
} }
// Maybe MouseInterpolator manipulation is better expressed using impls // Maybe MouseInterpolator manipulation is better expressed using impls
// and called from Instruction trait impls in session // and called from Instruction trait impls in session
impl InstructionConsumer<UnbufferedInputInstruction> for MouseInterpolator{ impl InstructionConsumer<PhysicsTimedUnbufferedInstruction> for MouseInterpolator{
type TimeInner=SessionTimeInner; type TimeInner=SessionTimeInner;
fn process_instruction(&mut self,ins:TimedInterpolatorInstruction){ fn process_instruction(&mut self,ins:DoubleTimedUnbufferedInstruction){
self.push_unbuffered_input(ins) self.push_unbuffered_input(ins)
} }
} }
impl InstructionEmitter<SessionInternalInstruction> for MouseInterpolator{ impl InstructionEmitter<StepInstruction> for MouseInterpolator{
type TimeInner=SessionTimeInner; type TimeInner=SessionTimeInner;
fn next_instruction(&self,time_limit:SessionTime)->Option<TimedInstruction<SessionInternalInstruction,Self::TimeInner>>{ fn next_instruction(&self,time_limit:SessionTime)->Option<TimedInstruction<StepInstruction,Self::TimeInner>>{
self.buffered_instruction_with_timeout(time_limit) self.buffered_instruction_with_timeout(time_limit)
} }
} }
impl MouseInterpolator{ impl MouseInterpolator{
pub fn new()->MouseInterpolator{ pub fn new()->MouseInterpolator{
MouseInterpolator{ MouseInterpolator{
last_mouse_state:MouseState::default(),
physics_timeline:std::collections::VecDeque::new(), physics_timeline:std::collections::VecDeque::new(),
} }
} }
pub fn push_unbuffered_input(&mut self,ins:TimedInterpolatorInstruction){ pub fn push_unbuffered_input(&mut self,ins:DoubleTimedUnbufferedInstruction){
// new input // new input
// if there is zero instruction buffered, it means the mouse is not moving
} }
pub fn buffered_instruction_with_timeout(&self,time_limit:SessionTime)->Option<TimedInstruction<SessionInternalInstruction,SessionTimeInner>>{ fn is_first_ready(&self)->bool{
// if the mouse has stopped moving for over 10ms, emit DoStepReplaceMouse // if the last instruction is a mouse instruction
// if there is a mouse interpolation target, emit DoStep // and there is 2 or more instructions
// else emit None 1<self.physics_timeline.len()&&matches!(self.physics_timeline.back(),Some(TimedInstruction{
None instruction:PhysicsInputInstruction::SetNextMouse(_),
..
}))
}
pub fn buffered_instruction_with_timeout(&self,time_limit:SessionTime)->Option<TimedInstruction<StepInstruction,SessionTimeInner>>{
let timeout=self.last_mouse_state.time+MOUSE_TIMEOUT;
if timeout<time_limit{
// if the mouse has stopped moving for over 10ms, emit DoStepReplaceMouse at that exact timestamp
Some(TimedInstruction{
time:timeout,
instruction:StepInstruction::ReplaceMouse,
})
}else if self.is_first_ready(){
// emit Step
Some(TimedInstruction{
// this timestamp should not matter
// verify this and potentially emit a different type using the enum only
time:time_limit,
instruction:StepInstruction::Other,
})
}else{
None
}
}
pub fn pop_buffered_instruction(&mut self,ins:StepInstruction)->Option<TimedInstruction<PhysicsInputInstruction,PhysicsTimeInner>>{
match ins{
StepInstruction::Other=>{
// if the last instruction is a mouse instruction,
// then the buffer is in the process of flushing.
// pop and return the first event.
// if the first instruction is a mouse instruction,
// then events are being buffered to wait for another
// mouse instruction as an interpolation target
},
StepInstruction::ReplaceMouse=>{
// use the first instruction which should be a mouse instruction
// to push a ReplaceMouse instruction
},
} }
pub fn pop_buffered_instruction(&mut self)->Option<TimedInstruction<PhysicsInputInstruction,PhysicsTimeInner>>{
// so the idea is that Session gets in the middle of MouseInterpolator instruction processing
// and injects its own side effects, notably running physics
None None
} }
} }

View File

@ -1759,7 +1759,6 @@ fn atomic_input_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedI
|PhysicsInputInstruction::Idle=>false, |PhysicsInputInstruction::Idle=>false,
//these controls only update the body if you are on the ground //these controls only update the body if you are on the ground
PhysicsInputInstruction::SetNextMouse(..) PhysicsInputInstruction::SetNextMouse(..)
|PhysicsInputInstruction::ReplaceMouse(..)
|PhysicsInputInstruction::SetMoveForward(..) |PhysicsInputInstruction::SetMoveForward(..)
|PhysicsInputInstruction::SetMoveLeft(..) |PhysicsInputInstruction::SetMoveLeft(..)
|PhysicsInputInstruction::SetMoveBack(..) |PhysicsInputInstruction::SetMoveBack(..)
@ -1789,10 +1788,6 @@ fn atomic_input_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedI
state.camera.move_mouse(state.input_state.mouse_delta()); state.camera.move_mouse(state.input_state.mouse_delta());
state.input_state.set_next_mouse(m); state.input_state.set_next_mouse(m);
}, },
PhysicsInputInstruction::ReplaceMouse(m0,m1)=>{
state.camera.move_mouse(m0.pos-state.input_state.mouse.pos);
state.input_state.replace_mouse(m0,m1);
},
PhysicsInputInstruction::SetMoveForward(s)=>state.input_state.set_control(Controls::MoveForward,s), PhysicsInputInstruction::SetMoveForward(s)=>state.input_state.set_control(Controls::MoveForward,s),
PhysicsInputInstruction::SetMoveLeft(s)=>state.input_state.set_control(Controls::MoveLeft,s), PhysicsInputInstruction::SetMoveLeft(s)=>state.input_state.set_control(Controls::MoveLeft,s),
PhysicsInputInstruction::SetMoveBack(s)=>state.input_state.set_control(Controls::MoveBackward,s), PhysicsInputInstruction::SetMoveBack(s)=>state.input_state.set_control(Controls::MoveBackward,s),

View File

@ -5,7 +5,7 @@ use strafesnet_common::physics::{Instruction as PhysicsInputInstruction,TimeInne
use strafesnet_common::timer::{Scaled,Timer}; use strafesnet_common::timer::{Scaled,Timer};
use strafesnet_common::session::{TimeInner as SessionTimeInner,Time as SessionTime}; use strafesnet_common::session::{TimeInner as SessionTimeInner,Time as SessionTime};
use crate::mouse_interpolator::{MouseInterpolator,UnbufferedInputInstruction}; use crate::mouse_interpolator::{MouseInterpolator,UnbufferedInputInstruction,StepInstruction};
pub enum ExternalInstruction{ pub enum ExternalInstruction{
ToBuffer(UnbufferedInputInstruction), ToBuffer(UnbufferedInputInstruction),
@ -16,10 +16,6 @@ pub enum ExternalInstruction{
//Graphics(crate::graphics_worker::Instruction), //Graphics(crate::graphics_worker::Instruction),
} }
pub enum StepInstruction{
DoStep,
}
pub struct FrameState{ pub struct FrameState{
pub body:crate::physics::Body, pub body:crate::physics::Body,
pub camera:crate::physics::PhysicsCamera, pub camera:crate::physics::PhysicsCamera,
@ -92,10 +88,13 @@ impl InstructionConsumer<ExternalInstruction> for Session{
type TimeInner=SessionTimeInner; type TimeInner=SessionTimeInner;
fn process_instruction(&mut self,ins:TimedInstruction<ExternalInstruction,Self::TimeInner>){ fn process_instruction(&mut self,ins:TimedInstruction<ExternalInstruction,Self::TimeInner>){
match ins.instruction{ match ins.instruction{
// send it down to MouseInterpolator // send it down to MouseInterpolator with two timestamps, SessionTime and PhysicsTime
ExternalInstruction::ToBuffer(instruction)=>self.mouse_interpolator.process_instruction(TimedInstruction{ ExternalInstruction::ToBuffer(instruction)=>self.mouse_interpolator.process_instruction(TimedInstruction{
time:ins.time, time:ins.time,
instruction:TimedInstruction{
time:self.simulation.timer.time(ins.time),
instruction, instruction,
},
}), }),
ExternalInstruction::SetPaused(paused)=>{ ExternalInstruction::SetPaused(paused)=>{
// don't flush the buffered instructions in the mouse interpolator // don't flush the buffered instructions in the mouse interpolator
@ -114,15 +113,12 @@ impl InstructionConsumer<ExternalInstruction> for Session{
impl InstructionConsumer<StepInstruction> for Session{ impl InstructionConsumer<StepInstruction> for Session{
type TimeInner=SessionTimeInner; type TimeInner=SessionTimeInner;
fn process_instruction(&mut self,ins:TimedInstruction<StepInstruction,Self::TimeInner>){ fn process_instruction(&mut self,ins:TimedInstruction<StepInstruction,Self::TimeInner>){
match ins.instruction{ // ins.time ignored???
StepInstruction::DoStep=>{ if let Some(instruction)=self.mouse_interpolator.pop_buffered_instruction(ins.instruction){
if let Some(instruction)=self.mouse_interpolator.pop_buffered_instruction(){
self.simulation.physics.run_input_instruction(instruction); self.simulation.physics.run_input_instruction(instruction);
} }
} }
} }
}
}
impl InstructionEmitter<StepInstruction> for Session{ impl InstructionEmitter<StepInstruction> for Session{
type TimeInner=SessionTimeInner; type TimeInner=SessionTimeInner;
fn next_instruction(&self,time_limit:SessionTime)->Option<TimedInstruction<StepInstruction,Self::TimeInner>>{ fn next_instruction(&self,time_limit:SessionTime)->Option<TimedInstruction<StepInstruction,Self::TimeInner>>{