present sim time in a nicer format

This commit is contained in:
Dustin Carlino 2018-08-20 15:45:56 -07:00
parent b87af4b303
commit 9f1ad3755d
3 changed files with 75 additions and 9 deletions

View File

@ -22,7 +22,7 @@ struct Flags {
/// Optional time to savestate
#[structopt(long = "save_at")]
save_at: Option<u32>,
save_at: Option<String>,
/// Optional savestate to load
#[structopt(long = "load_from")]
@ -59,6 +59,16 @@ fn main() {
}
}
let save_at = if let Some(ref time_str) = flags.save_at {
if let Some(t) = sim::Tick::parse(time_str) {
Some(t)
} else {
panic!("Couldn't parse time {}", time_str);
}
} else {
None
};
let mut benchmark = sim.start_benchmark();
loop {
sim.step(&map, &control_map);
@ -66,11 +76,9 @@ fn main() {
let speed = sim.measure_speed(&mut benchmark);
println!("{0}, speed = {1:.2}x", sim.summary(), speed);
}
if let Some(ticks) = flags.save_at {
if sim.time == sim::Tick::from_raw(ticks) {
abstutil::write_json("sim_state", &sim).expect("Writing sim state failed");
println!("Wrote sim_state at {}", sim.time);
}
if Some(sim.time) == save_at {
abstutil::write_json("sim_state", &sim).expect("Writing sim state failed");
println!("Wrote sim_state at {}", sim.time);
}
}
}

View File

@ -81,6 +81,39 @@ impl Tick {
Tick(ticks)
}
pub fn parse(string: &str) -> Option<Tick> {
let parts: Vec<&str> = string.split(":").collect();
if parts.is_empty() {
return None;
}
let mut ticks: u32 = 0;
if parts.last().unwrap().contains(".") {
let last_parts: Vec<&str> = parts.last().unwrap().split(".").collect();
if last_parts.len() != 2 {
return None;
}
ticks += u32::from_str_radix(last_parts[1], 10).ok()?;
ticks += 10 * u32::from_str_radix(last_parts[0], 10).ok()?;
} else {
ticks += 10 * u32::from_str_radix(parts.last().unwrap(), 10).ok()?;
}
match parts.len() {
1 => Some(Tick(ticks)),
2 => {
ticks += 60 * 10 * u32::from_str_radix(parts[0], 10).ok()?;
Some(Tick(ticks))
}
3 => {
ticks += 60 * 10 * u32::from_str_radix(parts[1], 10).ok()?;
ticks += 60 * 60 * 10 * u32::from_str_radix(parts[0], 10).ok()?;
Some(Tick(ticks))
}
_ => None,
}
}
pub fn as_time(&self) -> Time {
(self.0 as f64) * TIMESTEP
}
@ -115,11 +148,36 @@ impl std::ops::Sub for Tick {
impl std::fmt::Display for Tick {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
// TODO switch to minutes and hours when this gets big
write!(f, "{0:.1}s", (self.0 as f64) * TIMESTEP.value_unsafe)
// TODO hardcoding these to avoid floating point issues... urgh. :\
let ticks_per_second = 10;
let ticks_per_minute = 60 * ticks_per_second;
let ticks_per_hour = 60 * ticks_per_minute;
let hours = self.0 / ticks_per_hour;
let mut remainder = self.0 % ticks_per_hour;
let minutes = remainder / ticks_per_minute;
remainder = remainder % ticks_per_minute;
let seconds = remainder / ticks_per_second;
remainder = remainder % ticks_per_second;
write!(
f,
"{0:02}:{1:02}:{2:02}.{3}",
hours, minutes, seconds, remainder
)
}
}
#[test]
fn time_parsing() {
assert_eq!(Tick::parse("2.3"), Some(Tick(23)));
assert_eq!(Tick::parse("02.3"), Some(Tick(23)));
assert_eq!(Tick::parse("00:00:02.3"), Some(Tick(23)));
assert_eq!(Tick::parse("00:02:03.5"), Some(Tick(35 + 1200)));
assert_eq!(Tick::parse("01:02:03.5"), Some(Tick(35 + 1200 + 36000)));
}
// TODO this name isn't quite right :)
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub(crate) enum On {

View File

@ -247,7 +247,7 @@ impl Sim {
let (waiting_cars, active_cars) = self.driving_state.get_active_and_waiting_count();
let (waiting_peds, active_peds) = self.walking_state.get_active_and_waiting_count();
format!(
"Time: {0:.2}, {1} / {2} active cars waiting, {3} cars parked, {4} / {5} pedestrians waiting",
"Time: {0}, {1} / {2} active cars waiting, {3} cars parked, {4} / {5} pedestrians waiting",
self.time,
waiting_cars,
active_cars,