mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 12:12:00 +03:00
porting the last two plugins to generic event()
This commit is contained in:
parent
52535771e3
commit
b57a4335e0
@ -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";
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
114
editor/src/ui.rs
114
editor/src/ui.rs
@ -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>,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user