mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-30 18:01:35 +03:00
Record timing while applying map edits. Even in release mode, this is a long inexplicable pause for large-scale bike network changes. A loading screen is better.
This commit is contained in:
parent
0fc1af0dd9
commit
309db511c2
@ -499,7 +499,9 @@ impl State<App> for SaveEdits {
|
|||||||
"Save" => {
|
"Save" => {
|
||||||
let mut edits = app.primary.map.get_edits().clone();
|
let mut edits = app.primary.map.get_edits().clone();
|
||||||
edits.edits_name = self.current_name.clone();
|
edits.edits_name = self.current_name.clone();
|
||||||
app.primary.map.must_apply_edits(edits);
|
app.primary
|
||||||
|
.map
|
||||||
|
.must_apply_edits(edits, &mut Timer::throwaway());
|
||||||
app.primary.map.save_edits();
|
app.primary.map.save_edits();
|
||||||
if self.reset {
|
if self.reset {
|
||||||
apply_map_edits(ctx, app, app.primary.map.new_edits());
|
apply_map_edits(ctx, app, app.primary.map.new_edits());
|
||||||
@ -687,8 +689,7 @@ fn make_topcenter(ctx: &mut EventCtx, app: &App) -> Panel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_map_edits(ctx: &mut EventCtx, app: &mut App, edits: MapEdits) {
|
pub fn apply_map_edits(ctx: &mut EventCtx, app: &mut App, edits: MapEdits) {
|
||||||
let mut timer = Timer::new("apply map edits");
|
ctx.loading_screen("apply map edits", |ctx, timer| {
|
||||||
|
|
||||||
if app.primary.unedited_map.is_none() {
|
if app.primary.unedited_map.is_none() {
|
||||||
timer.start("save unedited map");
|
timer.start("save unedited map");
|
||||||
assert!(app.primary.map.get_edits().commands.is_empty());
|
assert!(app.primary.map.get_edits().commands.is_empty());
|
||||||
@ -697,14 +698,14 @@ pub fn apply_map_edits(ctx: &mut EventCtx, app: &mut App, edits: MapEdits) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
timer.start("edit map");
|
timer.start("edit map");
|
||||||
let effects = app.primary.map.must_apply_edits(edits);
|
let effects = app.primary.map.must_apply_edits(edits, timer);
|
||||||
timer.stop("edit map");
|
timer.stop("edit map");
|
||||||
|
|
||||||
if !effects.changed_roads.is_empty() || !effects.changed_intersections.is_empty() {
|
if !effects.changed_roads.is_empty() || !effects.changed_intersections.is_empty() {
|
||||||
app.primary
|
app.primary
|
||||||
.draw_map
|
.draw_map
|
||||||
.draw_all_unzoomed_roads_and_intersections =
|
.draw_all_unzoomed_roads_and_intersections =
|
||||||
DrawMap::regenerate_unzoomed_layer(&app.primary.map, &app.cs, ctx, &mut timer);
|
DrawMap::regenerate_unzoomed_layer(&app.primary.map, &app.cs, ctx, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
for l in effects.deleted_lanes {
|
for l in effects.deleted_lanes {
|
||||||
@ -738,6 +739,7 @@ pub fn apply_map_edits(ctx: &mut EventCtx, app: &mut App, edits: MapEdits) {
|
|||||||
|
|
||||||
// Autosave
|
// Autosave
|
||||||
app.primary.map.save_edits();
|
app.primary.map.save_edits();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_edit_lane(app: &App, l: LaneID) -> bool {
|
pub fn can_edit_lane(app: &App, l: LaneID) -> bool {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
|
use abstutil::Timer;
|
||||||
use map_gui::tools::PopupMsg;
|
use map_gui::tools::PopupMsg;
|
||||||
use map_model::{connectivity, EditCmd, PathConstraints};
|
use map_model::{connectivity, EditCmd, PathConstraints};
|
||||||
use widgetry::{EventCtx, State};
|
use widgetry::{EventCtx, State};
|
||||||
@ -21,11 +22,15 @@ pub fn check_sidewalk_connectivity(
|
|||||||
|
|
||||||
let mut edits = orig_edits.clone();
|
let mut edits = orig_edits.clone();
|
||||||
edits.commands.push(cmd);
|
edits.commands.push(cmd);
|
||||||
app.primary.map.try_apply_edits(edits);
|
app.primary
|
||||||
|
.map
|
||||||
|
.try_apply_edits(edits, &mut Timer::throwaway());
|
||||||
|
|
||||||
let (_, disconnected_after) =
|
let (_, disconnected_after) =
|
||||||
connectivity::find_scc(&app.primary.map, PathConstraints::Pedestrian);
|
connectivity::find_scc(&app.primary.map, PathConstraints::Pedestrian);
|
||||||
app.primary.map.must_apply_edits(orig_edits);
|
app.primary
|
||||||
|
.map
|
||||||
|
.must_apply_edits(orig_edits, &mut Timer::throwaway());
|
||||||
|
|
||||||
let newly_disconnected = disconnected_after
|
let newly_disconnected = disconnected_after
|
||||||
.difference(&disconnected_before)
|
.difference(&disconnected_before)
|
||||||
@ -68,7 +73,9 @@ pub fn check_blackholes(
|
|||||||
|
|
||||||
let mut edits = orig_edits.clone();
|
let mut edits = orig_edits.clone();
|
||||||
edits.commands.push(cmd);
|
edits.commands.push(cmd);
|
||||||
app.primary.map.try_apply_edits(edits);
|
app.primary
|
||||||
|
.map
|
||||||
|
.try_apply_edits(edits, &mut Timer::throwaway());
|
||||||
|
|
||||||
let mut newly_disconnected = BTreeSet::new();
|
let mut newly_disconnected = BTreeSet::new();
|
||||||
for l in connectivity::find_scc(&app.primary.map, PathConstraints::Car).1 {
|
for l in connectivity::find_scc(&app.primary.map, PathConstraints::Car).1 {
|
||||||
@ -81,7 +88,9 @@ pub fn check_blackholes(
|
|||||||
newly_disconnected.insert(l);
|
newly_disconnected.insert(l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.primary.map.must_apply_edits(orig_edits);
|
app.primary
|
||||||
|
.map
|
||||||
|
.must_apply_edits(orig_edits, &mut Timer::throwaway());
|
||||||
|
|
||||||
if newly_disconnected.is_empty() {
|
if newly_disconnected.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -202,7 +202,7 @@ fn handle_command(
|
|||||||
old: map.get_i_edit(id),
|
old: map.get_i_edit(id),
|
||||||
new: EditIntersection::TrafficSignal(ts.export(map)),
|
new: EditIntersection::TrafficSignal(ts.export(map)),
|
||||||
});
|
});
|
||||||
map.must_apply_edits(edits);
|
map.must_apply_edits(edits, &mut Timer::throwaway());
|
||||||
map.recalculate_pathfinding_after_edits(&mut Timer::throwaway());
|
map.recalculate_pathfinding_after_edits(&mut Timer::throwaway());
|
||||||
|
|
||||||
Ok(format!("{} has been updated", id))
|
Ok(format!("{} has been updated", id))
|
||||||
@ -476,7 +476,7 @@ impl LoadSim {
|
|||||||
let mut map = Map::load_synchronously(scenario.map_name.path(), timer);
|
let mut map = Map::load_synchronously(scenario.map_name.path(), timer);
|
||||||
if let Some(perma) = self.edits.clone() {
|
if let Some(perma) = self.edits.clone() {
|
||||||
let edits = perma.into_edits(&map).unwrap();
|
let edits = perma.into_edits(&map).unwrap();
|
||||||
map.must_apply_edits(edits);
|
map.must_apply_edits(edits, timer);
|
||||||
map.recalculate_pathfinding_after_edits(timer);
|
map.recalculate_pathfinding_after_edits(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,17 +815,22 @@ impl Map {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns (changed_roads, deleted_lanes, deleted_turns, added_turns, changed_intersections)
|
/// Returns (changed_roads, deleted_lanes, deleted_turns, added_turns, changed_intersections)
|
||||||
pub fn must_apply_edits(&mut self, new_edits: MapEdits) -> EditEffects {
|
pub fn must_apply_edits(&mut self, new_edits: MapEdits, timer: &mut Timer) -> EditEffects {
|
||||||
self.apply_edits(new_edits, true)
|
self.apply_edits(new_edits, true, timer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_apply_edits(&mut self, new_edits: MapEdits) {
|
pub fn try_apply_edits(&mut self, new_edits: MapEdits, timer: &mut Timer) {
|
||||||
self.apply_edits(new_edits, false);
|
self.apply_edits(new_edits, false, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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,
|
||||||
|
timer: &mut Timer,
|
||||||
|
) -> EditEffects {
|
||||||
self.edits_generation += 1;
|
self.edits_generation += 1;
|
||||||
|
|
||||||
let mut effects = EditEffects {
|
let mut effects = EditEffects {
|
||||||
@ -855,8 +860,9 @@ impl Map {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Undo existing edits
|
timer.start_iter("undo old edits", self.edits.commands.len() - start_at_idx);
|
||||||
for _ in start_at_idx..self.edits.commands.len() {
|
for _ in start_at_idx..self.edits.commands.len() {
|
||||||
|
timer.next();
|
||||||
self.edits
|
self.edits
|
||||||
.commands
|
.commands
|
||||||
.pop()
|
.pop()
|
||||||
@ -865,8 +871,9 @@ impl Map {
|
|||||||
.apply(&mut effects, self);
|
.apply(&mut effects, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply new edits.
|
timer.start_iter("apply new edits", new_edits.commands.len() - start_at_idx);
|
||||||
for cmd in &new_edits.commands[start_at_idx..] {
|
for cmd in &new_edits.commands[start_at_idx..] {
|
||||||
|
timer.next();
|
||||||
cmd.apply(&mut effects, self);
|
cmd.apply(&mut effects, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ impl SimFlags {
|
|||||||
timer,
|
timer,
|
||||||
) {
|
) {
|
||||||
Ok(edits) => {
|
Ok(edits) => {
|
||||||
map.must_apply_edits(edits);
|
map.must_apply_edits(edits, timer);
|
||||||
map.recalculate_pathfinding_after_edits(timer);
|
map.recalculate_pathfinding_after_edits(timer);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -26,7 +26,7 @@ fn main() {
|
|||||||
{
|
{
|
||||||
let mut edits = map.get_edits().clone();
|
let mut edits = map.get_edits().clone();
|
||||||
edits.edits_name = "traffic_seitan".to_string();
|
edits.edits_name = "traffic_seitan".to_string();
|
||||||
map.must_apply_edits(edits);
|
map.must_apply_edits(edits, &mut timer);
|
||||||
map.recalculate_pathfinding_after_edits(&mut timer);
|
map.recalculate_pathfinding_after_edits(&mut timer);
|
||||||
sim.handle_live_edits(&map, &mut timer);
|
sim.handle_live_edits(&map, &mut timer);
|
||||||
}
|
}
|
||||||
@ -36,7 +36,7 @@ fn main() {
|
|||||||
})) {
|
})) {
|
||||||
let mut edits = map.get_edits().clone();
|
let mut edits = map.get_edits().clone();
|
||||||
edits.edits_name = "traffic_seitan_crash".to_string();
|
edits.edits_name = "traffic_seitan_crash".to_string();
|
||||||
map.must_apply_edits(edits);
|
map.must_apply_edits(edits, &mut timer);
|
||||||
map.save_edits();
|
map.save_edits();
|
||||||
|
|
||||||
println!("Crashed at {}", sim.time());
|
println!("Crashed at {}", sim.time());
|
||||||
@ -58,7 +58,7 @@ fn run(map: &mut Map, sim: &mut Sim, rng: &mut XorShiftRng, timer: &mut Timer) {
|
|||||||
nuke_random_parking(map, rng, &mut edits);
|
nuke_random_parking(map, rng, &mut edits);
|
||||||
alter_turn_destinations(sim, map, rng, &mut edits);
|
alter_turn_destinations(sim, map, rng, &mut edits);
|
||||||
|
|
||||||
map.must_apply_edits(edits);
|
map.must_apply_edits(edits, timer);
|
||||||
map.recalculate_pathfinding_after_edits(timer);
|
map.recalculate_pathfinding_after_edits(timer);
|
||||||
sim.handle_live_edited_traffic_signals(map);
|
sim.handle_live_edited_traffic_signals(map);
|
||||||
sim.handle_live_edits(map, timer);
|
sim.handle_live_edits(map, timer);
|
||||||
|
Loading…
Reference in New Issue
Block a user