diff --git a/sim/Cargo.toml b/sim/Cargo.toml index 497f7191ca..f48acd1797 100644 --- a/sim/Cargo.toml +++ b/sim/Cargo.toml @@ -19,6 +19,7 @@ ordered-float = "0.5.0" pretty_assertions = "0.5.1" rand = { version = "0.5.1", features = ["serde1"] } rayon = "1.0" +regex = "1.0.6" serde = "1.0" serde_derive = "1.0" structopt = "0.2" diff --git a/sim/src/lib.rs b/sim/src/lib.rs index e47662ab87..8836e1d54a 100644 --- a/sim/src/lib.rs +++ b/sim/src/lib.rs @@ -21,6 +21,7 @@ extern crate ordered_float; extern crate pretty_assertions; extern crate rand; extern crate rayon; +extern crate regex; extern crate serde; #[macro_use] extern crate serde_derive; diff --git a/sim/src/physics.rs b/sim/src/physics.rs index d563abca24..a7aa95faf2 100644 --- a/sim/src/physics.rs +++ b/sim/src/physics.rs @@ -1,5 +1,6 @@ use dimensioned::si; use rand::{Rng, XorShiftRng}; +use regex::Regex; pub const TIMESTEP: Time = si::Second { value_unsafe: 0.1, @@ -29,6 +30,7 @@ impl Tick { Tick(10 * secs) } + // TODO Why have these two forms? Consolidate pub fn parse(string: &str) -> Option { let parts: Vec<&str> = string.split(":").collect(); if parts.is_empty() { @@ -62,6 +64,19 @@ impl Tick { } } + pub fn parse_filename(string: &str) -> Option { + lazy_static! { + static ref RE: Regex = Regex::new(r"(\d+)h(\d+)m(\d+)\.(\d+)s").unwrap(); + } + let caps = RE.captures(string)?; + let hours = 60 * 60 * 10 * u32::from_str_radix(&caps[1], 10).ok()?; + let minutes = 60 * 10 * u32::from_str_radix(&caps[2], 10).ok()?; + let seconds = 10 * u32::from_str_radix(&caps[3], 10).ok()?; + let ms = u32::from_str_radix(&caps[4], 10).ok()?; + + Some(Tick(hours + minutes + seconds + ms)) + } + pub fn as_time(&self) -> Time { (self.0 as f64) * TIMESTEP } diff --git a/sim/src/sim.rs b/sim/src/sim.rs index 4eaf4705c7..50a251fad8 100644 --- a/sim/src/sim.rs +++ b/sim/src/sim.rs @@ -313,9 +313,9 @@ impl Sim { // TODO Return a descriptive error again pub fn load_most_recent(&self) -> Result { - let (_, load) = self.find_all_savestates().and_then(|mut list| { - list.pop().ok_or(io_error("empty directory")) - })?; + let (_, load) = self + .find_all_savestates() + .and_then(|mut list| list.pop().ok_or(io_error("empty directory")))?; info!("Loading {}", load); abstutil::read_json(&load) } @@ -329,12 +329,13 @@ impl Sim { ))? { let path = entry?.path(); let filename = path - .file_name() - .expect("path isn't a filename") - .to_os_string() - .into_string() - .expect("can't convert path to string"); - let tick = Tick::parse(&filename).expect(&format!("invalid Tick: {}", filename)); + .file_name() + .expect("path isn't a filename") + .to_os_string() + .into_string() + .expect("can't convert path to string"); + let tick = + Tick::parse_filename(&filename).expect(&format!("invalid Tick: {}", filename)); results.push(( tick, path.as_path()