hide IDs unless in dev mode

This commit is contained in:
Dustin Carlino 2020-01-09 11:50:56 -06:00
parent c049221743
commit 53f33a31e4
7 changed files with 103 additions and 80 deletions

View File

@ -161,32 +161,3 @@ impl<K: Copy + PartialEq, V> VecMap<K, V> {
&mut self.inner.last_mut().unwrap().1 &mut self.inner.last_mut().unwrap().1
} }
} }
pub struct IsLastIter<T> {
// TODO Should be able to just store the vector's iterator?
stack: Vec<T>,
}
impl<T> IsLastIter<T> {
// TODO Take an IntoIterator. Can't figure out how to say T == I::Item.
pub fn vec(mut vec: Vec<T>) -> IsLastIter<T> {
vec.reverse();
IsLastIter { stack: vec }
}
pub fn set(set: BTreeSet<T>) -> IsLastIter<T> {
let mut vec: Vec<T> = set.into_iter().collect();
vec.reverse();
IsLastIter { stack: vec }
}
}
impl<T> Iterator for IsLastIter<T> {
// true if we're the last item
type Item = (T, bool);
fn next(&mut self) -> Option<Self::Item> {
let item = self.stack.pop()?;
Some((item, self.stack.is_empty()))
}
}

View File

@ -10,8 +10,8 @@ mod time;
pub use crate::cli::CmdArgs; pub use crate::cli::CmdArgs;
pub use crate::clone::Cloneable; pub use crate::clone::Cloneable;
pub use crate::collections::{ pub use crate::collections::{
contains_duplicates, retain_btreemap, retain_btreeset, wraparound_get, Counter, IsLastIter, contains_duplicates, retain_btreemap, retain_btreeset, wraparound_get, Counter, MultiMap,
MultiMap, VecMap, VecMap,
}; };
pub use crate::error::Error; pub use crate::error::Error;
pub use crate::io::{ pub use crate::io::{

View File

@ -19,10 +19,9 @@ pub use self::route_explorer::RouteExplorer;
pub use self::trip_explorer::TripExplorer; pub use self::trip_explorer::TripExplorer;
pub use self::warp::Warping; pub use self::warp::Warping;
use crate::game::Transition; use crate::game::Transition;
use crate::helpers::ID; use crate::helpers::{list_names, ID};
use crate::render::DrawOptions; use crate::render::DrawOptions;
use crate::ui::UI; use crate::ui::UI;
use abstutil::IsLastIter;
use ezgui::{ use ezgui::{
hotkey, lctrl, Color, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, Text, VerticalAlignment, hotkey, lctrl, Color, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, Text, VerticalAlignment,
}; };
@ -83,19 +82,22 @@ impl CommonState {
let mut osd = Text::new().with_bg(); let mut osd = Text::new().with_bg();
match id { match id {
ID::Lane(l) => { ID::Lane(l) => {
if ui.opts.dev {
osd.append(Line(l.to_string()).fg(id_color));
osd.append(Line(" is "));
}
osd.append_all(vec![ osd.append_all(vec![
Line(l.to_string()).fg(id_color), Line(format!("{} of ", map.get_l(l).lane_type.describe())),
Line(format!(" is {} of ", map.get_l(l).lane_type.describe())),
Line(map.get_parent(l).get_name()).fg(name_color), Line(map.get_parent(l).get_name()).fg(name_color),
]); ]);
} }
ID::Building(b) => { ID::Building(b) => {
if ui.opts.dev {
osd.append(Line(b.to_string()).fg(id_color));
osd.append(Line(" is "));
}
let bldg = map.get_b(b); let bldg = map.get_b(b);
osd.append_all(vec![ osd.append(Line(bldg.get_name(map)).fg(name_color));
Line(b.to_string()).fg(id_color),
Line(" is "),
Line(bldg.get_name(map)).fg(name_color),
]);
if let Some(ref p) = bldg.parking { if let Some(ref p) = bldg.parking {
osd.append(Line(format!( osd.append(Line(format!(
" ({} parking spots via {})", " ({} parking spots via {})",
@ -104,6 +106,7 @@ impl CommonState {
} }
} }
ID::Turn(t) => { ID::Turn(t) => {
// Only selectable in dev mode anyway
osd.append_all(vec![ osd.append_all(vec![
Line(format!("TurnID({})", map.get_t(t).lookup_idx)).fg(id_color), Line(format!("TurnID({})", map.get_t(t).lookup_idx)).fg(id_color),
Line(" between "), Line(" between "),
@ -113,21 +116,29 @@ impl CommonState {
]); ]);
} }
ID::Intersection(i) => { ID::Intersection(i) => {
osd.append_all(vec![Line(i.to_string()).fg(id_color), Line(" of ")]); if map.get_i(i).is_border() {
osd.append(Line("Border "));
}
if ui.opts.dev {
osd.append(Line(i.to_string()).fg(id_color));
} else {
osd.append(Line("Intersection"));
}
osd.append(Line(" of "));
let mut road_names = BTreeSet::new(); let mut road_names = BTreeSet::new();
for r in &map.get_i(i).roads { for r in &map.get_i(i).roads {
road_names.insert(map.get_r(*r).get_name()); road_names.insert(map.get_r(*r).get_name());
} }
for (n, is_last) in IsLastIter::set(road_names) { list_names(&mut osd, |l| l.fg(name_color), road_names);
osd.append(Line(n).fg(name_color));
if !is_last {
osd.append(Line(", "));
}
}
} }
ID::Car(c) => { ID::Car(c) => {
osd.append(Line(c.to_string()).fg(id_color)); if ui.opts.dev {
osd.append(Line(c.to_string()).fg(id_color));
} else {
osd.append(Line(format!("a {}", c.1)));
}
if let Some(r) = ui.primary.sim.bus_route_id(c) { if let Some(r) = ui.primary.sim.bus_route_id(c) {
osd.append_all(vec![ osd.append_all(vec![
Line(" serving "), Line(" serving "),
@ -135,20 +146,40 @@ impl CommonState {
]); ]);
} }
} }
ID::BusStop(bs) => { ID::Pedestrian(p) => {
osd.append_all(vec![Line(bs.to_string()).fg(id_color), Line(" serving ")]); if ui.opts.dev {
osd.append(Line(p.to_string()).fg(id_color));
let routes = map.get_routes_serving_stop(bs); } else {
for (n, is_last) in IsLastIter::vec(routes) { osd.append(Line("a pedestrian"));
osd.append(Line(&n.name).fg(name_color));
if !is_last {
osd.append(Line(", "));
}
} }
} }
_ => { ID::PedCrowd(list) => {
osd.append(Line(format!("{:?}", id)).fg(id_color)); osd.append(Line(format!("a crowd of {} pedestrians", list.len())));
} }
ID::BusStop(bs) => {
if ui.opts.dev {
osd.append(Line(bs.to_string()).fg(id_color));
} else {
osd.append(Line("a bus stop"));
}
osd.append(Line(" served by "));
let routes: BTreeSet<String> = map
.get_routes_serving_stop(bs)
.into_iter()
.map(|r| r.name.clone())
.collect();
list_names(&mut osd, |l| l.fg(name_color), routes);
}
ID::ExtraShape(es) => {
// Only selectable in dev mode anyway
osd.append(Line(es.to_string()).fg(id_color));
}
ID::Area(a) => {
// Only selectable in dev mode anyway
osd.append(Line(a.to_string()).fg(id_color));
}
ID::Road(_) => unreachable!(),
} }
osd osd
} }

View File

@ -1,12 +1,12 @@
use crate::render::ExtraShapeID; use crate::render::ExtraShapeID;
use crate::ui::PerMapUI; use crate::ui::PerMapUI;
use abstutil::Timer; use abstutil::Timer;
use ezgui::Color; use ezgui::{Color, Line, Text, TextSpan};
use geom::Pt2D; use geom::Pt2D;
use map_model::{AreaID, BuildingID, BusStopID, IntersectionID, LaneID, RoadID, TurnID}; use map_model::{AreaID, BuildingID, BusStopID, IntersectionID, LaneID, RoadID, TurnID};
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use sim::{AgentID, CarID, PedestrianID}; use sim::{AgentID, CarID, PedestrianID};
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, BTreeSet, HashMap};
// Aside from Road, everything here can actually be selected. // Aside from Road, everything here can actually be selected.
#[derive(Clone, Hash, PartialEq, Eq, Debug, PartialOrd, Ord)] #[derive(Clone, Hash, PartialEq, Eq, Debug, PartialOrd, Ord)]
@ -182,3 +182,21 @@ pub fn rotating_color_agents(idx: usize) -> Color {
} }
Color::hex("#00A27B") Color::hex("#00A27B")
} }
pub fn list_names<F: Fn(TextSpan) -> TextSpan>(txt: &mut Text, styler: F, names: BTreeSet<String>) {
let len = names.len();
for (idx, n) in names.into_iter().enumerate() {
if idx != 0 {
if idx == len - 1 {
if len == 2 {
txt.append(Line(" and "));
} else {
txt.append(Line(", and "));
}
} else {
txt.append(Line(", "));
}
}
txt.append(styler(Line(n)));
}
}

View File

@ -1,7 +1,7 @@
use crate::helpers::list_names;
use crate::options::TrafficSignalStyle; use crate::options::TrafficSignalStyle;
use crate::render::{DrawCtx, DrawTurnGroup, BIG_ARROW_THICKNESS}; use crate::render::{DrawCtx, DrawTurnGroup, BIG_ARROW_THICKNESS};
use crate::ui::UI; use crate::ui::UI;
use abstutil::IsLastIter;
use ezgui::{ use ezgui::{
Button, Color, Composite, DrawBoth, EventCtx, GeomBatch, GfxCtx, Line, ManagedWidget, Button, Color, Composite, DrawBoth, EventCtx, GeomBatch, GfxCtx, Line, ManagedWidget,
ModalMenu, Outcome, Text, ModalMenu, Outcome, Text,
@ -234,14 +234,12 @@ fn make_diagram(i: IntersectionID, selected: usize, ui: &UI, ctx: &mut EventCtx)
.map(|r| ui.primary.map.get_r(*r).get_name()) .map(|r| ui.primary.map.get_r(*r).get_name())
.collect::<BTreeSet<_>>(); .collect::<BTreeSet<_>>();
// TODO Some kind of reusable TextStyle thing // TODO Some kind of reusable TextStyle thing
// TODO Need to wrap this
txt.add(Line("").roboto().size(21).fg(Color::WHITE.alpha(0.54))); txt.add(Line("").roboto().size(21).fg(Color::WHITE.alpha(0.54)));
for (n, is_last) in IsLastIter::set(road_names) { list_names(
txt.append(Line(n).roboto().fg(Color::WHITE.alpha(0.54))); &mut txt,
if !is_last { |l| l.roboto().fg(Color::WHITE.alpha(0.54)),
txt.append(Line(", ").roboto().fg(Color::WHITE.alpha(0.54))); road_names,
} );
}
txt.add(Line(format!("{} phases", signal.phases.len()))); txt.add(Line(format!("{} phases", signal.phases.len())));
txt.add(Line("")); txt.add(Line(""));
txt.add(Line(format!("Signal offset: {}", signal.offset))); txt.add(Line(format!("Signal offset: {}", signal.offset)));

View File

@ -338,7 +338,11 @@ impl Road {
pub fn get_name(&self) -> String { pub fn get_name(&self) -> String {
if let Some(name) = self.osm_tags.get(osm::NAME) { if let Some(name) = self.osm_tags.get(osm::NAME) {
return name.to_string(); if name == "" {
return "???".to_string();
} else {
return name.to_string();
}
} }
if let Some(name) = self.osm_tags.get("ref") { if let Some(name) = self.osm_tags.get("ref") {
return name.to_string(); return name.to_string();

View File

@ -59,16 +59,7 @@ pub struct CarID(pub usize, pub VehicleType);
impl fmt::Display for CarID { impl fmt::Display for CarID {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!( write!(f, "CarID({} -- {})", self.0, self.1)
f,
"CarID({0} -- {1})",
self.0,
match self.1 {
VehicleType::Car => "car",
VehicleType::Bus => "bus",
VehicleType::Bike => "bike",
}
)
} }
} }
@ -121,6 +112,16 @@ pub enum VehicleType {
Bike, Bike,
} }
impl fmt::Display for VehicleType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
VehicleType::Car => write!(f, "car"),
VehicleType::Bus => write!(f, "bus"),
VehicleType::Bike => write!(f, "bike"),
}
}
}
impl VehicleType { impl VehicleType {
pub fn to_constraints(self) -> PathConstraints { pub fn to_constraints(self) -> PathConstraints {
match self { match self {