mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-27 11:10:11 +00:00
refactor : 重构异步操作模块
This commit is contained in:
@@ -228,7 +228,18 @@ namespace YooAsset
|
|||||||
DebugUpdateRecording();
|
DebugUpdateRecording();
|
||||||
|
|
||||||
// 更新任务
|
// 更新任务
|
||||||
InternalUpdate();
|
// 注意:兜底隔离机制
|
||||||
|
// 说明:检测的异常源包含:I/O(解压/读写权限/磁盘满),平台差异等
|
||||||
|
try
|
||||||
|
{
|
||||||
|
InternalUpdate();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Status = EOperationStatus.Failed;
|
||||||
|
Error = ex.ToString();
|
||||||
|
YooLogger.Error($"Exception in {this.GetType().Name}.InternalUpdate : {ex}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDone && IsFinish == false)
|
if (IsDone && IsFinish == false)
|
||||||
@@ -353,7 +364,6 @@ namespace YooAsset
|
|||||||
public void WaitForAsyncComplete()
|
public void WaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
//TODO 防止异步操作被挂起陷入无限死循环!
|
//TODO 防止异步操作被挂起陷入无限死循环!
|
||||||
// 例如:文件解压任务或者文件导入任务!
|
|
||||||
if (Status == EOperationStatus.None)
|
if (Status == EOperationStatus.None)
|
||||||
{
|
{
|
||||||
StartOperation();
|
StartOperation();
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using System.Diagnostics;
|
|||||||
|
|
||||||
namespace YooAsset
|
namespace YooAsset
|
||||||
{
|
{
|
||||||
internal class OperationSystem
|
internal static class OperationSystem
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
[UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)]
|
[UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||||
@@ -57,11 +57,14 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
_isInitialize = true;
|
if (_isInitialize == false)
|
||||||
_watch = Stopwatch.StartNew();
|
{
|
||||||
|
_isInitialize = true;
|
||||||
|
_watch = Stopwatch.StartNew();
|
||||||
|
|
||||||
// 创建全局调度器
|
// 创建全局调度器
|
||||||
CreatePackageScheduler(GLOBAL_SCHEDULER_NAME, 0);
|
CreatePackageScheduler(GLOBAL_SCHEDULER_NAME, int.MaxValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -97,6 +100,7 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void DestroyAll()
|
public static void DestroyAll()
|
||||||
{
|
{
|
||||||
|
_isInitialize = false;
|
||||||
YooLogger.Log("Operation system destroy all !");
|
YooLogger.Log("Operation system destroy all !");
|
||||||
|
|
||||||
// 清空所有调度器
|
// 清空所有调度器
|
||||||
@@ -108,7 +112,6 @@ namespace YooAsset
|
|||||||
_schedulerList.Clear();
|
_schedulerList.Clear();
|
||||||
_schedulerListDirty = false;
|
_schedulerListDirty = false;
|
||||||
_createIndex = 0;
|
_createIndex = 0;
|
||||||
_isInitialize = false;
|
|
||||||
|
|
||||||
_watch = null;
|
_watch = null;
|
||||||
_frameTime = 0;
|
_frameTime = 0;
|
||||||
@@ -120,6 +123,8 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void CreatePackageScheduler(string packageName, int priority)
|
public static void CreatePackageScheduler(string packageName, int priority)
|
||||||
{
|
{
|
||||||
|
DebugCheckInitialize(packageName);
|
||||||
|
|
||||||
if (_schedulerDic.ContainsKey(packageName))
|
if (_schedulerDic.ContainsKey(packageName))
|
||||||
{
|
{
|
||||||
throw new YooInternalException($"Package scheduler already exists: {packageName}");
|
throw new YooInternalException($"Package scheduler already exists: {packageName}");
|
||||||
@@ -136,6 +141,8 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void DestroyPackageScheduler(string packageName)
|
public static void DestroyPackageScheduler(string packageName)
|
||||||
{
|
{
|
||||||
|
DebugCheckInitialize(packageName);
|
||||||
|
|
||||||
// 不允许销毁默认调度器
|
// 不允许销毁默认调度器
|
||||||
if (packageName == GLOBAL_SCHEDULER_NAME)
|
if (packageName == GLOBAL_SCHEDULER_NAME)
|
||||||
{
|
{
|
||||||
@@ -155,6 +162,8 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ClearPackageOperation(string packageName)
|
public static void ClearPackageOperation(string packageName)
|
||||||
{
|
{
|
||||||
|
DebugCheckInitialize(packageName);
|
||||||
|
|
||||||
var scheduler = GetScheduler(packageName);
|
var scheduler = GetScheduler(packageName);
|
||||||
scheduler.ClearAll();
|
scheduler.ClearAll();
|
||||||
}
|
}
|
||||||
@@ -164,6 +173,8 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void StartOperation(string packageName, AsyncOperationBase operation)
|
public static void StartOperation(string packageName, AsyncOperationBase operation)
|
||||||
{
|
{
|
||||||
|
DebugCheckInitialize(packageName);
|
||||||
|
|
||||||
var scheduler = GetScheduler(packageName);
|
var scheduler = GetScheduler(packageName);
|
||||||
scheduler.StartOperation(operation);
|
scheduler.StartOperation(operation);
|
||||||
}
|
}
|
||||||
@@ -179,15 +190,29 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 严格模式:非默认包裹必须先创建调度器
|
// 严格模式:非默认包裹必须先创建调度器
|
||||||
throw new YooInternalException($"Operation scheduler not found: {packageName}. Please call YooAssets.CreatePackage() first!");
|
throw new YooInternalException($"Operation scheduler not found: {packageName}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 调试信息
|
#region 调试信息
|
||||||
internal static List<DebugOperationInfo> GetDebugOperationInfos(string packageName)
|
internal static List<DebugOperationInfo> GetDebugOperationInfos(string packageName)
|
||||||
{
|
{
|
||||||
|
DebugCheckInitialize(packageName);
|
||||||
|
|
||||||
var scheduler = GetScheduler(packageName);
|
var scheduler = GetScheduler(packageName);
|
||||||
return scheduler.GetDebugOperationInfos();
|
return scheduler.GetDebugOperationInfos();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region 调试方法
|
||||||
|
[Conditional("DEBUG")]
|
||||||
|
private static void DebugCheckInitialize(string packageName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(packageName))
|
||||||
|
throw new YooInternalException("Package name is null or empty.");
|
||||||
|
|
||||||
|
if (_isInitialize == false)
|
||||||
|
throw new YooInternalException($"{nameof(OperationSystem)} not initialized !");
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,16 +227,16 @@ public static void StartOperation(string packageName, AsyncOperationBase operati
|
|||||||
|
|
||||||
#### 回调监听
|
#### 回调监听
|
||||||
|
|
||||||
```csharp
|
OperationSystem **当前未提供**全局任务开始/结束回调的注册接口。
|
||||||
/// <summary>
|
|
||||||
/// 注册任务开始回调
|
|
||||||
/// </summary>
|
|
||||||
public static void RegisterStartCallback(Action<string, AsyncOperationBase> callback);
|
|
||||||
|
|
||||||
/// <summary>
|
如需监听任务结束(推荐),请直接订阅具体任务的 `Completed` 事件:
|
||||||
/// 注册任务结束回调
|
|
||||||
/// </summary>
|
```csharp
|
||||||
public static void RegisterFinishCallback(Action<string, AsyncOperationBase> callback);
|
var operation = package.LoadAssetAsync<GameObject>(location);
|
||||||
|
operation.Completed += op =>
|
||||||
|
{
|
||||||
|
// TODO : 根据 op.Status 判断成功/失败
|
||||||
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -515,4 +515,4 @@ IEnumerator + IComparable<AsyncOperationBase>
|
|||||||
4. **子任务中止**:父操作中止时会自动中止所有子操作
|
4. **子任务中止**:父操作中止时会自动中止所有子操作
|
||||||
5. **回调异常**:`Completed` 回调中的异常会被捕获并记录,不会中断系统
|
5. **回调异常**:`Completed` 回调中的异常会被捕获并记录,不会中断系统
|
||||||
6. **编辑器重置**:编辑器中使用 `RuntimeInitializeOnLoadMethod` 自动重置状态
|
6. **编辑器重置**:编辑器中使用 `RuntimeInitializeOnLoadMethod` 自动重置状态
|
||||||
7. **循环保护**:在 `InternalWaitForAsyncComplete()` 中如果使用 `ExecuteWhileDone()`,内部默认有 1000 次执行保护,防止无限循环
|
7. **循环保护**:在 `InternalWaitForAsyncComplete()` 中建议使用 `RunBatchExecution()`(默认 1000 次)限制单次推进次数,避免陷入无限循环或长时间占用主线程
|
||||||
|
|||||||
Reference in New Issue
Block a user