fix non-determinism bug

This commit is contained in:
Quaternions 2025-01-15 03:03:07 -08:00
parent 2a9e848541
commit 8659f0a132
2 changed files with 7 additions and 12 deletions

View File

@ -122,17 +122,6 @@ impl MouseInterpolator{
// case 3: stop
// a mouse event is buffered, but no mouse events have transpired within 10ms
// This is a potential source of non-determinism
// since the timestamp from the first instruction after timeout is used
// and not the precise timeout timestamp.
// This can be fixed by polling the mouse interpolator for timeout externally
// and then conditionally running the timeout right before every instruction.
// Essentially moving this if statement outside where the timer is accessible.
if self.get_mouse_timedout_at(ins.time).is_some(){
// push buffered mouse instruction and flush buffer to output
self.timeout_mouse(ins.instruction.time);
}
// replace_with allows the enum variant to safely be replaced
// from behind a mutable reference, but a panic in the closure means that
// the entire program terminates rather than completing an unwind.

View File

@ -122,6 +122,7 @@ impl Session{
impl InstructionConsumer<Instruction<'_>> for Session{
type TimeInner=SessionTimeInner;
fn process_instruction(&mut self,ins:TimedInstruction<Instruction,Self::TimeInner>){
// repetitive procedure macro
macro_rules! run_mouse_interpolator_instruction{
($instruction:expr)=>{
self.mouse_interpolator.process_instruction(TimedInstruction{
@ -133,6 +134,10 @@ impl InstructionConsumer<Instruction<'_>> for Session{
});
};
}
// process any timeouts that occured since the last instruction
self.process_exhaustive(ins.time);
match ins.instruction{
// send it down to MouseInterpolator with two timestamps, SessionTime and PhysicsTime
Instruction::Input(SessionInputInstruction::Mouse(pos))=>{
@ -168,7 +173,8 @@ impl InstructionConsumer<Instruction<'_>> for Session{
run_mouse_interpolator_instruction!(MouseInterpolatorInstruction::Other(OtherInstruction::Mode(ModeInstruction::Spawn(ModeId::MAIN,StageId::FIRST))));
},
};
// run all buffered instruction produced
// run all emitted output instructions or timeouts
self.process_exhaustive(ins.time);
}
}