mirror of
https://github.com/a-b-street/abstreet.git
synced 2025-01-06 05:44:46 +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);
|
let new_state = cb(self.states.last_mut().unwrap(), &mut self.app, ctx);
|
||||||
self.states.push(new_state);
|
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) => {
|
Transition::KeepWithData(cb) => {
|
||||||
cb(self.states.last_mut().unwrap(), &mut self.app, ctx);
|
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)>),
|
PopWithData(Box<dyn FnOnce(&mut Box<dyn State>, &mut App, &mut EventCtx)>),
|
||||||
KeepWithData(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>>),
|
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>),
|
Push(Box<dyn State>),
|
||||||
Replace(Box<dyn State>),
|
Replace(Box<dyn State>),
|
||||||
ReplaceThenPush(Box<dyn State>, Box<dyn State>),
|
ReplaceThenPush(Box<dyn State>, Box<dyn State>),
|
||||||
|
@ -11,6 +11,7 @@ use crate::common::Warping;
|
|||||||
use crate::game::Transition;
|
use crate::game::Transition;
|
||||||
use crate::helpers::ID;
|
use crate::helpers::ID;
|
||||||
use crate::render::{ExtraShapeID, MIN_ZOOM_FOR_DETAIL};
|
use crate::render::{ExtraShapeID, MIN_ZOOM_FOR_DETAIL};
|
||||||
|
use crate::sandbox::SandboxMode;
|
||||||
use ezgui::{
|
use ezgui::{
|
||||||
hotkey, Btn, Checkbox, Choice, Color, Composite, Drawable, EventCtx, GeomBatch, GfxCtx,
|
hotkey, Btn, Checkbox, Choice, Color, Composite, Drawable, EventCtx, GeomBatch, GfxCtx,
|
||||||
HorizontalAlignment, Key, Line, Outcome, Plot, PlotOptions, Series, Text, TextExt,
|
HorizontalAlignment, Key, Line, Outcome, Plot, PlotOptions, Series, Text, TextExt,
|
||||||
@ -35,6 +36,7 @@ pub struct InfoPanel {
|
|||||||
|
|
||||||
hyperlinks: HashMap<String, Tab>,
|
hyperlinks: HashMap<String, Tab>,
|
||||||
warpers: HashMap<String, ID>,
|
warpers: HashMap<String, ID>,
|
||||||
|
time_warpers: HashMap<String, (TripID, Time)>,
|
||||||
|
|
||||||
// For drawing the OSD only
|
// For drawing the OSD only
|
||||||
cached_actions: Vec<Key>,
|
cached_actions: Vec<Key>,
|
||||||
@ -156,6 +158,7 @@ pub struct Details {
|
|||||||
pub zoomed: GeomBatch,
|
pub zoomed: GeomBatch,
|
||||||
pub hyperlinks: HashMap<String, Tab>,
|
pub hyperlinks: HashMap<String, Tab>,
|
||||||
pub warpers: HashMap<String, ID>,
|
pub warpers: HashMap<String, ID>,
|
||||||
|
pub time_warpers: HashMap<String, (TripID, Time)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InfoPanel {
|
impl InfoPanel {
|
||||||
@ -179,6 +182,7 @@ impl InfoPanel {
|
|||||||
zoomed: GeomBatch::new(),
|
zoomed: GeomBatch::new(),
|
||||||
hyperlinks: HashMap::new(),
|
hyperlinks: HashMap::new(),
|
||||||
warpers: HashMap::new(),
|
warpers: HashMap::new(),
|
||||||
|
time_warpers: HashMap::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (mut col, main_tab) = match tab {
|
let (mut col, main_tab) = match tab {
|
||||||
@ -321,6 +325,7 @@ impl InfoPanel {
|
|||||||
zoomed: details.zoomed.upload(ctx),
|
zoomed: details.zoomed.upload(ctx),
|
||||||
hyperlinks: details.hyperlinks,
|
hyperlinks: details.hyperlinks,
|
||||||
warpers: details.warpers,
|
warpers: details.warpers,
|
||||||
|
time_warpers: details.time_warpers,
|
||||||
cached_actions,
|
cached_actions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -386,6 +391,43 @@ impl InfoPanel {
|
|||||||
&mut app.primary,
|
&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 {
|
} else {
|
||||||
let mut close_panel = true;
|
let mut close_panel = true;
|
||||||
let t =
|
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 {
|
if props.total_waiting != Duration::ZERO {
|
||||||
Line(format!(
|
Line(format!(
|
||||||
"{}%",
|
"{}%",
|
||||||
(100.0 * (props.waiting_here / props.total_waiting)) as usize
|
(100.0 * (props.total_waiting / total_trip_time)) as usize
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
Line("0%")
|
Line("0%")
|
||||||
},
|
},
|
||||||
Line(format!(" of {} time", activity)).secondary(),
|
Line(format!(" total of {} time spent waiting", activity)).secondary(),
|
||||||
])
|
])
|
||||||
.draw(ctx),
|
.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)
|
Some(props.dist_crossed / props.total_dist)
|
||||||
} else {
|
} else {
|
||||||
|
// The trip is finished
|
||||||
let col_width = 15;
|
let col_width = 15;
|
||||||
|
|
||||||
// The trip is finished
|
|
||||||
col.push(Widget::row(vec![
|
col.push(Widget::row(vec![
|
||||||
Widget::row(vec![Line("Trip time").secondary().draw(ctx)]).force_width(ctx, col_width),
|
Widget::row(vec![Line("Trip time").secondary().draw(ctx)]).force_width(ctx, col_width),
|
||||||
total_trip_time.to_string().draw_text(ctx),
|
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),
|
.force_width(ctx, col_width),
|
||||||
waiting.to_string().draw_text(ctx),
|
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
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ pub use speed::{SpeedControls, TimePanel};
|
|||||||
|
|
||||||
pub struct SandboxMode {
|
pub struct SandboxMode {
|
||||||
gameplay: Box<dyn gameplay::GameplayState>,
|
gameplay: Box<dyn gameplay::GameplayState>,
|
||||||
gameplay_mode: GameplayMode,
|
pub gameplay_mode: GameplayMode,
|
||||||
|
|
||||||
pub controls: SandboxControls,
|
pub controls: SandboxControls,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user