Files
aibis-dream/Assets/Scripts/SaveSystem/Development/TestSaveRecorder.cs
T
2026-07-24 13:16:03 +08:00

91 lines
3.3 KiB
C#

#if UNITY_EDITOR || DEVELOPMENT_BUILD
using System;
using System.Linq;
using System.Threading.Tasks;
using AibisDream.Utility;
using UnityEngine;
namespace AibisDream.SaveSystem
{
/// <summary>正式自动档成功后使用的非阻塞测试存档旁路。</summary>
public static class TestSaveRecorder
{
private static TestSaveRepository _repository;
public static bool IsRecording { get; private set; }
public static TestSaveRepository Repository =>
_repository ??= new TestSaveRepository(ConstRef.TestSavePath);
public static event Action LibraryChanged;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetRuntimeState()
{
IsRecording = false;
_repository = null;
}
public static void SetRecording(bool recording)
{
IsRecording = recording;
}
internal static TestSaveRecordRequest CreateRequest(SaveSnapshot snapshot, byte[] thumbnail)
{
if (!IsRecording
|| snapshot?.anchor == null
|| string.IsNullOrWhiteSpace(snapshot.anchor.sceneSoName)
|| string.IsNullOrWhiteSpace(snapshot.anchor.yarnProjectId)
|| string.IsNullOrWhiteSpace(snapshot.anchor.nodeName))
{
return null;
}
var anchor = snapshot.anchor;
var chapter = GameManager.Instance?.RuntimeChapters?
.FirstOrDefault(item =>
item != null
&& string.Equals(item.name, anchor.sceneSoName, StringComparison.Ordinal)
&& string.Equals(item.yarnProject?.name, anchor.yarnProjectId, StringComparison.Ordinal));
var dedupeKey = BuildDedupeKey(anchor.sceneSoName, anchor.yarnProjectId, anchor.nodeName);
return new TestSaveRecordRequest
{
Snapshot = snapshot,
Thumbnail = thumbnail,
DedupeKey = dedupeKey,
EntryId = TestSaveRepository.StableHash(dedupeKey),
ChapterId = chapter?.name ?? anchor.sceneSoName,
ChapterTitle = string.IsNullOrWhiteSpace(chapter?.title) ? anchor.sceneSoName : chapter.title,
SceneSoName = anchor.sceneSoName,
YarnProjectId = anchor.yarnProjectId,
NodeName = anchor.nodeName,
SceneName = snapshot.scene?.sceneName,
GameVersion = snapshot.gameVersion
};
}
internal static void Enqueue(TestSaveRecordRequest request)
{
if (request == null) return;
_ = Task.Run(() =>
{
try
{
Repository.Record(request);
LibraryChanged?.Invoke();
}
catch (Exception ex)
{
Debug.LogError($"[TestSaveRecorder] 测试存档旁路写入失败,不影响正式存档:{ex}");
}
});
}
public static string BuildDedupeKey(string sceneSoName, string yarnProjectId, string nodeName)
{
return $"{sceneSoName ?? string.Empty}\n{yarnProjectId ?? string.Empty}\n{nodeName ?? string.Empty}";
}
}
}
#endif