mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 10:44:56 +03:00
stop blindly plumbing through no-op events after any input is used. do
it more explicitly in just a few places. fixes crash when cycling through turns while sim is running. this makes modal menus appear laggy, but that's fine; phasing those out anyway.
This commit is contained in:
parent
89a269a59e
commit
6d016cd01b
@ -47,9 +47,13 @@ impl<'a> EventCtx<'a> {
|
||||
}
|
||||
|
||||
// Use to immediately plumb through an (empty) event to something
|
||||
pub fn fake_mouseover<O, F: FnMut(&mut EventCtx) -> O>(&mut self, mut cb: F) -> O {
|
||||
pub fn no_op_event<O, F: FnMut(&mut EventCtx) -> O>(
|
||||
&mut self,
|
||||
fake_mouseover: bool,
|
||||
mut cb: F,
|
||||
) -> O {
|
||||
let mut tmp = EventCtx {
|
||||
fake_mouseover: true,
|
||||
fake_mouseover,
|
||||
input: UserInput::new(Event::NoOp, self.canvas),
|
||||
canvas: self.canvas,
|
||||
prerender: self.prerender,
|
||||
|
@ -877,7 +877,7 @@ impl CompositeBuilder {
|
||||
c.clip_rect = Some(ScreenRectangle::top_left(top_left, c.container_dims));
|
||||
}
|
||||
|
||||
ctx.fake_mouseover(|ctx| assert!(c.event(ctx).is_none()));
|
||||
ctx.no_op_event(true, |ctx| assert!(c.event(ctx).is_none()));
|
||||
c
|
||||
}
|
||||
|
||||
|
@ -432,14 +432,6 @@ fn loop_forever<G: GUI>(
|
||||
// Don't draw if an event was ignored and we're not in Animation mode. Every keypress also
|
||||
// fires a release event, most of which are ignored.
|
||||
if any_input_used || !wait_for_events {
|
||||
if any_input_used {
|
||||
// But if the event caused a state-change, the drawing state might be different
|
||||
// too. Need to recalculate what menu entries and such are valid. So send through
|
||||
// a no-op event.
|
||||
let (new_state, _, _) = state.event(Event::NoOp, &prerender, &program);
|
||||
state = new_state;
|
||||
}
|
||||
|
||||
state.draw(&prerender.display, &program, &prerender, false);
|
||||
prerender.num_uploads.set(0);
|
||||
}
|
||||
|
@ -42,9 +42,13 @@ impl GUI for Game {
|
||||
// If we fall through, there's a new state that we need to wakeup.
|
||||
match transition {
|
||||
Transition::Keep => {
|
||||
self.ui.per_obj.assert_chosen_used();
|
||||
return EventLoopMode::InputOnly;
|
||||
}
|
||||
Transition::KeepWithMode(evmode) => return evmode,
|
||||
Transition::KeepWithMode(evmode) => {
|
||||
self.ui.per_obj.assert_chosen_used();
|
||||
return evmode;
|
||||
}
|
||||
Transition::Pop => {
|
||||
self.states.pop().unwrap().on_destroy(ctx, &mut self.ui);
|
||||
if self.states.is_empty() {
|
||||
@ -85,7 +89,9 @@ impl GUI for Game {
|
||||
}
|
||||
Transition::ApplyObjectAction(action) => {
|
||||
self.ui.per_obj.action_chosen(action);
|
||||
return EventLoopMode::InputOnly;
|
||||
// Immediately go trigger the action. Things'll break unless current_selection
|
||||
// remains the same, so DON'T redo mouseover.
|
||||
return ctx.no_op_event(false, |ctx| self.event(ctx));
|
||||
}
|
||||
Transition::PushTwice(s1, s2) => {
|
||||
self.states
|
||||
@ -94,6 +100,7 @@ impl GUI for Game {
|
||||
.on_suspend(ctx, &mut self.ui);
|
||||
self.states.push(s1);
|
||||
self.states.push(s2);
|
||||
self.ui.per_obj.assert_chosen_used();
|
||||
return EventLoopMode::InputOnly;
|
||||
}
|
||||
};
|
||||
@ -101,7 +108,7 @@ impl GUI for Game {
|
||||
// Let the new state initialize with a fake event. Usually these just return
|
||||
// Transition::Keep, but nothing stops them from doing whatever. (For example, entering
|
||||
// tutorial mode immediately pushes on a Warper.) So just recurse.
|
||||
ctx.fake_mouseover(|ctx| self.event(ctx))
|
||||
ctx.no_op_event(true, |ctx| self.event(ctx))
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx) {
|
||||
|
Loading…
Reference in New Issue
Block a user