97 lines
2.7 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|