see modified trips in the table and info panels

This commit is contained in:
Dustin Carlino 2020-07-14 16:10:50 -07:00
parent e691545b63
commit 614354271a
15 changed files with 166 additions and 45 deletions

View File

@ -794,6 +794,13 @@ impl Composite {
pub fn is_checked(&self, name: &str) -> bool { pub fn is_checked(&self, name: &str) -> bool {
self.find::<Checkbox>(name).enabled self.find::<Checkbox>(name).enabled
} }
pub fn maybe_is_checked(&self, name: &str) -> Option<bool> {
if self.has_widget(name) {
Some(self.find::<Checkbox>(name).enabled)
} else {
None
}
}
pub fn text_box(&self, name: &str) -> String { pub fn text_box(&self, name: &str) -> String {
self.find::<TextBox>(name).get_line() self.find::<TextBox>(name).get_line()

View File

@ -522,6 +522,8 @@ pub struct PerMap {
pub zorder_range: (isize, isize), pub zorder_range: (isize, isize),
// If we ever left edit mode and resumed without restarting from midnight, this is true. // If we ever left edit mode and resumed without restarting from midnight, this is true.
pub dirty_from_edits: bool, pub dirty_from_edits: bool,
// Any ScenarioModifiers in effect?
pub has_modified_trips: bool,
} }
impl PerMap { impl PerMap {
@ -553,6 +555,7 @@ impl PerMap {
zorder_range: (low_z, high_z), zorder_range: (low_z, high_z),
show_zorder: high_z, show_zorder: high_z,
dirty_from_edits: false, dirty_from_edits: false,
has_modified_trips: false,
} }
} }

View File

@ -103,7 +103,7 @@ pub fn people(ctx: &mut EventCtx, app: &App, details: &mut Details, id: Building
for t in &person.trips { for t in &person.trips {
match app.primary.sim.trip_to_agent(*t) { match app.primary.sim.trip_to_agent(*t) {
TripResult::TripNotStarted => { TripResult::TripNotStarted => {
let (start_time, _, _, mode) = app.primary.sim.trip_info(*t); let (start_time, _, _, mode, _) = app.primary.sim.trip_info(*t);
next_trip = Some((start_time, mode)); next_trip = Some((start_time, mode));
break; break;
} }

View File

@ -721,20 +721,17 @@ impl DataOptions {
} }
pub fn from_controls(c: &Composite) -> DataOptions { pub fn from_controls(c: &Composite) -> DataOptions {
let show_before = let show_before = c.maybe_is_checked("Show before changes").unwrap_or(false);
c.has_widget("Show before changes") && c.is_checked("Show before changes");
let mut disabled_modes = BTreeSet::new(); let mut disabled_modes = BTreeSet::new();
for m in TripMode::all() { for m in TripMode::all() {
let label = m.noun(); let label = m.noun();
if c.has_widget(label) && !c.is_checked(label) { if !c.maybe_is_checked(label).unwrap_or(true) {
disabled_modes.insert(m); disabled_modes.insert(m);
} }
} }
DataOptions { DataOptions {
show_before, show_before,
show_end_of_day: show_before show_end_of_day: show_before && c.maybe_is_checked("Show full day").unwrap_or(false),
&& c.has_widget("Show full day")
&& c.is_checked("Show full day"),
disabled_modes, disabled_modes,
} }
} }

View File

@ -117,12 +117,15 @@ pub fn trips(
} }
TripResult::TripDoesntExist => unreachable!(), TripResult::TripDoesntExist => unreachable!(),
}; };
let (_, _, _, trip_mode) = sim.trip_info(*t); let (_, _, _, trip_mode, modified) = sim.trip_info(*t);
// TODO Style wrong. Button should be the entire row. // TODO Style wrong. Button should be the entire row.
rows.push( rows.push(
Widget::custom_row(vec![ Widget::custom_row(vec![
format!("Trip {} ", idx + 1).draw_text(ctx).margin_right(21), format!("Trip {} ", idx + 1)
.draw_text(ctx)
.centered_vert()
.margin_right(21),
Widget::row(vec![ Widget::row(vec![
Widget::draw_svg_transform( Widget::draw_svg_transform(
ctx, ctx,
@ -134,20 +137,31 @@ pub fn trips(
}, },
RewriteColor::ChangeAll(color), RewriteColor::ChangeAll(color),
), ),
Line(trip_status).small().fg(color).draw(ctx), Line(trip_status)
.small()
.fg(color)
.draw(ctx)
.centered_vert(),
]) ])
.fully_rounded() .fully_rounded()
.outline(1.0, color) .outline(1.0, color)
.bg(color.alpha(0.2)) .bg(color.alpha(0.2))
.padding(5) .padding(10)
.margin_right(21), .margin_right(21),
if modified {
Line("modified").draw(ctx).centered_vert().margin_right(15)
} else {
Widget::nothing()
},
if trip_status == "finished" { if trip_status == "finished" {
if let Some(before) = app if let Some(before) = app
.has_prebaked() .has_prebaked()
.and_then(|_| app.prebaked().finished_trip_time(*t)) .and_then(|_| app.prebaked().finished_trip_time(*t))
{ {
let (after, _) = app.primary.sim.finished_trip_time(*t).unwrap(); let (after, _) = app.primary.sim.finished_trip_time(*t).unwrap();
Text::from(cmp_duration_shorter(after, before)).draw(ctx) Text::from(cmp_duration_shorter(after, before))
.draw(ctx)
.centered_vert()
} else { } else {
Widget::nothing() Widget::nothing()
} }
@ -172,6 +186,7 @@ pub fn trips(
), ),
None, None,
) )
.centered_vert()
.align_right(), .align_right(),
]) ])
.outline(2.0, Color::WHITE) .outline(2.0, Color::WHITE)
@ -314,7 +329,7 @@ pub fn schedule(
// TODO Proportional 24-hour timeline would be easier to understand // TODO Proportional 24-hour timeline would be easier to understand
let mut last_t = Time::START_OF_DAY; let mut last_t = Time::START_OF_DAY;
for t in &person.trips { for t in &person.trips {
let (start_time, from, _, _) = app.primary.sim.trip_info(*t); let (start_time, from, _, _, _) = app.primary.sim.trip_info(*t);
let at = match from { let at = match from {
TripEndpoint::Bldg(b) => { TripEndpoint::Bldg(b) => {
let b = app.primary.map.get_b(b); let b = app.primary.map.get_b(b);
@ -334,7 +349,7 @@ pub fn schedule(
last_t = start_time; last_t = start_time;
} }
// Where do they spend the night? // Where do they spend the night?
let (start_time, _, to, _) = app.primary.sim.trip_info(*person.trips.last().unwrap()); let (start_time, _, to, _, _) = app.primary.sim.trip_info(*person.trips.last().unwrap());
let at = match to { let at = match to {
TripEndpoint::Bldg(b) => { TripEndpoint::Bldg(b) => {
let b = app.primary.map.get_b(b); let b = app.primary.map.get_b(b);

View File

@ -50,7 +50,7 @@ pub fn ongoing(
.sim .sim
.get_analytics() .get_analytics()
.get_trip_phases(trip, &app.primary.map); .get_trip_phases(trip, &app.primary.map);
let (start_time, _, _, _) = app.primary.sim.trip_info(trip); let (start_time, _, _, _, _) = app.primary.sim.trip_info(trip);
let col_width = 7; let col_width = 7;
let props = app.primary.sim.agent_properties(agent); let props = app.primary.sim.agent_properties(agent);
@ -143,7 +143,7 @@ pub fn future(
open_trip: &mut OpenTrip, open_trip: &mut OpenTrip,
details: &mut Details, details: &mut Details,
) -> Widget { ) -> Widget {
let (start_time, trip_start, trip_end, _) = app.primary.sim.trip_info(trip); let (start_time, trip_start, trip_end, _, _) = app.primary.sim.trip_info(trip);
let mut col = Vec::new(); let mut col = Vec::new();
@ -206,7 +206,7 @@ pub fn finished(
trip: TripID, trip: TripID,
details: &mut Details, details: &mut Details,
) -> Widget { ) -> Widget {
let (start_time, _, _, _) = app.primary.sim.trip_info(trip); let (start_time, _, _, _, _) = app.primary.sim.trip_info(trip);
let phases = if open_trips[&trip].show_after { let phases = if open_trips[&trip].show_after {
app.primary app.primary
.sim .sim
@ -300,7 +300,7 @@ pub fn finished(
} }
pub fn aborted(ctx: &mut EventCtx, app: &App, trip: TripID) -> Widget { pub fn aborted(ctx: &mut EventCtx, app: &App, trip: TripID) -> Widget {
let (start_time, trip_start, trip_end, _) = app.primary.sim.trip_info(trip); let (start_time, trip_start, trip_end, _, _) = app.primary.sim.trip_info(trip);
let mut col = vec![Text::from_multiline(vec![ let mut col = vec![Text::from_multiline(vec![
Line("A glitch in the simulation happened."), Line("A glitch in the simulation happened."),
@ -336,7 +336,7 @@ fn make_timeline(
let map = &app.primary.map; let map = &app.primary.map;
let sim = &app.primary.sim; let sim = &app.primary.sim;
// TODO Repeating stuff // TODO Repeating stuff
let (start_time, trip_start, trip_end, _) = sim.trip_info(trip); let (start_time, trip_start, trip_end, _, _) = sim.trip_info(trip);
let end_time = phases.last().as_ref().and_then(|p| p.end_time); let end_time = phases.last().as_ref().and_then(|p| p.end_time);
let start_btn = { let start_btn = {

View File

@ -133,8 +133,10 @@ impl Layer for Throughput {
_ => unreachable!(), _ => unreachable!(),
}, },
None => { None => {
let new_compare = self.composite.has_widget("Compare before edits") let new_compare = self
&& self.composite.is_checked("Compare before edits"); .composite
.maybe_is_checked("Compare before edits")
.unwrap_or(false);
if new_compare != self.compare { if new_compare != self.compare {
*self = Throughput::new(ctx, app, new_compare); *self = Throughput::new(ctx, app, new_compare);
self.composite.align_above(ctx, minimap); self.composite.align_above(ctx, minimap);
@ -312,8 +314,10 @@ impl Layer for Delay {
_ => unreachable!(), _ => unreachable!(),
}, },
None => { None => {
let new_compare = self.composite.has_widget("Compare before edits") let new_compare = self
&& self.composite.is_checked("Compare before edits"); .composite
.maybe_is_checked("Compare before edits")
.unwrap_or(false);
if new_compare != self.compare { if new_compare != self.compare {
*self = Delay::new(ctx, app, new_compare); *self = Delay::new(ctx, app, new_compare);
self.composite.align_above(ctx, minimap); self.composite.align_above(ctx, minimap);

View File

@ -165,7 +165,7 @@ fn make(ctx: &mut EventCtx, app: &App, opts: &Options) -> Composite {
// Gather raw data // Gather raw data
let mut data = Vec::new(); let mut data = Vec::new();
for (id, phases) in app.primary.sim.get_analytics().get_all_trip_phases() { for (id, phases) in app.primary.sim.get_analytics().get_all_trip_phases() {
let (_, start, end, _) = app.primary.sim.trip_info(id); let (_, start, end, _, _) = app.primary.sim.trip_info(id);
if !opts.off_map_starts { if !opts.off_map_starts {
if let TripEndpoint::Border(_, _) = start { if let TripEndpoint::Border(_, _) = start {
continue; continue;

View File

@ -28,6 +28,8 @@ struct Options {
modes: BTreeSet<TripMode>, modes: BTreeSet<TripMode>,
off_map_starts: bool, off_map_starts: bool,
off_map_ends: bool, off_map_ends: bool,
unmodified_trips: bool,
modified_trips: bool,
skip: usize, skip: usize,
} }
@ -62,6 +64,8 @@ impl TripTable {
modes: TripMode::all().into_iter().collect(), modes: TripMode::all().into_iter().collect(),
off_map_starts: true, off_map_starts: true,
off_map_ends: true, off_map_ends: true,
unmodified_trips: true,
modified_trips: true,
skip: 0, skip: 0,
}; };
Box::new(TripTable { Box::new(TripTable {
@ -145,11 +149,23 @@ impl State for TripTable {
} }
let off_map_starts = self.composite.is_checked("starting off-map"); let off_map_starts = self.composite.is_checked("starting off-map");
let off_map_ends = self.composite.is_checked("ending off-map"); let off_map_ends = self.composite.is_checked("ending off-map");
let unmodified_trips = self
.composite
.maybe_is_checked("trips unmodified by experiment")
.unwrap_or(true);
let modified_trips = self
.composite
.maybe_is_checked("trips modified by experiment")
.unwrap_or(true);
if self.opts.off_map_starts != off_map_starts if self.opts.off_map_starts != off_map_starts
|| self.opts.off_map_ends != off_map_ends || self.opts.off_map_ends != off_map_ends
|| self.opts.unmodified_trips != unmodified_trips
|| self.opts.modified_trips != modified_trips
{ {
self.opts.off_map_starts = off_map_starts; self.opts.off_map_starts = off_map_starts;
self.opts.off_map_ends = off_map_ends; self.opts.off_map_ends = off_map_ends;
self.opts.unmodified_trips = unmodified_trips;
self.opts.modified_trips = modified_trips;
self.opts.skip = 0; self.opts.skip = 0;
self.recalc(ctx, app); self.recalc(ctx, app);
} }
@ -173,6 +189,7 @@ impl State for TripTable {
struct Entry { struct Entry {
trip: TripID, trip: TripID,
mode: TripMode, mode: TripMode,
modified: bool,
departure: Time, departure: Time,
duration_after: Duration, duration_after: Duration,
duration_before: Duration, duration_before: Duration,
@ -208,7 +225,7 @@ fn make(ctx: &mut EventCtx, app: &App, opts: &Options) -> Composite {
aborted += 1; aborted += 1;
continue; continue;
}; };
let (departure, start, end, _) = sim.trip_info(*id); let (departure, start, end, _, modified) = sim.trip_info(*id);
if !opts.off_map_starts { if !opts.off_map_starts {
if let TripEndpoint::Border(_, _) = start { if let TripEndpoint::Border(_, _) = start {
continue; continue;
@ -219,6 +236,12 @@ fn make(ctx: &mut EventCtx, app: &App, opts: &Options) -> Composite {
continue; continue;
} }
} }
if !opts.unmodified_trips && !modified {
continue;
}
if !opts.modified_trips && modified {
continue;
}
let (_, waiting) = sim.finished_trip_time(*id).unwrap(); let (_, waiting) = sim.finished_trip_time(*id).unwrap();
let duration_before = if let Some(ref times) = trip_times_before { let duration_before = if let Some(ref times) = trip_times_before {
@ -237,6 +260,7 @@ fn make(ctx: &mut EventCtx, app: &App, opts: &Options) -> Composite {
trip: *id, trip: *id,
mode, mode,
departure, departure,
modified,
duration_after: *duration_after, duration_after: *duration_after,
duration_before, duration_before,
waiting, waiting,
@ -263,12 +287,15 @@ fn make(ctx: &mut EventCtx, app: &App, opts: &Options) -> Composite {
// Render data // Render data
let mut rows = Vec::new(); let mut rows = Vec::new();
for x in data.into_iter().skip(opts.skip).take(ROWS) { for x in data.into_iter().skip(opts.skip).take(ROWS) {
let mut row = vec![ let mut row = vec![Text::from(Line(x.trip.0.to_string())).render_ctx(ctx)];
Text::from(Line(x.trip.0.to_string())).render_ctx(ctx), if app.primary.has_modified_trips {
row.push(Text::from(Line(if x.modified { "Yes" } else { "No" })).render_ctx(ctx));
}
row.extend(vec![
Text::from(Line(x.mode.ongoing_verb()).fg(color_for_mode(app, x.mode))).render_ctx(ctx), Text::from(Line(x.mode.ongoing_verb()).fg(color_for_mode(app, x.mode))).render_ctx(ctx),
Text::from(Line(x.departure.ampm_tostring())).render_ctx(ctx), Text::from(Line(x.departure.ampm_tostring())).render_ctx(ctx),
Text::from(Line(x.duration_after.to_string())).render_ctx(ctx), Text::from(Line(x.duration_after.to_string())).render_ctx(ctx),
]; ]);
if app.has_prebaked().is_some() { if app.has_prebaked().is_some() {
row.push( row.push(
Text::from_all(cmp_duration_shorter(x.duration_after, x.duration_before)) Text::from_all(cmp_duration_shorter(x.duration_after, x.duration_before))
@ -312,12 +339,15 @@ fn make(ctx: &mut EventCtx, app: &App, opts: &Options) -> Composite {
Btn::text_bg2(name).build_def(ctx, None) Btn::text_bg2(name).build_def(ctx, None)
} }
}; };
let mut headers = vec![ let mut headers = vec![Line("Trip ID").draw(ctx)];
Line("Trip ID").draw(ctx), if app.primary.has_modified_trips {
headers.push(Line("Modified").draw(ctx));
}
headers.extend(vec![
Line("Type").draw(ctx), Line("Type").draw(ctx),
btn(SortBy::Departure, "Departure"), btn(SortBy::Departure, "Departure"),
btn(SortBy::Duration, "Duration"), btn(SortBy::Duration, "Duration"),
]; ]);
if app.has_prebaked().is_some() { if app.has_prebaked().is_some() {
headers.push(btn(SortBy::RelativeDuration, "Comparison")); headers.push(btn(SortBy::RelativeDuration, "Comparison"));
headers.push(btn(SortBy::PercentChangeDuration, "Normalized")); headers.push(btn(SortBy::PercentChangeDuration, "Normalized"));
@ -330,6 +360,26 @@ fn make(ctx: &mut EventCtx, app: &App, opts: &Options) -> Composite {
col.push(Widget::row(vec![ col.push(Widget::row(vec![
Checkbox::text(ctx, "starting off-map", None, opts.off_map_starts), Checkbox::text(ctx, "starting off-map", None, opts.off_map_starts),
Checkbox::text(ctx, "ending off-map", None, opts.off_map_ends), Checkbox::text(ctx, "ending off-map", None, opts.off_map_ends),
if app.primary.has_modified_trips {
Checkbox::text(
ctx,
"trips unmodified by experiment",
None,
opts.unmodified_trips,
)
} else {
Widget::nothing()
},
if app.primary.has_modified_trips {
Checkbox::text(
ctx,
"trips modified by experiment",
None,
opts.modified_trips,
)
} else {
Widget::nothing()
},
])); ]));
let (_, unfinished, _) = app.primary.sim.num_trips(); let (_, unfinished, _) = app.primary.sim.num_trips();
col.push( col.push(
@ -503,7 +553,7 @@ fn preview_route(g: &mut GfxCtx, app: &App, trip: TripID) -> GeomBatch {
} }
} }
let (_, start, end, _) = app.primary.sim.trip_info(trip); let (_, start, end, _, _) = app.primary.sim.trip_info(trip);
batch.append( batch.append(
GeomBatch::mapspace_svg(g.prerender, "system/assets/timeline/start_pos.svg") GeomBatch::mapspace_svg(g.prerender, "system/assets/timeline/start_pos.svg")
.scale(10.0) .scale(10.0)

View File

@ -533,6 +533,7 @@ pub fn spawn_agents_around(i: IntersectionID, app: &mut App) {
}, },
TripEndpoint::Border(lane.src_i, None), TripEndpoint::Border(lane.src_i, None),
false, false,
false,
map, map,
); );
} }
@ -554,6 +555,7 @@ pub fn spawn_agents_around(i: IntersectionID, app: &mut App) {
}, },
TripEndpoint::Border(lane.src_i, None), TripEndpoint::Border(lane.src_i, None),
false, false,
false,
map, map,
); );
} }

View File

@ -11,6 +11,7 @@ use ezgui::{
HorizontalAlignment, Key, Line, Outcome, Spinner, Text, TextExt, VerticalAlignment, Widget, HorizontalAlignment, Key, Line, Outcome, Spinner, Text, TextExt, VerticalAlignment, Widget,
}; };
use geom::Polygon; use geom::Polygon;
use maplit::btreeset;
use sim::{ScenarioModifier, TripMode}; use sim::{ScenarioModifier, TripMode};
use std::collections::BTreeSet; use std::collections::BTreeSet;
@ -23,7 +24,7 @@ pub struct PlayScenario {
impl PlayScenario { impl PlayScenario {
pub fn new( pub fn new(
ctx: &mut EventCtx, ctx: &mut EventCtx,
app: &App, app: &mut App,
name: &String, name: &String,
modifiers: Vec<ScenarioModifier>, modifiers: Vec<ScenarioModifier>,
) -> Box<dyn GameplayState> { ) -> Box<dyn GameplayState> {
@ -42,6 +43,10 @@ impl GameplayState for PlayScenario {
app: &mut App, app: &mut App,
_: &mut SandboxControls, _: &mut SandboxControls,
) -> Option<Transition> { ) -> Option<Transition> {
// This should really happen in the constructor once, but the old PlayScenario's
// on_destroy can wipe this out.
app.primary.has_modified_trips = !self.modifiers.is_empty();
match self.top_center.event(ctx) { match self.top_center.event(ctx) {
Some(Outcome::Clicked(x)) => match x.as_ref() { Some(Outcome::Clicked(x)) => match x.as_ref() {
"change map" => { "change map" => {
@ -92,6 +97,10 @@ impl GameplayState for PlayScenario {
fn draw(&self, g: &mut GfxCtx, _: &App) { fn draw(&self, g: &mut GfxCtx, _: &App) {
self.top_center.draw(g); self.top_center.draw(g);
} }
fn on_destroy(&self, app: &mut App) {
app.primary.has_modified_trips = false;
}
} }
fn make_top_center( fn make_top_center(
@ -308,7 +317,7 @@ impl ChangeMode {
Widget::dropdown( Widget::dropdown(
ctx, ctx,
"to_mode", "to_mode",
TripMode::Drive, TripMode::Bike,
TripMode::all() TripMode::all()
.into_iter() .into_iter()
.map(|m| Choice::new(m.ongoing_verb(), m)) .map(|m| Choice::new(m.ongoing_verb(), m))
@ -322,10 +331,10 @@ impl ChangeMode {
Spinner::new(ctx, (1, 100), 50).named("pct_ppl"), Spinner::new(ctx, (1, 100), 50).named("pct_ppl"),
]), ]),
"Types of trips to convert:".draw_text(ctx), "Types of trips to convert:".draw_text(ctx),
checkbox_per_mode(ctx, app, &BTreeSet::new()), checkbox_per_mode(ctx, app, &btreeset! { TripMode::Drive }),
Widget::row(vec![ Widget::row(vec![
"Departing from:".draw_text(ctx), "Departing from:".draw_text(ctx),
AreaSlider::new(ctx, 0.25 * ctx.canvas.window_width, 0.3).named("depart from"), AreaSlider::new(ctx, 0.25 * ctx.canvas.window_width, 0.0).named("depart from"),
]), ]),
Widget::row(vec![ Widget::row(vec![
"Departing until:".draw_text(ctx), "Departing until:".draw_text(ctx),

View File

@ -138,7 +138,15 @@ impl Scenario {
&mut tmp_rng, &mut tmp_rng,
map, map,
); );
spawner.schedule_trip(person, t.depart, spec, t.trip.start(map), t.cancelled, map); spawner.schedule_trip(
person,
t.depart,
spec,
t.trip.start(map),
t.cancelled,
t.modified,
map,
);
} }
} }

View File

@ -62,7 +62,7 @@ pub enum TripSpec {
// This structure is created temporarily by a Scenario or to interactively spawn agents. // This structure is created temporarily by a Scenario or to interactively spawn agents.
pub struct TripSpawner { pub struct TripSpawner {
trips: Vec<(PersonID, Time, TripSpec, TripEndpoint, bool)>, trips: Vec<(PersonID, Time, TripSpec, TripEndpoint, bool, bool)>,
} }
impl TripSpawner { impl TripSpawner {
@ -77,6 +77,7 @@ impl TripSpawner {
mut spec: TripSpec, mut spec: TripSpec,
trip_start: TripEndpoint, trip_start: TripEndpoint,
cancelled: bool, cancelled: bool,
modified: bool,
map: &Map, map: &Map,
) { ) {
// TODO We'll want to repeat this validation when we spawn stuff later for a second leg... // TODO We'll want to repeat this validation when we spawn stuff later for a second leg...
@ -187,7 +188,7 @@ impl TripSpawner {
}; };
self.trips self.trips
.push((person.id, start_time, spec, trip_start, cancelled)); .push((person.id, start_time, spec, trip_start, cancelled, modified));
} }
pub fn finalize( pub fn finalize(
@ -223,7 +224,8 @@ impl TripSpawner {
} }
timer.start_iter("spawn trips", paths.len()); timer.start_iter("spawn trips", paths.len());
for ((p, start_time, spec, trip_start, cancelled), maybe_req, maybe_path) in paths { for ((p, start_time, spec, trip_start, cancelled, modified), maybe_req, maybe_path) in paths
{
timer.next(); timer.next();
// TODO clone() is super weird to do here, but we just need to make the borrow checker // TODO clone() is super weird to do here, but we just need to make the borrow checker
@ -248,6 +250,7 @@ impl TripSpawner {
} else { } else {
TripMode::Drive TripMode::Drive
}, },
modified,
legs, legs,
map, map,
) )
@ -268,6 +271,7 @@ impl TripSpawner {
} else { } else {
TripMode::Drive TripMode::Drive
}, },
modified,
legs, legs,
map, map,
) )
@ -288,6 +292,7 @@ impl TripSpawner {
start_time, start_time,
trip_start, trip_start,
TripMode::Drive, TripMode::Drive,
modified,
legs, legs,
map, map,
) )
@ -297,6 +302,7 @@ impl TripSpawner {
start_time, start_time,
trip_start, trip_start,
TripMode::Walk, TripMode::Walk,
modified,
vec![TripLeg::Walk(goal.clone())], vec![TripLeg::Walk(goal.clone())],
map, map,
), ),
@ -313,7 +319,15 @@ impl TripSpawner {
} }
DrivingGoal::Border(_, _, _) => {} DrivingGoal::Border(_, _, _) => {}
}; };
trips.new_trip(person.id, start_time, trip_start, TripMode::Bike, legs, map) trips.new_trip(
person.id,
start_time,
trip_start,
TripMode::Bike,
modified,
legs,
map,
)
} }
TripSpec::UsingTransit { TripSpec::UsingTransit {
route, route,
@ -328,6 +342,7 @@ impl TripSpawner {
start_time, start_time,
trip_start, trip_start,
TripMode::Transit, TripMode::Transit,
modified,
vec![ vec![
TripLeg::Walk(walk_to.clone()), TripLeg::Walk(walk_to.clone()),
TripLeg::RideBus(route, stop2), TripLeg::RideBus(route, stop2),
@ -341,6 +356,7 @@ impl TripSpawner {
start_time, start_time,
trip_start, trip_start,
mode, mode,
modified,
vec![TripLeg::Remote(to)], vec![TripLeg::Remote(to)],
map, map,
), ),

View File

@ -964,8 +964,9 @@ impl Sim {
self.trips.trip_to_agent(id) self.trips.trip_to_agent(id)
} }
// (start time, start position, end position, trip type) // (start time, start position, end position, trip type, modified)
pub fn trip_info(&self, id: TripID) -> (Time, TripEndpoint, TripEndpoint, TripMode) { // TODO Time for a struct
pub fn trip_info(&self, id: TripID) -> (Time, TripEndpoint, TripEndpoint, TripMode, bool) {
self.trips.trip_info(id) self.trips.trip_info(id)
} }
// If trip is finished, returns (total time, total waiting time) // If trip is finished, returns (total time, total waiting time)

View File

@ -91,6 +91,7 @@ impl TripManager {
departure: Time, departure: Time,
start: TripEndpoint, start: TripEndpoint,
mode: TripMode, mode: TripMode,
modified: bool,
legs: Vec<TripLeg>, legs: Vec<TripLeg>,
map: &Map, map: &Map,
) -> TripID { ) -> TripID {
@ -125,6 +126,7 @@ impl TripManager {
legs: VecDeque::from(legs), legs: VecDeque::from(legs),
start, start,
end, end,
modified,
}; };
self.unfinished_trips += 1; self.unfinished_trips += 1;
let person = &mut self.people[trip.person.0]; let person = &mut self.people[trip.person.0];
@ -855,9 +857,15 @@ impl TripManager {
std::mem::replace(&mut self.events, Vec::new()) std::mem::replace(&mut self.events, Vec::new())
} }
pub fn trip_info(&self, id: TripID) -> (Time, TripEndpoint, TripEndpoint, TripMode) { pub fn trip_info(&self, id: TripID) -> (Time, TripEndpoint, TripEndpoint, TripMode, bool) {
let t = &self.trips[id.0]; let t = &self.trips[id.0];
(t.departure, t.start.clone(), t.end.clone(), t.mode) (
t.departure,
t.start.clone(),
t.end.clone(),
t.mode,
t.modified,
)
} }
pub fn finished_trip_time(&self, id: TripID) -> Option<(Duration, Duration)> { pub fn finished_trip_time(&self, id: TripID) -> Option<(Duration, Duration)> {
let t = &self.trips[id.0]; let t = &self.trips[id.0];
@ -1272,6 +1280,7 @@ struct Trip {
start: TripEndpoint, start: TripEndpoint,
end: TripEndpoint, end: TripEndpoint,
person: PersonID, person: PersonID,
modified: bool,
} }
impl Trip { impl Trip {