From a7b10b7ec5f59fe3250d492fe86d180275014703 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Tue, 18 Jun 2019 06:18:04 -0700 Subject: [PATCH] collapsing load/create scenario options directly into mission mode --- editor/src/mission/mod.rs | 69 +++++++++++++++++++++--- editor/src/mission/scenario.rs | 96 +++++++--------------------------- 2 files changed, 79 insertions(+), 86 deletions(-) diff --git a/editor/src/mission/mod.rs b/editor/src/mission/mod.rs index 65c9fc1915..00d4509c4a 100644 --- a/editor/src/mission/mod.rs +++ b/editor/src/mission/mod.rs @@ -11,8 +11,11 @@ use crate::render::DrawOptions; use crate::sandbox::SandboxMode; use crate::ui::ShowEverything; use crate::ui::UI; +use abstutil::Timer; use ezgui::{hotkey, EventCtx, EventLoopMode, GfxCtx, Key, ModalMenu, Wizard, WrappedWizard}; use geom::Duration; +use map_model::Map; +use sim::Scenario; pub struct MissionEditMode { state: State, @@ -21,7 +24,9 @@ pub struct MissionEditMode { enum State { Exploring(ModalMenu), Neighborhood(neighborhood::NeighborhoodEditor), - Scenario(scenario::ScenarioEditor), + LoadScenario(Wizard), + CreateNewScenario(Wizard), + EditScenario(scenario::ScenarioEditor), DataViz(dataviz::DataVisualizer), IndividualTrips(individ_trips::TripsVisualizer), AllTrips(all_trips::TripsVisualizer), @@ -44,7 +49,8 @@ impl MissionEditMode { (hotkey(Key::S), "set up simulation with PSRC trips"), (hotkey(Key::Q), "create scenario from PSRC trips"), (hotkey(Key::N), "manage neighborhoods"), - (hotkey(Key::W), "manage scenarios"), + (hotkey(Key::W), "load scenario"), + (None, "create new scenario"), ], ctx, )), @@ -98,10 +104,10 @@ impl MissionEditMode { mode.state = State::Neighborhood( neighborhood::NeighborhoodEditor::PickNeighborhood(Wizard::new()), ); - } else if menu.action("manage scenarios") { - mode.state = State::Scenario(scenario::ScenarioEditor::PickScenario( - Wizard::new(), - )); + } else if menu.action("load scenario") { + mode.state = State::LoadScenario(Wizard::new()); + } else if menu.action("create new scenario") { + mode.state = State::CreateNewScenario(Wizard::new()); } } State::DataViz(ref mut viz) => { @@ -134,7 +140,35 @@ impl MissionEditMode { mode.state = MissionEditMode::new(ctx, &mut state.ui).state; } } - State::Scenario(ref mut editor) => { + State::LoadScenario(ref mut wizard) => { + if let Some(scenario) = + load_scenario(&state.ui.primary.map, &mut wizard.wrap(ctx)) + { + mode.state = + State::EditScenario(scenario::ScenarioEditor::new(scenario, ctx)); + } else if wizard.aborted() { + mode.state = MissionEditMode::new(ctx, &mut state.ui).state; + } + } + State::CreateNewScenario(ref mut wizard) => { + let mut wrapped = wizard.wrap(ctx); + if let Some(name) = wrapped.input_string("Name the scenario") { + mode.state = State::EditScenario(scenario::ScenarioEditor::new( + Scenario { + scenario_name: name, + map_name: state.ui.primary.map.get_name().to_string(), + seed_parked_cars: Vec::new(), + spawn_over_time: Vec::new(), + border_spawn_over_time: Vec::new(), + individ_trips: Vec::new(), + }, + ctx, + )); + } else if wizard.aborted() { + mode.state = MissionEditMode::new(ctx, &mut state.ui).state; + } + } + State::EditScenario(ref mut editor) => { if let Some(new_mode) = editor.event(ctx, &mut state.ui) { state.mode = new_mode; } @@ -174,9 +208,12 @@ impl MissionEditMode { State::Neighborhood(ref editor) => { editor.draw(g, &state.ui); } - State::Scenario(ref editor) => { + State::EditScenario(ref editor) => { editor.draw(g, &state.ui); } + State::LoadScenario(ref wizard) | State::CreateNewScenario(ref wizard) => { + wizard.draw(g); + } }, _ => unreachable!(), } @@ -186,3 +223,19 @@ impl MissionEditMode { pub fn input_time(wizard: &mut WrappedWizard, query: &str) -> Option { wizard.input_something(query, None, Box::new(|line| Duration::parse(&line))) } + +fn load_scenario(map: &Map, wizard: &mut WrappedWizard) -> Option { + let map_name = map.get_name().to_string(); + wizard + .choose_something_no_keys::( + "Load which scenario?", + Box::new(move || abstutil::list_all_objects("scenarios", &map_name)), + ) + .map(|(_, s)| { + abstutil::read_binary( + &format!("../data/scenarios/{}/{}.bin", map.get_name(), s), + &mut Timer::throwaway(), + ) + .unwrap() + }) +} diff --git a/editor/src/mission/scenario.rs b/editor/src/mission/scenario.rs index 223a68155f..6589a69b7b 100644 --- a/editor/src/mission/scenario.rs +++ b/editor/src/mission/scenario.rs @@ -2,47 +2,38 @@ use crate::game::Mode; use crate::mission::{input_time, MissionEditMode}; use crate::sandbox::SandboxMode; use crate::ui::UI; -use abstutil::{Timer, WeightedUsizeChoice}; +use abstutil::WeightedUsizeChoice; use ezgui::{hotkey, EventCtx, GfxCtx, Key, LogScroller, ModalMenu, Wizard, WrappedWizard}; use geom::Duration; use map_model::{IntersectionID, Map, Neighborhood}; use sim::{BorderSpawnOverTime, OriginDestination, Scenario, SeedParkedCars, SpawnOverTime}; pub enum ScenarioEditor { - PickScenario(Wizard), ManageScenario(ModalMenu, Scenario, LogScroller), EditScenario(Scenario, Wizard), } impl ScenarioEditor { - fn modal_menu(name: &str, ctx: &EventCtx) -> ModalMenu { - ModalMenu::new( - &format!("Scenario Editor for {}", name), - vec![ - (hotkey(Key::Escape), "quit"), - (hotkey(Key::S), "save"), - (hotkey(Key::E), "edit"), - (hotkey(Key::I), "instantiate"), - ], - ctx, + pub fn new(scenario: Scenario, ctx: &mut EventCtx) -> ScenarioEditor { + let scroller = LogScroller::new(scenario.scenario_name.clone(), scenario.describe()); + ScenarioEditor::ManageScenario( + ModalMenu::new( + &format!("Scenario Editor for {}", scenario.scenario_name), + vec![ + (hotkey(Key::Escape), "quit"), + (hotkey(Key::S), "save"), + (hotkey(Key::E), "edit"), + (hotkey(Key::I), "instantiate"), + ], + ctx, + ), + scenario, + scroller, ) } pub fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Option { match self { - ScenarioEditor::PickScenario(ref mut wizard) => { - if let Some(scenario) = pick_scenario(&ui.primary.map, wizard.wrap(ctx)) { - let scroller = - LogScroller::new(scenario.scenario_name.clone(), scenario.describe()); - *self = ScenarioEditor::ManageScenario( - ScenarioEditor::modal_menu(&scenario.scenario_name, ctx), - scenario, - scroller, - ); - } else if wizard.aborted() { - return Some(Mode::Mission(MissionEditMode::new(ctx, ui))); - } - } ScenarioEditor::ManageScenario(ref mut menu, scenario, ref mut scroller) => { menu.handle_event(ctx, None); ctx.canvas.handle_event(ctx.input); @@ -67,22 +58,10 @@ impl ScenarioEditor { } ScenarioEditor::EditScenario(ref mut scenario, ref mut wizard) => { if let Some(()) = edit_scenario(&ui.primary.map, scenario, wizard.wrap(ctx)) { - let scroller = - LogScroller::new(scenario.scenario_name.clone(), scenario.describe()); // TODO autosave, or at least make it clear there are unsaved edits - *self = ScenarioEditor::ManageScenario( - ScenarioEditor::modal_menu(&scenario.scenario_name, ctx), - scenario.clone(), - scroller, - ); + *self = ScenarioEditor::new(scenario.clone(), ctx); } else if wizard.aborted() { - let scroller = - LogScroller::new(scenario.scenario_name.clone(), scenario.describe()); - *self = ScenarioEditor::ManageScenario( - ScenarioEditor::modal_menu(&scenario.scenario_name, ctx), - scenario.clone(), - scroller, - ); + *self = ScenarioEditor::new(scenario.clone(), ctx); } } } @@ -91,9 +70,6 @@ impl ScenarioEditor { pub fn draw(&self, g: &mut GfxCtx, ui: &UI) { match self { - ScenarioEditor::PickScenario(wizard) => { - wizard.draw(g); - } ScenarioEditor::ManageScenario(ref menu, _, scroller) => { scroller.draw(g); menu.draw(g); @@ -108,26 +84,6 @@ impl ScenarioEditor { } } -fn pick_scenario(map: &Map, mut wizard: WrappedWizard) -> Option { - let load_existing = "Load existing scenario"; - let create_new = "Create new scenario"; - if wizard.choose_string("What scenario to edit?", vec![load_existing, create_new])? - == load_existing - { - load_scenario(map, &mut wizard, "Load which scenario?") - } else { - let scenario_name = wizard.input_string("Name the scenario")?; - Some(Scenario { - scenario_name, - map_name: map.get_name().to_string(), - seed_parked_cars: Vec::new(), - spawn_over_time: Vec::new(), - border_spawn_over_time: Vec::new(), - individ_trips: Vec::new(), - }) - } -} - fn edit_scenario(map: &Map, scenario: &mut Scenario, mut wizard: WrappedWizard) -> Option<()> { let seed_parked = "Seed parked cars"; let spawn = "Spawn agents"; @@ -224,22 +180,6 @@ fn choose_neighborhood(map: &Map, wizard: &mut WrappedWizard, query: &str) -> Op .map(|(n, _)| n) } -fn load_scenario(map: &Map, wizard: &mut WrappedWizard, query: &str) -> Option { - let map_name = map.get_name().to_string(); - wizard - .choose_something_no_keys::( - query, - Box::new(move || abstutil::list_all_objects("scenarios", &map_name)), - ) - .map(|(_, s)| { - abstutil::read_binary( - &format!("../data/scenarios/{}/{}.bin", map.get_name(), s), - &mut Timer::throwaway(), - ) - .unwrap() - }) -} - fn input_weighted_usize(wizard: &mut WrappedWizard, query: &str) -> Option { wizard.input_something( query,