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:
Dustin Carlino 2018-12-24 18:33:07 -08:00
parent 7aed6fa690
commit 8913ea44e3
6 changed files with 34 additions and 27 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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 {

View File

@ -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,

View File

@ -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

View File

@ -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);
}