mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-27 08:24:15 +03:00
be able to trigger a loading screen anywhere
This commit is contained in:
parent
eed33931de
commit
798a7b5354
@ -1,7 +1,6 @@
|
||||
use crate::abtest::{ABTestMode, State};
|
||||
use crate::game::{GameState, Mode};
|
||||
use crate::ui::{Flags, PerMapUI, UI};
|
||||
use abstutil::Timer;
|
||||
use ezgui::{EventCtx, GfxCtx, Key, LogScroller, ModalMenu, Wizard, WrappedWizard};
|
||||
use map_model::Map;
|
||||
use sim::{ABTest, SimFlags};
|
||||
@ -103,7 +102,7 @@ fn launch_test(test: &ABTest, ui: &mut UI, ctx: &mut EventCtx) -> Mode {
|
||||
|
||||
// TODO Cheaper to load the edits for the map and then instantiate the scenario for the
|
||||
// primary.
|
||||
let mut timer = Timer::new("setup A/B test");
|
||||
let (primary, secondary) = ctx.loading_screen(|ctx, timer| {
|
||||
let primary = PerMapUI::new(
|
||||
Flags {
|
||||
sim_flags: SimFlags {
|
||||
@ -116,7 +115,7 @@ fn launch_test(test: &ABTest, ui: &mut UI, ctx: &mut EventCtx) -> Mode {
|
||||
},
|
||||
&ui.cs,
|
||||
ctx.prerender,
|
||||
&mut timer,
|
||||
timer,
|
||||
);
|
||||
let secondary = PerMapUI::new(
|
||||
Flags {
|
||||
@ -130,8 +129,10 @@ fn launch_test(test: &ABTest, ui: &mut UI, ctx: &mut EventCtx) -> Mode {
|
||||
},
|
||||
&ui.cs,
|
||||
ctx.prerender,
|
||||
&mut timer,
|
||||
timer,
|
||||
);
|
||||
(primary, secondary)
|
||||
});
|
||||
|
||||
ui.primary = primary;
|
||||
let mut mode = ABTestMode::new(ctx);
|
||||
|
@ -246,8 +246,9 @@ fn splash_screen(
|
||||
// This retains no state, but that's probably fine.
|
||||
let mut flags = ui.primary.current_flags.clone();
|
||||
flags.sim_flags.load = PathBuf::from(format!("../data/maps/{}.abst", name));
|
||||
let mut timer = Timer::new(&format!("load {}", name));
|
||||
*ui = UI::new(flags, ctx.prerender, ctx.canvas, &mut timer);
|
||||
*ui = ctx.loading_screen(|ctx, timer| {
|
||||
UI::new(flags, ctx.prerender, ctx.canvas, timer)
|
||||
});
|
||||
break Some(Mode::Sandbox(SandboxMode::new(ctx.canvas)));
|
||||
} else if wizard.aborted() {
|
||||
break Some(Mode::SplashScreen(Wizard::new(), maybe_screensaver.take()));
|
||||
|
@ -2,7 +2,7 @@ use crate::game::Mode;
|
||||
use crate::mission::MissionEditMode;
|
||||
use crate::sandbox::SandboxMode;
|
||||
use crate::ui::UI;
|
||||
use abstutil::{Timer, WeightedUsizeChoice};
|
||||
use abstutil::WeightedUsizeChoice;
|
||||
use ezgui::{
|
||||
Color, Drawable, EventCtx, GfxCtx, Key, LogScroller, ModalMenu, Wizard, WrappedWizard,
|
||||
};
|
||||
@ -58,12 +58,14 @@ impl ScenarioEditor {
|
||||
} else if menu.action("edit") {
|
||||
*self = ScenarioEditor::EditScenario(scenario.clone(), Wizard::new());
|
||||
} else if menu.action("instantiate") {
|
||||
ctx.loading_screen(|_, timer| {
|
||||
scenario.instantiate(
|
||||
&mut ui.primary.sim,
|
||||
&ui.primary.map,
|
||||
&mut ui.primary.current_flags.sim_flags.make_rng(),
|
||||
&mut Timer::new("instantiate scenario"),
|
||||
timer,
|
||||
);
|
||||
});
|
||||
return Some(Mode::Sandbox(SandboxMode::new(ctx.canvas)));
|
||||
} else if menu.action("visualize") {
|
||||
let neighborhoods = Neighborhood::load_all(
|
||||
|
@ -91,13 +91,18 @@ impl AgentSpawner {
|
||||
None => {
|
||||
if ui.primary.sim.is_empty() {
|
||||
if sandbox_menu.action("seed the sim with agents") {
|
||||
Scenario::scaled_run(map, ui.primary.current_flags.num_agents).instantiate(
|
||||
// TODO This covers up the map. :\
|
||||
ctx.loading_screen(|_, timer| {
|
||||
let map = &ui.primary.map;
|
||||
Scenario::scaled_run(map, ui.primary.current_flags.num_agents)
|
||||
.instantiate(
|
||||
&mut ui.primary.sim,
|
||||
map,
|
||||
&mut ui.primary.current_flags.sim_flags.make_rng(),
|
||||
&mut Timer::new("seed sim"),
|
||||
timer,
|
||||
);
|
||||
ui.primary.sim.step(map);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
use crate::runner::LoadingScreen;
|
||||
use crate::{Canvas, Color, UserInput};
|
||||
use abstutil::Timer;
|
||||
use geom::Polygon;
|
||||
use glium::implement_vertex;
|
||||
use std::cell::Cell;
|
||||
@ -112,6 +114,23 @@ pub struct EventCtx<'a> {
|
||||
// TODO These two probably shouldn't be public
|
||||
pub canvas: &'a mut Canvas,
|
||||
pub prerender: &'a Prerender<'a>,
|
||||
|
||||
pub(crate) program: &'a glium::Program,
|
||||
}
|
||||
|
||||
impl<'a> EventCtx<'a> {
|
||||
pub fn loading_screen<O, F: FnOnce(&mut EventCtx, &mut Timer) -> O>(&mut self, f: F) -> O {
|
||||
let mut timer = Timer::new_with_sink(
|
||||
"Loading...",
|
||||
Box::new(LoadingScreen::new(
|
||||
self.prerender,
|
||||
self.program,
|
||||
self.canvas.window_width,
|
||||
self.canvas.window_height,
|
||||
)),
|
||||
);
|
||||
f(self, &mut timer)
|
||||
}
|
||||
}
|
||||
|
||||
fn f32_to_u8(x: f32) -> u8 {
|
||||
|
@ -48,7 +48,12 @@ pub(crate) struct State<G: GUI> {
|
||||
|
||||
impl<G: GUI> State<G> {
|
||||
// The bool indicates if the input was actually used.
|
||||
fn event(mut self, ev: Event, prerender: &Prerender) -> (State<G>, EventLoopMode, bool) {
|
||||
fn event(
|
||||
mut self,
|
||||
ev: Event,
|
||||
prerender: &Prerender,
|
||||
program: &glium::Program,
|
||||
) -> (State<G>, EventLoopMode, bool) {
|
||||
// Clear out the possible keys
|
||||
match self.context_menu {
|
||||
ContextMenu::Inactive(_) => {
|
||||
@ -67,6 +72,7 @@ impl<G: GUI> State<G> {
|
||||
input: &mut input,
|
||||
canvas: &mut canvas,
|
||||
prerender,
|
||||
program,
|
||||
})
|
||||
})) {
|
||||
Ok(pair) => pair,
|
||||
@ -195,7 +201,6 @@ pub fn run<G: GUI, F: FnOnce(&mut Canvas, &Prerender, &mut Timer) -> G>(
|
||||
let mut timer = Timer::new_with_sink(
|
||||
"Loading application...",
|
||||
Box::new(LoadingScreen::new(
|
||||
&display,
|
||||
&prerender,
|
||||
&program,
|
||||
initial_width,
|
||||
@ -261,7 +266,7 @@ fn loop_forever<G: GUI>(
|
||||
let mut any_input_used = false;
|
||||
|
||||
for event in new_events {
|
||||
let (new_state, mode, input_used) = state.event(event, &prerender);
|
||||
let (new_state, mode, input_used) = state.event(event, &prerender, &program);
|
||||
if input_used {
|
||||
any_input_used = true;
|
||||
}
|
||||
@ -313,8 +318,7 @@ fn loop_forever<G: GUI>(
|
||||
}
|
||||
}
|
||||
|
||||
struct LoadingScreen<'a> {
|
||||
display: &'a glium::Display,
|
||||
pub struct LoadingScreen<'a> {
|
||||
canvas: Canvas,
|
||||
prerender: &'a Prerender<'a>,
|
||||
program: &'a glium::Program,
|
||||
@ -322,8 +326,7 @@ struct LoadingScreen<'a> {
|
||||
}
|
||||
|
||||
impl<'a> LoadingScreen<'a> {
|
||||
fn new(
|
||||
display: &'a glium::Display,
|
||||
pub fn new(
|
||||
prerender: &'a Prerender<'a>,
|
||||
program: &'a glium::Program,
|
||||
initial_width: f64,
|
||||
@ -331,11 +334,10 @@ impl<'a> LoadingScreen<'a> {
|
||||
) -> LoadingScreen<'a> {
|
||||
// TODO Ew! Expensive and wacky. Fix by not storing GlyphBrush in Canvas at all.
|
||||
let dejavu: &[u8] = include_bytes!("assets/DejaVuSans.ttf");
|
||||
let glyphs = GlyphBrush::new(display, vec![Font::from_bytes(dejavu).unwrap()]);
|
||||
let glyphs = GlyphBrush::new(prerender.display, vec![Font::from_bytes(dejavu).unwrap()]);
|
||||
let canvas = Canvas::new(initial_width, initial_height, glyphs);
|
||||
|
||||
LoadingScreen {
|
||||
display,
|
||||
canvas,
|
||||
prerender,
|
||||
program,
|
||||
@ -344,12 +346,12 @@ impl<'a> LoadingScreen<'a> {
|
||||
}
|
||||
|
||||
fn redraw(&self, text: Text) {
|
||||
let mut target = self.display.draw();
|
||||
let mut target = self.prerender.display.draw();
|
||||
let context_menu = ContextMenu::new();
|
||||
let mut g = GfxCtx::new(
|
||||
&self.canvas,
|
||||
self.prerender,
|
||||
self.display,
|
||||
self.prerender.display,
|
||||
&mut target,
|
||||
self.program,
|
||||
&context_menu,
|
||||
|
Loading…
Reference in New Issue
Block a user