mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
TEngine 6
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
@@ -7,24 +8,32 @@ namespace YooAsset
|
||||
{
|
||||
public abstract class AsyncOperationBase : IEnumerator, IComparable<AsyncOperationBase>
|
||||
{
|
||||
// 用户请求的回调
|
||||
private Action<AsyncOperationBase> _callback;
|
||||
|
||||
// 是否已经完成
|
||||
internal bool IsFinish = false;
|
||||
private string _packageName = null;
|
||||
private int _whileFrame = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// 所属包裹
|
||||
/// 所有子任务
|
||||
/// </summary>
|
||||
public string PackageName { private set; get; }
|
||||
internal readonly List<AsyncOperationBase> Childs = new List<AsyncOperationBase>(10);
|
||||
|
||||
/// <summary>
|
||||
/// 优先级
|
||||
/// 等待异步执行完成
|
||||
/// </summary>
|
||||
internal bool IsWaitForAsyncComplete { private set; get; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否已经完成
|
||||
/// </summary>
|
||||
internal bool IsFinish { private set; get; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 任务优先级
|
||||
/// </summary>
|
||||
public uint Priority { set; get; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// 任务状态
|
||||
/// </summary>
|
||||
public EOperationStatus Status { get; protected set; } = EOperationStatus.None;
|
||||
|
||||
@@ -38,6 +47,17 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public float Progress { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属包裹名称
|
||||
/// </summary>
|
||||
public string PackageName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _packageName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否已经完成
|
||||
/// </summary>
|
||||
@@ -84,43 +104,139 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract void InternalOnStart();
|
||||
internal abstract void InternalOnUpdate();
|
||||
internal virtual void InternalOnAbort() { }
|
||||
internal abstract void InternalStart();
|
||||
internal abstract void InternalUpdate();
|
||||
internal virtual void InternalAbort()
|
||||
{
|
||||
}
|
||||
internal virtual void InternalWaitForAsyncComplete()
|
||||
{
|
||||
throw new System.NotImplementedException(this.GetType().Name);
|
||||
}
|
||||
internal virtual string InternalGetDesc()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置包裹名称
|
||||
/// </summary>
|
||||
internal void SetPackageName(string packageName)
|
||||
{
|
||||
PackageName = packageName;
|
||||
_packageName = packageName;
|
||||
}
|
||||
internal void SetStart()
|
||||
|
||||
/// <summary>
|
||||
/// 添加子任务
|
||||
/// </summary>
|
||||
internal void AddChildOperation(AsyncOperationBase child)
|
||||
{
|
||||
Status = EOperationStatus.Processing;
|
||||
InternalOnStart();
|
||||
#if UNITY_EDITOR
|
||||
if (Childs.Contains(child))
|
||||
throw new Exception($"The child node {child.GetType().Name} already exists !");
|
||||
#endif
|
||||
|
||||
Childs.Add(child);
|
||||
}
|
||||
internal void SetFinish()
|
||||
|
||||
/// <summary>
|
||||
/// 获取异步操作说明
|
||||
/// </summary>
|
||||
internal string GetOperationDesc()
|
||||
{
|
||||
IsFinish = true;
|
||||
|
||||
// 进度百分百完成
|
||||
Progress = 1f;
|
||||
|
||||
//注意:如果完成回调内发生异常,会导致Task无限期等待
|
||||
_callback?.Invoke(this);
|
||||
|
||||
if (_taskCompletionSource != null)
|
||||
_taskCompletionSource.TrySetResult(null);
|
||||
return InternalGetDesc();
|
||||
}
|
||||
internal void SetAbort()
|
||||
|
||||
/// <summary>
|
||||
/// 开始异步操作
|
||||
/// </summary>
|
||||
internal void StartOperation()
|
||||
{
|
||||
if (Status == EOperationStatus.None)
|
||||
{
|
||||
Status = EOperationStatus.Processing;
|
||||
|
||||
// 开始记录
|
||||
DebugBeginRecording();
|
||||
|
||||
// 开始任务
|
||||
InternalStart();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新异步操作
|
||||
/// </summary>
|
||||
internal void UpdateOperation()
|
||||
{
|
||||
if (IsDone == false)
|
||||
{
|
||||
// 更新记录
|
||||
DebugUpdateRecording();
|
||||
|
||||
// 更新任务
|
||||
InternalUpdate();
|
||||
}
|
||||
|
||||
if (IsDone && IsFinish == false)
|
||||
{
|
||||
IsFinish = true;
|
||||
|
||||
// 进度百分百完成
|
||||
Progress = 1f;
|
||||
|
||||
// 结束记录
|
||||
DebugEndRecording();
|
||||
|
||||
//注意:如果完成回调内发生异常,会导致Task无限期等待
|
||||
_callback?.Invoke(this);
|
||||
|
||||
if (_taskCompletionSource != null)
|
||||
_taskCompletionSource.TrySetResult(null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 终止异步任务
|
||||
/// </summary>
|
||||
internal void AbortOperation()
|
||||
{
|
||||
foreach (var child in Childs)
|
||||
{
|
||||
child.AbortOperation();
|
||||
}
|
||||
|
||||
if (IsDone == false)
|
||||
{
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = "user abort";
|
||||
YooLogger.Warning($"Async operaiton has been abort : {this.GetType().Name}");
|
||||
InternalOnAbort();
|
||||
YooLogger.Warning($"Async operaiton {this.GetType().Name} has been abort !");
|
||||
InternalAbort();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行While循环
|
||||
/// </summary>
|
||||
protected bool ExecuteWhileDone()
|
||||
{
|
||||
if (IsDone == false)
|
||||
{
|
||||
// 执行更新逻辑
|
||||
InternalUpdate();
|
||||
|
||||
// 当执行次数用完时
|
||||
_whileFrame--;
|
||||
if (_whileFrame <= 0)
|
||||
{
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"Operation {this.GetType().Name} failed to wait for async complete !";
|
||||
YooLogger.Error(Error);
|
||||
}
|
||||
}
|
||||
return IsDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空完成回调
|
||||
/// </summary>
|
||||
@@ -129,6 +245,77 @@ namespace YooAsset
|
||||
_callback = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 等待异步执行完毕
|
||||
/// </summary>
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
if (IsDone)
|
||||
return;
|
||||
|
||||
//TODO 防止异步操作被挂起陷入无限死循环!
|
||||
// 例如:文件解压任务或者文件导入任务!
|
||||
if (Status == EOperationStatus.None)
|
||||
{
|
||||
StartOperation();
|
||||
}
|
||||
|
||||
IsWaitForAsyncComplete = true;
|
||||
InternalWaitForAsyncComplete();
|
||||
}
|
||||
|
||||
#region 调试信息
|
||||
/// <summary>
|
||||
/// 开始的时间
|
||||
/// </summary>
|
||||
public string BeginTime = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 处理耗时(单位:毫秒)
|
||||
/// </summary>
|
||||
public long ProcessTime { protected set; get; }
|
||||
|
||||
// 加载耗时统计
|
||||
private Stopwatch _watch = null;
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void DebugBeginRecording()
|
||||
{
|
||||
if (_watch == null)
|
||||
{
|
||||
BeginTime = SpawnTimeToString(UnityEngine.Time.realtimeSinceStartup);
|
||||
_watch = Stopwatch.StartNew();
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void DebugUpdateRecording()
|
||||
{
|
||||
if (_watch != null)
|
||||
{
|
||||
ProcessTime = _watch.ElapsedMilliseconds;
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void DebugEndRecording()
|
||||
{
|
||||
if (_watch != null)
|
||||
{
|
||||
ProcessTime = _watch.ElapsedMilliseconds;
|
||||
_watch = null;
|
||||
}
|
||||
}
|
||||
|
||||
private string SpawnTimeToString(float spawnTime)
|
||||
{
|
||||
float h = UnityEngine.Mathf.FloorToInt(spawnTime / 3600f);
|
||||
float m = UnityEngine.Mathf.FloorToInt(spawnTime / 60f - h * 60f);
|
||||
float s = UnityEngine.Mathf.FloorToInt(spawnTime - m * 60f - h * 3600f);
|
||||
return h.ToString("00") + ":" + m.ToString("00") + ":" + s.ToString("00");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 排序接口实现
|
||||
public int CompareTo(AsyncOperationBase other)
|
||||
{
|
||||
|
@@ -3,18 +3,22 @@ namespace YooAsset
|
||||
{
|
||||
public abstract class GameAsyncOperation : AsyncOperationBase
|
||||
{
|
||||
internal override void InternalOnStart()
|
||||
internal override void InternalStart()
|
||||
{
|
||||
OnStart();
|
||||
}
|
||||
internal override void InternalOnUpdate()
|
||||
internal override void InternalUpdate()
|
||||
{
|
||||
OnUpdate();
|
||||
}
|
||||
internal override void InternalOnAbort()
|
||||
internal override void InternalAbort()
|
||||
{
|
||||
OnAbort();
|
||||
}
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
OnWaitForAsyncComplete();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步操作开始
|
||||
@@ -31,6 +35,11 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
protected abstract void OnAbort();
|
||||
|
||||
/// <summary>
|
||||
/// 异步等待完成
|
||||
/// </summary>
|
||||
protected virtual void OnWaitForAsyncComplete() { }
|
||||
|
||||
/// <summary>
|
||||
/// 异步操作系统是否繁忙
|
||||
/// </summary>
|
||||
@@ -38,5 +47,13 @@ namespace YooAsset
|
||||
{
|
||||
return OperationSystem.IsBusy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 终止异步操作
|
||||
/// </summary>
|
||||
protected void Abort()
|
||||
{
|
||||
AbortOperation();
|
||||
}
|
||||
}
|
||||
}
|
@@ -43,7 +43,14 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public static void Update()
|
||||
{
|
||||
_frameTime = _watch.ElapsedMilliseconds;
|
||||
// 移除已经完成的异步操作
|
||||
// 注意:移除上一帧完成的异步操作,方便调试器接收到完整的信息!
|
||||
for (int i = _operations.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var operation = _operations[i];
|
||||
if (operation.IsFinish)
|
||||
_operations.RemoveAt(i);
|
||||
}
|
||||
|
||||
// 添加新增的异步操作
|
||||
if (_newList.Count > 0)
|
||||
@@ -67,6 +74,7 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
// 更新进行中的异步操作
|
||||
_frameTime = _watch.ElapsedMilliseconds;
|
||||
for (int i = 0; i < _operations.Count; i++)
|
||||
{
|
||||
if (IsBusy)
|
||||
@@ -76,19 +84,7 @@ namespace YooAsset
|
||||
if (operation.IsFinish)
|
||||
continue;
|
||||
|
||||
if (operation.IsDone == false)
|
||||
operation.InternalOnUpdate();
|
||||
|
||||
if (operation.IsDone)
|
||||
operation.SetFinish();
|
||||
}
|
||||
|
||||
// 移除已经完成的异步操作
|
||||
for (int i = _operations.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var operation = _operations[i];
|
||||
if (operation.IsFinish)
|
||||
_operations.RemoveAt(i);
|
||||
operation.UpdateOperation();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +110,7 @@ namespace YooAsset
|
||||
{
|
||||
if (operation.PackageName == packageName)
|
||||
{
|
||||
operation.SetAbort();
|
||||
operation.AbortOperation();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +119,7 @@ namespace YooAsset
|
||||
{
|
||||
if (operation.PackageName == packageName)
|
||||
{
|
||||
operation.SetAbort();
|
||||
operation.AbortOperation();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,16 +131,41 @@ namespace YooAsset
|
||||
{
|
||||
_newList.Add(operation);
|
||||
operation.SetPackageName(packageName);
|
||||
operation.SetStart();
|
||||
operation.StartOperation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始处理异步操作类
|
||||
/// </summary>
|
||||
public static void StartOperation(AsyncOperationBase operation)
|
||||
#region 调试信息
|
||||
internal static List<DebugOperationInfo> GetDebugOperationInfos(string packageName)
|
||||
{
|
||||
_newList.Add(operation);
|
||||
operation.SetStart();
|
||||
List<DebugOperationInfo> result = new List<DebugOperationInfo>(_operations.Count);
|
||||
foreach (var operation in _operations)
|
||||
{
|
||||
if (operation.PackageName == packageName)
|
||||
{
|
||||
var operationInfo = GetDebugOperationInfo(operation);
|
||||
result.Add(operationInfo);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
internal static DebugOperationInfo GetDebugOperationInfo(AsyncOperationBase operation)
|
||||
{
|
||||
var operationInfo = new DebugOperationInfo();
|
||||
operationInfo.OperationName = operation.GetType().Name;
|
||||
operationInfo.OperationDesc = operation.GetOperationDesc();
|
||||
operationInfo.Priority = operation.Priority;
|
||||
operationInfo.Progress = operation.Progress;
|
||||
operationInfo.BeginTime = operation.BeginTime;
|
||||
operationInfo.ProcessTime = operation.ProcessTime;
|
||||
operationInfo.Status = operation.Status.ToString();
|
||||
operationInfo.Childs = new List<DebugOperationInfo>(operation.Childs.Count);
|
||||
foreach (var child in operation.Childs)
|
||||
{
|
||||
var childInfo = GetDebugOperationInfo(child);
|
||||
operationInfo.Childs.Add(childInfo);
|
||||
}
|
||||
return operationInfo;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user