mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 15:33:44 +03:00
Collapse a few more of the Transitions
This commit is contained in:
parent
0b9b7e1a65
commit
5c6e781016
@ -41,18 +41,21 @@ impl State for Warping {
|
||||
Transition::Keep
|
||||
} else {
|
||||
if let Some(id) = self.id.clone() {
|
||||
Transition::PopWithData(Box::new(move |state, ctx, app| {
|
||||
// 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::from_id(app, id),
|
||||
&mut actions,
|
||||
);
|
||||
}
|
||||
}))
|
||||
Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, app| {
|
||||
// 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::from_id(app, id),
|
||||
&mut actions,
|
||||
);
|
||||
}
|
||||
})),
|
||||
])
|
||||
} else {
|
||||
Transition::Pop
|
||||
}
|
||||
@ -178,18 +181,21 @@ fn warp_to_id(ctx: &mut EventCtx, app: &mut App, line: &str) -> Option<Transitio
|
||||
'R' => {
|
||||
let r = BusRouteID(idx);
|
||||
app.primary.map.maybe_get_br(r)?;
|
||||
return Some(Transition::PopWithData(Box::new(move |state, ctx, app| {
|
||||
// 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::BusRoute(r),
|
||||
&mut actions,
|
||||
);
|
||||
}
|
||||
})));
|
||||
return Some(Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, app| {
|
||||
// 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::BusRoute(r),
|
||||
&mut actions,
|
||||
);
|
||||
}
|
||||
})),
|
||||
]));
|
||||
}
|
||||
'l' => ID::Lane(LaneID(idx)),
|
||||
'i' => ID::Intersection(IntersectionID(idx)),
|
||||
@ -199,18 +205,21 @@ fn warp_to_id(ctx: &mut EventCtx, app: &mut App, line: &str) -> Option<Transitio
|
||||
'P' => {
|
||||
let id = PersonID(idx);
|
||||
app.primary.sim.lookup_person(id)?;
|
||||
return Some(Transition::PopWithData(Box::new(move |state, ctx, app| {
|
||||
// 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(id, BTreeMap::new()),
|
||||
&mut actions,
|
||||
);
|
||||
}
|
||||
})));
|
||||
return Some(Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, app| {
|
||||
// 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(id, BTreeMap::new()),
|
||||
&mut actions,
|
||||
);
|
||||
}
|
||||
})),
|
||||
]));
|
||||
}
|
||||
'c' => {
|
||||
// This one gets more complicated. :)
|
||||
@ -220,18 +229,21 @@ fn warp_to_id(ctx: &mut EventCtx, app: &mut App, line: &str) -> Option<Transitio
|
||||
't' => {
|
||||
let trip = TripID(idx);
|
||||
let person = app.primary.sim.trip_to_person(trip);
|
||||
return Some(Transition::PopWithData(Box::new(move |state, ctx, app| {
|
||||
// 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, OpenTrip::single(trip)),
|
||||
&mut actions,
|
||||
);
|
||||
}
|
||||
})));
|
||||
return Some(Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, app| {
|
||||
// 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, OpenTrip::single(trip)),
|
||||
&mut actions,
|
||||
);
|
||||
}
|
||||
})),
|
||||
]));
|
||||
}
|
||||
_ => {
|
||||
return None;
|
||||
|
@ -410,11 +410,14 @@ fn search_osm(filter: String, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
draw: batch.upload(ctx),
|
||||
};
|
||||
|
||||
Transition::PopWithData(Box::new(|state, ctx, _| {
|
||||
let mut mode = state.downcast_mut::<DebugMode>().unwrap();
|
||||
mode.search_results = Some(results);
|
||||
mode.reset_info(ctx);
|
||||
}))
|
||||
Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(|state, ctx, _| {
|
||||
let mut mode = state.downcast_mut::<DebugMode>().unwrap();
|
||||
mode.search_results = Some(results);
|
||||
mode.reset_info(ctx);
|
||||
})),
|
||||
])
|
||||
}
|
||||
|
||||
struct SearchResults {
|
||||
@ -496,7 +499,7 @@ impl ContextualActions for Actions {
|
||||
close_info: &mut bool,
|
||||
) -> Transition {
|
||||
match (id, action.as_ref()) {
|
||||
(id, "hide this") => Transition::KeepWithData(Box::new(|state, ctx, app| {
|
||||
(id, "hide this") => Transition::ModifyState(Box::new(|state, ctx, app| {
|
||||
let mode = state.downcast_mut::<DebugMode>().unwrap();
|
||||
println!("Hiding {:?}", id);
|
||||
app.primary.current_selection = None;
|
||||
|
@ -184,13 +184,17 @@ impl State for StoryMapEditor {
|
||||
ctx,
|
||||
"Name this story map",
|
||||
Box::new(|name, _, _| {
|
||||
Transition::PopWithData(Box::new(move |state, ctx, app| {
|
||||
let editor = state.downcast_mut::<StoryMapEditor>().unwrap();
|
||||
editor.story.name = name;
|
||||
editor.story.save(app);
|
||||
editor.dirty = false;
|
||||
editor.redo_panel(ctx);
|
||||
}))
|
||||
Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, app| {
|
||||
let editor =
|
||||
state.downcast_mut::<StoryMapEditor>().unwrap();
|
||||
editor.story.name = name;
|
||||
editor.story.save(app);
|
||||
editor.dirty = false;
|
||||
editor.redo_panel(ctx);
|
||||
})),
|
||||
])
|
||||
}),
|
||||
));
|
||||
} else {
|
||||
@ -225,12 +229,15 @@ impl State for StoryMapEditor {
|
||||
self.panel.rect_of("load"),
|
||||
choices,
|
||||
Box::new(|story, _, _| {
|
||||
Transition::PopWithData(Box::new(move |state, ctx, _| {
|
||||
let editor = state.downcast_mut::<StoryMapEditor>().unwrap();
|
||||
editor.story = story;
|
||||
editor.dirty = false;
|
||||
editor.redo_panel(ctx);
|
||||
}))
|
||||
Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, _| {
|
||||
let editor = state.downcast_mut::<StoryMapEditor>().unwrap();
|
||||
editor.story = story;
|
||||
editor.dirty = false;
|
||||
editor.redo_panel(ctx);
|
||||
})),
|
||||
])
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
@ -74,12 +74,15 @@ impl State for ChangeDuration {
|
||||
PhaseType::Adaptive(dt)
|
||||
};
|
||||
let idx = self.idx;
|
||||
return Transition::PopWithData(Box::new(move |state, ctx, app| {
|
||||
let editor = state.downcast_mut::<TrafficSignalEditor>().unwrap();
|
||||
editor.add_new_edit(ctx, app, idx, |ts| {
|
||||
ts.stages[idx].phase_type = new_type.clone();
|
||||
});
|
||||
}));
|
||||
return Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, app| {
|
||||
let editor = state.downcast_mut::<TrafficSignalEditor>().unwrap();
|
||||
editor.add_new_edit(ctx, app, idx, |ts| {
|
||||
ts.stages[idx].phase_type = new_type.clone();
|
||||
});
|
||||
})),
|
||||
]);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
@ -145,23 +148,29 @@ pub fn edit_entire_signal(
|
||||
&mut Timer::throwaway(),
|
||||
)),
|
||||
Box::new(move |new_signal, _, _| {
|
||||
Transition::PopWithData(Box::new(move |state, ctx, app| {
|
||||
Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, app| {
|
||||
let editor = state.downcast_mut::<TrafficSignalEditor>().unwrap();
|
||||
editor.add_new_edit(ctx, app, 0, |ts| {
|
||||
*ts = new_signal.clone();
|
||||
});
|
||||
})),
|
||||
])
|
||||
}),
|
||||
)),
|
||||
x if x == all_walk => Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, app| {
|
||||
let mut new_signal = app.primary.map.get_traffic_signal(i).clone();
|
||||
if new_signal.convert_to_ped_scramble() {
|
||||
let editor = state.downcast_mut::<TrafficSignalEditor>().unwrap();
|
||||
editor.add_new_edit(ctx, app, 0, |ts| {
|
||||
*ts = new_signal.clone();
|
||||
});
|
||||
}))
|
||||
}),
|
||||
)),
|
||||
x if x == all_walk => Transition::PopWithData(Box::new(move |state, ctx, app| {
|
||||
let mut new_signal = app.primary.map.get_traffic_signal(i).clone();
|
||||
if new_signal.convert_to_ped_scramble() {
|
||||
let editor = state.downcast_mut::<TrafficSignalEditor>().unwrap();
|
||||
editor.add_new_edit(ctx, app, 0, |ts| {
|
||||
*ts = new_signal.clone();
|
||||
});
|
||||
}
|
||||
})),
|
||||
}
|
||||
})),
|
||||
]),
|
||||
x if x == stop_sign => {
|
||||
original.apply(app);
|
||||
|
||||
@ -195,19 +204,22 @@ pub fn edit_entire_signal(
|
||||
Transition::Multi(vec![Transition::Pop, Transition::Pop])
|
||||
}
|
||||
}
|
||||
x if x == reset => Transition::PopWithData(Box::new(move |state, ctx, app| {
|
||||
let editor = state.downcast_mut::<TrafficSignalEditor>().unwrap();
|
||||
let new_signal = ControlTrafficSignal::get_possible_policies(
|
||||
&app.primary.map,
|
||||
i,
|
||||
&mut Timer::throwaway(),
|
||||
)
|
||||
.remove(0)
|
||||
.1;
|
||||
editor.add_new_edit(ctx, app, 0, |ts| {
|
||||
*ts = new_signal.clone();
|
||||
});
|
||||
})),
|
||||
x if x == reset => Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, app| {
|
||||
let editor = state.downcast_mut::<TrafficSignalEditor>().unwrap();
|
||||
let new_signal = ControlTrafficSignal::get_possible_policies(
|
||||
&app.primary.map,
|
||||
i,
|
||||
&mut Timer::throwaway(),
|
||||
)
|
||||
.remove(0)
|
||||
.1;
|
||||
editor.add_new_edit(ctx, app, 0, |ts| {
|
||||
*ts = new_signal.clone();
|
||||
});
|
||||
})),
|
||||
]),
|
||||
_ => unreachable!(),
|
||||
}),
|
||||
)
|
||||
|
@ -96,8 +96,7 @@ impl Game {
|
||||
}
|
||||
true
|
||||
}
|
||||
Transition::PopWithData(cb) => {
|
||||
self.states.pop().unwrap().on_destroy(ctx, &mut self.app);
|
||||
Transition::ModifyState(cb) => {
|
||||
cb(self.states.last_mut().unwrap(), ctx, &mut self.app);
|
||||
true
|
||||
}
|
||||
@ -108,10 +107,6 @@ impl Game {
|
||||
self.states.extend(new_states);
|
||||
true
|
||||
}
|
||||
Transition::KeepWithData(cb) => {
|
||||
cb(self.states.last_mut().unwrap(), ctx, &mut self.app);
|
||||
true
|
||||
}
|
||||
Transition::Push(state) => {
|
||||
self.states.push(state);
|
||||
true
|
||||
@ -276,9 +271,9 @@ pub enum Transition {
|
||||
KeepWithMouseover,
|
||||
Pop,
|
||||
// If a state needs to pass data back to the parent, use this. Sadly, runtime type casting.
|
||||
// TODO Collapse some of these cases too
|
||||
PopWithData(Box<dyn FnOnce(&mut Box<dyn State>, &mut EventCtx, &mut App)>),
|
||||
KeepWithData(Box<dyn FnOnce(&mut Box<dyn State>, &mut EventCtx, &mut App)>),
|
||||
ModifyState(Box<dyn FnOnce(&mut Box<dyn State>, &mut EventCtx, &mut App)>),
|
||||
// TODO This is like Replace + ModifyState, then returning a few Push's from the callback. Not
|
||||
// sure how to express it in terms of the others without complicating ModifyState everywhere.
|
||||
ReplaceWithData(
|
||||
Box<dyn FnOnce(Box<dyn State>, &mut EventCtx, &mut App) -> Vec<Box<dyn State>>>,
|
||||
),
|
||||
|
@ -177,16 +177,19 @@ impl State for TransitRoutes {
|
||||
}
|
||||
};
|
||||
|
||||
Transition::PopWithData(Box::new(move |state, ctx, app| {
|
||||
let sandbox = state.downcast_mut::<SandboxMode>().unwrap();
|
||||
let mut actions = sandbox.contextual_actions();
|
||||
sandbox.controls.common.as_mut().unwrap().launch_info_panel(
|
||||
ctx,
|
||||
app,
|
||||
Tab::BusRoute(route),
|
||||
&mut actions,
|
||||
)
|
||||
}))
|
||||
Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, app| {
|
||||
let sandbox = state.downcast_mut::<SandboxMode>().unwrap();
|
||||
let mut actions = sandbox.contextual_actions();
|
||||
sandbox.controls.common.as_mut().unwrap().launch_info_panel(
|
||||
ctx,
|
||||
app,
|
||||
Tab::BusRoute(route),
|
||||
&mut actions,
|
||||
)
|
||||
})),
|
||||
])
|
||||
}
|
||||
|
||||
fn draw_baselayer(&self) -> DrawBaselayer {
|
||||
|
@ -109,16 +109,19 @@ impl State for ParkingOverhead {
|
||||
if let Ok(idx) = x.parse::<usize>() {
|
||||
let trip = TripID(idx);
|
||||
let person = app.primary.sim.trip_to_person(trip);
|
||||
return Transition::PopWithData(Box::new(move |state, ctx, app| {
|
||||
let sandbox = state.downcast_mut::<SandboxMode>().unwrap();
|
||||
let mut actions = sandbox.contextual_actions();
|
||||
sandbox.controls.common.as_mut().unwrap().launch_info_panel(
|
||||
ctx,
|
||||
app,
|
||||
Tab::PersonTrips(person, OpenTrip::single(trip)),
|
||||
&mut actions,
|
||||
);
|
||||
}));
|
||||
return Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, app| {
|
||||
let sandbox = state.downcast_mut::<SandboxMode>().unwrap();
|
||||
let mut actions = sandbox.contextual_actions();
|
||||
sandbox.controls.common.as_mut().unwrap().launch_info_panel(
|
||||
ctx,
|
||||
app,
|
||||
Tab::PersonTrips(person, OpenTrip::single(trip)),
|
||||
&mut actions,
|
||||
);
|
||||
})),
|
||||
]);
|
||||
}
|
||||
return DashTab::ParkingOverhead.transition(ctx, app, x);
|
||||
}
|
||||
|
@ -121,16 +121,19 @@ impl State for TripTable {
|
||||
if let Ok(idx) = x.parse::<usize>() {
|
||||
let trip = TripID(idx);
|
||||
let person = app.primary.sim.trip_to_person(trip);
|
||||
return Transition::PopWithData(Box::new(move |state, ctx, app| {
|
||||
let sandbox = state.downcast_mut::<SandboxMode>().unwrap();
|
||||
let mut actions = sandbox.contextual_actions();
|
||||
sandbox.controls.common.as_mut().unwrap().launch_info_panel(
|
||||
ctx,
|
||||
app,
|
||||
Tab::PersonTrips(person, OpenTrip::single(trip)),
|
||||
&mut actions,
|
||||
);
|
||||
}));
|
||||
return Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::ModifyState(Box::new(move |state, ctx, app| {
|
||||
let sandbox = state.downcast_mut::<SandboxMode>().unwrap();
|
||||
let mut actions = sandbox.contextual_actions();
|
||||
sandbox.controls.common.as_mut().unwrap().launch_info_panel(
|
||||
ctx,
|
||||
app,
|
||||
Tab::PersonTrips(person, OpenTrip::single(trip)),
|
||||
&mut actions,
|
||||
);
|
||||
})),
|
||||
]);
|
||||
}
|
||||
return DashTab::TripTable.transition(ctx, app, x);
|
||||
}
|
||||
|
@ -468,7 +468,7 @@ impl ContextualActions for Actions {
|
||||
}
|
||||
(_, "follow (run the simulation)") => {
|
||||
*close_panel = false;
|
||||
Transition::KeepWithData(Box::new(|state, ctx, app| {
|
||||
Transition::ModifyState(Box::new(|state, ctx, app| {
|
||||
let mode = state.downcast_mut::<SandboxMode>().unwrap();
|
||||
let speed = mode.controls.speed.as_mut().unwrap();
|
||||
assert!(speed.is_paused());
|
||||
@ -477,7 +477,7 @@ impl ContextualActions for Actions {
|
||||
}
|
||||
(_, "unfollow (pause the simulation)") => {
|
||||
*close_panel = false;
|
||||
Transition::KeepWithData(Box::new(|state, ctx, app| {
|
||||
Transition::ModifyState(Box::new(|state, ctx, app| {
|
||||
let mode = state.downcast_mut::<SandboxMode>().unwrap();
|
||||
let speed = mode.controls.speed.as_mut().unwrap();
|
||||
assert!(!speed.is_paused());
|
||||
|
Loading…
Reference in New Issue
Block a user