mirror of
https://github.com/a-b-street/abstreet.git
synced 2025-01-07 06:57:25 +03:00
reverse earlier decision and put prebaked analytics back in UI, so existing plumbing works. but it's optional and carefully set/reset
This commit is contained in:
parent
7c37c786fd
commit
c130e49cb4
@ -10,7 +10,7 @@ use ezgui::{
|
|||||||
hotkey, Choice, Color, EventCtx, Key, Line, ManagedWidget, Plot, Series, Text, Wizard,
|
hotkey, Choice, Color, EventCtx, Key, Line, ManagedWidget, Plot, Series, Text, Wizard,
|
||||||
};
|
};
|
||||||
use geom::{Duration, Statistic, Time};
|
use geom::{Duration, Statistic, Time};
|
||||||
use sim::{Analytics, TripID, TripMode};
|
use sim::{TripID, TripMode};
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Copy)]
|
#[derive(PartialEq, Clone, Copy)]
|
||||||
@ -22,7 +22,7 @@ pub enum Tab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Oh the dashboards melted, but we still had the radio
|
// Oh the dashboards melted, but we still had the radio
|
||||||
pub fn make(ctx: &EventCtx, ui: &UI, prebaked: &Analytics, tab: Tab) -> Box<dyn State> {
|
pub fn make(ctx: &EventCtx, ui: &UI, tab: Tab) -> Box<dyn State> {
|
||||||
let tab_data = vec![
|
let tab_data = vec![
|
||||||
(Tab::FinishedTripsSummary, "Finished trips summary"),
|
(Tab::FinishedTripsSummary, "Finished trips summary"),
|
||||||
(
|
(
|
||||||
@ -46,7 +46,7 @@ pub fn make(ctx: &EventCtx, ui: &UI, prebaked: &Analytics, tab: Tab) -> Box<dyn
|
|||||||
tabs.push(Composite::text_button(ctx, "BACK", hotkey(Key::Escape)));
|
tabs.push(Composite::text_button(ctx, "BACK", hotkey(Key::Escape)));
|
||||||
|
|
||||||
let content = match tab {
|
let content = match tab {
|
||||||
Tab::FinishedTripsSummary => finished_trips_summary(ctx, ui, prebaked),
|
Tab::FinishedTripsSummary => finished_trips_summary(ctx, ui),
|
||||||
Tab::IndividualFinishedTrips => {
|
Tab::IndividualFinishedTrips => {
|
||||||
return WizardState::new(Box::new(browse_trips));
|
return WizardState::new(Box::new(browse_trips));
|
||||||
}
|
}
|
||||||
@ -65,15 +65,7 @@ pub fn make(ctx: &EventCtx, ui: &UI, prebaked: &Analytics, tab: Tab) -> Box<dyn
|
|||||||
if t != tab {
|
if t != tab {
|
||||||
c = c.cb(
|
c = c.cb(
|
||||||
label,
|
label,
|
||||||
Box::new(move |ctx, ui| {
|
Box::new(move |ctx, ui| Some(Transition::Replace(make(ctx, ui, t)))),
|
||||||
Some(Transition::Replace(make(
|
|
||||||
ctx,
|
|
||||||
ui,
|
|
||||||
// TODO prebaked?
|
|
||||||
&Analytics::new(),
|
|
||||||
t,
|
|
||||||
)))
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,14 +73,14 @@ pub fn make(ctx: &EventCtx, ui: &UI, prebaked: &Analytics, tab: Tab) -> Box<dyn
|
|||||||
ManagedGUIState::new(c)
|
ManagedGUIState::new(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finished_trips_summary(ctx: &EventCtx, ui: &UI, prebaked: &Analytics) -> ManagedWidget {
|
fn finished_trips_summary(ctx: &EventCtx, ui: &UI) -> ManagedWidget {
|
||||||
let (now_all, now_aborted, now_per_mode) = ui
|
let (now_all, now_aborted, now_per_mode) = ui
|
||||||
.primary
|
.primary
|
||||||
.sim
|
.sim
|
||||||
.get_analytics()
|
.get_analytics()
|
||||||
.all_finished_trips(ui.primary.sim.time());
|
.all_finished_trips(ui.primary.sim.time());
|
||||||
let (baseline_all, baseline_aborted, baseline_per_mode) =
|
let (baseline_all, baseline_aborted, baseline_per_mode) =
|
||||||
prebaked.all_finished_trips(ui.primary.sim.time());
|
ui.prebaked().all_finished_trips(ui.primary.sim.time());
|
||||||
|
|
||||||
// TODO Include unfinished count
|
// TODO Include unfinished count
|
||||||
let mut txt = Text::new();
|
let mut txt = Text::new();
|
||||||
|
@ -8,7 +8,7 @@ use crate::ui::UI;
|
|||||||
use abstutil::prettyprint_usize;
|
use abstutil::prettyprint_usize;
|
||||||
use ezgui::{hotkey, EventCtx, Key, Line, ModalMenu, Text};
|
use ezgui::{hotkey, EventCtx, Key, Line, ModalMenu, Text};
|
||||||
use geom::Time;
|
use geom::Time;
|
||||||
use sim::{Analytics, TripMode};
|
use sim::TripMode;
|
||||||
|
|
||||||
pub struct CreateGridlock {
|
pub struct CreateGridlock {
|
||||||
time: Time,
|
time: Time,
|
||||||
@ -39,7 +39,6 @@ impl GameplayState for CreateGridlock {
|
|||||||
ctx: &mut EventCtx,
|
ctx: &mut EventCtx,
|
||||||
ui: &mut UI,
|
ui: &mut UI,
|
||||||
_: &mut Overlays,
|
_: &mut Overlays,
|
||||||
prebaked: &Analytics,
|
|
||||||
menu: &mut ModalMenu,
|
menu: &mut ModalMenu,
|
||||||
) -> Option<Transition> {
|
) -> Option<Transition> {
|
||||||
menu.event(ctx);
|
menu.event(ctx);
|
||||||
@ -54,7 +53,7 @@ impl GameplayState for CreateGridlock {
|
|||||||
|
|
||||||
if self.time != ui.primary.sim.time() {
|
if self.time != ui.primary.sim.time() {
|
||||||
self.time = ui.primary.sim.time();
|
self.time = ui.primary.sim.time();
|
||||||
menu.set_info(ctx, gridlock_panel(ui, prebaked));
|
menu.set_info(ctx, gridlock_panel(ui));
|
||||||
}
|
}
|
||||||
|
|
||||||
if menu.action("help") {
|
if menu.action("help") {
|
||||||
@ -68,13 +67,14 @@ impl GameplayState for CreateGridlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gridlock_panel(ui: &UI, prebaked: &Analytics) -> Text {
|
fn gridlock_panel(ui: &UI) -> Text {
|
||||||
let (now_all, _, now_per_mode) = ui
|
let (now_all, _, now_per_mode) = ui
|
||||||
.primary
|
.primary
|
||||||
.sim
|
.sim
|
||||||
.get_analytics()
|
.get_analytics()
|
||||||
.all_finished_trips(ui.primary.sim.time());
|
.all_finished_trips(ui.primary.sim.time());
|
||||||
let (baseline_all, _, baseline_per_mode) = prebaked.all_finished_trips(ui.primary.sim.time());
|
let (baseline_all, _, baseline_per_mode) =
|
||||||
|
ui.prebaked().all_finished_trips(ui.primary.sim.time());
|
||||||
|
|
||||||
let mut txt = Text::new();
|
let mut txt = Text::new();
|
||||||
txt.add_appended(vec![
|
txt.add_appended(vec![
|
||||||
|
@ -7,7 +7,7 @@ use crate::ui::UI;
|
|||||||
use abstutil::prettyprint_usize;
|
use abstutil::prettyprint_usize;
|
||||||
use ezgui::{hotkey, EventCtx, Key, Line, ModalMenu, Text};
|
use ezgui::{hotkey, EventCtx, Key, Line, ModalMenu, Text};
|
||||||
use geom::{Statistic, Time};
|
use geom::{Statistic, Time};
|
||||||
use sim::{Analytics, TripMode};
|
use sim::TripMode;
|
||||||
|
|
||||||
pub struct FasterTrips {
|
pub struct FasterTrips {
|
||||||
mode: TripMode,
|
mode: TripMode,
|
||||||
@ -41,14 +41,13 @@ impl GameplayState for FasterTrips {
|
|||||||
ctx: &mut EventCtx,
|
ctx: &mut EventCtx,
|
||||||
ui: &mut UI,
|
ui: &mut UI,
|
||||||
_: &mut Overlays,
|
_: &mut Overlays,
|
||||||
prebaked: &Analytics,
|
|
||||||
menu: &mut ModalMenu,
|
menu: &mut ModalMenu,
|
||||||
) -> Option<Transition> {
|
) -> Option<Transition> {
|
||||||
menu.event(ctx);
|
menu.event(ctx);
|
||||||
|
|
||||||
if self.time != ui.primary.sim.time() {
|
if self.time != ui.primary.sim.time() {
|
||||||
self.time = ui.primary.sim.time();
|
self.time = ui.primary.sim.time();
|
||||||
menu.set_info(ctx, faster_trips_panel(self.mode, ui, prebaked));
|
menu.set_info(ctx, faster_trips_panel(self.mode, ui));
|
||||||
}
|
}
|
||||||
|
|
||||||
if menu.action("help") {
|
if menu.action("help") {
|
||||||
@ -61,10 +60,10 @@ impl GameplayState for FasterTrips {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn faster_trips_panel(mode: TripMode, ui: &UI, prebaked: &Analytics) -> Text {
|
pub fn faster_trips_panel(mode: TripMode, ui: &UI) -> Text {
|
||||||
let time = ui.primary.sim.time();
|
let time = ui.primary.sim.time();
|
||||||
let now = ui.primary.sim.get_analytics().finished_trips(time, mode);
|
let now = ui.primary.sim.get_analytics().finished_trips(time, mode);
|
||||||
let baseline = prebaked.finished_trips(time, mode);
|
let baseline = ui.prebaked().finished_trips(time, mode);
|
||||||
|
|
||||||
// Enable to debug why sim results don't match prebaked.
|
// Enable to debug why sim results don't match prebaked.
|
||||||
if false && !now.seems_eq(&baseline) {
|
if false && !now.seems_eq(&baseline) {
|
||||||
@ -72,7 +71,8 @@ pub fn faster_trips_panel(mode: TripMode, ui: &UI, prebaked: &Analytics) -> Text
|
|||||||
"../current_sim.json".to_string(),
|
"../current_sim.json".to_string(),
|
||||||
&ui.primary.sim.get_analytics().finished_trips,
|
&ui.primary.sim.get_analytics().finished_trips,
|
||||||
);
|
);
|
||||||
let filtered = prebaked
|
let filtered = ui
|
||||||
|
.prebaked()
|
||||||
.finished_trips
|
.finished_trips
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(t, _, _, _)| *t <= time)
|
.filter(|(t, _, _, _)| *t <= time)
|
||||||
@ -106,10 +106,10 @@ pub fn faster_trips_panel(mode: TripMode, ui: &UI, prebaked: &Analytics) -> Text
|
|||||||
txt
|
txt
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn small_faster_trips_panel(mode: TripMode, ui: &UI, prebaked: &Analytics) -> Text {
|
pub fn small_faster_trips_panel(mode: TripMode, ui: &UI) -> Text {
|
||||||
let time = ui.primary.sim.time();
|
let time = ui.primary.sim.time();
|
||||||
let now = ui.primary.sim.get_analytics().finished_trips(time, mode);
|
let now = ui.primary.sim.get_analytics().finished_trips(time, mode);
|
||||||
let baseline = prebaked.finished_trips(time, mode);
|
let baseline = ui.prebaked().finished_trips(time, mode);
|
||||||
|
|
||||||
let mut txt = Text::new();
|
let mut txt = Text::new();
|
||||||
txt.add_appended(vec![
|
txt.add_appended(vec![
|
||||||
|
@ -8,7 +8,7 @@ use crate::ui::UI;
|
|||||||
use ezgui::{hotkey, EventCtx, Key, ModalMenu};
|
use ezgui::{hotkey, EventCtx, Key, ModalMenu};
|
||||||
use geom::{Duration, Statistic, Time};
|
use geom::{Duration, Statistic, Time};
|
||||||
use map_model::{IntersectionID, Map};
|
use map_model::{IntersectionID, Map};
|
||||||
use sim::{Analytics, BorderSpawnOverTime, OriginDestination, Scenario, TripMode};
|
use sim::{BorderSpawnOverTime, OriginDestination, Scenario, TripMode};
|
||||||
|
|
||||||
pub struct FixTrafficSignals {
|
pub struct FixTrafficSignals {
|
||||||
time: Time,
|
time: Time,
|
||||||
@ -47,12 +47,11 @@ impl GameplayState for FixTrafficSignals {
|
|||||||
ctx: &mut EventCtx,
|
ctx: &mut EventCtx,
|
||||||
ui: &mut UI,
|
ui: &mut UI,
|
||||||
overlays: &mut Overlays,
|
overlays: &mut Overlays,
|
||||||
prebaked: &Analytics,
|
|
||||||
menu: &mut ModalMenu,
|
menu: &mut ModalMenu,
|
||||||
) -> Option<Transition> {
|
) -> Option<Transition> {
|
||||||
// Once is never...
|
// Once is never...
|
||||||
if self.once {
|
if self.once {
|
||||||
*overlays = Overlays::finished_trips_histogram(ctx, ui, prebaked);
|
*overlays = Overlays::finished_trips_histogram(ctx, ui);
|
||||||
self.once = false;
|
self.once = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,12 +84,12 @@ impl GameplayState for FixTrafficSignals {
|
|||||||
},
|
},
|
||||||
self.time != ui.primary.sim.time(),
|
self.time != ui.primary.sim.time(),
|
||||||
) {
|
) {
|
||||||
*overlays = Overlays::finished_trips_histogram(ctx, ui, prebaked);
|
*overlays = Overlays::finished_trips_histogram(ctx, ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.time != ui.primary.sim.time() {
|
if self.time != ui.primary.sim.time() {
|
||||||
self.time = ui.primary.sim.time();
|
self.time = ui.primary.sim.time();
|
||||||
menu.set_info(ctx, small_faster_trips_panel(TripMode::Drive, ui, prebaked));
|
menu.set_info(ctx, small_faster_trips_panel(TripMode::Drive, ui));
|
||||||
}
|
}
|
||||||
|
|
||||||
if menu.action("help") {
|
if menu.action("help") {
|
||||||
@ -103,32 +102,26 @@ impl GameplayState for FixTrafficSignals {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if menu.action("final score") {
|
if menu.action("final score") {
|
||||||
return Some(Transition::Push(msg(
|
return Some(Transition::Push(msg("Final score", final_score(ui))));
|
||||||
"Final score",
|
|
||||||
final_score(ui, prebaked),
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ui.primary.sim.time() >= Time::END_OF_DAY {
|
if ui.primary.sim.time() >= Time::END_OF_DAY {
|
||||||
// TODO Stop the challenge somehow
|
// TODO Stop the challenge somehow
|
||||||
return Some(Transition::Push(msg(
|
return Some(Transition::Push(msg("Final score", final_score(ui))));
|
||||||
"Final score",
|
|
||||||
final_score(ui, prebaked),
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn final_score(ui: &UI, prebaked: &Analytics) -> Vec<String> {
|
fn final_score(ui: &UI) -> Vec<String> {
|
||||||
let time = ui.primary.sim.time();
|
let time = ui.primary.sim.time();
|
||||||
let now = ui
|
let now = ui
|
||||||
.primary
|
.primary
|
||||||
.sim
|
.sim
|
||||||
.get_analytics()
|
.get_analytics()
|
||||||
.finished_trips(time, TripMode::Drive);
|
.finished_trips(time, TripMode::Drive);
|
||||||
let baseline = prebaked.finished_trips(time, TripMode::Drive);
|
let baseline = ui.prebaked().finished_trips(time, TripMode::Drive);
|
||||||
// TODO Annoying to repeat this everywhere; any refactor possible?
|
// TODO Annoying to repeat this everywhere; any refactor possible?
|
||||||
if now.count() == 0 || baseline.count() == 0 {
|
if now.count() == 0 || baseline.count() == 0 {
|
||||||
return vec!["No data yet, run the simulation for longer".to_string()];
|
return vec!["No data yet, run the simulation for longer".to_string()];
|
||||||
|
@ -10,7 +10,6 @@ use ezgui::{
|
|||||||
ModalMenu, Text, VerticalAlignment,
|
ModalMenu, Text, VerticalAlignment,
|
||||||
};
|
};
|
||||||
use map_model::IntersectionID;
|
use map_model::IntersectionID;
|
||||||
use sim::Analytics;
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
// TODO Maybe remember what things were spawned, offer to replay this later
|
// TODO Maybe remember what things were spawned, offer to replay this later
|
||||||
@ -37,7 +36,6 @@ impl GameplayState for Freeform {
|
|||||||
ctx: &mut EventCtx,
|
ctx: &mut EventCtx,
|
||||||
ui: &mut UI,
|
ui: &mut UI,
|
||||||
_: &mut Overlays,
|
_: &mut Overlays,
|
||||||
_: &Analytics,
|
|
||||||
menu: &mut ModalMenu,
|
menu: &mut ModalMenu,
|
||||||
) -> Option<Transition> {
|
) -> Option<Transition> {
|
||||||
menu.event(ctx);
|
menu.event(ctx);
|
||||||
|
@ -23,7 +23,6 @@ pub struct GameplayRunner {
|
|||||||
pub menu: ModalMenu,
|
pub menu: ModalMenu,
|
||||||
controller: Composite,
|
controller: Composite,
|
||||||
state: Box<dyn GameplayState>,
|
state: Box<dyn GameplayState>,
|
||||||
pub prebaked: Analytics,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -47,7 +46,6 @@ pub trait GameplayState: downcast_rs::Downcast {
|
|||||||
ctx: &mut EventCtx,
|
ctx: &mut EventCtx,
|
||||||
ui: &mut UI,
|
ui: &mut UI,
|
||||||
overlays: &mut Overlays,
|
overlays: &mut Overlays,
|
||||||
prebaked: &Analytics,
|
|
||||||
menu: &mut ModalMenu,
|
menu: &mut ModalMenu,
|
||||||
) -> Option<Transition>;
|
) -> Option<Transition>;
|
||||||
fn draw(&self, _: &mut GfxCtx, _: &UI) {}
|
fn draw(&self, _: &mut GfxCtx, _: &UI) {}
|
||||||
@ -158,6 +156,7 @@ impl GameplayRunner {
|
|||||||
fix_traffic_signals::FixTrafficSignals::new(ctx, ui, mode.clone())
|
fix_traffic_signals::FixTrafficSignals::new(ctx, ui, mode.clone())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// TODO Maybe don't load this for Freeform mode
|
||||||
let prebaked = ctx.loading_screen("instantiate scenario", |_, timer| {
|
let prebaked = ctx.loading_screen("instantiate scenario", |_, timer| {
|
||||||
if let Some(scenario) =
|
if let Some(scenario) =
|
||||||
mode.scenario(&ui.primary.map, ui.primary.current_flags.num_agents, timer)
|
mode.scenario(&ui.primary.map, ui.primary.current_flags.num_agents, timer)
|
||||||
@ -184,9 +183,9 @@ impl GameplayRunner {
|
|||||||
Analytics::new()
|
Analytics::new()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
ui.set_prebaked(Some(prebaked));
|
||||||
GameplayRunner {
|
GameplayRunner {
|
||||||
mode,
|
mode,
|
||||||
prebaked,
|
|
||||||
menu: menu
|
menu: menu
|
||||||
.set_standalone_layout(layout::ContainerOrientation::TopRightButDownABit(150.0)),
|
.set_standalone_layout(layout::ContainerOrientation::TopRightButDownABit(150.0)),
|
||||||
controller,
|
controller,
|
||||||
@ -207,8 +206,7 @@ impl GameplayRunner {
|
|||||||
Some(Outcome::Clicked(_)) => unreachable!(),
|
Some(Outcome::Clicked(_)) => unreachable!(),
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
self.state
|
self.state.event(ctx, ui, overlays, &mut self.menu)
|
||||||
.event(ctx, ui, overlays, &self.prebaked, &mut self.menu)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&self, g: &mut GfxCtx, ui: &UI) {
|
pub fn draw(&self, g: &mut GfxCtx, ui: &UI) {
|
||||||
|
@ -13,7 +13,6 @@ use ezgui::{
|
|||||||
};
|
};
|
||||||
use geom::{Statistic, Time};
|
use geom::{Statistic, Time};
|
||||||
use map_model::BusRouteID;
|
use map_model::BusRouteID;
|
||||||
use sim::Analytics;
|
|
||||||
|
|
||||||
pub struct OptimizeBus {
|
pub struct OptimizeBus {
|
||||||
route: BusRouteID,
|
route: BusRouteID,
|
||||||
@ -55,7 +54,6 @@ impl GameplayState for OptimizeBus {
|
|||||||
ctx: &mut EventCtx,
|
ctx: &mut EventCtx,
|
||||||
ui: &mut UI,
|
ui: &mut UI,
|
||||||
overlays: &mut Overlays,
|
overlays: &mut Overlays,
|
||||||
prebaked: &Analytics,
|
|
||||||
menu: &mut ModalMenu,
|
menu: &mut ModalMenu,
|
||||||
) -> Option<Transition> {
|
) -> Option<Transition> {
|
||||||
menu.event(ctx);
|
menu.event(ctx);
|
||||||
@ -95,7 +93,7 @@ impl GameplayState for OptimizeBus {
|
|||||||
// TODO Expensive
|
// TODO Expensive
|
||||||
if self.time != ui.primary.sim.time() {
|
if self.time != ui.primary.sim.time() {
|
||||||
self.time = ui.primary.sim.time();
|
self.time = ui.primary.sim.time();
|
||||||
menu.set_info(ctx, bus_route_panel(self.route, self.stat, ui, prebaked));
|
menu.set_info(ctx, bus_route_panel(self.route, self.stat, ui));
|
||||||
}
|
}
|
||||||
|
|
||||||
if menu.action("change statistic") {
|
if menu.action("change statistic") {
|
||||||
@ -140,13 +138,13 @@ impl GameplayState for OptimizeBus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bus_route_panel(id: BusRouteID, stat: Statistic, ui: &UI, prebaked: &Analytics) -> Text {
|
fn bus_route_panel(id: BusRouteID, stat: Statistic, ui: &UI) -> Text {
|
||||||
let now = ui
|
let now = ui
|
||||||
.primary
|
.primary
|
||||||
.sim
|
.sim
|
||||||
.get_analytics()
|
.get_analytics()
|
||||||
.bus_arrivals(ui.primary.sim.time(), id);
|
.bus_arrivals(ui.primary.sim.time(), id);
|
||||||
let baseline = prebaked.bus_arrivals(ui.primary.sim.time(), id);
|
let baseline = ui.prebaked().bus_arrivals(ui.primary.sim.time(), id);
|
||||||
|
|
||||||
let route = ui.primary.map.get_br(id);
|
let route = ui.primary.map.get_br(id);
|
||||||
let mut txt = Text::new();
|
let mut txt = Text::new();
|
||||||
|
@ -5,7 +5,6 @@ use crate::sandbox::gameplay::{GameplayMode, GameplayState};
|
|||||||
use crate::sandbox::overlays::Overlays;
|
use crate::sandbox::overlays::Overlays;
|
||||||
use crate::ui::UI;
|
use crate::ui::UI;
|
||||||
use ezgui::{hotkey, EventCtx, Key, ModalMenu};
|
use ezgui::{hotkey, EventCtx, Key, ModalMenu};
|
||||||
use sim::Analytics;
|
|
||||||
|
|
||||||
pub struct PlayScenario;
|
pub struct PlayScenario;
|
||||||
|
|
||||||
@ -33,7 +32,6 @@ impl GameplayState for PlayScenario {
|
|||||||
ctx: &mut EventCtx,
|
ctx: &mut EventCtx,
|
||||||
_: &mut UI,
|
_: &mut UI,
|
||||||
_: &mut Overlays,
|
_: &mut Overlays,
|
||||||
_: &Analytics,
|
|
||||||
menu: &mut ModalMenu,
|
menu: &mut ModalMenu,
|
||||||
) -> Option<Transition> {
|
) -> Option<Transition> {
|
||||||
menu.event(ctx);
|
menu.event(ctx);
|
||||||
|
@ -141,7 +141,7 @@ impl State for SandboxMode {
|
|||||||
if let Some(t) = self.common.event(ctx, ui) {
|
if let Some(t) = self.common.event(ctx, ui) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
if let Some(t) = self.overlay.event(ctx, ui, &self.gameplay.prebaked) {
|
if let Some(t) = self.overlay.event(ctx, ui) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
match self.tool_panel.event(ctx, ui) {
|
match self.tool_panel.event(ctx, ui) {
|
||||||
@ -150,7 +150,6 @@ impl State for SandboxMode {
|
|||||||
}
|
}
|
||||||
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
Some(Outcome::Clicked(x)) => match x.as_ref() {
|
||||||
"back" => {
|
"back" => {
|
||||||
// TODO Clear edits?
|
|
||||||
return Transition::Push(WizardState::new(Box::new(move |wiz, ctx, ui| {
|
return Transition::Push(WizardState::new(Box::new(move |wiz, ctx, ui| {
|
||||||
let mut wizard = wiz.wrap(ctx);
|
let mut wizard = wiz.wrap(ctx);
|
||||||
let dirty = ui.primary.map.get_edits().dirty;
|
let dirty = ui.primary.map.get_edits().dirty;
|
||||||
@ -183,6 +182,7 @@ impl State for SandboxMode {
|
|||||||
&mut Timer::new("reset edits"),
|
&mut Timer::new("reset edits"),
|
||||||
);
|
);
|
||||||
ui.primary.clear_sim();
|
ui.primary.clear_sim();
|
||||||
|
ui.set_prebaked(None);
|
||||||
ctx.canvas.save_camera_state(ui.primary.map.get_name());
|
ctx.canvas.save_camera_state(ui.primary.map.get_name());
|
||||||
Some(Transition::Clear(main_menu(ctx, ui)))
|
Some(Transition::Clear(main_menu(ctx, ui)))
|
||||||
}
|
}
|
||||||
@ -200,6 +200,7 @@ impl State for SandboxMode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
ui.primary.clear_sim();
|
ui.primary.clear_sim();
|
||||||
|
ui.set_prebaked(None);
|
||||||
ctx.canvas.save_camera_state(ui.primary.map.get_name());
|
ctx.canvas.save_camera_state(ui.primary.map.get_name());
|
||||||
Some(Transition::Clear(main_menu(ctx, ui)))
|
Some(Transition::Clear(main_menu(ctx, ui)))
|
||||||
}
|
}
|
||||||
@ -212,7 +213,6 @@ impl State for SandboxMode {
|
|||||||
return Transition::Push(dashboards::make(
|
return Transition::Push(dashboards::make(
|
||||||
ctx,
|
ctx,
|
||||||
ui,
|
ui,
|
||||||
&self.gameplay.prebaked,
|
|
||||||
dashboards::Tab::FinishedTripsSummary,
|
dashboards::Tab::FinishedTripsSummary,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ use abstutil::{prettyprint_usize, Counter};
|
|||||||
use ezgui::{Choice, Color, Composite, Drawable, EventCtx, GeomBatch, GfxCtx, Key, Line, Text};
|
use ezgui::{Choice, Color, Composite, Drawable, EventCtx, GeomBatch, GfxCtx, Key, Line, Text};
|
||||||
use geom::{Distance, Duration, PolyLine, Time};
|
use geom::{Distance, Duration, PolyLine, Time};
|
||||||
use map_model::IntersectionID;
|
use map_model::IntersectionID;
|
||||||
use sim::{Analytics, ParkingSpot};
|
use sim::ParkingSpot;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
pub enum Overlays {
|
pub enum Overlays {
|
||||||
@ -29,12 +29,7 @@ pub enum Overlays {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Overlays {
|
impl Overlays {
|
||||||
pub fn event(
|
pub fn event(&mut self, ctx: &mut EventCtx, ui: &UI) -> Option<Transition> {
|
||||||
&mut self,
|
|
||||||
ctx: &mut EventCtx,
|
|
||||||
ui: &UI,
|
|
||||||
baseline: &Analytics,
|
|
||||||
) -> Option<Transition> {
|
|
||||||
let now = ui.primary.sim.time();
|
let now = ui.primary.sim.time();
|
||||||
match self {
|
match self {
|
||||||
// Don't bother with Inactive, BusRoute, BusDelaysOverTime, BikeNetwork, BusNetwork --
|
// Don't bother with Inactive, BusRoute, BusDelaysOverTime, BikeNetwork, BusNetwork --
|
||||||
@ -52,7 +47,7 @@ impl Overlays {
|
|||||||
*self = Overlays::intersection_demand(*i, ctx, ui);
|
*self = Overlays::intersection_demand(*i, ctx, ui);
|
||||||
}
|
}
|
||||||
Overlays::FinishedTripsHistogram(t, _) if now != *t => {
|
Overlays::FinishedTripsHistogram(t, _) if now != *t => {
|
||||||
*self = Overlays::finished_trips_histogram(ctx, ui, baseline);
|
*self = Overlays::finished_trips_histogram(ctx, ui);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
@ -121,8 +116,7 @@ impl Overlays {
|
|||||||
Choice::new("parking availability", ()).key(Key::P),
|
Choice::new("parking availability", ()).key(Key::P),
|
||||||
Choice::new("intersection delay", ()).key(Key::I),
|
Choice::new("intersection delay", ()).key(Key::I),
|
||||||
Choice::new("cumulative throughput", ()).key(Key::T),
|
Choice::new("cumulative throughput", ()).key(Key::T),
|
||||||
// TODO baseline borrow doesn't live long enough
|
Choice::new("finished trips histogram", ()).key(Key::H),
|
||||||
//Choice::new("finished trips histogram", ()).key(Key::H),
|
|
||||||
Choice::new("bike network", ()).key(Key::B),
|
Choice::new("bike network", ()).key(Key::B),
|
||||||
Choice::new("bus network", ()).key(Key::U),
|
Choice::new("bus network", ()).key(Key::U),
|
||||||
]
|
]
|
||||||
@ -134,6 +128,7 @@ impl Overlays {
|
|||||||
"parking availability" => Overlays::parking_availability(ctx, ui),
|
"parking availability" => Overlays::parking_availability(ctx, ui),
|
||||||
"intersection delay" => Overlays::intersection_delay(ctx, ui),
|
"intersection delay" => Overlays::intersection_delay(ctx, ui),
|
||||||
"cumulative throughput" => Overlays::cumulative_throughput(ctx, ui),
|
"cumulative throughput" => Overlays::cumulative_throughput(ctx, ui),
|
||||||
|
"finished trips histogram" => Overlays::finished_trips_histogram(ctx, ui),
|
||||||
"bike network" => Overlays::bike_network(ctx, ui),
|
"bike network" => Overlays::bike_network(ctx, ui),
|
||||||
"bus network" => Overlays::bus_network(ctx, ui),
|
"bus network" => Overlays::bus_network(ctx, ui),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@ -329,7 +324,7 @@ impl Overlays {
|
|||||||
Overlays::BusNetwork(colorer.build(ctx, &ui.primary.map))
|
Overlays::BusNetwork(colorer.build(ctx, &ui.primary.map))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finished_trips_histogram(ctx: &EventCtx, ui: &UI, baseline: &Analytics) -> Overlays {
|
pub fn finished_trips_histogram(ctx: &EventCtx, ui: &UI) -> Overlays {
|
||||||
let now = ui.primary.sim.time();
|
let now = ui.primary.sim.time();
|
||||||
Overlays::FinishedTripsHistogram(
|
Overlays::FinishedTripsHistogram(
|
||||||
now,
|
now,
|
||||||
@ -337,7 +332,7 @@ impl Overlays {
|
|||||||
ui.primary
|
ui.primary
|
||||||
.sim
|
.sim
|
||||||
.get_analytics()
|
.get_analytics()
|
||||||
.finished_trip_deltas(now, baseline),
|
.finished_trip_deltas(now, ui.prebaked()),
|
||||||
ctx,
|
ctx,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -10,12 +10,14 @@ use ezgui::{Color, EventCtx, GfxCtx, Prerender, TextureType};
|
|||||||
use geom::{Bounds, Circle, Distance, Pt2D};
|
use geom::{Bounds, Circle, Distance, Pt2D};
|
||||||
use map_model::{Map, Traversable};
|
use map_model::{Map, Traversable};
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use sim::{GetDrawAgents, Sim, SimFlags};
|
use sim::{Analytics, GetDrawAgents, Sim, SimFlags};
|
||||||
|
|
||||||
pub struct UI {
|
pub struct UI {
|
||||||
pub primary: PerMapUI,
|
pub primary: PerMapUI,
|
||||||
// Invariant: This is Some(...) iff we're in A/B test mode or a sub-state.
|
// Invariant: This is Some(...) iff we're in A/B test mode or a sub-state.
|
||||||
pub secondary: Option<PerMapUI>,
|
pub secondary: Option<PerMapUI>,
|
||||||
|
// Only exists in some gameplay modes. Must be carefully reset otherwise.
|
||||||
|
prebaked: Option<Analytics>,
|
||||||
pub cs: ColorScheme,
|
pub cs: ColorScheme,
|
||||||
// TODO This is a bit weird to keep here; it's controlled almost entirely by the minimap panel.
|
// TODO This is a bit weird to keep here; it's controlled almost entirely by the minimap panel.
|
||||||
// It has no meaning in edit mode.
|
// It has no meaning in edit mode.
|
||||||
@ -67,6 +69,7 @@ impl UI {
|
|||||||
UI {
|
UI {
|
||||||
primary,
|
primary,
|
||||||
secondary: None,
|
secondary: None,
|
||||||
|
prebaked: None,
|
||||||
agent_cs: AgentColorScheme::default(&cs),
|
agent_cs: AgentColorScheme::default(&cs),
|
||||||
cs,
|
cs,
|
||||||
opts,
|
opts,
|
||||||
@ -74,6 +77,14 @@ impl UI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn prebaked(&self) -> &Analytics {
|
||||||
|
self.prebaked.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_prebaked(&mut self, prebaked: Option<Analytics>) {
|
||||||
|
self.prebaked = prebaked;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn switch_map(&mut self, ctx: &mut EventCtx, load: String) {
|
pub fn switch_map(&mut self, ctx: &mut EventCtx, load: String) {
|
||||||
ctx.canvas.save_camera_state(self.primary.map.get_name());
|
ctx.canvas.save_camera_state(self.primary.map.get_name());
|
||||||
let mut flags = self.primary.current_flags.clone();
|
let mut flags = self.primary.current_flags.clone();
|
||||||
|
Loading…
Reference in New Issue
Block a user