Collapse a few more of the Transitions

This commit is contained in:
Dustin Carlino 2020-09-07 10:49:20 -07:00
parent 0b9b7e1a65
commit 5c6e781016
9 changed files with 178 additions and 140 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);
})),
])
}),
));
}

View File

@ -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!(),
}),
)

View File

@ -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>>>,
),

View File

@ -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 {

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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());