From 351b8e95074b166cc7ab1d8044fa5a8c62bb21e6 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Mon, 22 Feb 2021 22:12:35 -0800 Subject: [PATCH] refactor sdl into lib observer. fix warns --- src/lib.rs | 87 ++++++++++++++++++++++++++++++++++++++++------------- src/life.rs | 12 +++----- src/main.rs | 53 ++------------------------------ 3 files changed, 74 insertions(+), 78 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d6f86db..d4a62ad 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,8 +3,8 @@ use sdl2::pixels::Color; use sdl2::video::Window; use sdl2::rect::Rect; - -use std::cmp; +use std::{thread, time}; +use std::time::{SystemTime}; pub mod life; @@ -38,43 +38,88 @@ impl Grid #[derive(Clone)] -pub struct Cell { +pub struct Patch { pub color: Color, } pub trait Engine { - fn evolve(&mut self) -> Grid; + fn evolve(&mut self) -> Grid; } pub struct Observer { - pub px_size: i32, - pub canvas: Canvas, + px_size: i32, + canvas: Canvas, + sdl_context: sdl2::Sdl, + render_grid: Grid, } impl Observer { - pub fn new(px_size: i32, canvas: Canvas) -> Observer { - Observer { px_size: px_size, canvas: canvas } + pub fn new(px_size: i32, num_patches: u32) -> Observer { + let size: usize = (num_patches/px_size as u32) as usize; + println!("Window: {}x{} at {} px per cell", num_patches, num_patches, px_size); + + let sdl_context = sdl2::init().unwrap(); + let video_subsystem = sdl_context.video().unwrap(); + let window = video_subsystem.window("Microworlds", num_patches, num_patches).build().unwrap(); + // setup initial black render grid + let render_grid = Grid::new(Patch {color: BLACK}, size); + + + // Let's create a Canvas which we will use to draw in our Window + let canvas : Canvas = window.into_canvas() + .present_vsync() //< this means the screen cannot + // render faster than your display rate (usually 60Hz or 144Hz) + .build().unwrap(); + + + Observer { px_size: px_size, canvas: canvas, sdl_context: sdl_context, render_grid: render_grid } } - pub fn render(&mut self, grid: Grid) { + pub fn sim(&mut self, mut engine: Box, steps_per_sec: u64) { + let mut frame = 0; + let mut event_pump = self.sdl_context.event_pump().unwrap(); + let period = time::Duration::from_millis(1000 / steps_per_sec); + 'main: loop { + for event in event_pump.poll_iter() { + match event { + sdl2::event::Event::Quit {..} => break 'main, + _ => {}, + } + } + + let start_rend = SystemTime::now(); + self.render(); + let render_time = start_rend.elapsed().unwrap(); + let start_evo = SystemTime::now(); + self.render_grid = engine.evolve(); + let evo_time = start_evo.elapsed().unwrap(); + let total_time = start_rend.elapsed().unwrap(); + frame += 1; + println!("frame: {} - render time: {:?} | evolve time: {:?} | total time: {:?}", frame, render_time, evo_time, total_time); + + if total_time < period { + thread::sleep(period - total_time); + } + } + } + + fn render(&mut self) { self.canvas.set_draw_color(BLACK); self.canvas.clear(); - for y in 0..grid.size() { - for x in 0..grid.size() { - self.canvas.set_draw_color(grid.get(y, x).color); - self.canvas.fill_rect(Rect::new(x as i32 * self.px_size, y as i32 * self.px_size, self.px_size as u32, self.px_size as u32)); + for y in 0..self.render_grid.size() { + for x in 0..self.render_grid.size() { + self.canvas.set_draw_color(self.render_grid.get(y, x).color); + match self.canvas.fill_rect(Rect::new(x as i32 * self.px_size, y as i32 * self.px_size, self.px_size as u32, self.px_size as u32)) { + Ok(()) => (), + Err(err) => { + println!("Error on canvas.fill_rect: {}", err); + return; + } + }; } } - /* - for (y, row) in grid.iter().enumerate() { - for (x, cell) in row.iter().enumerate() { - rectangle( cell.color, rectangle::square((x as u32 * px_size) as f64, (y as u32 * px_size) as f64, px_size as f64), c.transform, gl) - } - }*/ - - self.canvas.present(); } } \ No newline at end of file diff --git a/src/life.rs b/src/life.rs index 5e0cb0a..cca506a 100644 --- a/src/life.rs +++ b/src/life.rs @@ -1,6 +1,4 @@ -use std::cmp; - -use super::{Cell, Engine, Grid, WHITE, BLACK}; +use super::{Patch, Engine, Grid, WHITE, BLACK}; pub struct LifeEngine { grid: Grid, @@ -75,8 +73,8 @@ impl LifeEngine { } impl Engine for LifeEngine { - fn evolve(&mut self) -> super::Grid { - let mut new_render_grid = super::Grid::new(Cell{color: BLACK}, self.grid.size()); + fn evolve(&mut self) -> super::Grid { + let mut new_render_grid = super::Grid::new(Patch {color: BLACK}, self.grid.size()); let mut new_life_grid = Grid::new(false, self.grid.size()); for y in 0..self.grid.size() { @@ -85,11 +83,11 @@ impl Engine for LifeEngine { if *self.grid.get(y, x) { if nalive == 2 || nalive == 3 { - new_render_grid.set(y, x, Cell{color: WHITE}); + new_render_grid.set(y, x, Patch {color: WHITE}); new_life_grid.set(y, x, true); } } else if nalive == 3 { - new_render_grid.set(y, x, Cell{color: WHITE}); + new_render_grid.set(y, x, Patch {color: WHITE}); new_life_grid.set(y, x, true); } } diff --git a/src/main.rs b/src/main.rs index 9995035..875e9dd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,4 @@ - use clap::{App, Arg}; -use sdl2::render::Canvas; -use sdl2::video::Window; - -use std::{thread, time}; -use std::time::{SystemTime}; - -use microworlds::Engine; -use microworlds::Grid; pub const SCREEN_SIZE_DEFAULT: u32 = 800; pub const PX_SIZE_DEFAULT: u32 = 2; @@ -58,7 +49,7 @@ fn main() { }; let size: usize = (num_patches/px_size) as usize; - let mut engine; + let engine; match matches.value_of("engine") { Some(arg) => match arg { @@ -74,45 +65,7 @@ fn main() { } } - let sdl_context = sdl2::init().unwrap(); - let video_subsystem = sdl_context.video().unwrap(); - let window = video_subsystem.window("Microworlds", num_patches, num_patches).build().unwrap(); - println!("Window: {}x{} at {} px per cell", num_patches, num_patches, px_size); - let mut render_grid = Grid::new(microworlds::Cell{color: microworlds::BLACK}, size); - + let mut observer= microworlds::Observer::new(px_size as i32, num_patches); println!("cell grid: {}x{} ({} cells) - {} steps per sec", size, size, (size*size), steps); - - - // Let's create a Canvas which we will use to draw in our Window - let canvas : Canvas = window.into_canvas() - .present_vsync() //< this means the screen cannot - // render faster than your display rate (usually 60Hz or 144Hz) - .build().unwrap(); - - let mut renderer= microworlds::Observer::new(px_size as i32, canvas); - let mut frame = 0; - let mut event_pump = sdl_context.event_pump().unwrap(); - let period = time::Duration::from_millis(1000 / steps); - 'main: loop { - for event in event_pump.poll_iter() { - match event { - sdl2::event::Event::Quit {..} => break 'main, - _ => {}, - } - } - - let start_rend = SystemTime::now(); - renderer.render(render_grid); - let render_time = start_rend.elapsed().unwrap(); - let start_evo = SystemTime::now(); - render_grid = engine.evolve(); - let evo_time = start_evo.elapsed().unwrap(); - let total_time = start_rend.elapsed().unwrap(); - frame += 1; - println!("frame: {} - render time: {:?} | evolve time: {:?} | total time: {:?}", frame, render_time, evo_time, total_time); - - if total_time < period { - thread::sleep(period - total_time); - } - } + observer.sim(engine, steps); }