rewrite enums again
This commit is contained in:
parent
08bd57ffe1
commit
a6a242175b
@ -4,17 +4,20 @@ use crate::mouse::MouseState;
|
||||
pub enum TimeInner{}
|
||||
pub type Time=crate::integer::Time<TimeInner>;
|
||||
|
||||
#[derive(Clone,Debug)]
|
||||
pub enum UnbufferedInstruction{
|
||||
MoveMouse(glam::IVec2),
|
||||
Other(OtherInstruction),
|
||||
}
|
||||
|
||||
#[derive(Clone,Debug)]
|
||||
pub enum Instruction{
|
||||
Mouse(MouseInstruction),
|
||||
Other(OtherInstruction),
|
||||
}
|
||||
impl Instruction{
|
||||
pub const IDLE:Self=Self::Other(OtherInstruction::Other(OtherOtherInstruction::Idle));
|
||||
}
|
||||
#[derive(Clone,Debug)]
|
||||
pub enum OtherInstruction{
|
||||
SetControl(SetControlInstruction),
|
||||
Mode(ModeInstruction),
|
||||
Other(OtherOtherInstruction),
|
||||
}
|
||||
#[derive(Clone,Debug)]
|
||||
pub enum MouseInstruction{
|
||||
/// Replace the entire interpolation state to avoid dividing by zero when replacing twice
|
||||
@ -25,7 +28,7 @@ pub enum MouseInstruction{
|
||||
SetNextMouse(MouseState<TimeInner>),
|
||||
}
|
||||
#[derive(Clone,Debug)]
|
||||
pub enum OtherInstruction{
|
||||
pub enum SetControlInstruction{
|
||||
SetMoveRight(bool),
|
||||
SetMoveUp(bool),
|
||||
SetMoveBack(bool),
|
||||
@ -34,6 +37,9 @@ pub enum OtherInstruction{
|
||||
SetMoveForward(bool),
|
||||
SetJump(bool),
|
||||
SetZoom(bool),
|
||||
}
|
||||
#[derive(Clone,Debug)]
|
||||
pub enum ModeInstruction{
|
||||
/// Reset: fully replace the physics state.
|
||||
/// This forgets all inputs and settings which need to be reapplied.
|
||||
Reset,
|
||||
@ -42,10 +48,11 @@ pub enum OtherInstruction{
|
||||
/// Spawn: Teleport to a specific mode's spawn
|
||||
/// Sets current mode & spawn
|
||||
Spawn(crate::gameplay_modes::ModeId,crate::gameplay_modes::StageId),
|
||||
}
|
||||
#[derive(Clone,Debug)]
|
||||
pub enum OtherOtherInstruction{
|
||||
/// Idle: there were no input events, but the simulation is safe to advance to this timestep
|
||||
Idle,
|
||||
//Idle: there were no input events, but the simulation is safe to advance to this timestep
|
||||
//for interpolation / networking / playback reasons, most playback heads will always want
|
||||
//to be 1 instruction ahead to generate the next state for interpolation.
|
||||
PracticeFly,
|
||||
SetSensitivity(crate::integer::Ratio64Vec2),
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
use strafesnet_common::mouse::MouseState;
|
||||
use strafesnet_common::physics::{
|
||||
UnbufferedInstruction as PhysicsUnbufferedInstruction,
|
||||
Instruction as PhysicsInputInstruction,
|
||||
Time as PhysicsTime,
|
||||
TimeInner as PhysicsTimeInner,
|
||||
@ -11,11 +10,18 @@ use strafesnet_common::session::{Time as SessionTime,TimeInner as SessionTimeInn
|
||||
use strafesnet_common::instruction::{InstructionConsumer,InstructionEmitter,TimedInstruction};
|
||||
|
||||
type TimedPhysicsInstruction=TimedInstruction<PhysicsInputInstruction,PhysicsTimeInner>;
|
||||
type PhysicsTimedUnbufferedInstruction=TimedInstruction<PhysicsUnbufferedInstruction,PhysicsTimeInner>;
|
||||
type DoubleTimedUnbufferedInstruction=TimedInstruction<PhysicsTimedUnbufferedInstruction,SessionTimeInner>;
|
||||
type TimedUnbufferedInstruction=TimedInstruction<Instruction,PhysicsTimeInner>;
|
||||
type DoubleTimedUnbufferedInstruction=TimedInstruction<TimedUnbufferedInstruction,SessionTimeInner>;
|
||||
|
||||
const MOUSE_TIMEOUT:SessionTime=SessionTime::from_millis(10);
|
||||
|
||||
/// To be fed into MouseInterpolator
|
||||
#[derive(Clone,Debug)]
|
||||
pub enum Instruction{
|
||||
MoveMouse(glam::IVec2),
|
||||
Other(OtherInstruction),
|
||||
}
|
||||
|
||||
pub enum StepInstruction{
|
||||
Pop,
|
||||
Timeout,
|
||||
@ -35,7 +41,7 @@ pub struct MouseInterpolator{
|
||||
}
|
||||
// Maybe MouseInterpolator manipulation is better expressed using impls
|
||||
// and called from Instruction trait impls in session
|
||||
impl InstructionConsumer<PhysicsTimedUnbufferedInstruction> for MouseInterpolator{
|
||||
impl InstructionConsumer<TimedUnbufferedInstruction> for MouseInterpolator{
|
||||
type TimeInner=SessionTimeInner;
|
||||
fn process_instruction(&mut self,ins:DoubleTimedUnbufferedInstruction){
|
||||
self.push_unbuffered_input(ins)
|
||||
@ -69,7 +75,7 @@ impl MouseInterpolator{
|
||||
let (ins_mouse,ins_other)=replace_with::replace_with_or_abort_and_return(&mut self.buffer_state,|buffer_state|{
|
||||
let next_state=match buffer_state{
|
||||
BufferState::Unbuffered=>{
|
||||
if let PhysicsUnbufferedInstruction::MoveMouse(pos)=ins.instruction.instruction{
|
||||
if let Instruction::MoveMouse(pos)=ins.instruction.instruction{
|
||||
return ((None,None),BufferState::Initializing(ins.time,MouseState{pos,time:ins.instruction.time}));
|
||||
}
|
||||
BufferState::Unbuffered
|
||||
@ -87,7 +93,7 @@ impl MouseInterpolator{
|
||||
};
|
||||
return ((Some(ins_mouse),None),BufferState::Unbuffered);
|
||||
}
|
||||
if let PhysicsUnbufferedInstruction::MoveMouse(pos)=ins.instruction.instruction{
|
||||
if let Instruction::MoveMouse(pos)=ins.instruction.instruction{
|
||||
let next_mouse_state=MouseState{pos,time:ins.instruction.time};
|
||||
let ins_mouse=TimedInstruction{
|
||||
time:mouse_state.time,
|
||||
@ -114,7 +120,7 @@ impl MouseInterpolator{
|
||||
};
|
||||
return ((Some(ins_mouse),None),BufferState::Unbuffered);
|
||||
}
|
||||
if let PhysicsUnbufferedInstruction::MoveMouse(pos)=ins.instruction.instruction{
|
||||
if let Instruction::MoveMouse(pos)=ins.instruction.instruction{
|
||||
let next_mouse_state=MouseState{pos,time:ins.instruction.time};
|
||||
let ins_mouse=TimedInstruction{
|
||||
time:ins.instruction.time,
|
||||
@ -126,8 +132,8 @@ impl MouseInterpolator{
|
||||
},
|
||||
};
|
||||
let ins_other=match ins.instruction.instruction{
|
||||
PhysicsUnbufferedInstruction::MoveMouse(_)=>None,
|
||||
PhysicsUnbufferedInstruction::Other(other_instruction)=>Some(TimedInstruction{
|
||||
Instruction::MoveMouse(_)=>None,
|
||||
Instruction::Other(other_instruction)=>Some(TimedInstruction{
|
||||
time:ins.instruction.time,
|
||||
instruction:other_instruction,
|
||||
}),
|
||||
@ -208,6 +214,7 @@ impl MouseInterpolator{
|
||||
// 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)
|
||||
|
@ -884,9 +884,7 @@ impl PhysicsState{
|
||||
self.touching.clear();
|
||||
}
|
||||
fn reset_to_default(&mut self){
|
||||
let mut new_state=Self::default();
|
||||
new_state.camera.sensitivity=self.camera.sensitivity;
|
||||
*self=new_state;
|
||||
*self=Self::default();
|
||||
}
|
||||
fn next_move_instruction(&self)->Option<TimedInstruction<PhysicsInternalInstruction,TimeInner>>{
|
||||
self.move_state.next_move_instruction(&self.style.strafe,self.time)
|
||||
@ -1837,6 +1835,7 @@ fn atomic_input_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedI
|
||||
state.set_move_state(data,MoveState::Air);
|
||||
b_refresh_walk_target=false;
|
||||
}
|
||||
// Spawn does not necessarily imply reset
|
||||
PhysicsInputInstruction::Other(PhysicsOtherInstruction::Spawn(mode_id,stage_id))=>{
|
||||
//spawn at a particular stage
|
||||
if let Some(mode)=data.modes.get_mode(mode_id){
|
||||
|
@ -1,19 +1,19 @@
|
||||
use crate::graphics_worker::Instruction as GraphicsInstruction;
|
||||
use crate::session::{ExternalInstruction as SessionInstruction,Session, Simulation};
|
||||
use crate::session::{SessionInputInstruction,Instruction as SessionInstruction,Session,Simulation};
|
||||
use strafesnet_common::instruction::{TimedInstruction,InstructionConsumer};
|
||||
use strafesnet_common::physics::Time as PhysicsTime;
|
||||
use strafesnet_common::session::{Time as SessionTime,TimeInner as SessionTimeInner};
|
||||
use strafesnet_common::timer::Timer;
|
||||
|
||||
pub enum Instruction{
|
||||
Input(strafesnet_common::physics::UnbufferedInstruction),
|
||||
Input(SessionInputInstruction),
|
||||
SetPaused(bool),
|
||||
Render,
|
||||
Resize(winit::dpi::PhysicalSize<u32>),
|
||||
ChangeMap(strafesnet_common::map::CompleteMap),
|
||||
}
|
||||
|
||||
const SESSION_INSTRUCTION_IDLE:SessionInstruction=SessionInstruction::Input(strafesnet_common::physics::UnbufferedInstruction::Other(strafesnet_common::physics::OtherInstruction::Idle));
|
||||
const SESSION_INSTRUCTION_IDLE:SessionInstruction=SessionInstruction::Input(SessionInputInstruction::Other(strafesnet_common::physics::OtherOtherInstruction::Idle));
|
||||
|
||||
pub fn new<'a>(
|
||||
mut graphics_worker:crate::compat_worker::INWorker<'a,crate::graphics_worker::Instruction>,
|
||||
|
@ -1,20 +1,39 @@
|
||||
use strafesnet_common::instruction::{InstructionConsumer,InstructionEmitter,InstructionFeedback,TimedInstruction};
|
||||
// session represents the non-hardware state of the client.
|
||||
// Ideally it is a deterministic state which is atomically updated by instructions, same as the simulation state.
|
||||
use strafesnet_common::physics::{UnbufferedInstruction as PhysicsUnbufferedInstruction,Instruction as PhysicsInputInstruction,TimeInner as PhysicsTimeInner,Time as PhysicsTime};
|
||||
use strafesnet_common::physics::{
|
||||
ModeInstruction,OtherInstruction,OtherOtherInstruction,
|
||||
Instruction as PhysicsInputInstruction,
|
||||
TimeInner as PhysicsTimeInner,
|
||||
Time as PhysicsTime
|
||||
};
|
||||
use strafesnet_common::timer::{Scaled,Timer};
|
||||
use strafesnet_common::session::{TimeInner as SessionTimeInner,Time as SessionTime};
|
||||
|
||||
use crate::mouse_interpolator::{MouseInterpolator,StepInstruction};
|
||||
use crate::mouse_interpolator::{MouseInterpolator,StepInstruction,Instruction as MouseInterpolatorInstruction};
|
||||
use crate::settings::UserSettings;
|
||||
|
||||
pub enum ExternalInstruction<'a>{
|
||||
Input(PhysicsUnbufferedInstruction),
|
||||
pub enum Instruction<'a>{
|
||||
Input(SessionInputInstruction),
|
||||
SetPaused(bool),
|
||||
ChangeMap(&'a strafesnet_common::map::CompleteMap),
|
||||
//Graphics(crate::graphics_worker::Instruction),
|
||||
}
|
||||
|
||||
pub enum SessionInputInstruction{
|
||||
Mouse(glam::IVec2),
|
||||
SetControl(strafesnet_common::physics::SetControlInstruction),
|
||||
Mode(ImplicitModeInstruction),
|
||||
Other(strafesnet_common::physics::OtherOtherInstruction),
|
||||
}
|
||||
/// Implicit mode instruction are fed separately to session.
|
||||
/// Session generates the explicit mode instructions interlaced with a SetSensitivity instruction
|
||||
#[derive(Clone,Debug)]
|
||||
pub enum ImplicitModeInstruction{
|
||||
ResetAndRestart,
|
||||
ResetAndSpawn(strafesnet_common::gameplay_modes::ModeId,strafesnet_common::gameplay_modes::StageId),
|
||||
}
|
||||
|
||||
pub struct FrameState{
|
||||
pub body:crate::physics::Body,
|
||||
pub camera:crate::physics::PhysicsCamera,
|
||||
@ -99,25 +118,50 @@ impl Session{
|
||||
// Session consumes DoStep -> forwards DoStep to mouseinterpolator
|
||||
// Session emits DoStep
|
||||
|
||||
impl InstructionConsumer<ExternalInstruction<'_>> for Session{
|
||||
impl InstructionConsumer<Instruction<'_>> for Session{
|
||||
type TimeInner=SessionTimeInner;
|
||||
fn process_instruction(&mut self,ins:TimedInstruction<ExternalInstruction,Self::TimeInner>){
|
||||
fn process_instruction(&mut self,ins:TimedInstruction<Instruction,Self::TimeInner>){
|
||||
match ins.instruction{
|
||||
// send it down to MouseInterpolator with two timestamps, SessionTime and PhysicsTime
|
||||
ExternalInstruction::Input(instruction)=>self.mouse_interpolator.process_instruction(TimedInstruction{
|
||||
time:ins.time,
|
||||
instruction:TimedInstruction{
|
||||
time:self.simulation.timer.time(ins.time),
|
||||
instruction,
|
||||
},
|
||||
}),
|
||||
ExternalInstruction::SetPaused(paused)=>{
|
||||
Instruction::Input(instruction)=>{
|
||||
let instructions:&[MouseInterpolatorInstruction]=match instruction{
|
||||
SessionInputInstruction::Mouse(pos)=>&[
|
||||
MouseInterpolatorInstruction::MoveMouse(pos)
|
||||
],
|
||||
SessionInputInstruction::SetControl(set_control_instruction)=>&[
|
||||
MouseInterpolatorInstruction::Other(OtherInstruction::SetControl(set_control_instruction))
|
||||
],
|
||||
SessionInputInstruction::Mode(ImplicitModeInstruction::ResetAndRestart)=>&[
|
||||
MouseInterpolatorInstruction::Other(OtherInstruction::Mode(ModeInstruction::Reset)),
|
||||
MouseInterpolatorInstruction::Other(OtherInstruction::Other(OtherOtherInstruction::SetSensitivity(self.user_settings().calculate_sensitivity()))),
|
||||
MouseInterpolatorInstruction::Other(OtherInstruction::Mode(ModeInstruction::Restart)),
|
||||
],
|
||||
SessionInputInstruction::Mode(ImplicitModeInstruction::ResetAndSpawn(mode_id,spawn_id))=>&[
|
||||
MouseInterpolatorInstruction::Other(OtherInstruction::Mode(ModeInstruction::Reset)),
|
||||
MouseInterpolatorInstruction::Other(OtherInstruction::Other(OtherOtherInstruction::SetSensitivity(self.user_settings().calculate_sensitivity()))),
|
||||
MouseInterpolatorInstruction::Other(OtherInstruction::Mode(ModeInstruction::Spawn(mode_id,spawn_id))),
|
||||
],
|
||||
SessionInputInstruction::Other(other_other_instruction)=>&[
|
||||
MouseInterpolatorInstruction::Other(OtherInstruction::Other(other_other_instruction))
|
||||
],
|
||||
};
|
||||
for ins_interpolator in (*instructions).into_iter(){
|
||||
self.mouse_interpolator.process_instruction(TimedInstruction{
|
||||
time:ins.time,
|
||||
instruction:TimedInstruction{
|
||||
time:self.simulation.timer.time(ins.time),
|
||||
instruction:ins_interpolator,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
Instruction::SetPaused(paused)=>{
|
||||
// don't flush the buffered instructions in the mouse interpolator
|
||||
// until the mouse is confirmed to be not moving at a later time
|
||||
// what if they pause for 5ms lmao
|
||||
_=self.simulation.timer.set_paused(ins.time,paused);
|
||||
}
|
||||
ExternalInstruction::ChangeMap(complete_map)=>self.change_map(complete_map),
|
||||
Instruction::ChangeMap(complete_map)=>self.change_map(complete_map),
|
||||
};
|
||||
// run all buffered instruction produced
|
||||
self.process_exhaustive(ins.time);
|
||||
|
@ -1,7 +1,8 @@
|
||||
use strafesnet_common::instruction::TimedInstruction;
|
||||
use strafesnet_common::session::{Time as SessionTime,TimeInner as SessionTimeInner};
|
||||
use strafesnet_common::physics::{OtherInstruction,UnbufferedInstruction};
|
||||
use strafesnet_common::physics::{OtherInstruction,OtherOtherInstruction,SetControlInstruction};
|
||||
use crate::physics_worker::Instruction as PhysicsWorkerInstruction;
|
||||
use crate::session::SessionInputInstruction;
|
||||
|
||||
pub enum Instruction{
|
||||
Resize(winit::dpi::PhysicalSize<u32>),
|
||||
@ -91,29 +92,29 @@ impl WindowContext<'_>{
|
||||
},
|
||||
(keycode,state)=>{
|
||||
let s=state.is_pressed();
|
||||
if let Some(input_instruction)=match keycode{
|
||||
winit::keyboard::Key::Named(winit::keyboard::NamedKey::Space)=>Some(OtherInstruction::SetJump(s)),
|
||||
if let Some(session_input_instruction)=match keycode{
|
||||
winit::keyboard::Key::Named(winit::keyboard::NamedKey::Space)=>Some(SessionInputInstruction::SetControl(SetControlInstruction::SetJump(s))),
|
||||
winit::keyboard::Key::Character(key)=>match key.as_str(){
|
||||
"W"|"w"=>Some(OtherInstruction::SetMoveForward(s)),
|
||||
"A"|"a"=>Some(OtherInstruction::SetMoveLeft(s)),
|
||||
"S"|"s"=>Some(OtherInstruction::SetMoveBack(s)),
|
||||
"D"|"d"=>Some(OtherInstruction::SetMoveRight(s)),
|
||||
"E"|"e"=>Some(OtherInstruction::SetMoveUp(s)),
|
||||
"Q"|"q"=>Some(OtherInstruction::SetMoveDown(s)),
|
||||
"Z"|"z"=>Some(OtherInstruction::SetZoom(s)),
|
||||
"R"|"r"=>if s{
|
||||
"W"|"w"=>Some(SessionInputInstruction::SetControl(SetControlInstruction::SetMoveForward(s))),
|
||||
"A"|"a"=>Some(SessionInputInstruction::SetControl(SetControlInstruction::SetMoveLeft(s))),
|
||||
"S"|"s"=>Some(SessionInputInstruction::SetControl(SetControlInstruction::SetMoveBack(s))),
|
||||
"D"|"d"=>Some(SessionInputInstruction::SetControl(SetControlInstruction::SetMoveRight(s))),
|
||||
"E"|"e"=>Some(SessionInputInstruction::SetControl(SetControlInstruction::SetMoveUp(s))),
|
||||
"Q"|"q"=>Some(SessionInputInstruction::SetControl(SetControlInstruction::SetMoveDown(s))),
|
||||
"Z"|"z"=>Some(SessionInputInstruction::SetControl(SetControlInstruction::SetZoom(s))),
|
||||
"R"|"r"=>s.then(||{
|
||||
//mouse needs to be reset since the position is absolute
|
||||
self.mouse_pos=glam::DVec2::ZERO;
|
||||
Some(OtherInstruction::ResetAndRestart)
|
||||
}else{None},
|
||||
"F"|"f"=>if s{Some(OtherInstruction::PracticeFly)}else{None},
|
||||
SessionInputInstruction::Mode(crate::session::ImplicitModeInstruction::ResetAndRestart)
|
||||
}),
|
||||
"F"|"f"=>s.then_some(SessionInputInstruction::Other(OtherOtherInstruction::PracticeFly)),
|
||||
_=>None,
|
||||
},
|
||||
_=>None,
|
||||
}{
|
||||
self.physics_thread.send(TimedInstruction{
|
||||
time,
|
||||
instruction:PhysicsWorkerInstruction::Input(UnbufferedInstruction::Other(input_instruction)),
|
||||
instruction:PhysicsWorkerInstruction::Input(session_input_instruction),
|
||||
}).unwrap();
|
||||
}
|
||||
},
|
||||
@ -137,7 +138,7 @@ impl WindowContext<'_>{
|
||||
self.mouse_pos+=glam::dvec2(delta.0,delta.1);
|
||||
self.physics_thread.send(TimedInstruction{
|
||||
time,
|
||||
instruction:PhysicsWorkerInstruction::Input(UnbufferedInstruction::MoveMouse(self.mouse_pos.as_ivec2())),
|
||||
instruction:PhysicsWorkerInstruction::Input(SessionInputInstruction::Mouse(self.mouse_pos.as_ivec2())),
|
||||
}).unwrap();
|
||||
},
|
||||
winit::event::DeviceEvent::MouseWheel {
|
||||
@ -147,7 +148,7 @@ impl WindowContext<'_>{
|
||||
if false{//self.physics.style.use_scroll{
|
||||
self.physics_thread.send(TimedInstruction{
|
||||
time,
|
||||
instruction:PhysicsWorkerInstruction::Input(UnbufferedInstruction::Other(OtherInstruction::SetJump(true))),//activates the immediate jump path, but the style modifier prevents controls&CONTROL_JUMP bit from being set to auto jump
|
||||
instruction:PhysicsWorkerInstruction::Input(SessionInputInstruction::SetControl(SetControlInstruction::SetJump(true))),//activates the immediate jump path, but the style modifier prevents controls&CONTROL_JUMP bit from being set to auto jump
|
||||
}).unwrap();
|
||||
}
|
||||
},
|
||||
|
@ -190,7 +190,7 @@ mod test{
|
||||
for _ in 0..5 {
|
||||
let task = instruction::TimedInstruction{
|
||||
time:strafesnet_common::physics::Time::ZERO,
|
||||
instruction:strafesnet_common::physics::Instruction::Other(strafesnet_common::physics::OtherInstruction::Idle),
|
||||
instruction:strafesnet_common::physics::Instruction::IDLE,
|
||||
};
|
||||
worker.send(task).unwrap();
|
||||
}
|
||||
@ -204,7 +204,7 @@ mod test{
|
||||
// Send a new task
|
||||
let task = instruction::TimedInstruction{
|
||||
time:integer::Time::ZERO,
|
||||
instruction:strafesnet_common::physics::Instruction::Other(strafesnet_common::physics::OtherInstruction::Idle),
|
||||
instruction:strafesnet_common::physics::Instruction::IDLE,
|
||||
};
|
||||
worker.send(task).unwrap();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user