Files
ShrinkDataSaver.Integration…/Runtime/ShrinkDataSaverAppComponent.cs
T

92 lines
3.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#nullable enable
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using ShrinkApp;
using ShrinkContext;
using ShrinkDataSaver;
namespace ShrinkDataSaver.Integration.App
{
/// <summary>
/// ShrinkDataSaver 的原生 Cordis 组件(阶段 3):
/// - 提供 <c>shrink.service.datasaver</c> 余效应键(门面服务);
/// - 初始化为前向;停用时的终止动作为最终落盘设置(补偿式收尾:
/// 存档写入本身跨会话持久,不可严格求逆,以 flush 保证一致性,见论文 6.1 扣留与补偿);
/// - 与经典 ShrinkDataSaverAppInstaller(ModuleId "shrink.datasaver")二选一使用。
/// </summary>
public sealed class ShrinkDataSaverAppComponent : IShrinkComponent
{
public const string ServiceKey = "shrink.service.datasaver";
public const string ModuleKey = "app.module.shrink.datasaver";
private static readonly string[] ProvideKeys = { ModuleKey, ServiceKey };
private readonly ShrinkDataSaverRuntimeConfig? _runtimeConfig;
public ShrinkDataSaverAppComponent()
{
}
public ShrinkDataSaverAppComponent(ShrinkDataSaverRuntimeConfig? runtimeConfig)
{
_runtimeConfig = runtimeConfig;
}
public string Name => "shrink.datasaver";
public IReadOnlyList<string> Inject => Array.Empty<string>();
public IReadOnlyList<string> Provide => ProvideKeys;
public UniTask ApplyAsync(ShrinkCtx ctx, object? config)
{
ShrinkAppServices? appServices = null;
var runtimeConfig = _runtimeConfig ?? CreateDefaultRuntimeConfig();
if (config is ShrinkDataSaverAppModuleConfig moduleConfig)
{
appServices = moduleConfig.Services;
if (moduleConfig.RuntimeConfig != null)
runtimeConfig = moduleConfig.RuntimeConfig;
}
else if (config is ShrinkAppServices services)
{
appServices = services;
}
ShrinkDataSaverRuntime.Initialize(runtimeConfig);
var facade = new ShrinkDataSaverService();
ctx.Set(ServiceKey, facade, new ShrinkDataSaverAccessPolicy(facade));
ctx.Set(ModuleKey, Name);
if (appServices != null)
{
appServices.Register(facade);
ctx.EffectInverse(() =>
{
appServices.TryUnregister(facade);
return UniTask.CompletedTask;
});
}
ctx.EffectInverse(async () =>
{
await ShrinkSettings.SaveAsync();
});
return UniTask.CompletedTask;
}
private static ShrinkDataSaverRuntimeConfig CreateDefaultRuntimeConfig()
{
// 编辑器/EditMode 环境下 DontDestroyOnLoad 会抛异常,驱动只在播放模式常驻
return new ShrinkDataSaverRuntimeConfig
{
#if UNITY_5_3_OR_NEWER
DontDestroyOnLoadDriver = UnityEngine.Application.isPlaying
#else
DontDestroyOnLoadDriver = false
#endif
};
}
}
}