1use crate::ID;
2use map_model::{Map, Position};
3use sim::{AgentID, Sim};
4use widgetry::{GfxCtx, Key, Text};
5
6use crate::app::App;
7
8pub struct ObjectDebugger;
9
10impl ObjectDebugger {
11 pub fn draw(&self, g: &mut GfxCtx, app: &App) {
12 if g.is_key_down(Key::LeftControl) {
13 if let Some(pt) = g.canvas.get_cursor_in_map_space() {
14 let mut txt = Text::new();
15 txt.add_line(pt.to_string());
16 txt.add_line(pt.to_gps(app.primary.map.get_gps_bounds()).to_string());
17 txt.add_line(format!("{:?}", g.canvas.get_cursor()));
18 txt.add_line(format!("zoom: {}", g.canvas.cam_zoom));
19 txt.add_line(format!(
20 "cam_x = {}, cam_y = {}",
21 g.canvas.cam_x, g.canvas.cam_y
22 ));
23 if let Some(ID::Lane(l)) = app.primary.current_selection {
24 let lane = app.primary.map.get_l(l);
25 let pl = &lane.lane_center_pts;
26 if let Some((dist, _)) = pl.dist_along_of_point(pl.project_pt(pt)) {
27 txt.add_line(Position::new(l, dist).to_string());
28 }
29 txt.add_line(format!(
30 "{:?}",
31 lane.get_nearest_side_of_road(&app.primary.map)
32 ));
33 }
34 g.draw_mouse_tooltip(txt);
35 }
36 }
37 }
38
39 pub fn dump_debug(id: ID, map: &Map, sim: &Sim) {
40 match id {
41 ID::Lane(id) => {
42 let l = map.get_l(id);
43 println!("{}", abstutil::to_json(l));
44
45 sim.debug_lane(id);
46
47 let r = map.get_parent(id);
48 println!("Parent {} ({}) points to {}", r.id, r.orig_id, r.dst_i);
49 println!("{}", abstutil::to_json(r));
50 }
51 ID::Intersection(id) => {
52 let i = map.get_i(id);
53 println!("{}", abstutil::to_json(i));
54
55 println!("{}", sim.debug_intersection_json(id, map));
56
57 println!("{} connecting:", i.orig_id);
58 for r in &i.roads {
59 let road = map.get_r(*r);
60 println!("- {} = {}", road.id, road.orig_id);
61 }
62 }
63 ID::Building(id) => {
64 println!("{}", abstutil::to_json(map.get_b(id)));
65 }
66 ID::ParkingLot(id) => {
67 println!("{}", abstutil::to_json(map.get_pl(id)));
68 }
69 ID::Car(id) => {
70 sim.debug_car(id);
71 if let Some(t) = sim.agent_to_trip(AgentID::Car(id)) {
72 println!("Trip log for {}", t);
73 for p in sim.get_analytics().get_trip_phases(t, map) {
74 println!("- {:?}", p);
75 }
76 }
77 }
78 ID::Pedestrian(id) => {
79 sim.debug_ped(id);
80 if let Some(t) = sim.agent_to_trip(AgentID::Pedestrian(id)) {
81 println!("Trip log for {}", t);
82 for p in sim.get_analytics().get_trip_phases(t, map) {
83 println!("- {:?}", p);
84 }
85 }
86 }
87 ID::PedCrowd(members) => {
88 println!("Crowd with {} members", members.len());
89 for p in members {
90 sim.debug_ped(p);
91 }
92 }
93 ID::TransitStop(id) => {
94 println!("{}", abstutil::to_json(map.get_ts(id)));
95 }
96 ID::Area(id) => {
97 println!("{}", abstutil::to_json(map.get_a(id)));
98 }
99 ID::Road(_) => unreachable!(),
100 }
101 }
102
103 pub fn debug_json(id: ID, map: &Map, sim: &Sim) {
104 let json_string = match id {
105 ID::Lane(id) => abstutil::to_json(map.get_l(id)),
106 ID::Intersection(id) => {
107 let json1 = abstutil::to_json(map.get_i(id));
108 let json2 = sim.debug_intersection_json(id, map);
109 format!("[{json1}, {json2}]")
110 }
111 ID::Building(id) => abstutil::to_json(map.get_b(id)),
112 ID::ParkingLot(id) => abstutil::to_json(map.get_pl(id)),
113 ID::Car(id) => sim.debug_agent_json(AgentID::Car(id)),
114 ID::Pedestrian(id) => sim.debug_agent_json(AgentID::Pedestrian(id)),
115 ID::PedCrowd(members) => sim.debug_agent_json(AgentID::Pedestrian(members[0])),
117 ID::TransitStop(id) => abstutil::to_json(map.get_ts(id)),
118 ID::Area(id) => abstutil::to_json(map.get_a(id)),
119 ID::Road(_) => unreachable!(),
120 };
121 #[cfg(target_arch = "wasm32")]
122 {
123 info!("{}", json_string);
124 }
125 #[cfg(not(target_arch = "wasm32"))]
126 {
127 use std::io::Write;
128
129 let path = format!("{}/abst_obj.json", std::env::temp_dir().display());
131 {
132 let mut f = fs_err::File::create(&path).unwrap();
133 writeln!(f, "{}", json_string).unwrap();
134 }
135 if let Err(err) = std::process::Command::new("dadroit").arg(path).spawn() {
140 warn!("Couldn't launch dadroit: {}", err);
141 }
142 }
143 }
144}