Render simulations to the terminal and to disk simultaneously

This commit is contained in:
2020-09-05 17:43:51 -07:00
parent 861d7430e2
commit fc14961d32
3 changed files with 39 additions and 9 deletions

View File

@@ -26,7 +26,9 @@ fn main() {
}
let mut step = 0u64;
let mut renderer = render::Y4MRenderer::new("test.y4m");
let mut renderer = render::MultiRenderer::new()
.with(render::Y4MRenderer::new("em_reflection.y4m"))
.with(render::ColorTermRenderer);
loop {
step += 1;
let imp = if step < 50 {
@@ -43,6 +45,6 @@ fn main() {
}
renderer.render(&state);
state.step();
thread::sleep(time::Duration::from_millis(67));
//thread::sleep(time::Duration::from_millis(67));
}
}

View File

@@ -45,7 +45,9 @@ fn main() {
}
}
let mut renderer = render::ColorTermRenderer;
let mut renderer = render::MultiRenderer::new()
.with(render::Y4MRenderer::new("ferromagnet.y4m"))
.with(render::ColorTermRenderer);
loop {
//let imp = match state.step_no() {
// 20..=60 => 1e6,
@@ -66,7 +68,7 @@ fn main() {
state.impulse_ey(x, y, imp as _);
}
}
if state.step_no() % 10 == 0 {
if state.step_no() % 1 == 0 {
renderer.render(&state);
thread::sleep(time::Duration::from_millis(33));
}

View File

@@ -128,7 +128,12 @@ impl ImageRenderExt for RgbImage {
}
pub trait Renderer {
fn render(&mut self, state: &SimState);
fn render(&mut self, state: &SimState) {
self.render_with_image(state, &state.to_image());
}
fn render_with_image(&mut self, state: &SimState, _im: &RgbImage) {
self.render(state);
}
}
pub struct NumericTermRenderer;
@@ -154,9 +159,8 @@ impl Renderer for NumericTermRenderer {
pub struct ColorTermRenderer;
impl Renderer for ColorTermRenderer {
fn render(&mut self, state: &SimState) {
fn render_with_image(&mut self, state: &SimState, im: &RgbImage) {
let square = "";
let im = state.to_image();
let buf: String = im
.enumerate_rows()
.map(|(_y, row)| {
@@ -185,8 +189,7 @@ impl Y4MRenderer {
}
impl Renderer for Y4MRenderer {
fn render(&mut self, state: &SimState) {
let im = state.to_image();
fn render_with_image(&mut self, _state: &SimState, im: &RgbImage) {
if self.encoder.is_none() {
let writer = File::create(&self.out_path).unwrap();
self.encoder = Some(y4m::encode(im.width() as usize, im.height() as usize, y4m::Ratio::new(30, 1))
@@ -216,3 +219,26 @@ impl Renderer for Y4MRenderer {
enc.write_frame(&frame).unwrap()
}
}
#[derive(Default)]
pub struct MultiRenderer {
renderers: Vec<Box<dyn Renderer>>,
}
impl MultiRenderer {
pub fn new() -> Self {
Default::default()
}
pub fn with<R: Renderer + 'static>(mut self, r: R) -> Self {
self.renderers.push(Box::new(r));
self
}
}
impl Renderer for MultiRenderer {
fn render_with_image(&mut self, state: &SimState, im: &RgbImage) {
for r in &mut self.renderers {
r.render_with_image(state, im);
}
}
}