porting the last two plugins to generic event()

This commit is contained in:
Dustin Carlino 2018-10-22 08:42:09 -07:00
parent 52535771e3
commit b57a4335e0
5 changed files with 152 additions and 181 deletions

View File

@ -1,9 +1,8 @@
use ezgui::{Canvas, GfxCtx, LogScroller, UserInput, Wizard, WrappedWizard};
use ezgui::{Canvas, GfxCtx, LogScroller, Wizard, WrappedWizard};
use map_model::Map;
use objects::ID;
use objects::SIM_SETUP;
use piston::input::Key;
use plugins::{choose_edits, choose_scenario, load_ab_test, Colorizer};
use plugins::{choose_edits, choose_scenario, load_ab_test, Colorizer, PluginCtx};
use sim::{ABTest, SimFlags};
use ui::{PerMapUI, PluginsPerMap};
@ -18,56 +17,6 @@ impl ABTestManager {
ABTestManager::Inactive
}
// May return a new primary and secondary UI
pub fn event(
&mut self,
input: &mut UserInput,
selected: Option<ID>,
map: &Map,
kml: &Option<String>,
current_flags: &SimFlags,
) -> (
bool,
Option<((PerMapUI, PluginsPerMap), (PerMapUI, PluginsPerMap))>,
) {
let mut new_ui: Option<((PerMapUI, PluginsPerMap), (PerMapUI, PluginsPerMap))> = None;
let mut new_state: Option<ABTestManager> = None;
match self {
ABTestManager::Inactive => {
if selected.is_none()
&& input.unimportant_key_pressed(Key::B, SIM_SETUP, "manage A/B tests")
{
new_state = Some(ABTestManager::PickABTest(Wizard::new()));
}
}
ABTestManager::PickABTest(ref mut wizard) => {
if let Some(ab_test) = pick_ab_test(map, wizard.wrap(input)) {
let scroller = LogScroller::new_from_lines(ab_test.describe());
new_state = Some(ABTestManager::ManageABTest(ab_test, scroller));
} else if wizard.aborted() {
new_state = Some(ABTestManager::Inactive);
}
}
ABTestManager::ManageABTest(test, ref mut scroller) => {
if input.key_pressed(Key::R, "run this A/B test") {
new_ui = Some(launch_test(test, kml, current_flags));
new_state = Some(ABTestManager::Inactive);
}
if scroller.event(input) {
new_state = Some(ABTestManager::Inactive);
}
}
}
if let Some(s) = new_state {
*self = s;
}
let active = match self {
ABTestManager::Inactive => false,
_ => true,
};
(active, new_ui)
}
pub fn draw(&self, g: &mut GfxCtx, canvas: &Canvas) {
match self {
ABTestManager::Inactive => {}
@ -81,7 +30,53 @@ impl ABTestManager {
}
}
impl Colorizer for ABTestManager {}
impl Colorizer for ABTestManager {
// May return a new primary and secondary UI
fn event(&mut self, ctx: PluginCtx) -> bool {
let selected = ctx.primary.current_selection;
let mut new_state: Option<ABTestManager> = None;
match self {
ABTestManager::Inactive => {
if selected.is_none() && ctx.input.unimportant_key_pressed(
Key::B,
SIM_SETUP,
"manage A/B tests",
) {
new_state = Some(ABTestManager::PickABTest(Wizard::new()));
}
}
ABTestManager::PickABTest(ref mut wizard) => {
if let Some(ab_test) = pick_ab_test(&ctx.primary.map, wizard.wrap(ctx.input)) {
let scroller = LogScroller::new_from_lines(ab_test.describe());
new_state = Some(ABTestManager::ManageABTest(ab_test, scroller));
} else if wizard.aborted() {
new_state = Some(ABTestManager::Inactive);
}
}
ABTestManager::ManageABTest(test, ref mut scroller) => {
if ctx.input.key_pressed(Key::R, "run this A/B test") {
let ((new_primary, new_primary_plugins), new_secondary) =
launch_test(test, ctx.kml, &ctx.primary.current_flags);
*ctx.primary = new_primary;
*ctx.new_primary_plugins = Some(new_primary_plugins);
*ctx.secondary = Some(new_secondary);
new_state = Some(ABTestManager::Inactive);
}
if scroller.event(ctx.input) {
new_state = Some(ABTestManager::Inactive);
}
}
}
if let Some(s) = new_state {
*self = s;
}
match self {
ABTestManager::Inactive => false,
_ => true,
}
}
}
fn pick_ab_test(map: &Map, mut wizard: WrappedWizard) -> Option<ABTest> {
let load_existing = "Load existing A/B test";

View File

@ -30,7 +30,15 @@ impl DisplayLogs {
DisplayLogs { active: false }
}
pub fn event(&mut self, ctx: PluginCtx) -> bool {
pub fn draw(&self, g: &mut GfxCtx, canvas: &Canvas) {
if self.active {
LOGGER.lock().unwrap().draw(g, canvas);
}
}
}
impl Colorizer for DisplayLogs {
fn event(&mut self, ctx: PluginCtx) -> bool {
if !self.active {
if ctx
.input
@ -48,16 +56,8 @@ impl DisplayLogs {
}
self.active
}
pub fn draw(&self, g: &mut GfxCtx, canvas: &Canvas) {
if self.active {
LOGGER.lock().unwrap().draw(g, canvas);
}
}
}
impl Colorizer for DisplayLogs {}
struct LogAdapter;
impl Log for LogAdapter {

View File

@ -1,9 +1,9 @@
use control::ControlMap;
use ezgui::{Canvas, GfxCtx, UserInput, Wizard, WrappedWizard};
use ezgui::{Canvas, GfxCtx, Wizard, WrappedWizard};
use map_model::Map;
use objects::SIM_SETUP;
use piston::input::Key;
use plugins::{choose_edits, Colorizer};
use plugins::{choose_edits, Colorizer, PluginCtx};
use sim::{MapEdits, SimFlags};
use ui::{PerMapUI, PluginsPerMap};
@ -17,49 +17,6 @@ impl EditsManager {
EditsManager::Inactive
}
// May return a new PerMapUI to replace the current primary.
pub fn event(
&mut self,
input: &mut UserInput,
map: &Map,
control_map: &ControlMap,
current_flags: &mut SimFlags,
kml: &Option<String>,
) -> (bool, Option<(PerMapUI, PluginsPerMap)>) {
let mut new_primary: Option<(PerMapUI, PluginsPerMap)> = None;
let mut new_state: Option<EditsManager> = None;
match self {
EditsManager::Inactive => {
if input.unimportant_key_pressed(Key::Q, SIM_SETUP, "manage map edits") {
new_state = Some(EditsManager::ManageEdits(Wizard::new()));
}
}
EditsManager::ManageEdits(ref mut wizard) => {
if manage_edits(
current_flags,
map,
control_map,
&mut new_primary,
kml,
wizard.wrap(input),
).is_some()
{
new_state = Some(EditsManager::Inactive);
} else if wizard.aborted() {
new_state = Some(EditsManager::Inactive);
}
}
}
if let Some(s) = new_state {
*self = s;
}
let active = match self {
EditsManager::Inactive => false,
_ => true,
};
(active, new_primary)
}
pub fn draw(&self, g: &mut GfxCtx, canvas: &Canvas) {
match self {
EditsManager::ManageEdits(ref wizard) => {
@ -70,14 +27,56 @@ impl EditsManager {
}
}
impl Colorizer for EditsManager {}
impl Colorizer for EditsManager {
fn event(&mut self, ctx: PluginCtx) -> bool {
let mut new_state: Option<EditsManager> = None;
match self {
EditsManager::Inactive => {
if ctx
.input
.unimportant_key_pressed(Key::Q, SIM_SETUP, "manage map edits")
{
new_state = Some(EditsManager::ManageEdits(Wizard::new()));
}
}
EditsManager::ManageEdits(ref mut wizard) => {
let mut new_primary: Option<(PerMapUI, PluginsPerMap)> = None;
if manage_edits(
&mut ctx.primary.current_flags,
&ctx.primary.map,
&ctx.primary.control_map,
ctx.kml,
&mut new_primary,
wizard.wrap(ctx.input),
).is_some()
{
new_state = Some(EditsManager::Inactive);
} else if wizard.aborted() {
new_state = Some(EditsManager::Inactive);
}
if let Some((p, plugins)) = new_primary {
*ctx.primary = p;
*ctx.new_primary_plugins = Some(plugins);
}
}
}
if let Some(s) = new_state {
*self = s;
}
match self {
EditsManager::Inactive => false,
_ => true,
}
}
}
fn manage_edits(
current_flags: &mut SimFlags,
map: &Map,
control_map: &ControlMap,
new_primary: &mut Option<(PerMapUI, PluginsPerMap)>,
kml: &Option<String>,
new_primary: &mut Option<(PerMapUI, PluginsPerMap)>,
mut wizard: WrappedWizard,
) -> Option<()> {
// TODO Indicate how many edits are there / if there are any unsaved edits

View File

@ -36,10 +36,7 @@ pub trait Colorizer {
None
}
// TODO remove default impl
fn event(&mut self, ctx: PluginCtx) -> bool {
false
}
fn event(&mut self, ctx: PluginCtx) -> bool;
}
// TODO Further refactoring should be done, but at least group these here to start.

View File

@ -231,7 +231,7 @@ pub struct PerMapUI {
pub current_selection: Option<ID>,
pub recalculate_current_selection: bool,
current_flags: SimFlags,
pub current_flags: SimFlags,
}
pub struct PluginsPerMap {
@ -347,38 +347,6 @@ impl UI {
cs: ColorScheme::load("color_scheme").unwrap(),
kml,
/*plugin_handlers: vec![
Box::new(|ctx| {
let (active, new_primary) = ctx.primary_plugins.edits_manager.event(
ctx.input,
&ctx.primary.map,
&ctx.primary.control_map,
&ctx.primary_plugins.road_editor,
&mut ctx.primary.current_flags,
ctx.kml,
);
if let Some((state, plugins)) = new_primary {
*ctx.primary = state;
*ctx.primary_plugins = plugins;
}
active
}),
Box::new(|ctx| {
let (active, new_ui) = ctx.plugins.ab_test_manager.event(
ctx.input,
ctx.primary.current_selection,
&ctx.primary.map,
ctx.kml,
&ctx.primary.current_flags,
);
if let Some(((new_primary, new_primary_plugins), new_secondary)) = new_ui {
*ctx.primary = new_primary;
*ctx.primary_plugins = new_primary_plugins;
*ctx.secondary = Some(new_secondary);
}
active
}),
],*/
};
match abstutil::read_json::<EditorState>("editor_state") {
@ -480,42 +448,50 @@ impl UI {
}
fn run_plugin(&mut self, idx: usize, input: &mut UserInput, osd: &mut Text) -> bool {
let ctx = PluginCtx {
primary: &mut self.primary,
secondary: &mut self.secondary,
canvas: &mut self.canvas,
cs: &mut self.cs,
input,
osd,
kml: &self.kml,
let mut new_primary_plugins: Option<PluginsPerMap> = None;
let active = {
let ctx = PluginCtx {
primary: &mut self.primary,
secondary: &mut self.secondary,
canvas: &mut self.canvas,
cs: &mut self.cs,
input,
osd,
kml: &self.kml,
new_primary_plugins: &mut new_primary_plugins,
};
match idx {
0 => self.plugins.layers.event(ctx),
1 => self.primary_plugins.traffic_signal_editor.event(ctx),
2 => self.primary_plugins.stop_sign_editor.event(ctx),
3 => self.plugins.road_editor.event(ctx),
4 => self.plugins.search_state.event(ctx),
5 => self.plugins.warp.event(ctx),
6 => self.primary_plugins.follow.event(ctx),
7 => self.primary_plugins.show_route.event(ctx),
8 => self.plugins.color_picker.event(ctx),
9 => self.primary_plugins.steepness_viz.event(ctx),
10 => self.plugins.osm_classifier.event(ctx),
11 => self.primary_plugins.hider.event(ctx),
12 => self.primary_plugins.debug_objects.event(ctx),
13 => self.primary_plugins.floodfiller.event(ctx),
14 => self.primary_plugins.geom_validator.event(ctx),
15 => self.primary_plugins.turn_cycler.event(ctx),
16 => self.primary_plugins.draw_neighborhoods.event(ctx),
17 => self.primary_plugins.scenarios.event(ctx),
18 => self.primary_plugins.chokepoints.event(ctx),
19 => self.plugins.logs.event(ctx),
20 => self.plugins.diff_worlds.event(ctx),
21 => self.primary_plugins.show_owner.event(ctx),
22 => self.primary_plugins.edits_manager.event(ctx),
23 => self.plugins.ab_test_manager.event(ctx),
_ => panic!("Plugin {} is too high", idx),
}
};
match idx {
0 => self.plugins.layers.event(ctx),
1 => self.primary_plugins.traffic_signal_editor.event(ctx),
2 => self.primary_plugins.stop_sign_editor.event(ctx),
3 => self.plugins.road_editor.event(ctx),
4 => self.plugins.search_state.event(ctx),
5 => self.plugins.warp.event(ctx),
6 => self.primary_plugins.follow.event(ctx),
7 => self.primary_plugins.show_route.event(ctx),
8 => self.plugins.color_picker.event(ctx),
9 => self.primary_plugins.steepness_viz.event(ctx),
10 => self.plugins.osm_classifier.event(ctx),
11 => self.primary_plugins.hider.event(ctx),
12 => self.primary_plugins.debug_objects.event(ctx),
13 => self.primary_plugins.floodfiller.event(ctx),
14 => self.primary_plugins.geom_validator.event(ctx),
15 => self.primary_plugins.turn_cycler.event(ctx),
16 => self.primary_plugins.draw_neighborhoods.event(ctx),
17 => self.primary_plugins.scenarios.event(ctx),
18 => self.primary_plugins.chokepoints.event(ctx),
19 => self.plugins.logs.event(ctx),
20 => self.plugins.diff_worlds.event(ctx),
21 => self.primary_plugins.show_owner.event(ctx),
/*22 => self.primary_plugins.edits_manager.event(ctx),
23 => self.plugins.ab_test_manager.event(ctx),*/
_ => panic!("Plugin {} is too high", idx),
if let Some(new_plugins) = new_primary_plugins {
self.primary_plugins = new_plugins;
}
active
}
}
@ -551,4 +527,8 @@ pub struct PluginCtx<'a> {
pub input: &'a mut UserInput,
pub osd: &'a mut Text,
pub kml: &'a Option<String>,
// Unfortunately we have to use an output parameter here, but it's pretty isolated to
// run_plugin
pub new_primary_plugins: &'a mut Option<PluginsPerMap>,
}