mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 07:25:47 +03:00
Fix #367 by making all constructors of SandboxMode appropriately defer
work that must happen after the map/scenario are loaded.
This commit is contained in:
parent
e7fb9b1a4a
commit
1e0d8536a4
@ -257,7 +257,8 @@ impl State for ChallengesPicker {
|
||||
}
|
||||
"Start!" => {
|
||||
let challenge = self.challenge.take().unwrap();
|
||||
let sandbox = SandboxMode::new(ctx, app, challenge.gameplay.clone());
|
||||
// Constructing the cutscene doesn't require the map/scenario to be loaded
|
||||
let sandbox = SandboxMode::simple_new(ctx, app, challenge.gameplay.clone());
|
||||
if let Some(cutscene) = challenge.cutscene {
|
||||
Transition::Multi(vec![
|
||||
Transition::Replace(sandbox),
|
||||
|
@ -70,7 +70,7 @@ impl Game {
|
||||
} else {
|
||||
let mode = maybe_mode
|
||||
.unwrap_or_else(|| GameplayMode::Freeform(app.primary.map.get_name().clone()));
|
||||
vec![SandboxMode::new(ctx, &mut app, mode)]
|
||||
vec![SandboxMode::simple_new(ctx, &mut app, mode)]
|
||||
};
|
||||
if let Some(ss) = savestate {
|
||||
// TODO This is weird, we're left in Freeform mode with the wrong UI. Can't instantiate
|
||||
|
@ -189,7 +189,7 @@ impl State for MainMenu {
|
||||
} else {
|
||||
"home_to_work"
|
||||
};
|
||||
return Transition::Push(SandboxMode::new(
|
||||
return Transition::Push(SandboxMode::simple_new(
|
||||
ctx,
|
||||
app,
|
||||
GameplayMode::PlayScenario(
|
||||
@ -437,7 +437,7 @@ impl State for Proposals {
|
||||
} else {
|
||||
app.primary.layer =
|
||||
Some(Box::new(crate::layer::map::Static::edits(ctx, app)));
|
||||
Transition::Replace(SandboxMode::new(
|
||||
Transition::Replace(SandboxMode::simple_new(
|
||||
ctx,
|
||||
app,
|
||||
GameplayMode::PlayScenario(
|
||||
|
@ -218,7 +218,7 @@ impl GameplayState for FixTrafficSignals {
|
||||
return Some(Transition::Push(FYI::new(ctx, contents, app.cs.panel_bg)));
|
||||
}
|
||||
"try again" => {
|
||||
return Some(Transition::Replace(SandboxMode::new(
|
||||
return Some(Transition::Replace(SandboxMode::simple_new(
|
||||
ctx,
|
||||
app,
|
||||
self.mode.clone(),
|
||||
|
@ -50,7 +50,7 @@ impl GameplayState for Freeform {
|
||||
Box::new(|ctx, app| {
|
||||
Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::Replace(SandboxMode::new(
|
||||
Transition::Replace(SandboxMode::simple_new(
|
||||
ctx,
|
||||
app,
|
||||
GameplayMode::Freeform(app.primary.map.get_name().clone()),
|
||||
@ -192,7 +192,7 @@ pub fn make_change_traffic(
|
||||
Box::new(|scenario_name, ctx, app| {
|
||||
Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::Replace(SandboxMode::new(
|
||||
Transition::Replace(SandboxMode::simple_new(
|
||||
ctx,
|
||||
app,
|
||||
if scenario_name == "none" {
|
||||
|
@ -270,7 +270,7 @@ impl State for FinalScore {
|
||||
"Try again" => {
|
||||
return Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::Replace(SandboxMode::new(ctx, app, self.retry.clone())),
|
||||
Transition::Replace(SandboxMode::simple_new(ctx, app, self.retry.clone())),
|
||||
]);
|
||||
}
|
||||
"Next challenge" => {
|
||||
@ -320,7 +320,8 @@ impl State for FinalScore {
|
||||
if self.chose_next {
|
||||
return Transition::Clear(vec![
|
||||
MainMenu::new(ctx, app),
|
||||
SandboxMode::new(ctx, app, self.next_mode.clone().unwrap()),
|
||||
// Constructing the cutscene doesn't require the map/scenario to be loaded.
|
||||
SandboxMode::simple_new(ctx, app, self.next_mode.clone().unwrap()),
|
||||
(Challenge::find(self.next_mode.as_ref().unwrap())
|
||||
.0
|
||||
.cutscene
|
||||
|
@ -73,7 +73,7 @@ impl GameplayState for PlayScenario {
|
||||
};
|
||||
Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::Replace(SandboxMode::new(ctx, app, mode)),
|
||||
Transition::Replace(SandboxMode::simple_new(ctx, app, mode)),
|
||||
])
|
||||
}),
|
||||
)))
|
||||
@ -241,7 +241,7 @@ impl State for EditScenarioModifiers {
|
||||
|
||||
return Transition::Multi(vec![
|
||||
Transition::Pop,
|
||||
Transition::Replace(SandboxMode::new(
|
||||
Transition::Replace(SandboxMode::simple_new(
|
||||
ctx,
|
||||
app,
|
||||
GameplayMode::PlayScenario(
|
||||
|
@ -53,7 +53,8 @@ impl TutorialPointer {
|
||||
impl Tutorial {
|
||||
pub fn start(ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
Transition::Multi(vec![
|
||||
Transition::Push(SandboxMode::new(
|
||||
// Constructing the intro_story cutscene doesn't require the map/scenario to be loaded.
|
||||
Transition::Push(SandboxMode::simple_new(
|
||||
ctx,
|
||||
app,
|
||||
GameplayMode::Tutorial(
|
||||
@ -662,7 +663,7 @@ fn make_bike_lane_scenario(map: &Map) -> ScenarioGenerator {
|
||||
fn transition(ctx: &mut EventCtx, app: &mut App, tut: &mut TutorialState) -> Transition {
|
||||
tut.reset_state();
|
||||
let mode = GameplayMode::Tutorial(tut.current);
|
||||
Transition::Replace(SandboxMode::new(ctx, app, mode))
|
||||
Transition::Replace(SandboxMode::simple_new(ctx, app, mode))
|
||||
}
|
||||
|
||||
impl TutorialState {
|
||||
|
@ -51,14 +51,17 @@ pub struct SandboxControls {
|
||||
}
|
||||
|
||||
impl SandboxMode {
|
||||
// TODO Audit all callers
|
||||
pub fn new(ctx: &mut EventCtx, app: &mut App, mode: GameplayMode) -> Box<dyn State> {
|
||||
/// If you don't need to chain any transitions after the SandboxMode that rely on its resources
|
||||
/// being loaded, use this. Otherwise, see `async_new`.
|
||||
pub fn simple_new(ctx: &mut EventCtx, app: &mut App, mode: GameplayMode) -> Box<dyn State> {
|
||||
SandboxMode::async_new(ctx, app, mode, Box::new(|_, _| Vec::new()))
|
||||
}
|
||||
|
||||
/// This does not immediately initialize anything (like loading the correct map, instantiating
|
||||
/// the scenario, etc). That means if you're chaining this call with other transitions, you
|
||||
/// probably need to defer running them using `finalize`.
|
||||
// TODO Remove the unused ctx param? It affects lots of downstream callers; maybe better to
|
||||
// leave it here in case this monstrosity is refactored again.
|
||||
pub fn async_new(
|
||||
_: &mut EventCtx,
|
||||
app: &mut App,
|
||||
|
@ -165,7 +165,7 @@ impl SpeedControls {
|
||||
}
|
||||
"reset to midnight" => {
|
||||
if let Some(mode) = maybe_mode {
|
||||
return Some(Transition::Replace(SandboxMode::new(
|
||||
return Some(Transition::Replace(SandboxMode::simple_new(
|
||||
ctx,
|
||||
app,
|
||||
mode.clone(),
|
||||
|
@ -87,10 +87,20 @@ impl State for JumpToTime {
|
||||
"jump to time" => {
|
||||
if self.target < app.primary.sim.time() {
|
||||
if let Some(mode) = self.maybe_mode.take() {
|
||||
return Transition::Multi(vec![
|
||||
Transition::Replace(SandboxMode::new(ctx, app, mode)),
|
||||
Transition::Push(TimeWarpScreen::new(ctx, app, self.target, None)),
|
||||
]);
|
||||
let target_time = self.target;
|
||||
return Transition::Replace(SandboxMode::async_new(
|
||||
ctx,
|
||||
app,
|
||||
mode,
|
||||
Box::new(move |ctx, app| {
|
||||
vec![Transition::Push(TimeWarpScreen::new(
|
||||
ctx,
|
||||
app,
|
||||
target_time,
|
||||
None,
|
||||
))]
|
||||
}),
|
||||
));
|
||||
} else {
|
||||
return Transition::Replace(PopupMsg::new(
|
||||
ctx,
|
||||
|
Loading…
Reference in New Issue
Block a user