don't mutate physics_timeline on the fly

This commit is contained in:
Quaternions 2025-01-13 23:18:05 -08:00
parent a8581a2a4f
commit 52bbaaddc7

View File

@ -28,11 +28,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>)->(Option<TimedInstruction<OtherInstruction,PhysicsTimeInner>>,Self){ fn next_state(self,ins:DoubleTimedUnbufferedInstruction)->((Option<TimedInstruction<MouseInstruction,PhysicsTimeInner>>,Option<TimedInstruction<OtherInstruction,PhysicsTimeInner>>),Self){
let next_state=match self{ let next_state=match self{
BufferState::Unbuffered=>{ BufferState::Unbuffered=>{
if let PhysicsUnbufferedInstruction::MoveMouse(pos)=ins.instruction.instruction{ if let PhysicsUnbufferedInstruction::MoveMouse(pos)=ins.instruction.instruction{
return (None,BufferState::Initializing(ins.time,MouseState{pos,time:ins.instruction.time})); return ((None,None),BufferState::Initializing(ins.time,MouseState{pos,time:ins.instruction.time}));
} }
BufferState::Unbuffered BufferState::Unbuffered
}, },
@ -40,29 +40,25 @@ impl BufferState{
let timeout=time+MOUSE_TIMEOUT; let timeout=time+MOUSE_TIMEOUT;
if timeout<ins.time{ if timeout<ins.time{
// duplicate the current mouse // duplicate the current mouse
physics_timeline.push_front(TimedInstruction{ let ins_mouse=TimedInstruction{
// This should be simulation_timer.time(time) // This should be simulation_timer.time(time)
// 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::Mouse( instruction:MouseInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:ins.instruction.time}),
MouseInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:ins.instruction.time}) };
), return ((Some(ins_mouse),None),BufferState::Unbuffered);
});
return (None,BufferState::Unbuffered);
} }
if let PhysicsUnbufferedInstruction::MoveMouse(pos)=ins.instruction.instruction{ if let PhysicsUnbufferedInstruction::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{ let ins_mouse=TimedInstruction{
time:mouse_state.time, time:mouse_state.time,
instruction:PhysicsInputInstruction::Mouse( instruction:MouseInstruction::ReplaceMouse{
MouseInstruction::ReplaceMouse{ s0:mouse_state,
s0:mouse_state, s1:next_mouse_state.clone(),
s1:next_mouse_state.clone(), },
} };
), return ((Some(ins_mouse),None),BufferState::Buffered(ins.time,next_mouse_state));
});
return (None,BufferState::Buffered(ins.time,next_mouse_state));
} }
BufferState::Initializing(time,mouse_state) BufferState::Initializing(time,mouse_state)
}, },
@ -71,38 +67,34 @@ impl BufferState{
let timeout=time+MOUSE_TIMEOUT; let timeout=time+MOUSE_TIMEOUT;
if timeout<ins.time{ if timeout<ins.time{
// duplicate the current mouse // duplicate the current mouse
physics_timeline.push_front(TimedInstruction{ let ins_mouse=TimedInstruction{
// This should be simulation_timer.time(timeout) // This should be simulation_timer.time(timeout)
// 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::Mouse( instruction:MouseInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:ins.instruction.time}),
MouseInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:ins.instruction.time}) };
), return ((Some(ins_mouse),None),BufferState::Unbuffered);
});
return (None,BufferState::Unbuffered);
} }
if let PhysicsUnbufferedInstruction::MoveMouse(pos)=ins.instruction.instruction{ if let PhysicsUnbufferedInstruction::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{ let ins_mouse=TimedInstruction{
time:ins.instruction.time, time:ins.instruction.time,
instruction:PhysicsInputInstruction::Mouse( instruction:MouseInstruction::SetNextMouse(next_mouse_state.clone()),
MouseInstruction::SetNextMouse(next_mouse_state.clone()) };
), return ((Some(ins_mouse),None),BufferState::Buffered(ins.time,next_mouse_state));
});
return (None,BufferState::Buffered(ins.time,next_mouse_state));
} }
BufferState::Buffered(time,mouse_state) BufferState::Buffered(time,mouse_state)
}, },
}; };
let instruction_out=match ins.instruction.instruction{ let ins_other=match ins.instruction.instruction{
PhysicsUnbufferedInstruction::MoveMouse(_)=>None, PhysicsUnbufferedInstruction::MoveMouse(_)=>None,
PhysicsUnbufferedInstruction::Other(other_instruction)=>Some(TimedInstruction{ PhysicsUnbufferedInstruction::Other(other_instruction)=>Some(TimedInstruction{
time:ins.instruction.time, time:ins.instruction.time,
instruction:other_instruction, instruction:other_instruction,
}), }),
}; };
(instruction_out,next_state) ((None,ins_other),next_state)
} }
} }
pub struct MouseInterpolator{ pub struct MouseInterpolator{
@ -143,10 +135,16 @@ 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
// replace_with allows the enum variant to safely be replaced from behind a mutable reference // replace_with allows the enum variant to safely be replaced from behind a mutable reference
let ins_inner=replace_with::replace_with_or_abort_and_return(&mut self.buffer_state,|buffer_state|{ let (ins_mouse,ins_other)=replace_with::replace_with_or_abort_and_return(&mut self.buffer_state,|buffer_state|{
buffer_state.next_state(ins,&mut self.physics_timeline) buffer_state.next_state(ins)
}); });
if let Some(ins)=ins_inner{ if let Some(ins)=ins_mouse{
self.physics_timeline.push_front(TimedInstruction{
time:ins.time,
instruction:PhysicsInputInstruction::Mouse(ins.instruction),
});
}
if let Some(ins)=ins_other{
self.physics_timeline.push_back(TimedInstruction{ self.physics_timeline.push_back(TimedInstruction{
time:ins.time, time:ins.time,
instruction:PhysicsInputInstruction::Other(ins.instruction), instruction:PhysicsInputInstruction::Other(ins.instruction),