cool changes
This commit is contained in:
parent
1b35c96f6e
commit
92c30c3b87
@ -1,11 +1,25 @@
|
|||||||
|
use crate::mouse::MouseState;
|
||||||
|
|
||||||
#[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)]
|
#[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)]
|
||||||
pub enum TimeInner{}
|
pub enum TimeInner{}
|
||||||
pub type Time=crate::integer::Time<TimeInner>;
|
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>),
|
Mouse(MouseInstruction),
|
||||||
SetNextMouse(crate::mouse::MouseState<TimeInner>),
|
Other(OtherInstruction),
|
||||||
|
}
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub enum MouseInstruction{
|
||||||
|
/// Replace the entire interpolation state to avoid dividing by zero when replacing twice
|
||||||
|
ReplaceMouse{
|
||||||
|
s0:MouseState<TimeInner>,
|
||||||
|
s1:MouseState<TimeInner>,
|
||||||
|
},
|
||||||
|
SetNextMouse(MouseState<TimeInner>),
|
||||||
|
}
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub enum OtherInstruction{
|
||||||
SetMoveRight(bool),
|
SetMoveRight(bool),
|
||||||
SetMoveUp(bool),
|
SetMoveUp(bool),
|
||||||
SetMoveBack(bool),
|
SetMoveBack(bool),
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
#[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)]
|
#[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)]
|
||||||
pub enum TimeInner{}
|
pub enum TimeInner{}
|
||||||
pub type Time=crate::integer::Time<TimeInner>;
|
pub type Time=crate::integer::Time<TimeInner>;
|
||||||
|
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub enum UnbufferedInputInstruction{
|
||||||
|
MoveMouse(glam::IVec2),
|
||||||
|
Other(crate::physics::OtherInstruction),
|
||||||
|
}
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
use strafesnet_common::mouse::MouseState;
|
use strafesnet_common::mouse::MouseState;
|
||||||
use strafesnet_common::physics::{Instruction as PhysicsInputInstruction,Time as PhysicsTime,TimeInner as PhysicsTimeInner};
|
use strafesnet_common::physics::{
|
||||||
use strafesnet_common::session::{Time as SessionTime,TimeInner as SessionTimeInner};
|
Instruction as PhysicsInputInstruction,
|
||||||
|
Time as PhysicsTime,
|
||||||
|
TimeInner as PhysicsTimeInner,
|
||||||
|
MouseInstruction,
|
||||||
|
OtherInstruction,
|
||||||
|
};
|
||||||
|
use strafesnet_common::session::{Time as SessionTime,TimeInner as SessionTimeInner,UnbufferedInputInstruction};
|
||||||
use strafesnet_common::instruction::{InstructionConsumer,InstructionEmitter,TimedInstruction};
|
use strafesnet_common::instruction::{InstructionConsumer,InstructionEmitter,TimedInstruction};
|
||||||
|
|
||||||
type TimedPhysicsInstruction=TimedInstruction<PhysicsInputInstruction,PhysicsTimeInner>;
|
type TimedPhysicsInstruction=TimedInstruction<PhysicsInputInstruction,PhysicsTimeInner>;
|
||||||
@ -9,23 +15,6 @@ type DoubleTimedUnbufferedInstruction=TimedInstruction<PhysicsTimedUnbufferedIns
|
|||||||
|
|
||||||
const MOUSE_TIMEOUT:SessionTime=SessionTime::from_millis(10);
|
const MOUSE_TIMEOUT:SessionTime=SessionTime::from_millis(10);
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum UnbufferedInputInstruction{
|
|
||||||
MoveMouse(glam::IVec2),
|
|
||||||
MoveRight(bool),
|
|
||||||
MoveUp(bool),
|
|
||||||
MoveBack(bool),
|
|
||||||
MoveLeft(bool),
|
|
||||||
MoveDown(bool),
|
|
||||||
MoveForward(bool),
|
|
||||||
Jump(bool),
|
|
||||||
Zoom(bool),
|
|
||||||
ResetAndRestart,
|
|
||||||
ResetAndSpawn(strafesnet_common::gameplay_modes::ModeId,strafesnet_common::gameplay_modes::StageId),
|
|
||||||
PracticeFly,
|
|
||||||
Idle,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum StepInstruction{
|
pub enum StepInstruction{
|
||||||
Other,
|
Other,
|
||||||
ReplaceMouse,
|
ReplaceMouse,
|
||||||
@ -38,11 +27,11 @@ enum BufferState{
|
|||||||
Buffered(SessionTime,MouseState<PhysicsTimeInner>),
|
Buffered(SessionTime,MouseState<PhysicsTimeInner>),
|
||||||
}
|
}
|
||||||
impl BufferState{
|
impl BufferState{
|
||||||
fn next_state(&self,ins:DoubleTimedUnbufferedInstruction,physics_timeline:&mut std::collections::VecDeque<TimedPhysicsInstruction>)->Self{
|
fn next_state(&self,ins:DoubleTimedUnbufferedInstruction,physics_timeline:&mut std::collections::VecDeque<TimedPhysicsInstruction>)->(Self,Option<TimedInstruction<OtherInstruction,PhysicsTimeInner>>){
|
||||||
match self{
|
match self{
|
||||||
BufferState::Unbuffered=>{
|
BufferState::Unbuffered=>{
|
||||||
if let UnbufferedInputInstruction::MoveMouse(pos)=ins.instruction.instruction{
|
if let UnbufferedInputInstruction::MoveMouse(pos)=ins.instruction.instruction{
|
||||||
return BufferState::Initializing(ins.time,MouseState{pos,time:ins.instruction.time});
|
return (BufferState::Initializing(ins.time,MouseState{pos,time:ins.instruction.time}),None);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BufferState::Initializing(time,mouse_state)=>{
|
BufferState::Initializing(time,mouse_state)=>{
|
||||||
@ -54,17 +43,24 @@ impl BufferState{
|
|||||||
// but the timer is not accessible from this scope
|
// but the timer is not accessible from this scope
|
||||||
// and it's just here to say that the mouse isn't moving anyways.
|
// and it's just here to say that the mouse isn't moving anyways.
|
||||||
time:ins.instruction.time,
|
time:ins.instruction.time,
|
||||||
instruction:PhysicsInputInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:ins.instruction.time}),
|
instruction:PhysicsInputInstruction::Mouse(
|
||||||
|
MouseInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:ins.instruction.time})
|
||||||
|
),
|
||||||
});
|
});
|
||||||
return BufferState::Unbuffered;
|
return (BufferState::Unbuffered,None);
|
||||||
}
|
}
|
||||||
if let UnbufferedInputInstruction::MoveMouse(pos)=ins.instruction.instruction{
|
if let UnbufferedInputInstruction::MoveMouse(pos)=ins.instruction.instruction{
|
||||||
let next_mouse_state=MouseState{pos,time:ins.instruction.time};
|
let next_mouse_state=MouseState{pos,time:ins.instruction.time};
|
||||||
physics_timeline.push_front(TimedInstruction{
|
physics_timeline.push_front(TimedInstruction{
|
||||||
time:mouse_state.time,
|
time:mouse_state.time,
|
||||||
instruction:PhysicsInputInstruction::ReplaceMouse(mouse_state.clone(),next_mouse_state.clone()),
|
instruction:PhysicsInputInstruction::Mouse(
|
||||||
|
MouseInstruction::ReplaceMouse{
|
||||||
|
s0:mouse_state.clone(),
|
||||||
|
s1:next_mouse_state.clone(),
|
||||||
|
}
|
||||||
|
),
|
||||||
});
|
});
|
||||||
return BufferState::Buffered(ins.time,next_mouse_state);
|
return (BufferState::Buffered(ins.time,next_mouse_state),None);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BufferState::Buffered(time,mouse_state)=>{
|
BufferState::Buffered(time,mouse_state)=>{
|
||||||
@ -76,21 +72,32 @@ impl BufferState{
|
|||||||
// but the timer is not accessible from this scope
|
// but the timer is not accessible from this scope
|
||||||
// and it's just here to say that the mouse isn't moving anyways.
|
// and it's just here to say that the mouse isn't moving anyways.
|
||||||
time:ins.instruction.time,
|
time:ins.instruction.time,
|
||||||
instruction:PhysicsInputInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:ins.instruction.time}),
|
instruction:PhysicsInputInstruction::Mouse(
|
||||||
|
MouseInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:ins.instruction.time})
|
||||||
|
),
|
||||||
});
|
});
|
||||||
return BufferState::Unbuffered;
|
return (BufferState::Unbuffered,None);
|
||||||
}
|
}
|
||||||
if let UnbufferedInputInstruction::MoveMouse(pos)=ins.instruction.instruction{
|
if let UnbufferedInputInstruction::MoveMouse(pos)=ins.instruction.instruction{
|
||||||
let next_mouse_state=MouseState{pos,time:ins.instruction.time};
|
let next_mouse_state=MouseState{pos,time:ins.instruction.time};
|
||||||
physics_timeline.push_front(TimedInstruction{
|
physics_timeline.push_front(TimedInstruction{
|
||||||
time:ins.instruction.time,
|
time:ins.instruction.time,
|
||||||
instruction:PhysicsInputInstruction::SetNextMouse(next_mouse_state.clone()),
|
instruction:PhysicsInputInstruction::Mouse(
|
||||||
|
MouseInstruction::SetNextMouse(next_mouse_state.clone())
|
||||||
|
),
|
||||||
});
|
});
|
||||||
return BufferState::Buffered(ins.time,next_mouse_state);
|
return (BufferState::Buffered(ins.time,next_mouse_state),None);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
self.clone()
|
let instruction_out=match ins.instruction.instruction{
|
||||||
|
UnbufferedInputInstruction::MoveMouse(_)=>None,
|
||||||
|
UnbufferedInputInstruction::Other(other_instruction)=>Some(TimedInstruction{
|
||||||
|
time:ins.instruction.time,
|
||||||
|
instruction:other_instruction,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
(self.clone(),instruction_out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub struct MouseInterpolator{
|
pub struct MouseInterpolator{
|
||||||
@ -131,39 +138,55 @@ impl MouseInterpolator{
|
|||||||
// case 3: stop
|
// case 3: stop
|
||||||
// a mouse event is buffered, but no mouse events have transpired within 10ms
|
// a mouse event is buffered, but no mouse events have transpired within 10ms
|
||||||
// TODO: remove clone
|
// TODO: remove clone
|
||||||
self.buffer_state=self.buffer_state.next_state(ins,&mut self.physics_timeline);
|
let ins_inner;
|
||||||
|
(self.buffer_state,ins_inner)=self.buffer_state.next_state(ins,&mut self.physics_timeline);
|
||||||
|
if let Some(ins)=ins_inner{
|
||||||
|
self.physics_timeline.push_back(TimedInstruction{
|
||||||
|
time:ins.time,
|
||||||
|
instruction:PhysicsInputInstruction::Other(ins.instruction),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn is_first_ready(&self)->bool{
|
fn is_first_ready(&self)->bool{
|
||||||
// if the last instruction is a ReplaceMouse instruction
|
// if the last instruction is a ReplaceMouse instruction
|
||||||
matches!(self.physics_timeline.back(),Some(TimedInstruction{
|
matches!(self.physics_timeline.back(),Some(TimedInstruction{
|
||||||
instruction:PhysicsInputInstruction::ReplaceMouse(_,_),
|
instruction:PhysicsInputInstruction::Mouse(MouseInstruction::ReplaceMouse{..}),
|
||||||
..
|
..
|
||||||
}))
|
}))
|
||||||
// or if the last instruction is a SetNextMouse instruction
|
// or if the last instruction is a SetNextMouse instruction
|
||||||
// and there is 2 or more instructions
|
// and there is 2 or more instructions
|
||||||
||1<self.physics_timeline.len()&&matches!(self.physics_timeline.back(),Some(TimedInstruction{
|
||1<self.physics_timeline.len()&&matches!(self.physics_timeline.back(),Some(TimedInstruction{
|
||||||
instruction:PhysicsInputInstruction::SetNextMouse(_),
|
instruction:PhysicsInputInstruction::Mouse(MouseInstruction::SetNextMouse(_)),
|
||||||
..
|
..
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
pub fn buffered_instruction_with_timeout(&self,time_limit:SessionTime)->Option<TimedInstruction<StepInstruction,SessionTimeInner>>{
|
pub fn buffered_instruction_with_timeout(&self,time_limit:SessionTime)->Option<TimedInstruction<StepInstruction,SessionTimeInner>>{
|
||||||
let timeout=self.last_mouse_state.time+MOUSE_TIMEOUT;
|
match &self.buffer_state{
|
||||||
if timeout<time_limit{
|
BufferState::Unbuffered=>self.physics_timeline.front().map(|_|TimedInstruction{
|
||||||
// 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,
|
time:time_limit,
|
||||||
instruction:StepInstruction::Other,
|
instruction:StepInstruction::Other,
|
||||||
})
|
}),
|
||||||
}else{
|
BufferState::Initializing(time,_mouse_state)
|
||||||
None
|
|BufferState::Buffered(time,_mouse_state)=>{
|
||||||
|
let timeout=*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>>{
|
pub fn pop_buffered_instruction(&mut self,ins:StepInstruction)->Option<TimedInstruction<PhysicsInputInstruction,PhysicsTimeInner>>{
|
||||||
@ -177,6 +200,7 @@ impl MouseInterpolator{
|
|||||||
// mouse instruction as an interpolation target
|
// mouse instruction as an interpolation target
|
||||||
},
|
},
|
||||||
StepInstruction::ReplaceMouse=>{
|
StepInstruction::ReplaceMouse=>{
|
||||||
|
// convert to BufferState::Unbuffered
|
||||||
// use the first instruction which should be a mouse instruction
|
// use the first instruction which should be a mouse instruction
|
||||||
// to push a ReplaceMouse instruction
|
// to push a ReplaceMouse instruction
|
||||||
},
|
},
|
||||||
|
@ -3,9 +3,9 @@ use strafesnet_common::instruction::{InstructionConsumer, InstructionEmitter, In
|
|||||||
// Ideally it is a deterministic state which is atomically updated by instructions, same as the simulation state.
|
// Ideally it is a deterministic state which is atomically updated by instructions, same as the simulation state.
|
||||||
use strafesnet_common::physics::{Instruction as PhysicsInputInstruction,TimeInner as PhysicsTimeInner,Time as PhysicsTime};
|
use strafesnet_common::physics::{Instruction as PhysicsInputInstruction,TimeInner as PhysicsTimeInner,Time as PhysicsTime};
|
||||||
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,UnbufferedInputInstruction};
|
||||||
|
|
||||||
use crate::mouse_interpolator::{MouseInterpolator,UnbufferedInputInstruction,StepInstruction};
|
use crate::mouse_interpolator::{MouseInterpolator,StepInstruction};
|
||||||
|
|
||||||
pub enum ExternalInstruction{
|
pub enum ExternalInstruction{
|
||||||
ToBuffer(UnbufferedInputInstruction),
|
ToBuffer(UnbufferedInputInstruction),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user