Refactor how signal editor applies a single new change

This commit is contained in:
Dustin Carlino 2020-08-13 14:11:30 -07:00
parent 92a7279a44
commit 340d61d33e
2 changed files with 45 additions and 92 deletions

View File

@ -1,5 +1,5 @@
use crate::app::App;
use crate::edit::traffic_signals::{make_top_panel, BundleEdits, TrafficSignalEditor};
use crate::edit::traffic_signals::{BundleEdits, TrafficSignalEditor};
use crate::edit::{apply_map_edits, check_sidewalk_connectivity, StopSignEditor};
use crate::game::{ChooseSomething, DrawBaselayer, State, Transition};
use crate::sandbox::GameplayMode;
@ -76,17 +76,9 @@ impl State for ChangeDuration {
let idx = self.idx;
return Transition::PopWithData(Box::new(move |state, ctx, app| {
let editor = state.downcast_mut::<TrafficSignalEditor>().unwrap();
let mut bundle = BundleEdits::get_current(app, &editor.members);
editor.command_stack.push(bundle.clone());
editor.redo_stack.clear();
for ts in &mut bundle.signals {
editor.add_new_edit(ctx, app, idx, |ts| {
ts.phases[idx].phase_type = new_type.clone();
}
bundle.apply(app);
editor.top_panel = make_top_panel(ctx, app, true, false);
editor.change_phase(ctx, app, idx);
});
}));
}
_ => unreachable!(),
@ -155,15 +147,9 @@ pub fn edit_entire_signal(
Box::new(move |new_signal, _, _| {
Transition::PopWithData(Box::new(move |state, ctx, app| {
let editor = state.downcast_mut::<TrafficSignalEditor>().unwrap();
let mut bundle = BundleEdits::get_current(app, &editor.members);
editor.command_stack.push(bundle.clone());
editor.redo_stack.clear();
bundle.signals = vec![new_signal];
bundle.apply(app);
editor.top_panel = make_top_panel(ctx, app, true, false);
editor.change_phase(ctx, app, 0);
editor.add_new_edit(ctx, app, 0, |ts| {
*ts = new_signal.clone();
});
}))
}),
)),
@ -171,15 +157,9 @@ pub fn edit_entire_signal(
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();
let mut bundle = BundleEdits::get_current(app, &editor.members);
editor.command_stack.push(bundle.clone());
editor.redo_stack.clear();
bundle.signals = vec![new_signal];
bundle.apply(app);
editor.top_panel = make_top_panel(ctx, app, true, false);
editor.change_phase(ctx, app, 0);
editor.add_new_edit(ctx, app, 0, |ts| {
*ts = new_signal.clone();
});
}
})),
x if x == stop_sign => {
@ -214,10 +194,6 @@ pub fn edit_entire_signal(
}
x if x == reset => Transition::PopWithData(Box::new(move |state, ctx, app| {
let editor = state.downcast_mut::<TrafficSignalEditor>().unwrap();
let mut bundle = BundleEdits::get_current(app, &editor.members);
editor.command_stack.push(bundle.clone());
editor.redo_stack.clear();
let new_signal = ControlTrafficSignal::get_possible_policies(
&app.primary.map,
i,
@ -225,11 +201,9 @@ pub fn edit_entire_signal(
)
.remove(0)
.1;
bundle.signals = vec![new_signal];
bundle.apply(app);
editor.top_panel = make_top_panel(ctx, app, true, false);
editor.change_phase(ctx, app, 0);
editor.add_new_edit(ctx, app, 0, |ts| {
*ts = new_signal.clone();
});
})),
_ => unreachable!(),
}),

View File

@ -122,6 +122,25 @@ impl TrafficSignalEditor {
self.draw_current = self.recalc_draw_current(ctx, app);
}
fn add_new_edit<F: Fn(&mut ControlTrafficSignal)>(
&mut self,
ctx: &mut EventCtx,
app: &mut App,
idx: usize,
fxn: F,
) {
let mut bundle = BundleEdits::get_current(app, &self.members);
self.command_stack.push(bundle.clone());
self.redo_stack.clear();
for ts in &mut bundle.signals {
fxn(ts);
}
bundle.apply(app);
self.top_panel = make_top_panel(ctx, app, true, false);
self.change_phase(ctx, app, idx);
}
fn recalc_draw_current(&self, ctx: &mut EventCtx, app: &App) -> Drawable {
let mut batch = GeomBatch::new();
@ -218,16 +237,9 @@ impl State for TrafficSignalEditor {
));
}
if x == "Add new phase" {
let mut bundle = BundleEdits::get_current(app, &self.members);
self.command_stack.push(bundle.clone());
self.redo_stack.clear();
for ts in &mut bundle.signals {
self.add_new_edit(ctx, app, num_phases, |ts| {
ts.phases.push(Phase::new());
}
bundle.apply(app);
self.top_panel = make_top_panel(ctx, app, true, false);
self.change_phase(ctx, app, num_phases);
});
return Transition::Keep;
}
if let Some(x) = x.strip_prefix("change duration of phase ") {
@ -240,49 +252,23 @@ impl State for TrafficSignalEditor {
}
if let Some(x) = x.strip_prefix("delete phase ") {
let idx = x.parse::<usize>().unwrap() - 1;
let mut bundle = BundleEdits::get_current(app, &self.members);
self.command_stack.push(bundle.clone());
self.redo_stack.clear();
for ts in &mut bundle.signals {
self.add_new_edit(ctx, app, 0, |ts| {
ts.phases.remove(idx);
}
bundle.apply(app);
self.top_panel = make_top_panel(ctx, app, true, false);
// Don't use change_phase; it tries to preserve scroll
self.current_phase = if idx == num_phases - 1 { idx - 1 } else { idx };
self.side_panel = make_side_panel(ctx, app, &self.members, self.current_phase);
});
return Transition::Keep;
}
if let Some(x) = x.strip_prefix("move up phase ") {
let idx = x.parse::<usize>().unwrap() - 1;
let mut bundle = BundleEdits::get_current(app, &self.members);
self.command_stack.push(bundle.clone());
self.redo_stack.clear();
for ts in &mut bundle.signals {
self.add_new_edit(ctx, app, idx - 1, |ts| {
ts.phases.swap(idx, idx - 1);
}
bundle.apply(app);
self.top_panel = make_top_panel(ctx, app, true, false);
self.change_phase(ctx, app, idx - 1);
});
return Transition::Keep;
}
if let Some(x) = x.strip_prefix("move down phase ") {
let idx = x.parse::<usize>().unwrap() - 1;
let mut bundle = BundleEdits::get_current(app, &self.members);
self.command_stack.push(bundle.clone());
self.redo_stack.clear();
for ts in &mut bundle.signals {
self.add_new_edit(ctx, app, idx + 1, |ts| {
ts.phases.swap(idx, idx + 1);
}
bundle.apply(app);
self.top_panel = make_top_panel(ctx, app, true, false);
self.change_phase(ctx, app, idx + 1);
});
return Transition::Keep;
}
if let Some(x) = x.strip_prefix("phase ") {
@ -303,9 +289,8 @@ impl State for TrafficSignalEditor {
self.command_stack.push(bundle.clone());
self.redo_stack.clear();
self.current_phase = 0;
self.top_panel = make_top_panel(ctx, app, true, false);
self.change_phase(ctx, app, self.current_phase);
self.change_phase(ctx, app, 0);
return Transition::Push(PopupMsg::new(
ctx,
@ -426,19 +411,13 @@ impl State for TrafficSignalEditor {
pri
),
) {
let mut bundle = BundleEdits::get_current(app, &self.members);
self.command_stack.push(bundle.clone());
self.redo_stack.clear();
for ts in &mut bundle.signals {
let idx = self.current_phase;
let signal = signal.clone();
self.add_new_edit(ctx, app, idx, |ts| {
if ts.id == id.parent {
ts.phases[self.current_phase].edit_group(&signal.turn_groups[&id], pri);
break;
ts.phases[idx].edit_group(&signal.turn_groups[&id], pri);
}
}
bundle.apply(app);
self.top_panel = make_top_panel(ctx, app, true, false);
self.change_phase(ctx, app, self.current_phase);
});
return Transition::KeepWithMouseover;
}
}