mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-29 04:35:51 +03:00
use Event::Alert instead of random println's, and make better controls for handling these
This commit is contained in:
parent
cce4fbe80d
commit
597ee6c47e
@ -6,7 +6,7 @@ use crate::render::DrawMap;
|
|||||||
use ezgui::{Choice, EventCtx, GfxCtx, Wizard, WrappedWizard};
|
use ezgui::{Choice, EventCtx, GfxCtx, Wizard, WrappedWizard};
|
||||||
use geom::Duration;
|
use geom::Duration;
|
||||||
use map_model::MapEdits;
|
use map_model::MapEdits;
|
||||||
use sim::{ABTest, Scenario, SimFlags, SimOptions};
|
use sim::{ABTest, AlertHandler, Scenario, SimFlags, SimOptions};
|
||||||
|
|
||||||
pub struct PickABTest;
|
pub struct PickABTest;
|
||||||
impl PickABTest {
|
impl PickABTest {
|
||||||
@ -167,6 +167,7 @@ fn launch_test(test: &ABTest, app: &mut App, ctx: &mut EventCtx) -> ABTestMode {
|
|||||||
.opts
|
.opts
|
||||||
.break_turn_conflict_cycles,
|
.break_turn_conflict_cycles,
|
||||||
enable_pandemic_model: None,
|
enable_pandemic_model: None,
|
||||||
|
alerts: AlertHandler::Print,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
..current_flags.clone()
|
..current_flags.clone()
|
||||||
|
@ -274,27 +274,22 @@ impl SpeedControls {
|
|||||||
if !alerts.is_empty() {
|
if !alerts.is_empty() {
|
||||||
self.pause(ctx, app);
|
self.pause(ctx, app);
|
||||||
|
|
||||||
// Just go to the first one, but print all messages
|
let popup = msg("Alerts", alerts.iter().map(|(_, _, msg)| msg).collect());
|
||||||
let id = ID::Intersection(alerts[0].1);
|
if let Some(i) = alerts[0].1 {
|
||||||
return Some(Transition::PushTwice(
|
// Just go to the first one, but print all messages
|
||||||
msg(
|
return Some(Transition::PushTwice(
|
||||||
"Alerts",
|
popup,
|
||||||
alerts
|
Warping::new(
|
||||||
.into_iter()
|
ctx,
|
||||||
.map(|(_, _, msg)| {
|
ID::Intersection(i).canonical_point(&app.primary).unwrap(),
|
||||||
println!("Alert: {}", msg);
|
Some(10.0),
|
||||||
msg
|
None,
|
||||||
})
|
&mut app.primary,
|
||||||
.collect(),
|
),
|
||||||
),
|
));
|
||||||
Warping::new(
|
} else {
|
||||||
ctx,
|
return Some(Transition::Push(popup));
|
||||||
id.canonical_point(&app.primary).unwrap(),
|
}
|
||||||
Some(10.0),
|
|
||||||
None,
|
|
||||||
&mut app.primary,
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
@ -517,9 +512,13 @@ impl State for TimeWarpScreen {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
// TODO secondary for a/b test mode
|
// TODO secondary for a/b test mode
|
||||||
// For now, don't stop for this
|
|
||||||
for (t, i, msg) in app.primary.sim.clear_alerts() {
|
for (t, maybe_i, alert) in app.primary.sim.clear_alerts() {
|
||||||
println!("- Alert: At {}, near {}, {}", t, i, msg);
|
// TODO Just the first :(
|
||||||
|
return Transition::Replace(msg(
|
||||||
|
"Alert",
|
||||||
|
vec![format!("At {}, near {:?}, {}", t, maybe_i, alert)],
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// I'm covered in shame for not doing this from the start.
|
// I'm covered in shame for not doing this from the start.
|
||||||
|
@ -26,7 +26,7 @@ pub struct Analytics {
|
|||||||
pub intersection_delays: BTreeMap<IntersectionID, Vec<(Time, Duration)>>,
|
pub intersection_delays: BTreeMap<IntersectionID, Vec<(Time, Duration)>>,
|
||||||
// Per parking lane, when does a spot become filled (true) or free (false)
|
// Per parking lane, when does a spot become filled (true) or free (false)
|
||||||
parking_spot_changes: BTreeMap<LaneID, Vec<(Time, bool)>>,
|
parking_spot_changes: BTreeMap<LaneID, Vec<(Time, bool)>>,
|
||||||
pub(crate) alerts: Vec<(Time, IntersectionID, String)>,
|
pub(crate) alerts: Vec<(Time, Option<IntersectionID>, String)>,
|
||||||
|
|
||||||
// After we restore from a savestate, don't record anything. This is only going to make sense
|
// After we restore from a savestate, don't record anything. This is only going to make sense
|
||||||
// if savestates are only used for quickly previewing against prebaked results, where we have
|
// if savestates are only used for quickly previewing against prebaked results, where we have
|
||||||
|
@ -47,7 +47,8 @@ pub enum Event {
|
|||||||
// to plumb info into Analytics is Event.
|
// to plumb info into Analytics is Event.
|
||||||
PathAmended(Path),
|
PathAmended(Path),
|
||||||
|
|
||||||
Alert(IntersectionID, String),
|
// TODO Also buildings
|
||||||
|
Alert(Option<IntersectionID>, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
@ -23,7 +23,7 @@ pub(crate) use self::mechanics::{
|
|||||||
pub(crate) use self::pandemic::PandemicModel;
|
pub(crate) use self::pandemic::PandemicModel;
|
||||||
pub(crate) use self::router::{ActionAtEnd, Router};
|
pub(crate) use self::router::{ActionAtEnd, Router};
|
||||||
pub(crate) use self::scheduler::{Command, Scheduler};
|
pub(crate) use self::scheduler::{Command, Scheduler};
|
||||||
pub use self::sim::{AgentProperties, Sim, SimOptions};
|
pub use self::sim::{AgentProperties, AlertHandler, Sim, SimOptions};
|
||||||
pub(crate) use self::transit::TransitSimState;
|
pub(crate) use self::transit::TransitSimState;
|
||||||
pub use self::trips::{Person, PersonState, TripCount, TripResult};
|
pub use self::trips::{Person, PersonState, TripCount, TripResult};
|
||||||
pub use self::trips::{TripEndpoint, TripMode};
|
pub use self::trips::{TripEndpoint, TripMode};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{Scenario, Sim, SimOptions};
|
use crate::{AlertHandler, Scenario, Sim, SimOptions};
|
||||||
use abstutil::CmdArgs;
|
use abstutil::CmdArgs;
|
||||||
use geom::Duration;
|
use geom::Duration;
|
||||||
use map_model::{Map, MapEdits};
|
use map_model::{Map, MapEdits};
|
||||||
@ -41,6 +41,15 @@ impl SimFlags {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
alerts: args
|
||||||
|
.optional("--alerts")
|
||||||
|
.map(|x| match x.as_ref() {
|
||||||
|
"print" => AlertHandler::Print,
|
||||||
|
"block" => AlertHandler::Block,
|
||||||
|
"silence" => AlertHandler::Silence,
|
||||||
|
_ => panic!("Bad --alerts={}. Must be print|block|silence", x),
|
||||||
|
})
|
||||||
|
.unwrap_or(AlertHandler::Print),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -395,12 +395,10 @@ impl State {
|
|||||||
while !queue.is_empty() {
|
while !queue.is_empty() {
|
||||||
let current = queue.pop().unwrap();
|
let current = queue.pop().unwrap();
|
||||||
if !seen.is_empty() && current == req.agent {
|
if !seen.is_empty() && current == req.agent {
|
||||||
if false {
|
events.push(Event::Alert(
|
||||||
events.push(Event::Alert(
|
Some(req.turn.parent),
|
||||||
req.turn.parent,
|
format!("Turn conflict cycle involving {:?}", seen),
|
||||||
format!("Turn conflict cycle involving {:?}", seen),
|
));
|
||||||
));
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Because the blocked-by relation is many-to-many, this might happen.
|
// Because the blocked-by relation is many-to-many, this might happen.
|
||||||
@ -539,11 +537,13 @@ impl State {
|
|||||||
if time_to_cross > remaining_phase_time {
|
if time_to_cross > remaining_phase_time {
|
||||||
// Actually, we might have bigger problems...
|
// Actually, we might have bigger problems...
|
||||||
if time_to_cross > phase.duration {
|
if time_to_cross > phase.duration {
|
||||||
println!(
|
events.push(Event::Alert(
|
||||||
"OYYY! {:?} is impossible to fit into phase duration of {}. Allowing, but fix \
|
Some(req.turn.parent),
|
||||||
the policy!",
|
format!(
|
||||||
req, phase.duration
|
"{:?} is impossible to fit into phase duration of {}",
|
||||||
);
|
req, phase.duration
|
||||||
|
),
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,10 @@ pub struct Sim {
|
|||||||
#[derivative(PartialEq = "ignore")]
|
#[derivative(PartialEq = "ignore")]
|
||||||
#[serde(skip_serializing, skip_deserializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
check_for_gridlock: Option<(Time, Duration)>,
|
check_for_gridlock: Option<(Time, Duration)>,
|
||||||
|
|
||||||
|
#[derivative(PartialEq = "ignore")]
|
||||||
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
|
alerts: AlertHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -72,6 +76,23 @@ pub struct SimOptions {
|
|||||||
pub recalc_lanechanging: bool,
|
pub recalc_lanechanging: bool,
|
||||||
pub break_turn_conflict_cycles: bool,
|
pub break_turn_conflict_cycles: bool,
|
||||||
pub enable_pandemic_model: Option<XorShiftRng>,
|
pub enable_pandemic_model: Option<XorShiftRng>,
|
||||||
|
pub alerts: AlertHandler,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum AlertHandler {
|
||||||
|
// Just print the alert to STDOUT
|
||||||
|
Print,
|
||||||
|
// Print the alert to STDOUT and don't proceed until the UI calls clear_alerts()
|
||||||
|
Block,
|
||||||
|
// Don't do anything
|
||||||
|
Silence,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::default::Default for AlertHandler {
|
||||||
|
fn default() -> AlertHandler {
|
||||||
|
AlertHandler::Print
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimOptions {
|
impl SimOptions {
|
||||||
@ -84,6 +105,7 @@ impl SimOptions {
|
|||||||
recalc_lanechanging: true,
|
recalc_lanechanging: true,
|
||||||
break_turn_conflict_cycles: false,
|
break_turn_conflict_cycles: false,
|
||||||
enable_pandemic_model: None,
|
enable_pandemic_model: None,
|
||||||
|
alerts: AlertHandler::Print,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,6 +145,7 @@ impl Sim {
|
|||||||
step_count: 0,
|
step_count: 0,
|
||||||
trip_positions: None,
|
trip_positions: None,
|
||||||
check_for_gridlock: None,
|
check_for_gridlock: None,
|
||||||
|
alerts: opts.alerts,
|
||||||
|
|
||||||
analytics: Analytics::new(),
|
analytics: Analytics::new(),
|
||||||
}
|
}
|
||||||
@ -586,10 +609,25 @@ impl Sim {
|
|||||||
|
|
||||||
timer.start(format!("Advance sim to {}", end_time));
|
timer.start(format!("Advance sim to {}", end_time));
|
||||||
while self.time < end_time {
|
while self.time < end_time {
|
||||||
if !self.analytics.alerts.is_empty() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
self.minimal_step(map, end_time - self.time);
|
self.minimal_step(map, end_time - self.time);
|
||||||
|
if !self.analytics.alerts.is_empty() {
|
||||||
|
match self.alerts {
|
||||||
|
AlertHandler::Print => {
|
||||||
|
for (t, _, msg) in self.analytics.alerts.drain(..) {
|
||||||
|
println!("Alert at {}: {}", t, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AlertHandler::Block => {
|
||||||
|
for (t, _, msg) in &self.analytics.alerts {
|
||||||
|
println!("Alert at {}: {}", t, msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AlertHandler::Silence => {
|
||||||
|
self.analytics.alerts.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if Duration::realtime_elapsed(last_update) >= Duration::seconds(1.0) {
|
if Duration::realtime_elapsed(last_update) >= Duration::seconds(1.0) {
|
||||||
// TODO Not timer?
|
// TODO Not timer?
|
||||||
println!(
|
println!(
|
||||||
@ -627,10 +665,25 @@ impl Sim {
|
|||||||
let end_time = self.time + dt;
|
let end_time = self.time + dt;
|
||||||
|
|
||||||
while self.time < end_time && Duration::realtime_elapsed(started_at) < real_time_limit {
|
while self.time < end_time && Duration::realtime_elapsed(started_at) < real_time_limit {
|
||||||
if !self.analytics.alerts.is_empty() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
self.minimal_step(map, end_time - self.time);
|
self.minimal_step(map, end_time - self.time);
|
||||||
|
if !self.analytics.alerts.is_empty() {
|
||||||
|
match self.alerts {
|
||||||
|
AlertHandler::Print => {
|
||||||
|
for (t, _, msg) in self.analytics.alerts.drain(..) {
|
||||||
|
println!("Alert at {}: {}", t, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AlertHandler::Block => {
|
||||||
|
for (t, _, msg) in &self.analytics.alerts {
|
||||||
|
println!("Alert at {}: {}", t, msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AlertHandler::Silence => {
|
||||||
|
self.analytics.alerts.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if let Some((ref mut t, dt)) = self.check_for_gridlock {
|
if let Some((ref mut t, dt)) = self.check_for_gridlock {
|
||||||
if self.time >= *t {
|
if self.time >= *t {
|
||||||
*t += dt;
|
*t += dt;
|
||||||
@ -1134,7 +1187,7 @@ impl Sim {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_alerts(&mut self) -> Vec<(Time, IntersectionID, String)> {
|
pub fn clear_alerts(&mut self) -> Vec<(Time, Option<IntersectionID>, String)> {
|
||||||
std::mem::replace(&mut self.analytics.alerts, Vec::new())
|
std::mem::replace(&mut self.analytics.alerts, Vec::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
156
sim/src/trips.rs
156
sim/src/trips.rs
@ -195,6 +195,7 @@ impl TripManager {
|
|||||||
&self.people[trip.person.0],
|
&self.people[trip.person.0],
|
||||||
map,
|
map,
|
||||||
scheduler,
|
scheduler,
|
||||||
|
&mut self.events,
|
||||||
) {
|
) {
|
||||||
self.unfinished_trips -= 1;
|
self.unfinished_trips -= 1;
|
||||||
}
|
}
|
||||||
@ -242,10 +243,13 @@ impl TripManager {
|
|||||||
let path = if let Some(p) = map.pathfind(req.clone()) {
|
let path = if let Some(p) = map.pathfind(req.clone()) {
|
||||||
p
|
p
|
||||||
} else {
|
} else {
|
||||||
println!(
|
self.events.push(Event::Alert(
|
||||||
"Aborting {} at {} because no path for the car portion! {} to {}",
|
None,
|
||||||
trip.id, now, start, end
|
format!(
|
||||||
);
|
"Aborting {} because no path for the car portion! {} to {}",
|
||||||
|
trip.id, start, end
|
||||||
|
),
|
||||||
|
));
|
||||||
// Move the car to the destination...
|
// Move the car to the destination...
|
||||||
parking.remove_parked_car(parked_car.clone());
|
parking.remove_parked_car(parked_car.clone());
|
||||||
let trip = trip.id;
|
let trip = trip.id;
|
||||||
@ -324,11 +328,14 @@ impl TripManager {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
println!(
|
self.events.push(Event::Alert(
|
||||||
"Aborting {} at {} because no path for the bike portion (or sidewalk connection \
|
None,
|
||||||
at the end)! {} to {}",
|
format!(
|
||||||
trip.id, now, driving_pos, end
|
"Aborting {} because no path for the bike portion (or sidewalk connection at \
|
||||||
);
|
the end)! {} to {}",
|
||||||
|
trip.id, driving_pos, end
|
||||||
|
),
|
||||||
|
));
|
||||||
let trip = trip.id;
|
let trip = trip.id;
|
||||||
self.abort_trip(now, trip, None, parking, scheduler, map);
|
self.abort_trip(now, trip, None, parking, scheduler, map);
|
||||||
}
|
}
|
||||||
@ -357,7 +364,14 @@ impl TripManager {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if !trip.spawn_ped(now, bike_rack, &self.people[trip.person.0], map, scheduler) {
|
if !trip.spawn_ped(
|
||||||
|
now,
|
||||||
|
bike_rack,
|
||||||
|
&self.people[trip.person.0],
|
||||||
|
map,
|
||||||
|
scheduler,
|
||||||
|
&mut self.events,
|
||||||
|
) {
|
||||||
self.unfinished_trips -= 1;
|
self.unfinished_trips -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -478,7 +492,14 @@ impl TripManager {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if !trip.spawn_ped(now, start, &self.people[trip.person.0], map, scheduler) {
|
if !trip.spawn_ped(
|
||||||
|
now,
|
||||||
|
start,
|
||||||
|
&self.people[trip.person.0],
|
||||||
|
map,
|
||||||
|
scheduler,
|
||||||
|
&mut self.events,
|
||||||
|
) {
|
||||||
self.unfinished_trips -= 1;
|
self.unfinished_trips -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -599,17 +620,23 @@ impl TripManager {
|
|||||||
.map(|(_, spot, _)| spot)
|
.map(|(_, spot, _)| spot)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
println!(
|
self.events.push(Event::Alert(
|
||||||
"{} had a trip aborted, and their car was warped to {:?}",
|
None,
|
||||||
person, spot
|
format!(
|
||||||
);
|
"{} had a trip aborted, and their car was warped to {:?}",
|
||||||
|
person, spot
|
||||||
|
),
|
||||||
|
));
|
||||||
parking.reserve_spot(spot);
|
parking.reserve_spot(spot);
|
||||||
parking.add_parked_car(ParkedCar { vehicle, spot });
|
parking.add_parked_car(ParkedCar { vehicle, spot });
|
||||||
} else {
|
} else {
|
||||||
println!(
|
self.events.push(Event::Alert(
|
||||||
"{} had a trip aborted, but nowhere to warp their car! Sucks.",
|
None,
|
||||||
person
|
format!(
|
||||||
);
|
"{} had a trip aborted, but nowhere to warp their car! Sucks.",
|
||||||
|
person
|
||||||
|
),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -798,10 +825,13 @@ impl TripManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let (trip, spec, maybe_req, maybe_path) = person.delayed_trips.remove(0);
|
let (trip, spec, maybe_req, maybe_path) = person.delayed_trips.remove(0);
|
||||||
println!(
|
self.events.push(Event::Alert(
|
||||||
"At {}, {} just freed up, so starting delayed trip {}",
|
None,
|
||||||
now, person.id, trip
|
format!(
|
||||||
);
|
"{} just freed up, so starting delayed trip {}",
|
||||||
|
person.id, trip
|
||||||
|
),
|
||||||
|
));
|
||||||
self.start_trip(
|
self.start_trip(
|
||||||
now, trip, spec, maybe_req, maybe_path, parking, scheduler, map,
|
now, trip, spec, maybe_req, maybe_path, parking, scheduler, map,
|
||||||
);
|
);
|
||||||
@ -821,10 +851,13 @@ impl TripManager {
|
|||||||
let person = &mut self.people[self.trips[trip.0].person.0];
|
let person = &mut self.people[self.trips[trip.0].person.0];
|
||||||
if let PersonState::Trip(_) = person.state {
|
if let PersonState::Trip(_) = person.state {
|
||||||
// Previous trip isn't done. Defer this one!
|
// Previous trip isn't done. Defer this one!
|
||||||
println!(
|
self.events.push(Event::Alert(
|
||||||
"At {}, {} is still doing a trip, so not starting {}",
|
None,
|
||||||
now, person.id, trip
|
format!(
|
||||||
);
|
"{} is still doing a trip, so not starting {}",
|
||||||
|
person.id, trip
|
||||||
|
),
|
||||||
|
));
|
||||||
person
|
person
|
||||||
.delayed_trips
|
.delayed_trips
|
||||||
.push((trip, spec, maybe_req, maybe_path));
|
.push((trip, spec, maybe_req, maybe_path));
|
||||||
@ -864,19 +897,25 @@ impl TripManager {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
println!(
|
self.events.push(Event::Alert(
|
||||||
"VehicleAppearing trip couldn't find the first path (or no bike->sidewalk \
|
None,
|
||||||
connection at the end): {}",
|
format!(
|
||||||
req
|
"VehicleAppearing trip couldn't find the first path (or no \
|
||||||
);
|
bike->sidewalk connection at the end): {}",
|
||||||
|
req
|
||||||
|
),
|
||||||
|
));
|
||||||
self.abort_trip(now, trip, Some(vehicle), parking, scheduler, map);
|
self.abort_trip(now, trip, Some(vehicle), parking, scheduler, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TripSpec::NoRoomToSpawn { i, use_vehicle, .. } => {
|
TripSpec::NoRoomToSpawn { i, use_vehicle, .. } => {
|
||||||
println!(
|
self.events.push(Event::Alert(
|
||||||
"{} couldn't spawn at border {}, just aborting",
|
Some(i),
|
||||||
person.id, i
|
format!(
|
||||||
);
|
"{} couldn't spawn at border {}, just aborting",
|
||||||
|
person.id, i
|
||||||
|
),
|
||||||
|
));
|
||||||
let vehicle = person.get_vehicle(use_vehicle);
|
let vehicle = person.get_vehicle(use_vehicle);
|
||||||
self.abort_trip(now, trip, Some(vehicle), parking, scheduler, map);
|
self.abort_trip(now, trip, Some(vehicle), parking, scheduler, map);
|
||||||
}
|
}
|
||||||
@ -912,7 +951,10 @@ impl TripManager {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
println!("UsingParkedCar trip couldn't find the walking path {}", req);
|
self.events.push(Event::Alert(
|
||||||
|
None,
|
||||||
|
format!("UsingParkedCar trip couldn't find the walking path {}", req),
|
||||||
|
));
|
||||||
// Move the car to the destination
|
// Move the car to the destination
|
||||||
parking.remove_parked_car(parked_car.clone());
|
parking.remove_parked_car(parked_car.clone());
|
||||||
self.abort_trip(
|
self.abort_trip(
|
||||||
@ -927,11 +969,14 @@ impl TripManager {
|
|||||||
} else {
|
} else {
|
||||||
// This should only happen when a driving trip has been aborted and there was
|
// This should only happen when a driving trip has been aborted and there was
|
||||||
// absolutely no room to warp the car.
|
// absolutely no room to warp the car.
|
||||||
println!(
|
self.events.push(Event::Alert(
|
||||||
"At {}, {} should have {} parked somewhere, but it's unavailable, so \
|
None,
|
||||||
aborting {}",
|
format!(
|
||||||
now, person.id, car, trip
|
"{} should have {} parked somewhere, but it's unavailable, so \
|
||||||
);
|
aborting {}",
|
||||||
|
person.id, car, trip
|
||||||
|
),
|
||||||
|
));
|
||||||
self.abort_trip(now, trip, None, parking, scheduler, map);
|
self.abort_trip(now, trip, None, parking, scheduler, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -963,7 +1008,10 @@ impl TripManager {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
println!("JustWalking trip couldn't find the first path {}", req);
|
self.events.push(Event::Alert(
|
||||||
|
None,
|
||||||
|
format!("JustWalking trip couldn't find the first path {}", req),
|
||||||
|
));
|
||||||
self.abort_trip(now, trip, None, parking, scheduler, map);
|
self.abort_trip(now, trip, None, parking, scheduler, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -997,7 +1045,10 @@ impl TripManager {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
println!("UsingBike trip couldn't find the first path {}", req);
|
self.events.push(Event::Alert(
|
||||||
|
None,
|
||||||
|
format!("UsingBike trip couldn't find the first path {}", req),
|
||||||
|
));
|
||||||
self.abort_trip(now, trip, None, parking, scheduler, map);
|
self.abort_trip(now, trip, None, parking, scheduler, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1030,7 +1081,10 @@ impl TripManager {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
println!("UsingTransit trip couldn't find the first path {}", req);
|
self.events.push(Event::Alert(
|
||||||
|
None,
|
||||||
|
format!("UsingTransit trip couldn't find the first path {}", req),
|
||||||
|
));
|
||||||
self.abort_trip(now, trip, None, parking, scheduler, map);
|
self.abort_trip(now, trip, None, parking, scheduler, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1061,6 +1115,7 @@ impl Trip {
|
|||||||
person: &Person,
|
person: &Person,
|
||||||
map: &Map,
|
map: &Map,
|
||||||
scheduler: &mut Scheduler,
|
scheduler: &mut Scheduler,
|
||||||
|
events: &mut Vec<Event>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let walk_to = match self.legs[0] {
|
let walk_to = match self.legs[0] {
|
||||||
TripLeg::Walk(ref to) => to.clone(),
|
TripLeg::Walk(ref to) => to.clone(),
|
||||||
@ -1075,10 +1130,13 @@ impl Trip {
|
|||||||
let path = if let Some(p) = map.pathfind(req.clone()) {
|
let path = if let Some(p) = map.pathfind(req.clone()) {
|
||||||
p
|
p
|
||||||
} else {
|
} else {
|
||||||
println!(
|
events.push(Event::Alert(
|
||||||
"Aborting {} at {} because no path for the walking portion! {:?} to {:?}",
|
None,
|
||||||
self.id, now, start, walk_to
|
format!(
|
||||||
);
|
"Aborting {} because no path for the walking portion! {:?} to {:?}",
|
||||||
|
self.id, start, walk_to
|
||||||
|
),
|
||||||
|
));
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user