mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 17:34:58 +03:00
making all plugins that compute stuff for Sim cache per time
This commit is contained in:
parent
af25404777
commit
82beccf86c
@ -4,11 +4,16 @@ use map_model::LANE_THICKNESS;
|
||||
use objects::Ctx;
|
||||
use piston::input::Key;
|
||||
use plugins::{Plugin, PluginCtx};
|
||||
use sim::{Sim, Tick};
|
||||
|
||||
pub enum DiffAllState {
|
||||
Inactive,
|
||||
// TODO Or do we want to augment DrawCars and DrawPeds, so we get automatic quadtree support?
|
||||
Active(Vec<Line>),
|
||||
Active {
|
||||
time: Tick,
|
||||
same_trips: usize,
|
||||
lines: Vec<Line>,
|
||||
},
|
||||
}
|
||||
|
||||
impl DiffAllState {
|
||||
@ -19,49 +24,52 @@ impl DiffAllState {
|
||||
|
||||
impl Plugin for DiffAllState {
|
||||
fn event(&mut self, ctx: PluginCtx) -> bool {
|
||||
let active = match self {
|
||||
let primary_sim = &ctx.primary.sim;
|
||||
|
||||
let mut new_state: Option<DiffAllState> = None;
|
||||
match self {
|
||||
DiffAllState::Inactive => {
|
||||
ctx.secondary.is_some()
|
||||
if ctx.secondary.is_some()
|
||||
&& ctx.primary.current_selection.is_none()
|
||||
&& ctx.input.key_pressed(Key::D, "Diff all trips")
|
||||
}
|
||||
DiffAllState::Active(_) => {
|
||||
!ctx.input.key_pressed(Key::Return, "Stop diffing all trips")
|
||||
}
|
||||
};
|
||||
|
||||
if active {
|
||||
let primary_sim = &ctx.primary.sim;
|
||||
let secondary_sim = ctx.secondary.as_ref().map(|(s, _)| &s.sim).unwrap();
|
||||
|
||||
let stats1 = primary_sim.get_stats();
|
||||
let stats2 = secondary_sim.get_stats();
|
||||
let mut same_trips = 0;
|
||||
let mut lines: Vec<Line> = Vec::new();
|
||||
for (trip, pt1) in &stats1.canonical_pt_per_trip {
|
||||
if let Some(pt2) = stats2.canonical_pt_per_trip.get(trip) {
|
||||
if pt1 == pt2 {
|
||||
same_trips += 1;
|
||||
} else {
|
||||
lines.push(Line::new(*pt1, *pt2));
|
||||
}
|
||||
{
|
||||
let secondary_sim = ctx.secondary.as_ref().map(|(s, _)| &s.sim).unwrap();
|
||||
new_state = Some(diff_all(primary_sim, secondary_sim));
|
||||
}
|
||||
}
|
||||
DiffAllState::Active { time, .. } => {
|
||||
if ctx.input.key_pressed(Key::Return, "Stop diffing all trips") {
|
||||
new_state = Some(DiffAllState::Inactive);
|
||||
}
|
||||
if *time != ctx.primary.sim.time {
|
||||
let secondary_sim = ctx.secondary.as_ref().map(|(s, _)| &s.sim).unwrap();
|
||||
new_state = Some(diff_all(primary_sim, secondary_sim));
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Some(s) = new_state {
|
||||
*self = s;
|
||||
}
|
||||
|
||||
if let DiffAllState::Active {
|
||||
same_trips,
|
||||
ref lines,
|
||||
..
|
||||
} = self
|
||||
{
|
||||
ctx.osd.add_line(format!(
|
||||
"{} trips same, {} trips different",
|
||||
same_trips,
|
||||
lines.len()
|
||||
));
|
||||
*self = DiffAllState::Active(lines);
|
||||
true
|
||||
} else {
|
||||
*self = DiffAllState::Inactive;
|
||||
false
|
||||
}
|
||||
|
||||
active
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, ctx: Ctx) {
|
||||
if let DiffAllState::Active(ref lines) = self {
|
||||
if let DiffAllState::Active { ref lines, .. } = self {
|
||||
for line in lines {
|
||||
g.draw_line(
|
||||
ctx.cs.get("diff agents line", Color::YELLOW),
|
||||
@ -72,3 +80,24 @@ impl Plugin for DiffAllState {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn diff_all(primary_sim: &Sim, secondary_sim: &Sim) -> DiffAllState {
|
||||
let stats1 = primary_sim.get_stats();
|
||||
let stats2 = secondary_sim.get_stats();
|
||||
let mut same_trips = 0;
|
||||
let mut lines: Vec<Line> = Vec::new();
|
||||
for (trip, pt1) in &stats1.canonical_pt_per_trip {
|
||||
if let Some(pt2) = stats2.canonical_pt_per_trip.get(trip) {
|
||||
if pt1 == pt2 {
|
||||
same_trips += 1;
|
||||
} else {
|
||||
lines.push(Line::new(*pt1, *pt2));
|
||||
}
|
||||
}
|
||||
}
|
||||
DiffAllState::Active {
|
||||
time: primary_sim.time,
|
||||
same_trips,
|
||||
lines,
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,13 @@ use map_model::{Trace, LANE_THICKNESS};
|
||||
use objects::Ctx;
|
||||
use piston::input::Key;
|
||||
use plugins::{Plugin, PluginCtx};
|
||||
use sim::TripID;
|
||||
use sim::{Tick, TripID};
|
||||
use std::f64;
|
||||
|
||||
pub enum DiffWorldsState {
|
||||
Inactive,
|
||||
Active {
|
||||
time: Tick,
|
||||
trip: TripID,
|
||||
// These are all optional because mode-changes might cause temporary interruptions.
|
||||
// Just point from primary world agent to secondary world agent.
|
||||
@ -28,7 +29,7 @@ impl DiffWorldsState {
|
||||
|
||||
impl Plugin for DiffWorldsState {
|
||||
fn event(&mut self, ctx: PluginCtx) -> bool {
|
||||
let mut maybe_trip: Option<TripID> = None;
|
||||
let mut new_state: Option<DiffWorldsState> = None;
|
||||
match self {
|
||||
DiffWorldsState::Inactive => {
|
||||
if ctx.secondary.is_some() {
|
||||
@ -38,58 +39,26 @@ impl Plugin for DiffWorldsState {
|
||||
.input
|
||||
.key_pressed(Key::B, &format!("Show {}'s parallel world", trip))
|
||||
{
|
||||
maybe_trip = Some(trip);
|
||||
new_state = Some(diff_world(trip, ctx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DiffWorldsState::Active { trip, .. } => {
|
||||
DiffWorldsState::Active { time, trip, .. } => {
|
||||
if ctx.input.key_pressed(
|
||||
Key::Return,
|
||||
&format!("Stop showing {}'s parallel world", trip),
|
||||
) {
|
||||
maybe_trip = None;
|
||||
} else {
|
||||
maybe_trip = Some(*trip);
|
||||
new_state = Some(DiffWorldsState::Inactive);
|
||||
} else if *time != ctx.primary.sim.time {
|
||||
new_state = Some(diff_world(*trip, ctx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(trip) = maybe_trip {
|
||||
let primary_sim = &ctx.primary.sim;
|
||||
let primary_map = &ctx.primary.map;
|
||||
let (secondary_sim, secondary_map) = ctx
|
||||
.secondary
|
||||
.as_ref()
|
||||
.map(|(s, _)| (&s.sim, &s.map))
|
||||
.unwrap();
|
||||
|
||||
let pt1 = primary_sim.get_stats().canonical_pt_per_trip.get(&trip);
|
||||
let pt2 = secondary_sim.get_stats().canonical_pt_per_trip.get(&trip);
|
||||
let line = if pt1.is_some() && pt2.is_some() {
|
||||
Some(Line::new(*pt1.unwrap(), *pt2.unwrap()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let primary_route = primary_sim
|
||||
.trip_to_agent(trip)
|
||||
.and_then(|agent| primary_sim.trace_route(agent, primary_map, f64::MAX * si::M));
|
||||
let secondary_route = secondary_sim.trip_to_agent(trip).and_then(|agent| {
|
||||
secondary_sim.trace_route(agent, secondary_map, f64::MAX * si::M)
|
||||
});
|
||||
|
||||
if line.is_none() || primary_route.is_none() || secondary_route.is_none() {
|
||||
warn!("{} isn't present in both sims", trip);
|
||||
}
|
||||
*self = DiffWorldsState::Active {
|
||||
trip,
|
||||
line,
|
||||
primary_route,
|
||||
secondary_route,
|
||||
};
|
||||
} else {
|
||||
*self = DiffWorldsState::Inactive;
|
||||
if let Some(s) = new_state {
|
||||
*self = s;
|
||||
}
|
||||
|
||||
match self {
|
||||
@ -130,3 +99,38 @@ impl Plugin for DiffWorldsState {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn diff_world(trip: TripID, ctx: PluginCtx) -> DiffWorldsState {
|
||||
let primary_sim = &ctx.primary.sim;
|
||||
let primary_map = &ctx.primary.map;
|
||||
let (secondary_sim, secondary_map) = ctx
|
||||
.secondary
|
||||
.as_ref()
|
||||
.map(|(s, _)| (&s.sim, &s.map))
|
||||
.unwrap();
|
||||
|
||||
let pt1 = primary_sim.get_stats().canonical_pt_per_trip.get(&trip);
|
||||
let pt2 = secondary_sim.get_stats().canonical_pt_per_trip.get(&trip);
|
||||
let line = if pt1.is_some() && pt2.is_some() {
|
||||
Some(Line::new(*pt1.unwrap(), *pt2.unwrap()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let primary_route = primary_sim
|
||||
.trip_to_agent(trip)
|
||||
.and_then(|agent| primary_sim.trace_route(agent, primary_map, f64::MAX * si::M));
|
||||
let secondary_route = secondary_sim
|
||||
.trip_to_agent(trip)
|
||||
.and_then(|agent| secondary_sim.trace_route(agent, secondary_map, f64::MAX * si::M));
|
||||
|
||||
if line.is_none() || primary_route.is_none() || secondary_route.is_none() {
|
||||
warn!("{} isn't present in both sims", trip);
|
||||
}
|
||||
DiffWorldsState::Active {
|
||||
time: primary_sim.time,
|
||||
trip,
|
||||
line,
|
||||
primary_route,
|
||||
secondary_route,
|
||||
}
|
||||
}
|
||||
|
@ -4,76 +4,60 @@ use map_model::{Trace, LANE_THICKNESS};
|
||||
use objects::Ctx;
|
||||
use piston::input::Key;
|
||||
use plugins::{Plugin, PluginCtx};
|
||||
use sim::TripID;
|
||||
use sim::{Tick, TripID};
|
||||
use std::f64;
|
||||
|
||||
pub enum ShowRouteState {
|
||||
Empty,
|
||||
Active(TripID, Trace),
|
||||
Inactive,
|
||||
Active(Tick, TripID, Option<Trace>),
|
||||
}
|
||||
|
||||
impl ShowRouteState {
|
||||
pub fn new() -> ShowRouteState {
|
||||
ShowRouteState::Empty
|
||||
ShowRouteState::Inactive
|
||||
}
|
||||
}
|
||||
|
||||
impl Plugin for ShowRouteState {
|
||||
fn event(&mut self, ctx: PluginCtx) -> bool {
|
||||
let maybe_trip = match self {
|
||||
ShowRouteState::Empty => ctx
|
||||
.primary
|
||||
.current_selection
|
||||
.and_then(|id| id.agent_id())
|
||||
.and_then(|agent| ctx.primary.sim.agent_to_trip(agent))
|
||||
.and_then(|trip| {
|
||||
let mut new_state: Option<ShowRouteState> = None;
|
||||
|
||||
match self {
|
||||
ShowRouteState::Inactive => {
|
||||
if let Some(trip) = ctx
|
||||
.primary
|
||||
.current_selection
|
||||
.and_then(|id| id.agent_id())
|
||||
.and_then(|agent| ctx.primary.sim.agent_to_trip(agent))
|
||||
{
|
||||
if ctx
|
||||
.input
|
||||
.key_pressed(Key::R, &format!("show {}'s route", trip))
|
||||
{
|
||||
Some(trip)
|
||||
} else {
|
||||
None
|
||||
new_state = Some(show_route(trip, ctx));
|
||||
}
|
||||
}),
|
||||
ShowRouteState::Active(trip, _) => {
|
||||
};
|
||||
}
|
||||
ShowRouteState::Active(time, trip, _) => {
|
||||
if ctx.input.key_pressed(Key::Return, "stop showing route") {
|
||||
None
|
||||
} else {
|
||||
Some(*trip)
|
||||
new_state = Some(ShowRouteState::Inactive);
|
||||
} else if *time != ctx.primary.sim.time {
|
||||
new_state = Some(show_route(*trip, ctx));
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Some(trip) = maybe_trip {
|
||||
if let Some(agent) = ctx.primary.sim.trip_to_agent(trip) {
|
||||
// Trace along the entire route by passing in max distance
|
||||
if let Some(trace) =
|
||||
ctx.primary
|
||||
.sim
|
||||
.trace_route(agent, &ctx.primary.map, f64::MAX * si::M)
|
||||
{
|
||||
*self = ShowRouteState::Active(trip, trace);
|
||||
} else {
|
||||
warn!("{} has no trace right now", agent);
|
||||
}
|
||||
} else {
|
||||
warn!(
|
||||
"{} has no agent associated right now; is the trip done?",
|
||||
trip
|
||||
);
|
||||
}
|
||||
} else {
|
||||
*self = ShowRouteState::Empty;
|
||||
if let Some(s) = new_state {
|
||||
*self = s;
|
||||
}
|
||||
|
||||
match self {
|
||||
ShowRouteState::Empty => false,
|
||||
ShowRouteState::Inactive => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, ctx: Ctx) {
|
||||
if let ShowRouteState::Active(_, trace) = self {
|
||||
if let ShowRouteState::Active(_, _, Some(trace)) = self {
|
||||
g.draw_polygon(
|
||||
ctx.cs.get("route", Color::rgba(255, 0, 0, 0.8)),
|
||||
&trace.get_polyline().make_polygons_blindly(LANE_THICKNESS),
|
||||
@ -81,3 +65,26 @@ impl Plugin for ShowRouteState {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn show_route(trip: TripID, ctx: PluginCtx) -> ShowRouteState {
|
||||
let time = ctx.primary.sim.time;
|
||||
if let Some(agent) = ctx.primary.sim.trip_to_agent(trip) {
|
||||
// Trace along the entire route by passing in max distance
|
||||
if let Some(trace) = ctx
|
||||
.primary
|
||||
.sim
|
||||
.trace_route(agent, &ctx.primary.map, f64::MAX * si::M)
|
||||
{
|
||||
ShowRouteState::Active(time, trip, Some(trace))
|
||||
} else {
|
||||
warn!("{} has no trace right now", agent);
|
||||
ShowRouteState::Active(time, trip, None)
|
||||
}
|
||||
} else {
|
||||
warn!(
|
||||
"{} has no agent associated right now; is the trip done?",
|
||||
trip
|
||||
);
|
||||
ShowRouteState::Active(time, trip, None)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user