sharing flags for specifying sim to load

This commit is contained in:
Dustin Carlino 2018-10-02 16:16:25 -07:00
parent 04acd6723b
commit 190d9be972
9 changed files with 75 additions and 118 deletions

View File

@ -41,42 +41,24 @@ mod plugins;
mod render;
mod ui;
use sim::SimFlags;
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
#[structopt(name = "editor")]
struct Flags {
/// Map or savestate to load
#[structopt(name = "load")]
load: String,
/// Optional RNG seed
#[structopt(long = "rng_seed")]
rng_seed: Option<u8>,
#[structopt(flatten)]
sim_flags: SimFlags,
/// Extra KML to display
#[structopt(long = "kml")]
kml: Option<String>,
/// Run name for savestating
#[structopt(long = "run_name", default_value = "editor")]
run_name: String,
/// Name of map edits
#[structopt(long = "edits_name", default_value = "no_edits")]
edits_name: String,
}
fn main() {
let flags = Flags::from_args();
ezgui::run(
ui::UIWrapper::new(
flags.load,
flags.run_name,
flags.edits_name,
flags.rng_seed,
flags.kml,
),
ui::UIWrapper::new(flags.sim_flags, flags.kml),
"A/B Street",
1024,
768,

View File

@ -36,7 +36,7 @@ use plugins::warp::WarpState;
use plugins::Colorizer;
use render::{DrawMap, RenderOptions};
use sim;
use sim::{MapEdits, Sim};
use sim::{MapEdits, Sim, SimFlags};
use std::process;
// TODO ideally these would be tuned kind of dynamically based on rendering speed
@ -65,24 +65,12 @@ impl GUI for UIWrapper {
impl UIWrapper {
// nit: lots of this logic could live in UI, if it mattered
pub fn new(
load: String,
run_name: String,
edits_name: String,
rng_seed: Option<u8>,
kml: Option<String>,
) -> UIWrapper {
pub fn new(flags: SimFlags, kml: Option<String>) -> UIWrapper {
// Do this first, so anything logged by sim::load isn't lost.
let logs = DisplayLogs::new();
flame::start("setup");
let (map, control_map, sim) = sim::load(
load,
run_name,
edits_name,
rng_seed,
Some(sim::Tick::from_seconds(30)),
);
let (map, control_map, sim) = sim::load(flags, Some(sim::Tick::from_seconds(30)));
let extra_shapes = if let Some(path) = kml {
kml::load(&path, &map.get_gps_bounds()).expect("Couldn't load extra KML shapes")
} else {

View File

@ -10,6 +10,7 @@ extern crate structopt;
extern crate yansi;
use log::{LevelFilter, Log, Metadata, Record};
use sim::SimFlags;
use structopt::StructOpt;
static LOG_ADAPTER: LogAdapter = LogAdapter;
@ -17,13 +18,8 @@ static LOG_ADAPTER: LogAdapter = LogAdapter;
#[derive(StructOpt, Debug)]
#[structopt(name = "headless")]
struct Flags {
/// Map or savestate to load
#[structopt(name = "load")]
load: String,
/// Optional RNG seed
#[structopt(long = "rng_seed")]
rng_seed: Option<u8>,
#[structopt(flatten)]
sim_flags: SimFlags,
/// Optional time to savestate
#[structopt(long = "save_at")]
@ -32,14 +28,6 @@ struct Flags {
/// Big or large random scenario?
#[structopt(long = "big_sim")]
big_sim: bool,
/// Run name for savestating
#[structopt(long = "run_name", default_value = "headless")]
run_name: String,
/// Name of map edits
#[structopt(long = "edits_name", default_value = "no_edits")]
edits_name: String,
}
fn main() {
@ -48,16 +36,11 @@ fn main() {
log::set_max_level(LevelFilter::Debug);
log::set_logger(&LOG_ADAPTER).unwrap();
let (map, control_map, mut sim) = sim::load(
flags.load.clone(),
flags.run_name,
flags.edits_name,
flags.rng_seed,
Some(sim::Tick::from_seconds(30)),
);
// TODO not the ideal way to distinguish what thing we loaded
if flags.load.contains("data/maps/") {
let load = flags.sim_flags.load.clone();
let (map, control_map, mut sim) = sim::load(flags.sim_flags, Some(sim::Tick::from_seconds(30)));
if load.contains("data/maps/") {
if flags.big_sim {
sim.big_spawn(&map);
} else {

View File

@ -24,3 +24,4 @@ rand = { version = "0.5.1", features = ["serde1"] }
rayon = "1.0"
serde = "1.0"
serde_derive = "1.0"
structopt = "0.2"

View File

@ -7,35 +7,60 @@ use rand::Rng;
use std::collections::VecDeque;
use {CarID, Event, MapEdits, PedestrianID, RouteID, Scenario, Sim, Tick};
#[derive(StructOpt, Debug)]
#[structopt(name = "sim_flags")]
pub struct SimFlags {
/// Map, scenario, or savestate to load
#[structopt(name = "load")]
pub load: String,
/// Optional RNG seed
#[structopt(long = "rng_seed")]
pub rng_seed: Option<u8>,
/// Run name for savestating
#[structopt(long = "run_name", default_value = "unnamed")]
pub run_name: String,
/// Name of map edits
#[structopt(long = "edits_name", default_value = "no_edits")]
pub edits_name: String,
}
impl SimFlags {
pub fn for_test(run_name: &str) -> SimFlags {
SimFlags {
load: "../data/maps/small.abst".to_string(),
rng_seed: Some(42),
run_name: run_name.to_string(),
edits_name: "no_edits".to_string(),
}
}
}
// Convenience method to setup everything.
pub fn load(
input: String,
run_name: String,
edits_name: String,
rng_seed: Option<u8>,
savestate_every: Option<Tick>,
) -> (Map, ControlMap, Sim) {
if input.contains("data/save/") {
info!("Resuming from {}", input);
pub fn load(flags: SimFlags, savestate_every: Option<Tick>) -> (Map, ControlMap, Sim) {
if flags.load.contains("data/save/") {
info!("Resuming from {}", flags.load);
flame::start("read sim savestate");
let sim: Sim = abstutil::read_json(&input).expect("loading sim state failed");
let sim: Sim = abstutil::read_json(&flags.load).expect("loading sim state failed");
flame::end("read sim savestate");
// TODO assuming the relative path :(
let edits: MapEdits = abstutil::read_json(&format!(
"../data/edits/{}/{}.json",
sim.map_name, edits_name
sim.map_name, flags.edits_name
)).unwrap_or(MapEdits::new());
let map_path = format!("../data/maps/{}.abst", sim.map_name);
let map = Map::new(&map_path, edits.road_edits.clone())
.expect(&format!("Couldn't load map from {}", map_path));
let control_map = ControlMap::new(&map, &edits.stop_signs, &edits.traffic_signals);
(map, control_map, sim)
} else if input.contains("data/scenarios/") {
info!("Seeding the simulation from scenario {}", input);
let scenario: Scenario = abstutil::read_json(&input).expect("loading scenario failed");
} else if flags.load.contains("data/scenarios/") {
info!("Seeding the simulation from scenario {}", flags.load);
let scenario: Scenario = abstutil::read_json(&flags.load).expect("loading scenario failed");
let edits: MapEdits = abstutil::read_json(&format!(
"../data/edits/{}/{}.json",
scenario.map_name, edits_name
scenario.map_name, flags.edits_name
)).unwrap_or(MapEdits::new());
let map_path = format!("../data/maps/{}.abst", scenario.map_name);
let map = Map::new(&map_path, edits.road_edits.clone())
@ -44,26 +69,28 @@ pub fn load(
let mut sim = Sim::new(
&map,
scenario.scenario_name.clone(),
rng_seed,
flags.rng_seed,
savestate_every,
);
scenario.instantiate(&mut sim, &map);
(map, control_map, sim)
} else {
// TODO relative dir is brittle; match more cautiously
let map_name = input
let map_name = flags
.load
.trim_left_matches("../data/maps/")
.trim_right_matches(".abst")
.to_string();
info!("Loading map {}", input);
let edits: MapEdits =
abstutil::read_json(&format!("../data/edits/{}/{}.json", map_name, edits_name))
.unwrap_or(MapEdits::new());
let map = Map::new(&input, edits.road_edits.clone()).expect("Couldn't load map");
info!("Loading map {}", flags.load);
let edits: MapEdits = abstutil::read_json(&format!(
"../data/edits/{}/{}.json",
map_name, flags.edits_name
)).unwrap_or(MapEdits::new());
let map = Map::new(&flags.load, edits.road_edits.clone()).expect("Couldn't load map");
let control_map = ControlMap::new(&map, &edits.stop_signs, &edits.traffic_signals);
flame::start("create sim");
// Note this is the only time we actually use the run name!
let sim = Sim::new(&map, run_name, rng_seed, savestate_every);
let sim = Sim::new(&map, flags.run_name, flags.rng_seed, savestate_every);
flame::end("create sim");
(map, control_map, sim)
}

View File

@ -28,6 +28,8 @@ extern crate rayon;
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate structopt;
#[macro_use]
mod macros;
@ -55,7 +57,7 @@ use dimensioned::si;
pub use edits::MapEdits;
pub use events::Event;
use geom::{Angle, Pt2D};
pub use helpers::load;
pub use helpers::{load, SimFlags};
pub use instrument::save_backtraces;
use map_model::{LaneID, Map, TurnID};
pub use scenario::{Neighborhood, Scenario, SeedParkedCars, SpawnOverTime};

View File

@ -6,10 +6,7 @@ extern crate sim;
#[test]
fn aorta_model_completes() {
let (map, control_map, mut sim) = sim::load(
"../data/maps/small.abst".to_string(),
"aorta_model_completes".to_string(),
"no_edits".to_string(),
Some(42),
sim::SimFlags::for_test("aorta_model_completes"),
Some(sim::Tick::from_seconds(30)),
);
sim.small_spawn(&map);

View File

@ -5,13 +5,7 @@ extern crate sim;
#[test]
fn serialization() {
let (map, _, mut sim) = sim::load(
"../data/maps/small.abst".to_string(),
"serialization".to_string(),
"no_edits".to_string(),
Some(42),
None,
);
let (map, _, mut sim) = sim::load(sim::SimFlags::for_test("serialization"), None);
sim.small_spawn(&map);
// Does savestating produce the same string?
@ -23,13 +17,7 @@ fn serialization() {
#[test]
fn from_scratch() {
println!("Creating two simulations");
let (map, control_map, mut sim1) = sim::load(
"../data/maps/small.abst".to_string(),
"from_scratch_1".to_string(),
"no_edits".to_string(),
Some(42),
None,
);
let (map, control_map, mut sim1) = sim::load(sim::SimFlags::for_test("from_scratch_1"), None);
let mut sim2 = sim::Sim::new(&map, "from_scratch_2".to_string(), Some(42), None);
sim1.small_spawn(&map);
sim2.small_spawn(&map);
@ -51,13 +39,8 @@ fn from_scratch() {
#[test]
fn with_savestating() {
println!("Creating two simulations");
let (map, control_map, mut sim1) = sim::load(
"../data/maps/small.abst".to_string(),
"with_savestating_1".to_string(),
"no_edits".to_string(),
Some(42),
None,
);
let (map, control_map, mut sim1) =
sim::load(sim::SimFlags::for_test("with_savestating_1"), None);
let mut sim2 = sim::Sim::new(&map, "with_savestating_2".to_string(), Some(42), None);
sim1.small_spawn(&map);
sim2.small_spawn(&map);

View File

@ -6,10 +6,7 @@ extern crate sim;
#[test]
fn bus_reaches_stops() {
let (map, control_map, mut sim) = sim::load(
"../data/maps/small.abst".to_string(),
"bus_reaches_stops".to_string(),
"no_edits".to_string(),
Some(42),
sim::SimFlags::for_test("bus_reaches_stops"),
Some(sim::Tick::from_seconds(30)),
);
@ -35,10 +32,7 @@ fn bus_reaches_stops() {
#[test]
fn ped_uses_bus() {
let (map, control_map, mut sim) = sim::load(
"../data/maps/small.abst".to_string(),
"bus_reaches_stops".to_string(),
"no_edits".to_string(),
Some(42),
sim::SimFlags::for_test("bus_reaches_stops"),
Some(sim::Tick::from_seconds(30)),
);