mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-28 19:48:47 +00:00
Compare commits
7 Commits
f0563cce0b
...
a3f689d815
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3f689d815 | ||
|
|
d228e41df7 | ||
|
|
23032cc269 | ||
|
|
72f02bd73f | ||
|
|
a37663a8c2 | ||
|
|
f375d45bd6 | ||
|
|
3dd3d4ef76 |
@@ -108,14 +108,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,14 +108,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ namespace YooAsset
|
|||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
//注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
|
//注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
|
||||||
InternalUpdate();
|
RunOnceExecution();
|
||||||
}
|
}
|
||||||
public override void UnSuspendLoad()
|
public override void UnSuspendLoad()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -108,14 +108,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,14 +109,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,14 +88,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,7 +113,7 @@ namespace YooAsset
|
|||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
//注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
|
//注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
|
||||||
InternalUpdate();
|
RunOnceExecution();
|
||||||
}
|
}
|
||||||
public override void UnSuspendLoad()
|
public override void UnSuspendLoad()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -100,14 +100,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,14 +131,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,14 +197,141 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TUANJIE_1_7_OR_NEWER
|
||||||
|
/// <summary>
|
||||||
|
/// 加载团结文件
|
||||||
|
/// </summary>
|
||||||
|
internal class DBFSLoadInstantBundleOperation : FSLoadBundleOperation
|
||||||
|
{
|
||||||
|
private enum ESteps
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
LoadInstantBundle,
|
||||||
|
CheckResult,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly DefaultBuildinFileSystem _fileSystem;
|
||||||
|
private readonly PackageBundle _bundle;
|
||||||
|
private AssetBundleCreateRequest _createRequest;
|
||||||
|
private AssetBundle _assetBundle;
|
||||||
|
private Stream _managedStream;
|
||||||
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
|
||||||
|
internal DBFSLoadInstantBundleOperation(DefaultBuildinFileSystem fileSystem, PackageBundle bundle)
|
||||||
|
{
|
||||||
|
_fileSystem = fileSystem;
|
||||||
|
_bundle = bundle;
|
||||||
|
}
|
||||||
|
internal override void InternalStart()
|
||||||
|
{
|
||||||
|
DownloadProgress = 1f;
|
||||||
|
DownloadedBytes = _bundle.FileSize;
|
||||||
|
_steps = ESteps.LoadInstantBundle;
|
||||||
|
}
|
||||||
|
internal override void InternalUpdate()
|
||||||
|
{
|
||||||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_steps == ESteps.LoadInstantBundle)
|
||||||
{
|
{
|
||||||
if (ExecuteWhileDone())
|
if (_bundle.Encrypted)
|
||||||
|
{
|
||||||
|
if (_fileSystem.DecryptionServices == null)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
Status = EOperationStatus.Failed;
|
||||||
|
Error = $"The {nameof(IDecryptionServices)} is null !";
|
||||||
|
YooLogger.Error(Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsWaitForAsyncComplete)
|
||||||
|
{
|
||||||
|
if (_bundle.Encrypted)
|
||||||
|
{
|
||||||
|
var decryptResult = _fileSystem.LoadEncryptedAssetBundle(_bundle);
|
||||||
|
_assetBundle = decryptResult.Result;
|
||||||
|
_managedStream = decryptResult.ManagedStream;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string filePath = _fileSystem.GetBuildinFileLoadPath(_bundle);
|
||||||
|
_assetBundle = AssetBundle.LoadFromFile(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_bundle.Encrypted)
|
||||||
|
{
|
||||||
|
var decryptResult = _fileSystem.LoadEncryptedAssetBundleAsync(_bundle);
|
||||||
|
_createRequest = decryptResult.CreateRequest;
|
||||||
|
_managedStream = decryptResult.ManagedStream;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string filePath = _fileSystem.GetBuildinFileLoadPath(_bundle);
|
||||||
|
_createRequest = AssetBundle.LoadFromFileAsync(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_steps = ESteps.CheckResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.CheckResult)
|
||||||
|
{
|
||||||
|
if (_createRequest != null)
|
||||||
|
{
|
||||||
|
if (IsWaitForAsyncComplete)
|
||||||
|
{
|
||||||
|
// 强制挂起主线程(注意:该操作会很耗时)
|
||||||
|
YooLogger.Warning("Suspend the main thread to load unity bundle.");
|
||||||
|
_assetBundle = _createRequest.assetBundle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_createRequest.isDone == false)
|
||||||
|
return;
|
||||||
|
_assetBundle = _createRequest.assetBundle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_assetBundle == null)
|
||||||
|
{
|
||||||
|
if (_bundle.Encrypted)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
Status = EOperationStatus.Failed;
|
||||||
|
Error = $"Failed to load encrypted buildin asset bundle file : {_bundle.BundleName}";
|
||||||
|
YooLogger.Error(Error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
Status = EOperationStatus.Failed;
|
||||||
|
Error = $"Failed to load buildin asset bundle file : {_bundle.BundleName}";
|
||||||
|
YooLogger.Error(Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
break;
|
Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, _managedStream);
|
||||||
|
Status = EOperationStatus.Succeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
internal override void InternalWaitForAsyncComplete()
|
||||||
|
{
|
||||||
|
RunBatchExecution();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
@@ -262,14 +262,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,14 +412,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,7 @@ namespace YooAsset
|
|||||||
string bundleGUID = _allBundleGUIDs[i];
|
string bundleGUID = _allBundleGUIDs[i];
|
||||||
_fileSystem.DeleteCacheBundleFile(bundleGUID);
|
_fileSystem.DeleteCacheBundleFile(bundleGUID);
|
||||||
_allBundleGUIDs.RemoveAt(i);
|
_allBundleGUIDs.RemoveAt(i);
|
||||||
if (OperationSystem.IsBusy)
|
if (IsBusy)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ namespace YooAsset
|
|||||||
string bundleGUID = _clearBundleGUIDs[i];
|
string bundleGUID = _clearBundleGUIDs[i];
|
||||||
_fileSystem.DeleteCacheBundleFile(bundleGUID);
|
_fileSystem.DeleteCacheBundleFile(bundleGUID);
|
||||||
_clearBundleGUIDs.RemoveAt(i);
|
_clearBundleGUIDs.RemoveAt(i);
|
||||||
if (OperationSystem.IsBusy)
|
if (IsBusy)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ namespace YooAsset
|
|||||||
string bundleGUID = _clearBundleGUIDs[i];
|
string bundleGUID = _clearBundleGUIDs[i];
|
||||||
_fileSystem.DeleteCacheBundleFile(bundleGUID);
|
_fileSystem.DeleteCacheBundleFile(bundleGUID);
|
||||||
_clearBundleGUIDs.RemoveAt(i);
|
_clearBundleGUIDs.RemoveAt(i);
|
||||||
if (OperationSystem.IsBusy)
|
if (IsBusy)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ namespace YooAsset
|
|||||||
string bundleGUID = _unusedBundleGUIDs[i];
|
string bundleGUID = _unusedBundleGUIDs[i];
|
||||||
_fileSystem.DeleteCacheBundleFile(bundleGUID);
|
_fileSystem.DeleteCacheBundleFile(bundleGUID);
|
||||||
_unusedBundleGUIDs.RemoveAt(i);
|
_unusedBundleGUIDs.RemoveAt(i);
|
||||||
if (OperationSystem.IsBusy)
|
if (IsBusy)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,14 +124,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
internal override void InternalAbort()
|
internal override void InternalAbort()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -98,6 +98,10 @@ namespace YooAsset
|
|||||||
// 检测下载结果
|
// 检测下载结果
|
||||||
if (_steps == ESteps.CheckRequest)
|
if (_steps == ESteps.CheckRequest)
|
||||||
{
|
{
|
||||||
|
//TODO 更新下载后台,防止无限挂起
|
||||||
|
if (IsWaitForAsyncComplete)
|
||||||
|
_fileSystem.DownloadBackend.Update();
|
||||||
|
|
||||||
DownloadProgress = _request.DownloadProgress;
|
DownloadProgress = _request.DownloadProgress;
|
||||||
DownloadedBytes = _request.DownloadedBytes;
|
DownloadedBytes = _request.DownloadedBytes;
|
||||||
Progress = DownloadProgress;
|
Progress = DownloadProgress;
|
||||||
@@ -177,23 +181,12 @@ namespace YooAsset
|
|||||||
internal override void InternalAbort()
|
internal override void InternalAbort()
|
||||||
{
|
{
|
||||||
if (_request != null)
|
if (_request != null)
|
||||||
_request.AbortRequest();
|
_request.Dispose();
|
||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
//TODO 等待导入或解压本地文件完毕,该操作会挂起主线程!
|
||||||
{
|
RunUntilCompletion();
|
||||||
//TODO 更新下载后台,防止无限挂起
|
|
||||||
_fileSystem.DownloadBackend.Update();
|
|
||||||
|
|
||||||
//TODO 等待导入或解压本地文件完毕,该操作会挂起主线程!
|
|
||||||
InternalUpdate();
|
|
||||||
if (IsDone)
|
|
||||||
break;
|
|
||||||
|
|
||||||
//TODO 短暂休眠避免完全卡死
|
|
||||||
System.Threading.Thread.Sleep(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ namespace YooAsset
|
|||||||
internal override void InternalAbort()
|
internal override void InternalAbort()
|
||||||
{
|
{
|
||||||
if (_request != null)
|
if (_request != null)
|
||||||
_request.AbortRequest();
|
_request.Dispose();
|
||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -119,23 +119,16 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 中止所有下载任务
|
/// 释放下载资源
|
||||||
/// </summary>
|
|
||||||
public void AbortAll()
|
|
||||||
{
|
|
||||||
foreach (var valuePair in _downloaders)
|
|
||||||
{
|
|
||||||
valuePair.Value.AbortOperation();
|
|
||||||
}
|
|
||||||
_downloaders.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 释放资源
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
AbortAll();
|
foreach (var valuePair in _downloaders)
|
||||||
|
{
|
||||||
|
var operation = valuePair.Value;
|
||||||
|
operation.AbortOperation();
|
||||||
|
}
|
||||||
|
_downloaders.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ namespace YooAsset
|
|||||||
Result.Add(element);
|
Result.Add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OperationSystem.IsBusy)
|
if (IsBusy)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ namespace YooAsset
|
|||||||
|
|
||||||
for (int i = _waitingList.Count - 1; i >= 0; i--)
|
for (int i = _waitingList.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (OperationSystem.IsBusy)
|
if (IsBusy)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (_verifyingList.Count >= _verifyMaxNum)
|
if (_verifyingList.Count >= _verifyMaxNum)
|
||||||
|
|||||||
@@ -69,16 +69,8 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
//TODO 等待子线程验证文件完毕,该操作会挂起主线程!
|
||||||
{
|
RunUntilCompletion();
|
||||||
//TODO 等待子线程验证文件完毕,该操作会挂起主线程!
|
|
||||||
InternalUpdate();
|
|
||||||
if (IsDone)
|
|
||||||
break;
|
|
||||||
|
|
||||||
//TODO 短暂休眠避免完全卡死
|
|
||||||
System.Threading.Thread.Sleep(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VerifyInThread(object obj)
|
private void VerifyInThread(object obj)
|
||||||
|
|||||||
@@ -142,14 +142,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ namespace YooAsset
|
|||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Status = EOperationStatus.Failed;
|
Status = EOperationStatus.Failed;
|
||||||
Error = "WebGL platform not support sync load method !";
|
Error = "WebGL platform not support sync load method !";
|
||||||
UnityEngine.Debug.LogError(Error);
|
YooLogger.Error(Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ namespace YooAsset
|
|||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Status = EOperationStatus.Failed;
|
Status = EOperationStatus.Failed;
|
||||||
Error = "WebGL platform not support sync load method !";
|
Error = "WebGL platform not support sync load method !";
|
||||||
UnityEngine.Debug.LogError(Error);
|
YooLogger.Error(Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,31 +3,109 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
public class FileSystemParametersDefine
|
public class FileSystemParametersDefine
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化的时候缓存文件校验级别 <see cref=EFileVerifyLevel>
|
||||||
|
/// </summary>
|
||||||
public const string FILE_VERIFY_LEVEL = "FILE_VERIFY_LEVEL";
|
public const string FILE_VERIFY_LEVEL = "FILE_VERIFY_LEVEL";
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化的时候缓存文件校验最大并发数 <see cref=int>
|
||||||
|
/// </summary>
|
||||||
public const string FILE_VERIFY_MAX_CONCURRENCY = "FILE_VERIFY_MAX_CONCURRENCY";
|
public const string FILE_VERIFY_MAX_CONCURRENCY = "FILE_VERIFY_MAX_CONCURRENCY";
|
||||||
|
/// <summary>
|
||||||
|
/// 覆盖安装缓存清理模式 <see cref=EOverwriteInstallClearMode>
|
||||||
|
/// </summary>
|
||||||
public const string INSTALL_CLEAR_MODE = "INSTALL_CLEAR_MODE";
|
public const string INSTALL_CLEAR_MODE = "INSTALL_CLEAR_MODE";
|
||||||
|
/// <summary>
|
||||||
|
/// 远端资源地址查询服务类 <see cref=IRemoteServices>
|
||||||
|
/// </summary>
|
||||||
public const string REMOTE_SERVICES = "REMOTE_SERVICES";
|
public const string REMOTE_SERVICES = "REMOTE_SERVICES";
|
||||||
|
/// <summary>
|
||||||
|
/// 解密服务接口的实例类 <see cref=IDecryptionServices>
|
||||||
|
/// </summary>
|
||||||
public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES";
|
public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES";
|
||||||
|
/// <summary>
|
||||||
|
/// 资源清单服务类 <see cref=IManifestRestoreServices>
|
||||||
|
/// </summary>
|
||||||
public const string MANIFEST_SERVICES = "MANIFEST_SERVICES";
|
public const string MANIFEST_SERVICES = "MANIFEST_SERVICES";
|
||||||
|
/// <summary>
|
||||||
|
/// 数据文件追加文件格式 <see cref=bool>
|
||||||
|
/// </summary>
|
||||||
public const string APPEND_FILE_EXTENSION = "APPEND_FILE_EXTENSION";
|
public const string APPEND_FILE_EXTENSION = "APPEND_FILE_EXTENSION";
|
||||||
|
/// <summary>
|
||||||
|
/// 禁用Catalog目录查询文件 <see cref=bool>
|
||||||
|
/// </summary>
|
||||||
public const string DISABLE_CATALOG_FILE = "DISABLE_CATALOG_FILE";
|
public const string DISABLE_CATALOG_FILE = "DISABLE_CATALOG_FILE";
|
||||||
|
/// <summary>
|
||||||
|
/// 禁用Unity的网络缓存 <see cref=bool>
|
||||||
|
/// </summary>
|
||||||
public const string DISABLE_UNITY_WEB_CACHE = "DISABLE_UNITY_WEB_CACHE";
|
public const string DISABLE_UNITY_WEB_CACHE = "DISABLE_UNITY_WEB_CACHE";
|
||||||
|
/// <summary>
|
||||||
|
/// 禁用边玩边下机制 <see cref=bool>
|
||||||
|
/// </summary>
|
||||||
public const string DISABLE_ONDEMAND_DOWNLOAD = "DISABLE_ONDEMAND_DOWNLOAD";
|
public const string DISABLE_ONDEMAND_DOWNLOAD = "DISABLE_ONDEMAND_DOWNLOAD";
|
||||||
|
/// <summary>
|
||||||
|
/// UnityWebRequest 创建委托 <see cref=UnityWebRequestCreator>
|
||||||
|
/// </summary>
|
||||||
public const string UNITY_WEB_REQUEST_CREATOR = "UNITY_WEB_REQUEST_CREATOR";
|
public const string UNITY_WEB_REQUEST_CREATOR = "UNITY_WEB_REQUEST_CREATOR";
|
||||||
|
/// <summary>
|
||||||
|
/// 下载后台接口 <see cref=IDownloadBackend>
|
||||||
|
/// </summary>
|
||||||
public const string DOWNLOAD_BACKEND = "DOWNLOAD_BACKEND";
|
public const string DOWNLOAD_BACKEND = "DOWNLOAD_BACKEND";
|
||||||
|
/// <summary>
|
||||||
|
/// 最大并发连接数 默认值:10(推荐范围 1-32) <see cref=int>
|
||||||
|
/// </summary>
|
||||||
public const string DOWNLOAD_MAX_CONCURRENCY = "DOWNLOAD_MAX_CONCURRENCY";
|
public const string DOWNLOAD_MAX_CONCURRENCY = "DOWNLOAD_MAX_CONCURRENCY";
|
||||||
|
/// <summary>
|
||||||
|
/// 每帧发起的最大请求数 默认值:5(推荐范围 1-10)<see cref=int>
|
||||||
|
/// </summary>
|
||||||
public const string DOWNLOAD_MAX_REQUEST_PER_FRAME = "DOWNLOAD_MAX_REQUEST_PER_FRAME";
|
public const string DOWNLOAD_MAX_REQUEST_PER_FRAME = "DOWNLOAD_MAX_REQUEST_PER_FRAME";
|
||||||
|
/// <summary>
|
||||||
|
/// 下载任务的看门狗机制监控时间 <see cref=int>
|
||||||
|
/// </summary>
|
||||||
public const string DOWNLOAD_WATCH_DOG_TIME = "DOWNLOAD_WATCH_DOG_TIME";
|
public const string DOWNLOAD_WATCH_DOG_TIME = "DOWNLOAD_WATCH_DOG_TIME";
|
||||||
|
/// <summary>
|
||||||
|
/// 启用断点续传的最小尺寸 <see cref=long>
|
||||||
|
/// </summary>
|
||||||
public const string RESUME_DOWNLOAD_MINMUM_SIZE = "RESUME_DOWNLOAD_MINMUM_SIZE";
|
public const string RESUME_DOWNLOAD_MINMUM_SIZE = "RESUME_DOWNLOAD_MINMUM_SIZE";
|
||||||
|
/// <summary>
|
||||||
|
/// 断点续传下载器关注的错误码 <see cref=List<long>>
|
||||||
|
/// </summary>
|
||||||
public const string RESUME_DOWNLOAD_RESPONSE_CODES = "RESUME_DOWNLOAD_RESPONSE_CODES";
|
public const string RESUME_DOWNLOAD_RESPONSE_CODES = "RESUME_DOWNLOAD_RESPONSE_CODES";
|
||||||
|
/// <summary>
|
||||||
|
/// 模拟WebGL平台模式 <see cref=bool>
|
||||||
|
/// </summary>
|
||||||
public const string VIRTUAL_WEBGL_MODE = "VIRTUAL_WEBGL_MODE";
|
public const string VIRTUAL_WEBGL_MODE = "VIRTUAL_WEBGL_MODE";
|
||||||
|
/// <summary>
|
||||||
|
/// 模拟虚拟下载模式 <see cref=bool>
|
||||||
|
/// </summary>
|
||||||
public const string VIRTUAL_DOWNLOAD_MODE = "VIRTUAL_DOWNLOAD_MODE";
|
public const string VIRTUAL_DOWNLOAD_MODE = "VIRTUAL_DOWNLOAD_MODE";
|
||||||
|
/// <summary>
|
||||||
|
/// 模拟虚拟下载的网速(单位:字节) <see cref=int>
|
||||||
|
/// </summary>
|
||||||
public const string VIRTUAL_DOWNLOAD_SPEED = "VIRTUAL_DOWNLOAD_SPEED";
|
public const string VIRTUAL_DOWNLOAD_SPEED = "VIRTUAL_DOWNLOAD_SPEED";
|
||||||
|
/// <summary>
|
||||||
|
/// 异步模拟加载最小帧数 <see cref=int>
|
||||||
|
/// </summary>
|
||||||
public const string ASYNC_SIMULATE_MIN_FRAME = "ASYNC_SIMULATE_MIN_FRAME";
|
public const string ASYNC_SIMULATE_MIN_FRAME = "ASYNC_SIMULATE_MIN_FRAME";
|
||||||
|
/// <summary>
|
||||||
|
/// 异步模拟加载最大帧数 <see cref=int>
|
||||||
|
/// </summary>
|
||||||
public const string ASYNC_SIMULATE_MAX_FRAME = "ASYNC_SIMULATE_MAX_FRAME";
|
public const string ASYNC_SIMULATE_MAX_FRAME = "ASYNC_SIMULATE_MAX_FRAME";
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝内置清单 <see cref=bool>
|
||||||
|
/// </summary>
|
||||||
public const string COPY_BUILDIN_PACKAGE_MANIFEST = "COPY_BUILDIN_PACKAGE_MANIFEST";
|
public const string COPY_BUILDIN_PACKAGE_MANIFEST = "COPY_BUILDIN_PACKAGE_MANIFEST";
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝内置清单的目标目录 <see cref=string>
|
||||||
|
/// </summary>
|
||||||
public const string COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT = "COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT";
|
public const string COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT = "COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT";
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝内置文件接口的实例类 <see cref=ICopyLocalFileServices>
|
||||||
|
/// </summary>
|
||||||
public const string COPY_LOCAL_FILE_SERVICES = "COPY_LOCAL_FILE_SERVICES";
|
public const string COPY_LOCAL_FILE_SERVICES = "COPY_LOCAL_FILE_SERVICES";
|
||||||
|
/// <summary>
|
||||||
|
/// 解压文件系统的根目录 <see cref=string>
|
||||||
|
/// </summary>
|
||||||
public const string UNPACK_FILE_SYSTEM_ROOT = "UNPACK_FILE_SYSTEM_ROOT";
|
public const string UNPACK_FILE_SYSTEM_ROOT = "UNPACK_FILE_SYSTEM_ROOT";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,9 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
public abstract class AsyncOperationBase : IEnumerator, IComparable<AsyncOperationBase>
|
public abstract class AsyncOperationBase : IEnumerator, IComparable<AsyncOperationBase>
|
||||||
{
|
{
|
||||||
|
private List<AsyncOperationBase> _childs;
|
||||||
private Action<AsyncOperationBase> _callback;
|
private Action<AsyncOperationBase> _callback;
|
||||||
private string _packageName = null;
|
private uint _priority = 0;
|
||||||
private int _whileFrame = 1000;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 所有子任务
|
|
||||||
/// </summary>
|
|
||||||
internal readonly List<AsyncOperationBase> Childs = new List<AsyncOperationBase>(10);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 等待异步执行完成
|
/// 等待异步执行完成
|
||||||
@@ -27,10 +22,41 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal bool IsFinish { private set; get; } = false;
|
internal bool IsFinish { private set; get; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步系统是否繁忙
|
||||||
|
/// </summary>
|
||||||
|
internal bool IsBusy
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (IsWaitForAsyncComplete)
|
||||||
|
return false;
|
||||||
|
return OperationSystem.IsBusy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 标记脏(用于调度器检测并重排)
|
||||||
|
/// </summary>
|
||||||
|
internal bool IsDirty { set; get; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 任务优先级
|
/// 任务优先级
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint Priority { set; get; } = 0;
|
public uint Priority
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_priority == value)
|
||||||
|
return;
|
||||||
|
_priority = value;
|
||||||
|
IsDirty = true;
|
||||||
|
}
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _priority;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 任务状态
|
/// 任务状态
|
||||||
@@ -47,17 +73,6 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public float Progress { get; protected set; }
|
public float Progress { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 所属包裹名称
|
|
||||||
/// </summary>
|
|
||||||
public string PackageName
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _packageName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否已经完成
|
/// 是否已经完成
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -76,10 +91,24 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
add
|
add
|
||||||
{
|
{
|
||||||
|
if (value == null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (IsDone)
|
if (IsDone)
|
||||||
value.Invoke(this);
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
value.Invoke(this);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
YooLogger.Error($"Exception in completion callback: {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
_callback += value;
|
_callback += value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
remove
|
remove
|
||||||
{
|
{
|
||||||
@@ -111,32 +140,27 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal virtual void InternalWaitForAsyncComplete()
|
internal virtual void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException(this.GetType().Name);
|
throw new YooInternalException($"InternalWaitForAsyncComplete() not implemented : {this.GetType().Name}");
|
||||||
}
|
}
|
||||||
internal virtual string InternalGetDesc()
|
internal virtual string InternalGetDesc()
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设置包裹名称
|
|
||||||
/// </summary>
|
|
||||||
internal void SetPackageName(string packageName)
|
|
||||||
{
|
|
||||||
_packageName = packageName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加子任务
|
/// 添加子任务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal void AddChildOperation(AsyncOperationBase child)
|
internal void AddChildOperation(AsyncOperationBase child)
|
||||||
{
|
{
|
||||||
|
if (_childs == null)
|
||||||
|
_childs = new List<AsyncOperationBase>(10);
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
if (Childs.Contains(child))
|
if (_childs.Contains(child))
|
||||||
throw new YooInternalException($"The child node {child.GetType().Name} already exists !");
|
throw new YooInternalException($"The child node {child.GetType().Name} already exists !");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Childs.Add(child);
|
_childs.Add(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -144,12 +168,15 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal void RemoveChildOperation(AsyncOperationBase child)
|
internal void RemoveChildOperation(AsyncOperationBase child)
|
||||||
{
|
{
|
||||||
|
if (_childs == null)
|
||||||
|
return;
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
if (Childs.Contains(child) == false)
|
if (_childs.Contains(child) == false)
|
||||||
throw new YooInternalException($"The child node {child.GetType().Name} not exists !");
|
throw new YooInternalException($"The child node {child.GetType().Name} not exists !");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Childs.Remove(child);
|
_childs.Remove(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -193,9 +220,40 @@ namespace YooAsset
|
|||||||
|
|
||||||
if (IsDone && IsFinish == false)
|
if (IsDone && IsFinish == false)
|
||||||
{
|
{
|
||||||
IsFinish = true;
|
FinishOperation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 进度百分百完成
|
/// <summary>
|
||||||
|
/// 终止异步任务
|
||||||
|
/// </summary>
|
||||||
|
internal void AbortOperation()
|
||||||
|
{
|
||||||
|
if (_childs != null)
|
||||||
|
{
|
||||||
|
foreach (var child in _childs)
|
||||||
|
{
|
||||||
|
child.AbortOperation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsDone == false)
|
||||||
|
{
|
||||||
|
InternalAbort();
|
||||||
|
Status = EOperationStatus.Failed;
|
||||||
|
Error = "user abort";
|
||||||
|
YooLogger.Warning($"Async operation {this.GetType().Name} has been aborted !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 强制结束异步任务
|
||||||
|
/// </summary>
|
||||||
|
internal void FinishOperation()
|
||||||
|
{
|
||||||
|
if (IsFinish == false)
|
||||||
|
{
|
||||||
|
IsFinish = true;
|
||||||
Progress = 1f;
|
Progress = 1f;
|
||||||
|
|
||||||
// 结束记录
|
// 结束记录
|
||||||
@@ -211,6 +269,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
_callback = null;
|
||||||
if (_taskCompletionSource != null)
|
if (_taskCompletionSource != null)
|
||||||
_taskCompletionSource.TrySetResult(null);
|
_taskCompletionSource.TrySetResult(null);
|
||||||
}
|
}
|
||||||
@@ -218,52 +277,63 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 终止异步任务
|
/// 执行一次更新逻辑
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal void AbortOperation()
|
protected void RunOnceExecution()
|
||||||
{
|
{
|
||||||
foreach (var child in Childs)
|
if (IsDone)
|
||||||
{
|
return;
|
||||||
child.AbortOperation();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDone == false)
|
UpdateOperation();
|
||||||
{
|
|
||||||
Status = EOperationStatus.Failed;
|
|
||||||
Error = "user abort";
|
|
||||||
YooLogger.Warning($"Async operaiton {this.GetType().Name} has been abort !");
|
|
||||||
InternalAbort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 执行While循环
|
/// 批量执行一定次数的更新逻辑
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected bool ExecuteWhileDone()
|
/// <param name="count">次数</param>
|
||||||
|
protected void RunBatchExecution(int count = 1000)
|
||||||
{
|
{
|
||||||
if (IsDone == false)
|
if (IsDone)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int runCount = count;
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
// 执行更新逻辑
|
// 执行更新逻辑
|
||||||
InternalUpdate();
|
UpdateOperation();
|
||||||
|
if (IsDone)
|
||||||
|
break;
|
||||||
|
|
||||||
// 当执行次数用完时
|
// 当执行次数用完时
|
||||||
_whileFrame--;
|
runCount--;
|
||||||
if (_whileFrame <= 0)
|
if (runCount <= 0)
|
||||||
{
|
{
|
||||||
Status = EOperationStatus.Failed;
|
Status = EOperationStatus.Failed;
|
||||||
Error = $"Operation {this.GetType().Name} failed to wait for async complete !";
|
Error = $"Operation {this.GetType().Name} failed to wait for async complete !";
|
||||||
YooLogger.Error(Error);
|
YooLogger.Error(Error);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return IsDone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 清空完成回调
|
/// 无限次数的执行更新逻辑,直到任务完成
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected void ClearCompletedCallback()
|
/// <param name="sleepMS">休眠时长</param>
|
||||||
|
protected void RunUntilCompletion(int sleepMS = 1)
|
||||||
{
|
{
|
||||||
_callback = null;
|
if (IsDone)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
UpdateOperation();
|
||||||
|
if (IsDone)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 注意: 短暂休眠避免完全占用CPU资源
|
||||||
|
System.Threading.Thread.Sleep(sleepMS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -338,6 +408,34 @@ namespace YooAsset
|
|||||||
float s = UnityEngine.Mathf.FloorToInt(spawnTime - m * 60f - h * 3600f);
|
float s = UnityEngine.Mathf.FloorToInt(spawnTime - m * 60f - h * 3600f);
|
||||||
return h.ToString("00") + ":" + m.ToString("00") + ":" + s.ToString("00");
|
return h.ToString("00") + ":" + m.ToString("00") + ":" + s.ToString("00");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal DebugOperationInfo GetDebugOperationInfo()
|
||||||
|
{
|
||||||
|
var operationInfo = new DebugOperationInfo();
|
||||||
|
operationInfo.OperationName = this.GetType().Name;
|
||||||
|
operationInfo.OperationDesc = GetOperationDesc();
|
||||||
|
operationInfo.Priority = Priority;
|
||||||
|
operationInfo.Progress = Progress;
|
||||||
|
operationInfo.BeginTime = BeginTime;
|
||||||
|
operationInfo.ProcessTime = ProcessTime;
|
||||||
|
operationInfo.Status = Status.ToString();
|
||||||
|
|
||||||
|
if (_childs == null)
|
||||||
|
{
|
||||||
|
operationInfo.Childs = new List<DebugOperationInfo>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
operationInfo.Childs = new List<DebugOperationInfo>(_childs.Count);
|
||||||
|
foreach (var child in _childs)
|
||||||
|
{
|
||||||
|
var childInfo = child.GetDebugOperationInfo();
|
||||||
|
operationInfo.Childs.Add(childInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return operationInfo;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 排序接口实现
|
#region 排序接口实现
|
||||||
@@ -360,4 +458,4 @@ namespace YooAsset
|
|||||||
private TaskCompletionSource<object> _taskCompletionSource;
|
private TaskCompletionSource<object> _taskCompletionSource;
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,14 +11,6 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
OnUpdate();
|
OnUpdate();
|
||||||
}
|
}
|
||||||
internal override void InternalAbort()
|
|
||||||
{
|
|
||||||
OnAbort();
|
|
||||||
}
|
|
||||||
internal override void InternalWaitForAsyncComplete()
|
|
||||||
{
|
|
||||||
OnWaitForAsyncComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步操作开始
|
/// 异步操作开始
|
||||||
@@ -29,31 +21,5 @@ namespace YooAsset
|
|||||||
/// 异步操作更新
|
/// 异步操作更新
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected abstract void OnUpdate();
|
protected abstract void OnUpdate();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步操作终止
|
|
||||||
/// </summary>
|
|
||||||
protected abstract void OnAbort();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步等待完成
|
|
||||||
/// </summary>
|
|
||||||
protected virtual void OnWaitForAsyncComplete() { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步操作系统是否繁忙
|
|
||||||
/// </summary>
|
|
||||||
protected bool IsBusy()
|
|
||||||
{
|
|
||||||
return OperationSystem.IsBusy;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 终止异步操作
|
|
||||||
/// </summary>
|
|
||||||
protected void Abort()
|
|
||||||
{
|
|
||||||
AbortOperation();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
159
Assets/YooAsset/Runtime/OperationSystem/OperationScheduler.cs
Normal file
159
Assets/YooAsset/Runtime/OperationSystem/OperationScheduler.cs
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 异步操作调度器
|
||||||
|
/// </summary>
|
||||||
|
internal class OperationScheduler : IComparable<OperationScheduler>
|
||||||
|
{
|
||||||
|
private readonly List<AsyncOperationBase> _operations = new List<AsyncOperationBase>(100);
|
||||||
|
private readonly List<AsyncOperationBase> _newList = new List<AsyncOperationBase>(100);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所属包裹名称
|
||||||
|
/// </summary>
|
||||||
|
public string PackageName { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 调度器优先级(值越大越优先)
|
||||||
|
/// </summary>
|
||||||
|
public int Priority { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建顺序(用于同优先级稳定排序)
|
||||||
|
/// </summary>
|
||||||
|
public int CreateIndex { private set; get; }
|
||||||
|
|
||||||
|
|
||||||
|
public OperationScheduler(string packageName, int priority, int createIndex)
|
||||||
|
{
|
||||||
|
PackageName = packageName;
|
||||||
|
Priority = priority;
|
||||||
|
CreateIndex = createIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始处理异步操作
|
||||||
|
/// </summary>
|
||||||
|
public void StartOperation(AsyncOperationBase operation)
|
||||||
|
{
|
||||||
|
_newList.Add(operation);
|
||||||
|
operation.StartOperation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新调度器
|
||||||
|
/// </summary>
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
// 移除已经完成的异步操作
|
||||||
|
for (int i = _operations.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var operation = _operations[i];
|
||||||
|
if (operation.IsFinish)
|
||||||
|
{
|
||||||
|
_operations.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加新增的异步操作
|
||||||
|
if (_newList.Count > 0)
|
||||||
|
{
|
||||||
|
_operations.AddRange(_newList);
|
||||||
|
_newList.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测是否需要执行排序
|
||||||
|
bool isDirty = false;
|
||||||
|
foreach (var operation in _operations)
|
||||||
|
{
|
||||||
|
if (operation.IsDirty)
|
||||||
|
{
|
||||||
|
operation.IsDirty = false;
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isDirty)
|
||||||
|
{
|
||||||
|
_operations.Sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新进行中的异步操作
|
||||||
|
for (int i = 0; i < _operations.Count; i++)
|
||||||
|
{
|
||||||
|
// 检查全局时间切片预算
|
||||||
|
if (OperationSystem.IsBusy)
|
||||||
|
break;
|
||||||
|
|
||||||
|
var operation = _operations[i];
|
||||||
|
if (operation.IsFinish)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
operation.UpdateOperation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空并中止所有任务
|
||||||
|
/// </summary>
|
||||||
|
public void ClearAll()
|
||||||
|
{
|
||||||
|
// 终止临时队列里的任务
|
||||||
|
foreach (var operation in _newList)
|
||||||
|
{
|
||||||
|
operation.AbortOperation();
|
||||||
|
operation.FinishOperation(); //注意:强制收尾,确保Task能完成
|
||||||
|
}
|
||||||
|
_newList.Clear();
|
||||||
|
|
||||||
|
// 终止正在进行的任务
|
||||||
|
foreach (var operation in _operations)
|
||||||
|
{
|
||||||
|
operation.AbortOperation();
|
||||||
|
operation.FinishOperation(); //注意:强制收尾,确保Task能完成
|
||||||
|
}
|
||||||
|
_operations.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取调试信息
|
||||||
|
/// </summary>
|
||||||
|
public List<DebugOperationInfo> GetDebugOperationInfos()
|
||||||
|
{
|
||||||
|
int totalCount = _operations.Count + _newList.Count;
|
||||||
|
List<DebugOperationInfo> result = new List<DebugOperationInfo>(totalCount);
|
||||||
|
|
||||||
|
// 包含正在执行的任务
|
||||||
|
foreach (var operation in _operations)
|
||||||
|
{
|
||||||
|
var operationInfo = operation.GetDebugOperationInfo();
|
||||||
|
result.Add(operationInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 包含待处理的新任务
|
||||||
|
foreach (var operation in _newList)
|
||||||
|
{
|
||||||
|
var operationInfo = operation.GetDebugOperationInfo();
|
||||||
|
result.Add(operationInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 排序接口实现
|
||||||
|
public int CompareTo(OperationScheduler other)
|
||||||
|
{
|
||||||
|
// 优先级高的排前面
|
||||||
|
int result = other.Priority.CompareTo(this.Priority);
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
// 优先级相同,按创建顺序
|
||||||
|
result = this.CreateIndex.CompareTo(other.CreateIndex);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 919380cb845bb8146a03ed154644b89f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -15,22 +15,26 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private static readonly List<AsyncOperationBase> _operations = new List<AsyncOperationBase>(1000);
|
// 全局调度器名称
|
||||||
private static readonly List<AsyncOperationBase> _newList = new List<AsyncOperationBase>(1000);
|
public const string GLOBAL_SCHEDULER_NAME = "YOOASSET_GLOBAL_SCHEDULER";
|
||||||
private static Action<string, AsyncOperationBase> _startCallback = null;
|
|
||||||
private static Action<string, AsyncOperationBase> _finishCallback = null;
|
private static readonly Dictionary<string, OperationScheduler> _schedulerDic = new Dictionary<string, OperationScheduler>(100);
|
||||||
|
private static readonly List<OperationScheduler> _schedulerList = new List<OperationScheduler>(100);
|
||||||
|
private static bool _isInitialize = false;
|
||||||
|
private static bool _schedulerListDirty = false;
|
||||||
|
private static int _createIndex = 0;
|
||||||
|
|
||||||
// 计时器相关
|
// 计时器相关
|
||||||
private static Stopwatch _watch;
|
private static Stopwatch _watch;
|
||||||
private static long _frameTime;
|
private static long _frameTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步操作的最小时间片段
|
/// 异步操作系统的每帧最大执行预算(毫秒)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static long MaxTimeSlice { set; get; } = long.MaxValue;
|
public static long MaxTimeSlice { set; get; } = long.MaxValue;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 处理器是否繁忙
|
/// 异步操作系统是否繁忙
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool IsBusy
|
public static bool IsBusy
|
||||||
{
|
{
|
||||||
@@ -39,7 +43,10 @@ namespace YooAsset
|
|||||||
if (_watch == null)
|
if (_watch == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// NOTE : 单次调用开销约1微秒
|
if (MaxTimeSlice == long.MaxValue)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 注意 : 单次调用开销约1微秒
|
||||||
return _watch.ElapsedMilliseconds - _frameTime >= MaxTimeSlice;
|
return _watch.ElapsedMilliseconds - _frameTime >= MaxTimeSlice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +57,11 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
|
_isInitialize = true;
|
||||||
_watch = Stopwatch.StartNew();
|
_watch = Stopwatch.StartNew();
|
||||||
|
|
||||||
|
// 创建全局调度器
|
||||||
|
CreatePackageScheduler(GLOBAL_SCHEDULER_NAME, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -58,54 +69,26 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Update()
|
public static void Update()
|
||||||
{
|
{
|
||||||
// 移除已经完成的异步操作
|
if (_isInitialize == false)
|
||||||
// 注意:移除上一帧完成的异步操作,方便调试器接收到完整的信息!
|
return;
|
||||||
for (int i = _operations.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
var operation = _operations[i];
|
|
||||||
if (operation.IsFinish)
|
|
||||||
{
|
|
||||||
_operations.RemoveAt(i);
|
|
||||||
|
|
||||||
if (_finishCallback != null)
|
// 重新排序调度器
|
||||||
_finishCallback.Invoke(operation.PackageName, operation);
|
if (_schedulerListDirty)
|
||||||
}
|
{
|
||||||
|
_schedulerListDirty = false;
|
||||||
|
_schedulerList.Sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加新增的异步操作
|
// 更新帧时间
|
||||||
if (_newList.Count > 0)
|
|
||||||
{
|
|
||||||
bool sorting = false;
|
|
||||||
foreach (var operation in _newList)
|
|
||||||
{
|
|
||||||
if (operation.Priority > 0)
|
|
||||||
{
|
|
||||||
sorting = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_operations.AddRange(_newList);
|
|
||||||
_newList.Clear();
|
|
||||||
|
|
||||||
// 重新排序优先级
|
|
||||||
if (sorting)
|
|
||||||
_operations.Sort();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新进行中的异步操作
|
|
||||||
bool checkBusy = MaxTimeSlice < long.MaxValue;
|
|
||||||
_frameTime = _watch.ElapsedMilliseconds;
|
_frameTime = _watch.ElapsedMilliseconds;
|
||||||
for (int i = 0; i < _operations.Count; i++)
|
|
||||||
|
// 更新调度器
|
||||||
|
for (int i = 0; i < _schedulerList.Count; i++)
|
||||||
{
|
{
|
||||||
if (checkBusy && IsBusy)
|
if (IsBusy)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
var operation = _operations[i];
|
_schedulerList[i].Update();
|
||||||
if (operation.IsFinish)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
operation.UpdateOperation();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,37 +97,64 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void DestroyAll()
|
public static void DestroyAll()
|
||||||
{
|
{
|
||||||
_operations.Clear();
|
// 清空所有调度器
|
||||||
_newList.Clear();
|
foreach (var scheduler in _schedulerList)
|
||||||
_startCallback = null;
|
{
|
||||||
_finishCallback = null;
|
scheduler.ClearAll();
|
||||||
|
}
|
||||||
|
_schedulerDic.Clear();
|
||||||
|
_schedulerList.Clear();
|
||||||
|
_schedulerListDirty = false;
|
||||||
|
_createIndex = 0;
|
||||||
|
_isInitialize = false;
|
||||||
|
|
||||||
_watch = null;
|
_watch = null;
|
||||||
_frameTime = 0;
|
_frameTime = 0;
|
||||||
MaxTimeSlice = long.MaxValue;
|
MaxTimeSlice = long.MaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建包裹调度器
|
||||||
|
/// </summary>
|
||||||
|
public static void CreatePackageScheduler(string packageName, int priority)
|
||||||
|
{
|
||||||
|
if (_schedulerDic.ContainsKey(packageName))
|
||||||
|
{
|
||||||
|
throw new YooInternalException($"Package scheduler already exists: {packageName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
var scheduler = new OperationScheduler(packageName, priority, _createIndex++);
|
||||||
|
_schedulerDic.Add(packageName, scheduler);
|
||||||
|
_schedulerList.Add(scheduler);
|
||||||
|
_schedulerListDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 销毁包裹调度器
|
||||||
|
/// </summary>
|
||||||
|
public static void DestroyPackageScheduler(string packageName)
|
||||||
|
{
|
||||||
|
// 不允许销毁默认调度器
|
||||||
|
if (packageName == GLOBAL_SCHEDULER_NAME)
|
||||||
|
{
|
||||||
|
throw new YooInternalException("Cannot destroy the global package scheduler!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_schedulerDic.TryGetValue(packageName, out var scheduler))
|
||||||
|
{
|
||||||
|
scheduler.ClearAll();
|
||||||
|
_schedulerDic.Remove(packageName);
|
||||||
|
_schedulerList.Remove(scheduler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 销毁包裹的所有任务
|
/// 销毁包裹的所有任务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ClearPackageOperation(string packageName)
|
public static void ClearPackageOperation(string packageName)
|
||||||
{
|
{
|
||||||
// 终止临时队列里的任务
|
var scheduler = GetScheduler(packageName);
|
||||||
foreach (var operation in _newList)
|
scheduler.ClearAll();
|
||||||
{
|
|
||||||
if (operation.PackageName == packageName)
|
|
||||||
{
|
|
||||||
operation.AbortOperation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 终止正在进行的任务
|
|
||||||
foreach (var operation in _operations)
|
|
||||||
{
|
|
||||||
if (operation.PackageName == packageName)
|
|
||||||
{
|
|
||||||
operation.AbortOperation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -152,62 +162,30 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void StartOperation(string packageName, AsyncOperationBase operation)
|
public static void StartOperation(string packageName, AsyncOperationBase operation)
|
||||||
{
|
{
|
||||||
_newList.Add(operation);
|
var scheduler = GetScheduler(packageName);
|
||||||
operation.SetPackageName(packageName);
|
scheduler.StartOperation(operation);
|
||||||
operation.StartOperation();
|
|
||||||
|
|
||||||
if (_startCallback != null)
|
|
||||||
_startCallback.Invoke(packageName, operation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 监听任务开始
|
/// 获取调度器(严格模式)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void RegisterStartCallback(Action<string, AsyncOperationBase> callback)
|
private static OperationScheduler GetScheduler(string packageName)
|
||||||
{
|
{
|
||||||
_startCallback = callback;
|
if (_schedulerDic.TryGetValue(packageName, out var scheduler))
|
||||||
}
|
{
|
||||||
|
return scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
// 严格模式:非默认包裹必须先创建调度器
|
||||||
/// 监听任务结束
|
throw new YooInternalException($"Package scheduler not found: {packageName}. Please call YooAssets.CreatePackage() first!");
|
||||||
/// </summary>
|
|
||||||
public static void RegisterFinishCallback(Action<string, AsyncOperationBase> callback)
|
|
||||||
{
|
|
||||||
_finishCallback = callback;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 调试信息
|
#region 调试信息
|
||||||
internal static List<DebugOperationInfo> GetDebugOperationInfos(string packageName)
|
internal static List<DebugOperationInfo> GetDebugOperationInfos(string packageName)
|
||||||
{
|
{
|
||||||
List<DebugOperationInfo> result = new List<DebugOperationInfo>(_operations.Count);
|
var scheduler = GetScheduler(packageName);
|
||||||
foreach (var operation in _operations)
|
return scheduler.GetDebugOperationInfos();
|
||||||
{
|
|
||||||
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
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ OperationSystem 是 YooAsset 资源管理系统的**异步操作调度核心**
|
|||||||
### 核心组件
|
### 核心组件
|
||||||
|
|
||||||
- **OperationSystem**: 静态调度器,管理所有操作的执行
|
- **OperationSystem**: 静态调度器,管理所有操作的执行
|
||||||
|
- **OperationScheduler**: 包裹级调度器,维护操作队列并负责更新调度
|
||||||
- **AsyncOperationBase**: 异步操作基类,定义生命周期和状态
|
- **AsyncOperationBase**: 异步操作基类,定义生命周期和状态
|
||||||
- **GameAsyncOperation**: 游戏层操作基类,提供更友好的 API
|
|
||||||
- **EOperationStatus**: 操作状态枚举
|
- **EOperationStatus**: 操作状态枚举
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -68,8 +68,8 @@ OperationSystem 是 YooAsset 资源管理系统的**异步操作调度核心**
|
|||||||
OperationSystem/
|
OperationSystem/
|
||||||
├── EOperationStatus.cs # 操作状态枚举
|
├── EOperationStatus.cs # 操作状态枚举
|
||||||
├── AsyncOperationBase.cs # 异步操作基类
|
├── AsyncOperationBase.cs # 异步操作基类
|
||||||
|
├── OperationScheduler.cs # 包裹级调度器
|
||||||
├── OperationSystem.cs # 异步操作调度器
|
├── OperationSystem.cs # 异步操作调度器
|
||||||
└── GameAsyncOperation.cs # 游戏层操作基类
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -113,12 +113,21 @@ None ─────────────────► Processing ───
|
|||||||
| `Status` | `EOperationStatus` | 当前状态 |
|
| `Status` | `EOperationStatus` | 当前状态 |
|
||||||
| `Error` | `string` | 错误信息(失败时) |
|
| `Error` | `string` | 错误信息(失败时) |
|
||||||
| `Progress` | `float` | 处理进度(0-1) |
|
| `Progress` | `float` | 处理进度(0-1) |
|
||||||
| `PackageName` | `string` | 所属包裹名称 |
|
|
||||||
| `IsDone` | `bool` | 是否已完成(Succeed 或 Failed) |
|
| `IsDone` | `bool` | 是否已完成(Succeed 或 Failed) |
|
||||||
| `Task` | `Task` | 用于 async/await |
|
| `Task` | `Task` | 用于 async/await |
|
||||||
| `BeginTime` | `string` | 开始时间(调试用) |
|
| `BeginTime` | `string` | 开始时间(调试用) |
|
||||||
| `ProcessTime` | `long` | 处理耗时毫秒(调试用) |
|
| `ProcessTime` | `long` | 处理耗时毫秒(调试用) |
|
||||||
|
|
||||||
|
> 说明:`AsyncOperationBase` 本身不保存包裹名称;包裹名称由 `OperationSystem.StartOperation(packageName, operation)` 传入,并由 `OperationScheduler` 维护。
|
||||||
|
|
||||||
|
#### 内部协作:时间切片(`IsBusy`)
|
||||||
|
|
||||||
|
为配合 `OperationSystem.MaxTimeSlice` 的时间切片预算,`AsyncOperationBase` 提供了内部属性 `IsBusy`(`internal`)用于任务在 `InternalUpdate()` 内主动让出本帧预算。
|
||||||
|
|
||||||
|
- 推荐用法:在 `InternalUpdate()` 内部(或内部子步骤)在执行重逻辑前判断 `IsBusy`,若繁忙则 `return`,把工作拆到下一帧继续执行。
|
||||||
|
- 同步等待特殊处理:当调用了 `WaitForAsyncComplete()` 进入同步等待阶段时,`IsBusy` 会强制返回 `false`,避免因时间切片判断导致同步等待无法推进。
|
||||||
|
- 注意:`WaitForAsyncComplete()` 会阻塞主线程,应谨慎使用;同步等待阶段不受时间切片保护,可能带来卡顿。
|
||||||
|
|
||||||
#### 公共事件
|
#### 公共事件
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
@@ -150,14 +159,16 @@ public void WaitForAsyncComplete();
|
|||||||
#### 子任务管理
|
#### 子任务管理
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// 子任务列表
|
// 添加/移除子任务(内部使用)
|
||||||
internal readonly List<AsyncOperationBase> Childs;
|
|
||||||
|
|
||||||
// 添加/移除子任务
|
|
||||||
internal void AddChildOperation(AsyncOperationBase child);
|
internal void AddChildOperation(AsyncOperationBase child);
|
||||||
internal void RemoveChildOperation(AsyncOperationBase child);
|
internal void RemoveChildOperation(AsyncOperationBase child);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**调用约束(重要):**
|
||||||
|
- 仅允许在 Unity 主线程调用(与 `OperationSystem.Update()` 的调度线程一致)。
|
||||||
|
- 不要在 `InternalUpdate()` 正在遍历/处理中途频繁增删子任务;推荐在任务启动阶段完成子任务挂接,或在确保无并发修改风险的安全点调整。
|
||||||
|
- `AbortOperation()` 会递归中止子任务,子任务的生命周期由父任务统一管理;避免在 `Completed` 回调里再去修改子任务关系,防止时序混乱。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### OperationSystem(调度器)
|
### OperationSystem(调度器)
|
||||||
@@ -208,6 +219,12 @@ public static void ClearPackageOperation(string packageName);
|
|||||||
public static void StartOperation(string packageName, AsyncOperationBase operation);
|
public static void StartOperation(string packageName, AsyncOperationBase operation);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### 包裹调度说明
|
||||||
|
|
||||||
|
- `packageName` 不允许为空(`null` / `""`),否则会抛出异常。
|
||||||
|
- 若需要使用全局调度器,请传入 `OperationSystem.GLOBAL_SCHEDULER_NAME`(`Initialize()` 时自动创建)。
|
||||||
|
- `packageName` 为非全局调度器名称时,必须先通过 `YooAssets.CreatePackage(packageName)` 创建包裹(内部会注册对应 `OperationScheduler`),否则会抛出异常。
|
||||||
|
|
||||||
#### 回调监听
|
#### 回调监听
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
@@ -224,47 +241,6 @@ public static void RegisterFinishCallback(Action<string, AsyncOperationBase> cal
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### GameAsyncOperation(游戏层基类)
|
|
||||||
|
|
||||||
继承 `AsyncOperationBase`,为业务层提供更友好的 API。
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
public abstract class GameAsyncOperation : AsyncOperationBase
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 异步操作开始
|
|
||||||
/// </summary>
|
|
||||||
protected abstract void OnStart();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步操作更新
|
|
||||||
/// </summary>
|
|
||||||
protected abstract void OnUpdate();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步操作终止
|
|
||||||
/// </summary>
|
|
||||||
protected abstract void OnAbort();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步等待完成(可选重写)
|
|
||||||
/// </summary>
|
|
||||||
protected virtual void OnWaitForAsyncComplete();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步操作系统是否繁忙
|
|
||||||
/// </summary>
|
|
||||||
protected bool IsBusy();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 终止异步操作
|
|
||||||
/// </summary>
|
|
||||||
protected void Abort();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 异步编程模式
|
## 异步编程模式
|
||||||
|
|
||||||
### 1. 协程模式(IEnumerator)
|
### 1. 协程模式(IEnumerator)
|
||||||
@@ -345,9 +321,9 @@ operation.Priority = 100; // 设置高优先级
|
|||||||
```
|
```
|
||||||
|
|
||||||
**排序规则:**
|
**排序规则:**
|
||||||
- 新操作添加时检查是否需要排序
|
- 新操作添加时:若新增队列存在非零优先级,则触发排序
|
||||||
- 仅当存在非零优先级时触发排序
|
- 运行时修改 `Priority`:会在下一次调度器更新时自动触发重排(即时生效,通常为下一帧)
|
||||||
- 使用 `List.Sort()` 进行原地排序
|
- 排序使用 `List.Sort()` 进行原地排序;频繁修改优先级会带来额外排序开销,建议按需使用
|
||||||
|
|
||||||
### 时间切片
|
### 时间切片
|
||||||
|
|
||||||
@@ -358,6 +334,10 @@ operation.Priority = 100; // 设置高优先级
|
|||||||
OperationSystem.MaxTimeSlice = 8;
|
OperationSystem.MaxTimeSlice = 8;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**操作侧协作建议:**
|
||||||
|
- 在操作的 `InternalUpdate()` 中使用 `IsBusy`(`AsyncOperationBase` 的内部属性)进行“自愿让出”,将重任务拆分到多帧执行。
|
||||||
|
- 在同步等待(`WaitForAsyncComplete()`)阶段,`IsBusy` 会强制返回 `false`,以保证同步等待推进;此时需要自行评估卡顿风险。
|
||||||
|
|
||||||
**执行流程:**
|
**执行流程:**
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -420,24 +400,29 @@ OperationSystem.MaxTimeSlice = 8;
|
|||||||
### 调试信息结构
|
### 调试信息结构
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
[Serializable]
|
||||||
internal struct DebugOperationInfo
|
internal struct DebugOperationInfo
|
||||||
{
|
{
|
||||||
public string OperationName; // 操作类型名
|
public string OperationName; // 任务名称
|
||||||
public string OperationDesc; // 操作描述
|
public string OperationDesc; // 任务说明
|
||||||
public uint Priority; // 优先级
|
public uint Priority; // 优先级
|
||||||
public float Progress; // 进度
|
public float Progress; // 任务进度
|
||||||
public string BeginTime; // 开始时间
|
public string BeginTime; // 任务开始的时间
|
||||||
public long ProcessTime; // 处理耗时(毫秒)
|
public long ProcessTime; // 处理耗时(单位:毫秒)
|
||||||
public string Status; // 状态
|
public string Status; // 任务状态
|
||||||
public List<DebugOperationInfo> Childs; // 子操作
|
public List<DebugOperationInfo> Childs; // 子任务列表(注意:JsonUtility 序列化深度限制)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> 说明:该结构体真实定义位于 `Runtime/DiagnosticSystem/DebugOperationInfo.cs`,这里仅展示关键字段以便理解。
|
||||||
|
|
||||||
### 获取调试信息
|
### 获取调试信息
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// 获取指定包裹的所有操作信息
|
// 获取指定包裹的所有操作信息(内部调试接口)
|
||||||
var infos = OperationSystem.GetDebugOperationInfos("DefaultPackage");
|
// packageName 不允许为空;全局调度器请使用 OperationSystem.GLOBAL_SCHEDULER_NAME
|
||||||
|
// 非全局包裹需先 YooAssets.CreatePackage(packageName)
|
||||||
|
var infos = OperationSystem.GetDebugOperationInfos(OperationSystem.GLOBAL_SCHEDULER_NAME);
|
||||||
|
|
||||||
foreach (var info in infos)
|
foreach (var info in infos)
|
||||||
{
|
{
|
||||||
@@ -457,105 +442,6 @@ Debug.Log($"处理耗时: {operation.ProcessTime}ms");
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 使用示例
|
|
||||||
|
|
||||||
### 自定义异步操作
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
public class MyCustomOperation : GameAsyncOperation
|
|
||||||
{
|
|
||||||
private int _step = 0;
|
|
||||||
|
|
||||||
protected override void OnStart()
|
|
||||||
{
|
|
||||||
// 初始化操作
|
|
||||||
_step = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnUpdate()
|
|
||||||
{
|
|
||||||
// 检查系统是否繁忙(时间切片)
|
|
||||||
if (IsBusy())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 执行步骤
|
|
||||||
switch (_step)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
// 第一步
|
|
||||||
Progress = 0.3f;
|
|
||||||
_step = 1;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
// 第二步
|
|
||||||
Progress = 0.6f;
|
|
||||||
_step = 2;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// 完成
|
|
||||||
Status = EOperationStatus.Succeed;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnAbort()
|
|
||||||
{
|
|
||||||
// 清理资源
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 启动自定义操作
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
var operation = new MyCustomOperation();
|
|
||||||
OperationSystem.StartOperation("DefaultPackage", operation);
|
|
||||||
|
|
||||||
// 使用回调
|
|
||||||
operation.Completed += (op) =>
|
|
||||||
{
|
|
||||||
if (op.Status == EOperationStatus.Succeed)
|
|
||||||
Debug.Log("操作成功");
|
|
||||||
};
|
|
||||||
|
|
||||||
// 或使用 await
|
|
||||||
await operation.Task;
|
|
||||||
```
|
|
||||||
|
|
||||||
### 带子任务的操作
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
public class ParentOperation : GameAsyncOperation
|
|
||||||
{
|
|
||||||
private ChildOperation _child;
|
|
||||||
|
|
||||||
protected override void OnStart()
|
|
||||||
{
|
|
||||||
_child = new ChildOperation();
|
|
||||||
AddChildOperation(_child); // 添加子任务
|
|
||||||
OperationSystem.StartOperation(PackageName, _child);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnUpdate()
|
|
||||||
{
|
|
||||||
if (_child.IsDone)
|
|
||||||
{
|
|
||||||
if (_child.Status == EOperationStatus.Succeed)
|
|
||||||
Status = EOperationStatus.Succeed;
|
|
||||||
else
|
|
||||||
Status = EOperationStatus.Failed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnAbort()
|
|
||||||
{
|
|
||||||
// 子任务会自动中止
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 设计模式
|
## 设计模式
|
||||||
|
|
||||||
### 模板方法模式
|
### 模板方法模式
|
||||||
@@ -589,7 +475,7 @@ AsyncOperationBase
|
|||||||
|
|
||||||
### 组合模式
|
### 组合模式
|
||||||
|
|
||||||
通过 `Childs` 列表支持父子操作关系:
|
通过内部子任务列表支持父子操作关系:
|
||||||
|
|
||||||
```
|
```
|
||||||
ParentOperation
|
ParentOperation
|
||||||
@@ -608,10 +494,6 @@ IEnumerator + IComparable<AsyncOperationBase>
|
|||||||
│
|
│
|
||||||
▼
|
▼
|
||||||
AsyncOperationBase (抽象基类)
|
AsyncOperationBase (抽象基类)
|
||||||
│
|
|
||||||
├── GameAsyncOperation (游戏层基类)
|
|
||||||
│ │
|
|
||||||
│ └── [业务层自定义操作]
|
|
||||||
│
|
│
|
||||||
└── [YooAsset 内部操作]
|
└── [YooAsset 内部操作]
|
||||||
│
|
│
|
||||||
@@ -632,4 +514,4 @@ IEnumerator + IComparable<AsyncOperationBase>
|
|||||||
4. **子任务中止**:父操作中止时会自动中止所有子操作
|
4. **子任务中止**:父操作中止时会自动中止所有子操作
|
||||||
5. **回调异常**:`Completed` 回调中的异常会被捕获并记录,不会中断系统
|
5. **回调异常**:`Completed` 回调中的异常会被捕获并记录,不会中断系统
|
||||||
6. **编辑器重置**:编辑器中使用 `RuntimeInitializeOnLoadMethod` 自动重置状态
|
6. **编辑器重置**:编辑器中使用 `RuntimeInitializeOnLoadMethod` 自动重置状态
|
||||||
7. **循环保护**:`WaitForAsyncComplete()` 有 1000 帧上限,防止无限循环
|
7. **循环保护**:在 `InternalWaitForAsyncComplete()` 中如果使用 `ExecuteWhileDone()`,内部默认有 1000 次执行保护,防止无限循环
|
||||||
|
|||||||
@@ -62,6 +62,9 @@ namespace YooAsset
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsWaitForAsyncComplete)
|
||||||
|
_handle.WaitForAsyncComplete();
|
||||||
|
|
||||||
if (_handle.IsDone == false)
|
if (_handle.IsDone == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -138,18 +141,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
// 等待句柄完成
|
|
||||||
if (_handle != null)
|
|
||||||
_handle.WaitForAsyncComplete();
|
|
||||||
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
internal override string InternalGetDesc()
|
internal override string InternalGetDesc()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -127,14 +127,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
internal override string InternalGetDesc()
|
internal override string InternalGetDesc()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,11 +40,8 @@ namespace YooAsset
|
|||||||
_loopCounter--;
|
_loopCounter--;
|
||||||
LoopUnloadUnused();
|
LoopUnloadUnused();
|
||||||
|
|
||||||
if (IsWaitForAsyncComplete == false)
|
if (IsBusy)
|
||||||
{
|
break;
|
||||||
if (OperationSystem.IsBusy)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_loopCounter <= 0)
|
if (_loopCounter <= 0)
|
||||||
@@ -56,14 +53,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
internal override string InternalGetDesc()
|
internal override string InternalGetDesc()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -183,14 +183,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
internal override string InternalGetDesc()
|
internal override string InternalGetDesc()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,5 +22,10 @@ namespace YooAsset
|
|||||||
/// 原生文件
|
/// 原生文件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
RawBundle = 3,
|
RawBundle = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 团结资源包
|
||||||
|
/// </summary>
|
||||||
|
InstantBundle = 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,9 +108,6 @@ namespace YooAsset
|
|||||||
_downloadingMaxNumber = UnityEngine.Mathf.Clamp(downloadingMaxNumber, 1, MAX_LOADER_COUNT); ;
|
_downloadingMaxNumber = UnityEngine.Mathf.Clamp(downloadingMaxNumber, 1, MAX_LOADER_COUNT); ;
|
||||||
_failedTryAgain = failedTryAgain;
|
_failedTryAgain = failedTryAgain;
|
||||||
|
|
||||||
// 设置包裹名称 (fix #210)
|
|
||||||
SetPackageName(packageName);
|
|
||||||
|
|
||||||
// 统计下载信息
|
// 统计下载信息
|
||||||
CalculatDownloaderInfo();
|
CalculatDownloaderInfo();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,11 +159,8 @@ namespace YooAsset
|
|||||||
|
|
||||||
_packageAssetCount--;
|
_packageAssetCount--;
|
||||||
Progress = 1f - _packageAssetCount / _progressTotalValue;
|
Progress = 1f - _packageAssetCount / _progressTotalValue;
|
||||||
if (IsWaitForAsyncComplete == false)
|
if (IsBusy)
|
||||||
{
|
break;
|
||||||
if (OperationSystem.IsBusy)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_packageAssetCount <= 0)
|
if (_packageAssetCount <= 0)
|
||||||
@@ -196,11 +193,8 @@ namespace YooAsset
|
|||||||
|
|
||||||
_packageBundleCount--;
|
_packageBundleCount--;
|
||||||
Progress = 1f - _packageBundleCount / _progressTotalValue;
|
Progress = 1f - _packageBundleCount / _progressTotalValue;
|
||||||
if (IsWaitForAsyncComplete == false)
|
if (IsBusy)
|
||||||
{
|
break;
|
||||||
if (OperationSystem.IsBusy)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_packageBundleCount <= 0)
|
if (_packageBundleCount <= 0)
|
||||||
@@ -226,14 +220,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
{
|
{
|
||||||
while (true)
|
RunBatchExecution();
|
||||||
{
|
|
||||||
if (ExecuteWhileDone())
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateAssetCollection(PackageManifest manifest, int assetCount)
|
private void CreateAssetCollection(PackageManifest manifest, int assetCount)
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ namespace YooAsset
|
|||||||
options.ReleaseAllHandles = true;
|
options.ReleaseAllHandles = true;
|
||||||
options.LockLoadOperation = true;
|
options.LockLoadOperation = true;
|
||||||
var operation = new DestroyOperation(this, options);
|
var operation = new DestroyOperation(this, options);
|
||||||
OperationSystem.StartOperation(null, operation);
|
OperationSystem.StartOperation(OperationSystem.GLOBAL_SCHEDULER_NAME, operation);
|
||||||
return operation;
|
return operation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,16 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="packageName">包裹名称</param>
|
/// <param name="packageName">包裹名称</param>
|
||||||
public static ResourcePackage CreatePackage(string packageName)
|
public static ResourcePackage CreatePackage(string packageName)
|
||||||
|
{
|
||||||
|
return CreatePackage(packageName, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建资源包裹
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="packageName">包裹名称</param>
|
||||||
|
/// <param name="packagePriority">包裹优先级(值越大越优先更新)</param>
|
||||||
|
public static ResourcePackage CreatePackage(string packageName, int packagePriority)
|
||||||
{
|
{
|
||||||
CheckException(packageName);
|
CheckException(packageName);
|
||||||
if (ContainsPackage(packageName))
|
if (ContainsPackage(packageName))
|
||||||
@@ -122,6 +132,10 @@ namespace YooAsset
|
|||||||
YooLogger.Log($"Create resource package : {packageName}");
|
YooLogger.Log($"Create resource package : {packageName}");
|
||||||
ResourcePackage package = new ResourcePackage(packageName);
|
ResourcePackage package = new ResourcePackage(packageName);
|
||||||
_packages.Add(package);
|
_packages.Add(package);
|
||||||
|
|
||||||
|
// 注册包裹调度器
|
||||||
|
OperationSystem.CreatePackageScheduler(packageName, packagePriority);
|
||||||
|
|
||||||
return package;
|
return package;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +199,10 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
|
|
||||||
YooLogger.Log($"Remove resource package : {packageName}");
|
YooLogger.Log($"Remove resource package : {packageName}");
|
||||||
|
|
||||||
|
// 先销毁调度器,再移除包裹
|
||||||
|
OperationSystem.DestroyPackageScheduler(packageName);
|
||||||
|
|
||||||
_packages.Remove(package);
|
_packages.Remove(package);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -207,7 +225,7 @@ namespace YooAsset
|
|||||||
public static void StartOperation(GameAsyncOperation operation)
|
public static void StartOperation(GameAsyncOperation operation)
|
||||||
{
|
{
|
||||||
// 注意:游戏业务逻辑的包裹填写为空
|
// 注意:游戏业务逻辑的包裹填写为空
|
||||||
OperationSystem.StartOperation(string.Empty, operation);
|
OperationSystem.StartOperation(OperationSystem.GLOBAL_SCHEDULER_NAME, operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user