mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 12:12:00 +03:00
work around infinite cycle of laggy heads. #30
This commit is contained in:
parent
03c00bcb3b
commit
97a2434e1b
@ -125,3 +125,7 @@ git diff upstream/master
|
||||
## Refactoring
|
||||
|
||||
perl -pi -e 's/WrappedComposite::text_button\(ctx, (.+?), (.+?)\)/Btn::text_fg(\1).build_def\(ctx, \2\)/' `find|grep rs|xargs`
|
||||
|
||||
## Stack overflow
|
||||
|
||||
rust-gdb --args ../target/release/game --dev
|
||||
|
@ -3,7 +3,7 @@ use crate::{CarID, FOLLOWING_DISTANCE};
|
||||
use geom::{Distance, Time};
|
||||
use map_model::{Map, Traversable};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::collections::{BTreeMap, VecDeque};
|
||||
use std::collections::{BTreeMap, BTreeSet, VecDeque};
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Clone)]
|
||||
pub struct Queue {
|
||||
@ -38,6 +38,16 @@ impl Queue {
|
||||
now: Time,
|
||||
cars: &BTreeMap<CarID, Car>,
|
||||
queues: &BTreeMap<Traversable, Queue>,
|
||||
) -> Vec<(CarID, Distance)> {
|
||||
self.inner_get_car_positions(now, cars, queues, &mut BTreeSet::new())
|
||||
}
|
||||
|
||||
fn inner_get_car_positions(
|
||||
&self,
|
||||
now: Time,
|
||||
cars: &BTreeMap<CarID, Car>,
|
||||
queues: &BTreeMap<Traversable, Queue>,
|
||||
recursed_queues: &mut BTreeSet<Traversable>,
|
||||
) -> Vec<(CarID, Distance)> {
|
||||
if self.cars.is_empty() {
|
||||
return Vec::new();
|
||||
@ -56,10 +66,31 @@ impl Queue {
|
||||
//self.geom_len - cars[&id].vehicle.length - FOLLOWING_DISTANCE
|
||||
|
||||
// The expensive case. We need to figure out exactly where the laggy head
|
||||
// is on their queue. No protection against gridlock here!
|
||||
// is on their queue.
|
||||
let leader = &cars[&id];
|
||||
|
||||
// But don't create a cycle!
|
||||
let recurse_to = leader.router.head();
|
||||
if recursed_queues.contains(&recurse_to) {
|
||||
// See the picture in
|
||||
// https://github.com/dabreegster/abstreet/issues/30. We have two
|
||||
// extremes to break the cycle.
|
||||
//
|
||||
// 1) Hope that the last person in this queue isn't bounded by the
|
||||
// agent in front of them yet. geom_len
|
||||
// 2) Assume the leader has advanced minimally into the next lane.
|
||||
// geom_len - laggy head's length - FOLLOWING_DISTANCE.
|
||||
//
|
||||
// For now, optimistically assume 1. If we're wrong, consequences could
|
||||
// be queue spillover (we're too optimistic about the number of
|
||||
// vehicles that can fit on a lane) or cars jumping positions slightly
|
||||
// while the cycle occurs.
|
||||
self.geom_len
|
||||
} else {
|
||||
recursed_queues.insert(recurse_to);
|
||||
|
||||
let (head, head_dist) = *queues[&leader.router.head()]
|
||||
.get_car_positions(now, cars, queues)
|
||||
.inner_get_car_positions(now, cars, queues, recursed_queues)
|
||||
.last()
|
||||
.unwrap();
|
||||
assert_eq!(head, id);
|
||||
@ -73,7 +104,9 @@ impl Queue {
|
||||
}
|
||||
// They might actually be out of the way, but laggy_head hasn't been
|
||||
// updated yet.
|
||||
if dist_away_from_this_queue < leader.vehicle.length + FOLLOWING_DISTANCE {
|
||||
if dist_away_from_this_queue
|
||||
< leader.vehicle.length + FOLLOWING_DISTANCE
|
||||
{
|
||||
self.geom_len
|
||||
- (cars[&id].vehicle.length - dist_away_from_this_queue)
|
||||
- FOLLOWING_DISTANCE
|
||||
@ -81,6 +114,7 @@ impl Queue {
|
||||
self.geom_len
|
||||
}
|
||||
}
|
||||
}
|
||||
None => self.geom_len,
|
||||
},
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user