Files
pomomon-garden/src/features/savegame/components.rs

107 lines
2.8 KiB
Rust

use crate::prelude::*;
use std::fs;
use std::path::PathBuf;
#[derive(Resource, Clone, Debug)]
pub struct SavegamePath(pub PathBuf);
#[derive(Debug)]
pub struct SavegameInfo {
pub path: SavegamePath,
pub index: u32,
pub total_berries: u32,
pub completed_focus: u32,
}
#[derive(Deserialize)]
struct PartialSaveData {
session_tracker: PartialSessionTracker,
}
#[derive(Deserialize)]
struct PartialSessionTracker {
completed_focus_phases: u32,
}
impl SavegamePath {
pub fn new(index: u32) -> Self {
let base_path = get_internal_path().unwrap_or_else(|| {
println!(
"Could not determine platform-specific save directory. Falling back to `./saves/"
);
PathBuf::from("./saves/")
});
if let Err(e) = std::fs::create_dir_all(&base_path) {
panic!("Failed to create save directory at {:?}: {}", base_path, e);
}
Self(base_path.join(format!("savegame-{}.json", index)))
}
pub fn list() -> Vec<SavegameInfo> {
let mut savegames = Vec::new();
let Some(base_path) = get_internal_path() else {
return Vec::new();
};
if !base_path.exists() {
return Vec::new();
}
let Ok(entries) = fs::read_dir(base_path) else {
return Vec::new();
};
for entry in entries.flatten() {
let path = entry.path();
if path.extension().and_then(|s| s.to_str()) != Some("json") {
continue;
}
let Some(file_name) = path.file_stem().and_then(|s| s.to_str()) else {
continue;
};
if !file_name.starts_with("savegame-") {
continue;
}
let Ok(index) = file_name.trim_start_matches("savegame-").parse::<u32>() else {
continue;
};
let Ok(content) = fs::read_to_string(&path) else {
continue;
};
let Ok(data) = serde_json::from_str::<PartialSaveData>(&content) else {
continue;
};
savegames.push(SavegameInfo {
path: SavegamePath(path),
index,
total_berries: 0, // TODO: add total_berries
completed_focus: data.session_tracker.completed_focus_phases,
});
}
savegames.sort_by_key(|s| s.index);
savegames
}
pub fn next() -> Self {
let savegames = Self::list();
let next_index = savegames.last().map(|s| s.index + 1).unwrap_or(0);
Self::new(next_index)
}
}
#[derive(Component)]
pub enum RootMarker {
PopupSavegameLoad,
}
#[derive(Component)]
pub enum ButtonType {
SavegameLoad { savegame_path: SavegamePath },
SavegameDelete { savegame_path: SavegamePath },
PopupClose,
}