This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
||||
namespace ShrinkContext
|
||||
{
|
||||
/// <summary>
|
||||
/// 单个可逆效应的句柄(论文算法 1 的 effect 封装)。
|
||||
/// 前向执行时产出逆操作并累积在句柄内部;DisposeAsync 至多执行一次(armed 语义),
|
||||
/// 若前向仍在进行中则先等待其完成再运行累积的逆操作(dispose = await task; recover())。
|
||||
/// </summary>
|
||||
public sealed class ShrinkEffectHandle
|
||||
{
|
||||
private static readonly Func<UniTask> Nop = static () => UniTask.CompletedTask;
|
||||
|
||||
private bool _armed = true;
|
||||
private UniTask _forwardTask;
|
||||
private bool _hasForwardTask;
|
||||
private Func<UniTask> _inverseChain = Nop;
|
||||
|
||||
public bool IsArmed => _armed;
|
||||
|
||||
/// <summary>登记一个进行中的异步前向;DisposeAsync 会先等待它完成。</summary>
|
||||
internal void BeginForward(UniTask forwardTask)
|
||||
{
|
||||
_forwardTask = forwardTask;
|
||||
_hasForwardTask = true;
|
||||
}
|
||||
|
||||
/// <summary>前向完成后登记其逆操作;新逆操作在链首执行(LIFO)。</summary>
|
||||
internal void CompleteForward(Func<UniTask> inverse)
|
||||
{
|
||||
if (inverse == null)
|
||||
return;
|
||||
|
||||
var previous = _inverseChain;
|
||||
_inverseChain = async () =>
|
||||
{
|
||||
await inverse();
|
||||
await previous();
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>直接附加逆操作(等效于前向已同步完成)。</summary>
|
||||
internal void AttachInverse(Func<UniTask> inverse) => CompleteForward(inverse);
|
||||
|
||||
public async UniTask DisposeAsync()
|
||||
{
|
||||
if (!_armed)
|
||||
return;
|
||||
|
||||
_armed = false;
|
||||
if (_hasForwardTask && _forwardTask.Status == UniTaskStatus.Pending)
|
||||
await _forwardTask;
|
||||
|
||||
var chain = _inverseChain;
|
||||
_inverseChain = Nop;
|
||||
await chain();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user