make Timer methods and ModalMenu take &str or String

This commit is contained in:
Dustin Carlino 2019-12-12 10:25:48 -08:00
parent 1542e237d9
commit dc2cc81249
16 changed files with 40 additions and 35 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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