mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 01:15:12 +03:00
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:
parent
100b068086
commit
9b4107f061
@ -40,8 +40,7 @@ pub struct EditMode {
|
|||||||
// Retained state from the SandboxMode that spawned us
|
// Retained state from the SandboxMode that spawned us
|
||||||
mode: GameplayMode,
|
mode: GameplayMode,
|
||||||
|
|
||||||
// edits name, number of commands
|
map_edit_key: usize,
|
||||||
changelist_key: (String, usize),
|
|
||||||
|
|
||||||
unzoomed: Drawable,
|
unzoomed: Drawable,
|
||||||
zoomed: Drawable,
|
zoomed: Drawable,
|
||||||
@ -52,16 +51,15 @@ impl EditMode {
|
|||||||
let orig_dirty = app.primary.dirty_from_edits;
|
let orig_dirty = app.primary.dirty_from_edits;
|
||||||
assert!(app.primary.suspended_sim.is_none());
|
assert!(app.primary.suspended_sim.is_none());
|
||||||
app.primary.suspended_sim = Some(app.primary.clear_sim());
|
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);
|
let layer = crate::layer::map::Static::edits(ctx, app);
|
||||||
Box::new(EditMode {
|
Box::new(EditMode {
|
||||||
tool_panel: tool_panel(ctx),
|
tool_panel: tool_panel(ctx),
|
||||||
top_center: make_topcenter(ctx, app),
|
top_center: make_topcenter(ctx, app),
|
||||||
changelist: make_changelist(ctx, app),
|
changelist: make_changelist(ctx, app),
|
||||||
orig_edits: edits.clone(),
|
orig_edits: app.primary.map.get_edits().clone(),
|
||||||
orig_dirty,
|
orig_dirty,
|
||||||
mode,
|
mode,
|
||||||
changelist_key: (edits.edits_name.clone(), edits.commands.len()),
|
map_edit_key: app.primary.map.get_edits_change_key(),
|
||||||
unzoomed: layer.unzoomed,
|
unzoomed: layer.unzoomed,
|
||||||
zoomed: layer.zoomed,
|
zoomed: layer.zoomed,
|
||||||
})
|
})
|
||||||
@ -146,10 +144,11 @@ impl EditMode {
|
|||||||
impl State<App> for EditMode {
|
impl State<App> for EditMode {
|
||||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||||
{
|
{
|
||||||
let edits = app.primary.map.get_edits();
|
// We would normally use Cached, but so many values depend on one key, so this is more
|
||||||
let changelist_key = (edits.edits_name.clone(), edits.commands.len());
|
// clear.
|
||||||
if self.changelist_key != changelist_key {
|
let key = app.primary.map.get_edits_change_key();
|
||||||
self.changelist_key = changelist_key;
|
if self.map_edit_key != key {
|
||||||
|
self.map_edit_key = key;
|
||||||
self.changelist = make_changelist(ctx, app);
|
self.changelist = make_changelist(ctx, app);
|
||||||
let layer = crate::layer::map::Static::edits(ctx, app);
|
let layer = crate::layer::map::Static::edits(ctx, app);
|
||||||
self.unzoomed = layer.unzoomed;
|
self.unzoomed = layer.unzoomed;
|
||||||
|
@ -31,16 +31,12 @@ pub struct ExploreMap {
|
|||||||
// TODO Also cache Nearby, but recalculate it after edits
|
// TODO Also cache Nearby, but recalculate it after edits
|
||||||
nearby: Option<Nearby>,
|
nearby: Option<Nearby>,
|
||||||
|
|
||||||
// edits name, number of commands
|
map_edit_key: usize,
|
||||||
// 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),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExploreMap {
|
impl ExploreMap {
|
||||||
pub fn new_state(ctx: &mut EventCtx, app: &mut App) -> Box<dyn State<App>> {
|
pub fn new_state(ctx: &mut EventCtx, app: &mut App) -> Box<dyn State<App>> {
|
||||||
app.opts.show_building_driveways = false;
|
app.opts.show_building_driveways = false;
|
||||||
let edits = app.primary.map.get_edits();
|
|
||||||
|
|
||||||
Box::new(ExploreMap {
|
Box::new(ExploreMap {
|
||||||
top_panel: make_top_panel(ctx, app),
|
top_panel: make_top_panel(ctx, app),
|
||||||
@ -51,7 +47,7 @@ impl ExploreMap {
|
|||||||
elevation: false,
|
elevation: false,
|
||||||
nearby: None,
|
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 {
|
impl State<App> for ExploreMap {
|
||||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||||
{
|
{
|
||||||
let edits = app.primary.map.get_edits();
|
// We would normally use Cached, but so many values depend on one key, so this is more
|
||||||
let changelist_key = (edits.edits_name.clone(), edits.commands.len());
|
// clear.
|
||||||
if self.changelist_key != changelist_key {
|
let key = app.primary.map.get_edits_change_key();
|
||||||
self.changelist_key = changelist_key;
|
if self.map_edit_key != key {
|
||||||
|
self.map_edit_key = key;
|
||||||
self.network_layer = render_network_layer(ctx, app);
|
self.network_layer = render_network_layer(ctx, app);
|
||||||
self.edits_layer = render_edits(ctx, app);
|
self.edits_layer = render_edits(ctx, app);
|
||||||
self.top_panel = make_top_panel(ctx, app);
|
self.top_panel = make_top_panel(ctx, app);
|
||||||
|
@ -85,8 +85,8 @@ impl State<App> for QuickSketch {
|
|||||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||||
self.magnifying_glass.event(ctx, app);
|
self.magnifying_glass.event(ctx, app);
|
||||||
|
|
||||||
match self.top_panel.event(ctx) {
|
if let Outcome::Clicked(x) = self.top_panel.event(ctx) {
|
||||||
Outcome::Clicked(x) => match x.as_ref() {
|
match x.as_ref() {
|
||||||
"Cancel" => {
|
"Cancel" => {
|
||||||
return Transition::Pop;
|
return Transition::Pop;
|
||||||
}
|
}
|
||||||
@ -100,8 +100,7 @@ impl State<App> for QuickSketch {
|
|||||||
return Transition::Replace(PopupMsg::new_state(ctx, "Changes made", messages));
|
return Transition::Replace(PopupMsg::new_state(ctx, "Changes made", messages));
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.route_sketcher.event(ctx, app) {
|
if self.route_sketcher.event(ctx, app) {
|
||||||
|
@ -774,6 +774,8 @@ impl Map {
|
|||||||
// new_edits don't necessarily have to be valid; this could be used for speculatively testing
|
// new_edits don't necessarily have to be valid; this could be used for speculatively testing
|
||||||
// edits. Doesn't update pathfinding yet.
|
// edits. Doesn't update pathfinding yet.
|
||||||
fn apply_edits(&mut self, mut new_edits: MapEdits, enforce_valid: bool) -> EditEffects {
|
fn apply_edits(&mut self, mut new_edits: MapEdits, enforce_valid: bool) -> EditEffects {
|
||||||
|
self.edits_generation += 1;
|
||||||
|
|
||||||
let mut effects = EditEffects {
|
let mut effects = EditEffects {
|
||||||
changed_roads: BTreeSet::new(),
|
changed_roads: BTreeSet::new(),
|
||||||
deleted_lanes: BTreeSet::new(),
|
deleted_lanes: BTreeSet::new(),
|
||||||
@ -907,4 +909,9 @@ impl Map {
|
|||||||
);
|
);
|
||||||
self.traffic_signals.insert(signal.id, signal);
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,5 +116,7 @@ pub struct Map {
|
|||||||
#[serde(skip_serializing, skip_deserializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
edits: MapEdits,
|
edits: MapEdits,
|
||||||
#[serde(skip_serializing, skip_deserializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
|
edits_generation: usize,
|
||||||
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
road_to_buildings: MultiMap<RoadID, BuildingID>,
|
road_to_buildings: MultiMap<RoadID, BuildingID>,
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,7 @@ impl Map {
|
|||||||
routing_params: RoutingParams::default(),
|
routing_params: RoutingParams::default(),
|
||||||
name: raw.name.clone(),
|
name: raw.name.clone(),
|
||||||
edits: MapEdits::new(),
|
edits: MapEdits::new(),
|
||||||
|
edits_generation: 0,
|
||||||
road_to_buildings: MultiMap::new(),
|
road_to_buildings: MultiMap::new(),
|
||||||
};
|
};
|
||||||
map.edits = map.new_edits();
|
map.edits = map.new_edits();
|
||||||
|
@ -179,6 +179,7 @@ impl Map {
|
|||||||
routing_params: RoutingParams::default(),
|
routing_params: RoutingParams::default(),
|
||||||
name: MapName::new("zz", "blank city", "blank"),
|
name: MapName::new("zz", "blank city", "blank"),
|
||||||
edits: MapEdits::new(),
|
edits: MapEdits::new(),
|
||||||
|
edits_generation: 0,
|
||||||
road_to_buildings: MultiMap::new(),
|
road_to_buildings: MultiMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user