Make ChooseSomething take a FnOnce callback, so we can avoid cloning at a few call-sites

This commit is contained in:
Dustin Carlino 2021-05-16 08:41:37 -07:00
parent 7a262fb25f
commit 72d0e53fdc
5 changed files with 14 additions and 19 deletions

View File

@ -23,7 +23,7 @@ impl FindAmenity {
.map(|at| Choice::new(at.to_string(), at))
.collect(),
Box::new(move |at, ctx, app| {
let multi_isochrone = create_multi_isochrone(ctx, app, at, options.clone());
let multi_isochrone = create_multi_isochrone(ctx, app, at, options);
return Transition::Replace(Results::new_state(ctx, app, multi_isochrone, at));
}),
)

View File

@ -220,11 +220,7 @@ impl State<App> for EditMode {
"open a saved proposal" => {
if app.primary.map.unsaved_edits() {
Transition::Multi(vec![
Transition::Replace(LoadEdits::new_state(
ctx,
app,
mode.clone(),
)),
Transition::Replace(LoadEdits::new_state(ctx, app, mode)),
Transition::Push(SaveEdits::new_state(
ctx,
app,
@ -238,11 +234,7 @@ impl State<App> for EditMode {
)),
])
} else {
Transition::Replace(LoadEdits::new_state(
ctx,
app,
mode.clone(),
))
Transition::Replace(LoadEdits::new_state(ctx, app, mode))
}
}
"create a blank proposal" => {

View File

@ -287,7 +287,7 @@ pub fn edit_entire_signal(
apply_map_edits(ctx, app, edits);
Transition::Multi(vec![
Transition::Pop,
Transition::Replace(StopSignEditor::new_state(ctx, app, i, mode.clone())),
Transition::Replace(StopSignEditor::new_state(ctx, app, i, mode)),
])
}
x if x == close => {

View File

@ -88,10 +88,10 @@ pub fn make_previewer(
Choice::strings(vec![random, right_now]),
Box::new(move |x, ctx, app| {
if x == "random agents around these intersections" {
for (idx, i) in members.iter().enumerate() {
for (idx, i) in members.into_iter().enumerate() {
if idx == 0 {
// Start at the current stage
let signal = app.primary.map.get_traffic_signal(*i);
let signal = app.primary.map.get_traffic_signal(i);
// TODO Use the offset correctly
// TODO If there are variable stages, this could land anywhere
let mut step = Duration::ZERO;
@ -106,7 +106,7 @@ pub fn make_previewer(
);
}
spawn_agents_around(*i, app);
spawn_agents_around(i, app);
}
} else {
app.primary.sim = app.primary.suspended_sim.as_ref().unwrap().clone();

View File

@ -11,7 +11,8 @@ use crate::AppLike;
/// Choose something from a menu, then feed the answer to a callback.
pub struct ChooseSomething<A: AppLike, T> {
panel: Panel,
cb: Box<dyn Fn(T, &mut EventCtx, &mut A) -> Transition<A>>,
// Wrapped in an Option so that we can consume it once
cb: Option<Box<dyn FnOnce(T, &mut EventCtx, &mut A) -> Transition<A>>>,
}
impl<A: AppLike + 'static, T: 'static> ChooseSomething<A, T> {
@ -19,7 +20,7 @@ impl<A: AppLike + 'static, T: 'static> ChooseSomething<A, T> {
ctx: &mut EventCtx,
query: I,
choices: Vec<Choice<T>>,
cb: Box<dyn Fn(T, &mut EventCtx, &mut A) -> Transition<A>>,
cb: Box<dyn FnOnce(T, &mut EventCtx, &mut A) -> Transition<A>>,
) -> Box<dyn State<A>> {
Box::new(ChooseSomething {
panel: Panel::new_builder(Widget::col(vec![
@ -30,7 +31,7 @@ impl<A: AppLike + 'static, T: 'static> ChooseSomething<A, T> {
Menu::widget(ctx, choices).named("menu"),
]))
.build(ctx),
cb,
cb: Some(cb),
})
}
}
@ -42,7 +43,9 @@ impl<A: AppLike + 'static, T: 'static> State<A> for ChooseSomething<A, T> {
"close" => Transition::Pop,
_ => {
let data = self.panel.take_menu_choice::<T>("menu");
(self.cb)(data, ctx, app)
// If the callback doesn't replace or pop this ChooseSomething state, then
// it'll break when the user tries to interact with the menu again.
(self.cb.take().unwrap())(data, ctx, app)
}
},
_ => {