wipe/src/render.rs

95 lines
3.2 KiB
Rust
Raw Normal View History

2022-04-09 14:07:49 +00:00
use anyhow::Error;
use crate::sampler::{Sample, Sampler};
use crate::surface::Surface;
use crate::Vector;
2022-04-11 18:27:38 +00:00
#[cfg(test)]
2022-04-09 15:49:21 +00:00
use mockall::automock;
2022-04-15 05:42:01 +00:00
/// A trait for anything which performs some rendering.
2022-04-11 18:27:38 +00:00
#[cfg_attr(test, automock)]
2022-04-09 14:07:49 +00:00
pub trait Renderer {
2022-04-15 05:42:01 +00:00
/// Render the frame.
2022-04-09 14:07:49 +00:00
fn render(&mut self, step: f32);
2022-04-15 05:42:01 +00:00
/// Present the finished frame.
2022-04-09 14:07:49 +00:00
fn present(&mut self) -> Result<(), Error>;
}
2022-04-15 05:42:01 +00:00
/// Fills its [Surface] with the values received from a [Sampler].
2022-04-09 15:12:34 +00:00
pub struct SamplerRenderer<TSurface, TSampler> {
surface: TSurface,
sampler: TSampler,
2022-04-09 14:07:49 +00:00
}
2022-04-09 15:12:34 +00:00
impl<T1, T2> SamplerRenderer<T1, T2> {
pub fn new(surface: T1, sampler: T2) -> Self {
2022-04-09 14:07:49 +00:00
Self { surface, sampler }
}
}
2022-04-09 15:12:34 +00:00
impl<T1: Surface, T2: Sampler> Renderer for SamplerRenderer<T1, T2> {
2022-04-09 14:07:49 +00:00
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() {
2022-04-09 15:12:34 +00:00
let mut surface = MockSurface::new();
let mut sampler = MockSampler::new();
2022-04-09 14:07:49 +00:00
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() {
2022-04-09 15:12:34 +00:00
let mut surface = MockSurface::new();
let sampler = MockSampler::new();
2022-04-09 14:07:49 +00:00
surface.expect_present().once().returning(|| Ok(()));
let mut renderer = SamplerRenderer::new(surface, sampler);
renderer.present().unwrap();
}
}