finish structopt removal

This commit is contained in:
Dustin Carlino 2019-09-18 17:29:34 -07:00
parent 62d1777433
commit f18fc72265
21 changed files with 140 additions and 213 deletions

View File

@ -18,7 +18,7 @@ impl CmdArgs {
let parts: Vec<&str> = arg.split('=').collect();
if parts.len() == 1 {
if arg.starts_with("--") {
args.bits.insert(arg[2..].to_string());
args.bits.insert(arg);
} else {
args.free.push(arg);
}

View File

@ -5,7 +5,6 @@ use crate::{
MultiKey, ScreenPt, Text, Warper, LINE_HEIGHT,
};
use geom::{Distance, Duration, Polygon, Pt2D};
use std::str::FromStr;
// Pixels
const BAR_WIDTH: f64 = 300.0;
@ -378,7 +377,7 @@ impl SliderWithTextBox {
let line_before = self.tb.get_line().to_string();
match self.tb.event(ctx.input) {
InputResult::Done(line, _) => {
if let Ok(t) = Duration::from_str(&line) {
if let Ok(t) = Duration::parse(&line) {
if t >= self.low && t <= self.high {
return InputResult::Done(line, t);
}
@ -388,7 +387,7 @@ impl SliderWithTextBox {
}
InputResult::StillActive => {
if line_before != self.tb.get_line() {
if let Ok(t) = Duration::from_str(self.tb.get_line()) {
if let Ok(t) = Duration::parse(self.tb.get_line()) {
if t >= self.low && t <= self.high {
self.slider
.set_percent(ctx, (t - self.low) / (self.high - self.low));

View File

@ -23,7 +23,6 @@ rand_xorshift = "0.2.0"
serde = "1.0.98"
serde_derive = "1.0.98"
sim = { path = "../sim" }
structopt = "0.2.18"
[build-dependencies]
walkdir = "2.2.7"

View File

@ -7,7 +7,6 @@ use ezgui::{hotkey, Choice, EventCtx, GfxCtx, Key, Line, ModalMenu, Text, Wizard
use geom::Duration;
use map_model::MapEdits;
use sim::{ABTest, Scenario, SimFlags};
use std::path::PathBuf;
pub struct PickABTest;
impl PickABTest {
@ -165,7 +164,7 @@ fn launch_test(test: &ABTest, ui: &mut UI, ctx: &mut EventCtx) -> ABTestMode {
let mut secondary = PerMapUI::new(
Flags {
sim_flags: SimFlags {
load: PathBuf::from(abstutil::path_map(&test.map_name)),
load: abstutil::path_map(&test.map_name),
rng_seed: current_flags.sim_flags.rng_seed,
run_name: Some(format!("{} with {}", test.test_name, test.edits2_name)),
savestate_every: None,

View File

@ -426,7 +426,7 @@ pub fn apply_map_edits(
bundle.draw_map.lanes[l.0] = DrawLane::new(
bundle.map.get_l(l),
&bundle.map,
!bundle.current_flags.dont_draw_lane_markings,
bundle.current_flags.draw_lane_markings,
cs,
&mut timer,
)

View File

@ -13,15 +13,8 @@ pub struct Game {
}
impl Game {
pub fn new(mut flags: Flags, ctx: &mut EventCtx) -> Game {
if flags.dev {
flags.no_splash = true;
flags.no_textures = true;
flags.sim_flags.rng_seed = Some(42);
}
let splash = !flags.no_splash
&& !format!("{}", flags.sim_flags.load.display()).contains("data/save");
pub fn new(flags: Flags, ctx: &mut EventCtx) -> Game {
let splash = flags.splash && !flags.sim_flags.load.contains("data/save");
let ui = UI::new(flags, ctx, splash);
let states: Vec<Box<dyn State>> = if splash {
vec![Box::new(SplashScreen::new_with_screensaver(ctx, &ui))]

View File

@ -11,10 +11,31 @@ mod splash_screen;
mod tutorial;
mod ui;
use structopt::StructOpt;
use crate::ui::Flags;
use abstutil::CmdArgs;
use sim::SimFlags;
fn main() {
let mut args = CmdArgs::new();
let mut flags = Flags {
sim_flags: SimFlags::from_args(&mut args),
kml: args.optional("--kml"),
draw_lane_markings: !args.enabled("--dont_draw_lane_markings"),
enable_profiler: args.enabled("--enable_profiler"),
num_agents: args
.optional("--num_agents")
.map(|s| s.parse::<usize>().unwrap()),
splash: !args.enabled("--no_splash"),
textures: !args.enabled("--no_textures"),
};
if args.enabled("--dev") {
flags.splash = false;
flags.textures = false;
flags.sim_flags.rng_seed = Some(42);
}
args.done();
ezgui::run("A/B Street", 1800.0, 800.0, |ctx| {
game::Game::new(ui::Flags::from_args(), ctx)
game::Game::new(flags, ctx)
});
}

View File

@ -80,7 +80,7 @@ impl DrawMap {
DrawLane::new(
l,
map,
!flags.dont_draw_lane_markings,
flags.draw_lane_markings,
cs,
// TODO Really parallelize should give us something thread-safe that can at
// least take notes.

View File

@ -12,7 +12,6 @@ use geom::{Duration, Line, Pt2D, Speed};
use map_model::Map;
use rand::Rng;
use rand_xorshift::XorShiftRng;
use std::path::PathBuf;
use std::time::Instant;
pub struct SplashScreen {
@ -169,7 +168,7 @@ fn splash_screen(
ui.save_camera_state(ctx.canvas);
// This retains no state, but that's probably fine.
let mut flags = ui.primary.current_flags.clone();
flags.sim_flags.load = PathBuf::from(abstutil::path_map(&name));
flags.sim_flags.load = abstutil::path_map(&name);
*ui = UI::new(flags, ctx, false);
// TODO want to clear wizard and screensaver as we leave this state.
Some(Transition::Push(Box::new(SandboxMode::new(ctx))))

View File

@ -11,7 +11,6 @@ use map_model::{Map, Traversable};
use rand::seq::SliceRandom;
use serde_derive::{Deserialize, Serialize};
use sim::{GetDrawAgents, Sim, SimFlags, SimOptions};
use structopt::StructOpt;
pub struct UI {
pub primary: PerMapUI,
@ -26,7 +25,7 @@ impl UI {
let cs = ColorScheme::load().unwrap();
let primary = ctx.loading_screen("load map", |ctx, mut timer| {
ctx.set_textures(
!flags.no_textures,
flags.textures,
vec![
("assets/water_texture.png", Color::rgb(170, 211, 223)),
("assets/grass_texture.png", Color::rgb(200, 250, 204)),
@ -431,41 +430,17 @@ impl ShowObject for ShowEverything {
}
}
#[derive(StructOpt, Debug, Clone)]
#[structopt(name = "game")]
#[derive(Clone)]
pub struct Flags {
#[structopt(flatten)]
pub sim_flags: SimFlags,
/// Extra KML or ExtraShapes to display
#[structopt(long = "kml")]
pub kml: Option<String>,
// TODO Ideally these'd be phrased positively, but can't easily make them default to true.
/// Should lane markings be drawn? Sometimes they eat too much GPU memory.
#[structopt(long = "dont_draw_lane_markings")]
pub dont_draw_lane_markings: bool,
/// Enable cpuprofiler?
#[structopt(long = "enable_profiler")]
pub draw_lane_markings: bool,
pub enable_profiler: bool,
/// Number of agents to generate when requested. If unspecified, trips to/from borders will be
/// included.
#[structopt(long = "num_agents")]
// Number of agents to generate when requested. If unspecified, trips to/from borders will be
// included.
pub num_agents: Option<usize>,
/// Don't start with the splash screen and menu
#[structopt(long = "no_splash")]
pub no_splash: bool,
/// Don't upload textures
#[structopt(long = "no_textures")]
pub no_textures: bool,
/// "Dev" mode = --no_splash --no_textures --rng_seed=42
#[structopt(long = "dev")]
pub dev: bool,
pub splash: bool,
pub textures: bool,
}
// All of the state that's bound to a specific map+edit has to live here.

View File

@ -120,12 +120,8 @@ impl Duration {
hours, minutes, seconds, remainder
)
}
}
impl std::str::FromStr for Duration {
type Err = abstutil::Error;
fn from_str(string: &str) -> Result<Duration, Self::Err> {
pub fn parse(string: &str) -> Result<Duration, abstutil::Error> {
let parts: Vec<&str> = string.split(':').collect();
if parts.is_empty() {
return Err(abstutil::Error::new(format!("Duration {}: no :'s", string)));

View File

@ -10,4 +10,3 @@ cpuprofiler = "0.0.3"
geom = { path = "../geom" }
map_model = { path = "../map_model" }
sim = { path = "../sim" }
structopt = "0.2.18"

View File

@ -1,44 +1,29 @@
use abstutil::Timer;
use abstutil::{CmdArgs, Timer};
use geom::Duration;
use sim::{GetDrawAgents, Scenario, SimFlags};
use std::path::Path;
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
#[structopt(name = "headless")]
struct Flags {
#[structopt(flatten)]
sim_flags: SimFlags,
/// Optional time to savestate
#[structopt(long = "save_at")]
save_at: Option<Duration>,
/// Number of agents to generate. If unspecified, trips to/from borders will be included.
#[structopt(long = "num_agents")]
num_agents: Option<usize>,
/// Enable cpuprofiler?
#[structopt(long = "enable_profiler")]
enable_profiler: bool,
/// Every 0.1s, pretend to draw everything to make sure there are no bugs.
#[structopt(long = "paranoia")]
paranoia: bool,
}
fn main() {
let flags = Flags::from_args();
let mut args = CmdArgs::new();
let sim_flags = SimFlags::from_args(&mut args);
let save_at = args
.optional("--save_at")
.map(|s| Duration::parse(&s).unwrap());
let num_agents = args
.optional("--num_agents")
.map(|s| s.parse::<usize>().unwrap());
let enable_profiler = args.enabled("--enable_profiler");
// Every 0.1s, pretend to draw everything to make sure there are no bugs.
let paranoia = args.enabled("--paranoia");
args.done();
let mut timer = Timer::new("setup headless");
let (map, mut sim, mut rng) = sim_flags.load(&mut timer);
// TODO not the ideal way to distinguish what thing we loaded
let load = flags.sim_flags.load.clone();
let mut timer = Timer::new("setup headless");
let (map, mut sim, mut rng) = flags.sim_flags.load(&mut timer);
if load.starts_with(Path::new("../data/raw_maps/"))
|| load.starts_with(Path::new("../data/maps/"))
if sim_flags.load.starts_with("../data/raw_maps/")
|| sim_flags.load.starts_with("../data/maps/")
{
let s = if let Some(n) = flags.num_agents {
let s = if let Some(n) = num_agents {
Scenario::scaled_run(&map, n)
} else {
Scenario::small_run(&map)
@ -47,16 +32,13 @@ fn main() {
}
timer.done();
if flags.enable_profiler {
if enable_profiler {
cpuprofiler::PROFILER
.lock()
.unwrap()
.start("./profile")
.unwrap();
}
let enable_profiler = flags.enable_profiler;
let paranoia = flags.paranoia;
let save_at = flags.save_at;
let timer = Timer::new("run sim until done");
sim.run_until_done(
&map,
@ -77,7 +59,7 @@ fn main() {
);
timer.done();
println!("Done at {}", sim.time());
if flags.enable_profiler && save_at.is_none() {
if enable_profiler && save_at.is_none() {
cpuprofiler::PROFILER.lock().unwrap().stop().unwrap();
}
}

View File

@ -9,4 +9,3 @@ abstutil = { path = "../abstutil" }
geom = { path = "../geom" }
map_model = { path = "../map_model" }
popdat = { path = "../popdat" }
structopt = "0.2.18"

View File

@ -1,31 +1,22 @@
use abstutil::Timer;
use abstutil::{CmdArgs, Timer};
use geom::Duration;
use map_model::Map;
use popdat::trips_to_scenario;
use structopt::StructOpt;
#[derive(StructOpt)]
#[structopt(name = "precompute")]
struct Flags {
/// Map
#[structopt(name = "load")]
load: String,
/// Disable PSRC scenario generation for faster development
#[structopt(name = "disable_psrc_scenarios")]
disable_psrc_scenarios: bool,
}
fn main() {
let flags = Flags::from_args();
let mut timer = Timer::new(&format!("precompute {}", flags.load,));
let mut args = CmdArgs::new();
let load = args.required_free();
let disable_psrc_scenarios = args.enabled("--disable_psrc_scenarios");
args.done();
let map = Map::new(&flags.load, &mut timer).unwrap();
let mut timer = Timer::new(&format!("precompute {}", load));
let map = Map::new(&load, &mut timer).unwrap();
timer.start("save map");
map.save();
timer.stop("save map");
if !flags.disable_psrc_scenarios {
if !disable_psrc_scenarios {
trips_to_scenario(&map, Duration::ZERO, Duration::END_OF_DAY, &mut timer).save();
}
}

View File

@ -14,4 +14,3 @@ rand = "0.7.0"
rand_xorshift = "0.2.0"
serde = "1.0.98"
serde_derive = "1.0.98"
structopt = "0.2.18"

View File

@ -1,45 +1,38 @@
use crate::{Scenario, Sim, SimOptions};
use abstutil;
use abstutil::CmdArgs;
use geom::Duration;
use map_model::{Map, MapEdits};
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use std::path::{Path, PathBuf};
use structopt::StructOpt;
#[derive(StructOpt, Debug, Clone)]
#[structopt(name = "sim_flags")]
#[derive(Clone)]
pub struct SimFlags {
/// Map, scenario, or savestate to load
#[structopt(
name = "load",
parse(from_os_str),
default_value = "../data/maps/montlake.bin"
)]
pub load: PathBuf,
/// Optional RNG seed
#[structopt(long = "rng_seed")]
pub load: String,
pub rng_seed: Option<u8>,
/// Run name for savestating
#[structopt(long = "run_name")]
pub run_name: Option<String>,
/// Regularly save simulation state
#[structopt(long = "savestate_every")]
pub savestate_every: Option<Duration>,
/// Use freeform intersection policy everywhere
#[structopt(long = "freeform_policy")]
pub freeform_policy: bool,
/// Disable block-the-box prevention
#[structopt(long = "disable_block_the_box")]
pub disable_block_the_box: bool,
}
impl SimFlags {
pub fn from_args(args: &mut CmdArgs) -> SimFlags {
SimFlags {
load: args
.optional_free()
.unwrap_or_else(|| "../data/maps/montlake.bin".to_string()),
rng_seed: args
.optional("--rng_seed")
.map(|s| s.parse::<u8>().unwrap()),
run_name: args.optional("--run_name"),
savestate_every: args
.optional("--savestate_every")
.map(|s| Duration::parse(&s).unwrap()),
freeform_policy: args.enabled("--freeform_policy"),
disable_block_the_box: args.enabled("--disable_block_the_box"),
}
}
// TODO rename seattle_test
pub fn for_test(run_name: &str) -> SimFlags {
SimFlags::synthetic_test("montlake", run_name)
@ -47,7 +40,7 @@ impl SimFlags {
pub fn synthetic_test(map: &str, run_name: &str) -> SimFlags {
SimFlags {
load: PathBuf::from(abstutil::path_map(map)),
load: abstutil::path_map(map),
rng_seed: Some(42),
run_name: Some(run_name.to_string()),
savestate_every: None,
@ -78,11 +71,11 @@ impl SimFlags {
disable_block_the_box: self.disable_block_the_box,
};
if self.load.starts_with(Path::new("../data/save/")) {
timer.note(format!("Resuming from {}", self.load.display()));
if self.load.starts_with("../data/save/") {
timer.note(format!("Resuming from {}", self.load));
let sim: Sim = abstutil::read_binary(self.load.to_str().unwrap(), timer)
.expect("loading sim state failed");
let sim: Sim =
abstutil::read_binary(&self.load, timer).expect("loading sim state failed");
let mut map: Map =
abstutil::read_binary(&abstutil::path_map(&sim.map_name), timer).unwrap();
@ -90,14 +83,14 @@ impl SimFlags {
map.recalculate_pathfinding_after_edits(timer);
(map, sim, rng)
} else if self.load.starts_with(Path::new("../data/scenarios/")) {
} else if self.load.starts_with("../data/scenarios/") {
timer.note(format!(
"Seeding the simulation from scenario {}",
self.load.display()
self.load
));
let scenario: Scenario = abstutil::read_binary(self.load.to_str().unwrap(), timer)
.expect("loading scenario failed");
let scenario: Scenario =
abstutil::read_binary(&self.load, timer).expect("loading scenario failed");
let map: Map =
abstutil::read_binary(&abstutil::path_map(&scenario.map_name), timer).unwrap();
@ -110,22 +103,22 @@ impl SimFlags {
scenario.instantiate(&mut sim, &map, &mut rng, timer);
(map, sim, rng)
} else if self.load.starts_with(Path::new("../data/raw_maps/")) {
timer.note(format!("Loading map {}", self.load.display()));
} else if self.load.starts_with("../data/raw_maps/") {
timer.note(format!("Loading map {}", self.load));
let map = Map::new(self.load.to_str().unwrap(), timer)
.expect(&format!("Couldn't load map from {}", self.load.display()));
let map = Map::new(&self.load, timer)
.expect(&format!("Couldn't load map from {}", self.load));
timer.start("create sim");
let sim = Sim::new(&map, opts);
timer.stop("create sim");
(map, sim, rng)
} else if self.load.starts_with(Path::new("../data/maps/")) {
timer.note(format!("Loading map {}", self.load.display()));
} else if self.load.starts_with("../data/maps/") {
timer.note(format!("Loading map {}", self.load));
let map: Map = abstutil::read_binary(self.load.to_str().unwrap(), timer)
.expect(&format!("Couldn't load map from {}", self.load.display()));
let map: Map = abstutil::read_binary(&self.load, timer)
.expect(&format!("Couldn't load map from {}", self.load));
timer.start("create sim");
let sim = Sim::new(&map, opts);
@ -133,7 +126,7 @@ impl SimFlags {
(map, sim, rng)
} else {
panic!("Don't know how to load {}", self.load.display());
panic!("Don't know how to load {}", self.load);
}
}
}

View File

@ -13,5 +13,4 @@ map_model = { path = "../map_model" }
rand = "0.7.0"
rand_xorshift = "0.2.0"
sim = { path = "../sim" }
structopt = "0.2.18"
termion = "1.5.1"

View File

@ -1,6 +1,5 @@
use crate::runner::TestRunner;
use geom::{Duration, Line, PolyLine, Pt2D};
use std::str::FromStr;
#[allow(clippy::unreadable_literal)]
pub fn run(t: &mut TestRunner) {
@ -42,18 +41,12 @@ pub fn run(t: &mut TestRunner) {
});
t.run_fast("time_parsing", |_| {
assert_eq!(Duration::from_str("2.3"), Ok(Duration::seconds(2.3)));
assert_eq!(Duration::from_str("02.3"), Ok(Duration::seconds(2.3)));
assert_eq!(Duration::from_str("00:00:02.3"), Ok(Duration::seconds(2.3)));
assert_eq!(Duration::parse("2.3"), Ok(Duration::seconds(2.3)));
assert_eq!(Duration::parse("02.3"), Ok(Duration::seconds(2.3)));
assert_eq!(Duration::parse("00:00:02.3"), Ok(Duration::seconds(2.3)));
assert_eq!(
Duration::from_str("00:02:03.5"),
Ok(Duration::seconds(123.5))
);
assert_eq!(
Duration::from_str("01:02:03.5"),
Ok(Duration::seconds(3723.5))
);
assert_eq!(Duration::parse("00:02:03.5"), Ok(Duration::seconds(123.5)));
assert_eq!(Duration::parse("01:02:03.5"), Ok(Duration::seconds(3723.5)));
});
}

View File

@ -7,10 +7,27 @@ mod sim_determinism;
mod transit;
mod trips;
use structopt::StructOpt;
use abstutil::CmdArgs;
fn main() {
let mut t = runner::TestRunner::new(runner::Flags::from_args());
let mut args = CmdArgs::new();
let flags = runner::Flags {
filter: match args.optional("--filter") {
Some(x) => match x.as_str() {
"All" => runner::Filter::All,
"Slow" => runner::Filter::Slow,
"Fast" => runner::Filter::Fast,
_ => panic!("Bad --filter={}", x),
},
None => runner::Filter::All,
},
test_names: args.optional("--test_names"),
keep_output: args.enabled("--keep_output"),
clickable_links: args.enabled("--clickable_links"),
};
args.done();
let mut t = runner::TestRunner::new(flags);
geom::run(t.suite("geom"));
map_conversion::run(t.suite("map_conversion"));

View File

@ -1,35 +1,22 @@
// https://github.com/rust-lang/rust/issues/50297 would hopefully obsolete this approach.
use abstutil;
use abstutil::Error;
use gag::Redirect;
use map_model::{BuildingID, LaneID};
use rand_xorshift::XorShiftRng;
use sim::{CarID, ParkingSpot, Scenario, Sim};
use std;
use std::io::Write;
use structopt::StructOpt;
use termion;
use termion::color;
#[derive(StructOpt)]
#[structopt(name = "tests")]
pub struct Flags {
/// Which tests to run?
#[structopt(long = "filter", default_value = "All")]
filter: Filter,
/// If specified, only run tests with names containing this substring.
#[structopt(long = "test_names")]
test_names: Option<String>,
/// Keep the log and savestate even for passing tests.
#[structopt(long = "keep_output")]
keep_output: bool,
/// Print debug output as clickable HTTP links.
#[structopt(long = "clickable_links")]
clickable_links: bool,
// Which tests to run? Default to All
pub filter: Filter,
// If specified, only run tests with names containing this substring.
pub test_names: Option<String>,
// Keep the log and savestate even for passing tests.
pub keep_output: bool,
// Print debug output as clickable HTTP links.
pub clickable_links: bool,
}
pub struct TestRunner {
@ -292,16 +279,3 @@ pub enum Filter {
Slow,
Fast,
}
impl std::str::FromStr for Filter {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"All" => Ok(Filter::All),
"Slow" => Ok(Filter::Slow),
"Fast" => Ok(Filter::Fast),
_ => Err(Error::new(format!("{} isn't a valid Filter", s))),
}
}
}