mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 17:34:58 +03:00
a way to pop states and pass data back
This commit is contained in:
parent
3958ec556e
commit
e67305d084
@ -11,6 +11,7 @@ clipping = "0.1.1"
|
||||
colorbrewer = "0.1.0"
|
||||
counter = "0.4.3"
|
||||
derive-new = "0.5.6"
|
||||
downcast-rs = "1.0.4"
|
||||
ezgui = { path = "../ezgui" }
|
||||
geom = { path = "../geom" }
|
||||
itertools = "0.8.0"
|
||||
|
@ -552,9 +552,13 @@ impl State for SearchOSM {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO How to pass data back?
|
||||
//mode.search_results = Some((filter, ids));
|
||||
(Transition::Pop, EventLoopMode::InputOnly)
|
||||
(
|
||||
Transition::PopWithData(Box::new(|state| {
|
||||
state.downcast_mut::<DebugMode>().unwrap().search_results =
|
||||
Some((filter, ids));
|
||||
})),
|
||||
EventLoopMode::InputOnly,
|
||||
)
|
||||
}
|
||||
InputResult::StillActive => (Transition::Keep, EventLoopMode::InputOnly),
|
||||
}
|
||||
|
@ -54,6 +54,10 @@ impl GUI for Game {
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
Transition::PopWithData(cb) => {
|
||||
self.states.pop().unwrap().on_destroy(&mut self.ui);
|
||||
cb(self.states.last_mut().unwrap());
|
||||
}
|
||||
Transition::Push(state) => {
|
||||
self.states.last_mut().unwrap().on_suspend(&mut self.ui);
|
||||
self.states.push(state);
|
||||
@ -111,7 +115,7 @@ impl GUI for Game {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait State {
|
||||
pub trait State: downcast_rs::Downcast {
|
||||
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode);
|
||||
fn draw(&self, g: &mut GfxCtx, ui: &UI);
|
||||
fn draw_default_ui(&self) -> bool {
|
||||
@ -125,9 +129,13 @@ pub trait State {
|
||||
// We don't need an on_enter -- the constructor for the state can just do it.
|
||||
}
|
||||
|
||||
downcast_rs::impl_downcast!(State);
|
||||
|
||||
pub enum Transition {
|
||||
Keep,
|
||||
Pop,
|
||||
// If a state needs to pass data back to the parent, use this. Sadly, runtime type casting.
|
||||
PopWithData(Box<FnOnce(&mut Box<State>)>),
|
||||
Push(Box<State>),
|
||||
Replace(Box<State>),
|
||||
}
|
||||
|
@ -86,8 +86,16 @@ impl State for ScenarioEditor {
|
||||
if let Some(()) = edit_scenario(&ui.primary.map, &mut self.scenario, self.wizard.wrap(ctx))
|
||||
{
|
||||
// TODO autosave, or at least make it clear there are unsaved edits
|
||||
// TODO Need to Refresh the scenario in our parent!
|
||||
return (Transition::Pop, EventLoopMode::InputOnly);
|
||||
let scenario = self.scenario.clone();
|
||||
return (
|
||||
Transition::PopWithData(Box::new(|state| {
|
||||
let mut manager = state.downcast_mut::<ScenarioManager>().unwrap();
|
||||
manager.scroller =
|
||||
LogScroller::new(scenario.scenario_name.clone(), scenario.describe());
|
||||
manager.scenario = scenario;
|
||||
})),
|
||||
EventLoopMode::InputOnly,
|
||||
);
|
||||
} else if self.wizard.aborted() {
|
||||
return (Transition::Pop, EventLoopMode::InputOnly);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ impl TutorialMode {
|
||||
}
|
||||
|
||||
impl State for TutorialMode {
|
||||
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) {
|
||||
fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> (Transition, EventLoopMode) {
|
||||
let mut txt = Text::prompt("Tutorial");
|
||||
txt.add_line("Click and drag to pan around".to_string());
|
||||
|
||||
@ -64,7 +64,7 @@ struct Part2 {
|
||||
}
|
||||
|
||||
impl State for Part2 {
|
||||
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> (Transition, EventLoopMode) {
|
||||
fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> (Transition, EventLoopMode) {
|
||||
let mut txt = Text::prompt("Tutorial");
|
||||
txt.add_line("Use your mouse wheel or touchpad to zoom in and out".to_string());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user