Add runner and timer

This commit is contained in:
Nicolas 2022-04-09 17:05:43 +02:00
parent 6871f75d09
commit 25da606322
3 changed files with 79 additions and 5 deletions

View File

@ -1,4 +1,5 @@
use std::io::stdout; use std::io::stdout;
use std::time::Duration;
use anyhow::Error; use anyhow::Error;
use clap::Parser; use clap::Parser;
use clap::ArgEnum; use clap::ArgEnum;
@ -11,8 +12,10 @@ use crate::fill::circle::CircleFillMode;
use crate::fill::FillMode; use crate::fill::FillMode;
use crate::fill::level::LevelFillMode; use crate::fill::level::LevelFillMode;
use crate::render::{Renderer, SamplerRenderer}; use crate::render::{Renderer, SamplerRenderer};
use crate::runner::Runner;
use crate::sampler::ComposedSampler; use crate::sampler::ComposedSampler;
use crate::surface::WriteSurface; use crate::surface::WriteSurface;
use crate::timer::SimpleTimer;
use crate::vec::Vector; use crate::vec::Vector;
mod color; mod color;
@ -24,6 +27,8 @@ mod surface;
mod animation; mod animation;
mod sampler; mod sampler;
mod render; mod render;
mod timer;
mod runner;
#[derive(Copy, Clone, ArgEnum)] #[derive(Copy, Clone, ArgEnum)]
enum AnimationType { enum AnimationType {
@ -81,12 +86,11 @@ fn main() -> Result<(), Error> {
let sampler = Box::new(ComposedSampler::new(animation, fill, color, char)); let sampler = Box::new(ComposedSampler::new(animation, fill, color, char));
let surface = Box::new(WriteSurface::new(stdout(), width, height)); let surface = Box::new(WriteSurface::new(stdout(), width, height));
let mut renderer = Box::new(SamplerRenderer::new(surface, sampler)); let renderer = Box::new(SamplerRenderer::new(surface, sampler));
let timer = Box::new(SimpleTimer::new(Duration::from_millis(1000 / 60)));
let runner = Runner::new(Duration::from_secs(2), timer, renderer);
renderer.render(0.5); runner.run()
renderer.present()?;
Ok(())
} }
fn create_animation(animation: AnimationType, size: Vector) -> Box<dyn Animation> { fn create_animation(animation: AnimationType, size: Vector) -> Box<dyn Animation> {

31
src/runner.rs Normal file
View File

@ -0,0 +1,31 @@
use std::time::Duration;
use anyhow::Error;
use crate::Renderer;
use crate::timer::Timer;
pub struct Runner {
timer: Box<dyn Timer>,
ticks: u128,
renderer: Box<dyn Renderer>,
}
impl Runner {
pub fn new(duration: Duration,
timer: Box<dyn Timer>,
renderer: Box<dyn Renderer>) -> Self {
let ticks = duration.as_nanos() / timer.delay().as_nanos();
Self { timer, ticks, renderer }
}
pub fn run(mut self) -> Result<(), Error> {
for i in 0..self.ticks {
let step = i as f32 / self.ticks as f32;
self.renderer.render(step);
self.renderer.present()?;
self.timer.sleep();
}
self.renderer.finish()
}
}

39
src/timer.rs Normal file
View File

@ -0,0 +1,39 @@
use std::thread::sleep;
use std::time::{Duration, Instant};
use mockall::automock;
#[automock]
pub trait Timer {
fn sleep(&mut self);
fn delay(&self) -> Duration;
}
pub struct SimpleTimer {
delay: Duration,
last: Instant
}
impl SimpleTimer {
pub fn new(delay: Duration) -> Self {
Self {
last: Instant::now(),
delay,
}
}
}
impl Timer for SimpleTimer {
fn sleep(&mut self) {
let now = Instant::now();
if self.last + self.delay > now {
sleep(self.delay - (now - self.last));
}
self.last = Instant::now();
}
fn delay(&self) -> Duration {
self.delay
}
}