mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 15:02:59 +03:00
Autosave even the untitled edits!
Possibly when the player explicitly says "discard proposal", we should actually delete the file.
This commit is contained in:
parent
0a3479a3d0
commit
d68273086b
@ -226,7 +226,7 @@ impl State for EditMode {
|
||||
true,
|
||||
Some(Transition::Pop),
|
||||
Box::new(|ctx, app| {
|
||||
apply_map_edits(ctx, app, MapEdits::new());
|
||||
apply_map_edits(ctx, app, app.primary.map.new_edits());
|
||||
}),
|
||||
)),
|
||||
"save this proposal as..." => Transition::Replace(SaveEdits::new(
|
||||
@ -245,7 +245,7 @@ impl State for EditMode {
|
||||
app.primary.map.get_name(),
|
||||
&app.primary.map.get_edits().edits_name,
|
||||
));
|
||||
apply_map_edits(ctx, app, MapEdits::new());
|
||||
apply_map_edits(ctx, app, app.primary.map.new_edits());
|
||||
Transition::Pop
|
||||
}
|
||||
_ => unreachable!(),
|
||||
@ -430,13 +430,13 @@ impl State for SaveEdits {
|
||||
.must_apply_edits(edits, &mut Timer::new("name map edits"));
|
||||
app.primary.map.save_edits();
|
||||
if self.reset {
|
||||
apply_map_edits(ctx, app, MapEdits::new());
|
||||
apply_map_edits(ctx, app, app.primary.map.new_edits());
|
||||
}
|
||||
(self.on_success)(ctx, app);
|
||||
return Transition::Pop;
|
||||
}
|
||||
"Discard proposal" => {
|
||||
apply_map_edits(ctx, app, MapEdits::new());
|
||||
apply_map_edits(ctx, app, app.primary.map.new_edits());
|
||||
return Transition::Pop;
|
||||
}
|
||||
"Cancel" => {
|
||||
@ -516,7 +516,7 @@ impl State for LoadEdits {
|
||||
match x.as_ref() {
|
||||
"close" => Transition::Pop,
|
||||
"Start over with blank proposal" => {
|
||||
apply_map_edits(ctx, app, MapEdits::new());
|
||||
apply_map_edits(ctx, app, app.primary.map.new_edits());
|
||||
Transition::Pop
|
||||
}
|
||||
path => {
|
||||
@ -648,9 +648,7 @@ pub fn apply_map_edits(ctx: &mut EventCtx, app: &mut App, edits: MapEdits) {
|
||||
}
|
||||
|
||||
// Autosave
|
||||
if app.primary.map.get_edits().edits_name != "Untitled Proposal" {
|
||||
app.primary.map.save_edits();
|
||||
}
|
||||
app.primary.map.save_edits();
|
||||
}
|
||||
|
||||
pub fn can_edit_lane(mode: &GameplayMode, l: LaneID, app: &App) -> bool {
|
||||
@ -739,7 +737,6 @@ fn make_changelist(ctx: &mut EventCtx, app: &App) -> Panel {
|
||||
"manage proposals",
|
||||
lctrl(Key::P),
|
||||
),
|
||||
// TODO This is a lie for untitled proposals right now, need to pick names for those
|
||||
"autosaved"
|
||||
.draw_text(ctx)
|
||||
.container()
|
||||
|
@ -361,7 +361,7 @@ impl State for FinalScore {
|
||||
if self.chose_next || self.chose_back_to_challenges {
|
||||
ctx.loading_screen("reset map and sim", |ctx, mut timer| {
|
||||
// Always safe to do this
|
||||
apply_map_edits(ctx, app, MapEdits::new());
|
||||
apply_map_edits(ctx, app, app.primary.map.new_edits());
|
||||
app.primary
|
||||
.map
|
||||
.recalculate_pathfinding_after_edits(&mut timer);
|
||||
|
@ -21,7 +21,6 @@ use crate::pregame::MainMenu;
|
||||
use crate::render::UnzoomedAgents;
|
||||
pub use gameplay::{spawn_agents_around, GameplayMode, TutorialPointer, TutorialState};
|
||||
use geom::Time;
|
||||
use map_model::MapEdits;
|
||||
use maplit::btreeset;
|
||||
use sim::AgentType;
|
||||
pub use speed::{SpeedControls, TimePanel};
|
||||
@ -279,7 +278,7 @@ impl State for BackToMainMenu {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
ctx.loading_screen("reset map and sim", |ctx, mut timer| {
|
||||
// Always safe to do this
|
||||
apply_map_edits(ctx, app, MapEdits::new());
|
||||
apply_map_edits(ctx, app, app.primary.map.new_edits());
|
||||
app.primary
|
||||
.map
|
||||
.recalculate_pathfinding_after_edits(&mut timer);
|
||||
|
@ -85,10 +85,9 @@ pub struct EditEffects {
|
||||
}
|
||||
|
||||
impl MapEdits {
|
||||
pub fn new() -> MapEdits {
|
||||
pub(crate) fn new() -> MapEdits {
|
||||
MapEdits {
|
||||
// Something has to fill this out later
|
||||
edits_name: "Untitled Proposal".to_string(),
|
||||
edits_name: "TODO temporary".to_string(),
|
||||
proposal_description: Vec::new(),
|
||||
proposal_link: None,
|
||||
commands: Vec::new(),
|
||||
@ -114,7 +113,10 @@ impl MapEdits {
|
||||
|
||||
// TODO Version these? Or it's unnecessary, since we have a command stack.
|
||||
fn save(&self, map: &Map) {
|
||||
assert_ne!(self.edits_name, "Untitled Proposal");
|
||||
// If untitled and empty, don't actually save anything.
|
||||
if self.edits_name.starts_with("Untitled Proposal") && self.commands.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
abstutil::write_json(
|
||||
abstutil::path_edits(map.get_name(), &self.edits_name),
|
||||
@ -403,10 +405,29 @@ fn recalculate_turns(
|
||||
}
|
||||
|
||||
impl Map {
|
||||
pub fn new_edits(&self) -> MapEdits {
|
||||
let mut edits = MapEdits::new();
|
||||
|
||||
// Automatically find a new filename
|
||||
let mut i = 1;
|
||||
loop {
|
||||
let name = format!("Untitled Proposal {}", i);
|
||||
if !abstutil::file_exists(abstutil::path_edits(&self.name, &name)) {
|
||||
edits.edits_name = name;
|
||||
return edits;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_edits(&self) -> &MapEdits {
|
||||
&self.edits
|
||||
}
|
||||
|
||||
pub fn unsaved_edits(&self) -> bool {
|
||||
self.edits.edits_name.starts_with("Untitled Proposal") && !self.edits.commands.is_empty()
|
||||
}
|
||||
|
||||
pub fn get_r_edit(&self, r: RoadID) -> EditRoad {
|
||||
let r = self.get_r(r);
|
||||
EditRoad {
|
||||
|
@ -53,6 +53,7 @@ impl Map {
|
||||
name: raw.name.clone(),
|
||||
edits: MapEdits::new(),
|
||||
};
|
||||
map.edits = map.new_edits();
|
||||
|
||||
let road_id_mapping: BTreeMap<OriginalRoad, RoadID> = initial_map
|
||||
.roads
|
||||
|
@ -29,7 +29,8 @@ impl Map {
|
||||
if path.starts_with(&abstutil::path_all_maps()) {
|
||||
match abstutil::maybe_read_binary(path.clone(), timer) {
|
||||
Ok(map) => {
|
||||
let map: Map = map;
|
||||
let mut map: Map = map;
|
||||
map.edits = map.new_edits();
|
||||
|
||||
if false {
|
||||
use abstutil::{prettyprint_usize, serialized_size_bytes};
|
||||
@ -458,12 +459,8 @@ impl Map {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn unsaved_edits(&self) -> bool {
|
||||
self.edits.edits_name == "Untitled Proposal" && !self.edits.commands.is_empty()
|
||||
}
|
||||
|
||||
pub fn save(&self) {
|
||||
assert_eq!(self.edits.edits_name, "Untitled Proposal");
|
||||
assert!(self.edits.edits_name.starts_with("Untitled Proposal"));
|
||||
assert!(self.edits.commands.is_empty());
|
||||
assert!(!self.pathfinder_dirty);
|
||||
abstutil::write_binary(abstutil::path_map(&self.name), self);
|
||||
|
@ -88,17 +88,27 @@ impl SimFlags {
|
||||
let mut sim: Sim = abstutil::read_binary(self.load.clone(), timer);
|
||||
|
||||
let mut map = Map::new(abstutil::path_map(&sim.map_name), timer);
|
||||
if sim.edits_name != "Untitled Proposal" {
|
||||
map.must_apply_edits(
|
||||
MapEdits::load(
|
||||
&map,
|
||||
abstutil::path_edits(map.get_name(), &sim.edits_name),
|
||||
timer,
|
||||
)
|
||||
.unwrap(),
|
||||
timer,
|
||||
);
|
||||
map.recalculate_pathfinding_after_edits(timer);
|
||||
match MapEdits::load(
|
||||
&map,
|
||||
abstutil::path_edits(map.get_name(), &sim.edits_name),
|
||||
timer,
|
||||
) {
|
||||
Ok(edits) => {
|
||||
map.must_apply_edits(edits, timer);
|
||||
map.recalculate_pathfinding_after_edits(timer);
|
||||
}
|
||||
Err(err) => {
|
||||
// Little brittle. Sometimes legitimate edits wind up being saved without a
|
||||
// proper name.
|
||||
if sim.edits_name.starts_with("Untitled Proposal") {
|
||||
warn!(
|
||||
"Sim savestate refers to edits \"{}\", but not using them: {}",
|
||||
sim.edits_name, err
|
||||
);
|
||||
} else {
|
||||
panic!("Couldn't load edits \"{}\": {}", sim.edits_name, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
sim.restore_paths(&map, timer);
|
||||
|
||||
|
@ -143,8 +143,7 @@ impl Sim {
|
||||
time: Time::START_OF_DAY,
|
||||
|
||||
map_name: map.get_name().to_string(),
|
||||
// TODO
|
||||
edits_name: "Untitled Proposal".to_string(),
|
||||
edits_name: map.get_edits().edits_name.clone(),
|
||||
run_name: opts.run_name,
|
||||
step_count: 0,
|
||||
alerts: opts.alerts,
|
||||
|
Loading…
Reference in New Issue
Block a user