mirror of
https://github.com/ricoriedel/wipe.git
synced 2024-11-04 15:16:40 +00:00
Allow skipping frames
This commit is contained in:
parent
94888dcc7d
commit
7500e5af1b
@ -5,8 +5,8 @@ use crate::timer::Timer;
|
||||
|
||||
/// Periodically calls [Renderer::render] and [Renderer::present].
|
||||
pub struct Runner<TTimer, TRenderer> {
|
||||
duration: Duration,
|
||||
timer: TTimer,
|
||||
ticks: u128,
|
||||
renderer: TRenderer,
|
||||
}
|
||||
|
||||
@ -14,19 +14,23 @@ impl<T1: Timer, T2: Renderer> Runner<T1, T2> {
|
||||
pub fn new(duration: Duration,
|
||||
timer: T1,
|
||||
renderer: T2) -> Self {
|
||||
let ticks = duration.as_nanos() / timer.delay().as_nanos();
|
||||
|
||||
Self { timer, ticks, renderer }
|
||||
Self { duration, timer, renderer }
|
||||
}
|
||||
|
||||
pub fn run(mut self) -> Result<(), Error> {
|
||||
for i in 0..=self.ticks {
|
||||
let step = i as f32 / self.ticks as f32;
|
||||
self.timer.set();
|
||||
|
||||
while self.timer.elapsed() < self.duration {
|
||||
let step = self.timer.elapsed().as_secs_f32() / self.duration.as_secs_f32();
|
||||
|
||||
self.renderer.render(step);
|
||||
self.renderer.present()?;
|
||||
self.timer.sleep();
|
||||
}
|
||||
self.renderer.render(1.0);
|
||||
self.renderer.present()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -46,19 +50,21 @@ mod test {
|
||||
let mut renderer = MockRenderer::new();
|
||||
let seq = &mut Sequence::new();
|
||||
|
||||
timer.expect_delay().return_const(Duration::from_secs(2));
|
||||
timer.expect_set().once().in_sequence(seq).return_const(());
|
||||
|
||||
timer.expect_elapsed().times(2).in_sequence(seq).return_const(Duration::from_secs(0));
|
||||
renderer.expect_render().once().with(eq(0.0)).in_sequence(seq).return_const(());
|
||||
renderer.expect_present().once().in_sequence(seq).returning(|| Ok(()));
|
||||
timer.expect_sleep().once().in_sequence(seq).return_const(());
|
||||
|
||||
timer.expect_elapsed().times(2).in_sequence(seq).return_const(Duration::from_secs(2));
|
||||
renderer.expect_render().once().with(eq(0.5)).in_sequence(seq).return_const(());
|
||||
renderer.expect_present().once().in_sequence(seq).returning(|| Ok(()));
|
||||
timer.expect_sleep().once().in_sequence(seq).return_const(());
|
||||
|
||||
timer.expect_elapsed().times(1).in_sequence(seq).return_const(Duration::from_secs(4));
|
||||
renderer.expect_render().once().with(eq(1.0)).in_sequence(seq).return_const(());
|
||||
renderer.expect_present().once().in_sequence(seq).returning(|| Ok(()));
|
||||
timer.expect_sleep().once().in_sequence(seq).return_const(());
|
||||
|
||||
let runner = Runner::new(Duration::from_secs(4), timer, renderer);
|
||||
|
||||
|
26
src/timer.rs
26
src/timer.rs
@ -7,29 +7,43 @@ use mockall::automock;
|
||||
/// Allows for periodic execution of code.
|
||||
#[cfg_attr(test, automock)]
|
||||
pub trait Timer {
|
||||
/// Set the start time of the timer.
|
||||
fn set(&mut self);
|
||||
|
||||
/// Get the elapsed time since calling [Timer::set].
|
||||
fn elapsed(&self) -> Duration;
|
||||
|
||||
/// Sleep until the next tick starts.
|
||||
fn sleep(&mut self);
|
||||
|
||||
/// Get the delay between ticks.
|
||||
fn delay(&self) -> Duration;
|
||||
}
|
||||
|
||||
/// A simple [Timer] based on the system clock.
|
||||
pub struct SimpleTimer {
|
||||
delay: Duration,
|
||||
start: Instant,
|
||||
last: Instant
|
||||
}
|
||||
|
||||
impl SimpleTimer {
|
||||
pub fn new(delay: Duration) -> Self {
|
||||
Self {
|
||||
last: Instant::now(),
|
||||
delay,
|
||||
start: Instant::now(),
|
||||
last: Instant::now(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Timer for SimpleTimer {
|
||||
fn set(&mut self) {
|
||||
self.start = Instant::now();
|
||||
self.last = self.start;
|
||||
}
|
||||
|
||||
fn elapsed(&self) -> Duration {
|
||||
Instant::now() - self.start
|
||||
}
|
||||
|
||||
fn sleep(&mut self) {
|
||||
let now = Instant::now();
|
||||
|
||||
@ -38,8 +52,4 @@ impl Timer for SimpleTimer {
|
||||
}
|
||||
self.last = Instant::now();
|
||||
}
|
||||
|
||||
fn delay(&self) -> Duration {
|
||||
self.delay
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user