feat: 优化存档管理,添加异步加载槽位摘要功能,减少主菜单等待时间

This commit is contained in:
2026-05-20 18:18:30 +08:00
parent e50cf57321
commit bc7063fb95
7 changed files with 39 additions and 11 deletions

View File

@@ -221,6 +221,9 @@ namespace BaseGames.Core.Save
}
// ── 存档槽摘要 ────────────────────────────────────────────────────────
/// <summary>
/// 仅解析 Meta 和 Player 两个顶层字段,避免反序列化整个 SaveData 造成不必要的 GC 压力。
/// </summary>
public async Task<SlotSummary> GetSlotSummaryAsync(int slotIndex)
{
if (!_storage.Exists(slotIndex)) return null;
@@ -228,14 +231,14 @@ namespace BaseGames.Core.Save
if (json == null) return null;
try
{
var data = JsonConvert.DeserializeObject<SaveData>(json);
var root = Newtonsoft.Json.Linq.JObject.Parse(json);
return new SlotSummary
{
SlotIndex = slotIndex,
Playtime = data.Meta.Playtime,
LastSaved = data.Meta.LastSaved,
SceneName = data.Player?.Scene,
ActiveFormId = data.Player?.ActiveFormId,
Playtime = root["Meta"]?["Playtime"]?.Value<float>() ?? 0f,
LastSaved = root["Meta"]?["LastSaved"]?.Value<string>(),
SceneName = root["Player"]?["Scene"]?.Value<string>(),
ActiveFormId = root["Player"]?["ActiveFormId"]?.Value<string>(),
};
}
catch { return null; }

View File

@@ -25,10 +25,14 @@ namespace BaseGames.Core.Save
public async Task WriteAsync(int slotIndex, string json)
{
var path = GetPath(slotIndex);
// 先写临时文件再原子性替换,防止写入中途断电损坏存档
// 先写临时文件再原子性替换,防止写入中途断电损坏存档
// File.Replace 要求 destination 必须已存在;首次存档时直接 Move。
var tmp = path + ".tmp";
await File.WriteAllTextAsync(tmp, json);
File.Replace(tmp, path, path + ".bak", ignoreMetadataErrors: true);
if (File.Exists(path))
File.Replace(tmp, path, path + ".bak", ignoreMetadataErrors: true);
else
File.Move(tmp, path);
}
public async Task<string> ReadAsync(int slotIndex)

View File

@@ -34,7 +34,7 @@ namespace BaseGames.Core.Save
[Serializable]
public class SaveMeta
{
public string Version = "2.2";
public string Version = SaveMigrator.CurrentVersion;
public int SlotIndex;
public string LastSaved; // ISO 8601
public float Playtime;