新增 showcase(order 69) 与 playTool(order 70) 两个快照 section, 分别持久化 SpriteShowcase 小图/大图与 PlayToolPanel 物品图/全屏图 的终态,读档时直接还原静止画面。SpriteShowcase 与 PlayToolPanel 补充快照捕获/还原与立即清理逻辑,GameManager 在卸载场景前清理 演出效果。screen 还原顺序顺延至 80。
108 lines
4.1 KiB
C#
108 lines
4.1 KiB
C#
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using UnityEngine;
|
||
|
||
namespace AibisDream.SaveSystem
|
||
{
|
||
/// <summary>
|
||
/// 快照 section 的稳定字符串 id。
|
||
/// 用于 JSON key、Provider 注册与反序列化,避免使用 AssemblyQualifiedName。
|
||
/// </summary>
|
||
public static class SnapshotProviderIds
|
||
{
|
||
public const string Environment = "env";
|
||
public const string Actor = "actor";
|
||
public const string Audio = "audio";
|
||
public const string Timeline = "timeline";
|
||
public const string Screen = "screen";
|
||
public const string PlayTool = "playTool";
|
||
public const string Showcase = "showcase";
|
||
public const string Subway = "subway";
|
||
public const string PunchTape = "punchTape";
|
||
public const string Fix = "fix";
|
||
public const string FixPanel = "fixPanel";
|
||
public const string BodyModule = "bodyModule";
|
||
public const string Eye = "eye";
|
||
|
||
/// <summary>
|
||
/// P1 应参与 Capture 的 provider 清单。
|
||
/// <see cref="SnapshotRegistry.ValidateRequiredProviders"/> 据此告警缺失项;不含深度维修。
|
||
/// scene 与 macro 已提升到 <see cref="SaveSnapshot"/> 根对象,由框架直管。
|
||
/// </summary>
|
||
public static readonly string[] RequiredForCapture =
|
||
{
|
||
Environment, Actor, Audio, Timeline, Subway, Fix, Showcase, PlayTool, Screen
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 运行时登记全部 <see cref="ISnapshotProvider"/>。
|
||
/// Capture/Restore 时按 <see cref="ISnapshotProvider.RestoreOrder"/> 迭代;
|
||
/// 不使用「谁注册了谁才存」的隐式行为,RequiredForCapture 用于显式校验。
|
||
/// </summary>
|
||
public static class SnapshotRegistry
|
||
{
|
||
private static readonly Dictionary<string, ISnapshotProvider> Providers = new();
|
||
private static bool _initialized;
|
||
|
||
/// <summary>幂等初始化:注册 P1 所需的全部 Provider。</summary>
|
||
public static void EnsureInitialized()
|
||
{
|
||
if (_initialized) return;
|
||
_initialized = true;
|
||
|
||
Register(new EnvironmentSnapshotProvider());
|
||
Register(new ActorSnapshotProvider());
|
||
Register(new AudioSnapshotProvider());
|
||
Register(new TimelineSnapshotProvider());
|
||
Register(new SubwaySnapshotProvider());
|
||
Register(new PunchTapeSnapshotProvider());
|
||
Register(new FixSnapshotProvider());
|
||
Register(new FixPanelSnapshotProvider());
|
||
Register(new BodyModuleSnapshotProvider());
|
||
Register(new EyeSnapshotProvider());
|
||
Register(new ShowcaseSnapshotProvider());
|
||
Register(new PlayToolSnapshotProvider());
|
||
Register(new ScreenSnapshotProvider());
|
||
}
|
||
|
||
/// <summary>注册 provider;同 SaveId 后者覆盖前者。</summary>
|
||
public static void Register(ISnapshotProvider provider)
|
||
{
|
||
if (provider == null) return;
|
||
Providers[provider.SaveId] = provider;
|
||
}
|
||
|
||
public static void Unregister(string saveId)
|
||
{
|
||
Providers.Remove(saveId);
|
||
}
|
||
|
||
public static bool TryGet(string saveId, out ISnapshotProvider provider)
|
||
{
|
||
return Providers.TryGetValue(saveId, out provider);
|
||
}
|
||
|
||
/// <summary>按 RestoreOrder 升序返回,供还原流水线使用。</summary>
|
||
public static IReadOnlyList<ISnapshotProvider> GetOrderedProviders()
|
||
{
|
||
return Providers.Values.OrderBy(p => p.RestoreOrder).ToList();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 校验 <see cref="SnapshotProviderIds.RequiredForCapture"/>;
|
||
/// 缺失时 <c>LogWarning</c> 但不阻断 Capture。
|
||
/// </summary>
|
||
public static void ValidateRequiredProviders()
|
||
{
|
||
foreach (var saveId in SnapshotProviderIds.RequiredForCapture)
|
||
{
|
||
if (!Providers.ContainsKey(saveId))
|
||
{
|
||
Debug.LogWarning($"[SnapshotRegistry] 缺少快照 provider: {saveId}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|