mirror of
https://github.com/ricoriedel/wipe.git
synced 2024-11-22 16:06:38 +00:00
Add renderer and mocks
This commit is contained in:
parent
26f4960276
commit
43cecf57b3
@ -10,4 +10,5 @@ repository = "https://github.com/ricoriedel/wipe"
|
||||
anyhow = "1.0"
|
||||
clap = { version = "3.1", features = ["derive"]}
|
||||
crossterm = "0.23"
|
||||
rand = "0.8"
|
||||
rand = "0.8"
|
||||
mockall = "0.11"
|
11
src/main.rs
11
src/main.rs
@ -10,6 +10,7 @@ use crate::color::{ColorSampler, SimpleColorSampler};
|
||||
use crate::fill::circle::CircleFillMode;
|
||||
use crate::fill::FillMode;
|
||||
use crate::fill::level::LevelFillMode;
|
||||
use crate::render::{Renderer, SamplerRenderer};
|
||||
use crate::sampler::ComposedSampler;
|
||||
use crate::surface::WriteSurface;
|
||||
use crate::vec::Vector;
|
||||
@ -22,6 +23,7 @@ mod array;
|
||||
mod surface;
|
||||
mod animation;
|
||||
mod sampler;
|
||||
mod render;
|
||||
|
||||
#[derive(Copy, Clone, ArgEnum)]
|
||||
enum AnimationType {
|
||||
@ -76,8 +78,13 @@ fn main() -> Result<(), Error> {
|
||||
let color = create_color(args.color[0]);
|
||||
let char = Box::new(SimpleCharSampler::new(args.chars));
|
||||
|
||||
let _ = Box::new(ComposedSampler::new(animation, fill, color, char));
|
||||
let _ = Box::new(WriteSurface::new(stdout(), width, height));
|
||||
let sampler = Box::new(ComposedSampler::new(animation, fill, color, char));
|
||||
let surface = Box::new(WriteSurface::new(stdout(), width, height));
|
||||
|
||||
let mut renderer = Box::new(SamplerRenderer::new(surface, sampler));
|
||||
|
||||
renderer.render(0.5);
|
||||
renderer.present()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
87
src/render.rs
Normal file
87
src/render.rs
Normal file
@ -0,0 +1,87 @@
|
||||
use anyhow::Error;
|
||||
use crate::sampler::{Sample, Sampler};
|
||||
use crate::surface::Surface;
|
||||
use crate::Vector;
|
||||
|
||||
pub trait Renderer {
|
||||
fn render(&mut self, step: f32);
|
||||
fn present(&mut self) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
pub struct SamplerRenderer {
|
||||
surface: Box<dyn Surface>,
|
||||
sampler: Box<dyn Sampler>,
|
||||
}
|
||||
|
||||
impl SamplerRenderer {
|
||||
pub fn new(surface: Box<dyn Surface>,
|
||||
sampler: Box<dyn Sampler>) -> Self {
|
||||
Self { surface, sampler }
|
||||
}
|
||||
}
|
||||
|
||||
impl Renderer for SamplerRenderer {
|
||||
fn render(&mut self, step: f32) {
|
||||
for x in 0..self.surface.width() {
|
||||
for y in 0..self.surface.height() {
|
||||
let pos = Vector::from_terminal(x, y);
|
||||
let sample = self.sampler.sample(step, pos);
|
||||
|
||||
match sample {
|
||||
Sample::Keep => (),
|
||||
Sample::Draw { char, color } => self.surface.draw(x, y, char, color),
|
||||
Sample::Clear => self.surface.clear(x, y),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn present(&mut self) -> Result<(), Error> {
|
||||
self.surface.present()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crossterm::style::*;
|
||||
use mockall::predicate::*;
|
||||
use super::*;
|
||||
use crate::surface::MockSurface;
|
||||
use crate::sampler::MockSampler;
|
||||
|
||||
#[test]
|
||||
fn render() {
|
||||
let mut surface = Box::new(MockSurface::new());
|
||||
let mut sampler = Box::new(MockSampler::new());
|
||||
|
||||
sampler.expect_sample().withf(|_, pos| pos.x == 0.0 && pos.y == 0.0).returning(|_,_| Sample::Clear);
|
||||
sampler.expect_sample().withf(|_, pos| pos.x == 1.0 && pos.y == 0.0).returning(|_,_| Sample::Keep);
|
||||
sampler.expect_sample().withf(|_, pos| pos.x == 0.0 && pos.y == 2.0).returning(|_,_| Sample::Draw { char: 'a', color: Color::Red });
|
||||
sampler.expect_sample().withf(|_, pos| pos.x == 1.0 && pos.y == 2.0).returning(|_,_| Sample::Keep);
|
||||
sampler.expect_sample().withf(|_, pos| pos.x == 0.0 && pos.y == 4.0).returning(|_,_| Sample::Draw { char: 'x', color: Color::Yellow });
|
||||
sampler.expect_sample().withf(|_, pos| pos.x == 1.0 && pos.y == 4.0).returning(|_,_| Sample::Clear);
|
||||
|
||||
surface.expect_width().return_const(2 as usize);
|
||||
surface.expect_height().return_const(3 as usize);
|
||||
surface.expect_clear().once().with(eq(0), eq(0)).return_const(());
|
||||
surface.expect_draw().once().with(eq(0), eq(1), eq('a'), eq(Color::Red)).return_const(());
|
||||
surface.expect_draw().once().with(eq(0), eq(2), eq('x'), eq(Color::Yellow)).return_const(());
|
||||
surface.expect_clear().once().with(eq(1), eq(2)).return_const(());
|
||||
|
||||
let mut renderer = SamplerRenderer::new(surface, sampler);
|
||||
|
||||
renderer.render(0.5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn present() {
|
||||
let mut surface = Box::new(MockSurface::new());
|
||||
let sampler = Box::new(MockSampler::new());
|
||||
|
||||
surface.expect_present().once().returning(|| Ok(()));
|
||||
|
||||
let mut renderer = SamplerRenderer::new(surface, sampler);
|
||||
|
||||
renderer.present().unwrap();
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
use crossterm::style::Color;
|
||||
use mockall::automock;
|
||||
use crate::animation::Animation;
|
||||
use crate::char::CharSampler;
|
||||
use crate::color::ColorSampler;
|
||||
@ -11,6 +12,7 @@ pub enum Sample {
|
||||
Clear,
|
||||
}
|
||||
|
||||
#[automock]
|
||||
pub trait Sampler {
|
||||
fn sample(&self, step: f32, pos: Vector) -> Sample;
|
||||
}
|
||||
|
@ -3,9 +3,11 @@ use crossterm::cursor::MoveTo;
|
||||
use crossterm::{ExecutableCommand, QueueableCommand};
|
||||
use crossterm::style::{Color, Print, SetForegroundColor};
|
||||
use crossterm::terminal::{Clear, ClearType};
|
||||
use mockall::automock;
|
||||
use std::io::Write;
|
||||
use crate::array::Array2D;
|
||||
|
||||
#[automock]
|
||||
pub trait Surface {
|
||||
fn width(&self) -> usize;
|
||||
fn height(&self) -> usize;
|
||||
|
Loading…
Reference in New Issue
Block a user