use replace_with to replace the enum variant in-place without cloning
This commit is contained in:
parent
844c7a08e1
commit
c6ff11dd3e
@ -28,15 +28,16 @@ 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>)->(Self,Option<TimedInstruction<OtherInstruction,PhysicsTimeInner>>){
|
fn next_state(self,ins:DoubleTimedUnbufferedInstruction,physics_timeline:&mut std::collections::VecDeque<TimedPhysicsInstruction>)->(Option<TimedInstruction<OtherInstruction,PhysicsTimeInner>>,Self){
|
||||||
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 (BufferState::Initializing(ins.time,MouseState{pos,time:ins.instruction.time}),None);
|
return (None,BufferState::Initializing(ins.time,MouseState{pos,time:ins.instruction.time}));
|
||||||
}
|
}
|
||||||
|
BufferState::Unbuffered
|
||||||
},
|
},
|
||||||
BufferState::Initializing(time,mouse_state)=>{
|
BufferState::Initializing(time,mouse_state)=>{
|
||||||
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{
|
physics_timeline.push_front(TimedInstruction{
|
||||||
@ -48,7 +49,7 @@ impl BufferState{
|
|||||||
MouseInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:ins.instruction.time})
|
MouseInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:ins.instruction.time})
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
return (BufferState::Unbuffered,None);
|
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};
|
||||||
@ -56,17 +57,18 @@ impl BufferState{
|
|||||||
time:mouse_state.time,
|
time:mouse_state.time,
|
||||||
instruction:PhysicsInputInstruction::Mouse(
|
instruction:PhysicsInputInstruction::Mouse(
|
||||||
MouseInstruction::ReplaceMouse{
|
MouseInstruction::ReplaceMouse{
|
||||||
s0:mouse_state.clone(),
|
s0:mouse_state,
|
||||||
s1:next_mouse_state.clone(),
|
s1:next_mouse_state.clone(),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
return (BufferState::Buffered(ins.time,next_mouse_state),None);
|
return (None,BufferState::Buffered(ins.time,next_mouse_state));
|
||||||
}
|
}
|
||||||
|
BufferState::Initializing(time,mouse_state)
|
||||||
},
|
},
|
||||||
BufferState::Buffered(time,mouse_state)=>{
|
BufferState::Buffered(time,mouse_state)=>{
|
||||||
// TODO: deduplicate code with above case
|
// TODO: deduplicate code with above case
|
||||||
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{
|
physics_timeline.push_front(TimedInstruction{
|
||||||
@ -78,7 +80,7 @@ impl BufferState{
|
|||||||
MouseInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:ins.instruction.time})
|
MouseInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:ins.instruction.time})
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
return (BufferState::Unbuffered,None);
|
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};
|
||||||
@ -88,10 +90,11 @@ impl BufferState{
|
|||||||
MouseInstruction::SetNextMouse(next_mouse_state.clone())
|
MouseInstruction::SetNextMouse(next_mouse_state.clone())
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
return (BufferState::Buffered(ins.time,next_mouse_state),None);
|
return (None,BufferState::Buffered(ins.time,next_mouse_state));
|
||||||
}
|
}
|
||||||
|
BufferState::Buffered(time,mouse_state)
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
let instruction_out=match ins.instruction.instruction{
|
let instruction_out=match ins.instruction.instruction{
|
||||||
PhysicsUnbufferedInstruction::MoveMouse(_)=>None,
|
PhysicsUnbufferedInstruction::MoveMouse(_)=>None,
|
||||||
PhysicsUnbufferedInstruction::Other(other_instruction)=>Some(TimedInstruction{
|
PhysicsUnbufferedInstruction::Other(other_instruction)=>Some(TimedInstruction{
|
||||||
@ -99,7 +102,7 @@ impl BufferState{
|
|||||||
instruction:other_instruction,
|
instruction:other_instruction,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
(self.clone(),instruction_out)
|
(instruction_out,next_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub struct MouseInterpolator{
|
pub struct MouseInterpolator{
|
||||||
@ -139,9 +142,10 @@ impl MouseInterpolator{
|
|||||||
// a mouse event is buffered, and exists within the last 10ms
|
// a mouse event is buffered, and exists within the last 10ms
|
||||||
// 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
|
||||||
// TODO: remove clone
|
// replace_with allows the enum variant to safely be replaced from behind a mutable reference
|
||||||
let ins_inner;
|
let ins_inner=replace_with::replace_with_or_abort_and_return(&mut self.buffer_state,|buffer_state|{
|
||||||
(self.buffer_state,ins_inner)=self.buffer_state.next_state(ins,&mut self.physics_timeline);
|
buffer_state.next_state(ins,&mut self.physics_timeline)
|
||||||
|
});
|
||||||
if let Some(ins)=ins_inner{
|
if let Some(ins)=ins_inner{
|
||||||
self.physics_timeline.push_back(TimedInstruction{
|
self.physics_timeline.push_back(TimedInstruction{
|
||||||
time:ins.time,
|
time:ins.time,
|
||||||
@ -196,26 +200,27 @@ impl MouseInterpolator{
|
|||||||
match ins{
|
match ins{
|
||||||
// could check if self.is_first_ready()
|
// could check if self.is_first_ready()
|
||||||
StepInstruction::Pop=>self.physics_timeline.pop_front(),
|
StepInstruction::Pop=>self.physics_timeline.pop_front(),
|
||||||
StepInstruction::Timeout=>match &self.buffer_state{
|
StepInstruction::Timeout=>replace_with::replace_with_or_abort_and_return(&mut self.buffer_state,|buffer_state|{
|
||||||
BufferState::Unbuffered=>None,
|
match buffer_state{
|
||||||
BufferState::Initializing(time,mouse_state)
|
BufferState::Unbuffered=>(None,BufferState::Unbuffered),
|
||||||
|BufferState::Buffered(time,mouse_state)=>{
|
BufferState::Initializing(_time,mouse_state)
|
||||||
// convert to BufferState::Unbuffered
|
|BufferState::Buffered(_time,mouse_state)=>{
|
||||||
// use the first instruction which should be a mouse instruction
|
// convert to BufferState::Unbuffered
|
||||||
// to push a ReplaceMouse instruction
|
// use the first instruction which should be a mouse instruction
|
||||||
// duplicate the current mouse
|
// to push a ReplaceMouse instruction
|
||||||
self.buffer_state=BufferState::Unbuffered;
|
// duplicate the current mouse
|
||||||
Some(TimedInstruction{
|
(Some(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:mouse_state.time,
|
time:mouse_state.time,
|
||||||
instruction:PhysicsInputInstruction::Mouse(
|
instruction:PhysicsInputInstruction::Mouse(
|
||||||
MouseInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:mouse_state.time})
|
MouseInstruction::SetNextMouse(MouseState{pos:mouse_state.pos,time:mouse_state.time})
|
||||||
),
|
),
|
||||||
})
|
}),BufferState::Unbuffered)
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user