Compare commits

...

16 Commits

Author SHA1 Message Date
何冠峰
3e3661ad95 refactor : 重构代码 2026-01-16 14:37:04 +08:00
何冠峰
611ac886b3 refactor : 重构代码 2026-01-16 10:30:02 +08:00
何冠峰
b0e85017d2 refactor : 重构代码 2026-01-16 10:28:01 +08:00
何冠峰
2b6e7856e7 update mini game 2026-01-14 19:28:30 +08:00
何冠峰
8d461056e4 update extension sample 2026-01-14 19:28:07 +08:00
何冠峰
f188cc715a update test sample 2026-01-14 19:27:39 +08:00
何冠峰
329cae1441 refactor : 重构资源包裹模块 2026-01-14 19:26:40 +08:00
何冠峰
c8c74b8c20 refactor : 重构资源包裹模块 2026-01-13 19:11:49 +08:00
何冠峰
b3d024743c update space shooter 2026-01-13 17:09:18 +08:00
何冠峰
246a62a675 refactor : 重构异步操作模块 2026-01-13 17:01:15 +08:00
何冠峰
354ca5197f refactor : 重构异步操作模块 2026-01-13 14:55:31 +08:00
何冠峰
ce4d6911db refactor : 重构异步操作模块 2026-01-13 12:08:02 +08:00
何冠峰
b796b1a44e refactor : 重构异步操作模块 2026-01-13 11:23:50 +08:00
何冠峰
7198e639d9 refactor : 重构异步操作模块 2026-01-12 16:10:24 +08:00
何冠峰
294fa18fec refactor : 重构异步操作模块 2026-01-12 15:35:00 +08:00
何冠峰
a3f689d815 refactor : 重构异步操作模块 2026-01-12 11:09:27 +08:00
187 changed files with 3180 additions and 2930 deletions

View File

@@ -19,7 +19,7 @@ namespace YooAsset.Editor
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(); buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = EBuildPipeline.EditorSimulateBuildPipeline.ToString(); buildParameters.BuildPipeline = EBuildPipeline.EditorSimulateBuildPipeline.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.VirtualBundle; buildParameters.BuildBundleType = (int)EBundleType.VirtualBundle;
buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget; buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget;
buildParameters.PackageName = packageName; buildParameters.PackageName = packageName;
buildParameters.PackageVersion = "Simulate"; buildParameters.PackageVersion = "Simulate";

View File

@@ -96,7 +96,7 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 资源包加密服务类 /// 资源包加密服务类
/// </summary> /// </summary>
public IEncryptionServices EncryptionServices; public IBundleEncryptionServices EncryptionServices;
/// <summary> /// <summary>
/// 资源清单加密服务类 /// 资源清单加密服务类
@@ -146,7 +146,7 @@ namespace YooAsset.Editor
string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineIsNullOrEmpty, "Build pipeline is null or empty !"); string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineIsNullOrEmpty, "Build pipeline is null or empty !");
throw new Exception(message); throw new Exception(message);
} }
if (BuildBundleType == (int)EBuildBundleType.Unknown) if (BuildBundleType == (int)EBundleType.Unknown)
{ {
string message = BuildLogger.GetErrorMessage(ErrorCode.BuildBundleTypeIsUnknown, $"Build bundle type is unknown {BuildBundleType} !"); string message = BuildLogger.GetErrorMessage(ErrorCode.BuildBundleTypeIsUnknown, $"Build bundle type is unknown {BuildBundleType} !");
throw new Exception(message); throw new Exception(message);

View File

@@ -15,7 +15,7 @@ namespace YooAsset.Editor
string buildinRootDirectory = buildParametersContext.GetBuildinRootDirectory(); string buildinRootDirectory = buildParametersContext.GetBuildinRootDirectory();
string buildPackageName = buildParametersContext.Parameters.PackageName; string buildPackageName = buildParametersContext.Parameters.PackageName;
var manifestServices = buildParametersContext.Parameters.ManifestRestoreServices; var manifestServices = buildParametersContext.Parameters.ManifestRestoreServices;
CatalogTools.CreateCatalogFile(manifestServices, buildPackageName, buildinRootDirectory); CatalogFileHelper.CreateFile(manifestServices, buildPackageName, buildinRootDirectory);
// 刷新目录 // 刷新目录
AssetDatabase.Refresh(); AssetDatabase.Refresh();

View File

@@ -31,7 +31,7 @@ namespace YooAsset.Editor
// 创建新补丁清单 // 创建新补丁清单
PackageManifest manifest = new PackageManifest(); PackageManifest manifest = new PackageManifest();
manifest.FileVersion = ManifestDefine.FileVersion; manifest.FileVersion = PackageManifestDefine.FileVersion;
manifest.EnableAddressable = buildMapContext.Command.EnableAddressable; manifest.EnableAddressable = buildMapContext.Command.EnableAddressable;
manifest.SupportExtensionless = buildMapContext.Command.SupportExtensionless; manifest.SupportExtensionless = buildMapContext.Command.SupportExtensionless;
manifest.LocationToLower = buildMapContext.Command.LocationToLower; manifest.LocationToLower = buildMapContext.Command.LocationToLower;
@@ -71,7 +71,7 @@ namespace YooAsset.Editor
{ {
string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion); string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}"; string filePath = $"{packageOutputDirectory}/{fileName}";
ManifestTools.SerializeToJson(filePath, manifest); PackageManifestTools.SerializeToJson(filePath, manifest);
BuildLogger.Log($"Create package manifest file: {filePath}"); BuildLogger.Log($"Create package manifest file: {filePath}");
} }
@@ -81,7 +81,7 @@ namespace YooAsset.Editor
{ {
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion); string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
packagePath = $"{packageOutputDirectory}/{fileName}"; packagePath = $"{packageOutputDirectory}/{fileName}";
ManifestTools.SerializeToBinary(packagePath, manifest, buildParameters.ManifestProcessServices); PackageManifestTools.SerializeToBinary(packagePath, manifest, buildParameters.ManifestProcessServices);
packageHash = HashUtility.FileCRC32(packagePath); packageHash = HashUtility.FileCRC32(packagePath);
BuildLogger.Log($"Create package manifest file: {packagePath}"); BuildLogger.Log($"Create package manifest file: {packagePath}");
} }
@@ -106,7 +106,7 @@ namespace YooAsset.Editor
{ {
ManifestContext manifestContext = new ManifestContext(); ManifestContext manifestContext = new ManifestContext();
byte[] bytesData = FileUtility.ReadAllBytes(packagePath); byte[] bytesData = FileUtility.ReadAllBytes(packagePath);
manifestContext.Manifest = ManifestTools.DeserializeFromBinary(bytesData, buildParameters.ManifestRestoreServices); manifestContext.Manifest = PackageManifestTools.DeserializeFromBinary(bytesData, buildParameters.ManifestRestoreServices);
context.SetContextObject(manifestContext); context.SetContextObject(manifestContext);
} }
} }

View File

@@ -24,7 +24,7 @@ namespace YooAsset.Editor
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.Collection) foreach (var bundleInfo in buildMapContext.Collection)
{ {
EncryptFileInfo fileInfo = new EncryptFileInfo(); EncryptBundleInfo fileInfo = new EncryptBundleInfo();
fileInfo.BundleName = bundleInfo.BundleName; fileInfo.BundleName = bundleInfo.BundleName;
fileInfo.FileLoadPath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; fileInfo.FileLoadPath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
var encryptResult = encryptionServices.Encrypt(fileInfo); var encryptResult = encryptionServices.Encrypt(fileInfo);

View File

@@ -54,8 +54,8 @@ namespace YooAsset.Editor
{ {
string bundleName = bundleInfo.BundleName; string bundleName = bundleInfo.BundleName;
string fileHash = bundleInfo.PackageFileHash; string fileHash = bundleInfo.PackageFileHash;
string fileExtension = ManifestTools.GetRemoteBundleFileExtension(bundleName); string fileExtension = PackageManifestTools.GetRemoteBundleFileExtension(bundleName);
string fileName = ManifestTools.GetRemoteBundleFileName(outputNameStyle, bundleName, fileExtension, fileHash); string fileName = PackageManifestTools.GetRemoteBundleFileName(outputNameStyle, bundleName, fileExtension, fileHash);
bundleInfo.PackageDestFilePath = $"{packageOutputDirectory}/{fileName}"; bundleInfo.PackageDestFilePath = $"{packageOutputDirectory}/{fileName}";
} }
} }

View File

@@ -1,9 +1,9 @@
 
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
public class EncryptionNone : IEncryptionServices public class EncryptionNone : IBundleEncryptionServices
{ {
public EncryptResult Encrypt(EncryptFileInfo fileInfo) public EncryptResult Encrypt(EncryptBundleInfo fileInfo)
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }

View File

@@ -46,13 +46,13 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 创建资源包加密服务类实例 /// 创建资源包加密服务类实例
/// </summary> /// </summary>
protected IEncryptionServices CreateEncryptionServicesInstance() protected IBundleEncryptionServices CreateEncryptionServicesInstance()
{ {
var className = AssetBundleBuilderSetting.GetPackageEncyptionServicesClassName(PackageName, PipelineName); var className = AssetBundleBuilderSetting.GetPackageEncyptionServicesClassName(PackageName, PipelineName);
var classTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices)); var classTypes = EditorTools.GetAssignableTypes(typeof(IBundleEncryptionServices));
var classType = classTypes.Find(x => x.FullName.Equals(className)); var classType = classTypes.Find(x => x.FullName.Equals(className));
if (classType != null) if (classType != null)
return (IEncryptionServices)Activator.CreateInstance(classType); return (IBundleEncryptionServices)Activator.CreateInstance(classType);
else else
return null; return null;
} }
@@ -184,7 +184,7 @@ namespace YooAsset.Editor
protected PopupField<Type> CreateEncryptionServicesField(VisualElement container) protected PopupField<Type> CreateEncryptionServicesField(VisualElement container)
{ {
// 资源包加密服务类 // 资源包加密服务类
var classTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices)); var classTypes = EditorTools.GetAssignableTypes(typeof(IBundleEncryptionServices));
if (classTypes.Count > 0) if (classTypes.Count > 0)
{ {
var className = AssetBundleBuilderSetting.GetPackageEncyptionServicesClassName(PackageName, PipelineName); var className = AssetBundleBuilderSetting.GetPackageEncyptionServicesClassName(PackageName, PipelineName);

View File

@@ -109,7 +109,7 @@ namespace YooAsset.Editor
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(); buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = PipelineName.ToString(); buildParameters.BuildPipeline = PipelineName.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.AssetBundle; buildParameters.BuildBundleType = (int)EBundleType.AssetBundle;
buildParameters.BuildTarget = BuildTarget; buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName; buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = _buildVersionField.value; buildParameters.PackageVersion = _buildVersionField.value;

View File

@@ -66,7 +66,7 @@ namespace YooAsset.Editor
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(); buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = PipelineName.ToString(); buildParameters.BuildPipeline = PipelineName.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.VirtualBundle; buildParameters.BuildBundleType = (int)EBundleType.VirtualBundle;
buildParameters.BuildTarget = BuildTarget; buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName; buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = _buildVersionField.value; buildParameters.PackageVersion = _buildVersionField.value;

View File

@@ -103,7 +103,7 @@ namespace YooAsset.Editor
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(); buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = PipelineName.ToString(); buildParameters.BuildPipeline = PipelineName.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.RawBundle; buildParameters.BuildBundleType = (int)EBundleType.RawBundle;
buildParameters.BuildTarget = BuildTarget; buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName; buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = _buildVersionField.value; buildParameters.PackageVersion = _buildVersionField.value;

View File

@@ -109,7 +109,7 @@ namespace YooAsset.Editor
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(); buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = PipelineName.ToString(); buildParameters.BuildPipeline = PipelineName.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.AssetBundle; buildParameters.BuildBundleType = (int)EBundleType.AssetBundle;
buildParameters.BuildTarget = BuildTarget; buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName; buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = _buildVersionField.value; buildParameters.PackageVersion = _buildVersionField.value;

View File

@@ -277,7 +277,7 @@ namespace YooAsset.Editor
if (dependTableData.BundleInfo.Encrypted) if (dependTableData.BundleInfo.Encrypted)
return; return;
if (_buildReport.Summary.BuildBundleType == (int)EBuildBundleType.AssetBundle) if (_buildReport.Summary.BuildBundleType == (int)EBundleType.AssetBundle)
{ {
string rootDirectory = Path.GetDirectoryName(_reportFilePath); string rootDirectory = Path.GetDirectoryName(_reportFilePath);
string filePath = $"{rootDirectory}/{dependTableData.BundleInfo.FileName}"; string filePath = $"{rootDirectory}/{dependTableData.BundleInfo.FileName}";

View File

@@ -348,7 +348,7 @@ namespace YooAsset.Editor
if (bundleTableData.BundleInfo.Encrypted) if (bundleTableData.BundleInfo.Encrypted)
return; return;
if (_buildReport.Summary.BuildBundleType == (int)EBuildBundleType.AssetBundle) if (_buildReport.Summary.BuildBundleType == (int)EBundleType.AssetBundle)
{ {
string rootDirectory = Path.GetDirectoryName(_reportFilePath); string rootDirectory = Path.GetDirectoryName(_reportFilePath);
string filePath = $"{rootDirectory}/{bundleTableData.BundleInfo.FileName}"; string filePath = $"{rootDirectory}/{bundleTableData.BundleInfo.FileName}";

View File

@@ -255,12 +255,7 @@ namespace YooAsset
if (_watchdogAborted) if (_watchdogAborted)
return; return;
#if UNITY_2020_3_OR_NEWER double realtimeSinceStartup = TimeUtility.RealtimeSinceStartup;
double realtimeSinceStartup = UnityEngine.Time.realtimeSinceStartupAsDouble;
#else
double realtimeSinceStartup = UnityEngine.Time.realtimeSinceStartup;
#endif
if (DownloadedBytes != _lastDownloadBytes) if (DownloadedBytes != _lastDownloadBytes)
{ {
_lastDownloadBytes = DownloadedBytes; _lastDownloadBytes = DownloadedBytes;

View File

@@ -87,7 +87,7 @@ namespace YooAsset
if (Status == EDownloadRequestStatus.None) if (Status == EDownloadRequestStatus.None)
{ {
Status = EDownloadRequestStatus.Running; Status = EDownloadRequestStatus.Running;
_lastUpdateTime = GetUnityEngineRealtime(); _lastUpdateTime = TimeUtility.RealtimeSinceStartup;
} }
} }
@@ -99,7 +99,7 @@ namespace YooAsset
if (Status != EDownloadRequestStatus.Running) if (Status != EDownloadRequestStatus.Running)
return; return;
double currentTime = GetUnityEngineRealtime(); double currentTime = TimeUtility.RealtimeSinceStartup;
double deltaTime = currentTime - _lastUpdateTime; double deltaTime = currentTime - _lastUpdateTime;
_lastUpdateTime = currentTime; _lastUpdateTime = currentTime;
@@ -137,14 +137,5 @@ namespace YooAsset
public void Dispose() public void Dispose()
{ {
} }
private double GetUnityEngineRealtime()
{
#if UNITY_2020_3_OR_NEWER
return UnityEngine.Time.realtimeSinceStartupAsDouble;
#else
return UnityEngine.Time.realtimeSinceStartup;
#endif
}
} }
} }

View File

@@ -3,103 +3,9 @@ using System.Collections.Generic;
namespace YooAsset namespace YooAsset
{ {
/// <summary> /// <summary>
/// 下载器结束 /// 导入的资源包信息
/// </summary> /// </summary>
public struct DownloaderFinishData public struct ImportBundleInfo
{
/// <summary>
/// 所属包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 是否成功
/// </summary>
public bool Succeed;
}
/// <summary>
/// 下载器相关的更新数据
/// </summary>
public struct DownloadUpdateData
{
/// <summary>
/// 所属包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 下载进度 (0-1f)
/// </summary>
public float Progress;
/// <summary>
/// 下载文件总数
/// </summary>
public int TotalDownloadCount;
/// <summary>
/// 当前完成的下载文件数量
/// </summary>
public int CurrentDownloadCount;
/// <summary>
/// 下载数据总大小(单位:字节)
/// </summary>
public long TotalDownloadBytes;
/// <summary>
/// 当前完成的下载数据大小(单位:字节)
/// </summary>
public long CurrentDownloadBytes;
}
/// <summary>
/// 下载器相关的错误数据
/// </summary>
public struct DownloadErrorData
{
/// <summary>
/// 所属包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 下载失败的文件名称
/// </summary>
public string FileName;
/// <summary>
/// 错误信息
/// </summary>
public string ErrorInfo;
}
/// <summary>
/// 下载器相关的文件数据
/// </summary>
public struct DownloadFileData
{
/// <summary>
/// 所属包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 下载的文件名称
/// </summary>
public string FileName;
/// <summary>
/// 下载的文件大小
/// </summary>
public long FileSize;
}
/// <summary>
/// 导入文件的信息
/// </summary>
public struct ImportFileInfo
{ {
/// <summary> /// <summary>
/// 本地文件路径 /// 本地文件路径

View File

@@ -41,20 +41,20 @@ DownloadSystem 的职责是提供“可替换后端 + 统一请求接口 + 轮
``` ```
┌─────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐
│ 上层调用者 │ │ 上层调用者
│ (FileSystem / ResourceManager) │ (FileSystem / ResourceManager) │
└─────────────────────────┬───────────────────────────────┘ └─────────────────────────┬───────────────────────────────┘
┌─────────────────────────▼───────────────────────────────┐ ┌─────────────────────────▼───────────────────────────────┐
│ IDownloadBackend │ IDownloadBackend │
│ (后端接口) │ │ (后端接口) │
│ 定义网络库合约,工厂模式创建请求 │ │ 定义网络库合约,工厂模式创建请求
└─────────────────────────┬───────────────────────────────┘ └─────────────────────────┬───────────────────────────────┘
┌─────────────────────────▼───────────────────────────────┐ ┌─────────────────────────▼───────────────────────────────┐
│ IDownloadRequest │ IDownloadRequest │
│ (请求接口) │ │ (请求接口) │
│ 轮询式生命周期管理,状态机驱动 │ │ 轮询式生命周期管理,状态机驱动
└─────────────────────────┬───────────────────────────────┘ └─────────────────────────┬───────────────────────────────┘
┌─────────────────────────▼───────────────────────────────┐ ┌─────────────────────────▼───────────────────────────────┐
@@ -244,16 +244,6 @@ public struct DownloadSimulateRequestArgs
} }
``` ```
### 回调数据结构体
| 结构体 | 用途 | 关键字段 |
|--------|------|----------|
| `DownloaderFinishData` | 下载完成回调 | `PackageName`, `Succeed` |
| `DownloadUpdateData` | 进度更新回调 | `Progress`, `TotalDownloadBytes`, `CurrentDownloadBytes` |
| `DownloadErrorData` | 下载错误回调 | `FileName`, `ErrorInfo` |
| `DownloadFileData` | 文件完成回调 | `FileName`, `FileSize` |
| `ImportFileInfo` | 导入文件元数据 | `FilePath`, `BundleName`, `BundleGUID` |
--- ---
## 核心类说明 ## 核心类说明

View File

@@ -108,14 +108,7 @@ namespace YooAsset
} }
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
while (true) RunBatchExecution();
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
} }
} }
} }

View File

@@ -108,14 +108,7 @@ namespace YooAsset
} }
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
while (true) RunBatchExecution();
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
} }
} }
} }

View File

@@ -107,7 +107,7 @@ namespace YooAsset
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
//注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法! //注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
InternalUpdate(); RunOnceExecution();
} }
public override void UnSuspendLoad() public override void UnSuspendLoad()
{ {

View File

@@ -108,14 +108,7 @@ namespace YooAsset
} }
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
while (true) RunBatchExecution();
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
} }
} }
} }

View File

@@ -109,14 +109,7 @@ namespace YooAsset
} }
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
while (true) RunBatchExecution();
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
} }
} }
} }

View File

@@ -88,14 +88,7 @@ namespace YooAsset
} }
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
while (true) RunBatchExecution();
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
} }
} }
} }

View File

@@ -113,7 +113,7 @@ namespace YooAsset
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
//注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法! //注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
InternalUpdate(); RunOnceExecution();
} }
public override void UnSuspendLoad() public override void UnSuspendLoad()
{ {

View File

@@ -100,14 +100,7 @@ namespace YooAsset
} }
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
while (true) RunBatchExecution();
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
} }
} }
} }

View File

@@ -1,7 +1,7 @@
 
namespace YooAsset namespace YooAsset
{ {
internal class CatalogDefine internal class CatalogFileDefine
{ {
/// <summary> /// <summary>
/// 文件极限大小100MB /// 文件极限大小100MB

View File

@@ -5,14 +5,14 @@ using UnityEngine;
namespace YooAsset namespace YooAsset
{ {
internal static class CatalogTools internal static class CatalogFileHelper
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
/// <summary> /// <summary>
/// 生成包裹的内置资源目录文件 /// 生成包裹的内置资源目录文件
/// 说明:根据指定目录下的文件生成清单文件。 /// 说明:根据指定目录下的文件生成清单文件。
/// </summary> /// </summary>
public static bool CreateCatalogFile(IManifestRestoreServices services, string packageName, string packageDirectory) public static bool CreateFile(IManifestRestoreServices services, string packageName, string packageDirectory)
{ {
// 获取资源清单版本 // 获取资源清单版本
string packageVersion; string packageVersion;
@@ -40,7 +40,7 @@ namespace YooAsset
} }
var binaryData = FileUtility.ReadAllBytes(manifestFilePath); var binaryData = FileUtility.ReadAllBytes(manifestFilePath);
packageManifest = ManifestTools.DeserializeFromBinary(binaryData, services); packageManifest = PackageManifestTools.DeserializeFromBinary(binaryData, services);
} }
// 获取文件名映射关系 // 获取文件名映射关系
@@ -54,7 +54,7 @@ namespace YooAsset
// 创建内置清单实例 // 创建内置清单实例
var buildinFileCatalog = new DefaultBuildinFileCatalog(); var buildinFileCatalog = new DefaultBuildinFileCatalog();
buildinFileCatalog.FileVersion = CatalogDefine.FileVersion; buildinFileCatalog.FileVersion = CatalogFileDefine.FileVersion;
buildinFileCatalog.PackageName = packageName; buildinFileCatalog.PackageName = packageName;
buildinFileCatalog.PackageVersion = packageVersion; buildinFileCatalog.PackageVersion = packageVersion;
@@ -122,11 +122,11 @@ namespace YooAsset
/// <summary> /// <summary>
/// 生成空的包裹内置资源目录文件 /// 生成空的包裹内置资源目录文件
/// </summary> /// </summary>
public static bool CreateEmptyCatalogFile(string packageName, string packageVersion, string outputPath) public static bool CreateEmptyFile(string packageName, string packageVersion, string outputPath)
{ {
// 创建内置清单实例 // 创建内置清单实例
var buildinFileCatalog = new DefaultBuildinFileCatalog(); var buildinFileCatalog = new DefaultBuildinFileCatalog();
buildinFileCatalog.FileVersion = CatalogDefine.FileVersion; buildinFileCatalog.FileVersion = CatalogFileDefine.FileVersion;
buildinFileCatalog.PackageName = packageName; buildinFileCatalog.PackageName = packageName;
buildinFileCatalog.PackageVersion = packageVersion; buildinFileCatalog.PackageVersion = packageVersion;
@@ -173,13 +173,13 @@ namespace YooAsset
using (FileStream fs = new FileStream(savePath, FileMode.Create)) using (FileStream fs = new FileStream(savePath, FileMode.Create))
{ {
// 创建缓存器 // 创建缓存器
BufferWriter buffer = new BufferWriter(CatalogDefine.FileMaxSize); BufferWriter buffer = new BufferWriter(CatalogFileDefine.FileMaxSize);
// 写入文件标记 // 写入文件标记
buffer.WriteUInt32(CatalogDefine.FileSign); buffer.WriteUInt32(CatalogFileDefine.FileSign);
// 写入文件版本 // 写入文件版本
buffer.WriteUTF8(CatalogDefine.FileVersion); buffer.WriteUTF8(CatalogFileDefine.FileVersion);
// 写入文件头信息 // 写入文件头信息
buffer.WriteUTF8(catalog.PackageName); buffer.WriteUTF8(catalog.PackageName);
@@ -213,13 +213,13 @@ namespace YooAsset
// 读取文件标记 // 读取文件标记
uint fileSign = buffer.ReadUInt32(); uint fileSign = buffer.ReadUInt32();
if (fileSign != CatalogDefine.FileSign) if (fileSign != CatalogFileDefine.FileSign)
throw new Exception("Invalid catalog file !"); throw new Exception("Invalid catalog file !");
// 读取文件版本 // 读取文件版本
string fileVersion = buffer.ReadUTF8(); string fileVersion = buffer.ReadUTF8();
if (fileVersion != CatalogDefine.FileVersion) if (fileVersion != CatalogFileDefine.FileVersion)
throw new Exception($"The catalog file version are not compatible : {fileVersion} != {CatalogDefine.FileVersion}"); throw new Exception($"The catalog file version are not compatible : {fileVersion} != {CatalogFileDefine.FileVersion}");
DefaultBuildinFileCatalog catalog = new DefaultBuildinFileCatalog(); DefaultBuildinFileCatalog catalog = new DefaultBuildinFileCatalog();
{ {

View File

@@ -107,12 +107,12 @@ namespace YooAsset
/// <summary> /// <summary>
/// 自定义参数:解密服务接口的实例类 /// 自定义参数:解密服务接口的实例类
/// </summary> /// </summary>
public IDecryptionServices DecryptionServices { private set; get; } public IBundleDecryptionServices BundleDecryptionServices { private set; get; }
/// <summary> /// <summary>
/// 自定义参数:资源清单服务类 /// 自定义参数:资源清单服务类
/// </summary> /// </summary>
public IManifestRestoreServices ManifestServices { private set; get; } public IManifestRestoreServices ManifestRestoreServices { private set; get; }
/// <summary> /// <summary>
/// 自定义参数:拷贝内置文件接口的实例类 /// 自定义参数:拷贝内置文件接口的实例类
@@ -129,39 +129,40 @@ namespace YooAsset
var operation = new DBFSInitializeOperation(this); var operation = new DBFSInitializeOperation(this);
return operation; return operation;
} }
public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(RequestPackageVersionOptions options)
{
var operation = new DBFSLoadPackageManifestOperation(this, packageVersion);
return operation;
}
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout)
{ {
var operation = new DBFSRequestPackageVersionOperation(this); var operation = new DBFSRequestPackageVersionOperation(this);
return operation; return operation;
} }
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options) public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(LoadPackageManifestOptions options)
{ {
return _unpackFileSystem.ClearCacheFilesAsync(manifest, options); var operation = new DBFSLoadPackageManifestOperation(this, options.PackageVersion);
return operation;
} }
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(ClearCacheFilesOptions options)
{
return _unpackFileSystem.ClearCacheFilesAsync(options);
}
public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options)
{ {
// 注意:业务层的解压器会依赖该方法 // 注意:业务层的解压器会依赖该方法
options.ImportFilePath = GetBuildinFileLoadPath(bundle); options.ImportFilePath = GetBuildinFileLoadPath(options.Bundle);
return _unpackFileSystem.DownloadFileAsync(bundle, options); return _unpackFileSystem.DownloadFileAsync(options);
} }
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options)
{ {
PackageBundle bundle = options.Bundle;
if (IsUnpackBundleFile(bundle)) if (IsUnpackBundleFile(bundle))
{ {
return _unpackFileSystem.LoadBundleFile(bundle); return _unpackFileSystem.LoadBundleAsync(options);
} }
if (bundle.BundleType == (int)EBuildBundleType.AssetBundle) if (bundle.BundleType == (int)EBundleType.AssetBundle)
{ {
var operation = new DBFSLoadAssetBundleOperation(this, bundle); var operation = new DBFSLoadAssetBundleOperation(this, bundle);
return operation; return operation;
} }
else if (bundle.BundleType == (int)EBuildBundleType.RawBundle) else if (bundle.BundleType == (int)EBundleType.RawBundle)
{ {
var operation = new DBFSLoadRawBundleOperation(this, bundle); var operation = new DBFSLoadRawBundleOperation(this, bundle);
return operation; return operation;
@@ -224,13 +225,13 @@ namespace YooAsset
{ {
UnpackFileSystemRoot = (string)value; UnpackFileSystemRoot = (string)value;
} }
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES) else if (name == FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES)
{ {
DecryptionServices = (IDecryptionServices)value; BundleDecryptionServices = (IBundleDecryptionServices)value;
} }
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES) else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES)
{ {
ManifestServices = (IManifestRestoreServices)value; ManifestRestoreServices = (IManifestRestoreServices)value;
} }
else if (name == FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES) else if (name == FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES)
{ {
@@ -264,7 +265,7 @@ namespace YooAsset
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel); _unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY, FileVerifyMaxConcurrency); _unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY, FileVerifyMaxConcurrency);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, AppendFileExtension); _unpackFileSystem.SetParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, AppendFileExtension);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, DecryptionServices); _unpackFileSystem.SetParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, BundleDecryptionServices);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES, CopyLocalFileServices); _unpackFileSystem.SetParameter(FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES, CopyLocalFileServices);
_unpackFileSystem.OnCreate(packageName, UnpackFileSystemRoot); _unpackFileSystem.OnCreate(packageName, UnpackFileSystemRoot);
} }
@@ -409,7 +410,7 @@ namespace YooAsset
if (bundle.Encrypted) if (bundle.Encrypted)
return true; return true;
if (bundle.BundleType == (int)EBuildBundleType.RawBundle) if (bundle.BundleType == (int)EBundleType.RawBundle)
return true; return true;
return false; return false;
@@ -479,31 +480,31 @@ namespace YooAsset
/// <summary> /// <summary>
/// 加载加密的资源文件 /// 加载加密的资源文件
/// </summary> /// </summary>
public DecryptResult LoadEncryptedAssetBundle(PackageBundle bundle) public DecryptSyncResult LoadEncryptedBundleSync(PackageBundle bundle)
{ {
string filePath = GetBuildinFileLoadPath(bundle); string filePath = GetBuildinFileLoadPath(bundle);
var fileInfo = new DecryptFileInfo() var bundleInfo = new DecryptBundleInfo()
{ {
BundleName = bundle.BundleName, BundleName = bundle.BundleName,
FileLoadCRC = bundle.UnityCRC, FileLoadCRC = bundle.UnityCRC,
FileLoadPath = filePath, FileLoadPath = filePath,
}; };
return DecryptionServices.LoadAssetBundle(fileInfo); return BundleDecryptionServices.LoadAssetBundleSync(bundleInfo);
} }
/// <summary> /// <summary>
/// 加载加密的资源文件 /// 加载加密的资源文件
/// </summary> /// </summary>
public DecryptResult LoadEncryptedAssetBundleAsync(PackageBundle bundle) public DecryptAsyncResult LoadEncryptedBundleAsync(PackageBundle bundle)
{ {
string filePath = GetBuildinFileLoadPath(bundle); string filePath = GetBuildinFileLoadPath(bundle);
var fileInfo = new DecryptFileInfo() var bundleInfo = new DecryptBundleInfo()
{ {
BundleName = bundle.BundleName, BundleName = bundle.BundleName,
FileLoadCRC = bundle.UnityCRC, FileLoadCRC = bundle.UnityCRC,
FileLoadPath = filePath, FileLoadPath = filePath,
}; };
return DecryptionServices.LoadAssetBundleAsync(fileInfo); return BundleDecryptionServices.LoadAssetBundleAsync(bundleInfo);
} }
#endregion #endregion
} }

View File

@@ -41,6 +41,205 @@ namespace YooAsset
return; return;
if (_steps == ESteps.LoadAssetBundle) if (_steps == ESteps.LoadAssetBundle)
{
if (_bundle.Encrypted)
{
if (_fileSystem.BundleDecryptionServices == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The {nameof(IBundleDecryptionServices)} is null !";
YooLogger.Error(Error);
return;
}
}
if (IsWaitForAsyncComplete)
{
if (_bundle.Encrypted)
{
var decryptResult = _fileSystem.LoadEncryptedBundleSync(_bundle);
_assetBundle = decryptResult.Result;
_managedStream = decryptResult.ManagedStream;
}
else
{
string filePath = _fileSystem.GetBuildinFileLoadPath(_bundle);
_assetBundle = AssetBundle.LoadFromFile(filePath);
}
}
else
{
if (_bundle.Encrypted)
{
var decryptResult = _fileSystem.LoadEncryptedBundleAsync(_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;
Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, _managedStream);
Status = EOperationStatus.Succeed;
}
}
}
internal override void InternalWaitForAsyncComplete()
{
RunBatchExecution();
}
}
/// <summary>
/// 加载原生文件
/// </summary>
internal class DBFSLoadRawBundleOperation : FSLoadBundleOperation
{
private enum ESteps
{
None,
LoadBuildinRawBundle,
Done,
}
private readonly DefaultBuildinFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private ESteps _steps = ESteps.None;
internal DBFSLoadRawBundleOperation(DefaultBuildinFileSystem fileSystem, PackageBundle bundle)
{
_fileSystem = fileSystem;
_bundle = bundle;
}
internal override void InternalStart()
{
DownloadProgress = 1f;
DownloadedBytes = _bundle.FileSize;
_steps = ESteps.LoadBuildinRawBundle;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadBuildinRawBundle)
{
string filePath = _fileSystem.GetBuildinFileLoadPath(_bundle);
#if UNITY_ANDROID
//TODO : 安卓平台内置文件属于APK压缩包内的文件。
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Can not load android buildin raw bundle file : {filePath}";
YooLogger.Error(Error);
#else
if (File.Exists(filePath))
{
_steps = ESteps.Done;
Result = new RawBundleResult(_fileSystem, _bundle);
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Can not found buildin raw bundle file : {filePath}";
YooLogger.Error(Error);
}
#endif
}
}
internal override void InternalWaitForAsyncComplete()
{
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 (_bundle.Encrypted) if (_bundle.Encrypted)
{ {
@@ -131,87 +330,8 @@ namespace YooAsset
} }
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
while (true) RunBatchExecution();
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
} }
} }
/// <summary>
/// 加载原生文件
/// </summary>
internal class DBFSLoadRawBundleOperation : FSLoadBundleOperation
{
private enum ESteps
{
None,
LoadBuildinRawBundle,
Done,
}
private readonly DefaultBuildinFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private ESteps _steps = ESteps.None;
internal DBFSLoadRawBundleOperation(DefaultBuildinFileSystem fileSystem, PackageBundle bundle)
{
_fileSystem = fileSystem;
_bundle = bundle;
}
internal override void InternalStart()
{
DownloadProgress = 1f;
DownloadedBytes = _bundle.FileSize;
_steps = ESteps.LoadBuildinRawBundle;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadBuildinRawBundle)
{
string filePath = _fileSystem.GetBuildinFileLoadPath(_bundle);
#if UNITY_ANDROID
//TODO : 安卓平台内置文件属于APK压缩包内的文件。
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Can not load android buildin raw bundle file : {filePath}";
YooLogger.Error(Error);
#else
if (File.Exists(filePath))
{
_steps = ESteps.Done;
Result = new RawBundleResult(_fileSystem, _bundle);
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Can not found buildin raw bundle file : {filePath}";
YooLogger.Error(Error);
}
#endif #endif
}
}
internal override void InternalWaitForAsyncComplete()
{
while (true)
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
}
}
} }

View File

@@ -82,7 +82,7 @@ namespace YooAsset
{ {
try try
{ {
Catalog = CatalogTools.DeserializeFromBinary(_fileData); Catalog = CatalogFileHelper.DeserializeFromBinary(_fileData);
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Succeed; Status = EOperationStatus.Succeed;
} }

View File

@@ -86,7 +86,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData) if (_steps == ESteps.VerifyFileData)
{ {
if (ManifestTools.VerifyManifestData(_fileData, _packageHash)) if (PackageManifestTools.VerifyManifestData(_fileData, _packageHash))
{ {
_steps = ESteps.LoadManifest; _steps = ESteps.LoadManifest;
} }
@@ -102,7 +102,7 @@ namespace YooAsset
{ {
if (_deserializer == null) if (_deserializer == null)
{ {
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _fileData); _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestRestoreServices, _fileData);
_deserializer.StartOperation(); _deserializer.StartOperation();
AddChildOperation(_deserializer); AddChildOperation(_deserializer);
} }

View File

@@ -129,12 +129,12 @@ namespace YooAsset
/// <summary> /// <summary>
/// 自定义参数:解密服务接口的实例类 /// 自定义参数:解密服务接口的实例类
/// </summary> /// </summary>
public IDecryptionServices DecryptionServices { private set; get; } public IBundleDecryptionServices BundleDecryptionServices { private set; get; }
/// <summary> /// <summary>
/// 自定义参数:资源清单服务类 /// 自定义参数:资源清单服务类
/// </summary> /// </summary>
public IManifestRestoreServices ManifestServices { private set; get; } public IManifestRestoreServices ManifestRestoreServices { private set; get; }
/// <summary> /// <summary>
/// 自定义参数:拷贝内置文件接口的实例类 /// 自定义参数:拷贝内置文件接口的实例类
@@ -151,17 +151,17 @@ namespace YooAsset
var operation = new DCFSInitializeOperation(this); var operation = new DCFSInitializeOperation(this);
return operation; return operation;
} }
public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(RequestPackageVersionOptions options)
{ {
var operation = new DCFSLoadPackageManifestOperation(this, packageVersion, timeout); var operation = new DCFSRequestPackageVersionOperation(this, options.AppendTimeTicks, options.Timeout);
return operation; return operation;
} }
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout) public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(LoadPackageManifestOptions options)
{ {
var operation = new DCFSRequestPackageVersionOperation(this, appendTimeTicks, timeout); var operation = new DCFSLoadPackageManifestOperation(this, options.PackageVersion, options.Timeout);
return operation; return operation;
} }
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options) public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(ClearCacheFilesOptions options)
{ {
if (options.ClearMode == EFileClearMode.ClearAllBundleFiles.ToString()) if (options.ClearMode == EFileClearMode.ClearAllBundleFiles.ToString())
{ {
@@ -170,17 +170,17 @@ namespace YooAsset
} }
else if (options.ClearMode == EFileClearMode.ClearUnusedBundleFiles.ToString()) else if (options.ClearMode == EFileClearMode.ClearUnusedBundleFiles.ToString())
{ {
var operation = new ClearUnusedCacheBundleFilesOperation(this, manifest); var operation = new ClearUnusedCacheBundleFilesOperation(this, options.Manifest);
return operation; return operation;
} }
else if (options.ClearMode == EFileClearMode.ClearBundleFilesByLocations.ToString()) else if (options.ClearMode == EFileClearMode.ClearBundleFilesByLocations.ToString())
{ {
var operation = new ClearCacheBundleFilesByLocationsOperaiton(this, manifest, options.ClearParam); var operation = new ClearCacheBundleFilesByLocationsOperaiton(this, options.Manifest, options.ClearParam);
return operation; return operation;
} }
else if (options.ClearMode == EFileClearMode.ClearBundleFilesByTags.ToString()) else if (options.ClearMode == EFileClearMode.ClearBundleFilesByTags.ToString())
{ {
var operation = new ClearCacheBundleFilesByTagsOperaiton(this, manifest, options.ClearParam); var operation = new ClearCacheBundleFilesByTagsOperaiton(this, options.Manifest, options.ClearParam);
return operation; return operation;
} }
else if (options.ClearMode == EFileClearMode.ClearAllManifestFiles.ToString()) else if (options.ClearMode == EFileClearMode.ClearAllManifestFiles.ToString())
@@ -190,7 +190,7 @@ namespace YooAsset
} }
else if (options.ClearMode == EFileClearMode.ClearUnusedManifestFiles.ToString()) else if (options.ClearMode == EFileClearMode.ClearUnusedManifestFiles.ToString())
{ {
var operation = new ClearUnusedCacheManifestFilesOperation(this, manifest); var operation = new ClearUnusedCacheManifestFilesOperation(this, options.Manifest);
return operation; return operation;
} }
else else
@@ -200,9 +200,10 @@ namespace YooAsset
return operation; return operation;
} }
} }
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options)
{ {
// 获取下载地址 // 获取下载地址
PackageBundle bundle = options.Bundle;
if (string.IsNullOrEmpty(options.ImportFilePath)) if (string.IsNullOrEmpty(options.ImportFilePath))
{ {
// 注意:如果是解压文件系统类,这里会返回本地内置文件的下载路径 // 注意:如果是解压文件系统类,这里会返回本地内置文件的下载路径
@@ -217,17 +218,18 @@ namespace YooAsset
options.SetURL(mainURL, mainURL); options.SetURL(mainURL, mainURL);
} }
var downloader = new DownloadPackageBundleOperation(this, bundle, options); var downloader = new DownloadPackageBundleOperation(this, options);
return downloader; return downloader;
} }
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options)
{ {
if (bundle.BundleType == (int)EBuildBundleType.AssetBundle) PackageBundle bundle = options.Bundle;
if (bundle.BundleType == (int)EBundleType.AssetBundle)
{ {
var operation = new DCFSLoadAssetBundleOperation(this, bundle); var operation = new DCFSLoadAssetBundleOperation(this, bundle);
return operation; return operation;
} }
else if (bundle.BundleType == (int)EBuildBundleType.RawBundle) else if (bundle.BundleType == (int)EBundleType.RawBundle)
{ {
var operation = new DCFSLoadRawBundleOperation(this, bundle); var operation = new DCFSLoadRawBundleOperation(this, bundle);
return operation; return operation;
@@ -315,13 +317,13 @@ namespace YooAsset
{ {
ResumeDownloadResponseCodes = (List<long>)value; ResumeDownloadResponseCodes = (List<long>)value;
} }
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES) else if (name == FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES)
{ {
DecryptionServices = (IDecryptionServices)value; BundleDecryptionServices = (IBundleDecryptionServices)value;
} }
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES) else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES)
{ {
ManifestServices = (IManifestRestoreServices)value; ManifestRestoreServices = (IManifestRestoreServices)value;
} }
else if (name == FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES) else if (name == FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES)
{ {
@@ -403,20 +405,20 @@ namespace YooAsset
if (bundle.Encrypted) if (bundle.Encrypted)
{ {
if (DecryptionServices == null) if (BundleDecryptionServices == null)
{ {
YooLogger.Error($"The {nameof(IDecryptionServices)} is null !"); YooLogger.Error($"The {nameof(IBundleDecryptionServices)} is null !");
return null; return null;
} }
string filePath = GetCacheBundleFileLoadPath(bundle); string filePath = GetCacheBundleFileLoadPath(bundle);
var fileInfo = new DecryptFileInfo() var bundleInfo = new DecryptBundleInfo()
{ {
BundleName = bundle.BundleName, BundleName = bundle.BundleName,
FileLoadCRC = bundle.UnityCRC, FileLoadCRC = bundle.UnityCRC,
FileLoadPath = filePath, FileLoadPath = filePath,
}; };
return DecryptionServices.ReadFileData(fileInfo); return BundleDecryptionServices.ReadFileData(bundleInfo);
} }
else else
{ {
@@ -431,20 +433,20 @@ namespace YooAsset
if (bundle.Encrypted) if (bundle.Encrypted)
{ {
if (DecryptionServices == null) if (BundleDecryptionServices == null)
{ {
YooLogger.Error($"The {nameof(IDecryptionServices)} is null !"); YooLogger.Error($"The {nameof(IBundleDecryptionServices)} is null !");
return null; return null;
} }
string filePath = GetCacheBundleFileLoadPath(bundle); string filePath = GetCacheBundleFileLoadPath(bundle);
var fileInfo = new DecryptFileInfo() var bundleInfo = new DecryptBundleInfo()
{ {
BundleName = bundle.BundleName, BundleName = bundle.BundleName,
FileLoadCRC = bundle.UnityCRC, FileLoadCRC = bundle.UnityCRC,
FileLoadPath = filePath, FileLoadPath = filePath,
}; };
return DecryptionServices.ReadFileText(fileInfo); return BundleDecryptionServices.ReadFileText(bundleInfo);
} }
else else
{ {
@@ -649,46 +651,46 @@ namespace YooAsset
/// <summary> /// <summary>
/// 加载加密资源文件 /// 加载加密资源文件
/// </summary> /// </summary>
public DecryptResult LoadEncryptedAssetBundle(PackageBundle bundle) public DecryptSyncResult LoadEncryptedBundleSync(PackageBundle bundle)
{ {
string filePath = GetCacheBundleFileLoadPath(bundle); string filePath = GetCacheBundleFileLoadPath(bundle);
var fileInfo = new DecryptFileInfo() var bundleInfo = new DecryptBundleInfo()
{ {
BundleName = bundle.BundleName, BundleName = bundle.BundleName,
FileLoadCRC = bundle.UnityCRC, FileLoadCRC = bundle.UnityCRC,
FileLoadPath = filePath, FileLoadPath = filePath,
}; };
return DecryptionServices.LoadAssetBundle(fileInfo); return BundleDecryptionServices.LoadAssetBundleSync(bundleInfo);
} }
/// <summary> /// <summary>
/// 加载加密资源文件 /// 加载加密资源文件
/// </summary> /// </summary>
public DecryptResult LoadEncryptedAssetBundleAsync(PackageBundle bundle) public DecryptAsyncResult LoadEncryptedBundleAsync(PackageBundle bundle)
{ {
string filePath = GetCacheBundleFileLoadPath(bundle); string filePath = GetCacheBundleFileLoadPath(bundle);
var fileInfo = new DecryptFileInfo() var bundleInfo = new DecryptBundleInfo()
{ {
BundleName = bundle.BundleName, BundleName = bundle.BundleName,
FileLoadCRC = bundle.UnityCRC, FileLoadCRC = bundle.UnityCRC,
FileLoadPath = filePath, FileLoadPath = filePath,
}; };
return DecryptionServices.LoadAssetBundleAsync(fileInfo); return BundleDecryptionServices.LoadAssetBundleAsync(bundleInfo);
} }
/// <summary> /// <summary>
/// 加载加密资源文件 /// 加载加密资源文件
/// </summary> /// </summary>
public DecryptResult LoadEncryptedAssetBundleFallback(PackageBundle bundle) public DecryptSyncResult LoadEncryptedBundleFallback(PackageBundle bundle)
{ {
string filePath = GetCacheBundleFileLoadPath(bundle); string filePath = GetCacheBundleFileLoadPath(bundle);
var fileInfo = new DecryptFileInfo() var bundleInfo = new DecryptBundleInfo()
{ {
BundleName = bundle.BundleName, BundleName = bundle.BundleName,
FileLoadCRC = bundle.UnityCRC, FileLoadCRC = bundle.UnityCRC,
FileLoadPath = filePath, FileLoadPath = filePath,
}; };
return DecryptionServices.LoadAssetBundleFallback(fileInfo); return BundleDecryptionServices.LoadAssetBundleFallback(bundleInfo);
} }
#endregion #endregion
} }

View File

@@ -79,8 +79,8 @@ namespace YooAsset
{ {
if (_downloadFileOp == null) if (_downloadFileOp == null)
{ {
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue); DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, options); _downloadFileOp = _fileSystem.DownloadFileAsync(options);
_downloadFileOp.StartOperation(); _downloadFileOp.StartOperation();
AddChildOperation(_downloadFileOp); AddChildOperation(_downloadFileOp);
} }
@@ -127,11 +127,11 @@ namespace YooAsset
{ {
if (_bundle.Encrypted) if (_bundle.Encrypted)
{ {
if (_fileSystem.DecryptionServices == null) if (_fileSystem.BundleDecryptionServices == null)
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Failed; Status = EOperationStatus.Failed;
Error = $"The {nameof(IDecryptionServices)} is null !"; Error = $"The {nameof(IBundleDecryptionServices)} is null !";
YooLogger.Error(Error); YooLogger.Error(Error);
return; return;
} }
@@ -141,7 +141,7 @@ namespace YooAsset
{ {
if (_bundle.Encrypted) if (_bundle.Encrypted)
{ {
var decryptResult = _fileSystem.LoadEncryptedAssetBundle(_bundle); var decryptResult = _fileSystem.LoadEncryptedBundleSync(_bundle);
_assetBundle = decryptResult.Result; _assetBundle = decryptResult.Result;
_managedStream = decryptResult.ManagedStream; _managedStream = decryptResult.ManagedStream;
} }
@@ -155,7 +155,7 @@ namespace YooAsset
{ {
if (_bundle.Encrypted) if (_bundle.Encrypted)
{ {
var decryptResult = _fileSystem.LoadEncryptedAssetBundleAsync(_bundle); var decryptResult = _fileSystem.LoadEncryptedBundleAsync(_bundle);
_createRequest = decryptResult.CreateRequest; _createRequest = decryptResult.CreateRequest;
_managedStream = decryptResult.ManagedStream; _managedStream = decryptResult.ManagedStream;
} }
@@ -202,7 +202,7 @@ namespace YooAsset
{ {
if (_bundle.Encrypted) if (_bundle.Encrypted)
{ {
var decryptResult = _fileSystem.LoadEncryptedAssetBundleFallback(_bundle); var decryptResult = _fileSystem.LoadEncryptedBundleFallback(_bundle);
_assetBundle = decryptResult.Result; _assetBundle = decryptResult.Result;
if (_assetBundle != null) if (_assetBundle != null)
{ {
@@ -262,14 +262,7 @@ namespace YooAsset
} }
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
while (true) RunBatchExecution();
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
} }
} }
@@ -355,8 +348,8 @@ namespace YooAsset
{ {
if (_downloadFileOp == null) if (_downloadFileOp == null)
{ {
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue); DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, options); _downloadFileOp = _fileSystem.DownloadFileAsync(options);
_downloadFileOp.StartOperation(); _downloadFileOp.StartOperation();
AddChildOperation(_downloadFileOp); AddChildOperation(_downloadFileOp);
} }
@@ -419,14 +412,7 @@ namespace YooAsset
} }
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
while (true) RunBatchExecution();
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
} }
} }
} }

View File

@@ -26,7 +26,7 @@ namespace YooAsset
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
internal DownloadPackageBundleOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle) internal DownloadPackageBundleOperation(DefaultCacheFileSystem fileSystem, DownloadFileOptions options) : base(options.Bundle)
{ {
_fileSystem = fileSystem; _fileSystem = fileSystem;
_options = options; _options = options;
@@ -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()
{ {

View File

@@ -59,7 +59,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData) if (_steps == ESteps.VerifyFileData)
{ {
if (ManifestTools.VerifyManifestData(_fileData, _packageHash)) if (PackageManifestTools.VerifyManifestData(_fileData, _packageHash))
{ {
_steps = ESteps.LoadManifest; _steps = ESteps.LoadManifest;
} }
@@ -75,7 +75,7 @@ namespace YooAsset
{ {
if (_deserializer == null) if (_deserializer == null)
{ {
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _fileData); _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestRestoreServices, _fileData);
_deserializer.StartOperation(); _deserializer.StartOperation();
AddChildOperation(_deserializer); AddChildOperation(_deserializer);
} }

View File

@@ -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);
}
} }
} }
} }

View File

@@ -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()
{ {

View File

@@ -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>

View File

@@ -17,7 +17,7 @@ namespace YooAsset
private readonly DefaultCacheFileSystem _fileSystem; private readonly DefaultCacheFileSystem _fileSystem;
private IEnumerator<string> _filesEnumerator = null; private IEnumerator<string> _filesEnumerator = null;
private float _verifyStartTime; private double _verifyStartTime;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
/// <summary> /// <summary>
@@ -33,7 +33,7 @@ namespace YooAsset
internal override void InternalStart() internal override void InternalStart()
{ {
_steps = ESteps.Prepare; _steps = ESteps.Prepare;
_verifyStartTime = UnityEngine.Time.realtimeSinceStartup; _verifyStartTime = TimeUtility.RealtimeSinceStartup;
} }
internal override void InternalUpdate() internal override void InternalUpdate()
{ {
@@ -58,7 +58,7 @@ namespace YooAsset
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Succeed; Status = EOperationStatus.Succeed;
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; double costTime = TimeUtility.RealtimeSinceStartup - _verifyStartTime;
YooLogger.Log($"Search cache files elapsed time {costTime:f1} seconds"); YooLogger.Log($"Search cache files elapsed time {costTime:f1} seconds");
} }
} }

View File

@@ -25,7 +25,7 @@ namespace YooAsset
private List<VerifyFileElement> _verifyingList; private List<VerifyFileElement> _verifyingList;
private int _verifyMaxNum; private int _verifyMaxNum;
private int _verifyTotalCount; private int _verifyTotalCount;
private float _verifyStartTime; private double _verifyStartTime;
private int _succeedCount; private int _succeedCount;
private int _failedCount; private int _failedCount;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
@@ -40,7 +40,7 @@ namespace YooAsset
internal override void InternalStart() internal override void InternalStart()
{ {
_steps = ESteps.InitVerify; _steps = ESteps.InitVerify;
_verifyStartTime = UnityEngine.Time.realtimeSinceStartup; _verifyStartTime = TimeUtility.RealtimeSinceStartup;
} }
internal override void InternalUpdate() internal override void InternalUpdate()
{ {
@@ -84,7 +84,7 @@ namespace YooAsset
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Succeed; Status = EOperationStatus.Succeed;
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; double costTime = TimeUtility.RealtimeSinceStartup - _verifyStartTime;
YooLogger.Log($"Verify cache files elapsed time {costTime:f1} seconds"); YooLogger.Log($"Verify cache files elapsed time {costTime:f1} seconds");
} }

View File

@@ -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)

View File

@@ -83,31 +83,32 @@ namespace YooAsset
var operation = new DEFSInitializeOperation(this); var operation = new DEFSInitializeOperation(this);
return operation; return operation;
} }
public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(RequestPackageVersionOptions options)
{
var operation = new DEFSLoadPackageManifestOperation(this, packageVersion);
return operation;
}
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout)
{ {
var operation = new DEFSRequestPackageVersionOperation(this); var operation = new DEFSRequestPackageVersionOperation(this);
return operation; return operation;
} }
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options) public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(LoadPackageManifestOptions options)
{
var operation = new DEFSLoadPackageManifestOperation(this, options.PackageVersion);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(ClearCacheFilesOptions options)
{ {
var operation = new FSClearCacheFilesCompleteOperation(); var operation = new FSClearCacheFilesCompleteOperation();
return operation; return operation;
} }
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options)
{ {
string mainURL = bundle.BundleName; string mainURL = options.Bundle.BundleName;
options.SetURL(mainURL, mainURL); options.SetURL(mainURL, mainURL);
var downloader = new DownloadVirtualBundleOperation(this, bundle, options); var downloader = new DownloadVirtualBundleOperation(this, options);
return downloader; return downloader;
} }
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options)
{ {
if (bundle.BundleType == (int)EBuildBundleType.VirtualBundle) PackageBundle bundle = options.Bundle;
if (bundle.BundleType == (int)EBundleType.VirtualBundle)
{ {
var operation = new DEFSLoadBundleOperation(this, bundle); var operation = new DEFSLoadBundleOperation(this, bundle);
return operation; return operation;

View File

@@ -64,8 +64,8 @@ namespace YooAsset
{ {
if (_downloadFileOp == null) if (_downloadFileOp == null)
{ {
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue); DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, options); _downloadFileOp = _fileSystem.DownloadFileAsync(options);
_downloadFileOp.StartOperation(); _downloadFileOp.StartOperation();
AddChildOperation(_downloadFileOp); AddChildOperation(_downloadFileOp);
} }
@@ -142,14 +142,7 @@ namespace YooAsset
} }
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
while (true) RunBatchExecution();
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
} }
} }
} }

View File

@@ -25,7 +25,7 @@ namespace YooAsset
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
internal DownloadVirtualBundleOperation(DefaultEditorFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle) internal DownloadVirtualBundleOperation(DefaultEditorFileSystem fileSystem, DownloadFileOptions options) : base(options.Bundle)
{ {
_fileSystem = fileSystem; _fileSystem = fileSystem;
_options = options; _options = options;

View File

@@ -59,7 +59,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData) if (_steps == ESteps.VerifyFileData)
{ {
if (ManifestTools.VerifyManifestData(_fileData, _packageHash)) if (PackageManifestTools.VerifyManifestData(_fileData, _packageHash))
{ {
_steps = ESteps.LoadManifest; _steps = ESteps.LoadManifest;
} }

View File

@@ -61,12 +61,12 @@ namespace YooAsset
/// <summary> /// <summary>
/// 自定义参数:解密服务接口的实例类 /// 自定义参数:解密服务接口的实例类
/// </summary> /// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; } public IWebBundleDecryptionServices BundleDecryptionServices { private set; get; }
/// <summary> /// <summary>
/// 自定义参数:资源清单服务类 /// 自定义参数:资源清单服务类
/// </summary> /// </summary>
public IManifestRestoreServices ManifestServices { private set; get; } public IManifestRestoreServices ManifestRestoreServices { private set; get; }
#endregion #endregion
@@ -78,28 +78,29 @@ namespace YooAsset
var operation = new DWRFSInitializeOperation(this); var operation = new DWRFSInitializeOperation(this);
return operation; return operation;
} }
public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(RequestPackageVersionOptions options)
{ {
var operation = new DWRFSLoadPackageManifestOperation(this, packageVersion, timeout); var operation = new DWRFSRequestPackageVersionOperation(this, options.AppendTimeTicks, options.Timeout);
return operation; return operation;
} }
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout) public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(LoadPackageManifestOptions options)
{ {
var operation = new DWRFSRequestPackageVersionOperation(this, appendTimeTicks, timeout); var operation = new DWRFSLoadPackageManifestOperation(this, options.PackageVersion, options.Timeout);
return operation; return operation;
} }
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options) public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(ClearCacheFilesOptions options)
{ {
var operation = new FSClearCacheFilesCompleteOperation(); var operation = new FSClearCacheFilesCompleteOperation();
return operation; return operation;
} }
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options)
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options)
{ {
if (bundle.BundleType == (int)EBuildBundleType.AssetBundle) PackageBundle bundle = options.Bundle;
if (bundle.BundleType == (int)EBundleType.AssetBundle)
{ {
var operation = new DWRFSLoadAssetBundleOperation(this, bundle); var operation = new DWRFSLoadAssetBundleOperation(this, bundle);
return operation; return operation;
@@ -130,13 +131,13 @@ namespace YooAsset
{ {
RemoteServices = (IRemoteServices)value; RemoteServices = (IRemoteServices)value;
} }
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES) else if (name == FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES)
{ {
DecryptionServices = (IWebDecryptionServices)value; BundleDecryptionServices = (IWebBundleDecryptionServices)value;
} }
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES) else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES)
{ {
ManifestServices = (IManifestRestoreServices)value; ManifestRestoreServices = (IManifestRestoreServices)value;
} }
else else
{ {

View File

@@ -36,18 +36,18 @@ namespace YooAsset
{ {
string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName); string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue); DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue);
options.SetURL(mainURL, fallbackURL); options.SetURL(mainURL, fallbackURL);
if (_bundle.Encrypted) if (_bundle.Encrypted)
{ {
_loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(_bundle, options, _fileSystem.DecryptionServices, _fileSystem.DownloadBackend); _loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(options, _fileSystem.BundleDecryptionServices, _fileSystem.DownloadBackend);
_loadWebAssetBundleOp.StartOperation(); _loadWebAssetBundleOp.StartOperation();
AddChildOperation(_loadWebAssetBundleOp); AddChildOperation(_loadWebAssetBundleOp);
} }
else else
{ {
_loadWebAssetBundleOp = new LoadWebNormalAssetBundleOperation(_bundle, options, _fileSystem.DisableUnityWebCache, _fileSystem.DownloadBackend); _loadWebAssetBundleOp = new LoadWebNormalAssetBundleOperation(options, _fileSystem.DisableUnityWebCache, _fileSystem.DownloadBackend);
_loadWebAssetBundleOp.StartOperation(); _loadWebAssetBundleOp.StartOperation();
AddChildOperation(_loadWebAssetBundleOp); AddChildOperation(_loadWebAssetBundleOp);
} }
@@ -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);
} }
} }
} }

View File

@@ -65,7 +65,7 @@ namespace YooAsset
{ {
string packageHash = _requestWebPackageHashOp.PackageHash; string packageHash = _requestWebPackageHashOp.PackageHash;
string packageName = _fileSystem.PackageName; string packageName = _fileSystem.PackageName;
var manifestServices = _fileSystem.ManifestServices; var manifestServices = _fileSystem.ManifestRestoreServices;
var remoteServices = _fileSystem.RemoteServices; var remoteServices = _fileSystem.RemoteServices;
var downloadBackend = _fileSystem.DownloadBackend; var downloadBackend = _fileSystem.DownloadBackend;
_loadWebPackageManifestOp = new LoadWebPackageManifestOperation(manifestServices, remoteServices, downloadBackend, packageName, _packageVersion, packageHash, _timeout); _loadWebPackageManifestOp = new LoadWebPackageManifestOperation(manifestServices, remoteServices, downloadBackend, packageName, _packageVersion, packageHash, _timeout);

View File

@@ -70,12 +70,12 @@ namespace YooAsset
/// <summary> /// <summary>
/// 自定义参数:解密服务接口的实例类 /// 自定义参数:解密服务接口的实例类
/// </summary> /// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; } public IWebBundleDecryptionServices BundleDecryptionServices { private set; get; }
/// <summary> /// <summary>
/// 自定义参数:资源清单服务类 /// 自定义参数:资源清单服务类
/// </summary> /// </summary>
public IManifestRestoreServices ManifestServices { private set; get; } public IManifestRestoreServices ManifestRestoreServices { private set; get; }
#endregion #endregion
@@ -87,28 +87,29 @@ namespace YooAsset
var operation = new DWSFSInitializeOperation(this); var operation = new DWSFSInitializeOperation(this);
return operation; return operation;
} }
public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(RequestPackageVersionOptions options)
{ {
var operation = new DWSFSLoadPackageManifestOperation(this, packageVersion, timeout); var operation = new DWSFSRequestPackageVersionOperation(this, options.Timeout);
return operation; return operation;
} }
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout) public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(LoadPackageManifestOptions options)
{ {
var operation = new DWSFSRequestPackageVersionOperation(this, timeout); var operation = new DWSFSLoadPackageManifestOperation(this, options.PackageVersion, options.Timeout);
return operation; return operation;
} }
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options) public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(ClearCacheFilesOptions options)
{ {
var operation = new FSClearCacheFilesCompleteOperation(); var operation = new FSClearCacheFilesCompleteOperation();
return operation; return operation;
} }
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options)
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options)
{ {
if (bundle.BundleType == (int)EBuildBundleType.AssetBundle) PackageBundle bundle = options.Bundle;
if (bundle.BundleType == (int)EBundleType.AssetBundle)
{ {
var operation = new DWSFSLoadAssetBundleOperation(this, bundle); var operation = new DWSFSLoadAssetBundleOperation(this, bundle);
return operation; return operation;
@@ -135,13 +136,13 @@ namespace YooAsset
{ {
DisableUnityWebCache = Convert.ToBoolean(value); DisableUnityWebCache = Convert.ToBoolean(value);
} }
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES) else if (name == FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES)
{ {
DecryptionServices = (IWebDecryptionServices)value; BundleDecryptionServices = (IWebBundleDecryptionServices)value;
} }
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES) else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES)
{ {
ManifestServices = (IManifestRestoreServices)value; ManifestRestoreServices = (IManifestRestoreServices)value;
} }
else else
{ {

View File

@@ -36,18 +36,18 @@ namespace YooAsset
{ {
string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle); string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle);
string mainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath); string mainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath);
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue); DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue);
options.SetURL(mainURL, mainURL); options.SetURL(mainURL, mainURL);
if (_bundle.Encrypted) if (_bundle.Encrypted)
{ {
_loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(_bundle, options, _fileSystem.DecryptionServices, _fileSystem.DownloadBackend); _loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(options, _fileSystem.BundleDecryptionServices, _fileSystem.DownloadBackend);
_loadWebAssetBundleOp.StartOperation(); _loadWebAssetBundleOp.StartOperation();
AddChildOperation(_loadWebAssetBundleOp); AddChildOperation(_loadWebAssetBundleOp);
} }
else else
{ {
_loadWebAssetBundleOp = new LoadWebNormalAssetBundleOperation(_bundle, options, _fileSystem.DisableUnityWebCache, _fileSystem.DownloadBackend); _loadWebAssetBundleOp = new LoadWebNormalAssetBundleOperation(options, _fileSystem.DisableUnityWebCache, _fileSystem.DownloadBackend);
_loadWebAssetBundleOp.StartOperation(); _loadWebAssetBundleOp.StartOperation();
AddChildOperation(_loadWebAssetBundleOp); AddChildOperation(_loadWebAssetBundleOp);
} }
@@ -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);
} }
} }
} }

View File

@@ -61,7 +61,7 @@ namespace YooAsset
{ {
try try
{ {
var catalog = CatalogTools.DeserializeFromBinary(_webDataRequestOp.Result); var catalog = CatalogFileHelper.DeserializeFromBinary(_webDataRequestOp.Result);
if (catalog.PackageName != _fileSystem.PackageName) if (catalog.PackageName != _fileSystem.PackageName)
{ {
_steps = ESteps.Done; _steps = ESteps.Done;

View File

@@ -70,7 +70,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData) if (_steps == ESteps.VerifyFileData)
{ {
if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash)) if (PackageManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
{ {
_steps = ESteps.LoadManifest; _steps = ESteps.LoadManifest;
} }
@@ -86,7 +86,7 @@ namespace YooAsset
{ {
if (_deserializer == null) if (_deserializer == null)
{ {
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _webDataRequestOp.Result); _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestRestoreServices, _webDataRequestOp.Result);
_deserializer.StartOperation(); _deserializer.StartOperation();
AddChildOperation(_deserializer); AddChildOperation(_deserializer);
} }

View File

@@ -83,11 +83,11 @@ namespace YooAsset
/// </summary> /// </summary>
/// <param name="decryptionServices">加密文件解密服务类</param> /// <param name="decryptionServices">加密文件解密服务类</param>
/// <param name="packageRoot">文件系统的根目录</param> /// <param name="packageRoot">文件系统的根目录</param>
public static FileSystemParameters CreateDefaultBuildinFileSystemParameters(IDecryptionServices decryptionServices = null, string packageRoot = null) public static FileSystemParameters CreateDefaultBuildinFileSystemParameters(IBundleDecryptionServices decryptionServices = null, string packageRoot = null)
{ {
string fileSystemClass = typeof(DefaultBuildinFileSystem).FullName; string fileSystemClass = typeof(DefaultBuildinFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot); var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices); fileSystemParams.AddParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, decryptionServices);
return fileSystemParams; return fileSystemParams;
} }
@@ -97,12 +97,12 @@ namespace YooAsset
/// <param name="remoteServices">远端资源地址查询服务类</param> /// <param name="remoteServices">远端资源地址查询服务类</param>
/// <param name="decryptionServices">加密文件解密服务类</param> /// <param name="decryptionServices">加密文件解密服务类</param>
/// <param name="packageRoot">文件系统的根目录</param> /// <param name="packageRoot">文件系统的根目录</param>
public static FileSystemParameters CreateDefaultCacheFileSystemParameters(IRemoteServices remoteServices, IDecryptionServices decryptionServices = null, string packageRoot = null) public static FileSystemParameters CreateDefaultCacheFileSystemParameters(IRemoteServices remoteServices, IBundleDecryptionServices decryptionServices = null, string packageRoot = null)
{ {
string fileSystemClass = typeof(DefaultCacheFileSystem).FullName; string fileSystemClass = typeof(DefaultCacheFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot); var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices); fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices); fileSystemParams.AddParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, decryptionServices);
return fileSystemParams; return fileSystemParams;
} }
@@ -111,11 +111,11 @@ namespace YooAsset
/// </summary> /// </summary>
/// <param name="decryptionServices">加密文件解密服务类</param> /// <param name="decryptionServices">加密文件解密服务类</param>
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</param> /// <param name="disableUnityWebCache">禁用Unity的网络缓存</param>
public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(IWebDecryptionServices decryptionServices = null, bool disableUnityWebCache = false) public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(IWebBundleDecryptionServices decryptionServices = null, bool disableUnityWebCache = false)
{ {
string fileSystemClass = typeof(DefaultWebServerFileSystem).FullName; string fileSystemClass = typeof(DefaultWebServerFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, null); var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices); fileSystemParams.AddParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, decryptionServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache); fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache);
return fileSystemParams; return fileSystemParams;
} }
@@ -126,12 +126,12 @@ namespace YooAsset
/// <param name="remoteServices">远端资源地址查询服务类</param> /// <param name="remoteServices">远端资源地址查询服务类</param>
/// <param name="decryptionServices">加密文件解密服务类</param> /// <param name="decryptionServices">加密文件解密服务类</param>
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</param> /// <param name="disableUnityWebCache">禁用Unity的网络缓存</param>
public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteServices remoteServices, IWebDecryptionServices decryptionServices = null, bool disableUnityWebCache = false) public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteServices remoteServices, IWebBundleDecryptionServices decryptionServices = null, bool disableUnityWebCache = false)
{ {
string fileSystemClass = typeof(DefaultWebRemoteFileSystem).FullName; string fileSystemClass = typeof(DefaultWebRemoteFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, null); var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices); fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices); fileSystemParams.AddParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, decryptionServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache); fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache);
return fileSystemParams; return fileSystemParams;
} }

View File

@@ -7,102 +7,127 @@ namespace YooAsset
/// 初始化的时候缓存文件校验级别 <see cref=EFileVerifyLevel> /// 初始化的时候缓存文件校验级别 <see cref=EFileVerifyLevel>
/// </summary> /// </summary>
public const string FILE_VERIFY_LEVEL = "FILE_VERIFY_LEVEL"; public const string FILE_VERIFY_LEVEL = "FILE_VERIFY_LEVEL";
/// <summary> /// <summary>
/// 初始化的时候缓存文件校验最大并发数 <see cref=int> /// 初始化的时候缓存文件校验最大并发数 <see cref=int>
/// </summary> /// </summary>
public const string FILE_VERIFY_MAX_CONCURRENCY = "FILE_VERIFY_MAX_CONCURRENCY"; public const string FILE_VERIFY_MAX_CONCURRENCY = "FILE_VERIFY_MAX_CONCURRENCY";
/// <summary> /// <summary>
/// 覆盖安装缓存清理模式 <see cref=EOverwriteInstallClearMode> /// 覆盖安装缓存清理模式 <see cref=EOverwriteInstallClearMode>
/// </summary> /// </summary>
public const string INSTALL_CLEAR_MODE = "INSTALL_CLEAR_MODE"; public const string INSTALL_CLEAR_MODE = "INSTALL_CLEAR_MODE";
/// <summary> /// <summary>
/// 远端资源地址查询服务类 <see cref=IRemoteServices> /// 远端资源地址查询服务类 <see cref=IRemoteServices>
/// </summary> /// </summary>
public const string REMOTE_SERVICES = "REMOTE_SERVICES"; public const string REMOTE_SERVICES = "REMOTE_SERVICES";
/// <summary> /// <summary>
/// 解密服务接口的实例类 <see cref=IDecryptionServices> /// 解密服务接口的实例类 <see cref=IBundleDecryptionServices>
/// </summary> /// </summary>
public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES"; public const string BUNDLE_DECRYPTION_SERVICES = "BUNDLE_DECRYPTION_SERVICES";
/// <summary> /// <summary>
/// 资源清单服务类 <see cref=IManifestRestoreServices> /// 资源清单服务类 <see cref=IManifestRestoreServices>
/// </summary> /// </summary>
public const string MANIFEST_SERVICES = "MANIFEST_SERVICES"; public const string MANIFEST_RESTORE_SERVICES = "MANIFEST_RESTORE_SERVICES";
/// <summary> /// <summary>
/// 数据文件追加文件格式 <see cref=bool> /// 数据文件追加文件格式 <see cref=bool>
/// </summary> /// </summary>
public const string APPEND_FILE_EXTENSION = "APPEND_FILE_EXTENSION"; public const string APPEND_FILE_EXTENSION = "APPEND_FILE_EXTENSION";
/// <summary> /// <summary>
/// 禁用Catalog目录查询文件 <see cref=bool> /// 禁用Catalog目录查询文件 <see cref=bool>
/// </summary> /// </summary>
public const string DISABLE_CATALOG_FILE = "DISABLE_CATALOG_FILE"; public const string DISABLE_CATALOG_FILE = "DISABLE_CATALOG_FILE";
/// <summary> /// <summary>
/// 禁用Unity的网络缓存 <see cref=bool> /// 禁用Unity的网络缓存 <see cref=bool>
/// </summary> /// </summary>
public const string DISABLE_UNITY_WEB_CACHE = "DISABLE_UNITY_WEB_CACHE"; public const string DISABLE_UNITY_WEB_CACHE = "DISABLE_UNITY_WEB_CACHE";
/// <summary> /// <summary>
/// 禁用边玩边下机制 <see cref=bool> /// 禁用边玩边下机制 <see cref=bool>
/// </summary> /// </summary>
public const string DISABLE_ONDEMAND_DOWNLOAD = "DISABLE_ONDEMAND_DOWNLOAD"; public const string DISABLE_ONDEMAND_DOWNLOAD = "DISABLE_ONDEMAND_DOWNLOAD";
/// <summary> /// <summary>
/// UnityWebRequest 创建委托 <see cref=UnityWebRequestCreator> /// UnityWebRequest 创建委托 <see cref=UnityWebRequestCreator>
/// </summary> /// </summary>
public const string UNITY_WEB_REQUEST_CREATOR = "UNITY_WEB_REQUEST_CREATOR"; public const string UNITY_WEB_REQUEST_CREATOR = "UNITY_WEB_REQUEST_CREATOR";
/// <summary> /// <summary>
/// 下载后台接口 <see cref=IDownloadBackend> /// 下载后台接口 <see cref=IDownloadBackend>
/// </summary> /// </summary>
public const string DOWNLOAD_BACKEND = "DOWNLOAD_BACKEND"; public const string DOWNLOAD_BACKEND = "DOWNLOAD_BACKEND";
/// <summary> /// <summary>
/// 最大并发连接数 默认值10推荐范围 1-32 <see cref=int> /// 最大并发连接数 默认值10推荐范围 1-32 <see cref=int>
/// </summary> /// </summary>
public const string DOWNLOAD_MAX_CONCURRENCY = "DOWNLOAD_MAX_CONCURRENCY"; public const string DOWNLOAD_MAX_CONCURRENCY = "DOWNLOAD_MAX_CONCURRENCY";
/// <summary> /// <summary>
/// 每帧发起的最大请求数 默认值5推荐范围 1-10<see cref=int> /// 每帧发起的最大请求数 默认值5推荐范围 1-10<see cref=int>
/// </summary> /// </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> /// <summary>
/// 下载任务的看门狗机制监控时间 <see cref=int> /// 下载任务的看门狗机制监控时间 <see cref=int>
/// </summary> /// </summary>
public const string DOWNLOAD_WATCH_DOG_TIME = "DOWNLOAD_WATCH_DOG_TIME"; public const string DOWNLOAD_WATCH_DOG_TIME = "DOWNLOAD_WATCH_DOG_TIME";
/// <summary> /// <summary>
/// 启用断点续传的最小尺寸 <see cref=long> /// 启用断点续传的最小尺寸 <see cref=long>
/// </summary> /// </summary>
public const string RESUME_DOWNLOAD_MINMUM_SIZE = "RESUME_DOWNLOAD_MINMUM_SIZE"; public const string RESUME_DOWNLOAD_MINMUM_SIZE = "RESUME_DOWNLOAD_MINMUM_SIZE";
/// <summary> /// <summary>
/// 断点续传下载器关注的错误码 <see cref=List<long>> /// 断点续传下载器关注的错误码 <see cref=List<long>>
/// </summary> /// </summary>
public const string RESUME_DOWNLOAD_RESPONSE_CODES = "RESUME_DOWNLOAD_RESPONSE_CODES"; public const string RESUME_DOWNLOAD_RESPONSE_CODES = "RESUME_DOWNLOAD_RESPONSE_CODES";
/// <summary> /// <summary>
/// 模拟WebGL平台模式 <see cref=bool> /// 模拟WebGL平台模式 <see cref=bool>
/// </summary> /// </summary>
public const string VIRTUAL_WEBGL_MODE = "VIRTUAL_WEBGL_MODE"; public const string VIRTUAL_WEBGL_MODE = "VIRTUAL_WEBGL_MODE";
/// <summary> /// <summary>
/// 模拟虚拟下载模式 <see cref=bool> /// 模拟虚拟下载模式 <see cref=bool>
/// </summary> /// </summary>
public const string VIRTUAL_DOWNLOAD_MODE = "VIRTUAL_DOWNLOAD_MODE"; public const string VIRTUAL_DOWNLOAD_MODE = "VIRTUAL_DOWNLOAD_MODE";
/// <summary> /// <summary>
/// 模拟虚拟下载的网速(单位:字节) <see cref=int> /// 模拟虚拟下载的网速(单位:字节) <see cref=int>
/// </summary> /// </summary>
public const string VIRTUAL_DOWNLOAD_SPEED = "VIRTUAL_DOWNLOAD_SPEED"; public const string VIRTUAL_DOWNLOAD_SPEED = "VIRTUAL_DOWNLOAD_SPEED";
/// <summary> /// <summary>
/// 异步模拟加载最小帧数 <see cref=int> /// 异步模拟加载最小帧数 <see cref=int>
/// </summary> /// </summary>
public const string ASYNC_SIMULATE_MIN_FRAME = "ASYNC_SIMULATE_MIN_FRAME"; public const string ASYNC_SIMULATE_MIN_FRAME = "ASYNC_SIMULATE_MIN_FRAME";
/// <summary> /// <summary>
/// 异步模拟加载最大帧数 <see cref=int> /// 异步模拟加载最大帧数 <see cref=int>
/// </summary> /// </summary>
public const string ASYNC_SIMULATE_MAX_FRAME = "ASYNC_SIMULATE_MAX_FRAME"; public const string ASYNC_SIMULATE_MAX_FRAME = "ASYNC_SIMULATE_MAX_FRAME";
/// <summary> /// <summary>
/// 拷贝内置清单 <see cref=bool> /// 拷贝内置清单 <see cref=bool>
/// </summary> /// </summary>
public const string COPY_BUILDIN_PACKAGE_MANIFEST = "COPY_BUILDIN_PACKAGE_MANIFEST"; public const string COPY_BUILDIN_PACKAGE_MANIFEST = "COPY_BUILDIN_PACKAGE_MANIFEST";
/// <summary> /// <summary>
/// 拷贝内置清单的目标目录 <see cref=string> /// 拷贝内置清单的目标目录 <see cref=string>
/// </summary> /// </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> /// <summary>
/// 拷贝内置文件接口的实例类 <see cref=ICopyLocalFileServices> /// 拷贝内置文件接口的实例类 <see cref=ICopyLocalFileServices>
/// </summary> /// </summary>
public const string COPY_LOCAL_FILE_SERVICES = "COPY_LOCAL_FILE_SERVICES"; public const string COPY_LOCAL_FILE_SERVICES = "COPY_LOCAL_FILE_SERVICES";
/// <summary> /// <summary>
/// 解压文件系统的根目录 <see cref=string> /// 解压文件系统的根目录 <see cref=string>
/// </summary> /// </summary>

View File

@@ -24,30 +24,30 @@ namespace YooAsset
/// </summary> /// </summary>
FSInitializeFileSystemOperation InitializeFileSystemAsync(); FSInitializeFileSystemOperation InitializeFileSystemAsync();
/// <summary>
/// 加载包裹清单
/// </summary>
FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout);
/// <summary> /// <summary>
/// 查询包裹版本 /// 查询包裹版本
/// </summary> /// </summary>
FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout); FSRequestPackageVersionOperation RequestPackageVersionAsync(RequestPackageVersionOptions options);
/// <summary>
/// 加载包裹清单
/// </summary>
FSLoadPackageManifestOperation LoadPackageManifestAsync(LoadPackageManifestOptions options);
/// <summary> /// <summary>
/// 清理缓存文件 /// 清理缓存文件
/// </summary> /// </summary>
FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options); FSClearCacheFilesOperation ClearCacheFilesAsync(ClearCacheFilesOptions options);
/// <summary> /// <summary>
/// 下载Bundle文件 /// 下载Bundle文件
/// </summary> /// </summary>
FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options); FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options);
/// <summary> /// <summary>
/// 加载Bundle文件 /// 加载Bundle文件
/// </summary> /// </summary>
FSLoadBundleOperation LoadBundleFile(PackageBundle bundle); FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options);
/// <summary> /// <summary>

View File

@@ -1,19 +1,6 @@
 
namespace YooAsset namespace YooAsset
{ {
internal class ClearCacheFilesOptions
{
/// <summary>
/// 清理模式
/// </summary>
public string ClearMode;
/// <summary>
/// 附加参数
/// </summary>
public object ClearParam;
}
internal abstract class FSClearCacheFilesOperation : AsyncOperationBase internal abstract class FSClearCacheFilesOperation : AsyncOperationBase
{ {
} }

View File

@@ -1,54 +1,6 @@
 
namespace YooAsset namespace YooAsset
{ {
internal class DownloadFileOptions
{
/// <summary>
/// 失败后重试次数
/// </summary>
public readonly int FailedTryAgain;
/// <summary>
/// 主资源地址
/// </summary>
public string MainURL { private set; get; }
/// <summary>
/// 备用资源地址
/// </summary>
public string FallbackURL { private set; get; }
/// <summary>
/// 拷贝的本地文件路径
/// </summary>
public string ImportFilePath { set; get; }
public DownloadFileOptions(int failedTryAgain)
{
FailedTryAgain = failedTryAgain;
}
/// <summary>
/// 设置下载地址
/// </summary>
public void SetURL(string mainURL, string fallbackURL)
{
MainURL = mainURL;
FallbackURL = fallbackURL;
}
/// <summary>
/// 是否有效
/// </summary>
public bool IsValid()
{
if (string.IsNullOrEmpty(MainURL) || string.IsNullOrEmpty(FallbackURL))
return false;
return true;
}
}
internal abstract class FSDownloadFileOperation : AsyncOperationBase internal abstract class FSDownloadFileOperation : AsyncOperationBase
{ {
public PackageBundle Bundle { private set; get; } public PackageBundle Bundle { private set; get; }

View File

@@ -0,0 +1,60 @@

namespace YooAsset
{
internal struct DownloadFileOptions
{
/// <summary>
/// 资源包
/// </summary>
public readonly PackageBundle Bundle;
/// <summary>
/// 失败后重试次数
/// </summary>
public readonly int FailedTryAgain;
/// <summary>
/// 主资源地址
/// </summary>
public string MainURL { private set; get; }
/// <summary>
/// 备用资源地址
/// </summary>
public string FallbackURL { private set; get; }
/// <summary>
/// 拷贝的本地文件路径
/// </summary>
public string ImportFilePath { set; get; }
public DownloadFileOptions(PackageBundle bundle, int failedTryAgain)
{
Bundle = bundle;
FailedTryAgain = failedTryAgain;
MainURL = null;
FallbackURL = null;
ImportFilePath = null;
}
/// <summary>
/// 设置下载地址
/// </summary>
public void SetURL(string mainURL, string fallbackURL)
{
MainURL = mainURL;
FallbackURL = fallbackURL;
}
/// <summary>
/// 是否有效
/// </summary>
public bool IsValid()
{
if (string.IsNullOrEmpty(MainURL) || string.IsNullOrEmpty(FallbackURL))
return false;
return true;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: ff8a96dd005f55346986f8a98aff8c99 guid: ae6a979ad693ddf488c7a0f387c6ea76
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@@ -0,0 +1,16 @@

namespace YooAsset
{
internal struct LoadBundleOptions
{
/// <summary>
/// 资源包
/// </summary>
public readonly PackageBundle Bundle;
public LoadBundleOptions(PackageBundle bundle)
{
Bundle = bundle;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 9143514bc9d4f3e4aa9a50a7cfb08d21 guid: 3d4cf0ce3cf4c794fa2d40665d5f3147
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@@ -13,9 +13,8 @@ namespace YooAsset
Done, Done,
} }
private readonly PackageBundle _bundle;
private readonly DownloadFileOptions _options; private readonly DownloadFileOptions _options;
private readonly IWebDecryptionServices _decryptionServices; private readonly IWebBundleDecryptionServices _decryptionServices;
private readonly IDownloadBackend _downloadBackend; private readonly IDownloadBackend _downloadBackend;
private IDownloadBytesRequest _unityWebDataRequestOp; private IDownloadBytesRequest _unityWebDataRequestOp;
@@ -24,9 +23,8 @@ namespace YooAsset
private int _failedTryAgain; private int _failedTryAgain;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
internal LoadWebEncryptAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options, IWebDecryptionServices decryptionServices, IDownloadBackend downloadBackend) internal LoadWebEncryptAssetBundleOperation(DownloadFileOptions options, IWebBundleDecryptionServices decryptionServices, IDownloadBackend downloadBackend)
{ {
_bundle = bundle;
_options = options; _options = options;
_failedTryAgain = options.FailedTryAgain; _failedTryAgain = options.FailedTryAgain;
_decryptionServices = decryptionServices; _decryptionServices = decryptionServices;
@@ -48,7 +46,7 @@ namespace YooAsset
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Failed; Status = EOperationStatus.Failed;
Error = $"The {nameof(IWebDecryptionServices)} is null !"; Error = $"The {nameof(IWebBundleDecryptionServices)} is null !";
YooLogger.Error(Error); YooLogger.Error(Error);
return; return;
} }
@@ -124,11 +122,11 @@ namespace YooAsset
/// </summary> /// </summary>
private AssetBundle LoadEncryptedAssetBundle(byte[] fileData) private AssetBundle LoadEncryptedAssetBundle(byte[] fileData)
{ {
var fileInfo = new WebDecryptFileInfo(); var fileInfo = new WebDecryptBundleInfo();
fileInfo.BundleName = _bundle.BundleName; fileInfo.BundleName = _options.Bundle.BundleName;
fileInfo.FileLoadCRC = _bundle.UnityCRC; fileInfo.FileLoadCRC = _options.Bundle.UnityCRC;
fileInfo.FileData = fileData; fileInfo.FileData = fileData;
var decryptResult = _decryptionServices.LoadAssetBundle(fileInfo); var decryptResult = _decryptionServices.LoadAssetBundleSync(fileInfo);
return decryptResult.Result; return decryptResult.Result;
} }

View File

@@ -13,7 +13,6 @@ namespace YooAsset
Done, Done,
} }
private readonly PackageBundle _bundle;
private readonly DownloadFileOptions _options; private readonly DownloadFileOptions _options;
private readonly bool _disableUnityWebCache; private readonly bool _disableUnityWebCache;
private readonly IDownloadBackend _downloadBackend; private readonly IDownloadBackend _downloadBackend;
@@ -25,9 +24,8 @@ namespace YooAsset
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
internal LoadWebNormalAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options, bool disableUnityWebCache, IDownloadBackend downloadBackend) internal LoadWebNormalAssetBundleOperation(DownloadFileOptions options, bool disableUnityWebCache, IDownloadBackend downloadBackend)
{ {
_bundle = bundle;
_options = options; _options = options;
_failedTryAgain = options.FailedTryAgain; _failedTryAgain = options.FailedTryAgain;
_disableUnityWebCache = disableUnityWebCache; _disableUnityWebCache = disableUnityWebCache;
@@ -46,7 +44,7 @@ namespace YooAsset
if (_steps == ESteps.CreateRequest) if (_steps == ESteps.CreateRequest)
{ {
string url = GetRequestURL(); string url = GetRequestURL();
var args = new DownloadAssetBundleRequestArgs(url, 0, 0, _disableUnityWebCache, _bundle.FileHash, _bundle.UnityCRC); var args = new DownloadAssetBundleRequestArgs(url, 0, 0, _disableUnityWebCache, _options.Bundle.FileHash, _options.Bundle.UnityCRC);
_unityAssetBundleRequestOp = _downloadBackend.CreateAssetBundleRequest(args); _unityAssetBundleRequestOp = _downloadBackend.CreateAssetBundleRequest(args);
_unityAssetBundleRequestOp.SendRequest(); _unityAssetBundleRequestOp.SendRequest();
_steps = ESteps.CheckRequest; _steps = ESteps.CheckRequest;

View File

@@ -80,7 +80,7 @@ internal class LoadWebPackageManifestOperation : AsyncOperationBase
if (_steps == ESteps.VerifyFileData) if (_steps == ESteps.VerifyFileData)
{ {
if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash)) if (PackageManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
{ {
_steps = ESteps.LoadManifest; _steps = ESteps.LoadManifest;
} }

View File

@@ -10,7 +10,7 @@ namespace YooAsset
{ {
private List<AsyncOperationBase> _childs; private List<AsyncOperationBase> _childs;
private Action<AsyncOperationBase> _callback; private Action<AsyncOperationBase> _callback;
private int _whileFrame = 1000; private uint _priority = 0;
/// <summary> /// <summary>
/// 等待异步执行完成 /// 等待异步执行完成
@@ -35,10 +35,28 @@ namespace YooAsset
} }
} }
/// <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>
/// 任务状态 /// 任务状态
@@ -122,7 +140,7 @@ 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()
{ {
@@ -137,9 +155,19 @@ namespace YooAsset
if (_childs == null) if (_childs == null)
_childs = new List<AsyncOperationBase>(10); _childs = new List<AsyncOperationBase>(10);
#if UNITY_EDITOR #if UNITY_EDITOR || DEBUG
if (child == null)
throw new YooInternalException("The child node is null !");
if (ReferenceEquals(child, this))
throw new YooInternalException("The child node cannot be itself !");
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 !");
// 禁止形成环依赖
if (WouldCreateCycle(child))
throw new YooInternalException($"AddChildOperation would create a cycle : {this.GetType().Name} -> {child.GetType().Name}");
#endif #endif
_childs.Add(child); _childs.Add(child);
@@ -153,7 +181,10 @@ namespace YooAsset
if (_childs == null) if (_childs == null)
return; return;
#if UNITY_EDITOR #if UNITY_EDITOR || DEBUG
if (child == null)
throw new YooInternalException("The child node is null !");
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
@@ -182,7 +213,16 @@ namespace YooAsset
DebugBeginRecording(); DebugBeginRecording();
// 开始任务 // 开始任务
InternalStart(); try
{
InternalStart();
}
catch (Exception ex)
{
Status = EOperationStatus.Failed;
Error = ex.ToString();
YooLogger.Error($"Exception in {this.GetType().Name}.InternalStart : {ex}");
}
} }
} }
@@ -197,7 +237,18 @@ namespace YooAsset
DebugUpdateRecording(); DebugUpdateRecording();
// 更新任务 // 更新任务
InternalUpdate(); // 注意:兜底隔离机制
// 说明检测的异常源包含I/O解压/读写权限/磁盘满),平台差异等
try
{
InternalUpdate();
}
catch (Exception ex)
{
Status = EOperationStatus.Failed;
Error = ex.ToString();
YooLogger.Error($"Exception in {this.GetType().Name}.InternalUpdate : {ex}");
}
} }
if (IsDone && IsFinish == false) if (IsDone && IsFinish == false)
@@ -226,12 +277,15 @@ namespace YooAsset
Error = "user abort"; Error = "user abort";
YooLogger.Warning($"Async operation {this.GetType().Name} has been aborted !"); YooLogger.Warning($"Async operation {this.GetType().Name} has been aborted !");
} }
//注意强制收尾确保Task能完成
FinishOperation();
} }
/// <summary> /// <summary>
/// 强制结束异步任务 /// 强制结束异步任务
/// </summary> /// </summary>
internal void FinishOperation() private void FinishOperation()
{ {
if (IsFinish == false) if (IsFinish == false)
{ {
@@ -243,6 +297,7 @@ namespace YooAsset
try try
{ {
//TODO 单个回调异常会阻断后续订阅者
_callback?.Invoke(this); _callback?.Invoke(this);
} }
catch (Exception ex) catch (Exception ex)
@@ -259,25 +314,59 @@ namespace YooAsset
} }
/// <summary> /// <summary>
/// 执行While循环 /// 执行一次更新逻辑
/// </summary> /// </summary>
protected bool ExecuteWhileDone() protected void RunOnceExecution()
{ {
if (IsDone == false) if (IsDone)
return;
UpdateOperation();
}
/// <summary>
/// 批量执行一定次数的更新逻辑
/// </summary>
/// <param name="count">次数</param>
protected void RunBatchExecution(int count = 1000)
{
if (IsDone)
return;
int runCount = count;
while (true)
{ {
// 执行更新逻辑 // 执行更新逻辑
InternalUpdate(); UpdateOperation();
if (IsDone)
break;
// 当执行次数用完时 // 当执行次数用完时
_whileFrame--; runCount--;
if (_whileFrame <= 0) if (runCount <= 0)
{ break;
Status = EOperationStatus.Failed; }
Error = $"Operation {this.GetType().Name} failed to wait for async complete !"; }
YooLogger.Error(Error);
} /// <summary>
/// 无限次数的执行更新逻辑,直到任务完成
/// 注意:该方法会阻塞主线程
/// </summary>
/// <param name="sleepMS">休眠时长</param>
protected void RunUntilCompletion(int sleepMS = 1)
{
if (IsDone)
return;
while (true)
{
UpdateOperation();
if (IsDone)
break;
// 注意: 短暂休眠避免完全占用CPU资源
System.Threading.Thread.Sleep(sleepMS);
} }
return IsDone;
} }
/// <summary> /// <summary>
@@ -285,11 +374,7 @@ namespace YooAsset
/// </summary> /// </summary>
public void WaitForAsyncComplete() public void WaitForAsyncComplete()
{ {
if (IsDone)
return;
//TODO 防止异步操作被挂起陷入无限死循环! //TODO 防止异步操作被挂起陷入无限死循环!
// 例如:文件解压任务或者文件导入任务!
if (Status == EOperationStatus.None) if (Status == EOperationStatus.None)
{ {
StartOperation(); StartOperation();
@@ -298,12 +383,19 @@ namespace YooAsset
if (IsWaitForAsyncComplete == false) if (IsWaitForAsyncComplete == false)
{ {
IsWaitForAsyncComplete = true; IsWaitForAsyncComplete = true;
InternalWaitForAsyncComplete();
#if UNITY_EDITOR
if (IsDone == false) if (IsDone == false)
throw new YooInternalException($"WaitForAsyncComplete() must complete operation: {this.GetType().Name}"); InternalWaitForAsyncComplete();
#endif
if (IsDone == false)
{
Status = EOperationStatus.Failed;
Error = $"Operation {this.GetType().Name} failed to wait for async complete !";
YooLogger.Error(Error);
}
//注意强制收尾确保Task能完成
FinishOperation();
} }
} }
@@ -311,7 +403,7 @@ namespace YooAsset
/// <summary> /// <summary>
/// 开始的时间 /// 开始的时间
/// </summary> /// </summary>
public string BeginTime = string.Empty; public string BeginTime { protected set; get; }
/// <summary> /// <summary>
/// 处理耗时(单位:毫秒) /// 处理耗时(单位:毫秒)
@@ -326,7 +418,7 @@ namespace YooAsset
{ {
if (_watch == null) if (_watch == null)
{ {
BeginTime = SpawnTimeToString(UnityEngine.Time.realtimeSinceStartup); BeginTime = SpawnTimeToString(TimeUtility.RealtimeSinceStartup);
_watch = Stopwatch.StartNew(); _watch = Stopwatch.StartNew();
} }
} }
@@ -350,14 +442,51 @@ namespace YooAsset
} }
} }
private string SpawnTimeToString(float spawnTime) private string SpawnTimeToString(double spawnTime)
{ {
float h = UnityEngine.Mathf.FloorToInt(spawnTime / 3600f); double h = System.Math.Floor(spawnTime / 3600);
float m = UnityEngine.Mathf.FloorToInt(spawnTime / 60f - h * 60f); double m = System.Math.Floor(spawnTime / 60 - h * 60);
float s = UnityEngine.Mathf.FloorToInt(spawnTime - m * 60f - h * 3600f); double s = System.Math.Floor(spawnTime - m * 60 - h * 3600);
return h.ToString("00") + ":" + m.ToString("00") + ":" + s.ToString("00"); return h.ToString("00") + ":" + m.ToString("00") + ":" + s.ToString("00");
} }
private bool WouldCreateCycle(AsyncOperationBase child)
{
const int maxVisited = 4096;
var stack = new Stack<AsyncOperationBase>();
var visited = new HashSet<AsyncOperationBase>();
stack.Push(child);
while (stack.Count > 0)
{
var node = stack.Pop();
if (node == null)
continue;
if (visited.Add(node) == false)
continue;
if (visited.Count > maxVisited)
throw new YooInternalException("Child operation graph is too large, cycle check aborted !");
if (ReferenceEquals(node, this))
return true;
if (node._childs == null)
continue;
for (int i = 0; i < node._childs.Count; i++)
{
stack.Push(node._childs[i]);
}
}
return false;
}
/// <summary>
/// 获取调试信息
/// 注意:递归构建子树存在深度风险
/// </summary>
internal DebugOperationInfo GetDebugOperationInfo() internal DebugOperationInfo GetDebugOperationInfo()
{ {
var operationInfo = new DebugOperationInfo(); var operationInfo = new DebugOperationInfo();

View File

@@ -1,25 +0,0 @@

namespace YooAsset
{
public abstract class GameAsyncOperation : AsyncOperationBase
{
internal override void InternalStart()
{
OnStart();
}
internal override void InternalUpdate()
{
OnUpdate();
}
/// <summary>
/// 异步操作开始
/// </summary>
protected abstract void OnStart();
/// <summary>
/// 异步操作更新
/// </summary>
protected abstract void OnUpdate();
}
}

View File

@@ -10,6 +10,7 @@ namespace YooAsset
{ {
private readonly List<AsyncOperationBase> _operations = new List<AsyncOperationBase>(100); private readonly List<AsyncOperationBase> _operations = new List<AsyncOperationBase>(100);
private readonly List<AsyncOperationBase> _newList = new List<AsyncOperationBase>(100); private readonly List<AsyncOperationBase> _newList = new List<AsyncOperationBase>(100);
private uint _priority = 0;
/// <summary> /// <summary>
/// 所属包裹名称 /// 所属包裹名称
@@ -19,7 +20,23 @@ namespace YooAsset
/// <summary> /// <summary>
/// 调度器优先级(值越大越优先) /// 调度器优先级(值越大越优先)
/// </summary> /// </summary>
public int Priority { private set; get; } public uint Priority
{
get { return _priority; }
set
{
if (_priority != value)
{
_priority = value;
IsDirty = true;
}
}
}
/// <summary>
/// 优先级是否已变更(需要重新排序)
/// </summary>
public bool IsDirty { set; get; } = false;
/// <summary> /// <summary>
/// 创建顺序(用于同优先级稳定排序) /// 创建顺序(用于同优先级稳定排序)
@@ -27,10 +44,9 @@ namespace YooAsset
public int CreateIndex { private set; get; } public int CreateIndex { private set; get; }
public OperationScheduler(string packageName, int priority, int createIndex) public OperationScheduler(string packageName, int createIndex)
{ {
PackageName = packageName; PackageName = packageName;
Priority = priority;
CreateIndex = createIndex; CreateIndex = createIndex;
} }
@@ -41,9 +57,6 @@ namespace YooAsset
{ {
_newList.Add(operation); _newList.Add(operation);
operation.StartOperation(); operation.StartOperation();
// 通知开始回调
OperationSystem.InvokeStartCallback(PackageName, operation);
} }
/// <summary> /// <summary>
@@ -58,31 +71,29 @@ namespace YooAsset
if (operation.IsFinish) if (operation.IsFinish)
{ {
_operations.RemoveAt(i); _operations.RemoveAt(i);
// 通知完成回调
OperationSystem.InvokeFinishCallback(PackageName, operation);
} }
} }
// 添加新增的异步操作 // 添加新增的异步操作
if (_newList.Count > 0) if (_newList.Count > 0)
{ {
bool sorting = false;
foreach (var operation in _newList)
{
if (operation.Priority > 0)
{
sorting = true;
break;
}
}
_operations.AddRange(_newList); _operations.AddRange(_newList);
_newList.Clear(); _newList.Clear();
}
// 重新排序优先级 // 检测是否需要执行排序
if (sorting) bool isDirty = false;
_operations.Sort(); foreach (var operation in _operations)
{
if (operation.IsDirty)
{
operation.IsDirty = false;
isDirty = true;
}
}
if (isDirty)
{
_operations.Sort();
} }
// 更新进行中的异步操作 // 更新进行中的异步操作
@@ -109,7 +120,6 @@ namespace YooAsset
foreach (var operation in _newList) foreach (var operation in _newList)
{ {
operation.AbortOperation(); operation.AbortOperation();
operation.FinishOperation(); //注意强制收尾确保Task能完成
} }
_newList.Clear(); _newList.Clear();
@@ -117,7 +127,6 @@ namespace YooAsset
foreach (var operation in _operations) foreach (var operation in _operations)
{ {
operation.AbortOperation(); operation.AbortOperation();
operation.FinishOperation(); //注意强制收尾确保Task能完成
} }
_operations.Clear(); _operations.Clear();
} }

View File

@@ -5,7 +5,7 @@ using System.Diagnostics;
namespace YooAsset namespace YooAsset
{ {
internal class OperationSystem internal static class OperationSystem
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
[UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)] [UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)]
@@ -16,24 +16,36 @@ namespace YooAsset
#endif #endif
// 全局调度器名称 // 全局调度器名称
public const string GLOBAL_SCHEDULER_NAME = ""; public const string GLOBAL_SCHEDULER_NAME = "YOOASSET_GLOBAL_SCHEDULER";
private static readonly Dictionary<string, OperationScheduler> _schedulerDic = new Dictionary<string, OperationScheduler>(100); private static readonly Dictionary<string, OperationScheduler> _schedulerDic = new Dictionary<string, OperationScheduler>(100);
private static readonly List<OperationScheduler> _schedulerList = new List<OperationScheduler>(100); private static readonly List<OperationScheduler> _schedulerList = new List<OperationScheduler>(100);
private static bool _schedulerListDirty = false; private static bool _isInitialize = false;
private static int _createIndex = 0; private static int _createIndex = 0;
private static Action<string, AsyncOperationBase> _startCallback = null;
private static Action<string, AsyncOperationBase> _finishCallback = null;
// 计时器相关 // 计时器相关
private static Stopwatch _watch; private static Stopwatch _watch;
private static long _frameTime; private static long _frameTime;
private static long _maxTimeSlice = long.MaxValue;
/// <summary> /// <summary>
/// 异步操作系统的每帧最大执行预算(毫秒) /// 异步操作系统的每帧最大执行预算(毫秒)
/// </summary> /// </summary>
public static long MaxTimeSlice { set; get; } = long.MaxValue; public static long MaxTimeSlice
{
set
{
if (value < 10)
{
_maxTimeSlice = 10;
YooLogger.Warning($"MaxTimeSlice minimum value is 10 milliseconds.");
}
else
{
_maxTimeSlice = value;
}
}
}
/// <summary> /// <summary>
/// 异步操作系统是否繁忙 /// 异步操作系统是否繁忙
@@ -45,11 +57,11 @@ namespace YooAsset
if (_watch == null) if (_watch == null)
return false; return false;
if (MaxTimeSlice == long.MaxValue) if (_maxTimeSlice == long.MaxValue)
return false; return false;
// 注意 : 单次调用开销约1微秒 // 注意 : 单次调用开销约1微秒
return _watch.ElapsedMilliseconds - _frameTime >= MaxTimeSlice; return _watch.ElapsedMilliseconds - _frameTime >= _maxTimeSlice;
} }
} }
@@ -59,10 +71,14 @@ namespace YooAsset
/// </summary> /// </summary>
public static void Initialize() public static void Initialize()
{ {
_watch = Stopwatch.StartNew(); if (_isInitialize == false)
{
_isInitialize = true;
_watch = Stopwatch.StartNew();
// 创建全局调度器 // 创建全局调度器
CreatePackageScheduler(GLOBAL_SCHEDULER_NAME, 0); CreatePackageScheduler(GLOBAL_SCHEDULER_NAME, uint.MaxValue);
}
} }
/// <summary> /// <summary>
@@ -70,10 +86,21 @@ namespace YooAsset
/// </summary> /// </summary>
public static void Update() public static void Update()
{ {
// 重新排序调度器 if (_isInitialize == false)
if (_schedulerListDirty) return;
// 检测是否需要执行排序
bool isDirty = false;
foreach (var scheduler in _schedulerList)
{
if (scheduler.IsDirty)
{
scheduler.IsDirty = false;
isDirty = true;
}
}
if (isDirty)
{ {
_schedulerListDirty = false;
_schedulerList.Sort(); _schedulerList.Sort();
} }
@@ -95,6 +122,9 @@ namespace YooAsset
/// </summary> /// </summary>
public static void DestroyAll() public static void DestroyAll()
{ {
_isInitialize = false;
YooLogger.Log("Operation system destroy all !");
// 清空所有调度器 // 清空所有调度器
foreach (var scheduler in _schedulerList) foreach (var scheduler in _schedulerList)
{ {
@@ -102,11 +132,8 @@ namespace YooAsset
} }
_schedulerDic.Clear(); _schedulerDic.Clear();
_schedulerList.Clear(); _schedulerList.Clear();
_schedulerListDirty = false;
_createIndex = 0; _createIndex = 0;
_startCallback = null;
_finishCallback = null;
_watch = null; _watch = null;
_frameTime = 0; _frameTime = 0;
MaxTimeSlice = long.MaxValue; MaxTimeSlice = long.MaxValue;
@@ -115,24 +142,29 @@ namespace YooAsset
/// <summary> /// <summary>
/// 创建包裹调度器 /// 创建包裹调度器
/// </summary> /// </summary>
internal static void CreatePackageScheduler(string packageName, int priority) public static OperationScheduler CreatePackageScheduler(string packageName, uint priority)
{ {
DebugCheckInitialize(packageName);
if (_schedulerDic.ContainsKey(packageName)) if (_schedulerDic.ContainsKey(packageName))
{ {
throw new YooInternalException($"Package scheduler already exists: {packageName}"); throw new YooInternalException($"Package scheduler already exists: {packageName}");
} }
var scheduler = new OperationScheduler(packageName, priority, _createIndex++); var scheduler = new OperationScheduler(packageName, _createIndex++);
_schedulerDic.Add(packageName, scheduler); _schedulerDic.Add(packageName, scheduler);
_schedulerList.Add(scheduler); _schedulerList.Add(scheduler);
_schedulerListDirty = true; scheduler.Priority = priority;
return scheduler;
} }
/// <summary> /// <summary>
/// 销毁包裹调度器 /// 销毁包裹调度器
/// </summary> /// </summary>
internal static void DestroyPackageScheduler(string packageName) public static void DestroyPackageScheduler(string packageName)
{ {
DebugCheckInitialize(packageName);
// 不允许销毁默认调度器 // 不允许销毁默认调度器
if (packageName == GLOBAL_SCHEDULER_NAME) if (packageName == GLOBAL_SCHEDULER_NAME)
{ {
@@ -152,6 +184,8 @@ namespace YooAsset
/// </summary> /// </summary>
public static void ClearPackageOperation(string packageName) public static void ClearPackageOperation(string packageName)
{ {
DebugCheckInitialize(packageName);
var scheduler = GetScheduler(packageName); var scheduler = GetScheduler(packageName);
scheduler.ClearAll(); scheduler.ClearAll();
} }
@@ -161,40 +195,32 @@ namespace YooAsset
/// </summary> /// </summary>
public static void StartOperation(string packageName, AsyncOperationBase operation) public static void StartOperation(string packageName, AsyncOperationBase operation)
{ {
DebugCheckInitialize(packageName);
var scheduler = GetScheduler(packageName); var scheduler = GetScheduler(packageName);
scheduler.StartOperation(operation); scheduler.StartOperation(operation);
} }
/// <summary> /// <summary>
/// 监听任务开始 /// 设置调度器优先级
/// </summary> /// </summary>
public static void RegisterStartCallback(Action<string, AsyncOperationBase> callback) public static void SetSchedulerPriority(string packageName, uint priority)
{ {
_startCallback = callback; DebugCheckInitialize(packageName);
var scheduler = GetScheduler(packageName);
scheduler.Priority = priority;
} }
/// <summary> /// <summary>
/// 监听任务结束 /// 获取调度器优先级
/// </summary> /// </summary>
public static void RegisterFinishCallback(Action<string, AsyncOperationBase> callback) public static uint GetSchedulerPriority(string packageName)
{ {
_finishCallback = callback; DebugCheckInitialize(packageName);
}
/// <summary> var scheduler = GetScheduler(packageName);
/// 触发任务开始回调 return scheduler.Priority;
/// </summary>
internal static void InvokeStartCallback(string packageName, AsyncOperationBase operation)
{
_startCallback?.Invoke(packageName, operation);
}
/// <summary>
/// 触发任务完成回调
/// </summary>
internal static void InvokeFinishCallback(string packageName, AsyncOperationBase operation)
{
_finishCallback?.Invoke(packageName, operation);
} }
/// <summary> /// <summary>
@@ -202,32 +228,34 @@ namespace YooAsset
/// </summary> /// </summary>
private static OperationScheduler GetScheduler(string packageName) private static OperationScheduler GetScheduler(string packageName)
{ {
// 空包名路由到默认调度器
if (string.IsNullOrEmpty(packageName))
packageName = GLOBAL_SCHEDULER_NAME;
if (_schedulerDic.TryGetValue(packageName, out var scheduler)) if (_schedulerDic.TryGetValue(packageName, out var scheduler))
{ {
return scheduler; return scheduler;
} }
// 严格模式:非默认包裹必须先创建调度器 // 严格模式:非默认包裹必须先创建调度器
throw new YooInternalException($"Package scheduler not found: {packageName}. Please call YooAssets.CreatePackage() first!"); throw new YooInternalException($"Operation scheduler not found: {packageName}.");
} }
#region #region
internal static List<DebugOperationInfo> GetDebugOperationInfos(string packageName) internal static List<DebugOperationInfo> GetDebugOperationInfos(string packageName)
{ {
// 空包名路由到默认调度器 DebugCheckInitialize(packageName);
if (string.IsNullOrEmpty(packageName))
packageName = GLOBAL_SCHEDULER_NAME;
if (_schedulerDic.TryGetValue(packageName, out var scheduler)) var scheduler = GetScheduler(packageName);
{ return scheduler.GetDebugOperationInfos();
return scheduler.GetDebugOperationInfos(); }
} #endregion
return new List<DebugOperationInfo>(); #region
[Conditional("DEBUG")]
private static void DebugCheckInitialize(string packageName)
{
if (string.IsNullOrWhiteSpace(packageName))
throw new YooInternalException("Package name is null or empty.");
if (_isInitialize == false)
throw new YooInternalException($"{nameof(OperationSystem)} not initialized !");
} }
#endregion #endregion
} }

View File

@@ -32,23 +32,23 @@ OperationSystem 是 YooAsset 资源管理系统的**异步操作调度核心**
``` ```
┌─────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐
│ 上层调用者 │ │ 上层调用者
│ (ResourceManager / FileSystem / 业务层) │ │ (ResourceManager / FileSystem / 业务层) │
└─────────────────────────┬───────────────────────────────┘ └─────────────────────────┬───────────────────────────────┘
│ StartOperation() │ StartOperation()
┌─────────────────────────▼───────────────────────────────┐ ┌─────────────────────────▼───────────────────────────────┐
│ OperationSystem │ OperationSystem │
│ (调度器) │ │ (调度器) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 优先级队列 │ │ 时间切片 │ │ 回调通知 │ │ │ │ 优先级队列 │ │ 时间切片 │ │ 回调通知 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────┬───────────────────────────────┘ └─────────────────────────┬───────────────────────────────┘
│ UpdateOperation() │ UpdateOperation()
┌─────────────────────────▼───────────────────────────────┐ ┌─────────────────────────▼───────────────────────────────┐
│ AsyncOperationBase │ AsyncOperationBase │
│ (操作基类) │ │ (操作基类) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 状态机 │ │ 子任务管理 │ │ 异步模式 │ │ │ │ 状态机 │ │ 子任务管理 │ │ 异步模式 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────┘
``` ```
@@ -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调度器
@@ -206,61 +217,36 @@ public static void ClearPackageOperation(string packageName);
/// 启动异步操作 /// 启动异步操作
/// </summary> /// </summary>
public static void StartOperation(string packageName, AsyncOperationBase operation); public static void StartOperation(string packageName, AsyncOperationBase operation);
/// <summary>
/// 设置调度器优先级
/// </summary>
public static void SetSchedulerPriority(string packageName, uint priority);
/// <summary>
/// 获取调度器优先级
/// </summary>
public static uint GetSchedulerPriority(string packageName);
``` ```
#### 包裹调度说明
- `packageName` 不允许为空(`null` / `""`),否则会抛出异常。
- 若需要使用全局调度器,请传入 `OperationSystem.GLOBAL_SCHEDULER_NAME``Initialize()` 时自动创建)。
- `packageName` 为非全局调度器名称时,必须先通过 `YooAssets.CreatePackage(packageName)` 创建包裹(内部会注册对应 `OperationScheduler`),否则会抛出异常。
#### 回调监听 #### 回调监听
```csharp OperationSystem **当前未提供**全局任务开始/结束回调的注册接口。
/// <summary>
/// 注册任务开始回调
/// </summary>
public static void RegisterStartCallback(Action<string, AsyncOperationBase> callback);
/// <summary> 如需监听任务结束(推荐),请直接订阅具体任务的 `Completed` 事件:
/// 注册任务结束回调
/// </summary>
public static void RegisterFinishCallback(Action<string, AsyncOperationBase> callback);
```
---
### GameAsyncOperation游戏层基类
继承 `AsyncOperationBase`,为业务层提供更友好的 API。
```csharp ```csharp
public abstract class GameAsyncOperation : AsyncOperationBase var operation = package.LoadAssetAsync<GameObject>(location);
operation.Completed += op =>
{ {
/// <summary> // TODO : 根据 op.Status 判断成功/失败
/// 异步操作开始 };
/// </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();
}
``` ```
--- ---
@@ -339,15 +325,37 @@ void LoadAssetSync()
操作按 `Priority` 属性降序排列,优先级高的操作先执行。 操作按 `Priority` 属性降序排列,优先级高的操作先执行。
#### 操作优先级
```csharp ```csharp
var operation = package.LoadAssetAsync<GameObject>(location); var operation = package.LoadAssetAsync<GameObject>(location);
operation.Priority = 100; // 设置高优先级 operation.Priority = 100; // 设置高优先级
``` ```
#### 包裹优先级
通过 `ResourcePackage.PackagePriority` 可以设置包裹的调度器优先级,值越大越优先更新。
```csharp
// 创建包裹时指定优先级
var package = YooAssets.CreatePackage("MyPackage", 100);
// 运行时动态调整优先级
package.PackagePriority = 200;
// 获取当前优先级
uint priority = package.PackagePriority;
```
**使用场景:**
- 多包裹场景下,可根据游戏状态动态调整包裹优先级
- 例如:进入战斗时提高战斗资源包的优先级,退出战斗时恢复默认优先级
**排序规则:** **排序规则:**
- 新操作添加时检查是否需要排序 - 新操作添加时:若新增队列存在非零优先级,则触发排序
- 仅当存在非零优先级时触发排序 - 运行中修改 `Priority`:调度器会在每帧 `Update()` 的排序阶段检测 `IsDirty` 并触发重排;若在某个操作的 `InternalUpdate()` 内修改(本帧排序已完成),则新的优先级会延后一帧生效(可能与预期不符)
- 使用 `List.Sort()` 进行原地排序 - 若期望本帧生效:请尽量在任务入队前或本帧调度器 `Update()` 开始前设置 `Priority`,避免在 `InternalUpdate()` 内临时调整
- 排序使用 `List.Sort()` 进行原地排序;频繁修改优先级会带来额外排序开销,建议按需使用
### 时间切片 ### 时间切片
@@ -358,6 +366,10 @@ operation.Priority = 100; // 设置高优先级
OperationSystem.MaxTimeSlice = 8; OperationSystem.MaxTimeSlice = 8;
``` ```
**操作侧协作建议:**
- 在操作的 `InternalUpdate()` 中使用 `IsBusy``AsyncOperationBase` 的内部属性)进行“自愿让出”,将重任务拆分到多帧执行。
- 在同步等待(`WaitForAsyncComplete()`)阶段,`IsBusy` 会强制返回 `false`,以保证同步等待推进;此时需要自行评估卡顿风险。
**执行流程:** **执行流程:**
``` ```
@@ -420,24 +432,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 +474,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 +507,7 @@ AsyncOperationBase
### 组合模式 ### 组合模式
通过 `Childs` 列表支持父子操作关系: 通过内部子任务列表支持父子操作关系:
``` ```
ParentOperation ParentOperation
@@ -608,10 +526,6 @@ IEnumerator + IComparable<AsyncOperationBase>
AsyncOperationBase (抽象基类) AsyncOperationBase (抽象基类)
├── GameAsyncOperation (游戏层基类)
│ │
│ └── [业务层自定义操作]
└── [YooAsset 内部操作] └── [YooAsset 内部操作]
@@ -632,4 +546,4 @@ IEnumerator + IComparable<AsyncOperationBase>
4. **子任务中止**:父操作中止时会自动中止所有子操作 4. **子任务中止**:父操作中止时会自动中止所有子操作
5. **回调异常**`Completed` 回调中的异常会被捕获并记录,不会中断系统 5. **回调异常**`Completed` 回调中的异常会被捕获并记录,不会中断系统
6. **编辑器重置**:编辑器中使用 `RuntimeInitializeOnLoadMethod` 自动重置状态 6. **编辑器重置**:编辑器中使用 `RuntimeInitializeOnLoadMethod` 自动重置状态
7. **循环保护**`WaitForAsyncComplete()` 有 1000 帧上限,防止无限循环 7. **循环保护**`InternalWaitForAsyncComplete()` 中建议使用 `RunBatchExecution()`(默认 1000 次)限制单次推进次数,避免陷入无限循环或长时间占用主线程

View File

@@ -1,9 +1,9 @@
 
namespace YooAsset namespace YooAsset
{ {
public class EditorSimulateModeHelper public class EditorSimulateBuildInvoker
{ {
public static PackageInvokeBuildResult SimulateBuild(string packageName) public static PackageInvokeBuildResult Build(string packageName)
{ {
var buildParam = new PackageInvokeBuildParam(packageName); var buildParam = new PackageInvokeBuildParam(packageName);
buildParam.BuildPipelineName = "EditorSimulateBuildPipeline"; buildParam.BuildPipelineName = "EditorSimulateBuildPipeline";

View File

@@ -6,22 +6,22 @@ namespace YooAsset
/// <summary> /// <summary>
/// 下载是否已经完成 /// 下载是否已经完成
/// </summary> /// </summary>
public bool IsDone; public bool IsDone { get; set; }
/// <summary> /// <summary>
/// 下载进度0-1f) /// 下载进度0-1f)
/// </summary> /// </summary>
public float Progress; public float Progress { get; set; }
/// <summary> /// <summary>
/// 下载文件的总大小 /// 下载文件的总大小
/// </summary> /// </summary>
public long TotalBytes; public long TotalBytes { get; set; }
/// <summary> /// <summary>
/// 已经下载的文件大小 /// 已经下载的文件大小
/// </summary> /// </summary>
public long DownloadedBytes; public long DownloadedBytes { get; set; }
public static DownloadStatus CreateDefaultStatus() public static DownloadStatus CreateDefaultStatus()
{ {

View File

@@ -76,62 +76,48 @@ namespace YooAsset
/// </summary> /// </summary>
public GameObject InstantiateSync() public GameObject InstantiateSync()
{ {
return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, null, false); var options = new InstantiateOptions(true);
return InstantiateSyncInternal(options);
} }
public GameObject InstantiateSync(Transform parent)
/// <summary>
/// 同步初始化游戏对象
/// </summary>
public GameObject InstantiateSync(InstantiateOptions options)
{ {
return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, parent, false); return InstantiateSyncInternal(options);
}
public GameObject InstantiateSync(Transform parent, bool worldPositionStays)
{
return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, parent, worldPositionStays);
}
public GameObject InstantiateSync(Vector3 position, Quaternion rotation)
{
return InstantiateSyncInternal(true, position, rotation, null, false);
}
public GameObject InstantiateSync(Vector3 position, Quaternion rotation, Transform parent)
{
return InstantiateSyncInternal(true, position, rotation, parent, false);
} }
/// <summary> /// <summary>
/// 异步初始化游戏对象 /// 异步初始化游戏对象
/// </summary> /// </summary>
public InstantiateOperation InstantiateAsync(bool actived = true) public InstantiateOperation InstantiateAsync()
{ {
return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, null, false, actived); var options = new InstantiateOptions(true);
} return InstantiateAsyncInternal(options);
public InstantiateOperation InstantiateAsync(Transform parent, bool actived = true)
{
return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, parent, false, actived);
}
public InstantiateOperation InstantiateAsync(Transform parent, bool worldPositionStays, bool actived = true)
{
return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, parent, worldPositionStays, actived);
}
public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation, bool actived = true)
{
return InstantiateAsyncInternal(true, position, rotation, null, false, actived);
}
public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation, Transform parent, bool actived = true)
{
return InstantiateAsyncInternal(true, position, rotation, parent, false, actived);
} }
private GameObject InstantiateSyncInternal(bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) /// <summary>
/// 异步初始化游戏对象
/// </summary>
public InstantiateOperation InstantiateAsync(InstantiateOptions options)
{
return InstantiateAsyncInternal(options);
}
private GameObject InstantiateSyncInternal(InstantiateOptions options)
{ {
if (IsValidWithWarning == false) if (IsValidWithWarning == false)
return null; return null;
if (Provider.AssetObject == null) if (Provider.AssetObject == null)
return null; return null;
return InstantiateOperation.InstantiateInternal(Provider.AssetObject, setPositionAndRotation, position, rotation, parent, worldPositionStays); return InstantiateOperation.InstantiateInternal(Provider.AssetObject, options);
} }
private InstantiateOperation InstantiateAsyncInternal(bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays, bool actived) private InstantiateOperation InstantiateAsyncInternal(InstantiateOptions options)
{ {
string packageName = GetAssetInfo().PackageName; string packageName = GetAssetInfo().PackageName;
InstantiateOperation operation = new InstantiateOperation(this, setPositionAndRotation, position, rotation, parent, worldPositionStays, actived); InstantiateOperation operation = new InstantiateOperation(this, options);
OperationSystem.StartOperation(packageName, operation); OperationSystem.StartOperation(packageName, operation);
return operation; return operation;
} }

View File

@@ -116,7 +116,7 @@ namespace YooAsset
/// 异步卸载场景对象 /// 异步卸载场景对象
/// 注意场景卸载成功后会自动释放该handle的引用计数 /// 注意场景卸载成功后会自动释放该handle的引用计数
/// </summary> /// </summary>
public UnloadSceneOperation UnloadAsync() public UnloadSceneOperation UnloadSceneAsync()
{ {
string packageName = GetAssetInfo().PackageName; string packageName = GetAssetInfo().PackageName;

View File

@@ -14,12 +14,7 @@ namespace YooAsset
} }
private readonly AssetHandle _handle; private readonly AssetHandle _handle;
private readonly bool _setPositionAndRotation; private readonly InstantiateOptions _options;
private readonly Vector3 _position;
private readonly Quaternion _rotation;
private readonly Transform _parent;
private readonly bool _worldPositionStays;
private readonly bool _actived;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
#if UNITY_2023_3_OR_NEWER #if UNITY_2023_3_OR_NEWER
@@ -32,16 +27,10 @@ namespace YooAsset
public GameObject Result = null; public GameObject Result = null;
internal InstantiateOperation(AssetHandle handle, bool setPositionAndRotation, Vector3 position, Quaternion rotation, internal InstantiateOperation(AssetHandle handle, InstantiateOptions options)
Transform parent, bool worldPositionStays, bool actived)
{ {
_handle = handle; _handle = handle;
_setPositionAndRotation = setPositionAndRotation; _options = options;
_position = position;
_rotation = rotation;
_parent = parent;
_worldPositionStays = worldPositionStays;
_actived = actived;
} }
internal override void InternalStart() internal override void InternalStart()
{ {
@@ -62,6 +51,9 @@ namespace YooAsset
return; return;
} }
if (IsWaitForAsyncComplete)
_handle.WaitForAsyncComplete();
if (_handle.IsDone == false) if (_handle.IsDone == false)
return; return;
@@ -87,8 +79,8 @@ namespace YooAsset
if (_steps == ESteps.CloneSync) if (_steps == ESteps.CloneSync)
{ {
// 实例化游戏对象 // 实例化游戏对象
Result = InstantiateInternal(_handle.AssetObject, _setPositionAndRotation, _position, _rotation, _parent, _worldPositionStays); Result = InstantiateInternal(_handle.AssetObject, _options);
if (_actived == false) if (_options.Actived == false)
Result.SetActive(false); Result.SetActive(false);
_steps = ESteps.Done; _steps = ESteps.Done;
@@ -100,7 +92,7 @@ namespace YooAsset
{ {
if (_instantiateAsync == null) if (_instantiateAsync == null)
{ {
_instantiateAsync = InstantiateAsyncInternal(_handle.AssetObject, _setPositionAndRotation, _position, _rotation, _parent, _worldPositionStays); _instantiateAsync = InstantiateAsyncInternal(_handle.AssetObject, _options);
} }
if (IsWaitForAsyncComplete) if (IsWaitForAsyncComplete)
@@ -114,7 +106,7 @@ namespace YooAsset
Result = _instantiateAsync.Result[0] as GameObject; Result = _instantiateAsync.Result[0] as GameObject;
if (Result != null) if (Result != null)
{ {
if (_actived == false) if (_options.Actived == false)
Result.SetActive(false); Result.SetActive(false);
_steps = ESteps.Done; _steps = ESteps.Done;
@@ -138,18 +130,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()
{ {
@@ -173,22 +154,22 @@ namespace YooAsset
/// <summary> /// <summary>
/// 同步实例化 /// 同步实例化
/// </summary> /// </summary>
internal static GameObject InstantiateInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) internal static GameObject InstantiateInternal(UnityEngine.Object assetObject, InstantiateOptions options)
{ {
if (assetObject == null) if (assetObject == null)
return null; return null;
if (setPositionAndRotation) if (options.SetPositionAndRotation)
{ {
if (parent != null) if (options.Parent != null)
return UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation, parent); return UnityEngine.Object.Instantiate(assetObject as GameObject, options.Position, options.Rotation, options.Parent);
else else
return UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation); return UnityEngine.Object.Instantiate(assetObject as GameObject, options.Position, options.Rotation);
} }
else else
{ {
if (parent != null) if (options.Parent != null)
return UnityEngine.Object.Instantiate(assetObject as GameObject, parent, worldPositionStays); return UnityEngine.Object.Instantiate(assetObject as GameObject, options.Parent, options.InWorldSpace);
else else
return UnityEngine.Object.Instantiate(assetObject as GameObject); return UnityEngine.Object.Instantiate(assetObject as GameObject);
} }
@@ -200,19 +181,19 @@ namespace YooAsset
/// 注意Unity2022.3.20f1及以上版本生效 /// 注意Unity2022.3.20f1及以上版本生效
/// https://docs.unity3d.com/2022.3/Documentation/ScriptReference/Object.InstantiateAsync.html /// https://docs.unity3d.com/2022.3/Documentation/ScriptReference/Object.InstantiateAsync.html
/// </summary> /// </summary>
internal static AsyncInstantiateOperation InstantiateAsyncInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) internal static AsyncInstantiateOperation InstantiateAsyncInternal(UnityEngine.Object assetObject, InstantiateOptions options)
{ {
if (setPositionAndRotation) if (options.SetPositionAndRotation)
{ {
if (parent != null) if (options.Parent != null)
return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, parent, position, rotation); return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, options.Parent, options.Position, options.Rotation);
else else
return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, position, rotation); return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, options.Position, options.Rotation);
} }
else else
{ {
if (parent != null) if (options.Parent != null)
return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, parent); return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, options.Parent);
else else
return UnityEngine.Object.InstantiateAsync(assetObject as GameObject); return UnityEngine.Object.InstantiateAsync(assetObject as GameObject);
} }

View File

@@ -0,0 +1,77 @@
using UnityEngine;
namespace YooAsset
{
public struct InstantiateOptions
{
/// <summary>
/// 是否激活实例化对象
/// </summary>
public bool Actived { private set; get; }
/// <summary>
/// 将指定给新对象的父对象
/// </summary>
public Transform Parent { private set; get; }
/// <summary>
/// 分配父对象时, 定位新对象关系。
/// true 在世界空间中定位新对象。
/// false 相对于父对象来设置新对象。
/// </summary>
public bool InWorldSpace { private set; get; }
/// <summary>
/// 新对象的位置
/// </summary>
public Vector3 Position { private set; get; }
/// <summary>
/// 新对象的方向
/// </summary>
public Quaternion Rotation { private set; get; }
internal bool SetPositionAndRotation { private set; get; }
public InstantiateOptions(bool actived)
{
Actived = actived;
Parent = null;
InWorldSpace = false;
SetPositionAndRotation = false;
Position = Vector3.zero;
Rotation = Quaternion.identity;
}
public InstantiateOptions(bool actived, Transform parent, bool inWorldSpace)
{
Actived = actived;
Parent = parent;
InWorldSpace = inWorldSpace;
SetPositionAndRotation = false;
Position = Vector3.zero;
Rotation = Quaternion.identity;
}
public InstantiateOptions(bool actived, Transform parent, Vector3 position, Quaternion rotation)
{
Actived = actived;
Parent = parent;
InWorldSpace = false;
SetPositionAndRotation = true;
Position = position;
Rotation = rotation;
}
public InstantiateOptions(bool actived, Vector3 position, Quaternion rotation)
{
Actived = actived;
Parent = null;
InWorldSpace = false;
SetPositionAndRotation = true;
Position = position;
Rotation = rotation;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 70420213c551a2b4b8cf014067699b07 guid: 7432581e3bde71648adef94499c7a398
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@@ -4,7 +4,7 @@ using System.Collections.Generic;
namespace YooAsset namespace YooAsset
{ {
internal class LoadBundleFileOperation : AsyncOperationBase internal class LoadBundleOperation : AsyncOperationBase
{ {
private enum ESteps private enum ESteps
{ {
@@ -51,7 +51,7 @@ namespace YooAsset
public BundleResult Result { set; get; } public BundleResult Result { set; get; }
internal LoadBundleFileOperation(ResourceManager resourceManager, BundleInfo bundleInfo) internal LoadBundleOperation(ResourceManager resourceManager, BundleInfo bundleInfo)
{ {
_resManager = resourceManager; _resManager = resourceManager;
LoadBundleInfo = bundleInfo; LoadBundleInfo = bundleInfo;
@@ -85,7 +85,7 @@ namespace YooAsset
{ {
// 统计计数增加 // 统计计数增加
_resManager.BundleLoadingCounter++; _resManager.BundleLoadingCounter++;
_loadBundleOp = LoadBundleInfo.LoadBundleFile(); _loadBundleOp = LoadBundleInfo.CreateBundleLoader();
_loadBundleOp.StartOperation(); _loadBundleOp.StartOperation();
AddChildOperation(_loadBundleOp); AddChildOperation(_loadBundleOp);
} }
@@ -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()
{ {

View File

@@ -3,19 +3,6 @@ using UnityEngine;
namespace YooAsset namespace YooAsset
{ {
public sealed class UnloadAllAssetsOptions
{
/// <summary>
/// 释放所有资源句柄,防止卸载过程中触发完成回调!
/// </summary>
public bool ReleaseAllHandles = false;
/// <summary>
/// 卸载过程中锁定加载操作,防止新的任务请求!
/// </summary>
public bool LockLoadOperation = false;
}
public sealed class UnloadAllAssetsOperation : AsyncOperationBase public sealed class UnloadAllAssetsOperation : AsyncOperationBase
{ {
private enum ESteps private enum ESteps
@@ -49,14 +36,6 @@ namespace YooAsset
if (_steps == ESteps.CheckOptions) if (_steps == ESteps.CheckOptions)
{ {
if (_options == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(UnloadAllAssetsOptions)} is null.";
return;
}
// 设置锁定状态 // 设置锁定状态
if (_options.LockLoadOperation) if (_options.LockLoadOperation)
_resManager.LockLoadOperation = true; _resManager.LockLoadOperation = true;

View File

@@ -0,0 +1,22 @@

namespace YooAsset
{
public struct UnloadAllAssetsOptions
{
/// <summary>
/// 释放所有资源句柄,防止卸载过程中触发完成回调!
/// </summary>
public bool ReleaseAllHandles { set; get; }
/// <summary>
/// 卸载过程中锁定加载操作,防止新的任务请求!
/// </summary>
public bool LockLoadOperation { set; get; }
public UnloadAllAssetsOptions(bool releaseAllHandles, bool lockLoadOperation)
{
ReleaseAllHandles = releaseAllHandles;
LockLoadOperation = lockLoadOperation;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 4629f36c31a96214b9057827c6a283cf guid: dc733fff9ba8d5747b556fb6cdb2b9e2
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@@ -1,6 +1,5 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine;
namespace YooAsset namespace YooAsset
{ {
@@ -14,19 +13,19 @@ namespace YooAsset
} }
private readonly ResourceManager _resManager; private readonly ResourceManager _resManager;
private readonly int _loopCount; private readonly UnloadUnusedAssetsOptions _options;
private int _loopCounter = 0; private int _loopCounter = 0;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
internal UnloadUnusedAssetsOperation(ResourceManager resourceManager, int loopCount) internal UnloadUnusedAssetsOperation(ResourceManager resourceManager, UnloadUnusedAssetsOptions options)
{ {
_resManager = resourceManager; _resManager = resourceManager;
_loopCount = loopCount; _options = options;
} }
internal override void InternalStart() internal override void InternalStart()
{ {
_steps = ESteps.UnloadUnused; _steps = ESteps.UnloadUnused;
_loopCounter = _loopCount; _loopCounter = _options.LoopCount;
} }
internal override void InternalUpdate() internal override void InternalUpdate()
{ {
@@ -53,18 +52,11 @@ 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()
{ {
return $"LoopCount : {_loopCount}"; return $"LoopCount : {_options.LoopCount}";
} }
/// <summary> /// <summary>
@@ -72,7 +64,7 @@ namespace YooAsset
/// </summary> /// </summary>
private void LoopUnloadUnused() private void LoopUnloadUnused()
{ {
var removeList = new List<LoadBundleFileOperation>(_resManager.LoaderDic.Count); var removeList = new List<LoadBundleOperation>(_resManager.LoaderDic.Count);
// 注意:优先销毁资源提供者 // 注意:优先销毁资源提供者
foreach (var loader in _resManager.LoaderDic.Values) foreach (var loader in _resManager.LoaderDic.Values)

View File

@@ -0,0 +1,16 @@

namespace YooAsset
{
public struct UnloadUnusedAssetsOptions
{
/// <summary>
/// 循环迭代次数
/// </summary>
public int LoopCount { set; get; }
public UnloadUnusedAssetsOptions(int loopCount)
{
LoopCount = loopCount;
}
}
}

View File

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

View File

@@ -80,8 +80,8 @@ namespace YooAsset
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
protected readonly ResourceManager _resManager; protected readonly ResourceManager _resManager;
private readonly LoadBundleFileOperation _mainBundleLoader; private readonly LoadBundleOperation _mainBundleLoader;
private readonly List<LoadBundleFileOperation> _bundleLoaders = new List<LoadBundleFileOperation>(10); private readonly List<LoadBundleOperation> _bundleLoaders = new List<LoadBundleOperation>(10);
private readonly HashSet<HandleBase> _handles = new HashSet<HandleBase>(); private readonly HashSet<HandleBase> _handles = new HashSet<HandleBase>();
public ProviderOperation(ResourceManager manager, string providerGUID, AssetInfo assetInfo) public ProviderOperation(ResourceManager manager, string providerGUID, AssetInfo assetInfo)
@@ -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()
{ {

View File

@@ -10,12 +10,12 @@ namespace YooAsset
internal class ResourceManager internal class ResourceManager
{ {
internal readonly Dictionary<string, ProviderOperation> ProviderDic = new Dictionary<string, ProviderOperation>(5000); internal readonly Dictionary<string, ProviderOperation> ProviderDic = new Dictionary<string, ProviderOperation>(5000);
internal readonly Dictionary<string, LoadBundleFileOperation> LoaderDic = new Dictionary<string, LoadBundleFileOperation>(5000); internal readonly Dictionary<string, LoadBundleOperation> LoaderDic = new Dictionary<string, LoadBundleOperation>(5000);
internal readonly List<SceneHandle> SceneHandles = new List<SceneHandle>(100); internal readonly List<SceneHandle> SceneHandles = new List<SceneHandle>(100);
private FileSystemHost _fileSystemHost;
private long _sceneCreateIndex = 0; private long _sceneCreateIndex = 0;
private IBundleQuery _bundleQuery;
private int _bundleLoadingMaxConcurrency; private int _bundleLoadingMaxConcurrency;
// 开发者配置选项 // 开发者配置选项
public bool AutoUnloadBundleWhenUnused { private set; get; } public bool AutoUnloadBundleWhenUnused { private set; get; }
public bool WebGLForceSyncLoadAsset { private set; get; } public bool WebGLForceSyncLoadAsset { private set; get; }
@@ -44,12 +44,12 @@ namespace YooAsset
/// <summary> /// <summary>
/// 初始化 /// 初始化
/// </summary> /// </summary>
public void Initialize(InitializeParameters parameters, IBundleQuery bundleServices) public void Initialize(InitializePackageOptions options, FileSystemHost host)
{ {
_bundleLoadingMaxConcurrency = parameters.BundleLoadingMaxConcurrency; _fileSystemHost = host;
AutoUnloadBundleWhenUnused = parameters.AutoUnloadBundleWhenUnused; _bundleLoadingMaxConcurrency = options.BundleLoadingMaxConcurrency;
WebGLForceSyncLoadAsset = parameters.WebGLForceSyncLoadAsset; AutoUnloadBundleWhenUnused = options.AutoUnloadBundleWhenUnused;
_bundleQuery = bundleServices; WebGLForceSyncLoadAsset = options.WebGLForceSyncLoadAsset;
SceneManager.sceneUnloaded += OnSceneUnloaded; SceneManager.sceneUnloaded += OnSceneUnloaded;
} }
@@ -82,7 +82,7 @@ namespace YooAsset
loopCount--; loopCount--;
// 卸载主资源包加载器 // 卸载主资源包加载器
string mainBundleName = _bundleQuery.GetMainBundleName(assetInfo.Asset.BundleID); string mainBundleName = _fileSystemHost.GetMainBundleName(assetInfo.Asset.BundleID);
var mainLoader = TryGetBundleFileLoader(mainBundleName); var mainLoader = TryGetBundleFileLoader(mainBundleName);
if (mainLoader != null) if (mainLoader != null)
{ {
@@ -97,7 +97,7 @@ namespace YooAsset
// 卸载依赖资源包加载器 // 卸载依赖资源包加载器
foreach (var dependID in assetInfo.Asset.DependBundleIDs) foreach (var dependID in assetInfo.Asset.DependBundleIDs)
{ {
string dependBundleName = _bundleQuery.GetMainBundleName(dependID); string dependBundleName = _fileSystemHost.GetMainBundleName(dependID);
var dependLoader = TryGetBundleFileLoader(dependBundleName); var dependLoader = TryGetBundleFileLoader(dependBundleName);
if (dependLoader != null) if (dependLoader != null)
{ {
@@ -296,15 +296,15 @@ namespace YooAsset
return provider.CreateHandle<RawFileHandle>(); return provider.CreateHandle<RawFileHandle>();
} }
internal LoadBundleFileOperation CreateMainBundleFileLoader(AssetInfo assetInfo) internal LoadBundleOperation CreateMainBundleFileLoader(AssetInfo assetInfo)
{ {
BundleInfo bundleInfo = _bundleQuery.GetMainBundleInfo(assetInfo); BundleInfo bundleInfo = _fileSystemHost.GetMainBundleInfo(assetInfo);
return CreateBundleFileLoaderInternal(bundleInfo); return CreateBundleFileLoaderInternal(bundleInfo);
} }
internal List<LoadBundleFileOperation> CreateDependBundleFileLoaders(AssetInfo assetInfo) internal List<LoadBundleOperation> CreateDependBundleFileLoaders(AssetInfo assetInfo)
{ {
List<BundleInfo> bundleInfos = _bundleQuery.GetDependBundleInfos(assetInfo); List<BundleInfo> bundleInfos = _fileSystemHost.GetDependBundleInfos(assetInfo);
List<LoadBundleFileOperation> result = new List<LoadBundleFileOperation>(bundleInfos.Count); List<LoadBundleOperation> result = new List<LoadBundleOperation>(bundleInfos.Count);
foreach (var bundleInfo in bundleInfos) foreach (var bundleInfo in bundleInfos)
{ {
var bundleLoader = CreateBundleFileLoaderInternal(bundleInfo); var bundleLoader = CreateBundleFileLoaderInternal(bundleInfo);
@@ -321,7 +321,7 @@ namespace YooAsset
} }
internal bool CheckBundleDestroyed(int bundleID) internal bool CheckBundleDestroyed(int bundleID)
{ {
string bundleName = _bundleQuery.GetMainBundleName(bundleID); string bundleName = _fileSystemHost.GetMainBundleName(bundleID);
var bundleFileLoader = TryGetBundleFileLoader(bundleName); var bundleFileLoader = TryGetBundleFileLoader(bundleName);
if (bundleFileLoader == null) if (bundleFileLoader == null)
return true; return true;
@@ -329,7 +329,7 @@ namespace YooAsset
} }
internal bool CheckBundleReleasable(int bundleID) internal bool CheckBundleReleasable(int bundleID)
{ {
string bundleName = _bundleQuery.GetMainBundleName(bundleID); string bundleName = _fileSystemHost.GetMainBundleName(bundleID);
var bundleFileLoader = TryGetBundleFileLoader(bundleName); var bundleFileLoader = TryGetBundleFileLoader(bundleName);
if (bundleFileLoader == null) if (bundleFileLoader == null)
return true; return true;
@@ -344,22 +344,22 @@ namespace YooAsset
return BundleLoadingCounter >= _bundleLoadingMaxConcurrency; return BundleLoadingCounter >= _bundleLoadingMaxConcurrency;
} }
private LoadBundleFileOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo) private LoadBundleOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo)
{ {
// 如果加载器已经存在 // 如果加载器已经存在
string bundleName = bundleInfo.Bundle.BundleName; string bundleName = bundleInfo.Bundle.BundleName;
LoadBundleFileOperation loaderOperation = TryGetBundleFileLoader(bundleName); LoadBundleOperation loaderOperation = TryGetBundleFileLoader(bundleName);
if (loaderOperation != null) if (loaderOperation != null)
return loaderOperation; return loaderOperation;
// 新增下载需求 // 新增下载需求
loaderOperation = new LoadBundleFileOperation(this, bundleInfo); loaderOperation = new LoadBundleOperation(this, bundleInfo);
LoaderDic.Add(bundleName, loaderOperation); LoaderDic.Add(bundleName, loaderOperation);
return loaderOperation; return loaderOperation;
} }
private LoadBundleFileOperation TryGetBundleFileLoader(string bundleName) private LoadBundleOperation TryGetBundleFileLoader(string bundleName)
{ {
if (LoaderDic.TryGetValue(bundleName, out LoadBundleFileOperation value)) if (LoaderDic.TryGetValue(bundleName, out LoadBundleOperation value))
return value; return value;
else else
return null; return null;

View File

@@ -26,21 +26,22 @@ namespace YooAsset
} }
/// <summary> /// <summary>
/// 加载资源包 /// 创建加载器
/// </summary> /// </summary>
public FSLoadBundleOperation LoadBundleFile() public FSLoadBundleOperation CreateBundleLoader()
{ {
return _fileSystem.LoadBundleFile(Bundle); var options = new LoadBundleOptions(Bundle);
return _fileSystem.LoadBundleAsync(options);
} }
/// <summary> /// <summary>
/// 创建下载器 /// 创建下载器
/// </summary> /// </summary>
public FSDownloadFileOperation CreateDownloader(int failedTryAgain) public FSDownloadFileOperation CreateBundleDownloader(int failedTryAgain)
{ {
DownloadFileOptions options = new DownloadFileOptions(failedTryAgain); DownloadFileOptions options = new DownloadFileOptions(Bundle, failedTryAgain);
options.ImportFilePath = _importFilePath; options.ImportFilePath = _importFilePath;
return _fileSystem.DownloadFileAsync(Bundle, options); return _fileSystem.DownloadFileAsync(options);
} }
/// <summary> /// <summary>

View File

@@ -1,7 +1,7 @@
 
namespace YooAsset namespace YooAsset
{ {
public enum EBuildBundleType public enum EBundleType
{ {
/// <summary> /// <summary>
/// 未知类型 /// 未知类型
@@ -22,5 +22,10 @@ namespace YooAsset
/// 原生文件 /// 原生文件
/// </summary> /// </summary>
RawBundle = 3, RawBundle = 3,
/// <summary>
/// 团结资源包
/// </summary>
InstantBundle = 4,
} }
} }

View File

@@ -0,0 +1,34 @@

namespace YooAsset
{
/// <summary>
/// 运行模式
/// </summary>
public enum EPlayMode
{
/// <summary>
/// 编辑器下的模拟模式
/// </summary>
EditorSimulateMode,
/// <summary>
/// 离线运行模式
/// </summary>
OfflinePlayMode,
/// <summary>
/// 联机运行模式
/// </summary>
HostPlayMode,
/// <summary>
/// WebGL运行模式
/// </summary>
WebPlayMode,
/// <summary>
/// 自定义运行模式
/// </summary>
CustomPlayMode,
}
}

View File

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

View File

@@ -4,22 +4,26 @@ using System.Collections.Generic;
namespace YooAsset namespace YooAsset
{ {
internal class PlayModeImpl : IPlayMode, IBundleQuery internal class FileSystemHost
{ {
public readonly string PackageName; public readonly string PackageName;
public readonly EPlayMode PlayMode;
public readonly List<IFileSystem> FileSystems = new List<IFileSystem>(10); public readonly List<IFileSystem> FileSystems = new List<IFileSystem>(10);
public PlayModeImpl(string packageName, EPlayMode playMode) /// <summary>
/// 当前激活的清单
/// </summary>
public PackageManifest ActiveManifest { private set; get; }
public FileSystemHost(string packageName)
{ {
PackageName = packageName; PackageName = packageName;
PlayMode = playMode;
} }
/// <summary> /// <summary>
/// 异步初始化 /// 异步初始化
/// </summary> /// </summary>
public InitializationOperation InitializeAsync(FileSystemParameters fileSystemParameter) public InitializeFileSystemOperation InitializeAsync(FileSystemParameters fileSystemParameter)
{ {
var fileSystemParamList = new List<FileSystemParameters>(); var fileSystemParamList = new List<FileSystemParameters>();
if (fileSystemParameter != null) if (fileSystemParameter != null)
@@ -30,7 +34,7 @@ namespace YooAsset
/// <summary> /// <summary>
/// 异步初始化 /// 异步初始化
/// </summary> /// </summary>
public InitializationOperation InitializeAsync(FileSystemParameters fileSystemParameterA, FileSystemParameters fileSystemParameterB) public InitializeFileSystemOperation InitializeAsync(FileSystemParameters fileSystemParameterA, FileSystemParameters fileSystemParameterB)
{ {
var fileSystemParamList = new List<FileSystemParameters>(); var fileSystemParamList = new List<FileSystemParameters>();
if (fileSystemParameterA != null) if (fileSystemParameterA != null)
@@ -43,22 +47,16 @@ namespace YooAsset
/// <summary> /// <summary>
/// 异步初始化 /// 异步初始化
/// </summary> /// </summary>
public InitializationOperation InitializeAsync(List<FileSystemParameters> fileSystemParameterList) public InitializeFileSystemOperation InitializeAsync(List<FileSystemParameters> fileSystemParameterList)
{ {
var operation = new InitializationOperation(this, fileSystemParameterList); var operation = new InitializeFileSystemOperation(this, fileSystemParameterList);
return operation; return operation;
} }
#region IPlayMode接口
/// <summary>
/// 当前激活的清单
/// </summary>
public PackageManifest ActiveManifest { set; get; }
/// <summary> /// <summary>
/// 销毁文件系统 /// 销毁文件系统
/// </summary> /// </summary>
void IPlayMode.DestroyFileSystem() public void Destroy()
{ {
foreach (var fileSystem in FileSystems) foreach (var fileSystem in FileSystems)
{ {
@@ -68,91 +66,44 @@ namespace YooAsset
} }
/// <summary> /// <summary>
/// 向网络端请求最新的资源版本 /// 设置当前激活的资源清单
/// </summary> /// </summary>
RequestPackageVersionOperation IPlayMode.RequestPackageVersionAsync(bool appendTimeTicks, int timeout) public void SetActiveManifest(PackageManifest manifest)
{ {
var operation = new RequestPackageVersionImplOperation(this, appendTimeTicks, timeout); ActiveManifest = manifest;
return operation;
} }
/// <summary> /// <summary>
/// 向网络端请求并更新清单 /// 获取主文件系统
/// 说明:文件系统列表里,最后一个属于主文件系统
/// </summary> /// </summary>
UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, int timeout) public IFileSystem GetMainFileSystem()
{ {
var operation = new UpdatePackageManifestOperation(this, packageVersion, timeout); int count = FileSystems.Count;
return operation; if (count == 0)
return null;
return FileSystems[count - 1];
} }
/// <summary> /// <summary>
/// 预下载指定版本的包裹内容 /// 获取资源包所属文件系统
/// </summary> /// </summary>
PreDownloadContentOperation IPlayMode.PreDownloadContentAsync(string packageVersion, int timeout) private IFileSystem GetBelongFileSystem(PackageBundle packageBundle)
{ {
var operation = new PreDownloadContentOperation(this, packageVersion, timeout); for (int i = 0; i < FileSystems.Count; i++)
return operation; {
IFileSystem fileSystem = FileSystems[i];
if (fileSystem.Belong(packageBundle))
{
return fileSystem;
}
}
YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}");
return null;
} }
/// <summary> #region
/// 清理缓存文件
/// </summary>
ClearCacheFilesOperation IPlayMode.ClearCacheFilesAsync(ClearCacheFilesOptions options)
{
var operation = new ClearCacheFilesOperation(this, options);
return operation;
}
// 下载相关
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain)
{
List<BundleInfo> downloadList = GetDownloadListByAll(ActiveManifest);
var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain);
return operation;
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain)
{
List<BundleInfo> downloadList = GetDownloadListByTags(ActiveManifest, tags);
var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain);
return operation;
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain)
{
List<BundleInfo> downloadList = GetDownloadListByPaths(ActiveManifest, assetInfos, recursiveDownload);
var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain);
return operation;
}
// 解压相关
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain)
{
List<BundleInfo> unpcakList = GetUnpackListByAll(ActiveManifest);
var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain);
return operation;
}
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain)
{
List<BundleInfo> unpcakList = GetUnpackListByTags(ActiveManifest, tags);
var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain);
return operation;
}
// 导入相关
ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importingMaxNumber, int failedTryAgain)
{
List<BundleInfo> importerList = GetImporterListByFilePaths(ActiveManifest, filePaths);
var operation = new ResourceImporterOperation(PackageName, importerList, importingMaxNumber, failedTryAgain);
return operation;
}
ResourceImporterOperation IPlayMode.CreateResourceImporterByFileInfos(ImportFileInfo[] fileInfos, int importingMaxNumber, int failedTryAgain)
{
List<BundleInfo> importerList = GetImporterListByFileInfos(ActiveManifest, fileInfos);
var operation = new ResourceImporterOperation(PackageName, importerList, importingMaxNumber, failedTryAgain);
return operation;
}
#endregion
#region IBundleQuery接口
private BundleInfo CreateBundleInfo(PackageBundle packageBundle) private BundleInfo CreateBundleInfo(PackageBundle packageBundle)
{ {
if (packageBundle == null) if (packageBundle == null)
@@ -167,7 +118,7 @@ namespace YooAsset
throw new YooFileSystemException($"Can not found belong file system : {packageBundle.BundleName}"); throw new YooFileSystemException($"Can not found belong file system : {packageBundle.BundleName}");
} }
BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo) public BundleInfo GetMainBundleInfo(AssetInfo assetInfo)
{ {
if (assetInfo == null || assetInfo.IsInvalid) if (assetInfo == null || assetInfo.IsInvalid)
throw new YooInternalException(); throw new YooInternalException();
@@ -176,7 +127,13 @@ namespace YooAsset
var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.Asset); var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.Asset);
return CreateBundleInfo(packageBundle); return CreateBundleInfo(packageBundle);
} }
List<BundleInfo> IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo) public string GetMainBundleName(int bundleID)
{
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = ActiveManifest.GetMainPackageBundle(bundleID);
return packageBundle.BundleName;
}
public List<BundleInfo> GetDependBundleInfos(AssetInfo assetInfo)
{ {
if (assetInfo == null || assetInfo.IsInvalid) if (assetInfo == null || assetInfo.IsInvalid)
throw new YooInternalException(); throw new YooInternalException();
@@ -201,45 +158,91 @@ namespace YooAsset
} }
return result; return result;
} }
string IBundleQuery.GetMainBundleName(int bundleID)
{
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = ActiveManifest.GetMainPackageBundle(bundleID);
return packageBundle.BundleName;
}
#endregion #endregion
/// <summary> #region
/// 获取主文件系统 public bool IsNeedDownloadFromRemoteInternal(AssetInfo assetInfo)
/// 说明:文件系统列表里,最后一个属于主文件系统
/// </summary>
public IFileSystem GetMainFileSystem()
{ {
int count = FileSystems.Count; if (assetInfo.IsInvalid)
if (count == 0)
return null;
return FileSystems[count - 1];
}
/// <summary>
/// 获取资源包所属文件系统
/// </summary>
public IFileSystem GetBelongFileSystem(PackageBundle packageBundle)
{
for (int i = 0; i < FileSystems.Count; i++)
{ {
IFileSystem fileSystem = FileSystems[i]; YooLogger.Warning(assetInfo.Error);
if (fileSystem.Belong(packageBundle)) return false;
{
return fileSystem;
}
} }
YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}"); BundleInfo bundleInfo = GetMainBundleInfo(assetInfo);
return null; if (bundleInfo.IsNeedDownloadFromRemote())
return true;
List<BundleInfo> depends = GetDependBundleInfos(assetInfo);
foreach (var depend in depends)
{
if (depend.IsNeedDownloadFromRemote())
return true;
}
return false;
} }
public List<BundleInfo> GetDownloadListByAll(PackageManifest manifest) public ResourceDownloaderOperation CreateResourceDownloader(ResourceDownloaderOptions options)
{
return CreateResourceDownloader(ActiveManifest, options);
}
public ResourceDownloaderOperation CreateResourceDownloader(PackageManifest manifest, ResourceDownloaderOptions options)
{
List<BundleInfo> downloadList;
if (options.Tags == null)
downloadList = GetDownloadListByAll(manifest);
else
downloadList = GetDownloadListByTags(manifest, options.Tags);
var operation = new ResourceDownloaderOperation(PackageName, downloadList, options.MaximumConcurrency, options.FailedTryAgain);
return operation;
}
public ResourceDownloaderOperation CreateResourceDownloader(BundleDownloaderOptions options)
{
return CreateResourceDownloader(ActiveManifest, options);
}
public ResourceDownloaderOperation CreateResourceDownloader(PackageManifest manifest, BundleDownloaderOptions options)
{
List<BundleInfo> downloadList;
if (options.AssetInfos == null)
downloadList = GetDownloadListByAll(manifest);
else
downloadList = GetDownloadListByAssetInfos(manifest, options.AssetInfos, options.DownloadBundleDependencies);
var operation = new ResourceDownloaderOperation(PackageName, downloadList, options.MaximumConcurrency, options.FailedTryAgain);
return operation;
}
public ResourceUnpackerOperation CreateResourceUnpacker(ResourceUnpackerOptions options)
{
return CreateResourceUnpacker(ActiveManifest, options);
}
public ResourceUnpackerOperation CreateResourceUnpacker(PackageManifest manifest, ResourceUnpackerOptions options)
{
List<BundleInfo> unpcakList;
if (options.Tags == null)
unpcakList = GetUnpackListByAll(manifest);
else
unpcakList = GetUnpackListByTags(manifest, options.Tags);
var operation = new ResourceUnpackerOperation(PackageName, unpcakList, options.MaximumConcurrency, options.FailedTryAgain);
return operation;
}
public ResourceImporterOperation CreateResourceImporter(BundleImporterOptions options)
{
return CreateResourceImporter(ActiveManifest, options);
}
public ResourceImporterOperation CreateResourceImporter(PackageManifest manifest, BundleImporterOptions options)
{
List<BundleInfo> importerList = GetImporterListByBundleInfos(manifest, options.BundleInfos);
var operation = new ResourceImporterOperation(PackageName, importerList, options.MaximumConcurrency, options.FailedTryAgain);
return operation;
}
private List<BundleInfo> GetDownloadListByAll(PackageManifest manifest)
{ {
if (manifest == null) if (manifest == null)
return new List<BundleInfo>(); return new List<BundleInfo>();
@@ -259,7 +262,7 @@ namespace YooAsset
} }
return result; return result;
} }
public List<BundleInfo> GetDownloadListByTags(PackageManifest manifest, string[] tags) private List<BundleInfo> GetDownloadListByTags(PackageManifest manifest, string[] tags)
{ {
if (manifest == null) if (manifest == null)
return new List<BundleInfo>(); return new List<BundleInfo>();
@@ -292,13 +295,14 @@ namespace YooAsset
} }
return result; return result;
} }
public List<BundleInfo> GetDownloadListByPaths(PackageManifest manifest, AssetInfo[] assetInfos, bool recursiveDownload) private List<BundleInfo> GetDownloadListByAssetInfos(PackageManifest manifest, AssetInfo[] assetInfos, bool recursiveDownload)
{ {
if (manifest == null) if (manifest == null)
return new List<BundleInfo>(); return new List<BundleInfo>();
// 获取资源对象的资源包和所有依赖资源包 // 获取资源对象的资源包和所有依赖资源包
List<PackageBundle> checkList = new List<PackageBundle>(); HashSet<string> checkSet = new HashSet<string>();
List<PackageBundle> checkList = new List<PackageBundle>(assetInfos.Length);
foreach (var assetInfo in assetInfos) foreach (var assetInfo in assetInfos)
{ {
if (assetInfo.IsInvalid) if (assetInfo.IsInvalid)
@@ -309,15 +313,21 @@ namespace YooAsset
// 注意:如果清单里未找到资源包会抛出异常! // 注意:如果清单里未找到资源包会抛出异常!
PackageBundle mainBundle = manifest.GetMainPackageBundle(assetInfo.Asset); PackageBundle mainBundle = manifest.GetMainPackageBundle(assetInfo.Asset);
if (checkList.Contains(mainBundle) == false) if (checkSet.Contains(mainBundle.BundleGUID) == false)
{
checkSet.Add(mainBundle.BundleGUID);
checkList.Add(mainBundle); checkList.Add(mainBundle);
}
// 注意:如果清单里未找到资源包会抛出异常! // 注意:如果清单里未找到资源包会抛出异常!
List<PackageBundle> mainDependBundles = manifest.GetAssetAllDependencies(assetInfo.Asset); List<PackageBundle> mainDependBundles = manifest.GetAssetAllDependencies(assetInfo.Asset);
foreach (var dependBundle in mainDependBundles) foreach (var dependBundle in mainDependBundles)
{ {
if (checkList.Contains(dependBundle) == false) if (checkSet.Contains(dependBundle.BundleGUID) == false)
{
checkSet.Add(dependBundle.BundleGUID);
checkList.Add(dependBundle); checkList.Add(dependBundle);
}
} }
// 下载主资源包内所有资源对象依赖的资源包 // 下载主资源包内所有资源对象依赖的资源包
@@ -326,14 +336,20 @@ namespace YooAsset
foreach (var otherMainAsset in mainBundle.IncludeMainAssets) foreach (var otherMainAsset in mainBundle.IncludeMainAssets)
{ {
var otherMainBundle = manifest.GetMainPackageBundle(otherMainAsset.BundleID); var otherMainBundle = manifest.GetMainPackageBundle(otherMainAsset.BundleID);
if (checkList.Contains(otherMainBundle) == false) if (checkSet.Contains(otherMainBundle.BundleGUID) == false)
{
checkSet.Add(otherMainBundle.BundleGUID);
checkList.Add(otherMainBundle); checkList.Add(otherMainBundle);
}
List<PackageBundle> otherDependBundles = manifest.GetAssetAllDependencies(otherMainAsset); List<PackageBundle> otherDependBundles = manifest.GetAssetAllDependencies(otherMainAsset);
foreach (var dependBundle in otherDependBundles) foreach (var dependBundle in otherDependBundles)
{ {
if (checkList.Contains(dependBundle) == false) if (checkSet.Contains(dependBundle.BundleGUID) == false)
{
checkSet.Add(dependBundle.BundleGUID);
checkList.Add(dependBundle); checkList.Add(dependBundle);
}
} }
} }
} }
@@ -354,7 +370,7 @@ namespace YooAsset
} }
return result; return result;
} }
public List<BundleInfo> GetUnpackListByAll(PackageManifest manifest) private List<BundleInfo> GetUnpackListByAll(PackageManifest manifest)
{ {
if (manifest == null) if (manifest == null)
return new List<BundleInfo>(); return new List<BundleInfo>();
@@ -374,7 +390,7 @@ namespace YooAsset
} }
return result; return result;
} }
public List<BundleInfo> GetUnpackListByTags(PackageManifest manifest, string[] tags) private List<BundleInfo> GetUnpackListByTags(PackageManifest manifest, string[] tags)
{ {
if (manifest == null) if (manifest == null)
return new List<BundleInfo>(); return new List<BundleInfo>();
@@ -397,22 +413,7 @@ namespace YooAsset
} }
return result; return result;
} }
public List<BundleInfo> GetImporterListByFilePaths(PackageManifest manifest, string[] filePaths) private List<BundleInfo> GetImporterListByBundleInfos(PackageManifest manifest, ImportBundleInfo[] fileInfos)
{
if (manifest == null)
return new List<BundleInfo>();
ImportFileInfo[] fileInfos = new ImportFileInfo[filePaths.Length];
for (int i = 0; i < filePaths.Length; i++)
{
ImportFileInfo fileInfo = new ImportFileInfo();
fileInfo.FilePath = filePaths[i];
fileInfos[i] = fileInfo;
}
return GetImporterListByFileInfos(manifest, fileInfos);
}
public List<BundleInfo> GetImporterListByFileInfos(PackageManifest manifest, ImportFileInfo[] fileInfos)
{ {
if (manifest == null) if (manifest == null)
return new List<BundleInfo>(); return new List<BundleInfo>();
@@ -466,5 +467,6 @@ namespace YooAsset
} }
return result; return result;
} }
#endregion
} }
} }

View File

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

View File

@@ -1,23 +0,0 @@
using System.Collections;
using System.Collections.Generic;
namespace YooAsset
{
internal interface IBundleQuery
{
/// <summary>
/// 获取主资源包信息
/// </summary>
BundleInfo GetMainBundleInfo(AssetInfo assetInfo);
/// <summary>
/// 获取依赖的资源包信息集合
/// </summary>
List<BundleInfo> GetDependBundleInfos(AssetInfo assetPath);
/// <summary>
/// 获取主资源包名称
/// </summary>
string GetMainBundleName(int bundleID);
}
}

View File

@@ -1,49 +0,0 @@

namespace YooAsset
{
internal interface IPlayMode
{
/// <summary>
/// 当前激活的清单
/// </summary>
PackageManifest ActiveManifest { set; get; }
/// <summary>
/// 销毁文件系统
/// </summary>
void DestroyFileSystem();
/// <summary>
/// 向网络端请求最新的资源版本
/// </summary>
RequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout);
/// <summary>
/// 向网络端请求并更新清单
/// </summary>
UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, int timeout);
/// <summary>
/// 预下载指定版本的包裹内容
/// </summary>
PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout);
/// <summary>
/// 清理缓存文件
/// </summary>
ClearCacheFilesOperation ClearCacheFilesAsync(ClearCacheFilesOptions options);
// 下载相关
ResourceDownloaderOperation CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain);
ResourceDownloaderOperation CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain);
ResourceDownloaderOperation CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain);
// 解压相关
ResourceUnpackerOperation CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain);
ResourceUnpackerOperation CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain);
// 导入相关
ResourceImporterOperation CreateResourceImporterByFilePaths(string[] filePaths, int importingMaxNumber, int failedTryAgain);
ResourceImporterOperation CreateResourceImporterByFileInfos(ImportFileInfo[] fileInfos, int importingMaxNumber, int failedTryAgain);
}
}

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