144 lines
4.6 KiB
C#
144 lines
4.6 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace AibisDream.SaveSystem
|
|
{
|
|
[Serializable]
|
|
public sealed class RestoreOptions
|
|
{
|
|
public bool StrictValidation = true;
|
|
|
|
public static RestoreOptions Default => new()
|
|
{
|
|
StrictValidation = true
|
|
};
|
|
|
|
}
|
|
|
|
public sealed class RestoreResult
|
|
{
|
|
public bool Success { get; internal set; }
|
|
public bool Cancelled { get; internal set; }
|
|
public string FailedPhase { get; internal set; }
|
|
public IReadOnlyList<string> Errors { get; internal set; } = Array.Empty<string>();
|
|
public IReadOnlyList<string> Warnings { get; internal set; } = Array.Empty<string>();
|
|
public IReadOnlyList<string> Log { get; internal set; } = Array.Empty<string>();
|
|
public TalkSceneSO RestoredTalkScene { get; internal set; }
|
|
|
|
public static RestoreResult CreateFailure(string phase, string error)
|
|
{
|
|
return new RestoreResult
|
|
{
|
|
Success = false,
|
|
FailedPhase = phase,
|
|
Errors = new[] { error }
|
|
};
|
|
}
|
|
}
|
|
|
|
internal sealed class RestorePreparation
|
|
{
|
|
internal bool Success => Result?.Success == true;
|
|
internal SaveSnapshot Snapshot { get; set; }
|
|
internal TalkSceneSO TargetTalkScene { get; set; }
|
|
internal string SourceLabel { get; set; }
|
|
internal RestoreOptions Options { get; set; }
|
|
internal RestoreResult Result { get; set; } = new();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 快照提供者契约:将某一子系统的运行时状态转换为纯数据 DTO。
|
|
/// 还原侧由同步 / 异步子接口显式声明,避免 Provider 内部 fire-and-forget。
|
|
/// </summary>
|
|
public interface ISnapshotProvider
|
|
{
|
|
/// <summary>
|
|
/// 稳定显式 id,用作 <see cref="SaveSnapshot.sections"/> 的 key。
|
|
/// 见 <see cref="SnapshotProviderIds"/>,不使用 C# 类型全名。
|
|
/// </summary>
|
|
string SaveId { get; }
|
|
|
|
/// <summary>
|
|
/// 同阶段内的读档还原顺序。数值越小越先执行。
|
|
/// </summary>
|
|
int RestoreOrder { get; }
|
|
|
|
/// <summary>从当前运行时捕获该子系统的快照 DTO;无可存内容时可返回 null。</summary>
|
|
object Capture();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步快照还原 Provider。实现中不得启动 fire-and-forget 协程。
|
|
/// </summary>
|
|
public interface ISyncSnapshotProvider : ISnapshotProvider
|
|
{
|
|
void Restore(object dto, SnapshotRestoreContext context);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步快照还原 Provider。所有必须等待的加载 / 状态切换须通过此协程暴露给编排层。
|
|
/// </summary>
|
|
public interface IAsyncSnapshotProvider : ISnapshotProvider
|
|
{
|
|
IEnumerator RestoreAsync(object dto, SnapshotRestoreContext context);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 单次读档还原流程上下文。
|
|
/// </summary>
|
|
public sealed class SnapshotRestoreContext
|
|
{
|
|
public SnapshotRestoreContext(
|
|
SaveSnapshot snapshot,
|
|
TalkSceneSO targetTalkScene = null,
|
|
bool strictMode = false,
|
|
Action<string> logStep = null)
|
|
{
|
|
Snapshot = snapshot;
|
|
TargetTalkScene = targetTalkScene;
|
|
StrictMode = strictMode;
|
|
LogStep = logStep;
|
|
}
|
|
|
|
public SaveSnapshot Snapshot { get; }
|
|
public TalkSceneSO TargetTalkScene { get; }
|
|
public bool StrictMode { get; }
|
|
public Action<string> LogStep { get; }
|
|
public string CurrentPhase { get; private set; }
|
|
public IReadOnlyList<string> Warnings => _warnings;
|
|
public IReadOnlyList<string> Errors => _errors;
|
|
public bool HasErrors => _errors.Count > 0;
|
|
|
|
private readonly List<string> _warnings = new();
|
|
private readonly List<string> _errors = new();
|
|
|
|
public void SetPhase(string phase)
|
|
{
|
|
CurrentPhase = phase;
|
|
Log(phase);
|
|
}
|
|
|
|
public void Log(string message)
|
|
{
|
|
LogStep?.Invoke(message);
|
|
Debug.Log($"[SnapshotRestore] {message}");
|
|
}
|
|
|
|
public void Warn(string message)
|
|
{
|
|
_warnings.Add(message);
|
|
LogStep?.Invoke($"WARN: {message}");
|
|
Debug.LogWarning($"[SnapshotRestore] {message}");
|
|
}
|
|
|
|
public void Error(string message)
|
|
{
|
|
_errors.Add(message);
|
|
LogStep?.Invoke($"ERROR: {message}");
|
|
Debug.LogError($"[SnapshotRestore] {message}");
|
|
}
|
|
}
|
|
}
|