Files

107 lines
3.6 KiB
C#

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);
}
/// <summary>
/// 从运行时组装 <see cref="SaveSnapshot"/>(纯内存,不写盘)。
/// <para>
/// 流程:元数据 → 场景 → 锚点(含宏观章节)→ Yarn 变量 → 各 Provider.Capture。
/// scene / anchor 由框架直管;其余子系统通过 Provider 写入 sections。
/// </para>
/// </summary>
public static class SnapshotCapture
{
/// <summary>捕获当前完整快照。调用前需已注册全部 provider。</summary>
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()
};
}
}
}