From 31f9f455bb1cb9ecd51b31807acdee1c0ac5dd1f Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Sun, 21 Apr 2019 13:35:32 -0700 Subject: [PATCH] scroll the map in the background while the splash screen menu is up. remove screensaver as a plugin. --- editor/src/plugins/debug/mod.rs | 1 - editor/src/plugins/debug/screensaver.rs | 69 -------------------- editor/src/splash.rs | 85 ++++++++++++++++++++++--- editor/src/state.rs | 3 - editor/src/ui.rs | 4 +- 5 files changed, 77 insertions(+), 85 deletions(-) delete mode 100644 editor/src/plugins/debug/screensaver.rs diff --git a/editor/src/plugins/debug/mod.rs b/editor/src/plugins/debug/mod.rs index 67c6680a5f..08553a0f80 100644 --- a/editor/src/plugins/debug/mod.rs +++ b/editor/src/plugins/debug/mod.rs @@ -8,5 +8,4 @@ pub mod geom_validation; pub mod hider; pub mod layers; pub mod orig_roads; -pub mod screensaver; pub mod spawn_agent; diff --git a/editor/src/plugins/debug/screensaver.rs b/editor/src/plugins/debug/screensaver.rs deleted file mode 100644 index 98a97e5dfd..0000000000 --- a/editor/src/plugins/debug/screensaver.rs +++ /dev/null @@ -1,69 +0,0 @@ -use crate::plugins::{BlockingPlugin, PluginCtx}; -use abstutil::elapsed_seconds; -use ezgui::EventLoopMode; -use geom::{Duration, Line, Pt2D, Speed}; -use rand::Rng; -use rand_xorshift::XorShiftRng; -use std::time::Instant; - -const SPEED: Speed = Speed::const_meters_per_second(50.0); - -pub struct Screensaver { - line: Line, - started: Instant, - rng: XorShiftRng, -} - -impl Screensaver { - pub fn new(ctx: &mut PluginCtx) -> Option { - if ctx.input.action_chosen("screensaver mode") { - let mut rng = ctx.primary.current_flags.sim_flags.make_rng(); - ctx.hints.mode = EventLoopMode::Animation; - - let at = ctx.canvas.center_to_map_pt(); - ctx.canvas.cam_zoom = 10.0; - ctx.canvas.center_on_map_pt(at); - - return Some(Screensaver { - line: Screensaver::bounce(ctx, &mut rng), - started: Instant::now(), - rng, - }); - } - None - } - - fn bounce(ctx: &mut PluginCtx, rng: &mut XorShiftRng) -> Line { - let bounds = ctx.primary.map.get_bounds(); - let at = ctx.canvas.center_to_map_pt(); - // TODO Ideally bounce off the edge of the map - let goto = Pt2D::new( - rng.gen_range(0.0, bounds.max_x), - rng.gen_range(0.0, bounds.max_y), - ); - Line::new(at, goto) - } -} - -impl BlockingPlugin for Screensaver { - fn blocking_event(&mut self, ctx: &mut PluginCtx) -> bool { - ctx.input.set_mode("Screensaver", &ctx.canvas); - if ctx.input.modal_action("quit") { - return false; - } - - if ctx.input.nonblocking_is_update_event() { - ctx.input.use_update_event(); - let dist_along = Duration::seconds(elapsed_seconds(self.started)) * SPEED; - if dist_along < self.line.length() { - ctx.canvas - .center_on_map_pt(self.line.dist_along(dist_along)); - } else { - self.line = Screensaver::bounce(ctx, &mut self.rng); - self.started = Instant::now(); - } - ctx.hints.mode = EventLoopMode::Animation; - } - true - } -} diff --git a/editor/src/splash.rs b/editor/src/splash.rs index f51384d1d3..a64de6c33e 100644 --- a/editor/src/splash.rs +++ b/editor/src/splash.rs @@ -1,9 +1,15 @@ -use crate::state::{DefaultUIState, Flags}; +use crate::state::{DefaultUIState, Flags, UIState}; use crate::ui::UI; +use abstutil::elapsed_seconds; use ezgui::{ - Canvas, EventCtx, EventLoopMode, GfxCtx, ModalMenu, Prerender, TopMenu, Wizard, WrappedWizard, - GUI, + Canvas, EventCtx, EventLoopMode, GfxCtx, ModalMenu, Prerender, TopMenu, UserInput, Wizard, + WrappedWizard, GUI, }; +use geom::{Duration, Line, Pt2D, Speed}; +use map_model::Map; +use rand::Rng; +use rand_xorshift::XorShiftRng; +use std::time::Instant; pub struct GameState { mode: Mode, @@ -11,15 +17,19 @@ pub struct GameState { } enum Mode { - SplashScreen(Wizard), + SplashScreen(Wizard, Screensaver, XorShiftRng), Playing, } impl GameState { pub fn new(flags: Flags, canvas: &mut Canvas, prerender: &Prerender) -> GameState { + let mut rng = flags.sim_flags.make_rng(); + let ui = UI::new(DefaultUIState::new(flags, prerender, true), canvas); + let screensaver = + Screensaver::start_bounce(&mut rng, canvas, &ui.state.get_state().primary.map); GameState { - mode: Mode::SplashScreen(Wizard::new()), - ui: UI::new(DefaultUIState::new(flags, prerender, true), canvas), + mode: Mode::SplashScreen(Wizard::new(), screensaver, rng), + ui, } } } @@ -37,11 +47,18 @@ impl GUI for GameState { fn event(&mut self, mut ctx: EventCtx) -> EventLoopMode { match self.mode { - Mode::SplashScreen(ref mut wizard) => { + Mode::SplashScreen(ref mut wizard, ref mut screensaver, ref mut rng) => { + screensaver.update( + rng, + &mut ctx.input, + &mut ctx.canvas, + &self.ui.state.get_state().primary.map, + ); + if splash_screen(wizard.wrap(&mut ctx.input, ctx.canvas), &mut self.ui).is_some() { self.mode = Mode::Playing; } - EventLoopMode::InputOnly + EventLoopMode::Animation } Mode::Playing => self.ui.event(ctx), } @@ -49,7 +66,10 @@ impl GUI for GameState { fn draw(&self, g: &mut GfxCtx, screencap: bool) -> Option { match self.mode { - Mode::SplashScreen(ref wizard) => { + Mode::SplashScreen(ref wizard, _, _) => { + // Draw the map in the background. + self.ui.draw(g, screencap); + wizard.draw(g); None } @@ -85,3 +105,50 @@ fn splash_screen(mut wizard: WrappedWizard, ui: &mut UI) -> Opti _ => unreachable!(), } } + +const SPEED: Speed = Speed::const_meters_per_second(50.0); + +// TODO I'd prefer to store the XorShiftRng in here, but it makes borrow checking without some +// boilerplate hard. +struct Screensaver { + line: Line, + started: Instant, +} + +impl Screensaver { + fn start_bounce(rng: &mut XorShiftRng, canvas: &mut Canvas, map: &Map) -> Screensaver { + let at = canvas.center_to_map_pt(); + let bounds = map.get_bounds(); + // TODO Ideally bounce off the edge of the map + let goto = Pt2D::new( + rng.gen_range(0.0, bounds.max_x), + rng.gen_range(0.0, bounds.max_y), + ); + + canvas.cam_zoom = 10.0; + canvas.center_on_map_pt(at); + + Screensaver { + line: Line::new(at, goto), + started: Instant::now(), + } + } + + fn update( + &mut self, + rng: &mut XorShiftRng, + input: &mut UserInput, + canvas: &mut Canvas, + map: &Map, + ) { + if input.nonblocking_is_update_event() { + input.use_update_event(); + let dist_along = Duration::seconds(elapsed_seconds(self.started)) * SPEED; + if dist_along < self.line.length() { + canvas.center_on_map_pt(self.line.dist_along(dist_along)); + } else { + *self = Screensaver::start_bounce(rng, canvas, map) + } + } + } +} diff --git a/editor/src/state.rs b/editor/src/state.rs index 474084a841..2e0ef7eae5 100644 --- a/editor/src/state.rs +++ b/editor/src/state.rs @@ -289,9 +289,6 @@ impl UIState for DefaultUIState { } else if let Some(p) = debug::spawn_agent::SpawnAgent::new(&mut ctx) { self.exclusive_blocking_plugin = Some(Box::new(p)); return; - } else if let Some(p) = debug::screensaver::Screensaver::new(&mut ctx) { - self.exclusive_blocking_plugin = Some(Box::new(p)); - return; } } } diff --git a/editor/src/ui.rs b/editor/src/ui.rs index a5ad044630..d7640e557d 100644 --- a/editor/src/ui.rs +++ b/editor/src/ui.rs @@ -18,7 +18,7 @@ pub struct UI { // TODO Probably move this into DefaultUIState after rewriting Tutorial and the whole UIState // abstraction. hints: RenderingHints, - state: S, + pub state: S, } impl GUI for UI { @@ -44,7 +44,6 @@ impl GUI for UI { (Some(Key::Num7), "show/hide extra shapes"), (Some(Key::Num9), "show/hide all turn icons"), (None, "show/hide geometry debug mode"), - (None, "screensaver mode"), ], )); } @@ -173,7 +172,6 @@ impl GUI for UI { vec![(Key::Enter, "quit"), (Key::N, "see next problem")], ), ModalMenu::new("Original Roads", vec![(Key::Enter, "quit")]), - ModalMenu::new("Screensaver", vec![(Key::Enter, "quit")]), ModalMenu::new("OSM Classifier", vec![(Key::Num6, "quit")]), ModalMenu::new( "Floodfiller",