diff --git a/game/src/edit/mod.rs b/game/src/edit/mod.rs index 5170b81430..0eb9f09b7d 100644 --- a/game/src/edit/mod.rs +++ b/game/src/edit/mod.rs @@ -40,8 +40,7 @@ pub struct EditMode { // Retained state from the SandboxMode that spawned us mode: GameplayMode, - // edits name, number of commands - changelist_key: (String, usize), + map_edit_key: usize, unzoomed: Drawable, zoomed: Drawable, @@ -52,16 +51,15 @@ impl EditMode { let orig_dirty = app.primary.dirty_from_edits; assert!(app.primary.suspended_sim.is_none()); app.primary.suspended_sim = Some(app.primary.clear_sim()); - let edits = app.primary.map.get_edits(); let layer = crate::layer::map::Static::edits(ctx, app); Box::new(EditMode { tool_panel: tool_panel(ctx), top_center: make_topcenter(ctx, app), changelist: make_changelist(ctx, app), - orig_edits: edits.clone(), + orig_edits: app.primary.map.get_edits().clone(), orig_dirty, mode, - changelist_key: (edits.edits_name.clone(), edits.commands.len()), + map_edit_key: app.primary.map.get_edits_change_key(), unzoomed: layer.unzoomed, zoomed: layer.zoomed, }) @@ -146,10 +144,11 @@ impl EditMode { impl State for EditMode { fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition { { - let edits = app.primary.map.get_edits(); - let changelist_key = (edits.edits_name.clone(), edits.commands.len()); - if self.changelist_key != changelist_key { - self.changelist_key = changelist_key; + // We would normally use Cached, but so many values depend on one key, so this is more + // clear. + let key = app.primary.map.get_edits_change_key(); + if self.map_edit_key != key { + self.map_edit_key = key; self.changelist = make_changelist(ctx, app); let layer = crate::layer::map::Static::edits(ctx, app); self.unzoomed = layer.unzoomed; diff --git a/game/src/ungap/mod.rs b/game/src/ungap/mod.rs index 3853778c97..4144edeeca 100644 --- a/game/src/ungap/mod.rs +++ b/game/src/ungap/mod.rs @@ -31,16 +31,12 @@ pub struct ExploreMap { // TODO Also cache Nearby, but recalculate it after edits nearby: Option, - // edits name, number of commands - // TODO Brittle -- could undo and add a new command. Add a proper edit counter to map. Refactor - // with EditMode. Use Cached. - changelist_key: (String, usize), + map_edit_key: usize, } impl ExploreMap { pub fn new_state(ctx: &mut EventCtx, app: &mut App) -> Box> { app.opts.show_building_driveways = false; - let edits = app.primary.map.get_edits(); Box::new(ExploreMap { top_panel: make_top_panel(ctx, app), @@ -51,7 +47,7 @@ impl ExploreMap { elevation: false, nearby: None, - changelist_key: (edits.edits_name.clone(), edits.commands.len()), + map_edit_key: app.primary.map.get_edits_change_key(), }) } } @@ -59,10 +55,11 @@ impl ExploreMap { impl State for ExploreMap { fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition { { - let edits = app.primary.map.get_edits(); - let changelist_key = (edits.edits_name.clone(), edits.commands.len()); - if self.changelist_key != changelist_key { - self.changelist_key = changelist_key; + // We would normally use Cached, but so many values depend on one key, so this is more + // clear. + let key = app.primary.map.get_edits_change_key(); + if self.map_edit_key != key { + self.map_edit_key = key; self.network_layer = render_network_layer(ctx, app); self.edits_layer = render_edits(ctx, app); self.top_panel = make_top_panel(ctx, app); diff --git a/game/src/ungap/quick_sketch.rs b/game/src/ungap/quick_sketch.rs index 8369e76660..7bfb85dd42 100644 --- a/game/src/ungap/quick_sketch.rs +++ b/game/src/ungap/quick_sketch.rs @@ -85,8 +85,8 @@ impl State for QuickSketch { fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition { self.magnifying_glass.event(ctx, app); - match self.top_panel.event(ctx) { - Outcome::Clicked(x) => match x.as_ref() { + if let Outcome::Clicked(x) = self.top_panel.event(ctx) { + match x.as_ref() { "Cancel" => { return Transition::Pop; } @@ -100,8 +100,7 @@ impl State for QuickSketch { return Transition::Replace(PopupMsg::new_state(ctx, "Changes made", messages)); } _ => unreachable!(), - }, - _ => {} + } } if self.route_sketcher.event(ctx, app) { diff --git a/map_model/src/edits/mod.rs b/map_model/src/edits/mod.rs index 9d101a9786..13e3e433fd 100644 --- a/map_model/src/edits/mod.rs +++ b/map_model/src/edits/mod.rs @@ -774,6 +774,8 @@ impl Map { // new_edits don't necessarily have to be valid; this could be used for speculatively testing // edits. Doesn't update pathfinding yet. fn apply_edits(&mut self, mut new_edits: MapEdits, enforce_valid: bool) -> EditEffects { + self.edits_generation += 1; + let mut effects = EditEffects { changed_roads: BTreeSet::new(), deleted_lanes: BTreeSet::new(), @@ -907,4 +909,9 @@ impl Map { ); self.traffic_signals.insert(signal.id, signal); } + + /// If you need to regenerate anything when the map is edited, use this key to detect edits. + pub fn get_edits_change_key(&self) -> usize { + self.edits_generation + } } diff --git a/map_model/src/lib.rs b/map_model/src/lib.rs index 367aa1884f..317bc2a56a 100644 --- a/map_model/src/lib.rs +++ b/map_model/src/lib.rs @@ -116,5 +116,7 @@ pub struct Map { #[serde(skip_serializing, skip_deserializing)] edits: MapEdits, #[serde(skip_serializing, skip_deserializing)] + edits_generation: usize, + #[serde(skip_serializing, skip_deserializing)] road_to_buildings: MultiMap, } diff --git a/map_model/src/make/mod.rs b/map_model/src/make/mod.rs index ed3f52ed11..fdf41a2a36 100644 --- a/map_model/src/make/mod.rs +++ b/map_model/src/make/mod.rs @@ -86,6 +86,7 @@ impl Map { routing_params: RoutingParams::default(), name: raw.name.clone(), edits: MapEdits::new(), + edits_generation: 0, road_to_buildings: MultiMap::new(), }; map.edits = map.new_edits(); diff --git a/map_model/src/map.rs b/map_model/src/map.rs index 20c8c22981..18ced78ea3 100644 --- a/map_model/src/map.rs +++ b/map_model/src/map.rs @@ -179,6 +179,7 @@ impl Map { routing_params: RoutingParams::default(), name: MapName::new("zz", "blank city", "blank"), edits: MapEdits::new(), + edits_generation: 0, road_to_buildings: MultiMap::new(), } }