mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-25 11:44:25 +03:00
state transitions for nicely handling a few things... in particular,
clearing splash screen wizard state so we dont get stuck on a choice ;)
This commit is contained in:
parent
551866169a
commit
3958ec556e
@ -93,8 +93,6 @@ impl State for ABTestMode {
|
||||
}
|
||||
|
||||
if self.menu.action("quit") {
|
||||
// TODO Should we clear edits too?
|
||||
ui.primary.reset_sim();
|
||||
// Note destroying mode.secondary has some noticeable delay.
|
||||
return (Transition::Pop, EventLoopMode::InputOnly);
|
||||
}
|
||||
@ -107,7 +105,6 @@ impl State for ABTestMode {
|
||||
}
|
||||
|
||||
if self.menu.action("scoreboard") {
|
||||
self.speed.pause();
|
||||
return (
|
||||
Transition::Push(Box::new(score::Scoreboard::new(
|
||||
ctx,
|
||||
@ -178,6 +175,15 @@ impl State for ABTestMode {
|
||||
self.menu.draw(g);
|
||||
self.speed.draw(g);
|
||||
}
|
||||
|
||||
fn on_suspend(&mut self, _: &mut UI) {
|
||||
self.speed.pause();
|
||||
}
|
||||
|
||||
fn on_destroy(&mut self, ui: &mut UI) {
|
||||
// TODO Should we clear edits too?
|
||||
ui.primary.reset_sim();
|
||||
}
|
||||
}
|
||||
|
||||
impl ABTestMode {
|
||||
|
@ -92,26 +92,15 @@ impl State for EditMode {
|
||||
}
|
||||
|
||||
if self.menu.action("quit") {
|
||||
// TODO Warn about unsaved edits
|
||||
// TODO Maybe put a loading screen around these.
|
||||
ui.primary
|
||||
.map
|
||||
.recalculate_pathfinding_after_edits(&mut Timer::new("apply pending map edits"));
|
||||
return (Transition::Pop, EventLoopMode::InputOnly);
|
||||
}
|
||||
if self.menu.action("sandbox mode") {
|
||||
ui.primary
|
||||
.map
|
||||
.recalculate_pathfinding_after_edits(&mut Timer::new("apply pending map edits"));
|
||||
return (
|
||||
Transition::Replace(Box::new(SandboxMode::new(ctx))),
|
||||
EventLoopMode::InputOnly,
|
||||
);
|
||||
}
|
||||
if self.menu.action("debug mode") {
|
||||
ui.primary
|
||||
.map
|
||||
.recalculate_pathfinding_after_edits(&mut Timer::new("apply pending map edits"));
|
||||
return (
|
||||
Transition::Replace(Box::new(DebugMode::new(ctx, ui))),
|
||||
EventLoopMode::InputOnly,
|
||||
@ -316,6 +305,14 @@ impl State for EditMode {
|
||||
self.common.draw(g, ui);
|
||||
self.menu.draw(g);
|
||||
}
|
||||
|
||||
fn on_destroy(&mut self, ui: &mut UI) {
|
||||
// TODO Warn about unsaved edits
|
||||
// TODO Maybe put a loading screen around these.
|
||||
ui.primary
|
||||
.map
|
||||
.recalculate_pathfinding_after_edits(&mut Timer::new("apply pending map edits"));
|
||||
}
|
||||
}
|
||||
|
||||
struct Saving {
|
||||
|
@ -12,10 +12,6 @@ pub struct Game {
|
||||
pub ui: UI,
|
||||
}
|
||||
|
||||
// TODO Need to reset_sim() when entering Edit, Tutorial, Mission, or ABTest and when leaving
|
||||
// Tutorial and ABTest. Expressing this manually right now is quite tedious; maybe having on_enter
|
||||
// and on_exit would be cleaner.
|
||||
|
||||
impl Game {
|
||||
pub fn new(flags: Flags, ctx: &mut EventCtx) -> Game {
|
||||
let splash = !flags.no_splash
|
||||
@ -52,17 +48,18 @@ impl GUI for Game {
|
||||
match transition {
|
||||
Transition::Keep => {}
|
||||
Transition::Pop => {
|
||||
self.states.pop();
|
||||
self.states.pop().unwrap().on_destroy(&mut self.ui);
|
||||
if self.states.is_empty() {
|
||||
self.before_quit(ctx.canvas);
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
Transition::Push(state) => {
|
||||
self.states.last_mut().unwrap().on_suspend(&mut self.ui);
|
||||
self.states.push(state);
|
||||
}
|
||||
Transition::Replace(state) => {
|
||||
self.states.pop();
|
||||
self.states.pop().unwrap().on_destroy(&mut self.ui);
|
||||
self.states.push(state);
|
||||
}
|
||||
}
|
||||
@ -120,6 +117,12 @@ pub trait State {
|
||||
fn draw_default_ui(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
// Before we push a new state on top of this one, call this.
|
||||
fn on_suspend(&mut self, _: &mut UI) {}
|
||||
// Before this state is popped or replaced, call this.
|
||||
fn on_destroy(&mut self, _: &mut UI) {}
|
||||
// We don't need an on_enter -- the constructor for the state can just do it.
|
||||
}
|
||||
|
||||
pub enum Transition {
|
||||
|
@ -268,7 +268,6 @@ impl State for SandboxMode {
|
||||
false,
|
||||
);
|
||||
} else if self.menu.action("jump to specific time") {
|
||||
self.speed.pause();
|
||||
return (
|
||||
Transition::Push(Box::new(JumpingToTime {
|
||||
wizard: Wizard::new(),
|
||||
@ -314,6 +313,10 @@ impl State for SandboxMode {
|
||||
_ => unreachable!(),
|
||||
}*/
|
||||
}
|
||||
|
||||
fn on_suspend(&mut self, _: &mut UI) {
|
||||
self.speed.pause();
|
||||
}
|
||||
}
|
||||
|
||||
struct JumpingToTime {
|
||||
|
@ -67,6 +67,10 @@ impl State for SplashScreen {
|
||||
fn draw(&self, g: &mut GfxCtx, _: &UI) {
|
||||
self.wizard.draw(g);
|
||||
}
|
||||
|
||||
fn on_suspend(&mut self, _: &mut UI) {
|
||||
self.wizard.reset();
|
||||
}
|
||||
}
|
||||
|
||||
const SPEED: Speed = Speed::const_meters_per_second(20.0);
|
||||
|
@ -43,7 +43,6 @@ impl State for TutorialMode {
|
||||
ctx.canvas.handle_event(ctx.input);
|
||||
|
||||
if self.menu.action("quit") {
|
||||
ui.primary.reset_sim();
|
||||
return (Transition::Pop, EventLoopMode::InputOnly);
|
||||
}
|
||||
|
||||
@ -53,6 +52,10 @@ impl State for TutorialMode {
|
||||
fn draw(&self, g: &mut GfxCtx, _: &UI) {
|
||||
self.menu.draw(g);
|
||||
}
|
||||
|
||||
fn on_destroy(&mut self, ui: &mut UI) {
|
||||
ui.primary.reset_sim();
|
||||
}
|
||||
}
|
||||
|
||||
struct Part2 {
|
||||
@ -69,7 +72,6 @@ impl State for Part2 {
|
||||
txt.add_line("".to_string());
|
||||
txt.add_line("Great! Press ENTER to continue.".to_string());
|
||||
if ctx.input.key_pressed(Key::Enter, "next step of tutorial") {
|
||||
ui.primary.reset_sim();
|
||||
return (Transition::Pop, EventLoopMode::InputOnly);
|
||||
}
|
||||
}
|
||||
@ -77,7 +79,6 @@ impl State for Part2 {
|
||||
ctx.canvas.handle_event(ctx.input);
|
||||
|
||||
if self.menu.action("quit") {
|
||||
ui.primary.reset_sim();
|
||||
return (Transition::Pop, EventLoopMode::InputOnly);
|
||||
}
|
||||
|
||||
@ -87,4 +88,8 @@ impl State for Part2 {
|
||||
fn draw(&self, g: &mut GfxCtx, _: &UI) {
|
||||
self.menu.draw(g);
|
||||
}
|
||||
|
||||
fn on_destroy(&mut self, ui: &mut UI) {
|
||||
ui.primary.reset_sim();
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,13 @@ impl Wizard {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
assert!(self.tb.is_none());
|
||||
assert!(self.menu.is_none());
|
||||
assert!(self.log_scroller.is_none());
|
||||
self.confirmed_state.clear();
|
||||
}
|
||||
|
||||
fn input_with_text_box<R: Cloneable>(
|
||||
&mut self,
|
||||
query: &str,
|
||||
|
Loading…
Reference in New Issue
Block a user