mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +03:00
jump to previous/next savestate
This commit is contained in:
parent
44d9065123
commit
ebc5419f9a
@ -3,7 +3,7 @@ use crate::plugins::{Plugin, PluginCtx};
|
||||
use abstutil::elapsed_seconds;
|
||||
use ezgui::EventLoopMode;
|
||||
use piston::input::Key;
|
||||
use sim::{Benchmark, TIMESTEP};
|
||||
use sim::{Benchmark, Sim, TIMESTEP};
|
||||
use std::mem;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
@ -77,15 +77,51 @@ impl Plugin for SimControls {
|
||||
}
|
||||
if ctx
|
||||
.input
|
||||
.unimportant_key_pressed(Key::P, SIM, "load sim state")
|
||||
.unimportant_key_pressed(Key::Y, SIM, "load previous sim state")
|
||||
{
|
||||
match ctx.primary.sim.load_most_recent() {
|
||||
match ctx
|
||||
.primary
|
||||
.sim
|
||||
.find_previous_savestate(ctx.primary.sim.time)
|
||||
.and_then(|path| Sim::load_savestate(path, None))
|
||||
{
|
||||
Ok(new_sim) => {
|
||||
// TODO From the perspective of other SimMode plugins, does this just
|
||||
// look like the simulation stepping forwards?
|
||||
ctx.primary.sim = new_sim;
|
||||
ctx.primary.recalculate_current_selection = true;
|
||||
|
||||
if let Some((s, _)) = ctx.secondary {
|
||||
s.sim = Sim::load_savestate(
|
||||
s.sim.find_previous_savestate(s.sim.time).unwrap(),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
Err(e) => error!("Couldn't load savestate: {}", e),
|
||||
};
|
||||
}
|
||||
if ctx
|
||||
.input
|
||||
.unimportant_key_pressed(Key::U, SIM, "load next sim state")
|
||||
{
|
||||
match ctx
|
||||
.primary
|
||||
.sim
|
||||
.find_next_savestate(ctx.primary.sim.time)
|
||||
.and_then(|path| Sim::load_savestate(path, None))
|
||||
{
|
||||
Ok(new_sim) => {
|
||||
ctx.primary.sim = new_sim;
|
||||
ctx.primary.recalculate_current_selection = true;
|
||||
|
||||
if let Some((s, _)) = ctx.secondary {
|
||||
s.sim = s.sim.load_most_recent().unwrap();
|
||||
s.sim = Sim::load_savestate(
|
||||
s.sim.find_next_savestate(s.sim.time).unwrap(),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
Err(e) => error!("Couldn't load savestate: {}", e),
|
||||
|
@ -88,9 +88,15 @@ impl Sim {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load(path: String, new_run_name: String) -> Result<Sim, std::io::Error> {
|
||||
pub fn load_savestate(
|
||||
path: String,
|
||||
new_run_name: Option<String>,
|
||||
) -> Result<Sim, std::io::Error> {
|
||||
info!("Loading {}", path);
|
||||
abstutil::read_json(&path).map(|mut s: Sim| {
|
||||
s.run_name = new_run_name;
|
||||
if let Some(name) = new_run_name {
|
||||
s.run_name = name;
|
||||
}
|
||||
s
|
||||
})
|
||||
}
|
||||
@ -135,15 +141,8 @@ impl Sim {
|
||||
"At {} while processing {:?}",
|
||||
self.time, self.current_agent_for_debugging
|
||||
);
|
||||
if let Ok(mut list) = self.find_all_savestates() {
|
||||
// Find the most recent one BEFORE the current time
|
||||
list.reverse();
|
||||
for (tick, path) in list {
|
||||
if tick < self.time {
|
||||
error!("Debug from {}", path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Ok(path) = self.find_previous_savestate(self.time) {
|
||||
error!("Debug from {}", path);
|
||||
}
|
||||
}
|
||||
|
||||
@ -313,15 +312,6 @@ impl Sim {
|
||||
path
|
||||
}
|
||||
|
||||
// TODO Return a descriptive error again
|
||||
pub fn load_most_recent(&self) -> Result<Sim, std::io::Error> {
|
||||
let (_, load) = self
|
||||
.find_all_savestates()
|
||||
.and_then(|mut list| list.pop().ok_or_else(|| io_error("empty directory")))?;
|
||||
info!("Loading {}", load);
|
||||
abstutil::read_json(&load)
|
||||
}
|
||||
|
||||
// Earliest one is first
|
||||
fn find_all_savestates(&self) -> Result<Vec<(Tick, String)>, std::io::Error> {
|
||||
let mut results: Vec<(Tick, String)> = Vec::new();
|
||||
@ -351,6 +341,28 @@ impl Sim {
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
pub fn find_previous_savestate(&self, base_time: Tick) -> Result<String, std::io::Error> {
|
||||
let mut list = self.find_all_savestates()?;
|
||||
// Find the most recent one BEFORE the current time
|
||||
list.reverse();
|
||||
for (tick, path) in list {
|
||||
if tick < base_time {
|
||||
return Ok(path);
|
||||
}
|
||||
}
|
||||
Err(io_error(&format!("no savestate before {}", base_time)))
|
||||
}
|
||||
|
||||
pub fn find_next_savestate(&self, base_time: Tick) -> Result<String, std::io::Error> {
|
||||
let list = self.find_all_savestates()?;
|
||||
for (tick, path) in list {
|
||||
if tick > base_time {
|
||||
return Ok(path);
|
||||
}
|
||||
}
|
||||
Err(io_error(&format!("no savestate after {}", base_time)))
|
||||
}
|
||||
|
||||
pub fn active_agents(&self) -> Vec<AgentID> {
|
||||
self.trips_state.active_agents()
|
||||
}
|
||||
|
@ -89,7 +89,8 @@ pub fn run(t: &mut TestRunner) {
|
||||
}
|
||||
|
||||
let sim3: sim::Sim =
|
||||
sim::Sim::load(sim1_save.clone(), "with_savestating_3".to_string()).unwrap();
|
||||
sim::Sim::load_savestate(sim1_save.clone(), Some("with_savestating_3".to_string()))
|
||||
.unwrap();
|
||||
if sim3 != sim2 {
|
||||
panic!(
|
||||
"sim state differs between {} and {}",
|
||||
|
Loading…
Reference in New Issue
Block a user