diff --git a/strafe-client/src/graphics_worker.rs b/strafe-client/src/graphics_worker.rs index fda2810..76d6eca 100644 --- a/strafe-client/src/graphics_worker.rs +++ b/strafe-client/src/graphics_worker.rs @@ -14,13 +14,13 @@ WorkerDescription{ */ //up to three frames in flight, dropping new frame requests when all three are busy, and dropping output frames when one renders out of order -pub fn new<'a>( +pub fn new( mut graphics:crate::graphics::GraphicsState, mut config:wgpu::SurfaceConfiguration, - surface:wgpu::Surface<'a>, + surface:wgpu::Surface, device:wgpu::Device, queue:wgpu::Queue, -)->crate::compat_worker::INWorker<'a,Instruction>{ +)->crate::compat_worker::INWorker<'_,Instruction>{ crate::compat_worker::INWorker::new(move |ins:Instruction|{ match ins{ Instruction::ChangeMap(map)=>{ diff --git a/strafe-client/src/physics_worker.rs b/strafe-client/src/physics_worker.rs index 7d713bc..fcfd42e 100644 --- a/strafe-client/src/physics_worker.rs +++ b/strafe-client/src/physics_worker.rs @@ -1,39 +1,81 @@ use crate::graphics_worker::Instruction as GraphicsInstruction; use crate::session::{ExternalInstruction 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; -type TimedSessionInstruction=strafesnet_common::instruction::TimedInstruction<SessionInstruction,SessionTimeInner>; +pub enum Instruction{ + Input(strafesnet_common::physics::UnbufferedInstruction), + 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)); pub fn new<'a>( mut graphics_worker:crate::compat_worker::INWorker<'a,crate::graphics_worker::Instruction>, user_settings:crate::settings::UserSettings, -)->crate::compat_worker::QNWorker<'a,TimedSessionInstruction>{ +)->crate::compat_worker::QNWorker<'a,TimedInstruction<Instruction,SessionTimeInner>>{ let physics=crate::physics::PhysicsContext::default(); let timer=Timer::unpaused(SessionTime::ZERO,PhysicsTime::ZERO); let simulation=Simulation::new(timer,physics); - let mouse_interpolator=crate::mouse_interpolator::MouseInterpolator::new(); let mut session=Session::new( user_settings, simulation, ); - crate::compat_worker::QNWorker::new(move |ins:TimedSessionInstruction|{ - session.handle_instruction(&ins); + crate::compat_worker::QNWorker::new(move |ins:TimedInstruction<Instruction,SessionTimeInner>|{ + // excruciating pain + macro_rules! run_session_instruction{ + ($time:expr,$instruction:expr)=>{ + session.process_instruction(TimedInstruction{ + time:$time, + instruction:$instruction, + }); + }; + } + macro_rules! run_graphics_worker_instruction{ + ($instruction:expr)=>{ + if let Some(instruction)=$instruction{ + graphics_worker.send(instruction).unwrap(); + } + }; + } match ins.instruction{ - SessionInstruction::Render=>{ + Instruction::Input(unbuffered_instruction)=>{ + let ins_session=SessionInstruction::Input(unbuffered_instruction); + run_session_instruction!(ins.time,ins_session); + let ins_graphics=None; + run_graphics_worker_instruction!(ins_graphics); + }, + Instruction::SetPaused(paused)=>{ + let ins_session=SessionInstruction::SetPaused(paused); + run_session_instruction!(ins.time,ins_session); + let ins_graphics=None; + run_graphics_worker_instruction!(ins_graphics); + }, + Instruction::Render=>{ + let ins_session=SESSION_INSTRUCTION_IDLE; + run_session_instruction!(ins.time,ins_session); let frame_state=session.get_frame_state(ins.time); - graphics_worker.send(GraphicsInstruction::Render(frame_state)).unwrap(); + let ins_graphics=Some(GraphicsInstruction::Render(frame_state)); + run_graphics_worker_instruction!(ins_graphics); }, - SessionInstruction::Resize(size)=>{ - graphics_worker.send(GraphicsInstruction::Resize(size,session.user_settings().clone())).unwrap(); + Instruction::Resize(physical_size)=>{ + let ins_session=SESSION_INSTRUCTION_IDLE; + run_session_instruction!(ins.time,ins_session); + let user_settings=session.user_settings().clone(); + let ins_graphics=Some(GraphicsInstruction::Resize(physical_size,user_settings)); + run_graphics_worker_instruction!(ins_graphics); }, - SessionInstruction::ChangeMap(map)=>{ - session.change_map(ins.time,&map); - graphics_worker.send(GraphicsInstruction::ChangeMap(map)).unwrap(); + Instruction::ChangeMap(complete_map)=>{ + let ins_session=SessionInstruction::ChangeMap(&complete_map); + run_session_instruction!(ins.time,ins_session); + let ins_graphics=Some(GraphicsInstruction::ChangeMap(complete_map)); + run_graphics_worker_instruction!(ins_graphics); }, - SessionInstruction::Input(_)=>(), - SessionInstruction::SetPaused(_)=>(), } }) } diff --git a/strafe-client/src/session.rs b/strafe-client/src/session.rs index c530637..1490a28 100644 --- a/strafe-client/src/session.rs +++ b/strafe-client/src/session.rs @@ -6,13 +6,12 @@ use strafesnet_common::timer::{Scaled,Timer}; use strafesnet_common::session::{TimeInner as SessionTimeInner,Time as SessionTime}; use crate::mouse_interpolator::{MouseInterpolator,StepInstruction}; +use crate::settings::UserSettings; -pub enum ExternalInstruction{ +pub enum ExternalInstruction<'a>{ Input(PhysicsUnbufferedInstruction), SetPaused(bool), - Render, - Resize(winit::dpi::PhysicalSize<u32>), - ChangeMap(strafesnet_common::map::CompleteMap), + ChangeMap(&'a strafesnet_common::map::CompleteMap), //Graphics(crate::graphics_worker::Instruction), } @@ -36,6 +35,13 @@ impl Simulation{ physics, } } + pub fn get_frame_state(&self,time:SessionTime)->FrameState{ + FrameState{ + body:self.physics.camera_body(), + camera:self.physics.camera(), + time:self.timer.time(time), + } + } } pub struct Replay{ @@ -57,7 +63,7 @@ impl Replay{ } pub struct Session{ - user_settings:crate::settings::UserSettings, + user_settings:UserSettings, mouse_interpolator:crate::mouse_interpolator::MouseInterpolator, //gui:GuiState simulation:Simulation, @@ -65,7 +71,7 @@ pub struct Session{ } impl Session{ pub fn new( - user_settings:crate::settings::UserSettings, + user_settings:UserSettings, simulation:Simulation, )->Self{ Self{ @@ -75,6 +81,15 @@ impl Session{ replays:Vec::new(), } } + fn change_map(&mut self,map:&strafesnet_common::map::CompleteMap){ + self.simulation.physics.generate_models(map); + } + pub fn get_frame_state(&self,time:SessionTime)->FrameState{ + self.simulation.get_frame_state(time) + } + pub fn user_settings(&self)->&UserSettings{ + &self.user_settings + } } // mouseinterpolator consumes RawInputInstruction @@ -84,7 +99,7 @@ impl Session{ // Session consumes DoStep -> forwards DoStep to mouseinterpolator // Session emits DoStep -impl InstructionConsumer<ExternalInstruction> for Session{ +impl InstructionConsumer<ExternalInstruction<'_>> for Session{ type TimeInner=SessionTimeInner; fn process_instruction(&mut self,ins:TimedInstruction<ExternalInstruction,Self::TimeInner>){ match ins.instruction{ @@ -102,9 +117,7 @@ impl InstructionConsumer<ExternalInstruction> for Session{ // what if they pause for 5ms lmao _=self.simulation.timer.set_paused(ins.time,paused); } - ExternalInstruction::Render=>(), - ExternalInstruction::Resize(physical_size)=>(), - ExternalInstruction::ChangeMap(complete_map)=>(), + ExternalInstruction::ChangeMap(complete_map)=>self.change_map(complete_map), }; // run all buffered instruction produced self.process_exhaustive(ins.time);