refactor engine and renderer, now life is a drop in engine
This commit is contained in:
		
							parent
							
								
									4da6c7caa6
								
							
						
					
					
						commit
						6381d02fb9
					
				
							
								
								
									
										58
									
								
								src/lib.rs
								
								
								
								
							
							
						
						
									
										58
									
								
								src/lib.rs
								
								
								
								
							|  | @ -0,0 +1,58 @@ | |||
| use sdl2::render::Canvas; | ||||
| use sdl2::pixels::Color; | ||||
| use sdl2::video::Window; | ||||
| use sdl2::rect::Rect; | ||||
| 
 | ||||
| 
 | ||||
| use std::cmp; | ||||
| 
 | ||||
| pub mod life; | ||||
| 
 | ||||
| pub const BLACK: Color =  Color::RGB(0, 0, 0); | ||||
| pub const WHITE: Color =  Color::RGB(255, 255, 255); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub struct Cell { | ||||
|     pub color: Color, | ||||
| } | ||||
| 
 | ||||
| pub trait Engine { | ||||
|     fn evolve(&mut self) -> Vec<Vec<Cell>>; | ||||
| } | ||||
| 
 | ||||
| pub struct Renderer { | ||||
|     pub px_size: i32, | ||||
|     pub canvas: Canvas<Window>, | ||||
| } | ||||
| 
 | ||||
| impl Renderer { | ||||
|     pub fn new(px_size: i32, canvas: Canvas<Window>) -> Renderer { | ||||
|         Renderer { px_size: px_size, canvas: canvas } | ||||
|     } | ||||
| 
 | ||||
|     pub fn render(&mut self, grid: &Vec<Vec<Cell>>) { | ||||
|         self.canvas.set_draw_color(BLACK); | ||||
|         self.canvas.clear(); | ||||
| 
 | ||||
|         for y in 0..grid.len() { | ||||
|             for x in 0..grid[y].len() { | ||||
|                 //if grid[y][x].alive {
 | ||||
|                 self.canvas.set_draw_color(grid[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, 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(); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,75 @@ | |||
| use std::cmp; | ||||
| 
 | ||||
| use super::{Cell, Engine, WHITE, BLACK}; | ||||
| 
 | ||||
| pub struct LifeEngine { | ||||
|     grid: Vec<Vec<bool>>, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| pub fn new(size: usize) -> LifeEngine { | ||||
|     let mut life = LifeEngine{grid: vec![vec![false; size]; size]}; | ||||
| 
 | ||||
|     // r pemento
 | ||||
|     let centery = size/2; | ||||
|     let centerx = size/2; | ||||
| 
 | ||||
|     life.grid[centery][centerx] = true; | ||||
|     life.grid[centery+1][centerx] =  true; | ||||
|     life.grid[centery-1][centerx] = true; | ||||
| 
 | ||||
|     life.grid[centery-1][centerx-1] =  true; | ||||
|     life.grid[centery][centerx+1] = true; | ||||
| 
 | ||||
|     life | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| impl Engine for LifeEngine { | ||||
|     fn evolve(&mut self) -> Vec<Vec<Cell>> { | ||||
|         let mut new_render_grid = vec![vec![Cell{color: BLACK}; self.grid.len()]; self.grid.len()]; | ||||
|         let mut new_life_grid = vec![vec![false; self.grid.len()]; self.grid.len()]; | ||||
| 
 | ||||
|         for y in 0..self.grid.len() { | ||||
|             for x in 0..self.grid[y].len() { | ||||
|                 let mut nalive = 0; | ||||
| 
 | ||||
|                 let mut ylow = 0; | ||||
|                 if y > 1 { | ||||
|                     ylow = y-1; | ||||
|                 } | ||||
|                 let yhigh = cmp::min(self.grid.len()-1, y+1); | ||||
| 
 | ||||
|                 let mut xlow = 0; | ||||
|                 if x > 1 { | ||||
|                     xlow = x-1; | ||||
|                 } | ||||
|                 let xhigh =  cmp::min(self.grid.len()-1, x+1); | ||||
| 
 | ||||
|                 for i in ylow..yhigh+1 { | ||||
|                     for j in xlow..xhigh+1 { | ||||
|                         if i == y && j == x { | ||||
|                             continue; | ||||
|                         } | ||||
|                         if self.grid[i][j] { | ||||
|                             nalive += 1; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if self.grid[y][x] { | ||||
|                     if nalive == 2 || nalive == 3 { | ||||
|                         new_render_grid[y][x] = Cell{color: WHITE}; | ||||
|                         new_life_grid[y][x] = true; | ||||
|                     } | ||||
|                 } else if nalive == 3 { | ||||
|                     new_render_grid[y][x] = Cell{color: WHITE}; | ||||
|                     new_life_grid[y][x] = true; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         self.grid = new_life_grid; | ||||
|         new_render_grid | ||||
|     } | ||||
| } | ||||
							
								
								
									
										143
									
								
								src/main.rs
								
								
								
								
							
							
						
						
									
										143
									
								
								src/main.rs
								
								
								
								
							|  | @ -1,134 +1,26 @@ | |||
| 
 | ||||
| use sdl2::render::Canvas; | ||||
| use sdl2::pixels::Color; | ||||
| use sdl2::video::Window; | ||||
| use sdl2::rect::Rect; | ||||
| 
 | ||||
| 
 | ||||
| use std::cmp; | ||||
| use std::{thread, time}; | ||||
| use std::time::{Duration, SystemTime}; | ||||
| use std::time::{SystemTime}; | ||||
| 
 | ||||
| use microworlds::Engine; | ||||
| 
 | ||||
| pub const SCREEN_SIZE: u32 = 800; | ||||
| pub const PX_SIZE: u32 = 2; | ||||
| pub const BLACK: Color =  Color::RGB(0, 0, 0); | ||||
| pub const WHITE: Color =  Color::RGB(255, 255, 255); | ||||
| 
 | ||||
| pub trait Cell { | ||||
|     fn color(&self) -> [f32; 4]; | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub struct ConwayCell { | ||||
|     color: Color, | ||||
|     alive: bool, | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| impl Cell { | ||||
|     pub fn clone(&self) -> Cell { | ||||
|         Cell{color: self.color} | ||||
|     } | ||||
| }*/ | ||||
| 
 | ||||
| pub struct App { | ||||
|     steps_per_sec: u64, | ||||
|     px_size: i32, | ||||
|     grid: Vec<Vec<ConwayCell>>, | ||||
|     canvas: Canvas<Window>, | ||||
| } | ||||
| 
 | ||||
| impl App { | ||||
|     fn render (&mut self) { | ||||
| 
 | ||||
|         self.canvas.set_draw_color(Color::RGB(0, 0, 0)); | ||||
|         self.canvas.clear(); | ||||
| 
 | ||||
|         for y in 0..self.grid.len() { | ||||
|             for x in 0..self.grid[y].len() { | ||||
|                 if self.grid[y][x].alive { | ||||
|                     self.canvas.set_draw_color(self.grid[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, 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(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     fn evolve(&mut self) { | ||||
|         let mut new_grid = vec![vec![ConwayCell{color: BLACK, alive: false}; self.grid.len()]; self.grid.len()]; | ||||
| 
 | ||||
|         for y in 0..self.grid.len() { | ||||
|             for x in 0..self.grid[y].len() { | ||||
|                 let mut nalive = 0; | ||||
| 
 | ||||
|                 let mut ylow = 0; | ||||
|                 if y > 1 { | ||||
|                     ylow = y-1; | ||||
|                 } | ||||
|                 let yhigh = cmp::min(self.grid.len()-1, y+1); | ||||
| 
 | ||||
|                 let mut xlow = 0; | ||||
|                 if x > 1 { | ||||
|                     xlow = x-1; | ||||
|                 } | ||||
|                 let xhigh =  cmp::min(self.grid.len()-1, x+1); | ||||
| 
 | ||||
|                 for i in ylow..yhigh+1 { | ||||
|                     for j in xlow..xhigh+1 { | ||||
|                         if i == y && j == x { | ||||
|                             continue; | ||||
|                         } | ||||
|                         if self.grid[i][j].alive { | ||||
|                             nalive += 1; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if self.grid[y][x].alive { | ||||
|                     if nalive == 2 || nalive == 3 { | ||||
|                         new_grid[y][x] = ConwayCell{color: WHITE, alive: true} | ||||
|                     } | ||||
|                 } else if nalive == 3 { | ||||
|                     new_grid[y][x] = ConwayCell{color: WHITE, alive: true} | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         self.grid = new_grid; | ||||
|     } | ||||
| } | ||||
| pub const STEPS_PER_SEC: u64 = 8; | ||||
| 
 | ||||
| fn main() { | ||||
|     let sdl_context = sdl2::init().unwrap(); | ||||
|     let video_subsystem = sdl_context.video().unwrap(); | ||||
|     let window = video_subsystem.window("Microworlds", SCREEN_SIZE, SCREEN_SIZE).build().unwrap(); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     println!("Window: {}x{} at {} px per cell", SCREEN_SIZE, SCREEN_SIZE, PX_SIZE); | ||||
|     let size: usize = (SCREEN_SIZE/PX_SIZE) as usize; | ||||
|     let mut grid = vec![vec![ConwayCell{color: BLACK, alive: false}; size]; size]; | ||||
|     println!("size:{}", size); | ||||
|     let mut grid = vec![vec![microworlds::Cell{color: microworlds::BLACK}; size]; size]; | ||||
| 
 | ||||
|     // r pemento
 | ||||
|     let centery = size/2; | ||||
|     let centerx = size/2; | ||||
|     println!("centery:{} centerx:{}", centery, centerx); | ||||
|     grid[centery][centerx] = ConwayCell{color: WHITE, alive: true}; | ||||
|     grid[centery+1][centerx] = ConwayCell{color: WHITE, alive: true}; | ||||
|     grid[centery-1][centerx] = ConwayCell{color: WHITE, alive: true}; | ||||
|     println!("cell grid: {}x{} ({} cells) - {} steps per sec", size, size, (size*size), STEPS_PER_SEC); | ||||
| 
 | ||||
|     grid[centery-1][centerx-1] = ConwayCell{color: WHITE, alive: true}; | ||||
|     grid[centery][centerx+1] = ConwayCell{color: WHITE, alive: true}; | ||||
|     let mut engine = microworlds::life::new(size); | ||||
| 
 | ||||
|     // Let's create a Canvas which we will use to draw in our Window
 | ||||
|     let canvas : Canvas<Window> = window.into_canvas() | ||||
|  | @ -136,17 +28,13 @@ fn main() { | |||
|         // render faster than your display rate (usually 60Hz or 144Hz)
 | ||||
|         .build().unwrap(); | ||||
| 
 | ||||
|     let mut app = App { | ||||
|         steps_per_sec: 32, | ||||
|         px_size: PX_SIZE as i32, | ||||
|         grid: grid, | ||||
|         canvas: canvas, | ||||
|     }; | ||||
| 
 | ||||
|     let mut renderer= microworlds::Renderer::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_PER_SEC); | ||||
|     'main: loop { | ||||
|         for event in event_pump.poll_iter() { | ||||
|             match event { | ||||
|  | @ -156,16 +44,17 @@ fn main() { | |||
|         } | ||||
| 
 | ||||
|         let start_rend = SystemTime::now(); | ||||
|         app.render(); | ||||
|         renderer.render(&grid); | ||||
|         let render_time = start_rend.elapsed().unwrap(); | ||||
|         let start_evo = SystemTime::now(); | ||||
|         app.evolve(); | ||||
|         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); | ||||
| 
 | ||||
|         thread::sleep(time::Duration::from_millis(1000 / app.steps_per_sec)); | ||||
|         if total_time < period { | ||||
|             thread::sleep(period - total_time); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue