implement copy instruction into replay

This commit is contained in:
Quaternions 2025-01-15 23:44:42 -08:00
parent 15a9136fc4
commit 4efe1209b8
2 changed files with 55 additions and 9 deletions

View File

@ -57,8 +57,9 @@ pub fn new<'a>(
}, },
Instruction::Render=>{ Instruction::Render=>{
run_session_instruction!(ins.time,SESSION_INSTRUCTION_IDLE); run_session_instruction!(ins.time,SESSION_INSTRUCTION_IDLE);
let frame_state=session.get_frame_state(ins.time); if let Some(frame_state)=session.get_frame_state(ins.time){
run_graphics_worker_instruction!(GraphicsInstruction::Render(frame_state)); run_graphics_worker_instruction!(GraphicsInstruction::Render(frame_state));
}
}, },
Instruction::Resize(physical_size)=>{ Instruction::Resize(physical_size)=>{
run_session_instruction!(ins.time,SESSION_INSTRUCTION_IDLE); run_session_instruction!(ins.time,SESSION_INSTRUCTION_IDLE);

View File

@ -1,3 +1,5 @@
use std::collections::HashMap;
use strafesnet_common::gameplay_modes::{ModeId,StageId}; use strafesnet_common::gameplay_modes::{ModeId,StageId};
use strafesnet_common::instruction::{InstructionConsumer,InstructionEmitter,InstructionFeedback,TimedInstruction}; use strafesnet_common::instruction::{InstructionConsumer,InstructionEmitter,InstructionFeedback,TimedInstruction};
// session represents the non-hardware state of the client. // session represents the non-hardware state of the client.
@ -105,14 +107,27 @@ impl Replay{
} }
} }
#[derive(Clone,Copy,Hash,PartialEq,Eq)]
struct BotId(u32);
//#[derive(Clone,Copy,Hash,PartialEq,Eq)]
//struct PlayerId(u32);
enum ViewState{
Play,
//Spectate(PlayerId),
Replay(BotId),
}
pub struct Session{ pub struct Session{
user_settings:UserSettings, user_settings:UserSettings,
mouse_interpolator:crate::mouse_interpolator::MouseInterpolator, mouse_interpolator:crate::mouse_interpolator::MouseInterpolator,
view_state:ViewState,
//gui:GuiState //gui:GuiState
simulation:Simulation, simulation:Simulation,
// below fields not included in lite session // below fields not included in lite session
recording:Recording, recording:Recording,
replays:Vec<Replay>, //players:HashMap<PlayerId,Simulation>,
replays:HashMap<BotId,Replay>,
} }
impl Session{ impl Session{
pub fn new( pub fn new(
@ -123,8 +138,9 @@ impl Session{
user_settings, user_settings,
mouse_interpolator:MouseInterpolator::new(), mouse_interpolator:MouseInterpolator::new(),
simulation, simulation,
view_state:ViewState::Play,
recording:Default::default(), recording:Default::default(),
replays:Vec::new(), replays:HashMap::new(),
} }
} }
fn clear_recording(&mut self){ fn clear_recording(&mut self){
@ -133,8 +149,13 @@ impl Session{
fn change_map(&mut self,map:&strafesnet_common::map::CompleteMap){ fn change_map(&mut self,map:&strafesnet_common::map::CompleteMap){
self.simulation.physics.generate_models(map); self.simulation.physics.generate_models(map);
} }
pub fn get_frame_state(&self,time:SessionTime)->FrameState{ pub fn get_frame_state(&self,time:SessionTime)->Option<FrameState>{
self.simulation.get_frame_state(time) match &self.view_state{
ViewState::Play=>Some(self.simulation.get_frame_state(time)),
ViewState::Replay(bot_id)=>self.replays.get(bot_id).map(|replay|
replay.simulation.get_frame_state(time)
),
}
} }
pub fn user_settings(&self)->&UserSettings{ pub fn user_settings(&self)->&UserSettings{
&self.user_settings &self.user_settings
@ -197,13 +218,37 @@ impl InstructionConsumer<Instruction<'_>> for Session{
_=self.simulation.timer.set_paused(ins.time,paused); _=self.simulation.timer.set_paused(ins.time,paused);
}, },
Instruction::Control(SessionControlInstruction::CopyRecordingIntoReplayAndSpectate)=>{ Instruction::Control(SessionControlInstruction::CopyRecordingIntoReplayAndSpectate)=>{
todo!(); // Bind: B
// pause simulation
_=self.simulation.timer.set_paused(ins.time,true);
// create recording
let mut recording=Recording::default();
recording.instructions.extend(self.recording.instructions.iter().cloned());
// create timer starting at first instruction (or zero if the list is empty)
let timer=Timer::unpaused(ins.time,recording.instructions.first().map_or(PhysicsTime::ZERO,|ins|ins.time));
// create default physics state
let simulation=Simulation::new(timer,Default::default());
// invent a new bot id and insert the replay
let bot_id=BotId(self.replays.len() as u32);
self.replays.insert(bot_id,Replay::new(
recording,
simulation,
));
// begin spectate
self.view_state=ViewState::Replay(bot_id);
}, },
Instruction::Control(SessionControlInstruction::StopSpectate)=>{ Instruction::Control(SessionControlInstruction::StopSpectate)=>{
todo!(); _=self.simulation.timer.set_paused(ins.time,false);
self.view_state=ViewState::Play;
}, },
Instruction::Playback(_)=>{ Instruction::Playback(_)=>{
todo!(); println!("[session] todo: Playback instructions");
}, },
Instruction::ChangeMap(complete_map)=>{ Instruction::ChangeMap(complete_map)=>{
self.clear_recording(); self.clear_recording();