Files
aibis-dream/Assets/Scripts/FrameAnimation/Runtime/FrameAnimationPlaybackHandle.cs
T

97 lines
2.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
namespace AibisDream.FrameAnimation
{
public sealed class FrameAnimationPlaybackHandle : CustomYieldInstruction
{
private readonly TaskCompletionSource<FrameAnimationPlaybackResult> completionSource =
new TaskCompletionSource<FrameAnimationPlaybackResult>(TaskCreationOptions.RunContinuationsAsynchronously);
private readonly List<Action<FrameAnimationPlaybackResult>> callbacks =
new List<Action<FrameAnimationPlaybackResult>>();
private bool isCompleted;
private FrameAnimationPlaybackResult result;
public long RequestId { get; }
public bool IsCompleted => isCompleted;
public override bool keepWaiting => !isCompleted;
public FrameAnimationPlaybackResult Result
{
get
{
if (!isCompleted)
{
throw new InvalidOperationException("播放请求尚未完成,不能读取 Result。");
}
return result;
}
}
internal FrameAnimationPlaybackHandle(long requestId)
{
RequestId = requestId;
}
public Task<FrameAnimationPlaybackResult> WaitAsync()
{
return completionSource.Task;
}
public void RegisterCompleted(Action<FrameAnimationPlaybackResult> callback)
{
if (callback == null)
{
throw new ArgumentNullException(nameof(callback));
}
if (isCompleted)
{
InvokeCallback(callback, result);
return;
}
callbacks.Add(callback);
}
internal bool TryComplete(FrameAnimationPlaybackResult completionResult)
{
if (isCompleted)
{
return false;
}
isCompleted = true;
result = completionResult;
completionSource.TrySetResult(completionResult);
var callbacksToInvoke = callbacks.ToArray();
callbacks.Clear();
foreach (var callback in callbacksToInvoke)
{
InvokeCallback(callback, completionResult);
}
return true;
}
private static void InvokeCallback(
Action<FrameAnimationPlaybackResult> callback,
FrameAnimationPlaybackResult completionResult)
{
try
{
callback(completionResult);
}
catch (Exception exception)
{
Debug.LogException(exception);
}
}
}
}