diff --git a/Cargo.lock b/Cargo.lock index 429308a..1892e76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,6 +15,26 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -45,6 +65,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "cmake" version = "0.1.45" @@ -116,6 +151,15 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "hermit-abi" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +dependencies = [ + "libc", +] + [[package]] name = "khronos_api" version = "3.1.0" @@ -153,6 +197,7 @@ checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" name = "microworlds" version = "0.1.0" dependencies = [ + "clap", "gl", "sdl2", ] @@ -218,6 +263,12 @@ dependencies = [ "version-compare", ] +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "tar" version = "0.4.30" @@ -230,6 +281,15 @@ dependencies = [ "xattr", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thread_local" version = "1.0.1" @@ -239,6 +299,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + [[package]] name = "unidiff" version = "0.3.3" @@ -250,6 +316,12 @@ dependencies = [ "regex", ] +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version-compare" version = "0.0.10" diff --git a/Cargo.toml b/Cargo.toml index fc412d5..1ed54d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,5 +7,6 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -sdl2 = { versoion = "0.34.3", features = ["bundled", "static-link"]} +sdl2 = { version = "0.34.3", features = ["bundled", "static-link"]} gl = "0.14.0" +clap = "2.33.3" diff --git a/src/lib.rs b/src/lib.rs index 9dbfe9a..d6f86db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,14 +46,14 @@ pub trait Engine { fn evolve(&mut self) -> Grid; } -pub struct Renderer { +pub struct Observer { pub px_size: i32, pub canvas: Canvas, } -impl Renderer { - pub fn new(px_size: i32, canvas: Canvas) -> Renderer { - Renderer { px_size: px_size, canvas: canvas } +impl Observer { + pub fn new(px_size: i32, canvas: Canvas) -> Observer { + Observer { px_size: px_size, canvas: canvas } } pub fn render(&mut self, grid: Grid) { @@ -62,10 +62,8 @@ impl Renderer { for y in 0..grid.size() { for x in 0..grid.size() { - //if grid[y][x].alive { 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)); - //} } } diff --git a/src/life.rs b/src/life.rs index 5713134..5e0cb0a 100644 --- a/src/life.rs +++ b/src/life.rs @@ -7,7 +7,7 @@ pub struct LifeEngine { } -pub fn new(size: usize) -> LifeEngine { +pub fn new(size: usize) -> Box { let mut life = LifeEngine{grid: Grid::new(false, size)}; // r pemento @@ -21,7 +21,7 @@ pub fn new(size: usize) -> LifeEngine { life.grid.set(centery-1, centerx-1, true); life.grid.set(centery, centerx+1, true); - life + Box::new(life) } impl LifeEngine { diff --git a/src/main.rs b/src/main.rs index b88987d..9995035 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ + +use clap::{App, Arg}; use sdl2::render::Canvas; use sdl2::video::Window; @@ -7,21 +9,79 @@ use std::time::{SystemTime}; use microworlds::Engine; use microworlds::Grid; -pub const SCREEN_SIZE: u32 = 800; -pub const PX_SIZE: u32 = 2; -pub const STEPS_PER_SEC: u64 = 8; +pub const SCREEN_SIZE_DEFAULT: u32 = 800; +pub const PX_SIZE_DEFAULT: u32 = 2; +pub const STEPS_PER_SEC_DEFAULT: u64 = 8; + fn main() { + let matches = App::new("microworlds") + .version("0.1") + .arg(Arg::with_name("engine") + .long("--engine") + .short("-e") + .help("select the engine to run") + .possible_values(&["life", "simple"]) + .takes_value(true) + .required(true)) + .arg(Arg::with_name("size") + .long("--size") + .help("dimension of square in number of patches") + .takes_value(true) + .default_value("800")) + .arg(Arg::with_name("pixels") + .long("--pixels") + .takes_value(true) + .help("pixels per patch") + .default_value("2")) + .arg(Arg::with_name("steps") + .long("--steps") + .help("steps per second to max out at") + .takes_value(true) + .default_value("8")) + .get_matches(); + + + let px_size = match matches.value_of("pixels") { + Some(arg) => arg.parse().expect("pixels requires a number"), + None => PX_SIZE_DEFAULT, + }; + + let num_patches: u32 = match matches.value_of("size") { + Some(arg) => arg.parse().expect("size requires a number"), + None => SCREEN_SIZE_DEFAULT, + }; + + let steps = match matches.value_of("steps") { + Some(arg) => arg.parse().expect("steps requires a number"), + None => STEPS_PER_SEC_DEFAULT, + }; + + let size: usize = (num_patches/px_size) as usize; + let mut engine; + + match matches.value_of("engine") { + Some(arg) => match arg { + "life" => engine = microworlds::life::new(size), + _ => { + println!("Invalud engine selected: {}", arg); + return; + } + }, + None => { + println!("Engine selection requires"); + return; + } + } + 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 = Grid::new(microworlds::Cell{color: microworlds::BLACK}, size); + 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); - println!("cell grid: {}x{} ({} cells) - {} steps per sec", size, size, (size*size), STEPS_PER_SEC); + println!("cell grid: {}x{} ({} cells) - {} steps per sec", size, size, (size*size), steps); - 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.into_canvas() @@ -29,13 +89,10 @@ fn main() { // render faster than your display rate (usually 60Hz or 144Hz) .build().unwrap(); - let mut renderer= microworlds::Renderer::new( PX_SIZE as i32, canvas); - + 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_PER_SEC); + let period = time::Duration::from_millis(1000 / steps); 'main: loop { for event in event_pump.poll_iter() { match event { @@ -45,10 +102,10 @@ fn main() { } let start_rend = SystemTime::now(); - renderer.render(grid); + renderer.render(render_grid); let render_time = start_rend.elapsed().unwrap(); let start_evo = SystemTime::now(); - grid = engine.evolve(); + render_grid = engine.evolve(); let evo_time = start_evo.elapsed().unwrap(); let total_time = start_rend.elapsed().unwrap(); frame += 1;