mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 15:02:59 +03:00
Entering edit mode is slow on large maps, because clearing the simulation recreates parking state for every building. Parallelize it to speed it up at least a bit.
This commit is contained in:
parent
866ecd5f88
commit
4fd86c8a41
@ -100,7 +100,10 @@ impl EditMode {
|
||||
app.primary
|
||||
.sim
|
||||
.handle_live_edited_traffic_signals(&app.primary.map);
|
||||
let (trips, parked_cars) = app.primary.sim.handle_live_edits(&app.primary.map);
|
||||
let (trips, parked_cars) = app
|
||||
.primary
|
||||
.sim
|
||||
.handle_live_edits(&app.primary.map, &mut timer);
|
||||
if trips == 0 && parked_cars == 0 {
|
||||
Transition::Pop
|
||||
} else {
|
||||
|
@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use abstutil::{
|
||||
deserialize_btreemap, deserialize_multimap, serialize_btreemap, serialize_multimap, MultiMap,
|
||||
Timer,
|
||||
};
|
||||
use geom::{Distance, PolyLine, Pt2D};
|
||||
use map_model::{
|
||||
@ -24,7 +25,7 @@ use crate::{CarID, CarStatus, DrawCarInput, Event, ParkedCar, ParkingSpot, Perso
|
||||
pub trait ParkingSim {
|
||||
/// Returns any cars that got very abruptly evicted from existence, and also cars actively
|
||||
/// moving into a deleted spot.
|
||||
fn handle_live_edits(&mut self, map: &Map) -> (Vec<ParkedCar>, Vec<CarID>);
|
||||
fn handle_live_edits(&mut self, map: &Map, timer: &mut Timer) -> (Vec<ParkedCar>, Vec<CarID>);
|
||||
fn get_free_onstreet_spots(&self, l: LaneID) -> Vec<ParkingSpot>;
|
||||
fn get_free_offstreet_spots(&self, b: BuildingID) -> Vec<ParkingSpot>;
|
||||
fn get_free_lot_spots(&self, pl: ParkingLotID) -> Vec<ParkingSpot>;
|
||||
@ -86,11 +87,11 @@ pub enum ParkingSimState {
|
||||
impl ParkingSimState {
|
||||
/// Counterintuitive: any spots located in blackholes are just not represented here. If somebody
|
||||
/// tries to drive from a blackholed spot, they couldn't reach most places.
|
||||
pub fn new(map: &Map, infinite: bool) -> ParkingSimState {
|
||||
pub fn new(map: &Map, infinite: bool, timer: &mut Timer) -> ParkingSimState {
|
||||
if infinite {
|
||||
ParkingSimState::Infinite(InfiniteParkingSimState::new(map))
|
||||
} else {
|
||||
ParkingSimState::Normal(NormalParkingSimState::new(map))
|
||||
ParkingSimState::Normal(NormalParkingSimState::new(map, timer))
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,7 +151,7 @@ pub struct NormalParkingSimState {
|
||||
}
|
||||
|
||||
impl NormalParkingSimState {
|
||||
fn new(map: &Map) -> NormalParkingSimState {
|
||||
fn new(map: &Map, timer: &mut Timer) -> NormalParkingSimState {
|
||||
let mut sim = NormalParkingSimState {
|
||||
parked_cars: BTreeMap::new(),
|
||||
occupants: BTreeMap::new(),
|
||||
@ -171,18 +172,36 @@ impl NormalParkingSimState {
|
||||
sim.onstreet_lanes.insert(lane.parking_lane, lane);
|
||||
}
|
||||
}
|
||||
for b in map.all_buildings() {
|
||||
if let Some((pos, _)) = b.driving_connection(map) {
|
||||
if !map.get_l(pos.lane()).driving_blackhole {
|
||||
let num_spots = b.num_parking_spots();
|
||||
if num_spots > 0 {
|
||||
sim.num_spots_per_offstreet.insert(b.id, num_spots);
|
||||
sim.driving_to_offstreet
|
||||
.insert(pos.lane(), (b.id, pos.dist_along()));
|
||||
// This is slow on huge maps
|
||||
for (b, pos, num_spots) in timer
|
||||
.parallelize(
|
||||
"setup offstreet parking",
|
||||
map.all_buildings().iter().collect(),
|
||||
|b| {
|
||||
if let Some((pos, _)) = b.driving_connection(map) {
|
||||
if !map.get_l(pos.lane()).driving_blackhole {
|
||||
let num_spots = b.num_parking_spots();
|
||||
if num_spots > 0 {
|
||||
Some((b.id, pos, num_spots))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
{
|
||||
sim.num_spots_per_offstreet.insert(b, num_spots);
|
||||
sim.driving_to_offstreet
|
||||
.insert(pos.lane(), (b, pos.dist_along()));
|
||||
}
|
||||
|
||||
for pl in map.all_parking_lots() {
|
||||
if !map.get_l(pl.driving_pos.lane()).driving_blackhole {
|
||||
sim.num_spots_per_lot.insert(pl.id, pl.capacity());
|
||||
@ -195,9 +214,9 @@ impl NormalParkingSimState {
|
||||
}
|
||||
|
||||
impl ParkingSim for NormalParkingSimState {
|
||||
fn handle_live_edits(&mut self, map: &Map) -> (Vec<ParkedCar>, Vec<CarID>) {
|
||||
fn handle_live_edits(&mut self, map: &Map, timer: &mut Timer) -> (Vec<ParkedCar>, Vec<CarID>) {
|
||||
let (filled_before, _) = self.get_all_parking_spots();
|
||||
let new = NormalParkingSimState::new(map);
|
||||
let new = NormalParkingSimState::new(map, timer);
|
||||
let (_, avail_after) = new.get_all_parking_spots();
|
||||
let avail_after: BTreeSet<ParkingSpot> = avail_after.into_iter().collect();
|
||||
|
||||
@ -814,7 +833,7 @@ impl InfiniteParkingSimState {
|
||||
}
|
||||
|
||||
impl ParkingSim for InfiniteParkingSimState {
|
||||
fn handle_live_edits(&mut self, map: &Map) -> (Vec<ParkedCar>, Vec<CarID>) {
|
||||
fn handle_live_edits(&mut self, map: &Map, _: &mut Timer) -> (Vec<ParkedCar>, Vec<CarID>) {
|
||||
// Can live edits possibly affect anything?
|
||||
let new = InfiniteParkingSimState::new(map);
|
||||
self.driving_to_offstreet = new.driving_to_offstreet;
|
||||
|
@ -202,10 +202,11 @@ impl SimOptions {
|
||||
// Setup
|
||||
impl Sim {
|
||||
pub fn new(map: &Map, opts: SimOptions) -> Sim {
|
||||
let mut timer = Timer::new("create blank sim");
|
||||
let mut scheduler = Scheduler::new();
|
||||
Sim {
|
||||
driving: DrivingSimState::new(map, &opts),
|
||||
parking: ParkingSimState::new(map, opts.infinite_parking),
|
||||
parking: ParkingSimState::new(map, opts.infinite_parking, &mut timer),
|
||||
walking: WalkingSimState::new(),
|
||||
intersections: IntersectionSimState::new(map, &mut scheduler, &opts),
|
||||
transit: TransitSimState::new(map),
|
||||
@ -841,10 +842,10 @@ impl Sim {
|
||||
|
||||
/// Respond to arbitrary map edits without resetting the simulation. Returns the number of
|
||||
/// (trips cancelled, parked cars displaced).
|
||||
pub fn handle_live_edits(&mut self, map: &Map) -> (usize, usize) {
|
||||
pub fn handle_live_edits(&mut self, map: &Map, timer: &mut Timer) -> (usize, usize) {
|
||||
self.edits_name = map.get_edits().edits_name.clone();
|
||||
|
||||
let (affected, num_parked_cars) = self.find_trips_affected_by_live_edits(map);
|
||||
let (affected, num_parked_cars) = self.find_trips_affected_by_live_edits(map, timer);
|
||||
let num_trips_cancelled = affected.len();
|
||||
let affected_agents: BTreeSet<AgentID> = affected.iter().map(|(a, _)| *a).collect();
|
||||
|
||||
@ -899,6 +900,7 @@ impl Sim {
|
||||
fn find_trips_affected_by_live_edits(
|
||||
&mut self,
|
||||
map: &Map,
|
||||
timer: &mut Timer,
|
||||
) -> (BTreeSet<(AgentID, TripID)>, usize) {
|
||||
let mut affected: BTreeSet<(AgentID, TripID)> = BTreeSet::new();
|
||||
|
||||
@ -939,7 +941,8 @@ impl Sim {
|
||||
}
|
||||
|
||||
let num_evicted = {
|
||||
let (evicted_cars, cars_parking_in_the_void) = self.parking.handle_live_edits(map);
|
||||
let (evicted_cars, cars_parking_in_the_void) =
|
||||
self.parking.handle_live_edits(map, timer);
|
||||
let num_evicted = evicted_cars.len();
|
||||
affected.extend(self.walking.find_trips_to_parking(evicted_cars));
|
||||
for car in cars_parking_in_the_void {
|
||||
|
Loading…
Reference in New Issue
Block a user