Add an --edits flag to headless

This commit is contained in:
Dustin Carlino 2020-09-18 10:43:58 -07:00
parent d9e50a7e38
commit 5dd761ceb9

View File

@ -14,7 +14,7 @@ use geom::{Duration, LonLat, Time};
use hyper::{Body, Request, Response, Server}; use hyper::{Body, Request, Response, Server};
use map_model::{ use map_model::{
CompressedMovementID, ControlTrafficSignal, EditCmd, EditIntersection, IntersectionID, Map, CompressedMovementID, ControlTrafficSignal, EditCmd, EditIntersection, IntersectionID, Map,
MovementID, PermanentMapEdits, MapEdits, MovementID, PermanentMapEdits,
}; };
use serde::Serialize; use serde::Serialize;
use sim::{ use sim::{
@ -30,6 +30,7 @@ lazy_static::lazy_static! {
static ref MAP: RwLock<Map> = RwLock::new(Map::blank()); static ref MAP: RwLock<Map> = RwLock::new(Map::blank());
static ref SIM: RwLock<Sim> = RwLock::new(Sim::new(&Map::blank(), SimOptions::new("tmp"), &mut Timer::throwaway())); static ref SIM: RwLock<Sim> = RwLock::new(Sim::new(&Map::blank(), SimOptions::new("tmp"), &mut Timer::throwaway()));
static ref FLAGS: RwLock<SimFlags> = RwLock::new(SimFlags::for_test("tmp")); static ref FLAGS: RwLock<SimFlags> = RwLock::new(SimFlags::for_test("tmp"));
static ref EDITS: RwLock<Option<String>> = RwLock::new(None);
} }
#[tokio::main] #[tokio::main]
@ -37,9 +38,11 @@ async fn main() {
let mut args = CmdArgs::new(); let mut args = CmdArgs::new();
let sim_flags = SimFlags::from_args(&mut args); let sim_flags = SimFlags::from_args(&mut args);
let port = args.required("--port").parse::<u16>().unwrap(); let port = args.required("--port").parse::<u16>().unwrap();
*EDITS.write().unwrap() = args.optional("--edits");
args.done(); args.done();
let (map, sim, _) = sim_flags.load(&mut Timer::new("setup headless")); let (mut map, sim, _) = sim_flags.load(&mut Timer::new("setup headless"));
apply_edits(&mut map);
*MAP.write().unwrap() = map; *MAP.write().unwrap() = map;
*SIM.write().unwrap() = sim; *SIM.write().unwrap() = sim;
*FLAGS.write().unwrap() = sim_flags; *FLAGS.write().unwrap() = sim_flags;
@ -90,12 +93,17 @@ fn handle_command(
match path { match path {
// Controlling the simulation // Controlling the simulation
"/sim/reset" => { "/sim/reset" => {
let (new_map, new_sim, _) = FLAGS.read().unwrap().load(&mut Timer::new("reset sim")); let (mut new_map, new_sim, _) =
FLAGS.read().unwrap().load(&mut Timer::new("reset sim"));
apply_edits(&mut new_map);
*map = new_map; *map = new_map;
*sim = new_sim; *sim = new_sim;
Ok(format!("sim reloaded")) Ok(format!("sim reloaded"))
} }
"/sim/load" => { "/sim/load" => {
// Reset --edits
*EDITS.write().unwrap() = None;
let flags: SimFlags = abstutil::from_json(body)?; let flags: SimFlags = abstutil::from_json(body)?;
// Only a few fields from SimFlags can be specified through the API. For the rest // Only a few fields from SimFlags can be specified through the API. For the rest
// (namely SimOptions), keep the ones from the command line. // (namely SimOptions), keep the ones from the command line.
@ -248,6 +256,15 @@ fn handle_command(
} }
} }
fn apply_edits(map: &mut Map) {
if let Some(name) = EDITS.read().unwrap().as_ref() {
let mut timer = Timer::new(format!("apply edits {}", name));
let edits =
MapEdits::load(map, abstutil::path_edits(map.get_name(), name), &mut timer).unwrap();
map.must_apply_edits(edits, &mut timer);
}
}
// TODO I think specifying the API with protobufs or similar will be a better idea. // TODO I think specifying the API with protobufs or similar will be a better idea.
#[derive(Serialize)] #[derive(Serialize)]