refactor : 代码重构

This commit is contained in:
何冠峰
2026-02-09 10:09:18 +08:00
parent d839146bd5
commit 811eb5d82b
283 changed files with 3488 additions and 2441 deletions

View File

@@ -22,7 +22,7 @@ namespace YooAsset.Editor
/// </summary>
public static string GetStreamingAssetsRoot()
{
return YooAssetSettingsData.GetYooDefaultBuildinRoot();
return YooAssetSettingsData.GetYooDefaultBuiltinRoot();
}
}
}

View File

@@ -31,7 +31,7 @@ namespace YooAsset.Editor
// 创建新补丁清单
PackageManifest manifest = new PackageManifest();
manifest.FileVersion = PackageManifestDefine.FileVersion;
manifest.FileVersion = PackageManifestConsts.FileVersion;
manifest.EnableAddressable = buildMapContext.Command.EnableAddressable;
manifest.SupportExtensionless = buildMapContext.Command.SupportExtensionless;
manifest.LocationToLower = buildMapContext.Command.LocationToLower;

View File

@@ -147,9 +147,9 @@ namespace YooAsset.Editor
EditorConnection.instance.Initialize();
EditorConnection.instance.RegisterConnection(OnHandleConnectionEvent);
EditorConnection.instance.RegisterDisconnection(OnHandleDisconnectionEvent);
EditorConnection.instance.Register(DiagnosticSystemDefine.PlayerToEditorMessageId, OnHandlePlayerMessage);
EditorConnection.instance.Register(DiagnosticSystemConsts.PlayerToEditorMessageId, OnHandlePlayerMessage);
MockEditorConnection.Instance.Initialize();
MockEditorConnection.Instance.Register(DiagnosticSystemDefine.PlayerToEditorMessageId, OnHandlePlayerMessage);
MockEditorConnection.Instance.Register(DiagnosticSystemConsts.PlayerToEditorMessageId, OnHandlePlayerMessage);
}
catch (Exception e)
{
@@ -161,8 +161,8 @@ namespace YooAsset.Editor
// 远程调试
EditorConnection.instance.UnregisterConnection(OnHandleConnectionEvent);
EditorConnection.instance.UnregisterDisconnection(OnHandleDisconnectionEvent);
EditorConnection.instance.Unregister(DiagnosticSystemDefine.PlayerToEditorMessageId, OnHandlePlayerMessage);
MockEditorConnection.Instance.Unregister(DiagnosticSystemDefine.PlayerToEditorMessageId, OnHandlePlayerMessage);
EditorConnection.instance.Unregister(DiagnosticSystemConsts.PlayerToEditorMessageId, OnHandlePlayerMessage);
MockEditorConnection.Instance.Unregister(DiagnosticSystemConsts.PlayerToEditorMessageId, OnHandlePlayerMessage);
_playerSessions.Clear();
}
public void Update()
@@ -194,9 +194,9 @@ namespace YooAsset.Editor
int playerId = args.playerId;
var debugReport = DiagnosticReport.Deserialize(args.data);
if (debugReport.ProtocolVersion != DiagnosticSystemDefine.ProtocolVersion)
if (debugReport.ProtocolVersion != DiagnosticSystemConsts.ProtocolVersion)
{
Debug.LogWarning($"Debugger versions are inconsistent : {debugReport.ProtocolVersion} != {DiagnosticSystemDefine.ProtocolVersion}");
Debug.LogWarning($"Debugger versions are inconsistent : {debugReport.ProtocolVersion} != {DiagnosticSystemConsts.ProtocolVersion}");
return;
}
@@ -258,8 +258,8 @@ namespace YooAsset.Editor
command.CommandType = (int)EDiagnosticCommandType.AutoSampling;
command.Parameter = evt.newValue ? "open" : "close";
byte[] data = DiagnosticCommand.Serialize(command);
EditorConnection.instance.Send(DiagnosticSystemDefine.EditorToPlayerMessageId, data);
MockEditorConnection.Instance.Send(DiagnosticSystemDefine.EditorToPlayerMessageId, data);
EditorConnection.instance.Send(DiagnosticSystemConsts.EditorToPlayerMessageId, data);
MockEditorConnection.Instance.Send(DiagnosticSystemConsts.EditorToPlayerMessageId, data);
}
private void SampleBtn_onClick()
@@ -269,8 +269,8 @@ namespace YooAsset.Editor
command.CommandType = (int)EDiagnosticCommandType.SampleOnce;
command.Parameter = string.Empty;
byte[] data = DiagnosticCommand.Serialize(command);
EditorConnection.instance.Send(DiagnosticSystemDefine.EditorToPlayerMessageId, data);
MockEditorConnection.Instance.Send(DiagnosticSystemDefine.EditorToPlayerMessageId, data);
EditorConnection.instance.Send(DiagnosticSystemConsts.EditorToPlayerMessageId, data);
MockEditorConnection.Instance.Send(DiagnosticSystemConsts.EditorToPlayerMessageId, data);
}
private void ExportBtn_clicked()
{

View File

@@ -358,7 +358,7 @@ namespace YooAsset
}
catch (Exception ex)
{
YooLogger.Error($"Exception in inoke callback: {ex}");
YooLogger.Error($"Exception in invoke callback: {ex}");
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a9ca0d0d29eb5294b9c6926c6a09e76b
guid: 4c4801976948fc14cb28d4982c9ebe5c
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,40 @@
using UnityEngine.SceneManagement;
namespace YooAsset
{
/// <summary>
/// 资源包句柄接口,提供对已加载资源包的操作能力
/// </summary>
internal interface IBundleHandle
{
/// <summary>
/// 获取资源包文件的本地路径
/// </summary>
string GetBundleFilePath();
/// <summary>
/// 卸载资源包文件
/// </summary>
void UnloadBundleFile();
/// <summary>
/// 加载资源对象
/// </summary>
BHLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo);
/// <summary>
/// 加载所有资源对象
/// </summary>
BHLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo);
/// <summary>
/// 加载资源对象及所有子资源对象
/// </summary>
BHLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo);
/// <summary>
/// 加载场景对象
/// </summary>
BHLoadSceneOperation LoadSceneAsync(AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool suspendLoad);
}
}

View File

@@ -0,0 +1,14 @@
namespace YooAsset
{
/// <summary>
/// 加载所有资源操作的抽象基类
/// </summary>
internal abstract class BHLoadAllAssetsOperation : AsyncOperationBase
{
/// <summary>
/// 加载的所有资源对象
/// </summary>
public UnityEngine.Object[] Result;
}
}

View File

@@ -0,0 +1,14 @@
namespace YooAsset
{
/// <summary>
/// 加载单个资源操作的抽象基类
/// </summary>
internal abstract class BHLoadAssetOperation : AsyncOperationBase
{
/// <summary>
/// 加载的资源对象
/// </summary>
public UnityEngine.Object Result;
}
}

View File

@@ -0,0 +1,19 @@
namespace YooAsset
{
/// <summary>
/// 加载场景操作的抽象基类
/// </summary>
internal abstract class BHLoadSceneOperation : AsyncOperationBase
{
/// <summary>
/// 加载的场景对象
/// </summary>
public UnityEngine.SceneManagement.Scene Result;
/// <summary>
/// 恢复挂起的场景加载
/// </summary>
public abstract void ResumeLoad();
}
}

View File

@@ -0,0 +1,14 @@
namespace YooAsset
{
/// <summary>
/// 加载子资源操作的抽象基类
/// </summary>
internal abstract class BHLoadSubAssetsOperation : AsyncOperationBase
{
/// <summary>
/// 加载的子资源对象集合
/// </summary>
public UnityEngine.Object[] Result;
}
}

View File

@@ -1,17 +1,20 @@
using System.IO;
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace YooAsset
{
internal class AssetBundleResult : IBundleResult
/// <summary>
/// AssetBundle资源包句柄
/// </summary>
internal class AssetBundleHandle : IBundleHandle
{
private readonly string _bundleFilePath;
private readonly PackageBundle _packageBundle;
private readonly AssetBundle _assetBundle;
private readonly Stream _managedStream;
public AssetBundleResult(string bundleFilePath, PackageBundle packageBundle, AssetBundle assetBundle, Stream managedStream)
public AssetBundleHandle(string bundleFilePath, PackageBundle packageBundle, AssetBundle assetBundle, Stream managedStream)
{
_bundleFilePath = bundleFilePath;
_packageBundle = packageBundle;
@@ -36,24 +39,24 @@ namespace YooAsset
}
}
public FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo)
public BHLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo)
{
var operation = new AssetBundleLoadAssetOperation(_packageBundle, _assetBundle, assetInfo);
var operation = new ABHLoadAssetOperation(_packageBundle, _assetBundle, assetInfo);
return operation;
}
public FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo)
public BHLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo)
{
var operation = new AssetBundleLoadAllAssetsOperation(_packageBundle, _assetBundle, assetInfo);
var operation = new ABHLoadAllAssetsOperation(_packageBundle, _assetBundle, assetInfo);
return operation;
}
public FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo)
public BHLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo)
{
var operation = new AssetBundleLoadSubAssetsOperation(_packageBundle, _assetBundle, assetInfo);
var operation = new ABHLoadSubAssetsOperation(_packageBundle, _assetBundle, assetInfo);
return operation;
}
public FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad)
public BHLoadSceneOperation LoadSceneAsync(AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool suspendLoad)
{
var operation = new AssetBundleLoadSceneOperation(assetInfo, loadParams, suspendLoad);
var operation = new ABHLoadSceneOperation(assetInfo, loadSceneParams, suspendLoad);
return operation;
}
}

View File

@@ -1,8 +1,11 @@
using UnityEngine;
using UnityEngine;
namespace YooAsset
{
internal class AssetBundleLoadAllAssetsOperation : FSLoadAllAssetsOperation
/// <summary>
/// AssetBundle的加载所有资源操作
/// </summary>
internal class ABHLoadAllAssetsOperation : BHLoadAllAssetsOperation
{
protected enum ESteps
{
@@ -19,7 +22,7 @@ namespace YooAsset
private AssetBundleRequest _request;
private ESteps _steps = ESteps.None;
public AssetBundleLoadAllAssetsOperation(PackageBundle packageBundle, AssetBundle assetBundle, AssetInfo assetInfo)
public ABHLoadAllAssetsOperation(PackageBundle packageBundle, AssetBundle assetBundle, AssetInfo assetInfo)
{
_packageBundle = packageBundle;
_assetBundle = assetBundle;
@@ -39,8 +42,8 @@ namespace YooAsset
if (_assetBundle == null)
{
_steps = ESteps.Done;
Error = $"The bundle {_packageBundle.BundleName} has been destroyed due to unity engine bugs.";
Status = EOperationStatus.Failed;
Error = $"The bundle {_packageBundle.BundleName} has been destroyed due to Unity engine bugs.";
return;
}
@@ -71,10 +74,11 @@ namespace YooAsset
{
if (_request != null)
{
// 注意: 异步加载过程中,业务逻辑可能会强制转换为同步加载
if (IsWaitForCompletion)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
YooLogger.Warning("Suspending the main thread to load Unity asset.");
Result = _request.allAssets;
}
else
@@ -90,14 +94,14 @@ namespace YooAsset
{
string error;
if (_assetInfo.AssetType == null)
error = $"Failed to load all assets : {_assetInfo.AssetPath} AssetType : null AssetBundle : {_packageBundle.BundleName}";
error = $"Failed to load all assets: {_assetInfo.AssetPath} AssetType: null AssetBundle: {_packageBundle.BundleName}";
else
error = $"Failed to load all assets : {_assetInfo.AssetPath} AssetType : {_assetInfo.AssetType} AssetBundle : {_packageBundle.BundleName}";
YooLogger.Error(error);
error = $"Failed to load all assets: {_assetInfo.AssetPath} AssetType: {_assetInfo.AssetType} AssetBundle: {_packageBundle.BundleName}";
_steps = ESteps.Done;
Error = error;
Status = EOperationStatus.Failed;
Error = error;
YooLogger.Error(error);
}
else
{

View File

@@ -1,8 +1,11 @@
using UnityEngine;
using UnityEngine;
namespace YooAsset
{
internal class AssetBundleLoadAssetOperation : FSLoadAssetOperation
/// <summary>
/// AssetBundle的加载单个资源操作
/// </summary>
internal class ABHLoadAssetOperation : BHLoadAssetOperation
{
protected enum ESteps
{
@@ -19,7 +22,7 @@ namespace YooAsset
private AssetBundleRequest _request;
private ESteps _steps = ESteps.None;
public AssetBundleLoadAssetOperation(PackageBundle packageBundle, AssetBundle assetBundle, AssetInfo assetInfo)
public ABHLoadAssetOperation(PackageBundle packageBundle, AssetBundle assetBundle, AssetInfo assetInfo)
{
_packageBundle = packageBundle;
_assetBundle = assetBundle;
@@ -39,8 +42,8 @@ namespace YooAsset
if (_assetBundle == null)
{
_steps = ESteps.Done;
Error = $"The bundle {_packageBundle.BundleName} has been destroyed due to unity engine bugs.";
Status = EOperationStatus.Failed;
Error = $"The bundle {_packageBundle.BundleName} has been destroyed due to Unity engine bugs.";
return;
}
@@ -71,10 +74,11 @@ namespace YooAsset
{
if (_request != null)
{
// 注意: 异步加载过程中,业务逻辑可能会强制转换为同步加载
if (IsWaitForCompletion)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
YooLogger.Warning("Suspending the main thread to load Unity asset.");
Result = _request.asset;
}
else
@@ -90,9 +94,9 @@ namespace YooAsset
{
string error;
if (_assetInfo.AssetType == null)
error = $"Failed to load asset : {_assetInfo.AssetPath} AssetType : null AssetBundle : {_packageBundle.BundleName}";
error = $"Failed to load asset: {_assetInfo.AssetPath} AssetType: null AssetBundle: {_packageBundle.BundleName}";
else
error = $"Failed to load asset : {_assetInfo.AssetPath} AssetType : {_assetInfo.AssetType} AssetBundle : {_packageBundle.BundleName}";
error = $"Failed to load asset: {_assetInfo.AssetPath} AssetType: {_assetInfo.AssetType} AssetBundle: {_packageBundle.BundleName}";
_steps = ESteps.Done;
Status = EOperationStatus.Failed;

View File

@@ -1,9 +1,12 @@
using UnityEngine;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace YooAsset
{
internal class AssetBundleLoadSceneOperation : FSLoadSceneOperation
/// <summary>
/// AssetBundle的场景加载操作
/// </summary>
internal class ABHLoadSceneOperation : BHLoadSceneOperation
{
protected enum ESteps
{
@@ -14,15 +17,15 @@ namespace YooAsset
}
private readonly AssetInfo _assetInfo;
private readonly LoadSceneParameters _loadParams;
private readonly LoadSceneParameters _loadSceneParams;
private bool _suspendLoad;
private AsyncOperation _asyncOperation;
private ESteps _steps = ESteps.None;
public AssetBundleLoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad)
public ABHLoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool suspendLoad)
{
_assetInfo = assetInfo;
_loadParams = loadParams;
_loadSceneParams = loadSceneParams;
_suspendLoad = suspendLoad;
}
internal override void InternalStart()
@@ -39,14 +42,14 @@ namespace YooAsset
if (IsWaitForCompletion)
{
// 注意:场景同步加载方法不会立即加载场景,而是在下一帧加载。
Result = SceneManager.LoadScene(_assetInfo.AssetPath, _loadParams);
Result = SceneManager.LoadScene(_assetInfo.AssetPath, _loadSceneParams);
_steps = ESteps.CheckResult;
}
else
{
// 注意如果场景不存在异步加载方法返回NULL
// 注意:即使是异步加载也要在当帧获取到场景对象
_asyncOperation = SceneManager.LoadSceneAsync(_assetInfo.AssetPath, _loadParams);
_asyncOperation = SceneManager.LoadSceneAsync(_assetInfo.AssetPath, _loadSceneParams);
if (_asyncOperation != null)
{
_asyncOperation.allowSceneActivation = !_suspendLoad;
@@ -56,11 +59,10 @@ namespace YooAsset
}
else
{
string error = $"Failed to load scene : {_assetInfo.AssetPath}";
YooLogger.Error(error);
_steps = ESteps.Done;
Error = error;
Status = EOperationStatus.Failed;
Error = $"Failed to load scene: {_assetInfo.AssetPath}";
YooLogger.Error(Error);
}
}
}
@@ -71,8 +73,8 @@ namespace YooAsset
{
if (IsWaitForCompletion)
{
//注意:场景加载无法强制异步转同步
YooLogger.Error("The scene is loading asyn.");
// 注意:场景加载无法强制异步转同步
YooLogger.Error("The scene is already loading asynchronously.");
}
else
{
@@ -96,11 +98,10 @@ namespace YooAsset
}
else
{
string error = $"The loaded scene is invalid : {_assetInfo.AssetPath}";
YooLogger.Error(error);
_steps = ESteps.Done;
Error = error;
Status = EOperationStatus.Failed;
Error = $"The loaded scene is invalid: {_assetInfo.AssetPath}";
YooLogger.Error(Error);
}
}
}
@@ -109,7 +110,7 @@ namespace YooAsset
//注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
ExecuteOnce();
}
public override void UnSuspendLoad()
public override void ResumeLoad()
{
_suspendLoad = false;
}

View File

@@ -1,8 +1,11 @@
using UnityEngine;
using UnityEngine;
namespace YooAsset
{
internal class AssetBundleLoadSubAssetsOperation : FSLoadSubAssetsOperation
/// <summary>
/// AssetBundle的加载子资源操作
/// </summary>
internal class ABHLoadSubAssetsOperation : BHLoadSubAssetsOperation
{
protected enum ESteps
{
@@ -19,7 +22,7 @@ namespace YooAsset
private AssetBundleRequest _request;
private ESteps _steps = ESteps.None;
public AssetBundleLoadSubAssetsOperation(PackageBundle packageBundle, AssetBundle assetBundle, AssetInfo assetInfo)
public ABHLoadSubAssetsOperation(PackageBundle packageBundle, AssetBundle assetBundle, AssetInfo assetInfo)
{
_packageBundle = packageBundle;
_assetBundle = assetBundle;
@@ -39,8 +42,8 @@ namespace YooAsset
if (_assetBundle == null)
{
_steps = ESteps.Done;
Error = $"The bundle {_packageBundle.BundleName} has been destroyed due to unity engine bugs.";
Status = EOperationStatus.Failed;
Error = $"The bundle {_packageBundle.BundleName} has been destroyed due to Unity engine bugs.";
return;
}
@@ -71,10 +74,11 @@ namespace YooAsset
{
if (_request != null)
{
// 注意: 异步加载过程中,业务逻辑可能会强制转换为同步加载
if (IsWaitForCompletion)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
YooLogger.Warning("Suspending the main thread to load Unity asset.");
Result = _request.allAssets;
}
else
@@ -90,14 +94,14 @@ namespace YooAsset
{
string error;
if (_assetInfo.AssetType == null)
error = $"Failed to load sub assets : {_assetInfo.AssetPath} AssetType : null AssetBundle : {_packageBundle.BundleName}";
error = $"Failed to load sub-assets: {_assetInfo.AssetPath} AssetType: null AssetBundle: {_packageBundle.BundleName}";
else
error = $"Failed to load sub assets : {_assetInfo.AssetPath} AssetType : {_assetInfo.AssetType} AssetBundle : {_packageBundle.BundleName}";
YooLogger.Error(error);
error = $"Failed to load sub-assets: {_assetInfo.AssetPath} AssetType: {_assetInfo.AssetType} AssetBundle: {_packageBundle.BundleName}";
_steps = ESteps.Done;
Error = error;
Status = EOperationStatus.Failed;
Error = error;
YooLogger.Error(error);
}
else
{

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: af833833252078e45866dd8e1e8299bb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c9e4bd9d00f3b2d4482c97519523474d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
namespace YooAsset
{
/// <summary>
/// 原生资源包的加载所有资源操作(不支持)
/// </summary>
internal class RBHLoadAllAssetsOperation : BHLoadAllAssetsOperation
{
internal override void InternalStart()
{
Status = EOperationStatus.Failed;
Error = $"{nameof(RBHLoadAllAssetsOperation)} does not support loading all assets.";
}
internal override void InternalUpdate()
{
}
}
}

View File

@@ -1,7 +1,10 @@

namespace YooAsset
{
internal class RawBundleLoadAssetOperation : FSLoadAssetOperation
/// <summary>
/// 原生资源包的加载单个资源操作
/// </summary>
internal class RBHLoadAssetOperation : BHLoadAssetOperation
{
protected enum ESteps
{
@@ -16,7 +19,7 @@ namespace YooAsset
private readonly AssetInfo _assetInfo;
private ESteps _steps = ESteps.None;
public RawBundleLoadAssetOperation(PackageBundle packageBundle, RawBundle rawBundle, AssetInfo assetInfo)
public RBHLoadAssetOperation(PackageBundle packageBundle, RawBundle rawBundle, AssetInfo assetInfo)
{
_packageBundle = packageBundle;
_rawBundle = rawBundle;
@@ -43,7 +46,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to load raw file object : {_assetInfo.AssetPath}";
Error = $"Failed to load raw file object: {_assetInfo.AssetPath}";
YooLogger.Error(Error);
}
else

View File

@@ -0,0 +1,21 @@
namespace YooAsset
{
/// <summary>
/// 原生资源包的场景加载操作(不支持)
/// </summary>
internal class RBHLoadSceneOperation : BHLoadSceneOperation
{
internal override void InternalStart()
{
Status = EOperationStatus.Failed;
Error = $"{nameof(RBHLoadSceneOperation)} does not support loading scene.";
}
internal override void InternalUpdate()
{
}
public override void ResumeLoad()
{
}
}
}

View File

@@ -0,0 +1,18 @@
namespace YooAsset
{
/// <summary>
/// 原生资源包的加载子资源操作(不支持)
/// </summary>
internal class RBHLoadSubAssetsOperation : BHLoadSubAssetsOperation
{
internal override void InternalStart()
{
Status = EOperationStatus.Failed;
Error = $"{nameof(RBHLoadSubAssetsOperation)} does not support loading sub-assets.";
}
internal override void InternalUpdate()
{
}
}
}

View File

@@ -1,6 +1,9 @@
namespace YooAsset
{
/// <summary>
/// 原生资源包
/// </summary>
public class RawBundle
{
private byte[] _data;
@@ -18,6 +21,9 @@ namespace YooAsset
return RawFileObject.Create(_data);
}
/// <summary>
/// 卸载原生资源包数据
/// </summary>
public void Unload()
{
_data = null;

View File

@@ -1,14 +1,17 @@
using UnityEngine.SceneManagement;
using UnityEngine.SceneManagement;
namespace YooAsset
{
internal class RawBundleResult : IBundleResult
/// <summary>
/// 原生资源包句柄
/// </summary>
internal class RawBundleHandle : IBundleHandle
{
private readonly string _bundleFilePath;
private readonly PackageBundle _packageBundle;
private readonly RawBundle _rawBundle;
public RawBundleResult(string bundleFilePath, PackageBundle packageBundle, RawBundle rawBundle)
public RawBundleHandle(string bundleFilePath, PackageBundle packageBundle, RawBundle rawBundle)
{
_bundleFilePath = bundleFilePath;
_packageBundle = packageBundle;
@@ -26,24 +29,24 @@ namespace YooAsset
}
}
public FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo)
public BHLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo)
{
var operation = new RawBundleLoadAssetOperation(_packageBundle, _rawBundle, assetInfo);
var operation = new RBHLoadAssetOperation(_packageBundle, _rawBundle, assetInfo);
return operation;
}
public FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo)
public BHLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo)
{
var operation = new RawBundleLoadAllAssetsOperation();
var operation = new RBHLoadAllAssetsOperation();
return operation;
}
public FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo)
public BHLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo)
{
var operation = new RawBundleLoadSubAssetsOperation();
var operation = new RBHLoadSubAssetsOperation();
return operation;
}
public FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad)
public BHLoadSceneOperation LoadSceneAsync(AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool suspendLoad)
{
var operation = new RawBundleLoadSceneOperation();
var operation = new RBHLoadSceneOperation();
return operation;
}
}

View File

@@ -11,8 +11,14 @@ namespace YooAsset
private byte[] _fileData;
private string _fileText;
/// <summary>
/// 原生文件的二进制数据
/// </summary>
public byte[] Data => _fileData;
/// <summary>
/// 原生文件的UTF-8文本内容
/// </summary>
public string Text
{
get

View File

@@ -1,8 +1,11 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace YooAsset
{
internal class VirtualBundleLoadAllAssetsOperation : FSLoadAllAssetsOperation
/// <summary>
/// 虚拟资源包的加载所有资源操作
/// </summary>
internal class VBHLoadAllAssetsOperation : BHLoadAllAssetsOperation
{
protected enum ESteps
{
@@ -17,7 +20,7 @@ namespace YooAsset
private readonly AssetInfo _assetInfo;
private ESteps _steps = ESteps.None;
public VirtualBundleLoadAllAssetsOperation(PackageBundle packageBundle, AssetInfo assetInfo)
public VBHLoadAllAssetsOperation(PackageBundle packageBundle, AssetInfo assetInfo)
{
_packageBundle = packageBundle;
_assetInfo = assetInfo;
@@ -28,8 +31,8 @@ namespace YooAsset
_steps = ESteps.CheckBundle;
#else
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(VirtualBundleLoadAllAssetsOperation)} only support unity editor platform.";
Status = EOperationStatus.Failed;
#endif
}
internal override void InternalUpdate()
@@ -44,11 +47,10 @@ namespace YooAsset
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(_assetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {_assetInfo.AssetPath}";
YooLogger.Error(error);
_steps = ESteps.Done;
Error = error;
Status = EOperationStatus.Failed;
Error = $"Asset not found: {_assetInfo.AssetPath}";
YooLogger.Error(Error);
return;
}
@@ -90,14 +92,14 @@ namespace YooAsset
{
string error;
if (_assetInfo.AssetType == null)
error = $"Failed to load all assets : {_assetInfo.AssetPath} AssetType : null";
error = $"Failed to load all assets: {_assetInfo.AssetPath} AssetType: null";
else
error = $"Failed to load all assets : {_assetInfo.AssetPath} AssetType : {_assetInfo.AssetType}";
YooLogger.Error(error);
error = $"Failed to load all assets: {_assetInfo.AssetPath} AssetType: {_assetInfo.AssetType}";
_steps = ESteps.Done;
Error = error;
Status = EOperationStatus.Failed;
Error = error;
YooLogger.Error(error);
}
else
{

View File

@@ -1,7 +1,10 @@

namespace YooAsset
{
internal class VirtualBundleLoadAssetOperation : FSLoadAssetOperation
/// <summary>
/// 虚拟资源包的加载单个资源操作
/// </summary>
internal class VBHLoadAssetOperation : BHLoadAssetOperation
{
protected enum ESteps
{
@@ -16,7 +19,7 @@ namespace YooAsset
private readonly AssetInfo _assetInfo;
private ESteps _steps = ESteps.None;
public VirtualBundleLoadAssetOperation(PackageBundle packageBundle, AssetInfo assetInfo)
public VBHLoadAssetOperation(PackageBundle packageBundle, AssetInfo assetInfo)
{
_packageBundle = packageBundle;
_assetInfo = assetInfo;
@@ -27,8 +30,8 @@ namespace YooAsset
_steps = ESteps.CheckBundle;
#else
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(VirtualBundleLoadAssetOperation)} only support unity editor platform.";
Status = EOperationStatus.Failed;
#endif
}
internal override void InternalUpdate()
@@ -43,11 +46,10 @@ namespace YooAsset
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(_assetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {_assetInfo.AssetPath}";
YooLogger.Error(error);
_steps = ESteps.Done;
Error = error;
Status = EOperationStatus.Failed;
Error = $"Asset not found: {_assetInfo.AssetPath}";
YooLogger.Error(Error);
return;
}
@@ -69,14 +71,14 @@ namespace YooAsset
{
string error;
if (_assetInfo.AssetType == null)
error = $"Failed to load asset object : {_assetInfo.AssetPath} AssetType : null";
error = $"Failed to load asset object: {_assetInfo.AssetPath} AssetType: null";
else
error = $"Failed to load asset object : {_assetInfo.AssetPath} AssetType : {_assetInfo.AssetType}";
YooLogger.Error(error);
error = $"Failed to load asset object: {_assetInfo.AssetPath} AssetType: {_assetInfo.AssetType}";
_steps = ESteps.Done;
Error = error;
Status = EOperationStatus.Failed;
Error = error;
YooLogger.Error(error);
}
else
{

View File

@@ -1,9 +1,12 @@
using UnityEngine;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace YooAsset
{
internal class VirtualBundleLoadSceneOperation : FSLoadSceneOperation
/// <summary>
/// 虚拟资源包的场景加载操作
/// </summary>
internal class VBHLoadSceneOperation : BHLoadSceneOperation
{
protected enum ESteps
{
@@ -19,7 +22,7 @@ namespace YooAsset
private AsyncOperation _asyncOperation;
private ESteps _steps = ESteps.None;
public VirtualBundleLoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad)
public VBHLoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad)
{
_assetInfo = assetInfo;
_loadParams = loadParams;
@@ -31,8 +34,8 @@ namespace YooAsset
_steps = ESteps.LoadScene;
#else
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(VirtualBundleLoadSceneOperation)} only support unity editor platform.";
Status = EOperationStatus.Failed;
#endif
}
internal override void InternalUpdate()
@@ -60,11 +63,10 @@ namespace YooAsset
}
else
{
string error = $"Failed to load scene : {_assetInfo.AssetPath}";
YooLogger.Error(error);
_steps = ESteps.Done;
Error = error;
Status = EOperationStatus.Failed;
Error = $"Failed to load scene: {_assetInfo.AssetPath}";
YooLogger.Error(Error);
return;
}
}
@@ -77,7 +79,7 @@ namespace YooAsset
if (IsWaitForCompletion)
{
// 注意:场景加载无法强制异步转同步
YooLogger.Error("The scene is loading asyn.");
YooLogger.Error("The scene is already loading asynchronously.");
}
else
{
@@ -101,11 +103,10 @@ namespace YooAsset
}
else
{
string error = $"The loaded scene is invalid : {_assetInfo.AssetPath}";
YooLogger.Error(error);
_steps = ESteps.Done;
Error = error;
Status = EOperationStatus.Failed;
Error = $"The loaded scene is invalid: {_assetInfo.AssetPath}";
YooLogger.Error(Error);
}
}
#endif
@@ -115,7 +116,7 @@ namespace YooAsset
//注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
ExecuteOnce();
}
public override void UnSuspendLoad()
public override void ResumeLoad()
{
_suspendLoad = false;
}

View File

@@ -1,8 +1,11 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace YooAsset
{
internal class VirtualBundleLoadSubAssetsOperation : FSLoadSubAssetsOperation
/// <summary>
/// 虚拟资源包的加载子资源操作
/// </summary>
internal class VBHLoadSubAssetsOperation : BHLoadSubAssetsOperation
{
protected enum ESteps
{
@@ -17,7 +20,7 @@ namespace YooAsset
private readonly AssetInfo _assetInfo;
private ESteps _steps = ESteps.None;
public VirtualBundleLoadSubAssetsOperation(PackageBundle packageBundle, AssetInfo assetInfo)
public VBHLoadSubAssetsOperation(PackageBundle packageBundle, AssetInfo assetInfo)
{
_packageBundle = packageBundle;
_assetInfo = assetInfo;
@@ -28,8 +31,8 @@ namespace YooAsset
_steps = ESteps.CheckBundle;
#else
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(VirtualBundleLoadSubAssetsOperation)} only support unity editor platform.";
Status = EOperationStatus.Failed;
#endif
}
internal override void InternalUpdate()
@@ -44,11 +47,10 @@ namespace YooAsset
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(_assetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {_assetInfo.AssetPath}";
YooLogger.Error(error);
_steps = ESteps.Done;
Error = error;
Status = EOperationStatus.Failed;
Error = $"Asset not found: {_assetInfo.AssetPath}";
YooLogger.Error(Error);
return;
}
@@ -81,14 +83,14 @@ namespace YooAsset
{
string error;
if (_assetInfo.AssetType == null)
error = $"Failed to load sub assets : {_assetInfo.AssetPath} AssetType : null";
error = $"Failed to load sub-assets: {_assetInfo.AssetPath} AssetType: null";
else
error = $"Failed to load sub assets : {_assetInfo.AssetPath} AssetType : {_assetInfo.AssetType}";
YooLogger.Error(error);
error = $"Failed to load sub-assets: {_assetInfo.AssetPath} AssetType: {_assetInfo.AssetType}";
_steps = ESteps.Done;
Error = error;
Status = EOperationStatus.Failed;
Error = error;
YooLogger.Error(error);
}
else
{

View File

@@ -0,0 +1,47 @@
using UnityEngine.SceneManagement;
namespace YooAsset
{
/// <summary>
/// 虚拟资源包句柄
/// </summary>
internal class VirtualBundleHandle : IBundleHandle
{
private readonly string _bundleFilePath;
private readonly PackageBundle _packageBundle;
public VirtualBundleHandle(string bundleFilePath, PackageBundle bundle)
{
_bundleFilePath = bundleFilePath;
_packageBundle = bundle;
}
public void UnloadBundleFile()
{
}
public string GetBundleFilePath()
{
return _bundleFilePath;
}
public BHLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo)
{
var operation = new VBHLoadAssetOperation(_packageBundle, assetInfo);
return operation;
}
public BHLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo)
{
var operation = new VBHLoadAllAssetsOperation(_packageBundle, assetInfo);
return operation;
}
public BHLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo)
{
var operation = new VBHLoadSubAssetsOperation(_packageBundle, assetInfo);
return operation;
}
public BHLoadSceneOperation LoadSceneAsync(AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool suspendLoad)
{
var operation = new VBHLoadSceneOperation(assetInfo, loadSceneParams, suspendLoad);
return operation;
}
}
}

View File

@@ -31,7 +31,7 @@ namespace YooAsset
private void OnEnable()
{
#if UNITY_EDITOR
MockPlayerConnection.Instance.Register(DiagnosticSystemDefine.EditorToPlayerMessageId, HandleEditorMessage);
MockPlayerConnection.Instance.Register(DiagnosticSystemConsts.EditorToPlayerMessageId, HandleEditorMessage);
#else
PlayerConnection.instance.Register(DiagnosticSystemDefine.EditorToPlayerMessageId, HandleEditorMessage);
#endif
@@ -39,7 +39,7 @@ namespace YooAsset
private void OnDisable()
{
#if UNITY_EDITOR
MockPlayerConnection.Instance.Unregister(DiagnosticSystemDefine.EditorToPlayerMessageId, HandleEditorMessage);
MockPlayerConnection.Instance.Unregister(DiagnosticSystemConsts.EditorToPlayerMessageId, HandleEditorMessage);
#else
PlayerConnection.instance.Unregister(DiagnosticSystemDefine.EditorToPlayerMessageId, HandleEditorMessage);
#endif
@@ -53,7 +53,7 @@ namespace YooAsset
var data = DiagnosticReport.Serialize(debugReport);
#if UNITY_EDITOR
MockPlayerConnection.Instance.Send(DiagnosticSystemDefine.PlayerToEditorMessageId, data);
MockPlayerConnection.Instance.Send(DiagnosticSystemConsts.PlayerToEditorMessageId, data);
#else
PlayerConnection.instance.Send(DiagnosticSystemDefine.PlayerToEditorMessageId, data);
#endif

View File

@@ -34,7 +34,7 @@ namespace YooAsset
public static DiagnosticReport Create()
{
var report = new DiagnosticReport();
report.ProtocolVersion = DiagnosticSystemDefine.ProtocolVersion;
report.ProtocolVersion = DiagnosticSystemConsts.ProtocolVersion;
report.FrameCount = Time.frameCount;
return report;
}

View File

@@ -5,7 +5,7 @@ namespace YooAsset
/// <summary>
/// 诊断系统的常量定义
/// </summary>
internal class DiagnosticSystemDefine
internal class DiagnosticSystemConsts
{
/// <summary>
/// 通信协议版本号

View File

@@ -1,57 +0,0 @@
using System.Collections.Generic;
namespace YooAsset
{
/// <summary>
/// 网络请求失败计数器(诊断用)
/// </summary>
/// <remarks>
/// 线程安全:内部使用 Dictionary 且未加锁,约定只在 Unity 主线程调用。
/// 如需在多线程/回调线程调用,请在外层加锁或改为并发容器实现。
/// </remarks>
internal class DownloadFailureCounter
{
#if UNITY_EDITOR
[UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)]
private static void OnRuntimeInitialize()
{
_failureRecords.Clear();
}
#endif
/// <summary>
/// 失败计数记录表
/// </summary>
/// <remarks>
/// Key 格式:$"{packageName}_{eventName}"
/// </remarks>
private static readonly Dictionary<string, int> _failureRecords = new Dictionary<string, int>(1000);
/// <summary>
/// 记录一次失败
/// </summary>
/// <param name="packageName">资源包名称</param>
/// <param name="eventName">事件名称</param>
public static void RecordFailure(string packageName, string eventName)
{
string key = $"{packageName}_{eventName}";
if (_failureRecords.ContainsKey(key) == false)
_failureRecords.Add(key, 0);
_failureRecords[key]++;
}
/// <summary>
/// 获取失败次数
/// </summary>
/// <param name="packageName">资源包名称</param>
/// <param name="eventName">事件名称</param>
/// <returns>失败次数,如果未记录过则返回 0</returns>
public static int GetFailureCount(string packageName, string eventName)
{
string key = $"{packageName}_{eventName}";
if (_failureRecords.TryGetValue(key, out int count))
return count;
return 0;
}
}
}

View File

@@ -0,0 +1,38 @@
namespace YooAsset
{
public struct DownloadReport
{
/// <summary>
/// HTTP 返回码
/// </summary>
public long HttpCode { get; set; }
/// <summary>
/// HTTP 错误信息
/// </summary>
public string HttpError { get; set; }
/// <summary>
/// 当前下载的字节数
/// </summary>
public long DownloadedBytes { get; set; }
/// <summary>
/// 当前下载进度0f - 1f
/// </summary>
public float DownloadProgress { get; set; }
/// <summary>
/// 创建默认的下载进度实例
/// </summary>
public static DownloadReport Default
{
get
{
var result = new DownloadReport();
return result;
}
}
}
}

View File

@@ -0,0 +1,93 @@
using UnityEngine;
namespace YooAsset
{
/// <summary>
/// 下载重试控制器
/// </summary>
internal sealed class DownloadRetry
{
private readonly int _maxRetryCount;
private readonly IDownloadRetryPolicy _retryPolicy;
private int _retryCount;
private float _waitTimer;
private float _waitDuration;
/// <summary>
/// 已重试次数
/// </summary>
public int RetryCount => _retryCount;
/// <summary>
/// 当前等待目标时长(秒)
/// </summary>
public float WaitDuration => _waitDuration;
/// <summary>
/// 创建下载重试控制器
/// </summary>
/// <param name="maxRetryCount">最大重试次数</param>
/// <param name="retryPolicy">重试策略</param>
public DownloadRetry(int maxRetryCount, IDownloadRetryPolicy retryPolicy)
{
_maxRetryCount = maxRetryCount;
_retryPolicy = retryPolicy;
_retryCount = 0;
_waitTimer = 0f;
_waitDuration = 0f;
}
/// <summary>
/// 判断本次失败是否允许重试
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="httpCode">HTTP 状态码</param>
/// <param name="httpError">HTTP 错误信息</param>
/// <returns>
/// 返回 true 表示允许重试;调用方应紧接着调用 BeginWait() 启动等待。
/// 返回 false 表示不允许重试(达到次数上限或错误不可重试)。
/// </returns>
public bool CanRetry(string url, long httpCode, string httpError)
{
if (_retryCount >= _maxRetryCount)
return false;
if (_retryPolicy.IsRetryableError(url, httpCode, httpError) == false)
return false;
YooLogger.Warning($"Download failed: {url}. HttpCode={httpCode}");
return true;
}
/// <summary>
/// 判断是否可以进入网络重试
/// </summary>
public bool CanRetry()
{
if (_retryCount >= _maxRetryCount)
return false;
return true;
}
/// <summary>
/// 开始本次重试等待
/// </summary>
public void BeginWait()
{
_waitTimer = 0f;
_retryCount++;
_waitDuration = _retryPolicy.ComputeDelay(_retryCount, _waitDuration);
YooLogger.Warning($"Download retrying in {WaitDuration:F1}s.");
}
/// <summary>
/// 推进等待计时
/// </summary>
public bool Tick()
{
_waitTimer += Time.unscaledDeltaTime;
return _waitTimer >= _waitDuration;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: ca9b2c6456d21bb4e9eecd9dc820a641
guid: 37c93b71779bcdf4da4005128e2cc6b8
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -42,10 +42,15 @@ namespace YooAsset
/// HTTP 返回码
/// </summary>
/// <remarks>
/// 非 HTTP 协议可返回 0。使用 long 类型以兼容各种协议的返回码。
/// 非 HTTP 协议可返回 0
/// </remarks>
long HttpCode { get; }
/// <summary>
/// HTTP 错误信息
/// </summary>
string HttpError { get; }
/// <summary>
/// 错误信息
/// </summary>

View File

@@ -1,4 +1,4 @@

namespace YooAsset
{
internal abstract class DownloadFileBaseOperation : AsyncOperationBase
@@ -13,21 +13,16 @@ namespace YooAsset
/// </summary>
public readonly string Url;
/// <summary>
/// 下载进度
/// </summary>
public float DownloadProgress { get; protected set; }
/// <summary>
/// 下载字节
/// </summary>
public long DownloadedBytes { get; protected set; }
/// <summary>
/// 引用计数
/// </summary>
public int RefCount { private set; get; }
/// <summary>
/// 下载报告
/// </summary>
public DownloadReport Report;
public DownloadFileBaseOperation(PackageBundle bundle, string url)
{
Bundle = bundle;
@@ -35,7 +30,7 @@ namespace YooAsset
}
internal override string InternalGetDescription()
{
return $"RefCount : {RefCount}";
return $"RefCount: {RefCount}";
}
/// <summary>

View File

@@ -9,7 +9,7 @@ namespace YooAsset
/// <remarks>
/// 管理所有活跃的下载任务,控制并发数量。
/// </remarks>
internal class DownloadSchedulerOperation : AsyncOperationBase, IDisposable
internal class DownloadSchedulerOperation : AsyncOperationBase
{
public struct SchedulerConfig
{
@@ -44,9 +44,6 @@ namespace YooAsset
}
}
/// <summary>
/// 构造下载中心
/// </summary>
public DownloadSchedulerOperation(SchedulerConfig config)
{
_config = config;
@@ -125,19 +122,6 @@ namespace YooAsset
return _config.SchedulerName;
}
/// <summary>
/// 释放下载资源
/// </summary>
public void Dispose()
{
foreach (var valuePair in _downloaders)
{
var operation = valuePair.Value;
operation.AbortOperation();
}
_downloaders.Clear();
}
/// <summary>
/// 尝试获取已经存在的下载器
/// </summary>

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4446775dfbf483f46a5edc74890a8245
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,53 @@
using UnityEngine;
namespace YooAsset
{
/// <summary>
/// 默认的下载重试策略
/// </summary>
public class DefaultDownloadRetryPolicy : IDownloadRetryPolicy
{
private const float BaseDelay = 1f;
private const float MaxDelay = 10f;
/// <summary>
/// 判断本次下载失败是否属于可重试的错误
/// </summary>
public bool IsRetryableError(string url, long httpCode, string httpError)
{
// HTTP 状态码
// 1xx 信息响应
// 2xx 成功响应
// 3xx 重定向消息
// 4xx 客户端错误响应
// 5xx 服务器错误响应
// 本地协议/本地路径不可重试
if (DownloadSystemTools.IsLocalFileUrl(url))
return false;
// 网络瞬断可重试
if (httpCode == 0)
return true;
// 4xx 客户端错误不可重试
// 例外408 Request Timeout
// 例外416 Range Not Satisfiable
// 例外429 Too Many Requests
if (httpCode >= 400 && httpCode < 500)
return httpCode == 408 || httpCode == 416 || httpCode == 429;
// 其它情况可重试
return true;
}
/// <summary>
/// 计算本次重试应等待的时长(秒)
/// 线性退避:每次在上一次基础上 +1 秒,封顶到最大等待秒数。
/// </summary>
public float ComputeDelay(int retryCount, float previousDelay)
{
return Mathf.Clamp(previousDelay + 1f, BaseDelay, MaxDelay);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2a84bce9bf9030645b7241a581a05af6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
using System.Collections.Generic;
namespace YooAsset
{
/// <summary>
/// 默认的 URL 选择策略
/// </summary>
public class DefaultDownloadURLPolicy : IDownloadURLPolicy
{
private int _failureCount = 0;
/// <summary>
/// 基于内部失败计数轮转选择 URL
/// </summary>
public string SelectURL(IReadOnlyList<string> candidateURLs)
{
int index = _failureCount % candidateURLs.Count;
return candidateURLs[index];
}
/// <summary>
/// 请求成功反馈(默认策略不做处理)
/// </summary>
public void OnSuccess(string url)
{
}
/// <summary>
/// 请求失败反馈,递增失败计数以切换 URL
/// </summary>
public void OnFailure(string url, long httpCode, string httpError)
{
_failureCount++;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 747ba5d3c490c8043b61bbef89fd049c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -69,6 +69,11 @@ namespace YooAsset
/// </summary>
public long HttpCode { get; private set; }
/// <summary>
/// HTTP 错误信息
/// </summary>
public string HttpError { get; private set; }
/// <summary>
/// 错误信息
/// </summary>

View File

@@ -86,6 +86,11 @@ namespace YooAsset
/// </summary>
public long HttpCode { get; private set; }
/// <summary>
/// HTTP 错误信息
/// </summary>
public string HttpError { get; private set; }
/// <summary>
/// 错误信息
/// </summary>
@@ -255,6 +260,8 @@ namespace YooAsset
return;
HttpCode = _webRequest.responseCode;
HttpError = _webRequest.error;
#if UNITY_2020_3_OR_NEWER
bool isSuccess = _webRequest.result == UnityWebRequest.Result.Success;
#else
@@ -269,7 +276,7 @@ namespace YooAsset
else
{
Status = EDownloadRequestStatus.Failed;
Error = $"[{GetType().Name}] Request failed. URL: {Url}, Error: {_webRequest.error}";
Error = $"[{GetType().Name}] Request failed. URL: {Url}, HttpCode={HttpCode} HttpError={HttpError}";
OnRequestFailed();
}

View File

@@ -47,7 +47,7 @@ namespace YooAsset
/// <summary>
/// 清理缓存文件
/// </summary>
FCClearCacheOperation ClearCacheAsync(ClearCacheOptions options);
FCClearCacheOperation ClearCacheAsync(FCClearCacheOptions options);
/// <summary>
/// 验证缓存文件

View File

@@ -1,4 +1,4 @@
using System.IO;
using System.IO;
using UnityEngine;
namespace YooAsset
@@ -74,7 +74,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{_options.CacheName} not support {decryptor.GetType().Name}";
Error = $"{_options.CacheName} does not support {decryptor.GetType().Name}";
return;
}
@@ -94,6 +94,7 @@ namespace YooAsset
{
if (_createRequest != null)
{
// 注意: 异步加载过程中,业务逻辑可能会强制转换为同步加载
if (IsWaitForCompletion)
{
// 强制挂起主线程(注意:该操作会很耗时)
@@ -120,7 +121,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new AssetBundleResult(_options.FilePath, _options.Bundle, _assetBundle, _loadStream);
BundleHandle = new AssetBundleHandle(_options.FilePath, _options.Bundle, _assetBundle, _loadStream);
}
}
}

View File

@@ -37,11 +37,11 @@ namespace YooAsset
{
if (_options.Bundle.IsEncrypted == false)
{
if (SupportsFileIO(_options.FilePath) == false)
if (FileUtility.SupportsFileIO(_options.FilePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"FileIO not supported for builtin path : {_options.FilePath}";
Error = $"FileIO is not supported for builtin path: {_options.FilePath}";
return;
}
@@ -67,7 +67,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{_options.CacheName} not support {decryptor.GetType().Name}";
Error = $"{_options.CacheName} does not support {decryptor.GetType().Name}";
return;
}
@@ -95,7 +95,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new RawBundleResult(_options.FilePath, _options.Bundle, _rawBundle);
BundleHandle = new RawBundleHandle(_options.FilePath, _options.Bundle, _rawBundle);
}
}
}

View File

@@ -1,4 +1,4 @@
using UnityEngine;
using UnityEngine;
namespace YooAsset
{
@@ -24,18 +24,16 @@ namespace YooAsset
}
protected readonly LoadWebAssetBundleOptions _options;
private readonly DownloadRetry _downloadRetry;
private IDownloadAssetBundleRequest _downloadAssetBundleRequest;
private ESteps _steps = ESteps.None;
// 失败重试
private int _requestCount = 0;
private float _tryAgainTimer = 0;
private int _failedTryAgain;
public LoadWebNormalAssetBundleOperation(LoadWebAssetBundleOptions options)
{
_options = options;
_failedTryAgain = int.MaxValue; //注意:网络原因失败后,重新尝试直到成功
// 注意:网络原因失败后,重新尝试直到成功
_downloadRetry = new DownloadRetry(int.MaxValue, options.RetryPolicy);
}
internal override void InternalStart()
{
@@ -63,6 +61,7 @@ namespace YooAsset
if (_downloadAssetBundleRequest.Status == EDownloadRequestStatus.Succeeded)
{
_options.URLPolicy.OnSuccess(_downloadAssetBundleRequest.Url);
var assetBundle = _downloadAssetBundleRequest.Result;
if (assetBundle == null)
{
@@ -74,13 +73,18 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new AssetBundleResult(_downloadAssetBundleRequest.Url, _options.Bundle, assetBundle, null);
BundleHandle = new AssetBundleHandle(_downloadAssetBundleRequest.Url, _options.Bundle, assetBundle, null);
}
}
else
{
if (_failedTryAgain > 0 && IsRetryableError(_downloadAssetBundleRequest.HttpCode))
string url = _downloadAssetBundleRequest.Url;
long httpCode = _downloadAssetBundleRequest.HttpCode;
string httpError = _downloadAssetBundleRequest.HttpError;
_options.URLPolicy.OnFailure(url, httpCode, httpError);
if (IsWaitForCompletion == false && _downloadRetry.CanRetry(url, httpCode, httpError))
{
_downloadRetry.BeginWait();
_steps = ESteps.TryAgain;
}
else
@@ -101,11 +105,8 @@ namespace YooAsset
_downloadAssetBundleRequest = null;
}
_tryAgainTimer += UnityEngine.Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
if (_downloadRetry.Tick())
{
_tryAgainTimer = 0f;
_failedTryAgain--;
Progress = 0f;
_steps = ESteps.BundleRequest;
}
@@ -122,12 +123,7 @@ namespace YooAsset
private string GetRequestURL()
{
// 轮流返回请求地址
_requestCount++;
if (_requestCount % 2 == 0)
return _options.FallbackURL;
else
return _options.MainURL;
return _options.URLPolicy.SelectURL(_options.CandidateURLs);
}
}
@@ -149,20 +145,18 @@ namespace YooAsset
}
protected readonly LoadWebAssetBundleOptions _options;
private readonly DownloadRetry _downloadRetry;
private IDownloadBytesRequest _downloadBytesRequest;
private IBundleMemoryDecryptor _decryptor;
private AssetBundleCreateRequest _createRequest;
private ESteps _steps = ESteps.None;
// 失败重试
private int _requestCount = 0;
private float _tryAgainTimer = 0;
private int _failedTryAgain;
public LoadWebEncryptedAssetBundleOperation(LoadWebAssetBundleOptions options)
{
_options = options;
_failedTryAgain = int.MaxValue; //注意:网络原因失败后,重新尝试直到成功
// 注意:网络原因失败后,重新尝试直到成功
_downloadRetry = new DownloadRetry(int.MaxValue, options.RetryPolicy);
}
internal override void InternalStart()
{
@@ -197,7 +191,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{_options.CacheName} not support {decryptor.GetType().Name}";
Error = $"{_options.CacheName} does not support {decryptor.GetType().Name}";
return;
}
}
@@ -210,12 +204,18 @@ namespace YooAsset
if (_downloadBytesRequest.Status == EDownloadRequestStatus.Succeeded)
{
_options.URLPolicy.OnSuccess(_downloadBytesRequest.Url);
_steps = ESteps.VerifyData;
}
else
{
if (_failedTryAgain > 0 && IsRetryableError(_downloadBytesRequest.HttpCode))
string url = _downloadBytesRequest.Url;
long httpCode = _downloadBytesRequest.HttpCode;
string httpError = _downloadBytesRequest.HttpError;
_options.URLPolicy.OnFailure(url, httpCode, httpError);
if (IsWaitForCompletion == false && _downloadRetry.CanRetry(url, httpCode, httpError))
{
_downloadRetry.BeginWait();
_steps = ESteps.TryAgain;
}
else
@@ -247,8 +247,9 @@ namespace YooAsset
string error = $"[WebBundleVerify] Verify failed. Url:{_downloadBytesRequest.Url} Level: {_options.DownloadVerifyLevel} Result: {verifyResult}";
YooLogger.Warning(error);
if (_failedTryAgain > 0)
if (IsWaitForCompletion == false && _downloadRetry.CanRetry())
{
_downloadRetry.BeginWait();
_steps = ESteps.TryAgain;
}
else
@@ -290,7 +291,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new AssetBundleResult(_downloadBytesRequest.Url, _options.Bundle, assetBundle, null);
BundleHandle = new AssetBundleHandle(_downloadBytesRequest.Url, _options.Bundle, assetBundle, null);
}
}
@@ -303,11 +304,8 @@ namespace YooAsset
_downloadBytesRequest = null;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
if (_downloadRetry.Tick())
{
_tryAgainTimer = 0f;
_failedTryAgain--;
Progress = 0f;
_steps = ESteps.DataRequest;
}
@@ -336,12 +334,7 @@ namespace YooAsset
}
private string GetRequestURL()
{
// 轮流返回请求地址
_requestCount++;
if (_requestCount % 2 == 0)
return _options.FallbackURL;
else
return _options.MainURL;
return _options.URLPolicy.SelectURL(_options.CandidateURLs);
}
}
}

View File

@@ -1,3 +1,4 @@
using System.Collections.Generic;
namespace YooAsset
{
@@ -17,14 +18,9 @@ namespace YooAsset
public PackageBundle Bundle { get; set; }
/// <summary>
/// 请求地址
/// 候选下载地址列表
/// </summary>
public string MainURL { get; set; }
/// <summary>
/// 备用请求地址
/// </summary>
public string FallbackURL { get; set; }
public IReadOnlyList<string> CandidateURLs { get; set; }
/// <summary>
/// AssetBundle 解密器
@@ -50,5 +46,15 @@ namespace YooAsset
/// 禁用Unity的网络缓存
/// </summary>
public bool DisableUnityWebCache { get; set; }
/// <summary>
/// 下载重试判定策略
/// </summary>
public IDownloadRetryPolicy RetryPolicy { get; set; }
/// <summary>
/// URL 选择策略
/// </summary>
public IDownloadURLPolicy URLPolicy { get; set; }
}
}

View File

@@ -1,3 +1,4 @@
using System.Collections.Generic;
namespace YooAsset
{
@@ -6,6 +7,130 @@ namespace YooAsset
/// </summary>
internal abstract class FCClearCacheOperation : AsyncOperationBase
{
protected readonly struct ClearResult
{
/// <summary>
/// 错误信息
/// </summary>
public readonly string Error;
/// <summary>
/// 需要清理的资源标识符集合
/// </summary>
public readonly List<string> BundleGUIDs;
/// <summary>
/// 是否成功
/// </summary>
public bool Succeeded
{
get { return Error == null; }
}
public ClearResult(string error)
{
Error = error;
BundleGUIDs = null;
}
public ClearResult(List<string> bundleGUIDs)
{
Error = null;
BundleGUIDs = bundleGUIDs;
}
public static ClearResult Success(List<string> bundleGUIDs)
{
return new ClearResult(bundleGUIDs);
}
public static ClearResult Failure(string error)
{
return new ClearResult(error);
}
}
protected ClearResult GetAllCache(IReadOnlyCollection<ICacheEntry> cacheEntries)
{
var bundleGUIDs = new List<string>(cacheEntries.Count);
foreach (var entry in cacheEntries)
{
bundleGUIDs.Add(entry.BundleGUID);
}
return ClearResult.Success(bundleGUIDs);
}
protected ClearResult GetUnusedCache(FCClearCacheOptions options, IReadOnlyCollection<ICacheEntry> cacheEntries)
{
if (options.Manifest == null)
return ClearResult.Failure("Active package manifest not found.");
var bundleGUIDs = new List<string>(cacheEntries.Count);
foreach (var entry in cacheEntries)
{
if (options.Manifest.IsIncludeBundleFile(entry.BundleGUID) == false)
{
bundleGUIDs.Add(entry.BundleGUID);
}
}
return ClearResult.Success(bundleGUIDs);
}
protected ClearResult GetCacheByLocations(FCClearCacheOptions options, IReadOnlyCollection<ICacheEntry> cacheEntries)
{
if (options.Manifest == null)
return ClearResult.Failure("Active package manifest not found.");
if (options.ClearParam == null)
return ClearResult.Failure("Clear param is null.");
string[] locations;
if (options.ClearParam is string str)
locations = new string[] { str };
else if (options.ClearParam is List<string> list)
locations = list.ToArray();
else if (options.ClearParam is string[] array)
locations = array;
else
return ClearResult.Failure($"Invalid clear param: {options.ClearParam.GetType().FullName}");
var bundleGUIDs = new List<string>(locations.Length);
foreach (var location in locations)
{
string assetPath = options.Manifest.TryMappingToAssetPath(location);
if (options.Manifest.TryGetPackageAsset(assetPath, out PackageAsset packageAsset))
{
PackageBundle bundle = options.Manifest.GetMainPackageBundle(packageAsset.BundleID);
bundleGUIDs.Add(bundle.BundleGUID);
}
}
return ClearResult.Success(bundleGUIDs);
}
protected ClearResult GetCacheByTags(FCClearCacheOptions options, IReadOnlyCollection<ICacheEntry> cacheEntries)
{
if (options.Manifest == null)
return ClearResult.Failure("Active package manifest not found.");
if (options.ClearParam == null)
return ClearResult.Failure("Clear param is null.");
string[] tags;
if (options.ClearParam is string str)
tags = new string[] { str };
else if (options.ClearParam is List<string> list)
tags = list.ToArray();
else if (options.ClearParam is string[] array)
tags = array;
else
return ClearResult.Failure($"Invalid clear param: {options.ClearParam.GetType().FullName}");
var bundleGUIDs = new List<string>(cacheEntries.Count);
foreach (var entry in cacheEntries)
{
if (options.Manifest.TryGetPackageBundleByBundleGUID(entry.BundleGUID, out PackageBundle bundle))
{
if (bundle.HasTag(tags))
bundleGUIDs.Add(bundle.BundleGUID);
}
}
return ClearResult.Success(bundleGUIDs);
}
}
/// <summary>

View File

@@ -0,0 +1,24 @@
namespace YooAsset
{
/// <summary>
/// 清理缓存操作选项
/// </summary>
internal struct FCClearCacheOptions
{
/// <summary>
/// 清理模式
/// </summary>
public string ClearMode { get; set; }
/// <summary>
/// 附加参数
/// </summary>
public object ClearParam { get; set; }
/// <summary>
/// 资源清单
/// </summary>
public PackageManifest Manifest { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cb7284d99e0056242806b0b21db09c09
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -6,7 +6,7 @@ namespace YooAsset
/// </summary>
internal abstract class FCLoadBundleOperation : AsyncOperationBase
{
protected struct LoadResult
protected readonly struct LoadResult
{
/// <summary>
/// 错误信息
@@ -14,7 +14,7 @@ namespace YooAsset
public readonly string Error;
/// <summary>
/// 加载成功
/// 是否成功
/// </summary>
public bool Succeeded
{
@@ -37,46 +37,9 @@ namespace YooAsset
}
/// <summary>
/// 资源包加载结果
/// 资源包句柄
/// </summary>
public IBundleResult BundleResult { get; protected set; }
/// <summary>
/// 检查文件路径是否支持 FileIO 读取
/// </summary>
protected bool SupportsFileIO(string filePath)
{
if (string.IsNullOrEmpty(filePath))
return false;
if (filePath.StartsWith("jar:") || filePath.StartsWith("content:"))
return false;
return true;
}
/// <summary>
/// 判断是否为可重试的错误
/// </summary>
protected bool IsRetryableError(long httpCode)
{
// HTTP 状态码
// 1xx 信息响应
// 2xx 成功响应
// 3xx 重定向消息
// 4xx 客户端错误响应
// 5xx 服务器错误响应
if (httpCode == 0)
return true;
// 4xx 客户端错误不可重试
// 说明408 Request Timeout
// 说明429 Too Many Requests
if (httpCode >= 400 && httpCode < 500)
return httpCode == 408 || httpCode == 429;
// 其它情况可重试
return true;
}
public IBundleHandle BundleHandle { get; protected set; }
}
/// <summary>

View File

@@ -4,7 +4,7 @@ namespace YooAsset
/// <summary>
/// 内置资源目录常量定义
/// </summary>
internal class BuiltinCatalogDefine
internal class BuiltinCatalogConsts
{
/// <summary>
/// 文件极限大小100MB

View File

@@ -57,7 +57,7 @@ namespace YooAsset
// 创建内置清单实例
var buildinCatalog = new BuiltinCatalog();
buildinCatalog.FileVersion = BuiltinCatalogDefine.FileVersion;
buildinCatalog.FileVersion = BuiltinCatalogConsts.FileVersion;
buildinCatalog.PackageName = packageName;
buildinCatalog.PackageVersion = packageVersion;
@@ -66,8 +66,8 @@ namespace YooAsset
{
"link.xml",
"buildlogtep.json",
BuiltinCatalogDefine.JsonFileName,
BuiltinCatalogDefine.BinaryFileName
BuiltinCatalogConsts.JsonFileName,
BuiltinCatalogConsts.BinaryFileName
};
string packageVersionFileName = YooAssetSettingsData.GetPackageVersionFileName(packageName);
string packageHashFileName = YooAssetSettingsData.GetPackageHashFileName(packageName, packageVersion);
@@ -106,13 +106,13 @@ namespace YooAsset
}
// 创建输出文件
string jsonFilePath = $"{packageDirectory}/{BuiltinCatalogDefine.JsonFileName}";
string jsonFilePath = $"{packageDirectory}/{BuiltinCatalogConsts.JsonFileName}";
if (File.Exists(jsonFilePath))
File.Delete(jsonFilePath);
SerializeToJson(jsonFilePath, buildinCatalog);
// 创建输出文件
string binaryFilePath = $"{packageDirectory}/{BuiltinCatalogDefine.BinaryFileName}";
string binaryFilePath = $"{packageDirectory}/{BuiltinCatalogConsts.BinaryFileName}";
if (File.Exists(binaryFilePath))
File.Delete(binaryFilePath);
SerializeToBinary(binaryFilePath, buildinCatalog);
@@ -129,18 +129,18 @@ namespace YooAsset
{
// 创建内置清单实例
var buildinFileCatalog = new BuiltinCatalog();
buildinFileCatalog.FileVersion = BuiltinCatalogDefine.FileVersion;
buildinFileCatalog.FileVersion = BuiltinCatalogConsts.FileVersion;
buildinFileCatalog.PackageName = packageName;
buildinFileCatalog.PackageVersion = packageVersion;
// 创建输出文件
string jsonFilePath = $"{outputPath}/{BuiltinCatalogDefine.JsonFileName}";
string jsonFilePath = $"{outputPath}/{BuiltinCatalogConsts.JsonFileName}";
if (File.Exists(jsonFilePath))
File.Delete(jsonFilePath);
SerializeToJson(jsonFilePath, buildinFileCatalog);
// 创建输出文件
string binaryFilePath = $"{outputPath}/{BuiltinCatalogDefine.BinaryFileName}";
string binaryFilePath = $"{outputPath}/{BuiltinCatalogConsts.BinaryFileName}";
if (File.Exists(binaryFilePath))
File.Delete(binaryFilePath);
SerializeToBinary(binaryFilePath, buildinFileCatalog);
@@ -167,13 +167,13 @@ namespace YooAsset
using (FileStream fs = new FileStream(savePath, FileMode.Create))
{
// 创建缓存器
BufferWriter buffer = new BufferWriter(BuiltinCatalogDefine.MaxFileSize);
BufferWriter buffer = new BufferWriter(BuiltinCatalogConsts.MaxFileSize);
// 写入文件标记
buffer.WriteUInt32(BuiltinCatalogDefine.FileHeader);
buffer.WriteUInt32(BuiltinCatalogConsts.FileHeader);
// 写入文件版本
buffer.WriteUTF8(BuiltinCatalogDefine.FileVersion);
buffer.WriteUTF8(BuiltinCatalogConsts.FileVersion);
// 写入文件头信息
buffer.WriteUTF8(catalog.PackageName);
@@ -216,13 +216,13 @@ namespace YooAsset
// 读取文件标记
uint fileHeader = buffer.ReadUInt32();
if (fileHeader != BuiltinCatalogDefine.FileHeader)
if (fileHeader != BuiltinCatalogConsts.FileHeader)
throw new Exception("Invalid catalog file.");
// 读取文件版本
string fileVersion = buffer.ReadUTF8();
if (fileVersion != BuiltinCatalogDefine.FileVersion)
throw new Exception($"The catalog file version is not compatible: {fileVersion} != {BuiltinCatalogDefine.FileVersion}");
if (fileVersion != BuiltinCatalogConsts.FileVersion)
throw new Exception($"The catalog file version is not compatible: {fileVersion} != {BuiltinCatalogConsts.FileVersion}");
BuiltinCatalog catalog = new BuiltinCatalog();
{

View File

@@ -96,7 +96,7 @@ namespace YooAsset
var operation = new FCWriteCacheCompleteOperation($"{nameof(BuiltinFileCache)} is readonly.");
return operation;
}
public virtual FCClearCacheOperation ClearCacheAsync(ClearCacheOptions options)
public virtual FCClearCacheOperation ClearCacheAsync(FCClearCacheOptions options)
{
var operation = new FCClearCacheCompleteOperation($"{nameof(BuiltinFileCache)} is readonly.");
return operation;
@@ -120,7 +120,7 @@ namespace YooAsset
}
else
{
string error = $"{nameof(BuiltinFileCache)} not support load bundle type : {options.Bundle.BundleType}";
string error = $"{nameof(BuiltinFileCache)} does not support bundle type: {options.Bundle.BundleType}";
var operation = new FCLoadBundleErrorOperation(error);
return operation;
}
@@ -132,7 +132,7 @@ namespace YooAsset
#region
/// <summary>
/// 获取指定缓存
/// 获取指定缓存条目
/// </summary>
internal BuiltinFileCacheEntry GetEntry(string bundleGUID)
{
@@ -143,7 +143,7 @@ namespace YooAsset
}
/// <summary>
/// 添加指定缓存
/// 添加指定缓存条目
/// </summary>
internal void AddEntry(string bundleGUID, BuiltinFileCacheEntry cacheEntry)
{
@@ -158,7 +158,7 @@ namespace YooAsset
/// </summary>
internal string GetCatalogBinaryFileLoadPath()
{
return PathUtility.Combine(RootPath, BuiltinCatalogDefine.BinaryFileName);
return PathUtility.Combine(RootPath, BuiltinCatalogConsts.BinaryFileName);
}
#endregion
}

View File

@@ -72,12 +72,12 @@ namespace YooAsset
if (_loadLocalAssetBundleOp.Status == EOperationStatus.Succeeded)
{
if (_loadLocalAssetBundleOp.BundleResult == null)
throw new YooInternalException("Loaded bundle result is null.");
if (_loadLocalAssetBundleOp.BundleHandle == null)
throw new YooInternalException("Loaded bundle handle is null.");
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = _loadLocalAssetBundleOp.BundleResult;
BundleHandle = _loadLocalAssetBundleOp.BundleHandle;
}
else
{
@@ -164,12 +164,12 @@ namespace YooAsset
if(_loadLocalRawBundleOp.Status == EOperationStatus.Succeeded)
{
if (_loadLocalRawBundleOp.BundleResult == null)
throw new YooInternalException("Loaded bundle result is null.");
if (_loadLocalRawBundleOp.BundleHandle == null)
throw new YooInternalException("Loaded bundle handle is null.");
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = _loadLocalRawBundleOp.BundleResult;
BundleHandle = _loadLocalRawBundleOp.BundleHandle;
}
else
{

View File

@@ -101,9 +101,9 @@ namespace YooAsset
var operation = new EFCWriteCacheOperation(this, options);
return operation;
}
public virtual FCClearCacheOperation ClearCacheAsync(ClearCacheOptions options)
public virtual FCClearCacheOperation ClearCacheAsync(FCClearCacheOptions options)
{
var operation = new FCClearCacheCompleteOperation();
var operation = new EFCClearCacheOperation(this, options);
return operation;
}
public virtual FCVerifyCacheOperation VerifyCacheAsync(FCVerifyCacheOptions options)
@@ -120,7 +120,7 @@ namespace YooAsset
}
else
{
string error = $"{nameof(EditorFileCache)} not support load bundle type : {options.Bundle.BundleType}";
string error = $"{nameof(EditorFileCache)} does not support bundle type: {options.Bundle.BundleType}";
var operation = new FCLoadBundleErrorOperation(error);
return operation;
}
@@ -135,7 +135,15 @@ namespace YooAsset
#region
/// <summary>
/// 添加指定缓存
/// 获取所有缓存条目
/// </summary>
internal IReadOnlyCollection<EditorFileCacheEntry> GetAllEntries()
{
return _cacheEntries.Values;
}
/// <summary>
/// 添加指定缓存条目
/// </summary>
internal void AddEntry(string bundleGUID, EditorFileCacheEntry cacheEntry)
{
@@ -144,6 +152,17 @@ namespace YooAsset
_cacheEntries.Add(bundleGUID, cacheEntry);
}
/// <summary>
/// 删除指定缓存条目
/// </summary>
internal void RemoveEntry(string bundleGUID)
{
if (_cacheEntries.TryGetValue(bundleGUID, out EditorFileCacheEntry entry))
{
_cacheEntries.Remove(bundleGUID);
}
}
#endregion
}
}

View File

@@ -0,0 +1,93 @@
using System.Collections.Generic;
namespace YooAsset
{
/// <summary>
/// 清理沙盒文件缓存操作
/// </summary>
internal class EFCClearCacheOperation : FCClearCacheOperation
{
private enum ESteps
{
None,
GetResult,
ClearCacheFiles,
Done,
}
private readonly EditorFileCache _fileCache;
private readonly FCClearCacheOptions _options;
private List<string> _bundleGUIDs;
private ESteps _steps = ESteps.None;
internal EFCClearCacheOperation(EditorFileCache fileCache, FCClearCacheOptions options)
{
_fileCache = fileCache;
_options = options;
}
internal override void InternalStart()
{
_steps = ESteps.GetResult;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.GetResult)
{
ClearResult clearResult;
if (_options.ClearMode == EFileClearMode.ClearAllBundleFiles.ToString())
{
clearResult = GetAllCache(_fileCache.GetAllEntries());
}
else if (_options.ClearMode == EFileClearMode.ClearUnusedBundleFiles.ToString())
{
clearResult = GetUnusedCache(_options, _fileCache.GetAllEntries());
}
else if (_options.ClearMode == EFileClearMode.ClearBundleFilesByLocations.ToString())
{
clearResult = GetCacheByLocations(_options, _fileCache.GetAllEntries());
}
else if (_options.ClearMode == EFileClearMode.ClearBundleFilesByTags.ToString())
{
clearResult = GetCacheByTags(_options, _fileCache.GetAllEntries());
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Invalid clear mode: {_options.ClearMode}";
return;
}
if (clearResult.Succeeded == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = clearResult.Error;
return;
}
_bundleGUIDs = clearResult.BundleGUIDs;
_steps = ESteps.ClearCacheFiles;
}
if (_steps == ESteps.ClearCacheFiles)
{
foreach(var bundleGUID in _bundleGUIDs)
{
_fileCache.RemoveEntry(bundleGUID);
}
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
}
}
internal override void InternalWaitForCompletion()
{
ExecuteBatch();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4dd5972832b5c9e40874d84a0e3b4b60
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -10,6 +10,7 @@ namespace YooAsset
{
None,
CheckCache,
CheckFilePath,
LoadBundle,
Done,
}
@@ -17,6 +18,7 @@ namespace YooAsset
private readonly EditorFileCache _fileCache;
private readonly PackageBundle _bundle;
private int _asyncSimulateFrame;
private string _editorFilePath;
private ESteps _steps = ESteps.None;
public EFCLoadBundleOperation(EditorFileCache fileCache, PackageBundle bundle)
@@ -44,7 +46,22 @@ namespace YooAsset
return;
}
_steps = ESteps.LoadBundle;
_steps = ESteps.CheckFilePath;
}
if (_steps == ESteps.CheckFilePath)
{
_editorFilePath = EditorFileSystemTools.GetEditorFilePath(_bundle);
if (string.IsNullOrEmpty(_editorFilePath))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Editor file path is null. Bundle: {_bundle.BundleName}";
}
else
{
_steps = ESteps.LoadBundle;
}
}
if (_steps == ESteps.LoadBundle)
@@ -61,9 +78,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
string editorFilePath = EditorFileSystemTools.GetEditorFilePath(_bundle);
BundleResult = new VirtualBundleResult(editorFilePath, _bundle);
BundleHandle = new VirtualBundleHandle(_editorFilePath, _bundle);
}
}
else
@@ -73,9 +88,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
string editorFilePath = EditorFileSystemTools.GetEditorFilePath(_bundle);
BundleResult = new VirtualBundleResult(editorFilePath, _bundle);
BundleHandle = new VirtualBundleHandle(_editorFilePath, _bundle);
}
}
}

View File

@@ -92,8 +92,8 @@ namespace YooAsset
// 创建验证元素类
string fileRootPath = childDirectory;
string dataFilePath = PathUtility.Combine(fileRootPath, SandboxFileCacheDefine.BundleDataFileName);
string infoFilePath = PathUtility.Combine(fileRootPath, SandboxFileCacheDefine.BundleInfoFileName);
string dataFilePath = PathUtility.Combine(fileRootPath, SandboxFileCacheConsts.BundleDataFileName);
string infoFilePath = PathUtility.Combine(fileRootPath, SandboxFileCacheConsts.BundleInfoFileName);
var element = new SearchFileInfo(bundleGUID, fileRootPath, dataFilePath, infoFilePath);
Result.Add(element);
}

Some files were not shown because too many files have changed in this diff Show More