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
|
## Refactoring
|
||||||
|
|
||||||
perl -pi -e 's/WrappedComposite::text_button\(ctx, (.+?), (.+?)\)/Btn::text_fg(\1).build_def\(ctx, \2\)/' `find|grep rs|xargs`
|
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 geom::{Distance, Time};
|
||||||
use map_model::{Map, Traversable};
|
use map_model::{Map, Traversable};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::collections::{BTreeMap, VecDeque};
|
use std::collections::{BTreeMap, BTreeSet, VecDeque};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Clone)]
|
#[derive(Serialize, Deserialize, PartialEq, Clone)]
|
||||||
pub struct Queue {
|
pub struct Queue {
|
||||||
@ -38,6 +38,16 @@ impl Queue {
|
|||||||
now: Time,
|
now: Time,
|
||||||
cars: &BTreeMap<CarID, Car>,
|
cars: &BTreeMap<CarID, Car>,
|
||||||
queues: &BTreeMap<Traversable, Queue>,
|
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)> {
|
) -> Vec<(CarID, Distance)> {
|
||||||
if self.cars.is_empty() {
|
if self.cars.is_empty() {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
@ -56,10 +66,31 @@ impl Queue {
|
|||||||
//self.geom_len - cars[&id].vehicle.length - FOLLOWING_DISTANCE
|
//self.geom_len - cars[&id].vehicle.length - FOLLOWING_DISTANCE
|
||||||
|
|
||||||
// The expensive case. We need to figure out exactly where the laggy head
|
// 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];
|
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()]
|
let (head, head_dist) = *queues[&leader.router.head()]
|
||||||
.get_car_positions(now, cars, queues)
|
.inner_get_car_positions(now, cars, queues, recursed_queues)
|
||||||
.last()
|
.last()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(head, id);
|
assert_eq!(head, id);
|
||||||
@ -73,7 +104,9 @@ impl Queue {
|
|||||||
}
|
}
|
||||||
// They might actually be out of the way, but laggy_head hasn't been
|
// They might actually be out of the way, but laggy_head hasn't been
|
||||||
// updated yet.
|
// 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
|
self.geom_len
|
||||||
- (cars[&id].vehicle.length - dist_away_from_this_queue)
|
- (cars[&id].vehicle.length - dist_away_from_this_queue)
|
||||||
- FOLLOWING_DISTANCE
|
- FOLLOWING_DISTANCE
|
||||||
@ -81,6 +114,7 @@ impl Queue {
|
|||||||
self.geom_len
|
self.geom_len
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
None => self.geom_len,
|
None => self.geom_len,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user