mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 01:13:53 +03:00
show accepted agents when hovering over an intersection
This commit is contained in:
parent
2a8842aa00
commit
28d025103c
@ -33,7 +33,6 @@ pub fn default_colors() -> HashMap<String, Color> {
|
||||
);
|
||||
m.insert("car turn arrow".to_string(), Color::CYAN);
|
||||
m.insert("car window".to_string(), Color::BLACK);
|
||||
m.insert("car/building owner".to_string(), Color::PURPLE);
|
||||
m.insert("chokepoint".to_string(), Color::RED);
|
||||
m.insert("crosswalk".to_string(), Color::WHITE);
|
||||
m.insert("crosswalk turn".to_string(), Color::WHITE);
|
||||
@ -99,6 +98,10 @@ pub fn default_colors() -> HashMap<String, Color> {
|
||||
m.insert("sidewalk corner".to_string(), Color::grey(0.7));
|
||||
m.insert("sidewalk lines".to_string(), Color::grey(0.7));
|
||||
m.insert("signal editor panel".to_string(), Color::BLACK.alpha(0.95));
|
||||
m.insert(
|
||||
"something associated with something else".to_string(),
|
||||
Color::PURPLE,
|
||||
);
|
||||
m.insert("stop line for lane".to_string(), Color::RED);
|
||||
m.insert("stop sign background".to_string(), Color::RED);
|
||||
m.insert("stop sign priority turns".to_string(), Color::GREEN);
|
||||
|
@ -3,7 +3,7 @@ mod follow;
|
||||
mod neighborhood_summary;
|
||||
mod search;
|
||||
mod show_activity;
|
||||
mod show_owner;
|
||||
mod show_associated;
|
||||
mod show_route;
|
||||
mod turn_cycler;
|
||||
mod warp;
|
||||
@ -37,7 +37,7 @@ impl ViewMode {
|
||||
timer,
|
||||
)),
|
||||
Box::new(show_activity::ShowActivityState::new(Key::A)),
|
||||
Box::new(show_owner::ShowOwnerState::new()),
|
||||
Box::new(show_associated::ShowAssociatedState::new()),
|
||||
Box::new(show_route::ShowRouteState::new(Key::R, Key::L)),
|
||||
Box::new(turn_cycler::TurnCyclerState::new(Key::Tab)),
|
||||
],
|
||||
|
113
editor/src/plugins/view/show_associated.rs
Normal file
113
editor/src/plugins/view/show_associated.rs
Normal file
@ -0,0 +1,113 @@
|
||||
use crate::objects::{Ctx, ID};
|
||||
use crate::plugins::{Plugin, PluginCtx};
|
||||
use crate::render::ExtraShapeID;
|
||||
use ezgui::Color;
|
||||
use map_model::{BuildingID, IntersectionID, RoadID};
|
||||
use sim::{AgentID, CarID};
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub enum ShowAssociatedState {
|
||||
Inactive,
|
||||
BuildingSelected(BuildingID, HashSet<CarID>),
|
||||
CarSelected(CarID, Option<BuildingID>),
|
||||
ShapeSelected(ExtraShapeID, Option<(RoadID, bool)>),
|
||||
IntersectionSelected(IntersectionID, HashSet<AgentID>),
|
||||
}
|
||||
|
||||
impl ShowAssociatedState {
|
||||
pub fn new() -> ShowAssociatedState {
|
||||
ShowAssociatedState::Inactive
|
||||
}
|
||||
}
|
||||
|
||||
impl Plugin for ShowAssociatedState {
|
||||
fn ambient_event(&mut self, ctx: &mut PluginCtx) {
|
||||
let (selected, sim) = (ctx.primary.current_selection, &ctx.primary.sim);
|
||||
|
||||
// Reset to Inactive when appropriate
|
||||
let mut reset = false;
|
||||
match self {
|
||||
ShowAssociatedState::Inactive => {}
|
||||
ShowAssociatedState::BuildingSelected(b, _) => {
|
||||
reset = selected != Some(ID::Building(*b));
|
||||
}
|
||||
ShowAssociatedState::CarSelected(c, _) => {
|
||||
reset = selected != Some(ID::Car(*c));
|
||||
}
|
||||
ShowAssociatedState::ShapeSelected(es, _) => {
|
||||
reset = selected != Some(ID::ExtraShape(*es));
|
||||
}
|
||||
ShowAssociatedState::IntersectionSelected(_, _) => {
|
||||
// Always recalculate.
|
||||
// TODO Only if the tick has changed, actually.
|
||||
reset = true;
|
||||
}
|
||||
}
|
||||
if reset {
|
||||
*self = ShowAssociatedState::Inactive;
|
||||
}
|
||||
|
||||
if let ShowAssociatedState::Inactive = self {
|
||||
match selected {
|
||||
Some(ID::Building(id)) => {
|
||||
*self = ShowAssociatedState::BuildingSelected(
|
||||
id,
|
||||
sim.get_parked_cars_by_owner(id)
|
||||
.iter()
|
||||
.map(|p| p.car)
|
||||
.collect(),
|
||||
);
|
||||
}
|
||||
Some(ID::Car(id)) => {
|
||||
*self = ShowAssociatedState::CarSelected(id, sim.get_owner_of_car(id));
|
||||
}
|
||||
Some(ID::ExtraShape(id)) => {
|
||||
*self = ShowAssociatedState::ShapeSelected(
|
||||
id,
|
||||
ctx.primary.draw_map.get_es(id).road,
|
||||
);
|
||||
}
|
||||
Some(ID::Intersection(id)) => {
|
||||
*self =
|
||||
ShowAssociatedState::IntersectionSelected(id, sim.get_accepted_agents(id));
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn color_for(&self, obj: ID, ctx: &Ctx) -> Option<Color> {
|
||||
let color = ctx
|
||||
.cs
|
||||
.get_def("something associated with something else", Color::PURPLE);
|
||||
match (self, obj) {
|
||||
(ShowAssociatedState::BuildingSelected(_, cars), ID::Car(id)) => {
|
||||
if cars.contains(&id) {
|
||||
return Some(color);
|
||||
}
|
||||
}
|
||||
(ShowAssociatedState::CarSelected(_, Some(id1)), ID::Building(id2)) => {
|
||||
if *id1 == id2 {
|
||||
return Some(color);
|
||||
}
|
||||
}
|
||||
(ShowAssociatedState::ShapeSelected(_, Some((r, fwds))), ID::Lane(l)) => {
|
||||
let parent = ctx.map.get_parent(l);
|
||||
if parent.id == *r
|
||||
&& ((*fwds && parent.is_forwards(l)) || (!fwds && parent.is_backwards(l)))
|
||||
{
|
||||
return Some(color);
|
||||
}
|
||||
}
|
||||
(ShowAssociatedState::IntersectionSelected(_, agents), _) => {
|
||||
if let Some(agent) = obj.agent_id() {
|
||||
if agents.contains(&agent) {
|
||||
return Some(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
use crate::objects::{Ctx, ID};
|
||||
use crate::plugins::{Plugin, PluginCtx};
|
||||
use crate::render::ExtraShapeID;
|
||||
use ezgui::Color;
|
||||
use map_model::{BuildingID, RoadID};
|
||||
use sim::CarID;
|
||||
use std::collections::HashSet;
|
||||
|
||||
// TODO rename ShowAssociated?
|
||||
pub enum ShowOwnerState {
|
||||
Inactive,
|
||||
BuildingSelected(BuildingID, HashSet<CarID>),
|
||||
CarSelected(CarID, Option<BuildingID>),
|
||||
ShapeSelected(ExtraShapeID, Option<(RoadID, bool)>),
|
||||
}
|
||||
|
||||
impl ShowOwnerState {
|
||||
pub fn new() -> ShowOwnerState {
|
||||
ShowOwnerState::Inactive
|
||||
}
|
||||
}
|
||||
|
||||
impl Plugin for ShowOwnerState {
|
||||
fn ambient_event(&mut self, ctx: &mut PluginCtx) {
|
||||
let (selected, sim) = (ctx.primary.current_selection, &ctx.primary.sim);
|
||||
|
||||
// Reset to Inactive when appropriate
|
||||
let mut reset = false;
|
||||
match self {
|
||||
ShowOwnerState::Inactive => {}
|
||||
ShowOwnerState::BuildingSelected(b, _) => {
|
||||
reset = selected != Some(ID::Building(*b));
|
||||
}
|
||||
ShowOwnerState::CarSelected(c, _) => {
|
||||
reset = selected != Some(ID::Car(*c));
|
||||
}
|
||||
ShowOwnerState::ShapeSelected(es, _) => {
|
||||
reset = selected != Some(ID::ExtraShape(*es));
|
||||
}
|
||||
}
|
||||
if reset {
|
||||
*self = ShowOwnerState::Inactive;
|
||||
}
|
||||
|
||||
if let ShowOwnerState::Inactive = self {
|
||||
match selected {
|
||||
Some(ID::Building(id)) => {
|
||||
*self = ShowOwnerState::BuildingSelected(
|
||||
id,
|
||||
sim.get_parked_cars_by_owner(id)
|
||||
.iter()
|
||||
.map(|p| p.car)
|
||||
.collect(),
|
||||
);
|
||||
}
|
||||
Some(ID::Car(id)) => {
|
||||
*self = ShowOwnerState::CarSelected(id, sim.get_owner_of_car(id));
|
||||
}
|
||||
Some(ID::ExtraShape(id)) => {
|
||||
*self = ShowOwnerState::ShapeSelected(id, ctx.primary.draw_map.get_es(id).road);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn color_for(&self, obj: ID, ctx: &Ctx) -> Option<Color> {
|
||||
let color = ctx.cs.get_def("car/building owner", Color::PURPLE);
|
||||
match (self, obj) {
|
||||
(ShowOwnerState::BuildingSelected(_, cars), ID::Car(id)) => {
|
||||
if cars.contains(&id) {
|
||||
return Some(color);
|
||||
}
|
||||
}
|
||||
(ShowOwnerState::CarSelected(_, Some(id1)), ID::Building(id2)) => {
|
||||
if *id1 == id2 {
|
||||
return Some(color);
|
||||
}
|
||||
}
|
||||
(ShowOwnerState::ShapeSelected(_, Some((r, fwds))), ID::Lane(l)) => {
|
||||
let parent = ctx.map.get_parent(l);
|
||||
if parent.id == *r
|
||||
&& ((*fwds && parent.is_forwards(l)) || (!fwds && parent.is_backwards(l)))
|
||||
{
|
||||
return Some(color);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ use dimensioned::si;
|
||||
use map_model::{ControlStopSign, IntersectionID, IntersectionType, Map, TurnID, TurnPriority};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::collections::{BTreeMap, BTreeSet, HashSet};
|
||||
|
||||
const WAIT_AT_STOP_SIGN: Time = si::Second {
|
||||
value_unsafe: 1.5,
|
||||
@ -155,6 +155,19 @@ impl IntersectionSimState {
|
||||
IntersectionPolicy::Border => {}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_accepted_agents(&self, id: IntersectionID) -> HashSet<AgentID> {
|
||||
match self.intersections[id.0] {
|
||||
IntersectionPolicy::StopSign(ref p) => {
|
||||
p.accepted.iter().map(|req| req.agent).collect()
|
||||
}
|
||||
IntersectionPolicy::TrafficSignal(ref p) => {
|
||||
p.accepted.iter().map(|req| req.agent).collect()
|
||||
}
|
||||
// Technically anybody on incoming lanes
|
||||
IntersectionPolicy::Border => HashSet::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use an enum instead of traits so that serialization works. I couldn't figure out erased_serde.
|
||||
|
@ -1,5 +1,3 @@
|
||||
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
use crate::driving::DrivingSimState;
|
||||
use crate::instrument::capture_backtrace;
|
||||
use crate::intersections::IntersectionSimState;
|
||||
@ -20,6 +18,7 @@ use map_model::{BuildingID, IntersectionID, LaneID, LaneType, Map, Path, Trace,
|
||||
use rand::{FromEntropy, SeedableRng, XorShiftRng};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Serialize, Deserialize, Derivative)]
|
||||
#[derivative(PartialEq)]
|
||||
@ -412,6 +411,10 @@ impl Sim {
|
||||
.or_else(|| self.parking_state.get_owner_of_car(id))
|
||||
}
|
||||
|
||||
pub fn get_accepted_agents(&self, id: IntersectionID) -> HashSet<AgentID> {
|
||||
self.intersection_state.get_accepted_agents(id)
|
||||
}
|
||||
|
||||
pub fn get_stats(&self) -> &SimStats {
|
||||
&self.stats
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user