mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-03 01:52:16 +03:00
tool to rewind and go watch a trip
This commit is contained in:
parent
3e49134088
commit
eb1ea20a37
@ -71,6 +71,12 @@ impl GUI for Game {
|
||||
let new_state = cb(self.states.last_mut().unwrap(), &mut self.app, ctx);
|
||||
self.states.push(new_state);
|
||||
}
|
||||
Transition::ReplaceWithData(cb) => {
|
||||
let mut last = self.states.pop().unwrap();
|
||||
last.on_destroy(ctx, &mut self.app);
|
||||
let new_state = cb(last, &mut self.app, ctx);
|
||||
self.states.push(new_state);
|
||||
}
|
||||
Transition::KeepWithData(cb) => {
|
||||
cb(self.states.last_mut().unwrap(), &mut self.app, ctx);
|
||||
}
|
||||
@ -221,6 +227,7 @@ pub enum Transition {
|
||||
PopWithData(Box<dyn FnOnce(&mut Box<dyn State>, &mut App, &mut EventCtx)>),
|
||||
KeepWithData(Box<dyn FnOnce(&mut Box<dyn State>, &mut App, &mut EventCtx)>),
|
||||
PushWithData(Box<dyn FnOnce(&mut Box<dyn State>, &mut App, &mut EventCtx) -> Box<dyn State>>),
|
||||
ReplaceWithData(Box<dyn FnOnce(Box<dyn State>, &mut App, &mut EventCtx) -> Box<dyn State>>),
|
||||
Push(Box<dyn State>),
|
||||
Replace(Box<dyn State>),
|
||||
ReplaceThenPush(Box<dyn State>, Box<dyn State>),
|
||||
|
@ -11,6 +11,7 @@ use crate::common::Warping;
|
||||
use crate::game::Transition;
|
||||
use crate::helpers::ID;
|
||||
use crate::render::{ExtraShapeID, MIN_ZOOM_FOR_DETAIL};
|
||||
use crate::sandbox::SandboxMode;
|
||||
use ezgui::{
|
||||
hotkey, Btn, Checkbox, Choice, Color, Composite, Drawable, EventCtx, GeomBatch, GfxCtx,
|
||||
HorizontalAlignment, Key, Line, Outcome, Plot, PlotOptions, Series, Text, TextExt,
|
||||
@ -35,6 +36,7 @@ pub struct InfoPanel {
|
||||
|
||||
hyperlinks: HashMap<String, Tab>,
|
||||
warpers: HashMap<String, ID>,
|
||||
time_warpers: HashMap<String, (TripID, Time)>,
|
||||
|
||||
// For drawing the OSD only
|
||||
cached_actions: Vec<Key>,
|
||||
@ -156,6 +158,7 @@ pub struct Details {
|
||||
pub zoomed: GeomBatch,
|
||||
pub hyperlinks: HashMap<String, Tab>,
|
||||
pub warpers: HashMap<String, ID>,
|
||||
pub time_warpers: HashMap<String, (TripID, Time)>,
|
||||
}
|
||||
|
||||
impl InfoPanel {
|
||||
@ -179,6 +182,7 @@ impl InfoPanel {
|
||||
zoomed: GeomBatch::new(),
|
||||
hyperlinks: HashMap::new(),
|
||||
warpers: HashMap::new(),
|
||||
time_warpers: HashMap::new(),
|
||||
};
|
||||
|
||||
let (mut col, main_tab) = match tab {
|
||||
@ -321,6 +325,7 @@ impl InfoPanel {
|
||||
zoomed: details.zoomed.upload(ctx),
|
||||
hyperlinks: details.hyperlinks,
|
||||
warpers: details.warpers,
|
||||
time_warpers: details.time_warpers,
|
||||
cached_actions,
|
||||
}
|
||||
}
|
||||
@ -386,6 +391,43 @@ impl InfoPanel {
|
||||
&mut app.primary,
|
||||
))),
|
||||
)
|
||||
} else if let Some((trip, time)) = self.time_warpers.get(&action) {
|
||||
let trip = *trip;
|
||||
let time = *time;
|
||||
// TODO time warp screen
|
||||
(
|
||||
false,
|
||||
Some(Transition::ReplaceWithData(Box::new(
|
||||
move |state, app, ctx| {
|
||||
let mode = state.downcast::<SandboxMode>().ok().unwrap();
|
||||
ctx.loading_screen("rewind simulation", |ctx, mut timer| {
|
||||
app.primary.clear_sim();
|
||||
let mut new_mode =
|
||||
SandboxMode::new(ctx, app, mode.gameplay_mode);
|
||||
app.primary.sim.timed_step(
|
||||
&app.primary.map,
|
||||
time - Time::START_OF_DAY,
|
||||
&mut timer,
|
||||
);
|
||||
if let Some(id) = app.primary.sim.trip_to_agent(trip).ok() {
|
||||
let mut actions = new_mode.contextual_actions();
|
||||
new_mode
|
||||
.controls
|
||||
.common
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.launch_info_panel(
|
||||
ID::from_agent(id),
|
||||
ctx,
|
||||
app,
|
||||
&mut actions,
|
||||
);
|
||||
}
|
||||
Box::new(new_mode)
|
||||
})
|
||||
},
|
||||
))),
|
||||
)
|
||||
} else {
|
||||
let mut close_panel = true;
|
||||
let t =
|
||||
|
@ -89,12 +89,12 @@ pub fn details(ctx: &mut EventCtx, app: &App, trip: TripID, details: &mut Detail
|
||||
if props.total_waiting != Duration::ZERO {
|
||||
Line(format!(
|
||||
"{}%",
|
||||
(100.0 * (props.waiting_here / props.total_waiting)) as usize
|
||||
(100.0 * (props.total_waiting / total_trip_time)) as usize
|
||||
))
|
||||
} else {
|
||||
Line("0%")
|
||||
},
|
||||
Line(format!(" of {} time", activity)).secondary(),
|
||||
Line(format!(" total of {} time spent waiting", activity)).secondary(),
|
||||
])
|
||||
.draw(ctx),
|
||||
]),
|
||||
@ -102,9 +102,9 @@ pub fn details(ctx: &mut EventCtx, app: &App, trip: TripID, details: &mut Detail
|
||||
|
||||
Some(props.dist_crossed / props.total_dist)
|
||||
} else {
|
||||
// The trip is finished
|
||||
let col_width = 15;
|
||||
|
||||
// The trip is finished
|
||||
col.push(Widget::row(vec![
|
||||
Widget::row(vec![Line("Trip time").secondary().draw(ctx)]).force_width(ctx, col_width),
|
||||
total_trip_time.to_string().draw_text(ctx),
|
||||
@ -115,6 +115,20 @@ pub fn details(ctx: &mut EventCtx, app: &App, trip: TripID, details: &mut Detail
|
||||
.force_width(ctx, col_width),
|
||||
waiting.to_string().draw_text(ctx),
|
||||
]));
|
||||
|
||||
col.push(
|
||||
Btn::text_bg2("Watch trip")
|
||||
.tooltip(Text::from(Line(format!(
|
||||
"This will reset the simulation to {}",
|
||||
start_time.ampm_tostring()
|
||||
))))
|
||||
.build(ctx, format!("watch {}", trip), None)
|
||||
.margin(5),
|
||||
);
|
||||
details
|
||||
.time_warpers
|
||||
.insert(format!("watch {}", trip), (trip, start_time));
|
||||
|
||||
None
|
||||
};
|
||||
|
||||
|
@ -31,7 +31,7 @@ pub use speed::{SpeedControls, TimePanel};
|
||||
|
||||
pub struct SandboxMode {
|
||||
gameplay: Box<dyn gameplay::GameplayState>,
|
||||
gameplay_mode: GameplayMode,
|
||||
pub gameplay_mode: GameplayMode,
|
||||
|
||||
pub controls: SandboxControls,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user