refactor(SaveSystem): 拆分 Provider 还原契约为 sync/async 接口
This commit is contained in:
@@ -1,13 +1,12 @@
|
||||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream.SaveSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 快照提供者契约:将某一子系统的运行时状态与纯数据 DTO 互相转换。
|
||||
/// <para>
|
||||
/// 设计约定:DTO 不含事件、协程或 Unity 引用;<see cref="Capture"/> 只读,
|
||||
/// <see cref="Restore"/> 负责逐项写回。实现类通常很薄,实际逻辑在各 Manager 中。
|
||||
/// </para>
|
||||
/// 快照提供者契约:将某一子系统的运行时状态转换为纯数据 DTO。
|
||||
/// 还原侧由同步 / 异步子接口显式声明,避免 Provider 内部 fire-and-forget。
|
||||
/// </summary>
|
||||
public interface ISnapshotProvider
|
||||
{
|
||||
@@ -18,14 +17,62 @@ namespace AibisDream.SaveSystem
|
||||
string SaveId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 读档还原顺序。数值越小越先执行(如 scene=10 先于 actor=40)。
|
||||
/// 同阶段内的读档还原顺序。数值越小越先执行。
|
||||
/// </summary>
|
||||
int RestoreOrder { get; }
|
||||
|
||||
/// <summary>从当前运行时捕获该子系统的快照 DTO;无可存内容时可返回 null。</summary>
|
||||
object Capture();
|
||||
}
|
||||
|
||||
/// <summary>将 DTO 逐项还原到运行时;可为协程以等待异步加载。</summary>
|
||||
IEnumerator Restore(object dto);
|
||||
/// <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, bool strictMode = false, Action<string> logStep = null)
|
||||
{
|
||||
Snapshot = snapshot;
|
||||
StrictMode = strictMode;
|
||||
LogStep = logStep;
|
||||
}
|
||||
|
||||
public SaveSnapshot Snapshot { get; }
|
||||
public bool StrictMode { get; }
|
||||
public Action<string> LogStep { get; }
|
||||
|
||||
public void Log(string message)
|
||||
{
|
||||
LogStep?.Invoke(message);
|
||||
Debug.Log($"[SnapshotRestore] {message}");
|
||||
}
|
||||
|
||||
public void Warn(string message)
|
||||
{
|
||||
LogStep?.Invoke($"WARN: {message}");
|
||||
Debug.LogWarning($"[SnapshotRestore] {message}");
|
||||
}
|
||||
|
||||
public void Error(string message)
|
||||
{
|
||||
LogStep?.Invoke($"ERROR: {message}");
|
||||
Debug.LogError($"[SnapshotRestore] {message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream.SaveSystem
|
||||
@@ -7,7 +6,7 @@ namespace AibisDream.SaveSystem
|
||||
/// sections["actor"]:场景中各角色显隐、槽位、动画状态、透明度等(ActorManager)。
|
||||
/// RestoreOrder=40,依赖 scene 与 env 已就绪。
|
||||
/// </summary>
|
||||
public class ActorSnapshotProvider : ISnapshotProvider
|
||||
public class ActorSnapshotProvider : ISyncSnapshotProvider
|
||||
{
|
||||
public string SaveId => SnapshotProviderIds.Actor;
|
||||
public int RestoreOrder => 40;
|
||||
@@ -23,14 +22,21 @@ namespace AibisDream.SaveSystem
|
||||
return ActorManager.Instance.CaptureSnapshot();
|
||||
}
|
||||
|
||||
public IEnumerator Restore(object dto)
|
||||
public void Restore(object dto, SnapshotRestoreContext context)
|
||||
{
|
||||
if (dto is not ActorSnapshotDto actors)
|
||||
{
|
||||
yield break;
|
||||
context.Warn("[ActorSnapshotProvider] DTO 类型不匹配,跳过还原。");
|
||||
return;
|
||||
}
|
||||
|
||||
yield return ActorManager.Instance.RestoreSnapshot(actors);
|
||||
if (ActorManager.Instance == null)
|
||||
{
|
||||
context.Warn("[ActorSnapshotProvider] ActorManager 未初始化,跳过还原。");
|
||||
return;
|
||||
}
|
||||
|
||||
ActorManager.Instance.RestoreSnapshot(actors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Collections;
|
||||
using AibisDream.Kit;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -8,7 +7,7 @@ namespace AibisDream.SaveSystem
|
||||
/// sections["audio"]:FMOD 音乐/SFX 实例路径与 AMB 状态终态(AudioManager)。
|
||||
/// 不记录播放进度,读档后按路径重新 CreateInstance 并 start。
|
||||
/// </summary>
|
||||
public class AudioSnapshotProvider : ISnapshotProvider
|
||||
public class AudioSnapshotProvider : ISyncSnapshotProvider
|
||||
{
|
||||
public string SaveId => SnapshotProviderIds.Audio;
|
||||
public int RestoreOrder => 50;
|
||||
@@ -24,14 +23,21 @@ namespace AibisDream.SaveSystem
|
||||
return AudioManager.Instance.CaptureSnapshot();
|
||||
}
|
||||
|
||||
public IEnumerator Restore(object dto)
|
||||
public void Restore(object dto, SnapshotRestoreContext context)
|
||||
{
|
||||
if (dto is not AudioSnapshotDto audio)
|
||||
{
|
||||
yield break;
|
||||
context.Warn("[AudioSnapshotProvider] DTO 类型不匹配,跳过还原。");
|
||||
return;
|
||||
}
|
||||
|
||||
yield return AudioManager.Instance.RestoreSnapshot(audio);
|
||||
if (AudioManager.Instance == null)
|
||||
{
|
||||
context.Warn("[AudioSnapshotProvider] AudioManager 未初始化,跳过还原。");
|
||||
return;
|
||||
}
|
||||
|
||||
AudioManager.Instance.RestoreSnapshot(audio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream.SaveSystem
|
||||
@@ -7,7 +6,7 @@ namespace AibisDream.SaveSystem
|
||||
/// sections["env"]:场景内时间/天气(EnvironmentManager)。
|
||||
/// RestoreOrder=20,在 scene 加载完成后、macro 之前还原环境。
|
||||
/// </summary>
|
||||
public class EnvironmentSnapshotProvider : ISnapshotProvider
|
||||
public class EnvironmentSnapshotProvider : ISyncSnapshotProvider
|
||||
{
|
||||
public string SaveId => SnapshotProviderIds.Environment;
|
||||
public int RestoreOrder => 20;
|
||||
@@ -23,14 +22,21 @@ namespace AibisDream.SaveSystem
|
||||
return EnvironmentManager.Instance.CaptureSnapshot();
|
||||
}
|
||||
|
||||
public IEnumerator Restore(object dto)
|
||||
public void Restore(object dto, SnapshotRestoreContext context)
|
||||
{
|
||||
if (dto is not EnvironmentSnapshotDto env)
|
||||
{
|
||||
yield break;
|
||||
context.Warn("[EnvironmentSnapshotProvider] DTO 类型不匹配,跳过还原。");
|
||||
return;
|
||||
}
|
||||
|
||||
yield return EnvironmentManager.Instance.RestoreSnapshot(env);
|
||||
if (EnvironmentManager.Instance == null)
|
||||
{
|
||||
context.Warn("[EnvironmentSnapshotProvider] EnvironmentManager 未初始化,跳过还原。");
|
||||
return;
|
||||
}
|
||||
|
||||
EnvironmentManager.Instance.RestoreSnapshot(env);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace AibisDream.SaveSystem
|
||||
/// sections["fix"]:Fix 场景宏观状态(FixStateMachine)。
|
||||
/// RestoreOrder=65,在 timeline(60) 之后、screen(70) 之前。
|
||||
/// </summary>
|
||||
public class FixSnapshotProvider : ISnapshotProvider
|
||||
public class FixSnapshotProvider : IAsyncSnapshotProvider
|
||||
{
|
||||
public string SaveId => SnapshotProviderIds.Fix;
|
||||
public int RestoreOrder => 65;
|
||||
@@ -23,16 +23,17 @@ namespace AibisDream.SaveSystem
|
||||
return FixSystem.FixSystemCenter.Instance.CaptureSnapshot();
|
||||
}
|
||||
|
||||
public IEnumerator Restore(object dto)
|
||||
public IEnumerator RestoreAsync(object dto, SnapshotRestoreContext context)
|
||||
{
|
||||
if (dto is not FixSnapshotDto fix)
|
||||
{
|
||||
context.Warn("[FixSnapshotProvider] DTO 类型不匹配,跳过还原。");
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (FixSystem.FixSystemCenter.Instance == null)
|
||||
{
|
||||
Debug.LogWarning("[FixSnapshotProvider] FixSystemCenter 未初始化,跳过还原。");
|
||||
context.Warn("[FixSnapshotProvider] FixSystemCenter 未初始化,跳过还原。");
|
||||
yield break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
using System.Collections;
|
||||
|
||||
namespace AibisDream.SaveSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// sections["screen"]:屏幕饱和度与演出淡入淡出遮罩。
|
||||
/// 委托 <see cref="ScreenSnapshotHelper"/>;RestoreOrder=70,通常在表现类最后还原。
|
||||
/// </summary>
|
||||
public class ScreenSnapshotProvider : ISnapshotProvider
|
||||
public class ScreenSnapshotProvider : ISyncSnapshotProvider
|
||||
{
|
||||
public string SaveId => SnapshotProviderIds.Screen;
|
||||
public int RestoreOrder => 70;
|
||||
@@ -16,15 +14,15 @@ namespace AibisDream.SaveSystem
|
||||
return ScreenSnapshotHelper.Capture();
|
||||
}
|
||||
|
||||
public IEnumerator Restore(object dto)
|
||||
public void Restore(object dto, SnapshotRestoreContext context)
|
||||
{
|
||||
if (dto is not ScreenSnapshotDto screen)
|
||||
{
|
||||
yield break;
|
||||
context.Warn("[ScreenSnapshotProvider] DTO 类型不匹配,跳过还原。");
|
||||
return;
|
||||
}
|
||||
|
||||
ScreenSnapshotHelper.Restore(screen);
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace AibisDream.SaveSystem
|
||||
/// sections["timeline"]:各 PlayableDirector 的终/初态(TimelineCenter)。
|
||||
/// 按 D1.1 只存 AtStart/AtEnd/Stopped,不存时间轴中间帧。
|
||||
/// </summary>
|
||||
public class TimelineSnapshotProvider : ISnapshotProvider
|
||||
public class TimelineSnapshotProvider : IAsyncSnapshotProvider
|
||||
{
|
||||
public string SaveId => SnapshotProviderIds.Timeline;
|
||||
public int RestoreOrder => 60;
|
||||
@@ -23,15 +23,21 @@ namespace AibisDream.SaveSystem
|
||||
return TimelineCenter.Instance.CaptureSnapshot();
|
||||
}
|
||||
|
||||
public IEnumerator Restore(object dto)
|
||||
public IEnumerator RestoreAsync(object dto, SnapshotRestoreContext context)
|
||||
{
|
||||
if (dto is not TimelineSnapshotDto timeline)
|
||||
{
|
||||
context.Warn("[TimelineSnapshotProvider] DTO 类型不匹配,跳过还原。");
|
||||
yield break;
|
||||
}
|
||||
|
||||
TimelineCenter.Instance.RestoreSnapshot(timeline);
|
||||
yield break;
|
||||
if (TimelineCenter.Instance == null)
|
||||
{
|
||||
context.Warn("[TimelineSnapshotProvider] TimelineCenter 未初始化,跳过还原。");
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return TimelineCenter.Instance.RestoreSnapshotAsync(timeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user