mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 07:25:47 +03:00
hide IDs unless in dev mode
This commit is contained in:
parent
c049221743
commit
53f33a31e4
@ -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()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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::{
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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)));
|
||||||
|
@ -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();
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user