Track when a map is edited and update things better, in both the game's edit mode and the new tool.

This commit is contained in:
Dustin Carlino 2021-08-08 09:22:32 -07:00
parent 100b068086
commit 9b4107f061
7 changed files with 29 additions and 23 deletions

View File

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

View File

@ -31,16 +31,12 @@ pub struct ExploreMap {
// TODO Also cache Nearby, but recalculate it after edits
nearby: Option<Nearby>,
// 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<dyn State<App>> {
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<App> 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);

View File

@ -85,8 +85,8 @@ impl State<App> 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<App> for QuickSketch {
return Transition::Replace(PopupMsg::new_state(ctx, "Changes made", messages));
}
_ => unreachable!(),
},
_ => {}
}
}
if self.route_sketcher.event(ctx, app) {

View File

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

View File

@ -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<RoadID, BuildingID>,
}

View File

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

View File

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