using System; using UnityEngine; namespace AibisDream.SaveSystem { public readonly struct AnchorCaptureSpec { public string SceneSoName { get; } public string YarnProjectId { get; } public string NodeName { get; } public bool StartDialogueOnRestore { get; } public AnchorCaptureSpec( string sceneSoName, string yarnProjectId, string nodeName, bool startDialogueOnRestore) { SceneSoName = sceneSoName; YarnProjectId = yarnProjectId; NodeName = nodeName; StartDialogueOnRestore = startDialogueOnRestore; } public bool IsComplete => !string.IsNullOrWhiteSpace(SceneSoName) && !string.IsNullOrWhiteSpace(YarnProjectId) && !string.IsNullOrWhiteSpace(NodeName); } /// /// 从运行时组装 (纯内存,不写盘)。 /// /// 流程:元数据 → 场景 → 锚点(含宏观章节)→ Yarn 变量 → 各 Provider.Capture。 /// scene / anchor 由框架直管;其余子系统通过 Provider 写入 sections。 /// /// public static class SnapshotCapture { /// 捕获当前完整快照。调用前需已注册全部 provider。 public static SaveSnapshot Capture( YarnVariableStorage storage, AnchorCaptureSpec anchorSpec) { if (!anchorSpec.IsComplete) { throw new ArgumentException( "Snapshot anchor requires TalkScene, YarnProject and node name.", nameof(anchorSpec)); } SnapshotRegistry.ValidateRequiredProviders(); var snapshot = new SaveSnapshot { gameVersion = Application.version, savedAt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }; CaptureScene(snapshot); CaptureAnchor(snapshot, anchorSpec); CaptureYarnVariables(storage, snapshot); foreach (var provider in SnapshotRegistry.GetOrderedProviders()) { var dto = provider.Capture(); if (dto == null) continue; snapshot.sections[provider.SaveId] = dto; } snapshot.schemaVersion = SaveSnapshotSchema.CurrentVersion; return snapshot; } private static void CaptureScene(SaveSnapshot snapshot) { var sceneLoader = SceneLoader.Instance; snapshot.scene = new SceneSnapshotDto { sceneName = sceneLoader != null ? sceneLoader.CurrentSceneName : null }; } private static void CaptureAnchor(SaveSnapshot snapshot, AnchorCaptureSpec anchorSpec) { snapshot.anchor = new AnchorSnapshot { sceneSoName = anchorSpec.SceneSoName, yarnProjectId = anchorSpec.YarnProjectId, nodeName = anchorSpec.NodeName, startDialogueOnRestore = anchorSpec.StartDialogueOnRestore }; } private static void CaptureYarnVariables(YarnVariableStorage storage, SaveSnapshot snapshot) { var (floats, strings, bools) = storage.GetAllVariables(); snapshot.yarnVariables = new YarnVariablesSnapshot { floats = floats ?? new(), strings = strings ?? new(), bools = bools ?? new() }; } } }