mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 01:13:53 +03:00
avoid a few crashes, mostly involving trips that were aborted in the
baseline
This commit is contained in:
parent
d80513235d
commit
5cf0b72bac
@ -6,6 +6,7 @@ use crate::sandbox::SandboxMode;
|
||||
use ezgui::{EventCtx, GfxCtx, Warper, Wizard};
|
||||
use geom::Pt2D;
|
||||
use map_model::{AreaID, BuildingID, IntersectionID, LaneID, RoadID};
|
||||
use maplit::btreemap;
|
||||
use sim::{PedestrianID, PersonID, TripID};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
@ -110,6 +111,7 @@ fn inner_warp(ctx: &mut EventCtx, app: &mut App, line: &str) -> Option<Transitio
|
||||
'p' => ID::Pedestrian(PedestrianID(idx)),
|
||||
'P' => {
|
||||
let id = PersonID(idx);
|
||||
app.primary.sim.lookup_person(id)?;
|
||||
return Some(Transition::PopWithData(Box::new(move |state, app, ctx| {
|
||||
// Other states pretty much don't use info panels.
|
||||
if let Some(ref mut s) = state.downcast_mut::<SandboxMode>() {
|
||||
@ -128,7 +130,22 @@ fn inner_warp(ctx: &mut EventCtx, app: &mut App, line: &str) -> Option<Transitio
|
||||
let c = app.primary.sim.lookup_car_id(idx)?;
|
||||
ID::Car(c)
|
||||
}
|
||||
't' => ID::from_agent(app.primary.sim.trip_to_agent(TripID(idx)).ok()?),
|
||||
't' => {
|
||||
let trip = TripID(idx);
|
||||
let person = app.primary.sim.trip_to_person(trip);
|
||||
return Some(Transition::PopWithData(Box::new(move |state, app, ctx| {
|
||||
// Other states pretty much don't use info panels.
|
||||
if let Some(ref mut s) = state.downcast_mut::<SandboxMode>() {
|
||||
let mut actions = s.contextual_actions();
|
||||
s.controls.common.as_mut().unwrap().launch_info_panel(
|
||||
ctx,
|
||||
app,
|
||||
Tab::PersonTrips(person, btreemap! {trip => true}),
|
||||
&mut actions,
|
||||
);
|
||||
}
|
||||
})));
|
||||
}
|
||||
'T' => {
|
||||
let t = app.primary.map.lookup_turn_by_idx(idx)?;
|
||||
ID::Turn(t)
|
||||
|
@ -65,7 +65,11 @@ pub fn trips(
|
||||
// TODO No details. Weird case.
|
||||
assert!(wheres_waldo);
|
||||
wheres_waldo = false;
|
||||
("ongoing", Color::hex("#7FFA4D"), None)
|
||||
(
|
||||
"ongoing",
|
||||
Color::hex("#7FFA4D"),
|
||||
open_trips.get(t).map(|_| Widget::nothing()),
|
||||
)
|
||||
}
|
||||
TripResult::TripDone => {
|
||||
assert!(wheres_waldo);
|
||||
@ -79,7 +83,11 @@ pub fn trips(
|
||||
}
|
||||
TripResult::TripAborted => {
|
||||
// Aborted trips can happen anywhere in the schedule right now
|
||||
("cancelled", Color::hex("#EB3223"), None)
|
||||
(
|
||||
"cancelled",
|
||||
Color::hex("#EB3223"),
|
||||
open_trips.get(t).map(|_| Widget::nothing()),
|
||||
)
|
||||
}
|
||||
TripResult::TripDoesntExist => unreachable!(),
|
||||
};
|
||||
|
@ -111,15 +111,16 @@ pub fn future(ctx: &mut EventCtx, app: &App, trip: TripID, details: &mut Details
|
||||
|
||||
let mut col = Vec::new();
|
||||
|
||||
if app.has_prebaked().is_some() {
|
||||
let phases = app.prebaked().get_trip_phases(trip, &app.primary.map);
|
||||
let estimated_trip_time =
|
||||
phases.last().as_ref().and_then(|p| p.end_time).unwrap() - start_time;
|
||||
if let Some(estimated_trip_time) = app
|
||||
.has_prebaked()
|
||||
.and_then(|_| app.prebaked().finished_trip_time(trip))
|
||||
{
|
||||
col.extend(make_table(
|
||||
ctx,
|
||||
vec![("Estimated trip time", estimated_trip_time.to_string())],
|
||||
));
|
||||
|
||||
let phases = app.prebaked().get_trip_phases(trip, &app.primary.map);
|
||||
col.push(make_timeline(ctx, app, trip, details, phases, None));
|
||||
} else {
|
||||
// TODO Warp buttons. make_table is showing its age.
|
||||
|
@ -129,7 +129,12 @@ fn make(ctx: &mut EventCtx, app: &App, sort: SortBy, descending: bool) -> Compos
|
||||
let (_, waiting) = sim.finished_trip_time(*id).unwrap();
|
||||
let (departure, _, _, _) = sim.trip_info(*id);
|
||||
let duration_before = if app.has_prebaked().is_some() {
|
||||
app.prebaked().finished_trip_time(*id).unwrap()
|
||||
if let Some(dt) = app.prebaked().finished_trip_time(*id) {
|
||||
dt
|
||||
} else {
|
||||
// Aborted
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
Duration::ZERO
|
||||
};
|
||||
|
@ -178,6 +178,7 @@ fn get_score(app: &App, trips: &Vec<TripID>) -> (Duration, Duration, usize) {
|
||||
if let Some((total, _)) = app.primary.sim.finished_trip_time(*t) {
|
||||
done += 1;
|
||||
after += total;
|
||||
// Assume all trips completed before changes
|
||||
before += app.prebaked().finished_trip_time(*t).unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -225,12 +225,16 @@ impl Analytics {
|
||||
(all, num_aborted, per_mode)
|
||||
}
|
||||
|
||||
// Ignores the current time.
|
||||
// Ignores the current time. Returns None for aborted trips.
|
||||
pub fn finished_trip_time(&self, trip: TripID) -> Option<Duration> {
|
||||
// TODO This is so inefficient!
|
||||
for (_, id, _, dt) in &self.finished_trips {
|
||||
for (_, id, maybe_mode, dt) in &self.finished_trips {
|
||||
if *id == trip {
|
||||
return Some(*dt);
|
||||
if maybe_mode.is_some() {
|
||||
return Some(*dt);
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
|
@ -988,9 +988,12 @@ impl Sim {
|
||||
self.parking.get_car_owned_by(id)
|
||||
}
|
||||
|
||||
pub fn get_person(&self, id: PersonID) -> &Person {
|
||||
pub fn lookup_person(&self, id: PersonID) -> Option<&Person> {
|
||||
self.trips.get_person(id)
|
||||
}
|
||||
pub fn get_person(&self, id: PersonID) -> &Person {
|
||||
self.trips.get_person(id).unwrap()
|
||||
}
|
||||
pub fn get_all_people(&self) -> &Vec<Person> {
|
||||
self.trips.get_all_people()
|
||||
}
|
||||
@ -1059,7 +1062,7 @@ impl Sim {
|
||||
TripResult::ModeChange
|
||||
}
|
||||
pub fn get_canonical_pt_per_person(&self, p: PersonID, map: &Map) -> Option<Pt2D> {
|
||||
match self.trips.get_person(p).state {
|
||||
match self.trips.get_person(p)?.state {
|
||||
PersonState::Inside(b) => Some(map.get_b(b).polygon.center()),
|
||||
PersonState::Trip(t) => self.get_canonical_pt_per_trip(t, map).ok(),
|
||||
PersonState::OffMap | PersonState::Limbo => None,
|
||||
|
@ -699,8 +699,8 @@ impl TripManager {
|
||||
people
|
||||
}
|
||||
|
||||
pub fn get_person(&self, p: PersonID) -> &Person {
|
||||
&self.people[p.0]
|
||||
pub fn get_person(&self, p: PersonID) -> Option<&Person> {
|
||||
self.people.get(p.0)
|
||||
}
|
||||
pub fn get_all_people(&self) -> &Vec<Person> {
|
||||
&self.people
|
||||
|
Loading…
Reference in New Issue
Block a user