mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-27 16:36:02 +03:00
brief interruption to plumb primary_plugins to plugins that need it in a different way outside the ctx, to avoid annoying borrow issues
This commit is contained in:
parent
7aed6fa690
commit
8913ea44e3
@ -584,15 +584,15 @@ Plugin styles are blocking or ambient. And some can conflict...
|
||||
|
||||
|
||||
|
||||
- probably dont need all those methods in UIState. just a way to get the main state.
|
||||
- dont recreate PluginCtx so many times? changing plugin API or something should help.
|
||||
|
||||
- probably change Plugin APIs... ambient_event and one event() indicating done or not. dont express blockingness in that API.
|
||||
- actually, take away Plugin trait entirely? Except for the stuff that gets all boxed up?
|
||||
- can we somehow fold PluginsPerMap into PerMapUI? :D different API that doesnt blindly pass in all of primary field
|
||||
- Layers could be stackable modal too, but do that later. low-pri.
|
||||
- probably dont need all those methods in UIState. just a way to get the main state.
|
||||
- dont recreate PluginCtx so many times? changing plugin API or something should help.
|
||||
- bulk-disable debug mode stuff in tutorial land. should be easy now!
|
||||
- layers
|
||||
- some exclusive stuff
|
||||
- hider
|
||||
- top and modal menus
|
||||
= top and modal menus
|
||||
|
@ -20,7 +20,11 @@ impl ABTestManager {
|
||||
}
|
||||
|
||||
impl Plugin for ABTestManager {
|
||||
fn blocking_event(&mut self, ctx: &mut PluginCtx) -> bool {
|
||||
fn blocking_event_with_plugins(
|
||||
&mut self,
|
||||
ctx: &mut PluginCtx,
|
||||
primary_plugins: &mut PluginsPerMap,
|
||||
) -> bool {
|
||||
match self {
|
||||
ABTestManager::PickABTest(ref mut wizard) => {
|
||||
if let Some(ab_test) =
|
||||
@ -42,9 +46,7 @@ impl Plugin for ABTestManager {
|
||||
let ((new_primary, new_primary_plugins), new_secondary) =
|
||||
launch_test(test, &ctx.primary.current_flags);
|
||||
*ctx.primary = new_primary;
|
||||
if let Some(p_plugins) = ctx.primary_plugins.as_mut() {
|
||||
**p_plugins = new_primary_plugins;
|
||||
}
|
||||
*primary_plugins = new_primary_plugins;
|
||||
*ctx.secondary = Some(new_secondary);
|
||||
return false;
|
||||
}
|
||||
|
@ -21,7 +21,11 @@ impl EditsManager {
|
||||
}
|
||||
|
||||
impl Plugin for EditsManager {
|
||||
fn blocking_event(&mut self, ctx: &mut PluginCtx) -> bool {
|
||||
fn blocking_event_with_plugins(
|
||||
&mut self,
|
||||
ctx: &mut PluginCtx,
|
||||
primary_plugins: &mut PluginsPerMap,
|
||||
) -> bool {
|
||||
let mut new_primary: Option<(PerMapUI, PluginsPerMap)> = None;
|
||||
|
||||
if manage_edits(
|
||||
@ -34,9 +38,7 @@ impl Plugin for EditsManager {
|
||||
{
|
||||
if let Some((p, plugins)) = new_primary {
|
||||
*ctx.primary = p;
|
||||
if let Some(p_plugins) = ctx.primary_plugins.as_mut() {
|
||||
**p_plugins = plugins;
|
||||
}
|
||||
*primary_plugins = plugins;
|
||||
}
|
||||
false
|
||||
} else {
|
||||
|
@ -26,6 +26,14 @@ pub trait Plugin: Any {
|
||||
fn blocking_event(&mut self, _ctx: &mut PluginCtx) -> bool {
|
||||
false
|
||||
}
|
||||
fn blocking_event_with_plugins(
|
||||
&mut self,
|
||||
ctx: &mut PluginCtx,
|
||||
_plugins: &mut PluginsPerMap,
|
||||
) -> bool {
|
||||
// By default, redirect to the other one.
|
||||
self.blocking_event(ctx)
|
||||
}
|
||||
|
||||
// True means active; false means done, please destroy.
|
||||
fn nonblocking_event(&mut self, _ctx: &mut PluginCtx) -> bool {
|
||||
@ -33,6 +41,7 @@ pub trait Plugin: Any {
|
||||
}
|
||||
|
||||
fn ambient_event(&mut self, _ctx: &mut PluginCtx) {}
|
||||
fn ambient_event_with_plugins(&mut self, _ctx: &mut PluginCtx, _plugins: &mut PluginsPerMap) {}
|
||||
}
|
||||
|
||||
downcast!(Plugin);
|
||||
@ -40,8 +49,6 @@ downcast!(Plugin);
|
||||
// This mirrors many, but not all, of the fields in UI.
|
||||
pub struct PluginCtx<'a> {
|
||||
pub primary: &'a mut PerMapUI,
|
||||
// Only filled out in a few cases.
|
||||
pub primary_plugins: Option<&'a mut PluginsPerMap>,
|
||||
pub secondary: &'a mut Option<(PerMapUI, PluginsPerMap)>,
|
||||
pub canvas: &'a mut Canvas,
|
||||
pub cs: &'a mut ColorScheme,
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::plugins::{Plugin, PluginCtx};
|
||||
use crate::state::PluginsPerMap;
|
||||
use abstutil::elapsed_seconds;
|
||||
use ezgui::EventLoopMode;
|
||||
use sim::{Benchmark, Event, Sim, Tick, TIMESTEP};
|
||||
@ -54,7 +55,11 @@ impl SimControls {
|
||||
}
|
||||
|
||||
impl Plugin for SimControls {
|
||||
fn ambient_event(&mut self, ctx: &mut PluginCtx) {
|
||||
fn ambient_event_with_plugins(
|
||||
&mut self,
|
||||
ctx: &mut PluginCtx,
|
||||
primary_plugins: &mut PluginsPerMap,
|
||||
) {
|
||||
if ctx.input.action_chosen("slow down sim") {
|
||||
self.desired_speed -= ADJUST_SPEED;
|
||||
self.desired_speed = self.desired_speed.max(0.0);
|
||||
@ -66,11 +71,9 @@ impl Plugin for SimControls {
|
||||
if ctx.secondary.is_some() && ctx.input.action_chosen("swap the primary/secondary sim") {
|
||||
info!("Swapping primary/secondary sim");
|
||||
// Check out this cool little trick. :D
|
||||
let primary_plugins = ctx.primary_plugins.take().unwrap();
|
||||
let (mut secondary, mut secondary_plugins) = ctx.secondary.take().unwrap();
|
||||
mem::swap(ctx.primary, &mut secondary);
|
||||
mem::swap(primary_plugins, &mut secondary_plugins);
|
||||
ctx.primary_plugins = Some(primary_plugins);
|
||||
*ctx.secondary = Some((secondary, secondary_plugins));
|
||||
*ctx.recalculate_current_selection = true;
|
||||
// TODO Only one consumer of primary_events right now and they don't care, but this
|
||||
|
@ -108,7 +108,6 @@ impl UIState for DefaultUIState {
|
||||
{
|
||||
let mut ctx = PluginCtx {
|
||||
primary: &mut self.primary,
|
||||
primary_plugins: None,
|
||||
secondary: &mut self.secondary,
|
||||
canvas,
|
||||
cs,
|
||||
@ -142,13 +141,12 @@ impl UIState for DefaultUIState {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.primary_plugins = Some(&mut self.primary_plugins);
|
||||
if self.exclusive_blocking_plugin.is_some() {
|
||||
if !self
|
||||
.exclusive_blocking_plugin
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.blocking_event(&mut ctx)
|
||||
.blocking_event_with_plugins(&mut ctx, &mut self.primary_plugins)
|
||||
{
|
||||
self.exclusive_blocking_plugin = None;
|
||||
}
|
||||
@ -216,7 +214,6 @@ impl UIState for DefaultUIState {
|
||||
{
|
||||
let mut ctx = PluginCtx {
|
||||
primary: &mut self.primary,
|
||||
primary_plugins: None,
|
||||
secondary: &mut self.secondary,
|
||||
canvas,
|
||||
cs,
|
||||
@ -248,7 +245,6 @@ impl UIState for DefaultUIState {
|
||||
// Stackable modal plugins
|
||||
let mut ctx = PluginCtx {
|
||||
primary: &mut self.primary,
|
||||
primary_plugins: None,
|
||||
secondary: &mut self.secondary,
|
||||
canvas,
|
||||
cs,
|
||||
@ -304,15 +300,12 @@ impl UIState for DefaultUIState {
|
||||
}
|
||||
}
|
||||
|
||||
// Ambient plugins. Do the primary_plugins group first, since we later borrow the plugins
|
||||
// for sim_controls.
|
||||
// Ambient plugins
|
||||
self.sim_controls
|
||||
.ambient_event_with_plugins(&mut ctx, &mut self.primary_plugins);
|
||||
for p in self.primary_plugins.ambient_plugins.iter_mut() {
|
||||
p.ambient_event(&mut ctx);
|
||||
}
|
||||
{
|
||||
ctx.primary_plugins = Some(&mut self.primary_plugins);
|
||||
self.sim_controls.ambient_event(&mut ctx);
|
||||
}
|
||||
if self.enable_debug_controls {
|
||||
self.layers.ambient_event(&mut ctx);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user