mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 03:35:51 +03:00
make Timer methods and ModalMenu take &str or String
This commit is contained in:
parent
1542e237d9
commit
dc2cc81249
@ -41,18 +41,18 @@ pub fn maybe_read_json<T: DeserializeOwned>(path: String, timer: &mut Timer) ->
|
||||
panic!("read_json needs {} to end with .json or .geojson", path);
|
||||
}
|
||||
|
||||
timer.start(&format!("parse {}", path));
|
||||
timer.start(format!("parse {}", path));
|
||||
// TODO timer.read_file isn't working here. And we need to call stop() if there's no file.
|
||||
match File::open(&path) {
|
||||
Ok(mut file) => {
|
||||
let mut contents = String::new();
|
||||
file.read_to_string(&mut contents)?;
|
||||
let obj: T = serde_json::from_str(&contents)?;
|
||||
timer.stop(&format!("parse {}", path));
|
||||
timer.stop(format!("parse {}", path));
|
||||
Ok(obj)
|
||||
}
|
||||
Err(e) => {
|
||||
timer.stop(&format!("parse {}", path));
|
||||
timer.stop(format!("parse {}", path));
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
@ -182,7 +182,7 @@ pub fn list_all_objects(dir: String) -> Vec<String> {
|
||||
// Load all serialized things from a directory, return sorted by name, with file extension removed.
|
||||
// Detects JSON or binary.
|
||||
pub fn load_all_objects<T: DeserializeOwned>(dir: String) -> Vec<(String, T)> {
|
||||
let mut timer = Timer::new(&format!("load_all_objects from {}", dir));
|
||||
let mut timer = Timer::new(format!("load_all_objects from {}", dir));
|
||||
let mut tree: BTreeMap<String, T> = BTreeMap::new();
|
||||
match std::fs::read_dir(&dir) {
|
||||
Ok(iter) => {
|
||||
|
@ -19,9 +19,9 @@ struct Progress {
|
||||
}
|
||||
|
||||
impl Progress {
|
||||
fn new(label: &str, total_items: usize) -> Progress {
|
||||
fn new(label: String, total_items: usize) -> Progress {
|
||||
Progress {
|
||||
label: label.to_string(),
|
||||
label,
|
||||
processed_items: 0,
|
||||
total_items,
|
||||
started_at: Instant::now(),
|
||||
@ -120,11 +120,12 @@ struct TimerSpan {
|
||||
}
|
||||
|
||||
impl<'a> Timer<'a> {
|
||||
pub fn new(name: &str) -> Timer<'a> {
|
||||
pub fn new<S: Into<String>>(raw_name: S) -> Timer<'a> {
|
||||
let name = raw_name.into();
|
||||
let mut t = Timer {
|
||||
results: Vec::new(),
|
||||
stack: Vec::new(),
|
||||
outermost_name: name.to_string(),
|
||||
outermost_name: name.clone(),
|
||||
notes: Vec::new(),
|
||||
warnings: Vec::new(),
|
||||
sink: None,
|
||||
@ -175,24 +176,26 @@ impl<'a> Timer<'a> {
|
||||
// Used to end the scope of a timer early.
|
||||
pub fn done(self) {}
|
||||
|
||||
pub fn start(&mut self, name: &str) {
|
||||
pub fn start<S: Into<String>>(&mut self, raw_name: S) {
|
||||
if self.outermost_name == "throwaway" {
|
||||
return;
|
||||
}
|
||||
|
||||
let name = raw_name.into();
|
||||
self.println(format!("{}...", name));
|
||||
self.stack.push(StackEntry::TimerSpan(TimerSpan {
|
||||
name: name.to_string(),
|
||||
name,
|
||||
started_at: Instant::now(),
|
||||
nested_results: Vec::new(),
|
||||
nested_time: 0.0,
|
||||
}));
|
||||
}
|
||||
|
||||
pub fn stop(&mut self, name: &str) {
|
||||
pub fn stop<S: Into<String>>(&mut self, raw_name: S) {
|
||||
if self.outermost_name == "throwaway" {
|
||||
return;
|
||||
}
|
||||
let name = raw_name.into();
|
||||
|
||||
let span = match self.stack.pop().unwrap() {
|
||||
StackEntry::TimerSpan(s) => s,
|
||||
@ -246,13 +249,14 @@ impl<'a> Timer<'a> {
|
||||
self.println(line);
|
||||
}
|
||||
|
||||
pub fn start_iter(&mut self, name: &str, total_items: usize) {
|
||||
pub fn start_iter<S: Into<String>>(&mut self, raw_name: S, total_items: usize) {
|
||||
if self.outermost_name == "throwaway" {
|
||||
return;
|
||||
}
|
||||
if total_items == 0 {
|
||||
return;
|
||||
}
|
||||
let name = raw_name.into();
|
||||
if let Some(StackEntry::Progress(p)) = self.stack.last() {
|
||||
panic!(
|
||||
"Can't start_iter({}) while Progress({}) is top of the stack",
|
||||
|
@ -15,7 +15,7 @@ fn main() {
|
||||
};
|
||||
args.done();
|
||||
|
||||
let mut timer = abstutil::Timer::new(&format!("generate {}", flags.output));
|
||||
let mut timer = abstutil::Timer::new(format!("generate {}", flags.output));
|
||||
let map = convert(&flags, &mut timer);
|
||||
timer.start("saving map");
|
||||
abstutil::write_binary(flags.output, &map);
|
||||
|
@ -21,20 +21,21 @@ pub struct EventCtx<'a> {
|
||||
}
|
||||
|
||||
impl<'a> EventCtx<'a> {
|
||||
pub fn loading_screen<O, F: FnOnce(&mut EventCtx, &mut Timer) -> O>(
|
||||
pub fn loading_screen<O, S: Into<String>, F: FnOnce(&mut EventCtx, &mut Timer) -> O>(
|
||||
&mut self,
|
||||
timer_name: &str,
|
||||
raw_timer_name: S,
|
||||
f: F,
|
||||
) -> O {
|
||||
let timer_name = raw_timer_name.into();
|
||||
let mut timer = Timer::new_with_sink(
|
||||
timer_name,
|
||||
&timer_name,
|
||||
Box::new(LoadingScreen::new(
|
||||
self.prerender,
|
||||
self.program,
|
||||
self.assets,
|
||||
self.canvas.window_width,
|
||||
self.canvas.window_height,
|
||||
timer_name.to_string(),
|
||||
timer_name.clone(),
|
||||
)),
|
||||
);
|
||||
f(self, &mut timer)
|
||||
|
@ -118,7 +118,7 @@ fn make_load_savestate(ab_test: ABTest) -> Box<dyn State> {
|
||||
|
||||
fn launch_test(test: &ABTest, ui: &mut UI, ctx: &mut EventCtx) -> ABTestMode {
|
||||
let secondary = ctx.loading_screen(
|
||||
&format!("Launching A/B test {}", test.test_name),
|
||||
format!("Launching A/B test {}", test.test_name),
|
||||
|ctx, mut timer| {
|
||||
let scenario: Scenario = abstutil::read_binary(
|
||||
abstutil::path_scenario(&test.map_name, &test.scenario_name),
|
||||
@ -213,7 +213,7 @@ fn launch_test(test: &ABTest, ui: &mut UI, ctx: &mut EventCtx) -> ABTestMode {
|
||||
|
||||
fn launch_savestate(test: &ABTest, ss_path: String, ui: &mut UI, ctx: &mut EventCtx) -> ABTestMode {
|
||||
ctx.loading_screen(
|
||||
&format!("Launch A/B test from savestate {}", ss_path),
|
||||
format!("Launch A/B test from savestate {}", ss_path),
|
||||
|ctx, mut timer| {
|
||||
let ss: ABTestSavestate = abstutil::read_binary(ss_path, &mut timer);
|
||||
|
||||
|
@ -267,11 +267,11 @@ pub fn prebake() {
|
||||
}
|
||||
}
|
||||
for (map_path, list) in per_map {
|
||||
timer.start(&format!("prebake for {}", map_path));
|
||||
timer.start(format!("prebake for {}", map_path));
|
||||
let map = map_model::Map::new(map_path.clone(), false, &mut timer);
|
||||
|
||||
for challenge in list {
|
||||
timer.start(&format!("prebake for {}", challenge.title));
|
||||
timer.start(format!("prebake for {}", challenge.title));
|
||||
if let Some(scenario) = challenge.gameplay.scenario(&map, None, &mut timer) {
|
||||
let mut sim = Sim::new(&map, SimOptions::new("prebaked"), &mut timer);
|
||||
// Bit of an abuse of this, but just need to fix the rng seed.
|
||||
@ -284,9 +284,9 @@ pub fn prebake() {
|
||||
sim.get_analytics(),
|
||||
);
|
||||
}
|
||||
timer.stop(&format!("prebake for {}", challenge.title));
|
||||
timer.stop(format!("prebake for {}", challenge.title));
|
||||
}
|
||||
|
||||
timer.stop(&format!("prebake for {}", map_path));
|
||||
timer.stop(format!("prebake for {}", map_path));
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ fn pick_color(wiz: &mut Wizard, ctx: &mut EventCtx, ui: &mut UI) -> Option<Trans
|
||||
name: name.clone(),
|
||||
original: ui.cs.get_modified(&name),
|
||||
menu: ModalMenu::new(
|
||||
&format!("Color Picker for {}", name),
|
||||
format!("Color Picker for {}", name),
|
||||
vec![
|
||||
(hotkey(Key::Backspace), "revert"),
|
||||
(hotkey(Key::Escape), "finalize"),
|
||||
|
@ -30,7 +30,7 @@ impl TrafficSignalEditor {
|
||||
pub fn new(id: IntersectionID, ctx: &mut EventCtx, ui: &mut UI) -> TrafficSignalEditor {
|
||||
ui.primary.current_selection = None;
|
||||
let menu = ModalMenu::new(
|
||||
&format!("Traffic Signal Editor for {}", id),
|
||||
format!("Traffic Signal Editor for {}", id),
|
||||
vec![
|
||||
(hotkey(Key::UpArrow), "select previous phase"),
|
||||
(hotkey(Key::DownArrow), "select next phase"),
|
||||
|
@ -27,7 +27,7 @@ impl State for NeighborhoodPicker {
|
||||
self.wizard = Wizard::new();
|
||||
return Transition::Push(Box::new(NeighborhoodEditor {
|
||||
menu: ModalMenu::new(
|
||||
&format!("Neighborhood Editor for {}", n.name),
|
||||
format!("Neighborhood Editor for {}", n.name),
|
||||
vec![
|
||||
(hotkey(Key::Escape), "quit"),
|
||||
(hotkey(Key::S), "save"),
|
||||
|
@ -16,7 +16,7 @@ impl FasterTrips {
|
||||
pub fn new(trip_mode: TripMode, ctx: &EventCtx) -> (ModalMenu, Box<dyn GameplayState>) {
|
||||
(
|
||||
ModalMenu::new(
|
||||
&format!("Speed up {} trips", trip_mode),
|
||||
format!("Speed up {} trips", trip_mode),
|
||||
vec![(hotkey(Key::H), "help")],
|
||||
ctx,
|
||||
),
|
||||
|
@ -21,7 +21,7 @@ impl OptimizeBus {
|
||||
let route = ui.primary.map.get_bus_route(&route_name).unwrap();
|
||||
(
|
||||
ModalMenu::new(
|
||||
&format!("Optimize {}", route_name),
|
||||
format!("Optimize {}", route_name),
|
||||
vec![
|
||||
(hotkey(Key::E), "show bus route"),
|
||||
(hotkey(Key::T), "show delays over time"),
|
||||
|
@ -11,7 +11,7 @@ impl PlayScenario {
|
||||
pub fn new(name: &String, ctx: &EventCtx) -> (ModalMenu, Box<dyn GameplayState>) {
|
||||
(
|
||||
ModalMenu::new(
|
||||
&format!("Playing {}", name),
|
||||
format!("Playing {}", name),
|
||||
vec![
|
||||
(hotkey(Key::S), "start another scenario"),
|
||||
(lctrl(Key::L), "load another map"),
|
||||
|
@ -158,7 +158,7 @@ fn import_parcels(
|
||||
// TODO Ideally we could just do the conversion directly without any dependencies, but the
|
||||
// formats are documented quite confusingly. Couldn't get the Rust crate for proj or GDAL
|
||||
// bindings to build. So just do this hack.
|
||||
timer.start(&format!(
|
||||
timer.start(format!(
|
||||
"run cs2cs on {} points",
|
||||
prettyprint_usize(parcel_metadata.len())
|
||||
));
|
||||
@ -176,7 +176,7 @@ fn import_parcels(
|
||||
])
|
||||
.output()?;
|
||||
assert!(output.status.success());
|
||||
timer.stop(&format!(
|
||||
timer.stop(format!(
|
||||
"run cs2cs on {} points",
|
||||
prettyprint_usize(parcel_metadata.len())
|
||||
));
|
||||
|
@ -9,7 +9,7 @@ fn main() {
|
||||
let use_fixes = !args.enabled("--nofixes");
|
||||
args.done();
|
||||
|
||||
let mut timer = Timer::new(&format!("precompute {}", load));
|
||||
let mut timer = Timer::new(format!("precompute {}", load));
|
||||
|
||||
let map = Map::new(load, use_fixes, &mut timer);
|
||||
timer.start("save map");
|
||||
|
@ -88,7 +88,7 @@ impl Scenario {
|
||||
pub fn instantiate(&self, sim: &mut Sim, map: &Map, rng: &mut XorShiftRng, timer: &mut Timer) {
|
||||
sim.set_name(self.scenario_name.clone());
|
||||
|
||||
timer.start(&format!("Instantiating {}", self.scenario_name));
|
||||
timer.start(format!("Instantiating {}", self.scenario_name));
|
||||
|
||||
if self.seed_buses {
|
||||
for route in map.get_all_bus_routes() {
|
||||
@ -156,7 +156,7 @@ impl Scenario {
|
||||
}
|
||||
|
||||
sim.spawn_all_trips(map, timer, true);
|
||||
timer.stop(&format!("Instantiating {}", self.scenario_name));
|
||||
timer.stop(format!("Instantiating {}", self.scenario_name));
|
||||
}
|
||||
|
||||
pub fn save(&self) {
|
||||
|
@ -583,7 +583,7 @@ impl Sim {
|
||||
// TODO Ideally print every second or so
|
||||
let orig_time = self.time;
|
||||
let chunks = (dt / Duration::seconds(10.0)).ceil() as usize;
|
||||
timer.start_iter(&format!("advance simulation by {}", dt), chunks);
|
||||
timer.start_iter(format!("advance simulation by {}", dt), chunks);
|
||||
for i in 0..chunks {
|
||||
timer.next();
|
||||
self.step(
|
||||
|
Loading…
Reference in New Issue
Block a user