using System; using System.Diagnostics; using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; namespace YooAsset { public abstract class AsyncOperationBase : IEnumerator, IComparable { private Action _callback; private string _packageName = null; private int _whileFrame = 1000; /// /// 等待异步执行完成 /// internal bool IsWaitForAsyncComplete = false; /// /// 是否已经完成 /// internal bool IsFinish = false; /// /// 优先级 /// public uint Priority { set; get; } = 0; /// /// 状态 /// public EOperationStatus Status { get; protected set; } = EOperationStatus.None; /// /// 错误信息 /// public string Error { get; protected set; } /// /// 处理进度 /// public float Progress { get; protected set; } /// /// 所属包裹名称 /// public string PackageName { get { return _packageName; } } /// /// 是否已经完成 /// public bool IsDone { get { return Status == EOperationStatus.Failed || Status == EOperationStatus.Succeed; } } /// /// 完成事件 /// public event Action Completed { add { if (IsDone) value.Invoke(this); else _callback += value; } remove { _callback -= value; } } /// /// 异步操作任务 /// public Task Task { get { if (_taskCompletionSource == null) { _taskCompletionSource = new TaskCompletionSource(); if (IsDone) _taskCompletionSource.SetResult(null); } return _taskCompletionSource.Task; } } internal abstract void InternalOnStart(); internal abstract void InternalOnUpdate(); internal virtual void InternalOnAbort() { } internal virtual void InternalWaitForAsyncComplete() { throw new System.NotImplementedException(this.GetType().Name); } internal void SetPackageName(string packageName) { _packageName = packageName; } internal void SetStart() { Status = EOperationStatus.Processing; InternalOnStart(); } internal void SetFinish() { IsFinish = true; // 进度百分百完成 Progress = 1f; //注意:如果完成回调内发生异常,会导致Task无限期等待 _callback?.Invoke(this); if (_taskCompletionSource != null) _taskCompletionSource.TrySetResult(null); } internal void SetAbort() { if (IsDone == false) { Status = EOperationStatus.Failed; Error = "user abort"; YooLogger.Warning($"Async operaiton {this.GetType().Name} has been abort !"); InternalOnAbort(); } } /// /// 执行While循环 /// protected bool ExecuteWhileDone() { if (IsDone == false) { // 执行更新逻辑 InternalOnUpdate(); // 当执行次数用完时 _whileFrame--; if (_whileFrame <= 0) { Status = EOperationStatus.Failed; Error = $"Operation {this.GetType().Name} failed to wait for async complete !"; YooLogger.Error(Error); } } return IsDone; } /// /// 清空完成回调 /// protected void ClearCompletedCallback() { _callback = null; } /// /// 等待异步执行完毕 /// public void WaitForAsyncComplete() { if (IsDone) return; IsWaitForAsyncComplete = true; InternalWaitForAsyncComplete(); } #region 排序接口实现 public int CompareTo(AsyncOperationBase other) { return other.Priority.CompareTo(this.Priority); } #endregion #region 异步编程相关 bool IEnumerator.MoveNext() { return !IsDone; } void IEnumerator.Reset() { } object IEnumerator.Current => null; private TaskCompletionSource _taskCompletionSource; #endregion } }