110 lines
4.2 KiB
C#
110 lines
4.2 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 Day2SleepPresentation = "day2SleepPresentation";
|
||
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 Day2SleepPresentationSnapshotProvider());
|
||
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}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|