diff --git a/src/physics_worker.rs b/src/physics_worker.rs index daee45b..33cf270 100644 --- a/src/physics_worker.rs +++ b/src/physics_worker.rs @@ -16,12 +16,8 @@ pub enum InputInstruction{ MoveForward(bool), Jump(bool), Zoom(bool), - /// Reset: fully replace the physics state. - /// This forgets all inputs and settings which need to be reapplied. - Reset, - /// Restart: Teleport to the start zone. - Restart, - Spawn(strafesnet_common::gameplay_modes::ModeId,strafesnet_common::gameplay_modes::StageId), + ResetAndRestart, + ResetAndSpawn(strafesnet_common::gameplay_modes::ModeId,strafesnet_common::gameplay_modes::StageId), PracticeFly, } pub enum Instruction{ @@ -87,41 +83,62 @@ impl MouseInterpolator<'_>{ } self.last_mouse_time=self.timer.time(ins.time); } - /// returns the mapped physics input instruction + fn push(&mut self,time:Time,phys_input:PhysicsInputInstruction){ + //This is always a non-mouse event + self.timeline.push_back(TimedInstruction{ + time:self.timer.time(time), + instruction:phys_input, + }); + } + /// returns should_empty_queue /// may or may not mutate internal state XD! - fn map_instruction(&mut self,ins:&TimedInstruction)->Option{ + fn map_instruction(&mut self,ins:&TimedInstruction)->bool{ + let mut update_mouse_blocking=false; match &ins.instruction{ Instruction::Input(input_instruction)=>match input_instruction{ &InputInstruction::MoveMouse(m)=>{ if !self.timer.is_paused(){ self.push_mouse_instruction(ins,m); } - None + update_mouse_blocking=true; }, - &InputInstruction::MoveForward(s)=>Some(PhysicsInputInstruction::SetMoveForward(s)), - &InputInstruction::MoveLeft(s)=>Some(PhysicsInputInstruction::SetMoveLeft(s)), - &InputInstruction::MoveBack(s)=>Some(PhysicsInputInstruction::SetMoveBack(s)), - &InputInstruction::MoveRight(s)=>Some(PhysicsInputInstruction::SetMoveRight(s)), - &InputInstruction::MoveUp(s)=>Some(PhysicsInputInstruction::SetMoveUp(s)), - &InputInstruction::MoveDown(s)=>Some(PhysicsInputInstruction::SetMoveDown(s)), - &InputInstruction::Jump(s)=>Some(PhysicsInputInstruction::SetJump(s)), - &InputInstruction::Zoom(s)=>Some(PhysicsInputInstruction::SetZoom(s)), - &InputInstruction::Spawn(mode_id,stage_id)=>Some(PhysicsInputInstruction::Spawn(mode_id,stage_id)), - InputInstruction::Restart=>Some(PhysicsInputInstruction::Restart), - InputInstruction::PracticeFly=>Some(PhysicsInputInstruction::PracticeFly), + &InputInstruction::MoveForward(s)=>self.push(ins.time,PhysicsInputInstruction::SetMoveForward(s)), + &InputInstruction::MoveLeft(s)=>self.push(ins.time,PhysicsInputInstruction::SetMoveLeft(s)), + &InputInstruction::MoveBack(s)=>self.push(ins.time,PhysicsInputInstruction::SetMoveBack(s)), + &InputInstruction::MoveRight(s)=>self.push(ins.time,PhysicsInputInstruction::SetMoveRight(s)), + &InputInstruction::MoveUp(s)=>self.push(ins.time,PhysicsInputInstruction::SetMoveUp(s)), + &InputInstruction::MoveDown(s)=>self.push(ins.time,PhysicsInputInstruction::SetMoveDown(s)), + &InputInstruction::Jump(s)=>self.push(ins.time,PhysicsInputInstruction::SetJump(s)), + &InputInstruction::Zoom(s)=>self.push(ins.time,PhysicsInputInstruction::SetZoom(s)), + &InputInstruction::ResetAndSpawn(mode_id,stage_id)=>{ + self.push(ins.time,PhysicsInputInstruction::Reset); + self.push(ins.time,PhysicsInputInstruction::Spawn(mode_id,stage_id)); + }, + InputInstruction::ResetAndRestart=>{ + self.push(ins.time,PhysicsInputInstruction::Reset); + self.push(ins.time,PhysicsInputInstruction::Restart); + }, + InputInstruction::PracticeFly=>self.push(ins.time,PhysicsInputInstruction::PracticeFly), }, //do these really need to idle the physics? //sending None dumps the instruction queue - Instruction::ChangeMap(_)=>Some(PhysicsInputInstruction::Idle), - Instruction::Resize(_)=>Some(PhysicsInputInstruction::Idle), - Instruction::Render=>Some(PhysicsInputInstruction::Idle), + Instruction::ChangeMap(_)=>self.push(ins.time,PhysicsInputInstruction::Idle), + Instruction::Resize(_)=>self.push(ins.time,PhysicsInputInstruction::Idle), + Instruction::Render=>self.push(ins.time,PhysicsInputInstruction::Idle), &Instruction::SetPaused(paused)=>{ if let Err(e)=self.timer.set_paused(ins.time,paused){ println!("Cannot pause: {e}"); } - Some(PhysicsInputInstruction::Idle) + self.push(ins.time,PhysicsInputInstruction::Idle); }, } + if update_mouse_blocking{ + //this returns the bool for us + self.update_mouse_blocking(ins.time) + }else{ + //do flush that queue + true + } } /// must check if self.mouse_blocking==true before calling! fn unblock_mouse(&mut self,time:Time){ @@ -153,17 +170,6 @@ impl MouseInterpolator<'_>{ true } } - /// returns whether or not to empty the instruction queue - fn handle_physics_input(&mut self,time:Time,phys_input:PhysicsInputInstruction)->bool{ - //non-mouse event - self.timeline.push_back(TimedInstruction{ - time:self.timer.time(time), - instruction:phys_input, - }); - - //this returns the bool for us - self.update_mouse_blocking(time) - } fn empty_queue(&mut self){ while let Some(instruction)=self.timeline.pop_front(){ //makeshift clone because requiring all TimedInstructions to be Clone is troublesome @@ -177,12 +183,7 @@ impl MouseInterpolator<'_>{ } } pub fn handle_instruction(&mut self,ins:&TimedInstruction){ - let should_empty_queue=self.map_instruction(ins) - //should empty queue defaults to true - .map_or(true,|physics_input| - //this returns whether to empty the queue based on the input - self.handle_physics_input(ins.time,physics_input) - ); + let should_empty_queue=self.map_instruction(ins); if should_empty_queue{ self.empty_queue(); } @@ -196,22 +197,14 @@ impl MouseInterpolator<'_>{ self.unblock_mouse(time); } self.empty_queue(); + //doing it like this to avoid doing PhysicsInstruction::ChangeMap(Rc) self.physics.generate_models(&map); - let simulation_time=self.timer.time(time); - //important! - //bots will not work properly without this exact restart + spawn setup - //reset the physics state to start a new run on the new map + //use the standard input interface so the instructions are written out to bots self.handle_instruction(&TimedInstruction{ - time:simulation_time, - instruction:Instruction::Input(InputInstruction::Reset), - }); - //generate a spawn event so bots work properly on the first run - //no run started so does not invalidate the run - self.handle_instruction(&TimedInstruction{ - time:simulation_time, - instruction:Instruction::Input(InputInstruction::Spawn( + time:self.timer.time(time), + instruction:Instruction::Input(InputInstruction::ResetAndSpawn( strafesnet_common::gameplay_modes::ModeId::MAIN, strafesnet_common::gameplay_modes::StageId::FIRST, )), diff --git a/src/window.rs b/src/window.rs index f05c7cf..1134fc1 100644 --- a/src/window.rs +++ b/src/window.rs @@ -110,7 +110,7 @@ impl WindowContext<'_>{ "r"=>if s{ //mouse needs to be reset since the position is absolute self.mouse=strafesnet_common::mouse::MouseState::default(); - Some(InputInstruction::Restart) + Some(InputInstruction::ResetAndRestart) }else{None}, "f"=>if s{Some(InputInstruction::PracticeFly)}else{None}, _=>None,