Consolidate code for loading edits from JSON

This commit is contained in:
Dustin Carlino 2020-08-20 16:26:44 -07:00
parent 2783c3e180
commit fa83554eb4
5 changed files with 70 additions and 55 deletions

View File

@ -447,57 +447,59 @@ impl LoadEdits {
impl State for LoadEdits {
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
match self.composite.event(ctx) {
Outcome::Clicked(x) => match x.as_ref() {
"close" => Transition::Pop,
"Start over with blank edits" => {
apply_map_edits(ctx, app, MapEdits::new());
Transition::Pop
}
name => {
// TODO Kind of a hack. If it ends with .json, it's already a path. Otherwise
// it's a result from the menu.
let path = if name.ends_with(".json") {
name.to_string()
} else {
abstutil::path_edits(app.primary.map.get_name(), name)
};
match abstutil::maybe_read_json::<PermanentMapEdits>(
path.clone(),
&mut Timer::throwaway(),
)
.map_err(|err| err.to_string())
.and_then(|perma| PermanentMapEdits::from_permanent(perma, &app.primary.map))
.and_then(|edits| {
if self.mode.allows(&edits) {
Ok(edits)
Outcome::Clicked(x) => {
match x.as_ref() {
"close" => Transition::Pop,
"Start over with blank edits" => {
apply_map_edits(ctx, app, MapEdits::new());
Transition::Pop
}
path => {
// TODO Kind of a hack. If it ends with .json, it's already a path.
// Otherwise it's a result from the menu.
let path = if path.ends_with(".json") {
path.to_string()
} else {
Err(
"The current gameplay mode restricts edits. These edits have a \
banned command."
.to_string(),
)
abstutil::path_edits(app.primary.map.get_name(), path)
};
match MapEdits::load(
&app.primary.map,
path.clone(),
&mut Timer::throwaway(),
)
.and_then(|edits| {
if self.mode.allows(&edits) {
Ok(edits)
} else {
Err(
"The current gameplay mode restricts edits. These edits have \
a banned command."
.to_string(),
)
}
}) {
Ok(edits) => {
apply_map_edits(ctx, app, edits);
Transition::Pop
}
// TODO Hack. Have to replace ourselves, because the Menu might be
// invalidated now that something was chosen.
Err(err) => Transition::Multi(vec![
Transition::Replace(LoadEdits::new(ctx, app, self.mode.clone())),
// TODO Menu draws at a weird Z-order to deal with tooltips, so now
// the menu underneath bleeds
// through
Transition::Push(PopupMsg::new(
ctx,
"Error",
vec![format!("Can't load {}", path), err.clone()],
)),
]),
}
}) {
Ok(edits) => {
apply_map_edits(ctx, app, edits);
Transition::Pop
}
// TODO Hack. Have to replace ourselves, because the Menu might be
// invalidated now that something was chosen.
Err(err) => Transition::Multi(vec![
Transition::Replace(LoadEdits::new(ctx, app, self.mode.clone())),
// TODO Menu draws at a weird Z-order to deal with tooltips, so now the
// menu underneath bleeds through
Transition::Push(PopupMsg::new(
ctx,
"Error",
vec![format!("Can't load {}", path), err.clone()],
)),
]),
}
}
},
}
_ => Transition::Keep,
}
}

View File

@ -52,8 +52,12 @@ impl Game {
if let Some(edits_name) = start_with_edits {
// TODO Maybe loading screen
let mut timer = abstutil::Timer::new("apply initial edits");
let edits =
map_model::MapEdits::load(&app.primary.map, &edits_name, &mut timer).unwrap();
let edits = map_model::MapEdits::load(
&app.primary.map,
abstutil::path_edits(app.primary.map.get_name(), &edits_name),
&mut timer,
)
.unwrap();
crate::edit::apply_map_edits(ctx, &mut app, edits);
app.primary
.map

View File

@ -331,6 +331,9 @@ impl Proposals {
let mut proposals = HashMap::new();
let mut buttons = Vec::new();
let mut current_tab = Vec::new();
// If a proposal has fallen out of date, it'll be skipped with an error logged. Since these
// are under version control, much more likely to notice when they break (or we could add a
// step to data/regen.sh).
for (name, edits) in
abstutil::load_all_objects::<PermanentMapEdits>(abstutil::path("system/proposals"))
{

View File

@ -96,12 +96,10 @@ impl MapEdits {
}
}
pub fn load(map: &Map, edits_name: &str, timer: &mut Timer) -> Result<MapEdits, String> {
if edits_name == "untitled edits" {
return Ok(MapEdits::new());
}
pub fn load(map: &Map, path: String, timer: &mut Timer) -> Result<MapEdits, String> {
// TODO If this fails, attempt to upgrade an older version of the edit format.
PermanentMapEdits::from_permanent(
abstutil::read_json(abstutil::path_edits(map.get_name(), edits_name), timer),
abstutil::maybe_read_json(path, timer).map_err(|x| x.to_string())?,
map,
)
}

View File

@ -82,7 +82,15 @@ impl SimFlags {
let mut map = Map::new(abstutil::path_map(&sim.map_name), timer);
if sim.edits_name != "untitled edits" {
map.must_apply_edits(MapEdits::load(&map, &sim.edits_name, timer).unwrap(), timer);
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);
}
sim.restore_paths(&map, timer);