mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 23:15:24 +03:00
Make SimpleApps all manage their own CLI parsing, so they can add their own overrides.
This commit is contained in:
parent
eda9ff20bd
commit
942c3ecdaf
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -1024,6 +1024,7 @@ dependencies = [
|
||||
"log",
|
||||
"map_gui",
|
||||
"map_model",
|
||||
"structopt",
|
||||
"wasm-bindgen",
|
||||
"widgetry",
|
||||
]
|
||||
@ -2137,6 +2138,7 @@ dependencies = [
|
||||
"maplit",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"structopt",
|
||||
"synthpop",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
@ -2777,6 +2779,7 @@ dependencies = [
|
||||
"getrandom",
|
||||
"map_gui",
|
||||
"map_model",
|
||||
"structopt",
|
||||
"wasm-bindgen",
|
||||
"widgetry",
|
||||
]
|
||||
@ -2865,6 +2868,7 @@ dependencies = [
|
||||
"map_gui",
|
||||
"map_model",
|
||||
"reqwest",
|
||||
"structopt",
|
||||
"widgetry",
|
||||
"xmltree",
|
||||
]
|
||||
|
@ -21,5 +21,6 @@ getrandom = { version = "0.2.3", optional = true }
|
||||
log = "0.4"
|
||||
map_gui = { path = "../map_gui" }
|
||||
map_model = { path = "../map_model" }
|
||||
structopt = "0.3.23"
|
||||
wasm-bindgen = { version = "0.2.70", optional = true }
|
||||
widgetry = { path = "../widgetry" }
|
||||
|
@ -1,5 +1,7 @@
|
||||
#![allow(clippy::type_complexity)]
|
||||
|
||||
use structopt::StructOpt;
|
||||
|
||||
use widgetry::Settings;
|
||||
|
||||
#[macro_use]
|
||||
@ -18,12 +20,15 @@ pub fn main() {
|
||||
}
|
||||
|
||||
fn run(mut settings: Settings) {
|
||||
let options = map_gui::options::Options::load_or_default();
|
||||
let mut options = map_gui::options::Options::load_or_default();
|
||||
let args = map_gui::SimpleAppArgs::from_iter(abstutil::cli_args());
|
||||
args.override_options(&mut options);
|
||||
|
||||
settings = settings
|
||||
.read_svg(Box::new(abstio::slurp_bytes))
|
||||
.canvas_settings(options.canvas_settings.clone());
|
||||
widgetry::run(settings, |ctx| {
|
||||
map_gui::SimpleApp::new(ctx, options, (), |ctx, app| {
|
||||
map_gui::SimpleApp::new(ctx, options, args.map_name(), args.cam, (), |ctx, app| {
|
||||
vec![
|
||||
map_gui::tools::TitleScreen::new_state(
|
||||
ctx,
|
||||
|
@ -32,6 +32,7 @@ serde_json = "1.0.61"
|
||||
synthpop = { path = "../synthpop" }
|
||||
wasm-bindgen = { version = "0.2.70", optional = true }
|
||||
widgetry = { path = "../widgetry" }
|
||||
structopt = "0.3.23"
|
||||
|
||||
[dependencies.web-sys]
|
||||
version = "0.3.47"
|
||||
|
@ -1,5 +1,7 @@
|
||||
#![allow(clippy::type_complexity)]
|
||||
|
||||
use structopt::StructOpt;
|
||||
|
||||
use widgetry::Settings;
|
||||
|
||||
pub use browse::BrowseNeighborhoods;
|
||||
@ -38,6 +40,9 @@ pub fn main() {
|
||||
fn run(mut settings: Settings) {
|
||||
let mut opts = map_gui::options::Options::load_or_default();
|
||||
opts.color_scheme = map_gui::colors::ColorSchemeChoice::DayMode;
|
||||
let args = map_gui::SimpleAppArgs::from_iter(abstutil::cli_args());
|
||||
args.override_options(&mut opts);
|
||||
|
||||
settings = settings
|
||||
.read_svg(Box::new(abstio::slurp_bytes))
|
||||
.canvas_settings(opts.canvas_settings.clone());
|
||||
@ -57,7 +62,7 @@ fn run(mut settings: Settings) {
|
||||
|
||||
current_trip_name: None,
|
||||
};
|
||||
map_gui::SimpleApp::new(ctx, opts, session, |ctx, app| {
|
||||
map_gui::SimpleApp::new(ctx, opts, args.map_name(), args.cam, session, |ctx, app| {
|
||||
vec![
|
||||
map_gui::tools::TitleScreen::new_state(
|
||||
ctx,
|
||||
|
@ -17,7 +17,7 @@ use map_model::{
|
||||
use sim::{AgentID, CarID, PedestrianID, Sim};
|
||||
use widgetry::{EventCtx, GfxCtx, State};
|
||||
|
||||
pub use self::simple_app::SimpleApp;
|
||||
pub use self::simple_app::{SimpleApp, SimpleAppArgs};
|
||||
use crate::render::DrawOptions;
|
||||
use colors::{ColorScheme, ColorSchemeChoice};
|
||||
use options::Options;
|
||||
|
@ -28,55 +28,47 @@ pub struct SimpleApp<T> {
|
||||
pub time: Time,
|
||||
}
|
||||
|
||||
// Don't give a name and description. If an app cares enough to override, they can't use SimpleApp
|
||||
// (or refactor to plumb through options themselves)
|
||||
// A SimpleApp can directly use this (`let args = SimpleAppArgs::from_iter(abstutil::cli_args())`)
|
||||
// or embed in their own struct and define other flags.
|
||||
#[derive(StructOpt)]
|
||||
struct Args {
|
||||
pub struct SimpleAppArgs {
|
||||
/// Path to a map to initially load. If not provided, load the last map used or a fixed
|
||||
/// default.
|
||||
#[structopt()]
|
||||
map_path: Option<String>,
|
||||
pub map_path: Option<String>,
|
||||
/// Initially position the camera here. The format is an OSM-style `zoom/lat/lon` string
|
||||
/// (https://wiki.openstreetmap.org/wiki/Browsing#Other_URL_tricks).
|
||||
#[structopt(long)]
|
||||
cam: Option<String>,
|
||||
pub cam: Option<String>,
|
||||
/// Dev mode exposes experimental tools useful for debugging, but that'd likely confuse most
|
||||
/// players.
|
||||
#[structopt(long)]
|
||||
dev: bool,
|
||||
pub dev: bool,
|
||||
/// The color scheme for map elements, agents, and the UI.
|
||||
#[structopt(long, parse(try_from_str = ColorSchemeChoice::parse))]
|
||||
color_scheme: Option<ColorSchemeChoice>,
|
||||
pub color_scheme: Option<ColorSchemeChoice>,
|
||||
/// When making a screen recording, enable this option to hide some UI elements
|
||||
#[structopt(long)]
|
||||
minimal_controls: bool,
|
||||
pub minimal_controls: bool,
|
||||
}
|
||||
|
||||
impl<T: 'static> SimpleApp<T> {
|
||||
pub fn new<
|
||||
F: 'static + Fn(&mut EventCtx, &mut SimpleApp<T>) -> Vec<Box<dyn State<SimpleApp<T>>>>,
|
||||
>(
|
||||
ctx: &mut EventCtx,
|
||||
mut opts: Options,
|
||||
session: T,
|
||||
init_states: F,
|
||||
) -> (SimpleApp<T>, Vec<Box<dyn State<SimpleApp<T>>>>) {
|
||||
abstutil::logger::setup();
|
||||
let args = Args::from_iter(abstutil::cli_args());
|
||||
// Options are passed in by each app, usually seeded with defaults or from a config file.
|
||||
// For the few options that we allow to be specified by command-line, overwrite the values.
|
||||
opts.dev = args.dev;
|
||||
opts.minimal_controls = args.minimal_controls;
|
||||
if let Some(cs) = args.color_scheme {
|
||||
impl SimpleAppArgs {
|
||||
/// Options are passed in by each app, usually seeded with defaults or from a config file. For
|
||||
/// the few options that we allow to be specified by command-line, overwrite the values.
|
||||
pub fn override_options(&self, opts: &mut Options) {
|
||||
opts.dev = self.dev;
|
||||
opts.minimal_controls = self.minimal_controls;
|
||||
if let Some(cs) = self.color_scheme {
|
||||
opts.color_scheme = cs;
|
||||
opts.toggle_day_night_colors = false;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.canvas.settings = opts.canvas_settings.clone();
|
||||
let map_name = args
|
||||
.map_path
|
||||
pub fn map_name(&self) -> MapName {
|
||||
self.map_path
|
||||
.as_ref()
|
||||
.map(|path| {
|
||||
MapName::from_path(&path).unwrap_or_else(|| panic!("bad map path: {}", path))
|
||||
MapName::from_path(path).unwrap_or_else(|| panic!("bad map path: {}", path))
|
||||
})
|
||||
.or_else(|| {
|
||||
abstio::maybe_read_json::<crate::tools::DefaultMap>(
|
||||
@ -86,7 +78,23 @@ impl<T: 'static> SimpleApp<T> {
|
||||
.ok()
|
||||
.map(|x| x.last_map)
|
||||
})
|
||||
.unwrap_or_else(|| MapName::seattle("montlake"));
|
||||
.unwrap_or_else(|| MapName::seattle("montlake"))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static> SimpleApp<T> {
|
||||
pub fn new<
|
||||
F: 'static + Fn(&mut EventCtx, &mut SimpleApp<T>) -> Vec<Box<dyn State<SimpleApp<T>>>>,
|
||||
>(
|
||||
ctx: &mut EventCtx,
|
||||
opts: Options,
|
||||
map_name: MapName,
|
||||
cam: Option<String>,
|
||||
session: T,
|
||||
init_states: F,
|
||||
) -> (SimpleApp<T>, Vec<Box<dyn State<SimpleApp<T>>>>) {
|
||||
abstutil::logger::setup();
|
||||
ctx.canvas.settings = opts.canvas_settings.clone();
|
||||
|
||||
let cs = ColorScheme::new(ctx, opts.color_scheme);
|
||||
// Start with a blank map
|
||||
@ -107,7 +115,7 @@ impl<T: 'static> SimpleApp<T> {
|
||||
&app,
|
||||
map_name,
|
||||
Box::new(move |ctx, app| {
|
||||
URLManager::change_camera(ctx, args.cam.as_ref(), app.map().get_gps_bounds());
|
||||
URLManager::change_camera(ctx, cam.as_ref(), app.map().get_gps_bounds());
|
||||
Transition::Clear(init_states(ctx, app))
|
||||
}),
|
||||
)];
|
||||
|
@ -18,5 +18,6 @@ geom = { path = "../geom" }
|
||||
getrandom = { version = "0.2.3", optional = true }
|
||||
map_gui = { path = "../map_gui" }
|
||||
map_model = { path = "../map_model" }
|
||||
structopt = "0.3.23"
|
||||
wasm-bindgen = { version = "0.2.70", optional = true }
|
||||
widgetry = { path = "../widgetry" }
|
||||
|
@ -1,5 +1,7 @@
|
||||
mod viewer;
|
||||
|
||||
use structopt::StructOpt;
|
||||
|
||||
use widgetry::Settings;
|
||||
|
||||
pub fn main() {
|
||||
@ -8,13 +10,16 @@ pub fn main() {
|
||||
}
|
||||
|
||||
pub fn run(mut settings: Settings) {
|
||||
let mut options = map_gui::options::Options::load_or_default();
|
||||
options.show_building_driveways = false;
|
||||
let mut opts = map_gui::options::Options::load_or_default();
|
||||
opts.show_building_driveways = false;
|
||||
let args = map_gui::SimpleAppArgs::from_iter(abstutil::cli_args());
|
||||
args.override_options(&mut opts);
|
||||
|
||||
settings = settings
|
||||
.read_svg(Box::new(abstio::slurp_bytes))
|
||||
.canvas_settings(options.canvas_settings.clone());
|
||||
.canvas_settings(opts.canvas_settings.clone());
|
||||
widgetry::run(settings, |ctx| {
|
||||
map_gui::SimpleApp::new(ctx, options, (), |ctx, app| {
|
||||
map_gui::SimpleApp::new(ctx, opts, args.map_name(), args.cam, (), |ctx, app| {
|
||||
vec![
|
||||
map_gui::tools::TitleScreen::new_state(
|
||||
ctx,
|
||||
|
@ -17,5 +17,6 @@ log = "0.4.14"
|
||||
map_gui = { path = "../map_gui" }
|
||||
map_model = { path = "../map_model" }
|
||||
reqwest = { version = "0.11.0", optional = true, default-features=false, features=["blocking", "rustls-tls"] }
|
||||
structopt = "0.3.23"
|
||||
widgetry = { path = "../widgetry" }
|
||||
xmltree = "0.10.1"
|
||||
|
@ -1,16 +1,21 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
use structopt::StructOpt;
|
||||
|
||||
mod mapper;
|
||||
|
||||
fn main() {
|
||||
let mut options = map_gui::options::Options::load_or_default();
|
||||
options.canvas_settings.min_zoom_for_detail = 2.0;
|
||||
let args = map_gui::SimpleAppArgs::from_iter(abstutil::cli_args());
|
||||
args.override_options(&mut options);
|
||||
|
||||
let settings = widgetry::Settings::new("OSM parking mapper")
|
||||
.read_svg(Box::new(abstio::slurp_bytes))
|
||||
.canvas_settings(options.canvas_settings.clone());
|
||||
widgetry::run(settings, |ctx| {
|
||||
map_gui::SimpleApp::new(ctx, options, (), |ctx, app| {
|
||||
map_gui::SimpleApp::new(ctx, options, args.map_name(), args.cam, (), |ctx, app| {
|
||||
vec![
|
||||
map_gui::tools::TitleScreen::new_state(
|
||||
ctx,
|
||||
|
@ -30,6 +30,8 @@ pub fn main() {
|
||||
fn run(mut settings: Settings) {
|
||||
let mut opts = map_gui::options::Options::load_or_default();
|
||||
opts.color_scheme = map_gui::colors::ColorSchemeChoice::NightMode;
|
||||
// Note we don't take any CLI arguments at all. Always start on the first level's map
|
||||
|
||||
settings = settings
|
||||
.read_svg(Box::new(abstio::slurp_bytes))
|
||||
.canvas_settings(opts.canvas_settings.clone());
|
||||
@ -37,23 +39,31 @@ fn run(mut settings: Settings) {
|
||||
let session = session::Session::load();
|
||||
session.save();
|
||||
|
||||
map_gui::SimpleApp::new(ctx, opts, session, |ctx, app| {
|
||||
if app.opts.dev {
|
||||
app.session.unlock_all();
|
||||
}
|
||||
app.session.music = music::Music::start(ctx, app.session.play_music, "jingle_bells");
|
||||
app.session.music.specify_volume(music::OUT_OF_GAME);
|
||||
map_gui::SimpleApp::new(
|
||||
ctx,
|
||||
opts,
|
||||
abstio::MapName::seattle("qa"),
|
||||
None,
|
||||
session,
|
||||
|ctx, app| {
|
||||
if app.opts.dev {
|
||||
app.session.unlock_all();
|
||||
}
|
||||
app.session.music =
|
||||
music::Music::start(ctx, app.session.play_music, "jingle_bells");
|
||||
app.session.music.specify_volume(music::OUT_OF_GAME);
|
||||
|
||||
vec![
|
||||
map_gui::tools::TitleScreen::new_state(
|
||||
ctx,
|
||||
app,
|
||||
map_gui::tools::Executable::Santa,
|
||||
Box::new(|ctx, app, _| title::TitleScreen::new_state(ctx, app)),
|
||||
),
|
||||
title::TitleScreen::new_state(ctx, app),
|
||||
]
|
||||
})
|
||||
vec![
|
||||
map_gui::tools::TitleScreen::new_state(
|
||||
ctx,
|
||||
app,
|
||||
map_gui::tools::Executable::Santa,
|
||||
Box::new(|ctx, app, _| title::TitleScreen::new_state(ctx, app)),
|
||||
),
|
||||
title::TitleScreen::new_state(ctx, app),
|
||||
]
|
||||
},
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user