fix more relative dir bugs. allow different directory for player data too. fixes #160

This commit is contained in:
Dustin Carlino 2020-07-07 16:49:46 -07:00
parent 4aaa41dd13
commit d1fdcbbd59
6 changed files with 59 additions and 40 deletions

View File

@ -75,83 +75,99 @@ lazy_static::lazy_static! {
panic!("Can't find the data/ directory");
}
};
static ref ROOT_PLAYER_DIR: String = {
// If you're packaging for a release and want the player's local data directory to be in
// some fixed location: ABST_PLAYER_DATA_DIR=/some/path cargo build ...
if let Some(dir) = option_env!("ABST_PLAYER_DATA_DIR") {
dir.trim_end_matches('/').to_string()
} else if file_exists("data/".to_string()) {
"data".to_string()
} else if file_exists("../data/".to_string()) {
"../data".to_string()
} else {
panic!("Can't find the data/ directory");
}
};
}
pub fn path<I: Into<String>>(p: I) -> String {
format!("{}/{}", *ROOT_DIR, p.into())
let p = p.into();
if p.starts_with("player/") {
format!("{}/{}", *ROOT_PLAYER_DIR, p)
} else {
format!("{}/{}", *ROOT_DIR, p)
}
}
// System data (Players can't edit, needed at runtime)
pub fn path_map(map_name: &str) -> String {
format!("{}/system/maps/{}.bin", *ROOT_DIR, map_name)
path(format!("system/maps/{}.bin", map_name))
}
pub fn path_all_maps() -> String {
format!("{}/system/maps", *ROOT_DIR)
path("system/maps")
}
pub fn path_prebaked_results(map_name: &str, scenario_name: &str) -> String {
format!(
"{}/system/prebaked_results/{}/{}.bin",
*ROOT_DIR, map_name, scenario_name
)
path(format!(
"system/prebaked_results/{}/{}.bin",
map_name, scenario_name
))
}
pub fn path_scenario(map_name: &str, scenario_name: &str) -> String {
format!(
"{}/system/scenarios/{}/{}.bin",
*ROOT_DIR, map_name, scenario_name
)
path(format!(
"system/scenarios/{}/{}.bin",
map_name, scenario_name
))
}
pub fn path_all_scenarios(map_name: &str) -> String {
format!("{}/system/scenarios/{}", *ROOT_DIR, map_name)
path(format!("system/scenarios/{}", map_name))
}
pub fn path_synthetic_map(map_name: &str) -> String {
format!("{}/system/synthetic_maps/{}.json", *ROOT_DIR, map_name)
path(format!("system/synthetic_maps/{}.json", map_name))
}
pub fn path_all_synthetic_maps() -> String {
format!("{}/system/synthetic_maps", *ROOT_DIR)
path("system/synthetic_maps")
}
// Player data (Players edit this)
pub fn path_camera_state(map_name: &str) -> String {
format!("{}/player/camera_state/{}.json", *ROOT_DIR, map_name)
path(format!("player/camera_state/{}.json", map_name))
}
pub fn path_edits(map_name: &str, edits_name: &str) -> String {
format!(
"{}/player/edits/{}/{}.json",
*ROOT_DIR, map_name, edits_name
)
path(format!("player/edits/{}/{}.json", map_name, edits_name))
}
pub fn path_all_edits(map_name: &str) -> String {
format!("{}/player/edits/{}", *ROOT_DIR, map_name)
path(format!("player/edits/{}", map_name))
}
pub fn path_save(map_name: &str, edits_name: &str, run_name: &str, time: String) -> String {
format!(
"{}/player/saves/{}/{}_{}/{}.bin",
*ROOT_DIR, map_name, edits_name, run_name, time
)
path(format!(
"player/saves/{}/{}_{}/{}.bin",
map_name, edits_name, run_name, time
))
}
pub fn path_all_saves(map_name: &str, edits_name: &str, run_name: &str) -> String {
format!(
"{}/player/saves/{}/{}_{}",
*ROOT_DIR, map_name, edits_name, run_name
)
path(format!(
"player/saves/{}/{}_{}",
map_name, edits_name, run_name
))
}
// Input data (For developers to build maps, not needed at runtime)
pub fn path_popdat() -> String {
format!("{}/input/seattle/popdat.bin", *ROOT_DIR)
path("input/seattle/popdat.bin")
}
pub fn path_raw_map(map_name: &str) -> String {
format!("{}/input/raw_maps/{}.bin", *ROOT_DIR, map_name)
path(format!("input/raw_maps/{}.bin", map_name))
}
pub fn path_all_raw_maps() -> String {
format!("{}/input/raw_maps", *ROOT_DIR)
path("input/raw_maps")
}

View File

@ -124,7 +124,7 @@ fn load_scenario(wiz: &mut Wizard, ctx: &mut EventCtx, app: &mut App) -> Option<
fn choose_polygon(wiz: &mut Wizard, ctx: &mut EventCtx, _: &mut App) -> Option<Transition> {
// TODO Sorry, Seattle only right now
let name = wiz.wrap(ctx).choose_string("Edit which polygon?", || {
abstutil::list_all_objects("input/seattle/polygons/".to_string())
abstutil::list_all_objects(abstutil::path("input/seattle/polygons/"))
})?;
match LonLat::read_osmosis_polygon(format!("input/seattle/polygons/{}.poly", name)) {
Ok(pts) => Some(Transition::Replace(polygon::PolygonEditor::new(
@ -140,7 +140,7 @@ fn choose_polygon(wiz: &mut Wizard, ctx: &mut EventCtx, _: &mut App) -> Option<T
fn choose_kml(wiz: &mut Wizard, ctx: &mut EventCtx, app: &mut App) -> Option<Transition> {
// TODO Sorry, Seattle only right now
let path = wiz.wrap(ctx).choose_string("View what KML dataset?", || {
abstutil::list_dir(std::path::Path::new("input/seattle/"))
abstutil::list_dir(std::path::Path::new(&abstutil::path("input/seattle/")))
.into_iter()
.filter(|x| x.ends_with(".bin") && !x.ends_with("popdat.bin"))
.collect()

View File

@ -213,7 +213,7 @@ impl State for StoryMapEditor {
|| {
let mut list = Vec::new();
for (name, story) in abstutil::load_all_objects::<RecordedStoryMap>(
"player/stories".to_string(),
abstutil::path("player/stories"),
) {
if story.name == current {
continue;
@ -432,7 +432,10 @@ impl StoryMap {
})
.collect(),
};
abstutil::write_json(format!("player/stories/{}.json", story.name), &story);
abstutil::write_json(
abstutil::path(format!("player/stories/{}.json", story.name)),
&story,
);
}
}

View File

@ -395,7 +395,7 @@ fn make_load_edits(app: &App, mode: GameplayMode) -> Box<dyn State> {
abstutil::load_all_objects(abstutil::path_all_edits(app.primary.map.get_name()))
.into_iter()
.chain(abstutil::load_all_objects::<PermanentMapEdits>(
"system/proposals".to_string(),
abstutil::path("system/proposals"),
))
.filter_map(|(path, perma)| {
PermanentMapEdits::from_permanent(perma, &app.primary.map)

View File

@ -24,8 +24,8 @@ impl Game {
ctx: &mut EventCtx,
) -> Game {
let title = !opts.dev
&& !flags.sim_flags.load.contains("data/player/save")
&& !flags.sim_flags.load.contains("data/system/scenarios")
&& !flags.sim_flags.load.contains("player/save")
&& !flags.sim_flags.load.contains("system/scenarios")
&& maybe_mode.is_none();
let mut app = App::new(flags, opts, ctx, title);
@ -35,7 +35,7 @@ impl Game {
.current_flags
.sim_flags
.load
.starts_with("player/saves/")
.contains("player/saves/")
{
assert!(maybe_mode.is_none());
Some(app.primary.clear_sim())

View File

@ -331,7 +331,7 @@ impl Proposals {
let mut buttons = Vec::new();
let mut current_tab = Vec::new();
for (name, edits) in
abstutil::load_all_objects::<PermanentMapEdits>("system/proposals".to_string())
abstutil::load_all_objects::<PermanentMapEdits>(abstutil::path("system/proposals"))
{
if current == Some(name.clone()) {
let mut txt = Text::new();