From eedf80bfef1e640e69edc9aa72d67edd3d4caf01 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Sun, 21 Jun 2020 11:38:34 -0700 Subject: [PATCH] tiny tweaks from final testing: - cutscene wording - elide traffic tab on parking lanes - dont crash when traffic signal data needs fixing, just warn more loudly. this lets lanes near some signals actually be modified --- README.md | 1 + abstutil/src/time.rs | 14 ++++++++++++++ docs/index.md | 2 +- game/src/debug/mod.rs | 7 ++++++- game/src/edit/traffic_signals.rs | 12 ++++++++---- game/src/info/lane.rs | 8 ++++---- game/src/sandbox/gameplay/tutorial.rs | 5 ++++- map_model/src/make/traffic_signals.rs | 11 ++++++++--- map_model/src/traffic_signals.rs | 5 +++-- 9 files changed, 49 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 4df31eb436..7c9277193e 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Measure the effects: ## Documentation - [How A/B Street works](docs/how_it_works.md) +- [Case studies](https://dabreegster.github.io/abstreet/) - Technical - [Developer guide](docs/dev.md) - [Map model](docs/articles/map/article.md) diff --git a/abstutil/src/time.rs b/abstutil/src/time.rs index 67cabfd3f0..9ae46d6cc4 100644 --- a/abstutil/src/time.rs +++ b/abstutil/src/time.rs @@ -108,6 +108,7 @@ pub struct Timer<'a> { notes: Vec, pub(crate) warnings: Vec, + pub(crate) errors: Vec, sink: Option>, } @@ -128,6 +129,7 @@ impl<'a> Timer<'a> { outermost_name: name.clone(), notes: Vec::new(), warnings: Vec::new(), + errors: Vec::new(), sink: None, }; t.start(name); @@ -180,6 +182,10 @@ impl<'a> Timer<'a> { self.warnings.push(line); } + pub fn error(&mut self, line: String) { + self.errors.push(line); + } + // Used to end the scope of a timer early. pub fn done(self) {} @@ -421,6 +427,14 @@ impl<'a> std::ops::Drop for Timer<'a> { self.println(String::new()); } + if !self.errors.is_empty() { + self.println(format!("***** {} errors: *****", self.errors.len())); + for line in &self.errors { + Timer::selfless_println(&mut self.sink, line.to_string()); + } + self.println(String::new()); + } + // In case of lots of notes and warnings, repeat the overall timing. Timer::selfless_println(&mut self.sink, self.results[0].clone()); } diff --git a/docs/index.md b/docs/index.md index 60ec4e123a..c9cbdaa8cc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,4 +1,4 @@ -# A/B Street +# Case studies See [the main page](https://github.com/dabreegster/abstreet/) for now. I'll probably organize everything here eventually. diff --git a/game/src/debug/mod.rs b/game/src/debug/mod.rs index 737f2dc9da..10cb18ae98 100644 --- a/game/src/debug/mod.rs +++ b/game/src/debug/mod.rs @@ -608,7 +608,12 @@ fn find_bad_signals(app: &App) { println!("Bad traffic signals:"); for i in app.primary.map.all_intersections() { if i.is_traffic_signal() { - let first = &ControlTrafficSignal::get_possible_policies(&app.primary.map, i.id)[0].0; + let first = &ControlTrafficSignal::get_possible_policies( + &app.primary.map, + i.id, + &mut Timer::throwaway(), + )[0] + .0; if first == "phase per road" || first == "arbitrary assignment" { println!("- {}", i.id); ControlTrafficSignal::brute_force(&app.primary.map, i.id); diff --git a/game/src/edit/traffic_signals.rs b/game/src/edit/traffic_signals.rs index 65476dbe80..b515b46f40 100644 --- a/game/src/edit/traffic_signals.rs +++ b/game/src/edit/traffic_signals.rs @@ -533,6 +533,7 @@ fn edit_entire_signal(app: &App, i: IntersectionID, mode: GameplayMode) -> Box Box().unwrap(); let orig_signal = app.primary.map.get_traffic_signal(editor.i); - let new_signal = - ControlTrafficSignal::get_possible_policies(&app.primary.map, editor.i) - .remove(0) - .1; + let new_signal = ControlTrafficSignal::get_possible_policies( + &app.primary.map, + editor.i, + &mut Timer::throwaway(), + ) + .remove(0) + .1; editor.command_stack.push(orig_signal.clone()); editor.redo_stack.clear(); editor.top_panel = make_top_panel(ctx, app, true, false); diff --git a/game/src/info/lane.rs b/game/src/info/lane.rs index 2366068bb4..2a78275e99 100644 --- a/game/src/info/lane.rs +++ b/game/src/info/lane.rs @@ -217,10 +217,10 @@ fn header(ctx: &EventCtx, app: &App, details: &mut Details, id: LaneID, tab: Tab ])); rows.push(format!("@ {}", r.get_name()).draw_text(ctx)); - let mut tabs = vec![ - ("Info", Tab::LaneInfo(id)), - ("Traffic", Tab::LaneTraffic(id, DataOptions::new())), - ]; + let mut tabs = vec![("Info", Tab::LaneInfo(id))]; + if !l.is_parking() { + tabs.push(("Traffic", Tab::LaneTraffic(id, DataOptions::new()))); + } if app.opts.dev { tabs.push(("Debug", Tab::LaneDebug(id))); } diff --git a/game/src/sandbox/gameplay/tutorial.rs b/game/src/sandbox/gameplay/tutorial.rs index 157548274f..2e44bc59df 100644 --- a/game/src/sandbox/gameplay/tutorial.rs +++ b/game/src/sandbox/gameplay/tutorial.rs @@ -1427,7 +1427,10 @@ fn intro_story(ctx: &mut EventCtx, app: &App) -> Box { .boss("Light rail and robot cars aren't here to save the day! Know what you'll be using?") .extra("drone", "The traffic drone") .player("Is that... duct tape?") - .boss("We ran out of spit and prayers. Well, off to training for you!") + .boss( + "Can't spit anymore cause of COVID and don't get me started on prayers. Well, off to \ + training for you!", + ) .build( ctx, app, diff --git a/map_model/src/make/traffic_signals.rs b/map_model/src/make/traffic_signals.rs index 2a3e44cdb0..231c9a6838 100644 --- a/map_model/src/make/traffic_signals.rs +++ b/map_model/src/make/traffic_signals.rs @@ -2,10 +2,15 @@ use crate::{ ControlTrafficSignal, IntersectionID, Map, Phase, RoadID, TurnGroup, TurnGroupID, TurnPriority, TurnType, }; +use abstutil::Timer; use geom::Duration; use std::collections::BTreeMap; -pub fn get_possible_policies(map: &Map, id: IntersectionID) -> Vec<(String, ControlTrafficSignal)> { +pub fn get_possible_policies( + map: &Map, + id: IntersectionID, + timer: &mut Timer, +) -> Vec<(String, ControlTrafficSignal)> { let mut results = Vec::new(); // TODO Cache with lazy_static. Don't serialize in Map; the repo of signal data may evolve @@ -17,10 +22,10 @@ pub fn get_possible_policies(map: &Map, id: IntersectionID) -> Vec<(String, Cont if let Some(ts) = ControlTrafficSignal::import(raw, id, map) { results.push(("hand-mapped current real settings".to_string(), ts)); } else { - panic!( + timer.error(format!( "seattle_traffic_signals data for {} out of date, go update it", map.get_i(id).orig_id.osm_node_id - ); + )); } } diff --git a/map_model/src/traffic_signals.rs b/map_model/src/traffic_signals.rs index 63db5b0994..5d0402a4bd 100644 --- a/map_model/src/traffic_signals.rs +++ b/map_model/src/traffic_signals.rs @@ -29,7 +29,7 @@ pub struct Phase { impl ControlTrafficSignal { pub fn new(map: &Map, id: IntersectionID, timer: &mut Timer) -> ControlTrafficSignal { - let mut policies = ControlTrafficSignal::get_possible_policies(map, id); + let mut policies = ControlTrafficSignal::get_possible_policies(map, id, timer); if policies.len() == 1 { timer.warn(format!("Falling back to greedy_assignment for {}", id)); } @@ -39,8 +39,9 @@ impl ControlTrafficSignal { pub fn get_possible_policies( map: &Map, id: IntersectionID, + timer: &mut Timer, ) -> Vec<(String, ControlTrafficSignal)> { - get_possible_policies(map, id) + get_possible_policies(map, id, timer) } // TODO tmp pub fn brute_force(map: &Map, id: IntersectionID) {