diff --git a/README.md b/README.md index 747cf78..8d3cd2f 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,6 @@ cargo run To exit the simulation, press q, ESC or Ctrl+c. -## Using as a library - -`src/main.rs` is a pretty minimal example of the currently exposed high-level functionality. `gntag::actor` includes simpler actor iplementations and all the types, `gntag::world` contains `ActualWorld` and `WorldState`. - ## Tests A few tests can be run with: diff --git a/benches/benchmark.rs b/benches/benchmark.rs index 78d990e..ce51364 100644 --- a/benches/benchmark.rs +++ b/benches/benchmark.rs @@ -1,5 +1,16 @@ use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; -use gntag::get_world; +use gntag::agent::{Agent, SimpleAgent}; +use gntag::world::ActualWorld; + +fn get_world(width: isize, spacing: usize, validate: bool) -> ActualWorld { + let mut agents = vec![]; + for x in (0..width).step_by(spacing) { + for y in (0..width).step_by(spacing) { + agents.push(((x, y).into(), Box::new(SimpleAgent) as Box)); + } + } + ActualWorld::new((width, width).into(), agents, validate) +} fn world(c: &mut Criterion) { let mut group = c.benchmark_group("world"); @@ -10,7 +21,7 @@ fn world(c: &mut Criterion) { BenchmarkId::new("validating", spacing), &spacing, |b, &spacing| { - let mut world = get_world(width, width, spacing as usize, true); + let mut world = get_world(width, spacing as usize, true); b.iter(|| world.do_step()); }, ); @@ -18,7 +29,7 @@ fn world(c: &mut Criterion) { BenchmarkId::new("non-validating", spacing), &spacing, |b, &spacing| { - let mut world = get_world(width, width, spacing as usize, false); + let mut world = get_world(width, spacing as usize, false); b.iter(|| world.do_step()); }, ); diff --git a/src/agent.rs b/src/agent.rs index 7cd68f7..260a922 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -110,7 +110,7 @@ fn random_move_within( loop { let mv = random_move(); if let Move::TryMove(Direction { x, y }) = mv { - if top + y >= 0 && bottom - y >= 0 && left + x >= 0 && right - x >= 0 { + if top + y > 0 && bottom - y > 0 && left + x > 0 && right - x > 0 { return mv; } } diff --git a/src/lib.rs b/src/lib.rs index 6e4f78e..53a7904 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,67 +1,3 @@ pub mod agent; pub mod view; pub mod world; - -use agent::{Agent, SimpleAgent}; -use std::error::Error; -use std::io; -use std::io::Read; -use std::process::exit; -use std::sync::{Arc, Mutex}; -use std::thread; -use view::{RawTerminal, TerminalView, TermionBackend}; -use world::ActualWorld; - -pub fn get_world(width: isize, height: isize, spacing: usize, validating: bool) -> ActualWorld { - let mut agents: Vec<(_, Box)> = vec![]; - for x in (0..width).step_by(spacing) { - for y in (0..height).step_by(spacing) { - agents.push(((x, y).into(), Box::new(SimpleAgent))); - } - } - ActualWorld::new((width, height).into(), agents, validating) -} - -pub type DefaultView = Arc>>>>>; -pub fn get_view() -> DefaultView { - let view = Arc::new(Mutex::new(Some(TerminalView::try_new().unwrap()))); - - // Exit on q, ESC and Ctrl-C and reset terminal - let view2 = view.clone(); - thread::spawn(move || { - let stdin = io::stdin(); - for byte in stdin.bytes().flatten() { - if byte == b'q' || byte == 0x1b || byte == 0x03 { - if let Ok(mut view) = view2.lock() { - *view = None; // drop view - println!("\n"); - } - exit(0); - } - } - }); - view -} - -pub fn draw_world( - world: &ActualWorld, - gen: usize, - view: &DefaultView, -) -> Result> { - (*view.lock().unwrap()).as_mut().unwrap().draw( - gen, - world - .state - .agent_positions - .get(&world.state.tagged) - .map(|pos| (pos.x, pos.y)) - .unwrap(), - world - .state - .agent_positions - .iter() - .map(|(_id, pos)| (pos.x, pos.y)) - .collect::>() - .as_ref(), - ) -} diff --git a/src/main.rs b/src/main.rs index 777bc82..8cb1afe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,24 +1,71 @@ -use gntag::{draw_world, get_view, get_world, DefaultView}; +use gntag::agent::{Agent, SimpleAgent}; +use gntag::view::{Backend, TerminalView}; +use gntag::world::ActualWorld; +use std::io; +use std::io::Read; +use std::process::exit; +use std::sync::{Arc, Mutex}; +use std::thread; fn main() { - let view = get_view(); + let view = Arc::new(Mutex::new(Some(TerminalView::try_new().unwrap()))); + + // Exit on q, ESC and Ctrl-C and reset terminal + let view2 = view.clone(); + thread::spawn(move || { + let stdin = io::stdin(); + for byte in stdin.bytes().flatten() { + if byte == b'q' || byte == 0x1b || byte == 0x03 { + if let Ok(mut view) = view2.lock() { + *view = None; // drop view + println!("\n"); + } + exit(0); + } + } + }); loop { run_simulation(&view); } } -fn run_simulation(view: &DefaultView) { +fn run_simulation(view: &Arc>>>) { let (width, height) = (*view.lock().unwrap()) .as_mut() .unwrap() .content_size() .unwrap(); - let mut world = get_world(width, height, 10, true); + let mut agents: Vec<(_, Box)> = vec![]; + for x in (0..width).step_by(10) { + for y in (0..height).step_by(10) { + agents.push(((x, y).into(), Box::new(SimpleAgent))); + } + } + let mut world = ActualWorld::new((width, height).into(), agents, true); let mut gen = 0; loop { - let resized = draw_world(&world, gen, view).unwrap(); + let resized = (*view.lock().unwrap()) + .as_mut() + .unwrap() + .draw( + gen, + world + .state + .agent_positions + .get(&world.state.tagged) + .map(|pos| (pos.x, pos.y)) + .unwrap(), + world + .state + .agent_positions + .iter() + .map(|(_id, pos)| (pos.x, pos.y)) + .collect::>() + .as_ref(), + ) + .unwrap(); if resized { return; }; diff --git a/src/view.rs b/src/view.rs index 8aa8a21..5fb7290 100644 --- a/src/view.rs +++ b/src/view.rs @@ -2,10 +2,9 @@ use std::convert::TryInto; use std::error::Error; use std::io::{stdout, Stdout, Write}; use termion::clear; -use termion::raw::IntoRawMode; -pub use termion::raw::RawTerminal; -use tui::backend::Backend; -pub use tui::backend::TermionBackend; +use termion::raw::{IntoRawMode, RawTerminal}; +pub use tui::backend::Backend; +use tui::backend::TermionBackend; use tui::layout::{Alignment, Constraint, Direction, Layout, Rect}; use tui::style::{Color, Modifier, Style}; use tui::text::{Span, Spans}; diff --git a/src/world.rs b/src/world.rs index 6633052..581d006 100644 --- a/src/world.rs +++ b/src/world.rs @@ -57,12 +57,7 @@ impl ActualWorld { self_id: *id, tagged_by: self.state.tagged_by, tagged: self.state.tagged, - bounds_distance: ( - pos.y, - self.size.x - pos.x - 1, - self.size.y - pos.y - 1, - pos.x, - ), + bounds_distance: (pos.y, self.size.x - pos.x, self.size.y - pos.y, pos.x), other_agents: &mut self .state .agent_positions @@ -128,9 +123,9 @@ impl ActualWorld { assert!(dir.y.abs() <= 1); let pos = self.state.agent_positions.get(&id).unwrap(); let size = &self.size; - assert!(pos.x + dir.x >= 0); + assert!(pos.x + dir.x > 0); assert!(pos.x + dir.x < size.x); - assert!(pos.y + dir.y >= 0); + assert!(pos.y + dir.y > 0); assert!(pos.y + dir.y < size.y); } }