diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..b4c5701a --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.cs text eol=lf \ No newline at end of file diff --git a/Assets/YooAsset.zip b/Assets/YooAsset.zip new file mode 100644 index 00000000..d2578faa Binary files /dev/null and b/Assets/YooAsset.zip differ diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildBundleInfo.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildBundleInfo.cs index 3d04bcb1..ee8b0910 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildBundleInfo.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildBundleInfo.cs @@ -204,7 +204,7 @@ namespace YooAsset.Editor packageBundle.FileHash = PackageFileHash; packageBundle.FileCRC = PackageFileCRC; packageBundle.FileSize = PackageFileSize; - packageBundle.Encrypted = Encrypted; + packageBundle.IsEncrypted = Encrypted; return packageBundle; } } diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateCatalog.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateCatalog.cs index 4cc79274..aa39abf7 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateCatalog.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateCatalog.cs @@ -15,7 +15,7 @@ namespace YooAsset.Editor string buildinRootDirectory = buildParametersContext.GetBuildinRootDirectory(); string buildPackageName = buildParametersContext.Parameters.PackageName; var manifestServices = buildParametersContext.Parameters.ManifestRestoreServices; - CatalogFileTools.CreateFile(manifestServices, buildPackageName, buildinRootDirectory); + BuiltinFileCatalogTools.CreateFile(manifestServices, buildPackageName, buildinRootDirectory); // 刷新目录 AssetDatabase.Refresh(); diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateManifest.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateManifest.cs index eb00708b..65ccc4b3 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateManifest.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateManifest.cs @@ -71,7 +71,7 @@ namespace YooAsset.Editor { string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion); string filePath = $"{packageOutputDirectory}/{fileName}"; - PackageManifestTools.SerializeToJson(filePath, manifest); + PackageManifestTools.SerializeManifestToJson(filePath, manifest); BuildLogger.Log($"Create package manifest file: {filePath}"); } @@ -81,8 +81,8 @@ namespace YooAsset.Editor { string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion); packagePath = $"{packageOutputDirectory}/{fileName}"; - PackageManifestTools.SerializeToBinary(packagePath, manifest, buildParameters.ManifestProcessServices); - packageHash = HashUtility.FileCRC32(packagePath); + PackageManifestTools.SerializeManifestToBinary(packagePath, manifest, buildParameters.ManifestProcessServices); + packageHash = HashUtility.ComputeFileCRC32(packagePath); BuildLogger.Log($"Create package manifest file: {packagePath}"); } @@ -106,7 +106,7 @@ namespace YooAsset.Editor { ManifestContext manifestContext = new ManifestContext(); byte[] bytesData = FileUtility.ReadAllBytes(packagePath); - manifestContext.Manifest = PackageManifestTools.DeserializeFromBinary(bytesData, buildParameters.ManifestRestoreServices); + manifestContext.Manifest = PackageManifestTools.DeserializeManifestFromBinary(bytesData, buildParameters.ManifestRestoreServices); context.SetContextObject(manifestContext); } } @@ -205,7 +205,7 @@ namespace YooAsset.Editor foreach (var packageAsset in manifest.AssetList) { var mainAssetInfo = packageAsset.TempDataInEditor as BuildAssetInfo; - packageAsset.DependBundleIDs = GetAssetDependBundleIDs(mainAssetInfo); + packageAsset.DependentBundleIDs = GetAssetDependBundleIDs(mainAssetInfo); } } @@ -229,7 +229,7 @@ namespace YooAsset.Editor // 排序并填充数据 dependIDs.Sort(); - packageBundle.DependBundleIDs = dependIDs.ToArray(); + packageBundle.DependentBundleIDs = dependIDs.ToArray(); } } @@ -249,9 +249,9 @@ namespace YooAsset.Editor var assetTags = packageAsset.AssetTags; int bundleID = packageAsset.BundleID; CacheBundleTags(bundleID, assetTags); - if (packageAsset.DependBundleIDs != null) + if (packageAsset.DependentBundleIDs != null) { - foreach (var dependBundleID in packageAsset.DependBundleIDs) + foreach (var dependBundleID in packageAsset.DependentBundleIDs) { CacheBundleTags(dependBundleID, assetTags); } @@ -359,11 +359,11 @@ namespace YooAsset.Editor { if (cacheBundleIDs.Contains(packageAsset.BundleID)) { - if (packageAsset.DependBundleIDs.Contains(builtinBundleID) == false) + if (packageAsset.DependentBundleIDs.Contains(builtinBundleID) == false) { - var tempBundleIDs = new List(packageAsset.DependBundleIDs); + var tempBundleIDs = new List(packageAsset.DependentBundleIDs); tempBundleIDs.Add(builtinBundleID); - packageAsset.DependBundleIDs = tempBundleIDs.ToArray(); + packageAsset.DependentBundleIDs = tempBundleIDs.ToArray(); } foreach (var tag in packageAsset.AssetTags) diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateReport.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateReport.cs index 21ed09d1..ceade7ce 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateReport.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateReport.cs @@ -106,7 +106,7 @@ namespace YooAsset.Editor reportBundleInfo.FileHash = packageBundle.FileHash; reportBundleInfo.FileCRC = packageBundle.FileCRC; reportBundleInfo.FileSize = packageBundle.FileSize; - reportBundleInfo.Encrypted = packageBundle.Encrypted; + reportBundleInfo.Encrypted = packageBundle.IsEncrypted; reportBundleInfo.Tags = packageBundle.Tags; reportBundleInfo.DependBundles = GetBundleDependBundles(manifest, packageBundle); reportBundleInfo.ReferenceBundles = GetBundleReferenceBundles(manifest, packageBundle); @@ -145,8 +145,8 @@ namespace YooAsset.Editor /// private List GetAssetDependBundles(PackageManifest manifest, PackageAsset packageAsset) { - List dependBundles = new List(packageAsset.DependBundleIDs.Length); - foreach (int index in packageAsset.DependBundleIDs) + List dependBundles = new List(packageAsset.DependentBundleIDs.Length); + foreach (int index in packageAsset.DependentBundleIDs) { string dependBundleName = manifest.BundleList[index].BundleName; dependBundles.Add(dependBundleName); @@ -160,8 +160,8 @@ namespace YooAsset.Editor /// private List GetBundleDependBundles(PackageManifest manifest, PackageBundle packageBundle) { - List dependBundles = new List(packageBundle.DependBundleIDs.Length); - foreach (int index in packageBundle.DependBundleIDs) + List dependBundles = new List(packageBundle.DependentBundleIDs.Length); + foreach (int index in packageBundle.DependentBundleIDs) { string dependBundleName = manifest.BundleList[index].BundleName; dependBundles.Add(dependBundleName); @@ -218,7 +218,7 @@ namespace YooAsset.Editor int fileCount = 0; foreach (var packageBundle in manifest.BundleList) { - if (packageBundle.Encrypted) + if (packageBundle.IsEncrypted) fileCount++; } return fileCount; @@ -228,7 +228,7 @@ namespace YooAsset.Editor long fileBytes = 0; foreach (var packageBundle in manifest.BundleList) { - if (packageBundle.Encrypted) + if (packageBundle.IsEncrypted) fileBytes += packageBundle.FileSize; } return fileBytes; diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BuiltinBuildPipeline/BuildTasks/TaskUpdateBundleInfo_BBP.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BuiltinBuildPipeline/BuildTasks/TaskUpdateBundleInfo_BBP.cs index 0603cdc4..288c04ba 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BuiltinBuildPipeline/BuildTasks/TaskUpdateBundleInfo_BBP.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BuiltinBuildPipeline/BuildTasks/TaskUpdateBundleInfo_BBP.cs @@ -43,12 +43,12 @@ namespace YooAsset.Editor protected override string GetBundleFileHash(BuildBundleInfo bundleInfo, BuildContext context) { string filePath = bundleInfo.PackageSourceFilePath; - return HashUtility.FileMD5(filePath); + return HashUtility.ComputeFileMD5(filePath); } protected override uint GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildContext context) { string filePath = bundleInfo.PackageSourceFilePath; - return HashUtility.FileCRC32Value(filePath); + return HashUtility.ComputeFileCRC32AsUInt(filePath); } protected override long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildContext context) { diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/EditorSimulateBuildPipeline/BuildTasks/TaskUpdateBundleInfo_ESBP.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/EditorSimulateBuildPipeline/BuildTasks/TaskUpdateBundleInfo_ESBP.cs index f56a7cb4..8aba08e6 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/EditorSimulateBuildPipeline/BuildTasks/TaskUpdateBundleInfo_ESBP.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/EditorSimulateBuildPipeline/BuildTasks/TaskUpdateBundleInfo_ESBP.cs @@ -36,7 +36,7 @@ namespace YooAsset.Editor private string GetFilePathTempHash(string filePath) { byte[] bytes = Encoding.UTF8.GetBytes(filePath); - return HashUtility.BytesMD5(bytes); + return HashUtility.ComputeBytesMD5(bytes); // 注意:在文件路径的哈希值冲突的情况下,可以使用下面的方法 //return $"{HashUtility.BytesMD5(bytes)}-{Guid.NewGuid():N}"; diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/RawFileBuildPipeline/BuildTasks/TaskUpdateBundleInfo_RFBP.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/RawFileBuildPipeline/BuildTasks/TaskUpdateBundleInfo_RFBP.cs index ee267f57..35bae3a2 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/RawFileBuildPipeline/BuildTasks/TaskUpdateBundleInfo_RFBP.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/RawFileBuildPipeline/BuildTasks/TaskUpdateBundleInfo_RFBP.cs @@ -25,7 +25,7 @@ namespace YooAsset.Editor else { string filePath = bundleInfo.PackageSourceFilePath; - return HashUtility.FileMD5(filePath); + return HashUtility.ComputeFileMD5(filePath); } } protected override uint GetUnityCRC(BuildBundleInfo bundleInfo, BuildContext context) @@ -44,13 +44,13 @@ namespace YooAsset.Editor else { string filePath = bundleInfo.PackageSourceFilePath; - return HashUtility.FileMD5(filePath); + return HashUtility.ComputeFileMD5(filePath); } } protected override uint GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildContext context) { string filePath = bundleInfo.PackageSourceFilePath; - return HashUtility.FileCRC32Value(filePath); + return HashUtility.ComputeFileCRC32AsUInt(filePath); } protected override long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildContext context) { @@ -60,10 +60,10 @@ namespace YooAsset.Editor private string GetFileMD5IncludePath(string filePath) { - string pathHash = HashUtility.StringMD5(filePath.ToLowerInvariant()); - string contentHash = HashUtility.FileMD5(filePath); + string pathHash = HashUtility.ComputeMD5(filePath.ToLowerInvariant()); + string contentHash = HashUtility.ComputeFileMD5(filePath); string combined = pathHash + contentHash; - return HashUtility.StringMD5(combined); + return HashUtility.ComputeMD5(combined); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/ScriptableBuildPipeline/BuildTasks/TaskUpdateBundleInfo_SBP.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/ScriptableBuildPipeline/BuildTasks/TaskUpdateBundleInfo_SBP.cs index 84a39a4a..8b263168 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/ScriptableBuildPipeline/BuildTasks/TaskUpdateBundleInfo_SBP.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/ScriptableBuildPipeline/BuildTasks/TaskUpdateBundleInfo_SBP.cs @@ -43,12 +43,12 @@ namespace YooAsset.Editor protected override string GetBundleFileHash(BuildBundleInfo bundleInfo, BuildContext context) { string filePath = bundleInfo.PackageSourceFilePath; - return HashUtility.FileMD5(filePath); + return HashUtility.ComputeFileMD5(filePath); } protected override uint GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildContext context) { string filePath = bundleInfo.PackageSourceFilePath; - return HashUtility.FileCRC32Value(filePath); + return HashUtility.ComputeFileCRC32AsUInt(filePath); } protected override long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildContext context) { diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildLogger.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildLogger.cs index b4571229..0d9af872 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildLogger.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildSystem/BuildLogger.cs @@ -48,7 +48,7 @@ namespace YooAsset.Editor if (File.Exists(_logFilePath)) File.Delete(_logFilePath); - FileUtility.CreateFileDirectory(_logFilePath); + FileUtility.EnsureFileDirectory(_logFilePath); File.WriteAllText(_logFilePath, _logBuilder.ToString(), Encoding.UTF8); _logBuilder.Clear(); } diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs index e191d251..511e40c1 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs @@ -162,7 +162,7 @@ namespace YooAsset.Editor EditorConnection.instance.UnregisterConnection(OnHandleConnectionEvent); EditorConnection.instance.UnregisterDisconnection(OnHandleDisconnectionEvent); EditorConnection.instance.Unregister(DiagnosticSystemDefine.PlayerToEditorMessageId, OnHandlePlayerMessage); - MockEditorConnection.Instance.Unregister(DiagnosticSystemDefine.PlayerToEditorMessageId); + MockEditorConnection.Instance.Unregister(DiagnosticSystemDefine.PlayerToEditorMessageId, OnHandlePlayerMessage); _playerSessions.Clear(); } public void Update() diff --git a/Assets/YooAsset/Runtime/AsyncOperation/AsyncOperationBase.cs b/Assets/YooAsset/Runtime/AsyncOperation/AsyncOperationBase.cs index 86fe0a45..1e9dad77 100644 --- a/Assets/YooAsset/Runtime/AsyncOperation/AsyncOperationBase.cs +++ b/Assets/YooAsset/Runtime/AsyncOperation/AsyncOperationBase.cs @@ -78,7 +78,7 @@ namespace YooAsset public float Progress { get; protected set; } /// - /// 任务逻辑是否完成(Status为Succeed、Failed或Aborted) + /// 任务逻辑是否完成(Status为Succeeded、Failed或Aborted) /// public bool IsDone { @@ -102,7 +102,7 @@ namespace YooAsset { try { - //注意:任务已完成,立即调用回调 + // 注意:任务已完成,立即调用回调 value.Invoke(this); } catch (Exception ex) @@ -162,7 +162,7 @@ namespace YooAsset /// internal virtual void InternalWaitForCompletion() { - throw new YooInternalException($"InternalWaitForCompletion not implemented : {this.GetType().Name}"); + throw new YooInternalException($"InternalWaitForCompletion() is not implemented: {this.GetType().Name}"); } /// @@ -183,17 +183,17 @@ namespace YooAsset #if UNITY_EDITOR || DEBUG if (child == null) - throw new YooInternalException("The child node is null."); + throw new YooInternalException("Child operation is null."); if (ReferenceEquals(child, this)) - throw new YooInternalException("The child node cannot be itself."); + throw new YooInternalException("Cannot add operation as its own child."); if (_children.Contains(child)) - throw new YooInternalException($"The child node {child.GetType().Name} already exists."); + throw new YooInternalException($"Child operation {child.GetType().Name} already exists."); // 禁止形成环依赖 if (WouldCreateCycle(child)) - throw new YooInternalException($"AddChildOperation would create a cycle : {this.GetType().Name} -> {child.GetType().Name}"); + throw new YooInternalException($"Adding {child.GetType().Name} would create a circular dependency with {this.GetType().Name}."); #endif _children.Add(child); @@ -209,10 +209,10 @@ namespace YooAsset #if UNITY_EDITOR || DEBUG if (child == null) - throw new YooInternalException("The child node is null."); + throw new YooInternalException("Child operation is null."); if (_children.Contains(child) == false) - throw new YooInternalException($"The child node {child.GetType().Name} not exists."); + throw new YooInternalException($"Child operation {child.GetType().Name} does not exist."); #endif _children.Remove(child); @@ -247,7 +247,7 @@ namespace YooAsset { Status = EOperationStatus.Failed; Error = ex.ToString(); - YooLogger.Error($"Exception in {this.GetType().Name}.InternalStart : {ex}"); + YooLogger.Error($"Exception in {this.GetType().Name}.InternalStart: {ex}"); } } } @@ -273,7 +273,7 @@ namespace YooAsset { Status = EOperationStatus.Failed; Error = ex.ToString(); - YooLogger.Error($"Exception in {this.GetType().Name}.InternalUpdate : {ex}"); + YooLogger.Error($"Exception in {this.GetType().Name}.InternalUpdate: {ex}"); } } @@ -300,11 +300,11 @@ namespace YooAsset { InternalAbort(); Status = EOperationStatus.Aborted; - Error = "user abort"; + Error = "Aborted by user"; YooLogger.Warning($"Async operation {this.GetType().Name} has been aborted."); } - //注意:强制收尾,确保Task能完成 + // 注意:强制收尾,确保Task能完成 FinishOperation(); } @@ -397,7 +397,7 @@ namespace YooAsset if (IsDone) break; - // 注意: 短暂休眠避免完全占用CPU资源 + // 注意:短暂休眠避免完全占用CPU资源 System.Threading.Thread.Sleep(sleepMS); } } @@ -407,7 +407,7 @@ namespace YooAsset /// public void WaitForCompletion() { - //注意:防止异步操作被挂起陷入无限死循环! + // 注意:防止异步操作被挂起陷入无限死循环 if (Status == EOperationStatus.None) { StartOperation(); @@ -423,11 +423,11 @@ namespace YooAsset if (IsDone == false) { Status = EOperationStatus.Failed; - Error = $"Operation {this.GetType().Name} failed to wait for async complete."; + Error = $"Operation {this.GetType().Name} failed to wait for completion."; YooLogger.Error(Error); } - //注意:强制收尾,确保Task能完成 + // 注意:强制收尾,确保Task能完成 FinishOperation(); } } diff --git a/Assets/YooAsset/Runtime/AsyncOperation/AsyncOperationSystem.cs b/Assets/YooAsset/Runtime/AsyncOperation/AsyncOperationSystem.cs index a55dc313..a727ec63 100644 --- a/Assets/YooAsset/Runtime/AsyncOperation/AsyncOperationSystem.cs +++ b/Assets/YooAsset/Runtime/AsyncOperation/AsyncOperationSystem.cs @@ -68,7 +68,7 @@ namespace YooAsset if (_maxTimeSlice == long.MaxValue) return false; - // 注意 : 单次调用开销约1微秒 + // 注意:单次调用开销约1微秒 return _stopwatch.ElapsedMilliseconds - _frameStartTime >= _maxTimeSlice; } } @@ -265,7 +265,7 @@ namespace YooAsset throw new YooInternalException("Package name is null or empty."); if (_isInitialized == false) - throw new YooInternalException($"{nameof(AsyncOperationSystem)} not initialized."); + throw new YooInternalException($"{nameof(AsyncOperationSystem)} is not initialized."); } #endregion } diff --git a/Assets/YooAsset/Runtime/DiagnosticSystem/DiagnosticBehaviour.cs b/Assets/YooAsset/Runtime/DiagnosticSystem/DiagnosticBehaviour.cs index e4717ed6..a7d23349 100644 --- a/Assets/YooAsset/Runtime/DiagnosticSystem/DiagnosticBehaviour.cs +++ b/Assets/YooAsset/Runtime/DiagnosticSystem/DiagnosticBehaviour.cs @@ -1,4 +1,4 @@ -using System; +using System; using UnityEngine; using UnityEngine.Networking.PlayerConnection; @@ -39,7 +39,7 @@ namespace YooAsset private void OnDisable() { #if UNITY_EDITOR - MockPlayerConnection.Instance.Unregister(DiagnosticSystemDefine.EditorToPlayerMessageId); + MockPlayerConnection.Instance.Unregister(DiagnosticSystemDefine.EditorToPlayerMessageId, HandleEditorMessage); #else PlayerConnection.instance.Unregister(DiagnosticSystemDefine.EditorToPlayerMessageId, HandleEditorMessage); #endif diff --git a/Assets/YooAsset/Runtime/DiagnosticSystem/DiagnosticReport/DiagnosticOperationInfo.cs b/Assets/YooAsset/Runtime/DiagnosticSystem/DiagnosticReport/DiagnosticOperationInfo.cs index baa49bc5..c1e0b5f8 100644 --- a/Assets/YooAsset/Runtime/DiagnosticSystem/DiagnosticReport/DiagnosticOperationInfo.cs +++ b/Assets/YooAsset/Runtime/DiagnosticSystem/DiagnosticReport/DiagnosticOperationInfo.cs @@ -47,7 +47,7 @@ namespace YooAsset /// /// 子任务列表 - /// TODO : Serialization depth limit 10 exceeded + /// TODO:序列化深度限制为10层 /// public List Children; diff --git a/Assets/YooAsset/Runtime/DiagnosticSystem/MockEditorConnection.cs b/Assets/YooAsset/Runtime/DiagnosticSystem/MockEditorConnection.cs index 876e3de4..e93b3671 100644 --- a/Assets/YooAsset/Runtime/DiagnosticSystem/MockEditorConnection.cs +++ b/Assets/YooAsset/Runtime/DiagnosticSystem/MockEditorConnection.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using UnityEngine.Events; using UnityEngine.Networking.PlayerConnection; @@ -63,7 +63,8 @@ namespace YooAsset /// 注销消息处理回调 /// /// 消息标识符 - public void Unregister(Guid messageID) + /// 要注销的回调函数 + public void Unregister(Guid messageID, UnityAction callback) { if (_messageHandlers.ContainsKey(messageID)) _messageHandlers.Remove(messageID); diff --git a/Assets/YooAsset/Runtime/DiagnosticSystem/MockPlayerConnection.cs b/Assets/YooAsset/Runtime/DiagnosticSystem/MockPlayerConnection.cs index 166576e4..e463faf8 100644 --- a/Assets/YooAsset/Runtime/DiagnosticSystem/MockPlayerConnection.cs +++ b/Assets/YooAsset/Runtime/DiagnosticSystem/MockPlayerConnection.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using UnityEngine.Events; using UnityEngine.Networking.PlayerConnection; @@ -63,7 +63,8 @@ namespace YooAsset /// 注销消息处理回调 /// /// 消息标识符 - public void Unregister(Guid messageID) + /// 要注销的回调函数 + public void Unregister(Guid messageID, UnityAction callback) { if (_messageHandlers.ContainsKey(messageID)) _messageHandlers.Remove(messageID); diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadRequestArgs.cs b/Assets/YooAsset/Runtime/DownloadSystem/DownloadRequestArgs.cs index 710f1d23..c76ab455 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadRequestArgs.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/DownloadRequestArgs.cs @@ -14,7 +14,7 @@ namespace YooAsset /// /// 请求地址 /// - public readonly string URL; + public readonly string Url; /// /// 响应的超时时间(单位:秒) @@ -91,7 +91,7 @@ namespace YooAsset bool removeFileOnAbort = true, long resumeOffset = 0) { - URL = url; + Url = url; SavePath = savePath; Timeout = timeout; WatchdogTimeout = watchdogTimeout; @@ -104,6 +104,8 @@ namespace YooAsset /// /// 添加请求头数据 /// + /// 请求头名称(如 "Authorization"、"User-Agent") + /// 请求头值 public void AddRequestHeader(string name, string value) { if (Headers == null) @@ -124,7 +126,7 @@ namespace YooAsset /// /// 请求地址 /// - public readonly string URL; + public readonly string Url; /// /// 响应的超时时间(单位:秒) @@ -164,7 +166,7 @@ namespace YooAsset /// 看门狗超时时间(秒),0 表示禁用 public DownloadDataRequestArgs(string url, int timeout, int watchdogTimeout) { - URL = url; + Url = url; Timeout = timeout; WatchdogTimeout = watchdogTimeout; Headers = null; @@ -173,6 +175,8 @@ namespace YooAsset /// /// 添加请求头数据 /// + /// 请求头名称(如 "Authorization"、"User-Agent") + /// 请求头值 public void AddRequestHeader(string name, string value) { if (Headers == null) @@ -193,7 +197,7 @@ namespace YooAsset /// /// 请求地址 /// - public readonly string URL; + public readonly string Url; /// /// 响应的超时时间(单位:秒) @@ -232,7 +236,7 @@ namespace YooAsset /// /// Unity CRC 校验值 /// - public readonly uint UnityCRC; + public readonly uint UnityCrc; /// /// 自定义请求头(可选) @@ -260,18 +264,20 @@ namespace YooAsset string fileHash = null, uint unityCrc = 0) { - URL = url; + Url = url; Timeout = timeout; WatchdogTimeout = watchdogTimeout; DisableUnityWebCache = disableUnityWebCache; FileHash = fileHash; - UnityCRC = unityCrc; + UnityCrc = unityCrc; Headers = null; } /// /// 添加请求头数据 /// + /// 请求头名称(如 "Authorization"、"User-Agent") + /// 请求头值 public void AddRequestHeader(string name, string value) { if (Headers == null) @@ -286,12 +292,12 @@ namespace YooAsset /// /// 用于编辑器模式下模拟下载进度,不进行实际网络请求。 /// - internal struct DownloadSimulateRequestArgs + internal struct SimulateDownloadRequestArgs { /// /// 请求地址(仅用于标识) /// - public readonly string URL; + public readonly string Url; /// /// 模拟的文件大小(字节) @@ -312,9 +318,9 @@ namespace YooAsset /// 请求地址(仅用于标识) /// 模拟的文件大小(字节) /// 模拟的下载速度(字节/秒),默认 1MB/s - public DownloadSimulateRequestArgs(string url, long fileSize, long downloadSpeed = 1024 * 1024) + public SimulateDownloadRequestArgs(string url, long fileSize, long downloadSpeed = 1024 * 1024) { - URL = url; + Url = url; FileSize = fileSize; DownloadSpeed = downloadSpeed > 0 ? downloadSpeed : 1024 * 1024; } diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemTools.cs b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemTools.cs index 145aad0c..4a87a9e1 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemTools.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemTools.cs @@ -14,7 +14,7 @@ namespace YooAsset /// /// 本地文件路径 /// 可用于 UnityWebRequest 的文件协议 URL - public static string ToLocalURL(string path) + public static string ToLocalUrl(string path) { string url; @@ -23,6 +23,8 @@ namespace YooAsset // 说明:iPhone和iPod对应的是iOS系统。 // 说明:iPad对应的是iPadOS系统。 // 说明:AppleTV对应的是tvOS系统。 + // TODO 安卓平台未考虑外部存储器 + // TODO Linux平台确认路径正确 #if UNITY_EDITOR_OSX url = StringUtility.Format("file://{0}", path); #elif UNITY_EDITOR_WIN @@ -75,7 +77,7 @@ namespace YooAsset /// /// 要判断的 URL /// 如果是本地文件 URL 返回 true,否则返回 false - public static bool IsLocalFileURL(string url) + public static bool IsLocalFileUrl(string url) { //TODO UNITY_STANDALONE_OSX平台目前无法确定 diff --git a/Assets/YooAsset/Runtime/DownloadSystem/EDownloadRequestStatus.cs b/Assets/YooAsset/Runtime/DownloadSystem/EDownloadRequestStatus.cs index 357ad62b..f3dd334b 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/EDownloadRequestStatus.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/EDownloadRequestStatus.cs @@ -19,7 +19,7 @@ namespace YooAsset /// /// 已成功 /// - Succeed, + Succeeded, /// /// 已失败 diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Interfaces/IDownloadBackend.cs b/Assets/YooAsset/Runtime/DownloadSystem/Interfaces/IDownloadBackend.cs index 09bd7138..d2d2aa75 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Interfaces/IDownloadBackend.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Interfaces/IDownloadBackend.cs @@ -73,6 +73,6 @@ namespace YooAsset /// /// 模拟下载参数 /// 模拟下载请求实例 - IDownloadFileRequest CreateSimulateRequest(DownloadSimulateRequestArgs args); + IDownloadFileRequest CreateSimulateRequest(SimulateDownloadRequestArgs args); } } diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Interfaces/IDownloadRequest.cs b/Assets/YooAsset/Runtime/DownloadSystem/Interfaces/IDownloadRequest.cs index f7712ac6..527f4fdc 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Interfaces/IDownloadRequest.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Interfaces/IDownloadRequest.cs @@ -5,22 +5,16 @@ namespace YooAsset /// /// 可轮询的下载请求接口 /// - /// - /// 上层通常在每帧检查 IsDone 属性,完成后读取结果并调用 Dispose() 释放资源。 - /// internal interface IDownloadRequest : IDisposable { /// /// 请求地址 /// - string URL { get; } + string Url { get; } /// /// 是否完成(成功/失败/中止) /// - /// - /// 注意:访问此属性时会自动调用 PollingRequest() 进行轮询。 - /// bool IsDone { get; } /// @@ -65,11 +59,6 @@ namespace YooAsset /// void SendRequest(); - /// - /// 轮询请求 - /// - void PollingRequest(); - /// /// 中止请求 /// diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operations.meta similarity index 77% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Operations.meta index 82ba251e..f600c210 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler.meta +++ b/Assets/YooAsset/Runtime/DownloadSystem/Operations.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: bf9991076b60f0f459846f54b0ca6698 +guid: cc2d6a25257866e459a31ad41ea97d58 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheFileOperation.cs b/Assets/YooAsset/Runtime/DownloadSystem/Operations/DownloadFileBaseOperation.cs similarity index 72% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheFileOperation.cs rename to Assets/YooAsset/Runtime/DownloadSystem/Operations/DownloadFileBaseOperation.cs index 6c9a4c9b..18fd6595 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheFileOperation.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Operations/DownloadFileBaseOperation.cs @@ -1,17 +1,17 @@  namespace YooAsset { - internal abstract class DownloadAndCacheFileOperation : AsyncOperationBase + internal abstract class DownloadFileBaseOperation : AsyncOperationBase { /// - /// 引用计数 + /// 资源包对象 /// - public int RefCount { private set; get; } + public readonly PackageBundle Bundle; /// /// 下载地址 /// - public readonly string URL; + public readonly string Url; /// /// 下载进度 @@ -23,9 +23,15 @@ namespace YooAsset /// public long DownloadedBytes { get; protected set; } - public DownloadAndCacheFileOperation(string url) + /// + /// 引用计数 + /// + public int RefCount { private set; get; } + + public DownloadFileBaseOperation(PackageBundle bundle, string url) { - URL = url; + Bundle = bundle; + Url = url; } internal override string InternalGetDescription() { diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheFileOperation.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operations/DownloadFileBaseOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheFileOperation.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Operations/DownloadFileBaseOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadSchedulerOperation.cs b/Assets/YooAsset/Runtime/DownloadSystem/Operations/DownloadSchedulerOperation.cs similarity index 74% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadSchedulerOperation.cs rename to Assets/YooAsset/Runtime/DownloadSystem/Operations/DownloadSchedulerOperation.cs index ebb8f9ac..7680a16d 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadSchedulerOperation.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Operations/DownloadSchedulerOperation.cs @@ -11,9 +11,17 @@ namespace YooAsset /// internal class DownloadSchedulerOperation : AsyncOperationBase, IDisposable { - private readonly CacheFileSystem _fileSystem; - private readonly Dictionary _downloaders = new Dictionary(1000); + public struct SchedulerConfig + { + public string SchedulerName { get; set; } + public IDownloadBackend DownloadBackend { get; set; } + public int MaxConcurrency { get; set; } + public int MaxRequestPerFrame { get; set; } + } + + private readonly Dictionary _downloaders = new Dictionary(1000); private readonly List _removeList = new List(1000); + private readonly SchedulerConfig _config; /// /// 是否已暂停 @@ -36,13 +44,12 @@ namespace YooAsset } } - /// /// 构造下载中心 /// - public DownloadSchedulerOperation(CacheFileSystem fileSystem) + public DownloadSchedulerOperation(SchedulerConfig config) { - _fileSystem = fileSystem; + _config = config; } internal override void InternalStart() { @@ -50,7 +57,7 @@ namespace YooAsset internal override void InternalUpdate() { // 驱动下载后台 - _fileSystem.DownloadBackend.Update(); + _config.DownloadBackend.Update(); // 获取可移除的下载器集合 _removeList.Clear(); @@ -91,8 +98,8 @@ namespace YooAsset ActiveDownloadCount = GetProcessingOperationCount(); if (ActiveDownloadCount != _downloaders.Count) { - int maxConcurrency = _fileSystem.DownloadMaxConcurrency; - int maxRequestPerFrame = _fileSystem.DownloadMaxRequestPerFrame; + int maxConcurrency = _config.MaxConcurrency; + int maxRequestPerFrame = _config.MaxRequestPerFrame; if (ActiveDownloadCount < maxConcurrency) { int startCount = maxConcurrency - ActiveDownloadCount; @@ -115,7 +122,7 @@ namespace YooAsset } internal override string InternalGetDescription() { - return $"{_fileSystem.GetType().FullName}"; + return _config.SchedulerName; } /// @@ -132,36 +139,30 @@ namespace YooAsset } /// - /// 创建下载任务 + /// 尝试获取已经存在的下载器 /// - /// 资源包信息 - /// 下载地址 - /// 下载操作 - public DownloadAndCacheFileOperation DownloadAndCacheFileAsync(PackageBundle bundle, string url) + public DownloadFileBaseOperation TryGetDownloadFile(PackageBundle bundle) { - // 查询旧的下载器 if (_downloaders.TryGetValue(bundle.BundleGUID, out var oldDownloader)) { oldDownloader.Reference(); return oldDownloader; } + return null; + } - // 创建新的下载器 - DownloadAndCacheFileOperation newDownloader; - bool isRequestLocalFile = DownloadSystemTools.IsLocalFileURL(url); - if (isRequestLocalFile) - { - newDownloader = new DownloadAndCacheLocalFileOperation(_fileSystem, bundle, url); - } - else - { - newDownloader = new DownloadAndCacheRemoteFileOperation(_fileSystem, bundle, url); - } + /// + /// 添加新的下载器到调度中心 + /// + public void AddDownloadFile(DownloadFileBaseOperation downloadFileOp) + { + string bundleGUID = downloadFileOp.Bundle.BundleGUID; + if (_downloaders.ContainsKey(bundleGUID)) + throw new YooInternalException(); - AddChildOperation(newDownloader); - _downloaders.Add(bundle.BundleGUID, newDownloader); - newDownloader.Reference(); - return newDownloader; + AddChildOperation(downloadFileOp); + _downloaders.Add(bundleGUID, downloadFileOp); + downloadFileOp.Reference(); } /// diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadSchedulerOperation.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operations/DownloadSchedulerOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadSchedulerOperation.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Operations/DownloadSchedulerOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebBackend/UnityWebRequestBackend.cs b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebBackend/UnityWebRequestBackend.cs index 5e052294..f3a7bdd1 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebBackend/UnityWebRequestBackend.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebBackend/UnityWebRequestBackend.cs @@ -12,6 +12,9 @@ namespace YooAsset /// internal sealed class UnityWebRequestBackend : IDownloadBackend { + /// + /// 自定义 UnityWebRequest 创建器(可为 null) + /// private readonly UnityWebRequestCreator _webRequestCreator; /// @@ -102,9 +105,9 @@ namespace YooAsset /// /// 创建模拟下载请求 /// - public IDownloadFileRequest CreateSimulateRequest(DownloadSimulateRequestArgs args) + public IDownloadFileRequest CreateSimulateRequest(SimulateDownloadRequestArgs args) { - return new SimulateRequestFile(args); + return new SimulatedFileRequest(args); } } } diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/SimulateRequestFile.cs b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/SimulatedFileRequest.cs similarity index 78% rename from Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/SimulateRequestFile.cs rename to Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/SimulatedFileRequest.cs index 78287e81..5842e8ce 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/SimulateRequestFile.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/SimulatedFileRequest.cs @@ -9,10 +9,17 @@ namespace YooAsset /// 用于编辑器模式下模拟下载进度,不进行实际网络请求。 /// 根据配置的下载速度模拟进度变化。 /// - internal sealed class SimulateRequestFile : IDownloadFileRequest + internal sealed class SimulatedFileRequest : IDownloadFileRequest { - private readonly DownloadSimulateRequestArgs _args; - private double _lastTickTime; + /// + /// 模拟下载参数 + /// + private readonly SimulateDownloadRequestArgs _args; + + /// + /// 最近一次更新的时间戳(用于计算时间增量) + /// + private double _lastestUpdateTime; /// /// 文件保存路径(模拟下载不需要) @@ -26,7 +33,7 @@ namespace YooAsset /// /// 请求地址 /// - public string URL { get; } + public string Url { get; } /// /// 是否完成 @@ -35,8 +42,8 @@ namespace YooAsset { get { - PollingRequest(); - return Status == EDownloadRequestStatus.Succeed + PollRequest(); + return Status == EDownloadRequestStatus.Succeeded || Status == EDownloadRequestStatus.Failed || Status == EDownloadRequestStatus.Aborted; } @@ -72,10 +79,10 @@ namespace YooAsset /// 构造模拟下载器 /// /// 模拟下载参数 - public SimulateRequestFile(DownloadSimulateRequestArgs args) + public SimulatedFileRequest(SimulateDownloadRequestArgs args) { _args = args; - URL = args.URL; + Url = args.Url; Status = EDownloadRequestStatus.None; } @@ -87,36 +94,7 @@ namespace YooAsset if (Status == EDownloadRequestStatus.None) { Status = EDownloadRequestStatus.Running; - _lastTickTime = TimeUtility.RealtimeSinceStartup; - } - } - - /// - /// 轮询请求 - /// - public void PollingRequest() - { - if (Status != EDownloadRequestStatus.Running) - return; - - double currentTime = TimeUtility.RealtimeSinceStartup; - double deltaTime = currentTime - _lastTickTime; - _lastTickTime = currentTime; - - // 计算本帧下载的字节数 - long downloadBytes = (long)(_args.DownloadSpeed * deltaTime); - DownloadedBytes += downloadBytes; - - if (_args.FileSize > 0) - DownloadProgress = (float)DownloadedBytes / _args.FileSize; - - // 检查是否完成 - if (DownloadedBytes >= _args.FileSize) - { - HttpCode = 200; - DownloadProgress = 1f; - DownloadedBytes = _args.FileSize; - Status = EDownloadRequestStatus.Succeed; + _lastestUpdateTime = TimeUtility.RealtimeSinceStartup; } } @@ -137,5 +115,34 @@ namespace YooAsset public void Dispose() { } + + /// + /// 更新网络请求 + /// + private void PollRequest() + { + if (Status != EDownloadRequestStatus.Running) + return; + + double currentTime = TimeUtility.RealtimeSinceStartup; + double deltaTime = currentTime - _lastestUpdateTime; + _lastestUpdateTime = currentTime; + + // 计算本帧下载的字节数 + long downloadBytes = (long)(_args.DownloadSpeed * deltaTime); + DownloadedBytes += downloadBytes; + + if (_args.FileSize > 0) + DownloadProgress = (float)DownloadedBytes / _args.FileSize; + + // 检查是否完成 + if (DownloadedBytes >= _args.FileSize) + { + HttpCode = 200; + DownloadProgress = 1f; + DownloadedBytes = _args.FileSize; + Status = EDownloadRequestStatus.Succeeded; + } + } } } diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/SimulateRequestFile.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/SimulatedFileRequest.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/SimulateRequestFile.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/SimulatedFileRequest.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestAssetBundle.cs b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestAssetBundle.cs index cbe1c17d..f9d9d6c2 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestAssetBundle.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestAssetBundle.cs @@ -13,7 +13,14 @@ namespace YooAsset /// internal sealed class UnityWebRequestAssetBundle : UnityWebRequestBase, IDownloadAssetBundleRequest { + /// + /// AssetBundle 下载参数 + /// private readonly DownloadAssetBundleRequestArgs _args; + + /// + /// AssetBundle 下载处理器 + /// private DownloadHandlerAssetBundle _downloadHandler; /// @@ -27,7 +34,7 @@ namespace YooAsset /// AssetBundle 下载参数 /// UnityWebRequest 创建器(可选) public UnityWebRequestAssetBundle(DownloadAssetBundleRequestArgs args, UnityWebRequestCreator webRequestCreator) - : base(args.URL, webRequestCreator) + : base(args.Url, webRequestCreator) { _args = args; } @@ -38,7 +45,7 @@ namespace YooAsset protected override void CreateWebRequest() { _downloadHandler = CreateAssetBundleDownloadHandler(); - _webRequest = CreateGetRequest(URL); + _webRequest = CreateGetWebRequest(Url); _webRequest.downloadHandler = _downloadHandler; _webRequest.disposeDownloadHandlerOnDispose = true; ConfigureRequest(_args.Timeout, _args.WatchdogTimeout, _args.Headers); @@ -47,13 +54,13 @@ namespace YooAsset /// /// 请求成功时的回调 /// - protected override void OnRequestSucceed() + protected override void OnRequestSucceeded() { AssetBundle assetBundle = _downloadHandler.assetBundle; if (assetBundle == null) { Status = EDownloadRequestStatus.Failed; - Error = $"[{GetType().Name}] URL: {URL} - AssetBundle object is null"; + Error = $"[{GetType().Name}] Failed to load AssetBundle. URL: {Url}, Error: AssetBundle object is null"; } else { @@ -64,6 +71,10 @@ namespace YooAsset /// /// 创建 AssetBundle 下载处理器 /// + /// + /// 根据 DisableUnityWebCache 配置决定是否使用 Unity 内置缓存。 + /// 启用缓存时需要提供有效的 FileHash。 + /// private DownloadHandlerAssetBundle CreateAssetBundleDownloadHandler() { DownloadHandlerAssetBundle handler; @@ -71,17 +82,17 @@ namespace YooAsset if (_args.DisableUnityWebCache) { // 禁用 Unity 缓存 - handler = new DownloadHandlerAssetBundle(URL, _args.UnityCRC); + handler = new DownloadHandlerAssetBundle(Url, _args.UnityCrc); } else { if (string.IsNullOrEmpty(_args.FileHash)) - throw new YooInternalException("File hash is null or empty."); + throw new YooInternalException("FileHash is required when Unity web cache is enabled (DisableUnityWebCache = false)."); // 使用 Unity 缓存 // 说明:The file hash defining the version of the asset bundle. Hash128 fileHash = Hash128.Parse(_args.FileHash); - handler = new DownloadHandlerAssetBundle(URL, fileHash, _args.UnityCRC); + handler = new DownloadHandlerAssetBundle(Url, fileHash, _args.UnityCrc); } return handler; diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestBase.cs b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestBase.cs index 92790b40..8946c5ea 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestBase.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestBase.cs @@ -13,33 +13,54 @@ namespace YooAsset /// internal abstract class UnityWebRequestBase : IDownloadRequest { + /// + /// 自定义 UnityWebRequest 创建器 + /// private readonly UnityWebRequestCreator _webRequestCreator; + + /// + /// UnityWebRequest 实例 + /// protected UnityWebRequest _webRequest; - // 看门狗相关 + /// + /// 看门狗超时时间(秒) + /// private int _watchdogTimeout = 0; + + /// + /// 是否已被看门狗中止 + /// private bool _watchdogAborted = false; - private long _lastDownloadBytes = -1; - private double _lastDataReceivedTime; + + /// + /// 最近一次记录的下载字节数 + /// + private long _lastestDownloadBytes = -1; + + /// + /// 最近一次接收数据的时间 + /// + private double _lastestDataReceivedTime; #region 接口实现 /// /// 请求地址 /// - public string URL { get; } + public string Url { get; } /// /// 是否完成 /// /// - /// 每次调用都会主动轮询请求 PollingRequest + /// 每次访问此属性都会自动调用内部方法 UpdateRequest() 进行状态更新。 /// public bool IsDone { get { - PollingRequest(); - return Status == EDownloadRequestStatus.Succeed + PollRequest(); + return Status == EDownloadRequestStatus.Succeeded || Status == EDownloadRequestStatus.Failed || Status == EDownloadRequestStatus.Aborted; } @@ -78,7 +99,7 @@ namespace YooAsset /// UnityWebRequest 创建器(可选) protected UnityWebRequestBase(string url, UnityWebRequestCreator webRequestCreator) { - URL = url; + Url = url; _webRequestCreator = webRequestCreator; Status = EDownloadRequestStatus.None; } @@ -86,6 +107,10 @@ namespace YooAsset /// /// 发起请求 /// + /// + /// 仅在 Status 为 None 时生效,重复调用无效。 + /// 调用后 Status 变为 Running。 + /// public void SendRequest() { if (Status == EDownloadRequestStatus.None) @@ -99,7 +124,7 @@ namespace YooAsset if (_webRequest == null) { Status = EDownloadRequestStatus.Failed; - Error = $"[{GetType().Name}] Created web request is null."; + Error = $"[{GetType().Name}] CreateWebRequest() returned null"; } else { @@ -114,47 +139,13 @@ namespace YooAsset } } - /// - /// 轮询请求 - /// - public void PollingRequest() - { - if (Status != EDownloadRequestStatus.Running) - return; - - DownloadProgress = _webRequest.downloadProgress; - DownloadedBytes = (long)_webRequest.downloadedBytes; - - TickWatchdog(); - if (_webRequest.isDone == false) - return; - - HttpCode = _webRequest.responseCode; -#if UNITY_2020_3_OR_NEWER - bool isSuccess = _webRequest.result == UnityWebRequest.Result.Success; -#else - bool isSuccess = !_webRequest.isNetworkError && !_webRequest.isHttpError; -#endif - - if (isSuccess) - { - Status = EDownloadRequestStatus.Succeed; - OnRequestSucceed(); - } - else - { - Status = EDownloadRequestStatus.Failed; - Error = $"[{GetType().Name}] URL: {URL} - Error: {_webRequest.error}"; - OnRequestFailed(); - } - - // 完成后释放 - CleanupWebRequest(); - } - /// /// 中止请求 /// + /// + /// 可在任意状态调用,仅当 Status 为 None 或 Running 时生效。 + /// 调用后 Status 变为 Aborted。 + /// public void AbortRequest() { if (Status == EDownloadRequestStatus.None || Status == EDownloadRequestStatus.Running) @@ -182,7 +173,7 @@ namespace YooAsset /// /// 请求成功时的回调(子类可重写) /// - protected virtual void OnRequestSucceed() + protected virtual void OnRequestSucceeded() { } @@ -199,7 +190,7 @@ namespace YooAsset /// /// 请求地址 /// UnityWebRequest 实例 - protected UnityWebRequest CreateGetRequest(string requestUrl) + protected UnityWebRequest CreateGetWebRequest(string requestUrl) { if (_webRequestCreator != null) return _webRequestCreator.Invoke(requestUrl, UnityWebRequest.kHttpVerbGET); @@ -212,7 +203,7 @@ namespace YooAsset /// /// 请求地址 /// UnityWebRequest 实例 - protected UnityWebRequest CreateHeadRequest(string requestUrl) + protected UnityWebRequest CreateHeadWebRequest(string requestUrl) { if (_webRequestCreator != null) return _webRequestCreator.Invoke(requestUrl, UnityWebRequest.kHttpVerbHEAD); @@ -223,10 +214,13 @@ namespace YooAsset /// /// 配置通用请求参数 /// + /// 响应超时时间(秒),0 表示不应用超时 + /// 看门狗超时时间(秒),0 表示禁用 + /// 自定义请求头(可选) protected void ConfigureRequest(int timeout, int watchdogTimeout, Dictionary headers) { if (_webRequest == null) - throw new YooInternalException("Web request is null."); + throw new YooInternalException("Cannot configure request: UnityWebRequest object is null. Ensure CreateWebRequest() is called first."); // 设置看门狗超时时间 _watchdogTimeout = watchdogTimeout; @@ -246,9 +240,47 @@ namespace YooAsset } /// - /// 检测看门狗 + /// 更新网络请求 /// - private void TickWatchdog() + private void PollRequest() + { + if (Status != EDownloadRequestStatus.Running) + return; + + DownloadProgress = _webRequest.downloadProgress; + DownloadedBytes = (long)_webRequest.downloadedBytes; + + UpdateWatchdog(); + if (_webRequest.isDone == false) + return; + + HttpCode = _webRequest.responseCode; +#if UNITY_2020_3_OR_NEWER + bool isSuccess = _webRequest.result == UnityWebRequest.Result.Success; +#else + bool isSuccess = !_webRequest.isNetworkError && !_webRequest.isHttpError; +#endif + + if (isSuccess) + { + Status = EDownloadRequestStatus.Succeeded; + OnRequestSucceeded(); + } + else + { + Status = EDownloadRequestStatus.Failed; + Error = $"[{GetType().Name}] Request failed. URL: {Url}, Error: {_webRequest.error}"; + OnRequestFailed(); + } + + // 完成后释放 + CleanupWebRequest(); + } + + /// + /// 更新看门狗机制 + /// + private void UpdateWatchdog() { if (_watchdogTimeout == 0) return; @@ -256,14 +288,14 @@ namespace YooAsset return; double realtimeSinceStartup = TimeUtility.RealtimeSinceStartup; - if (DownloadedBytes != _lastDownloadBytes) + if (DownloadedBytes != _lastestDownloadBytes) { - _lastDownloadBytes = DownloadedBytes; - _lastDataReceivedTime = realtimeSinceStartup; + _lastestDownloadBytes = DownloadedBytes; + _lastestDataReceivedTime = realtimeSinceStartup; } else { - double deltaTime = realtimeSinceStartup - _lastDataReceivedTime; + double deltaTime = realtimeSinceStartup - _lastestDataReceivedTime; if (deltaTime > _watchdogTimeout) { _watchdogAborted = true; diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestBytes.cs b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestBytes.cs index 9cc25068..9072bcc1 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestBytes.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestBytes.cs @@ -11,6 +11,9 @@ namespace YooAsset /// internal sealed class UnityWebRequestBytes : UnityWebRequestBase, IDownloadBytesRequest { + /// + /// 数据下载参数 + /// private readonly DownloadDataRequestArgs _args; /// @@ -24,7 +27,7 @@ namespace YooAsset /// 数据下载参数 /// UnityWebRequest 创建器(可选) public UnityWebRequestBytes(DownloadDataRequestArgs args, UnityWebRequestCreator webRequestCreator) - : base(args.URL, webRequestCreator) + : base(args.Url, webRequestCreator) { _args = args; } @@ -35,7 +38,7 @@ namespace YooAsset protected override void CreateWebRequest() { var handler = new DownloadHandlerBuffer(); - _webRequest = CreateGetRequest(URL); + _webRequest = CreateGetWebRequest(Url); _webRequest.downloadHandler = handler; _webRequest.disposeDownloadHandlerOnDispose = true; ConfigureRequest(_args.Timeout, _args.WatchdogTimeout, _args.Headers); @@ -44,7 +47,7 @@ namespace YooAsset /// /// 请求成功时的回调 /// - protected override void OnRequestSucceed() + protected override void OnRequestSucceeded() { Result = _webRequest.downloadHandler.data; } diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestFile.cs b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestFile.cs index 602b3a9f..66bd362c 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestFile.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestFile.cs @@ -11,6 +11,9 @@ namespace YooAsset /// internal sealed class UnityWebRequestFile : UnityWebRequestBase, IDownloadFileRequest { + /// + /// 文件下载参数 + /// private readonly DownloadFileRequestArgs _args; /// @@ -27,7 +30,7 @@ namespace YooAsset /// 文件下载参数 /// UnityWebRequest 创建器(可选) public UnityWebRequestFile(DownloadFileRequestArgs args, UnityWebRequestCreator webRequestCreator) - : base(args.URL, webRequestCreator) + : base(args.Url, webRequestCreator) { _args = args; } @@ -40,7 +43,7 @@ namespace YooAsset var handler = new DownloadHandlerFile(_args.SavePath, _args.AppendToFile); handler.removeFileOnAbort = _args.RemoveFileOnAbort; - _webRequest = CreateGetRequest(URL); + _webRequest = CreateGetWebRequest(Url); _webRequest.downloadHandler = handler; _webRequest.disposeDownloadHandlerOnDispose = true; diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestHead.cs b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestHead.cs index de8a1e81..dffe449e 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestHead.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestHead.cs @@ -13,8 +13,17 @@ namespace YooAsset /// internal sealed class UnityWebRequestHead : UnityWebRequestBase, IDownloadHeadRequest { - // 注意:缓存响应头(因为 WebRequest 释放后无法获取) + /// + /// 缓存的响应头(请求完成后从 WebRequest 复制) + /// + /// + /// WebRequest 释放后无法获取响应头,因此需要提前缓存。 + /// private Dictionary _cachedResponseHeaders; + + /// + /// 数据下载参数 + /// private readonly DownloadDataRequestArgs _args; /// @@ -70,7 +79,7 @@ namespace YooAsset /// 数据下载参数 /// UnityWebRequest 创建器(可选) public UnityWebRequestHead(DownloadDataRequestArgs args, UnityWebRequestCreator webRequestCreator) - : base(args.URL, webRequestCreator) + : base(args.Url, webRequestCreator) { _args = args; } @@ -98,7 +107,7 @@ namespace YooAsset /// protected override void CreateWebRequest() { - _webRequest = CreateHeadRequest(URL); + _webRequest = CreateHeadWebRequest(Url); _webRequest.downloadHandler = null; // HEAD 请求不需要 DownloadHandler ConfigureRequest(_args.Timeout, _args.WatchdogTimeout, _args.Headers); } @@ -106,7 +115,7 @@ namespace YooAsset /// /// 请求成功时的回调 /// - protected override void OnRequestSucceed() + protected override void OnRequestSucceeded() { var headers = _webRequest.GetResponseHeaders(); if (headers != null) diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestText.cs b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestText.cs index b054e2a0..3134ed4b 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestText.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Services/UnityWebRequest/UnityWebRequestText.cs @@ -11,6 +11,9 @@ namespace YooAsset /// internal sealed class UnityWebRequestText : UnityWebRequestBase, IDownloadTextRequest { + /// + /// 数据下载参数 + /// private readonly DownloadDataRequestArgs _args; /// @@ -24,7 +27,7 @@ namespace YooAsset /// 数据下载参数 /// UnityWebRequest 创建器(可选) public UnityWebRequestText(DownloadDataRequestArgs args, UnityWebRequestCreator webRequestCreator) - : base(args.URL, webRequestCreator) + : base(args.Url, webRequestCreator) { _args = args; } @@ -35,7 +38,7 @@ namespace YooAsset protected override void CreateWebRequest() { var handler = new DownloadHandlerBuffer(); - _webRequest = CreateGetRequest(URL); + _webRequest = CreateGetWebRequest(Url); _webRequest.downloadHandler = handler; _webRequest.disposeDownloadHandlerOnDispose = true; ConfigureRequest(_args.Timeout, _args.WatchdogTimeout, _args.Headers); @@ -44,7 +47,7 @@ namespace YooAsset /// /// 请求成功时的回调 /// - protected override void OnRequestSucceed() + protected override void OnRequestSucceeded() { Result = _webRequest.downloadHandler.text; } diff --git a/Assets/YooAsset/Runtime/FileCache/Interfaces/IFileCache.cs b/Assets/YooAsset/Runtime/FileCache/Interfaces/IFileCache.cs index 8935c688..db0a9ba1 100644 --- a/Assets/YooAsset/Runtime/FileCache/Interfaces/IFileCache.cs +++ b/Assets/YooAsset/Runtime/FileCache/Interfaces/IFileCache.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; namespace YooAsset @@ -5,10 +6,8 @@ namespace YooAsset /// /// 文件缓存系统接口 /// - /// 缓存记录类型 - internal interface IFileCache where TEntry : ICacheEntry + internal interface IFileCache : IDisposable { - #region 状态属性 /// /// 包裹名称 /// @@ -24,44 +23,45 @@ namespace YooAsset /// bool IsReadOnly { get; } + /// + /// 缓存文件数量 + /// + int FileCount { get; } + /// /// 已占用空间(字节) /// long SpaceOccupied { get; } - #endregion - #region 异步操作 - /// - /// 初始化缓存 - /// - FCInitializeOperation InitializeAsync(FCInitializeOptions options); /// - /// 存储缓存文件 + /// 初始化文件缓存系统 /// - FCStoreCacheOperation StoreCacheAsync(FCStoreCacheOptions options); + FCInitializeOperation InitializeAsync(); + + /// + /// 写入缓存文件 + /// + FCWriteCacheOperation WriteCacheAsync(WriteCacheOptions options); /// /// 清理缓存文件 /// - FCClearCacheOperation ClearCacheAsync(FCClearCacheOptions options); - #endregion + FCClearCacheOperation ClearCacheAsync(ClearCacheOptions options); + + /// + /// 验证缓存文件 + /// + FCVerifyCacheOperation VerifyCacheAsync(VerifyCacheOptions options); + + /// + /// 加载资源包 + /// + FCLoadBundleOperation LoadBundleAsync(LoadBundleOptions options); - #region 查询方法 /// /// 是否已缓存指定 Bundle /// bool IsCached(string bundleGUID); - - /// - /// 获取缓存记录 - /// - TEntry GetEntry(string bundleGUID); - - /// - /// 获取所有的缓存记录 - /// - IReadOnlyCollection GetAllEntries(); - #endregion } } diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOperation.cs b/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOperation.cs index a96e244f..32ef1a50 100644 --- a/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOperation.cs +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOperation.cs @@ -1,78 +1,36 @@ -using System.Collections.Generic; -using System.Linq; namespace YooAsset { - internal class FCClearCacheOperation : AsyncOperationBase + internal abstract class FCClearCacheOperation : AsyncOperationBase { - private enum ESteps + } + + internal class FCClearCacheCompleteOperation : FCClearCacheOperation + { + private readonly string _error; + + public FCClearCacheCompleteOperation() { - None, - CheckOptions, - ClearCache, - Done, + _error = null; } - - private BundleCache _cache; - private FCClearCacheOptions _options; - private int _clearFileTotalCount; - private List _bundleGUIDs; - private ESteps _steps = ESteps.None; - - public FCClearCacheOperation(BundleCache cache, FCClearCacheOptions options) + public FCClearCacheCompleteOperation(string error) { - _cache = cache; - _options = options; + _error = error; } internal override void InternalStart() { - _steps = ESteps.CheckOptions; + if (string.IsNullOrEmpty(_error)) + { + Status = EOperationStatus.Succeeded; + } + else + { + Status = EOperationStatus.Failed; + Error = _error; + } } internal override void InternalUpdate() { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.CheckOptions) - { - if (_options.BundleGUIDs == null || _options.BundleGUIDs.Count == 0) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - return; - } - - _bundleGUIDs = _options.BundleGUIDs.ToList(); - _clearFileTotalCount = _options.BundleGUIDs.Count; - _steps = ESteps.ClearCache; - } - - if (_steps == ESteps.ClearCache) - { - for (int i = _bundleGUIDs.Count - 1; i >= 0; i--) - { - string bundleGUID = _bundleGUIDs[i]; - _cache.RemoveEntry(bundleGUID); - _bundleGUIDs.RemoveAt(i); - if (IsBusy) - break; - } - - if (_clearFileTotalCount == 0) - Progress = 1.0f; - else - Progress = 1.0f - ((float)_bundleGUIDs.Count / _clearFileTotalCount); - - if (_bundleGUIDs.Count == 0) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - } - } - } - internal override void InternalWaitForCompletion() - { - ExecuteBatch(); } } } diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOperation.cs.meta index efeb6639..215db836 100644 --- a/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOperation.cs.meta +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: fb3347395a55d3048bcec202aca0e4a7 +guid: 0df121ea04074ca46b7fbe7932a5d452 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOptions.cs b/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOptions.cs deleted file mode 100644 index 0b6a741a..00000000 --- a/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOptions.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; - -namespace YooAsset -{ - internal struct FCClearCacheOptions - { - /// - /// 清理指定缓存列表 - /// - public IReadOnlyList BundleGUIDs { get; set; } - } -} diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOperation.cs b/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOperation.cs index ec9472ee..bb57ae32 100644 --- a/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOperation.cs +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOperation.cs @@ -1,79 +1,7 @@ namespace YooAsset { - internal class FCInitializeOperation : AsyncOperationBase + internal abstract class FCInitializeOperation : AsyncOperationBase { - private enum ESteps - { - None, - SearchCacheFiles, - VerifyCacheFiles, - Done, - } - - private readonly BundleCache _cache; - private readonly FCInitializeOptions _options; - private SearchCacheFilesOperation _searchCacheFilesOp; - private VerifyCacheFilesOperation _verifyCacheFilesOp; - private ESteps _steps = ESteps.None; - - public FCInitializeOperation(BundleCache cache, FCInitializeOptions options) - { - _cache = cache; - _options = options; - } - internal override void InternalStart() - { - _steps = ESteps.SearchCacheFiles; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.SearchCacheFiles) - { - if (_searchCacheFilesOp == null) - { - _searchCacheFilesOp = new SearchCacheFilesOperation(_cache); - _searchCacheFilesOp.StartOperation(); - AddChildOperation(_searchCacheFilesOp); - } - - _searchCacheFilesOp.UpdateOperation(); - Progress = _searchCacheFilesOp.Progress; - if (_searchCacheFilesOp.IsDone == false) - return; - - _steps = ESteps.VerifyCacheFiles; - } - - if (_steps == ESteps.VerifyCacheFiles) - { - if (_verifyCacheFilesOp == null) - { - _verifyCacheFilesOp = new VerifyCacheFilesOperation(_cache, _options.FileVerifyLevel, _options.FileVerifyMaxConcurrency, _searchCacheFilesOp.Result); - _verifyCacheFilesOp.StartOperation(); - AddChildOperation(_verifyCacheFilesOp); - } - - _verifyCacheFilesOp.UpdateOperation(); - Progress = _verifyCacheFilesOp.Progress; - if (_verifyCacheFilesOp.IsDone == false) - return; - - if (_verifyCacheFilesOp.Status == EOperationStatus.Succeeded) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _verifyCacheFilesOp.Error; - } - } - } } } diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOperation.cs.meta index a9820a38..3562f101 100644 --- a/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOperation.cs.meta +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9be990c57fe162845ba3893188a68f8b +guid: 22422599c3cb80342ad546cbc4b8adc5 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOptions.cs b/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOptions.cs deleted file mode 100644 index 00b7f944..00000000 --- a/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOptions.cs +++ /dev/null @@ -1,16 +0,0 @@ - -namespace YooAsset -{ - internal struct FCInitializeOptions - { - /// - /// 文件校验最大并发数 - /// - public int FileVerifyMaxConcurrency { get; set; } - - /// - /// 文件校验级别 - /// - public EFileVerifyLevel FileVerifyLevel { get; set; } - } -} diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileCache/Operations/FCLoadBundleOperation.cs new file mode 100644 index 00000000..ca1e9a10 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCLoadBundleOperation.cs @@ -0,0 +1,38 @@ + +namespace YooAsset +{ + internal abstract class FCLoadBundleOperation : AsyncOperationBase + { + public IBundleResult BundleResult { get; protected set; } + + /// + /// 检查文件路径是否支持 FileIO 读取 + /// + protected bool IsSupportFileIO(string filePath) + { + if (string.IsNullOrEmpty(filePath)) + return true; + if (filePath.StartsWith("jar:") || filePath.StartsWith("content:")) + return false; + return true; + } + } + + internal sealed class FCLoadBundleErrorOperation : FCLoadBundleOperation + { + private readonly string _error; + + internal FCLoadBundleErrorOperation(string error) + { + _error = error; + } + internal override void InternalStart() + { + Status = EOperationStatus.Failed; + Error = _error; + } + internal override void InternalUpdate() + { + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOptions.cs.meta b/Assets/YooAsset/Runtime/FileCache/Operations/FCLoadBundleOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOptions.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Operations/FCLoadBundleOperation.cs.meta index b889face..317e630c 100644 --- a/Assets/YooAsset/Runtime/FileCache/Operations/FCInitializeOptions.cs.meta +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCLoadBundleOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 75f6c6588c154e145b09fa36cc6f2602 +guid: f80086e0af509ae47829d80ca2037f5c MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadBundleOptions.cs b/Assets/YooAsset/Runtime/FileCache/Operations/FCLoadBundleOptions.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadBundleOptions.cs rename to Assets/YooAsset/Runtime/FileCache/Operations/FCLoadBundleOptions.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadBundleOptions.cs.meta b/Assets/YooAsset/Runtime/FileCache/Operations/FCLoadBundleOptions.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadBundleOptions.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Operations/FCLoadBundleOptions.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCVerifyCacheOperation.cs b/Assets/YooAsset/Runtime/FileCache/Operations/FCVerifyCacheOperation.cs new file mode 100644 index 00000000..f2312a5b --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCVerifyCacheOperation.cs @@ -0,0 +1,36 @@ + +namespace YooAsset +{ + internal abstract class FCVerifyCacheOperation : AsyncOperationBase + { + } + + internal class FCVerifyCacheCompleteOperation : FCVerifyCacheOperation + { + private readonly string _error; + + public FCVerifyCacheCompleteOperation() + { + _error = null; + } + public FCVerifyCacheCompleteOperation(string error) + { + _error = error; + } + internal override void InternalStart() + { + if (string.IsNullOrEmpty(_error)) + { + Status = EOperationStatus.Succeeded; + } + else + { + Status = EOperationStatus.Failed; + Error = _error; + } + } + internal override void InternalUpdate() + { + } + } +} diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCStoreCacheOptions.cs.meta b/Assets/YooAsset/Runtime/FileCache/Operations/FCVerifyCacheOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/FileCache/Operations/FCStoreCacheOptions.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Operations/FCVerifyCacheOperation.cs.meta index 6d28f147..ed047bec 100644 --- a/Assets/YooAsset/Runtime/FileCache/Operations/FCStoreCacheOptions.cs.meta +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCVerifyCacheOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: cbe6c6f462ef0c9429568f9d1df559f6 +guid: 920884f1ed1f59948aeb0fe0acdab027 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCVerifyCacheOptions.cs b/Assets/YooAsset/Runtime/FileCache/Operations/FCVerifyCacheOptions.cs new file mode 100644 index 00000000..e9279bdc --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCVerifyCacheOptions.cs @@ -0,0 +1,16 @@ + +namespace YooAsset +{ + internal struct VerifyCacheOptions + { + /// + /// 要验证的资源包 + /// + public PackageBundle Bundle { get; set; } + + /// + /// 失败后直接移除缓存 + /// + public bool FailedDeleteCache { get; set; } + } +} diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOptions.cs.meta b/Assets/YooAsset/Runtime/FileCache/Operations/FCVerifyCacheOptions.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOptions.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Operations/FCVerifyCacheOptions.cs.meta index 03927c30..b26191fa 100644 --- a/Assets/YooAsset/Runtime/FileCache/Operations/FCClearCacheOptions.cs.meta +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCVerifyCacheOptions.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 03f8c5e4c7af7df4387f56d045d8d357 +guid: b3daf736aed95a848a15feb00d81ed0f MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCWriteCacheOperation.cs b/Assets/YooAsset/Runtime/FileCache/Operations/FCWriteCacheOperation.cs new file mode 100644 index 00000000..3c817586 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCWriteCacheOperation.cs @@ -0,0 +1,36 @@ + +namespace YooAsset +{ + internal abstract class FCWriteCacheOperation : AsyncOperationBase + { + } + + internal class FCWriteCacheCompleteOperation : FCWriteCacheOperation + { + private readonly string _error; + + public FCWriteCacheCompleteOperation() + { + _error = null; + } + public FCWriteCacheCompleteOperation(string error) + { + _error = error; + } + internal override void InternalStart() + { + if (string.IsNullOrEmpty(_error)) + { + Status = EOperationStatus.Succeeded; + } + else + { + Status = EOperationStatus.Failed; + Error = _error; + } + } + internal override void InternalUpdate() + { + } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs.meta b/Assets/YooAsset/Runtime/FileCache/Operations/FCWriteCacheOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Operations/FCWriteCacheOperation.cs.meta index 8642fb2b..c2d93ad5 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs.meta +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCWriteCacheOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 773d121e67073ec44adaa843ebcb01a0 +guid: d7127f4341e3a9e43a7db51c48737241 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCStoreCacheOptions.cs b/Assets/YooAsset/Runtime/FileCache/Operations/FCWriteCacheOptions.cs similarity index 63% rename from Assets/YooAsset/Runtime/FileCache/Operations/FCStoreCacheOptions.cs rename to Assets/YooAsset/Runtime/FileCache/Operations/FCWriteCacheOptions.cs index d603b122..71b73c17 100644 --- a/Assets/YooAsset/Runtime/FileCache/Operations/FCStoreCacheOptions.cs +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCWriteCacheOptions.cs @@ -1,7 +1,7 @@ namespace YooAsset { - internal struct FCStoreCacheOptions + internal struct WriteCacheOptions { /// /// 要缓存的资源包 @@ -12,5 +12,10 @@ namespace YooAsset /// 要缓存的文件路径 /// public string FilePath { get; set; } + + /// + /// 要缓存的文件数据 + /// + public byte[] FileData { get; set; } } } diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCWriteCacheOptions.cs.meta b/Assets/YooAsset/Runtime/FileCache/Operations/FCWriteCacheOptions.cs.meta new file mode 100644 index 00000000..d9b381a1 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Operations/FCWriteCacheOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6cdea99ab2acded4ebd8c5766c8b3b7b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem.meta b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache.meta similarity index 77% rename from Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem.meta rename to Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache.meta index 343af569..4b93ed1f 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem.meta +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 07e60a75ff092314cb4d9ba6d5b14296 +guid: 3fc8cc5c0f4f38941bcbad7d4866d535 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCache.cs b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCache.cs new file mode 100644 index 00000000..448d4c22 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCache.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class BuiltinFileCache : IFileCache + { + internal struct CacheConfig + { + public IDownloadBackend DownloadBackend { get; set; } + } + + private readonly Dictionary _caches = new Dictionary(10000); + + // 缓存配置 + internal readonly CacheConfig Config; + + #region 接口属性 + /// + /// 包裹名称 + /// + public string PackageName { get; } + + /// + /// 缓存根目录 + /// + public string RootPath { get; } + + /// + /// 只读属性 + /// + public bool IsReadOnly { get; } + + /// + /// 缓存文件数量 + /// + public int FileCount + { + get + { + return _caches.Count; + } + } + + /// + /// 已占用空间 + /// 说明:按缓存索引累计 + /// + public long SpaceOccupied { get; private set; } + #endregion + + public BuiltinFileCache(string packageName, string rootPath, CacheConfig config) + { + PackageName = packageName; + RootPath = rootPath; + Config = config; + IsReadOnly = true; + } + public void Dispose() + { + } + public virtual FCInitializeOperation InitializeAsync() + { + var operation = new BFCInitializeOperation(this); + return operation; + } + public virtual FCWriteCacheOperation WriteCacheAsync(WriteCacheOptions options) + { + var operation = new FCWriteCacheCompleteOperation($"{nameof(BuiltinFileCache)} is readonly."); + return operation; + } + public virtual FCClearCacheOperation ClearCacheAsync(ClearCacheOptions options) + { + var operation = new FCClearCacheCompleteOperation($"{nameof(BuiltinFileCache)} is readonly."); + return operation; + } + public virtual FCVerifyCacheOperation VerifyCacheAsync(VerifyCacheOptions options) + { + var operation = new FCVerifyCacheCompleteOperation(); + return operation; + } + public virtual FCLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) + { + if (options.Bundle.BundleType == (int)EBundleType.AssetBundle) + { + var operation = new BFCLoadAssetBundleOperation(this, options.Bundle); + return operation; + } + else if (options.Bundle.BundleType == (int)EBundleType.RawBundle) + { + var operation = new BFCLoadRawBundleOperation(this, options.Bundle); + return operation; + } + else + { + string error = $"{nameof(BuiltinFileCache)} not support load bundle type : {options.Bundle.BundleType}"; + var operation = new FCLoadBundleErrorOperation(error); + return operation; + } + } + public virtual bool IsCached(string bundleGUID) + { + return _caches.ContainsKey(bundleGUID); + } + + #region 内部方法 + /// + /// 获取指定缓存 + /// + public BuiltinFileCacheEntry GetEntry(string bundleGUID) + { + if (_caches.TryGetValue(bundleGUID, out BuiltinFileCacheEntry entry)) + return entry; + else + return null; + } + + /// + /// 添加指定缓存 + /// + internal void AddEntry(string bundleGUID, BuiltinFileCacheEntry entry) + { + if (_caches.ContainsKey(bundleGUID)) + throw new YooInternalException($"Cache entry already existed: {bundleGUID}"); + + _caches.Add(bundleGUID, entry); + } + + /// + /// 获取Catalog文件加载路径 + /// + internal string GetCatalogBinaryFileLoadPath() + { + return PathUtility.Combine(RootPath, BuiltinFileCatalogDefine.BinaryFileName); + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCache.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCache.cs.meta new file mode 100644 index 00000000..2dbe56fe --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCache.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 91fdd72294b893b4a835072732641208 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCacheEntry.cs b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCacheEntry.cs new file mode 100644 index 00000000..8f86aefc --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCacheEntry.cs @@ -0,0 +1,15 @@ + +namespace YooAsset +{ + internal class BuiltinFileCacheEntry : ICacheEntry + { + public string BundleGUID { get; private set; } + public string FilePath { get; private set; } + + public BuiltinFileCacheEntry(string bundleGUID, string filePath) + { + BundleGUID = bundleGUID; + FilePath = filePath; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCacheEntry.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCacheEntry.cs.meta new file mode 100644 index 00000000..bf838567 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCacheEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c1ac8aeeac16de547bd0eff9bbaa3a23 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/BuiltinFileCatalog.cs b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalog.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/BuiltinFileCatalog.cs rename to Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalog.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/BuiltinFileCatalog.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalog.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/BuiltinFileCatalog.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalog.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/CatalogFileDefine.cs b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalogDefine.cs similarity index 55% rename from Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/CatalogFileDefine.cs rename to Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalogDefine.cs index f7cf1eb5..b3e9dc87 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/CatalogFileDefine.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalogDefine.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class CatalogFileConstants + internal class BuiltinFileCatalogDefine { /// /// 文件极限大小(100MB) @@ -17,5 +17,16 @@ namespace YooAsset /// 文件格式版本 /// public const string FileVersion = "1.0.0"; + + + /// + /// JSON文件名称 + /// + public const string JsonFileName = "BuiltinCatalog.json"; + + /// + /// 二进制文件名称 + /// + public const string BinaryFileName = "BuiltinCatalog.bytes"; } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/CatalogFileDefine.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalogDefine.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/CatalogFileDefine.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalogDefine.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/CatalogFileTools.cs b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalogTools.cs similarity index 89% rename from Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/CatalogFileTools.cs rename to Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalogTools.cs index a916eafc..5b4636f9 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/CatalogFileTools.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalogTools.cs @@ -5,7 +5,7 @@ using UnityEngine; namespace YooAsset { - internal static class CatalogFileTools + internal static class BuiltinFileCatalogTools { #if UNITY_EDITOR /// @@ -40,7 +40,7 @@ namespace YooAsset } var binaryData = FileUtility.ReadAllBytes(manifestFilePath); - packageManifest = PackageManifestTools.DeserializeFromBinary(binaryData, services); + packageManifest = PackageManifestTools.DeserializeManifestFromBinary(binaryData, services); } // 获取文件名映射关系 @@ -54,7 +54,7 @@ namespace YooAsset // 创建内置清单实例 var buildinFileCatalog = new BuiltinFileCatalog(); - buildinFileCatalog.FileVersion = CatalogFileConstants.FileVersion; + buildinFileCatalog.FileVersion = BuiltinFileCatalogDefine.FileVersion; buildinFileCatalog.PackageName = packageName; buildinFileCatalog.PackageVersion = packageVersion; @@ -63,8 +63,8 @@ namespace YooAsset { "link.xml", "buildlogtep.json", - BuiltinFileSystemConstants.BuiltinCatalogJsonFileName, - BuiltinFileSystemConstants.BuiltinCatalogBinaryFileName + BuiltinFileCatalogDefine.JsonFileName, + BuiltinFileCatalogDefine.BinaryFileName }; string packageVersionFileName = YooAssetSettingsData.GetPackageVersionFileName(packageName); string packageHashFileName = YooAssetSettingsData.GetPackageHashFileName(packageName, packageVersion); @@ -103,13 +103,13 @@ namespace YooAsset } // 创建输出文件 - string jsonFilePath = $"{packageDirectory}/{BuiltinFileSystemConstants.BuiltinCatalogJsonFileName}"; + string jsonFilePath = $"{packageDirectory}/{BuiltinFileCatalogDefine.JsonFileName}"; if (File.Exists(jsonFilePath)) File.Delete(jsonFilePath); SerializeToJson(jsonFilePath, buildinFileCatalog); // 创建输出文件 - string binaryFilePath = $"{packageDirectory}/{BuiltinFileSystemConstants.BuiltinCatalogBinaryFileName}"; + string binaryFilePath = $"{packageDirectory}/{BuiltinFileCatalogDefine.BinaryFileName}"; if (File.Exists(binaryFilePath)) File.Delete(binaryFilePath); SerializeToBinary(binaryFilePath, buildinFileCatalog); @@ -126,18 +126,18 @@ namespace YooAsset { // 创建内置清单实例 var buildinFileCatalog = new BuiltinFileCatalog(); - buildinFileCatalog.FileVersion = CatalogFileConstants.FileVersion; + buildinFileCatalog.FileVersion = BuiltinFileCatalogDefine.FileVersion; buildinFileCatalog.PackageName = packageName; buildinFileCatalog.PackageVersion = packageVersion; // 创建输出文件 - string jsonFilePath = $"{outputPath}/{BuiltinFileSystemConstants.BuiltinCatalogJsonFileName}"; + string jsonFilePath = $"{outputPath}/{BuiltinFileCatalogDefine.JsonFileName}"; if (File.Exists(jsonFilePath)) File.Delete(jsonFilePath); SerializeToJson(jsonFilePath, buildinFileCatalog); // 创建输出文件 - string binaryFilePath = $"{outputPath}/{BuiltinFileSystemConstants.BuiltinCatalogBinaryFileName}"; + string binaryFilePath = $"{outputPath}/{BuiltinFileCatalogDefine.BinaryFileName}"; if (File.Exists(binaryFilePath)) File.Delete(binaryFilePath); SerializeToBinary(binaryFilePath, buildinFileCatalog); @@ -173,13 +173,13 @@ namespace YooAsset using (FileStream fs = new FileStream(savePath, FileMode.Create)) { // 创建缓存器 - BufferWriter buffer = new BufferWriter(CatalogFileConstants.FileMaxSize); + BufferWriter buffer = new BufferWriter(BuiltinFileCatalogDefine.FileMaxSize); // 写入文件标记 - buffer.WriteUInt32(CatalogFileConstants.FileSign); + buffer.WriteUInt32(BuiltinFileCatalogDefine.FileSign); // 写入文件版本 - buffer.WriteUTF8(CatalogFileConstants.FileVersion); + buffer.WriteUTF8(BuiltinFileCatalogDefine.FileVersion); // 写入文件头信息 buffer.WriteUTF8(catalog.PackageName); @@ -213,13 +213,13 @@ namespace YooAsset // 读取文件标记 uint fileSign = buffer.ReadUInt32(); - if (fileSign != CatalogFileConstants.FileSign) + if (fileSign != BuiltinFileCatalogDefine.FileSign) throw new Exception("Invalid catalog file."); // 读取文件版本 string fileVersion = buffer.ReadUTF8(); - if (fileVersion != CatalogFileConstants.FileVersion) - throw new Exception($"The catalog file version are not compatible : {fileVersion} != {CatalogFileConstants.FileVersion}"); + if (fileVersion != BuiltinFileCatalogDefine.FileVersion) + throw new Exception($"The catalog file version are not compatible : {fileVersion} != {BuiltinFileCatalogDefine.FileVersion}"); BuiltinFileCatalog catalog = new BuiltinFileCatalog(); { diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/CatalogFileTools.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalogTools.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/CatalogFileTools.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/BuiltinFileCatalogTools.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations.meta b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations.meta new file mode 100644 index 00000000..35fe8443 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 34b5f5fd59f780c40bd9e581c5c6a718 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/BFCInitializeOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/BFCInitializeOperation.cs new file mode 100644 index 00000000..7751300b --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/BFCInitializeOperation.cs @@ -0,0 +1,68 @@ + +namespace YooAsset +{ + internal class BFCInitializeOperation : FCInitializeOperation + { + private enum ESteps + { + None, + LoadCatalogFile, + RecordFiles, + Done, + } + + private readonly BuiltinFileCache _fileCache; + private LoadBuiltinCatalogFileOperation _loadBuiltinCatalogFileOp; + private ESteps _steps = ESteps.None; + + public BFCInitializeOperation(BuiltinFileCache cache) + { + _fileCache = cache; + } + internal override void InternalStart() + { + _steps = ESteps.LoadCatalogFile; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadCatalogFile) + { + if (_loadBuiltinCatalogFileOp == null) + { + _loadBuiltinCatalogFileOp = new LoadBuiltinCatalogFileOperation(_fileCache); + _loadBuiltinCatalogFileOp.StartOperation(); + AddChildOperation(_loadBuiltinCatalogFileOp); + } + + _loadBuiltinCatalogFileOp.UpdateOperation(); + if (_loadBuiltinCatalogFileOp.IsDone == false) + return; + + if (_loadBuiltinCatalogFileOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.RecordFiles; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadBuiltinCatalogFileOp.Error; + } + } + + if (_steps == ESteps.RecordFiles) + { + var catalog = _loadBuiltinCatalogFileOp.Catalog; + foreach (var wrapper in catalog.Wrappers) + { + string filePath = PathUtility.Combine(_fileCache.RootPath, wrapper.FileName); + var entry = new BuiltinFileCacheEntry(wrapper.BundleGUID, filePath); + _fileCache.AddEntry(wrapper.BundleGUID, entry); + } + } + } + } +} diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/BFCInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/BFCInitializeOperation.cs.meta new file mode 100644 index 00000000..fba0310a --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/BFCInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d1cd01c3a273ec8428ba5cca5aaed254 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/BFCLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/BFCLoadBundleOperation.cs new file mode 100644 index 00000000..5bf97d24 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/BFCLoadBundleOperation.cs @@ -0,0 +1,178 @@ +using System; +using System.IO; +using UnityEngine; + +namespace YooAsset +{ + internal class BFCLoadAssetBundleOperation : FCLoadBundleOperation + { + private enum ESteps + { + None, + LoadAssetBundle, + CheckResult, + Done, + } + + private readonly BuiltinFileCache _fileCache; + private readonly PackageBundle _bundle; + private AssetBundleCreateRequest _createRequest; + private AssetBundle _assetBundle; + private string _filePath; + private ESteps _steps = ESteps.None; + + public BFCLoadAssetBundleOperation(BuiltinFileCache fileCache, PackageBundle bundle) + { + _fileCache = fileCache; + _bundle = bundle; + } + internal override void InternalStart() + { + _steps = ESteps.LoadAssetBundle; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadAssetBundle) + { + var entry = _fileCache.GetEntry(_bundle.BundleGUID); + if (entry == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Not found file cache entry: {_bundle.BundleGUID}"; + return; + } + + _filePath = entry.FilePath; + if (IsWaitForCompletion) + _assetBundle = AssetBundle.LoadFromFile(_filePath); + else + _createRequest = AssetBundle.LoadFromFileAsync(_filePath); + + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (_createRequest != null) + { + if (IsWaitForCompletion) + { + // 强制挂起主线程(注意:该操作会很耗时) + 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) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load asset bundle : {_bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + BundleResult = new AssetBundleResult(_filePath, _bundle, _assetBundle, null); + } + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + } + + internal class BFCLoadRawBundleOperation : FCLoadBundleOperation + { + private enum ESteps + { + None, + LoadRawBundle, + Done, + } + + private readonly BuiltinFileCache _fileCache; + private readonly PackageBundle _bundle; + private ESteps _steps = ESteps.None; + + public BFCLoadRawBundleOperation(BuiltinFileCache fileCache, PackageBundle bundle) + { + _fileCache = fileCache; + _bundle = bundle; + } + internal override void InternalStart() + { + _steps = ESteps.LoadRawBundle; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadRawBundle) + { + var entry = _fileCache.GetEntry(_bundle.BundleGUID); + if (entry == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Not found file cache entry: {_bundle.BundleGUID}"; + return; + } + + string filePath = entry.FilePath; + if (IsSupportFileIO(filePath) == false) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"FileIO not supported for builtin path : {filePath}"; + } + else + { + if (File.Exists(filePath)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + + byte[] data = File.ReadAllBytes(filePath); + var rawBundle = new RawBundle(data); + BundleResult = new RawBundleResult(filePath, _bundle, rawBundle); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Can not found raw bundle file : {filePath}"; + } + } + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + } + + internal abstract class BFCLoadAssetBundleFromOperation : FCLoadBundleOperation + { + internal abstract AssetBundle LoadFromOffset(); + internal abstract AssetBundleCreateRequest LoadFromOffsetAsync(); + + internal abstract AssetBundle LoadFromMemory(); + internal abstract AssetBundleCreateRequest LoadFromMemoryAsync(); + + internal abstract AssetBundle LoadFromStream(); + internal abstract AssetBundleCreateRequest LoadFromStreamAsync(); + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/BFCLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/BFCLoadBundleOperation.cs.meta new file mode 100644 index 00000000..7cda4a95 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/BFCLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc8b3f7e6178e2e4990674d5518eff33 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/Internal.meta b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/Internal.meta new file mode 100644 index 00000000..86d7187d --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/Internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0dd4916e71be0934883f2fc404dd18fc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/LoadBuiltinCatalogFileOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/Internal/LoadBuiltinCatalogFileOperation.cs similarity index 67% rename from Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/LoadBuiltinCatalogFileOperation.cs rename to Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/Internal/LoadBuiltinCatalogFileOperation.cs index 82496cba..91b4e78d 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/LoadBuiltinCatalogFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/Internal/LoadBuiltinCatalogFileOperation.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; namespace YooAsset @@ -11,10 +11,11 @@ namespace YooAsset TryLoadFileData, RequestFileData, LoadCatalog, + CheckResut, Done, } - private readonly BuiltinFileSystem _fileSystem; + private readonly BuiltinFileCache _fileCache; private IDownloadBytesRequest _webDataRequestOp; private byte[] _fileData; private ESteps _steps = ESteps.None; @@ -24,9 +25,9 @@ namespace YooAsset /// public BuiltinFileCatalog Catalog; - internal LoadBuiltinCatalogFileOperation(BuiltinFileSystem fileSystem) + internal LoadBuiltinCatalogFileOperation(BuiltinFileCache fileCache) { - _fileSystem = fileSystem; + _fileCache = fileCache; } internal override void InternalStart() { @@ -39,7 +40,7 @@ namespace YooAsset if (_steps == ESteps.TryLoadFileData) { - string filePath = _fileSystem.GetCatalogBinaryFileLoadPath(); + string filePath = _fileCache.GetCatalogBinaryFileLoadPath(); if (File.Exists(filePath)) { _fileData = File.ReadAllBytes(filePath); @@ -55,17 +56,17 @@ namespace YooAsset { if (_webDataRequestOp == null) { - string filePath = _fileSystem.GetCatalogBinaryFileLoadPath(); - string url = DownloadSystemTools.ToLocalURL(filePath); + string filePath = _fileCache.GetCatalogBinaryFileLoadPath(); + string url = DownloadSystemTools.ToLocalUrl(filePath); var args = new DownloadDataRequestArgs(url, 60, 0); - _webDataRequestOp = _fileSystem.DownloadBackend.CreateBytesRequest(args); + _webDataRequestOp = _fileCache.Config.DownloadBackend.CreateBytesRequest(args); _webDataRequestOp.SendRequest(); } if (_webDataRequestOp.IsDone == false) return; - if (_webDataRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webDataRequestOp.Status == EDownloadRequestStatus.Succeeded) { _fileData = _webDataRequestOp.Result; _steps = ESteps.LoadCatalog; @@ -82,9 +83,8 @@ namespace YooAsset { try { - Catalog = CatalogFileTools.DeserializeFromBinary(_fileData); - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; + Catalog = BuiltinFileCatalogTools.DeserializeFromBinary(_fileData); + _steps = ESteps.CheckResut; } catch (Exception ex) { @@ -93,6 +93,20 @@ namespace YooAsset Error = $"Failed to load catalog file : {ex.Message}"; } } + + if (_steps == ESteps.CheckResut) + { + if (Catalog.PackageName != _fileCache.PackageName) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Catalog file package name {Catalog.PackageName} cannot match the file cache package name {_fileCache.PackageName}"; + return; + } + + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/LoadBuiltinCatalogFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/Internal/LoadBuiltinCatalogFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/LoadBuiltinCatalogFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/BuiltinFileCache/Operations/Internal/LoadBuiltinCatalogFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCache.cs b/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCache.cs deleted file mode 100644 index 075a1297..00000000 --- a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCache.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System.Collections.Generic; -using System.IO; - -namespace YooAsset -{ - internal class BundleCache : IFileCache - { - private const int HashFolderLength = 2; - - // 缓存索引 - private readonly Dictionary _caches = new Dictionary(10000); - - // 路径缓存 - private readonly Dictionary _dataFilePathMapping = new Dictionary(10000); - private readonly Dictionary _infoFilePathMapping = new Dictionary(10000); - - // 共享缓冲区 - internal readonly BufferWriter SharedBuffer = new BufferWriter(1024); - - - /// - /// 包裹名称 - /// - public string PackageName { get; } - - /// - /// 缓存根目录 - /// - public string RootPath { get; } - - /// - /// 追加文件扩展名 - /// - public readonly bool AppendFileExtension; - - /// - /// 只读属性 - /// - public bool IsReadOnly { get; } - - /// - /// 缓存文件数量 - /// - public int FileCount - { - get - { - return _caches.Count; - } - } - - /// - /// 已占用空间 - /// 说明:按缓存索引累计 - /// - public long SpaceOccupied { get; private set; } - - - public BundleCache(string packageName, string rootPath, bool appendFileExtension) - { - PackageName = packageName; - RootPath = rootPath; - AppendFileExtension = appendFileExtension; - IsReadOnly = false; - } - - /// - /// 初始化缓存 - /// - public FCInitializeOperation InitializeAsync(FCInitializeOptions options) - { - var operation = new FCInitializeOperation(this, options); - return operation; - } - - /// - /// 存储缓存文件 - /// - public FCStoreCacheOperation StoreCacheAsync(FCStoreCacheOptions options) - { - var operation = new FCStoreCacheOperation(this, options); - return operation; - } - - /// - /// 清理缓存文件 - /// - public FCClearCacheOperation ClearCacheAsync(FCClearCacheOptions options) - { - var operation = new FCClearCacheOperation(this, options); - return operation; - } - - /// - /// 是否已缓存指定 Bundle - /// - public bool IsCached(string bundleGUID) - { - return _caches.ContainsKey(bundleGUID); - } - - /// - /// 获取缓存记录 - /// - public BundleCacheEntry GetEntry(string bundleGUID) - { - if (_caches.TryGetValue(bundleGUID, out BundleCacheEntry entry)) - return entry; - else - return null; - } - - /// - /// 获取所有的缓存记录 - /// - public IReadOnlyCollection GetAllEntries() - { - return _caches.Values; - } - - #region 内部方法 - /// - /// 获取 Bundle 数据文件路径 - /// - internal string GetDataFilePath(PackageBundle bundle) - { - if (_dataFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false) - { - string folderName = GetHashFolderName(bundle.FileHash); - filePath = PathUtility.Combine(RootPath, folderName, bundle.BundleGUID, BundleCacheDefine.BundleDataFileName); - if (AppendFileExtension) - filePath += bundle.FileExtension; - _dataFilePathMapping.Add(bundle.BundleGUID, filePath); - } - return filePath; - } - - /// - /// 获取 Bundle 信息文件路径 - /// - internal string GetInfoFilePath(PackageBundle bundle) - { - if (_infoFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false) - { - string folderName = GetHashFolderName(bundle.FileHash); - filePath = PathUtility.Combine(RootPath, folderName, bundle.BundleGUID, BundleCacheDefine.BundleInfoFileName); - _infoFilePathMapping.Add(bundle.BundleGUID, filePath); - } - return filePath; - } - - /// - /// 添加指定缓存 - /// - internal void AddEntry(string bundleGUID, BundleCacheEntry entry) - { - if (_caches.ContainsKey(bundleGUID)) - throw new YooInternalException($"Cache already existed: {bundleGUID}"); - - _caches.Add(bundleGUID, entry); - SpaceOccupied += entry.DataFileSize; - } - - /// - /// 删除指定缓存 - /// - internal void RemoveEntry(string bundleGUID) - { - if (_caches.TryGetValue(bundleGUID, out BundleCacheEntry entry)) - { - _caches.Remove(bundleGUID); - _dataFilePathMapping.Remove(bundleGUID); - _infoFilePathMapping.Remove(bundleGUID); - SpaceOccupied -= entry.DataFileSize; - entry.Delete(); - } - } - - private string GetHashFolderName(string fileHash) - { - if (string.IsNullOrEmpty(fileHash)) - throw new YooInternalException(); - - if (fileHash.Length <= HashFolderLength) - return fileHash; - return fileHash.Substring(0, HashFolderLength); - } - #endregion - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/DefaultLoadAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadAssetBundleOperation.cs similarity index 99% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/DefaultLoadAssetBundleOperation.cs rename to Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadAssetBundleOperation.cs index 11693f13..0df3df7e 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/DefaultLoadAssetBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadAssetBundleOperation.cs @@ -79,6 +79,9 @@ namespace YooAsset public override AssetBundle LoadFromMemory() { + if (IsSupportFileIO(_options.FileLoadPath) == false) + return null; + byte[] fileData = FileUtility.ReadAllBytes(_options.FileLoadPath); if (fileData == null || fileData.Length == 0) return null; @@ -198,7 +201,7 @@ namespace YooAsset private AssetBundleCreateRequest _createRequest; private ESteps _steps = ESteps.None; - + public DefaultLoadAssetBundleFromMemoryOperation(LoadAssetBundleOptions options) : base(options) { } internal override void InternalStart() { diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/DefaultLoadAssetBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadAssetBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/DefaultLoadAssetBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadAssetBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/DefaultLoadRawBundleOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadRawBundleOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/DefaultLoadRawBundleOperation.cs rename to Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadRawBundleOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/DefaultLoadRawBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadRawBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/DefaultLoadRawBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadRawBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/DefaultLoadWebAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadWebAssetBundleOperation.cs similarity index 97% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/DefaultLoadWebAssetBundleOperation.cs rename to Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadWebAssetBundleOperation.cs index 245cee5c..9cc2a73a 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/DefaultLoadWebAssetBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadWebAssetBundleOperation.cs @@ -26,7 +26,7 @@ namespace YooAsset public DefaultLoadWebAssetBundleOperation(LoadWebAssetBundleOptions opionts) : base(opionts) { - _failedTryAgain = opionts.FailedTryAgain; + _failedTryAgain = opionts.RetryCount; } internal override void InternalStart() { @@ -56,7 +56,7 @@ namespace YooAsset if (_downloadAssetBundleRequest.IsDone == false) return; - if (_downloadAssetBundleRequest.Status == EDownloadRequestStatus.Succeed) + if (_downloadAssetBundleRequest.Status == EDownloadRequestStatus.Succeeded) { _steps = ESteps.Done; Status = EOperationStatus.Succeeded; @@ -67,7 +67,7 @@ namespace YooAsset if (_failedTryAgain > 0) { _steps = ESteps.TryAgain; - YooLogger.Warning($"Failed download : {_downloadAssetBundleRequest.URL} Try again."); + YooLogger.Warning($"Failed download : {_downloadAssetBundleRequest.Url} Try again."); } else { @@ -136,7 +136,7 @@ namespace YooAsset public DefaultLoadWebAssetBundleFromMemoryOperation(LoadWebAssetBundleOptions opionts) : base(opionts) { - _failedTryAgain = opionts.FailedTryAgain; + _failedTryAgain = opionts.RetryCount; } internal override void InternalStart() { @@ -167,7 +167,7 @@ namespace YooAsset return; // 检查网络错误 - if (_downloadBytesRequest.Status == EDownloadRequestStatus.Succeed) + if (_downloadBytesRequest.Status == EDownloadRequestStatus.Succeeded) { var rawData = Decryption(_downloadBytesRequest.Result); if (rawData == null || rawData.Length == 0) @@ -198,7 +198,7 @@ namespace YooAsset if (_failedTryAgain > 0) { _steps = ESteps.TryAgain; - YooLogger.Warning($"Failed download : {_downloadBytesRequest.URL} Try again."); + YooLogger.Warning($"Failed download : {_downloadBytesRequest.Url} Try again."); } else { diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/DefaultLoadWebAssetBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadWebAssetBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/DefaultLoadWebAssetBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/DefaultLoadWebAssetBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache.meta b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache.meta new file mode 100644 index 00000000..f56cea78 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0d4152d48d076244fb4e339ebd34db0a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/EditorFileCache.cs b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/EditorFileCache.cs new file mode 100644 index 00000000..80b90723 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/EditorFileCache.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class EditorFileCache : IFileCache + { + internal struct CacheConfig + { + public bool VirtualDownloadMode { get; set; } + public bool VirtualWebGLMode { get; set; } + public int AsyncSimulateMinFrame { get; set; } + public int AsyncSimulateMaxFrame { get; set; } + } + + private readonly Dictionary _caches = new Dictionary(10000); + + // 缓存配置 + internal readonly CacheConfig Config; + + #region 接口属性 + /// + /// 包裹名称 + /// + public string PackageName { get; } + + /// + /// 缓存根目录 + /// + public string RootPath { get; } + + /// + /// 只读属性 + /// + public bool IsReadOnly { get; } + + /// + /// 缓存文件数量 + /// + public int FileCount + { + get + { + return _caches.Count; + } + } + + /// + /// 已占用空间 + /// 说明:按缓存索引累计 + /// + public long SpaceOccupied { get; private set; } + #endregion + + public EditorFileCache(string packageName, string rootPath, CacheConfig config) + { + PackageName = packageName; + RootPath = rootPath; + Config = config; + IsReadOnly = true; + } + public void Dispose() + { + } + public virtual FCInitializeOperation InitializeAsync() + { + var operation = new EFCInitializeOperation(this); + return operation; + } + public virtual FCWriteCacheOperation WriteCacheAsync(WriteCacheOptions options) + { + var operation = new EFCWriteCacheOperation(this, options); + return operation; + } + public virtual FCClearCacheOperation ClearCacheAsync(ClearCacheOptions options) + { + var operation = new FCClearCacheCompleteOperation(); + return operation; + } + public virtual FCVerifyCacheOperation VerifyCacheAsync(VerifyCacheOptions options) + { + var operation = new FCVerifyCacheCompleteOperation(); + return operation; + } + public virtual FCLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) + { + var operation = new EFCLoadVirtualBundleOperation(this, options.Bundle); + return operation; + } + public virtual bool IsCached(string bundleGUID) + { + if (Config.VirtualDownloadMode) + return _caches.ContainsKey(bundleGUID); + else + return true; + } + + #region 内部方法 + /// + /// 获取指定缓存 + /// + public EditorFileCacheEntry GetEntry(string bundleGUID) + { + if (_caches.TryGetValue(bundleGUID, out EditorFileCacheEntry entry)) + return entry; + else + return null; + } + + /// + /// 添加指定缓存 + /// + internal void AddEntry(string bundleGUID, EditorFileCacheEntry entry) + { + if (_caches.ContainsKey(bundleGUID)) + throw new YooInternalException($"Cache entry already existed: {bundleGUID}"); + + _caches.Add(bundleGUID, entry); + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/EditorFileCache.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/EditorFileCache.cs.meta new file mode 100644 index 00000000..266f6cad --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/EditorFileCache.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8fe012ac4472e645a3f9235636be7e5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/EditorFileCacheEntry.cs b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/EditorFileCacheEntry.cs new file mode 100644 index 00000000..ca55410a --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/EditorFileCacheEntry.cs @@ -0,0 +1,15 @@ + +namespace YooAsset +{ + internal class EditorFileCacheEntry : ICacheEntry + { + public string BundleGUID { get; private set; } + public string FilePath { get; private set; } + + public EditorFileCacheEntry(string bundleGUID, string filePath) + { + BundleGUID = bundleGUID; + FilePath = filePath; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/EditorFileCacheEntry.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/EditorFileCacheEntry.cs.meta new file mode 100644 index 00000000..15b2c52f --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/EditorFileCacheEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0381df9e70060b54bb4985fb7f5f9a77 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations.meta b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations.meta new file mode 100644 index 00000000..12e5d616 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d6b994fd3cded4a45b28ae75987780fa +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCInitializeOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCInitializeOperation.cs new file mode 100644 index 00000000..93199391 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCInitializeOperation.cs @@ -0,0 +1,20 @@ + +namespace YooAsset +{ + internal class EFCInitializeOperation : FCInitializeOperation + { + private readonly EditorFileCache _fileCache; + + public EFCInitializeOperation(EditorFileCache cache) + { + _fileCache = cache; + } + internal override void InternalStart() + { + Status = EOperationStatus.Succeeded; + } + internal override void InternalUpdate() + { + } + } +} diff --git a/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCInitializeOperation.cs.meta new file mode 100644 index 00000000..13bb3c43 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 92dc2e40bf8f75e4aadcb2a137192c40 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCLoadBundleOperation.cs new file mode 100644 index 00000000..201a55ad --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCLoadBundleOperation.cs @@ -0,0 +1,85 @@ + +namespace YooAsset +{ + internal class EFCLoadVirtualBundleOperation : FCLoadBundleOperation + { + private enum ESteps + { + None, + LoadVirtualBundle, + CheckResult, + Done, + } + + private readonly EditorFileCache _fileCache; + private readonly PackageBundle _bundle; + private int _asyncSimulateFrame; + private ESteps _steps = ESteps.None; + + public EFCLoadVirtualBundleOperation(EditorFileCache fileCache, PackageBundle bundle) + { + _fileCache = fileCache; + _bundle = bundle; + } + internal override void InternalStart() + { + _steps = ESteps.LoadVirtualBundle; + _asyncSimulateFrame = GetAsyncSimulateFrame(); + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadVirtualBundle) + { + var entry = _fileCache.GetEntry(_bundle.BundleGUID); + if (entry == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Not found file cache entry: {_bundle.BundleGUID}"; + return; + } + + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (IsWaitForCompletion) + { + if (_fileCache.Config.VirtualWebGLMode) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "WebGL mode only support asyn load method."; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + } + else + { + _asyncSimulateFrame--; + if (_asyncSimulateFrame <= 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + } + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + + private int GetAsyncSimulateFrame() + { + return UnityEngine.Random.Range(_fileCache.Config.AsyncSimulateMinFrame, _fileCache.Config.AsyncSimulateMaxFrame + 1); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCLoadBundleOperation.cs.meta new file mode 100644 index 00000000..b947fdb0 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 35ea191497792124a9e76418e1b7f6d0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCWriteCacheOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCWriteCacheOperation.cs new file mode 100644 index 00000000..d5461630 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCWriteCacheOperation.cs @@ -0,0 +1,61 @@ +using System; +using System.IO; + +namespace YooAsset +{ + internal class EFCWriteCacheOperation : FCWriteCacheOperation + { + private enum ESteps + { + None, + Check, + CacheFile, + Done, + } + + private readonly EditorFileCache _cache; + private readonly WriteCacheOptions _options; + private ESteps _steps = ESteps.None; + + public EFCWriteCacheOperation(EditorFileCache cache, WriteCacheOptions options) + { + _cache = cache; + _options = options; + } + internal override void InternalStart() + { + _steps = ESteps.Check; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.Check) + { + if (_cache.IsCached(_options.Bundle.BundleGUID)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "The bundle is cached."; + } + else + { + _steps = ESteps.CacheFile; + } + } + + if (_steps == ESteps.CacheFile) + { + var cacheEntry = new EditorFileCacheEntry(_options.Bundle.BundleGUID, _options.FilePath); + _cache.AddEntry(_options.Bundle.BundleGUID, cacheEntry); + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + } +} diff --git a/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCWriteCacheOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCWriteCacheOperation.cs.meta new file mode 100644 index 00000000..dbb9ae5b --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/EditorFileCache/Operations/EFCWriteCacheOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 835873c2997792a4a9aaa2bc283de35a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/LoadAssetBundleOperation.cs similarity index 91% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadAssetBundleOperation.cs rename to Assets/YooAsset/Runtime/FileCache/Services/LoadAssetBundleOperation.cs index dccb53cf..3b7829d9 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadAssetBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/LoadAssetBundleOperation.cs @@ -3,11 +3,6 @@ using UnityEngine; namespace YooAsset { - /// - /// 加载 AssetBundle 的 Operation 工厂委托 - /// - public delegate LoadAssetBundleOperation LoadAssetBundleOperationFactory(bool bundleEncrypted, LoadAssetBundleOptions options); - /// /// 加载 AssetBundle 的抽象基类 /// 用户可继承此类实现自定义加载逻辑(如加密解密) diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadAssetBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/LoadAssetBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadAssetBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/LoadAssetBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadAssetBundleOptions.cs b/Assets/YooAsset/Runtime/FileCache/Services/LoadAssetBundleOptions.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadAssetBundleOptions.cs rename to Assets/YooAsset/Runtime/FileCache/Services/LoadAssetBundleOptions.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadAssetBundleOptions.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/LoadAssetBundleOptions.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadAssetBundleOptions.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/LoadAssetBundleOptions.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/LoadRawBundleFileOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/LoadRawBundleFileOperation.cs similarity index 88% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/LoadRawBundleFileOperation.cs rename to Assets/YooAsset/Runtime/FileCache/Services/LoadRawBundleFileOperation.cs index 2fcb02cf..9715fec5 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/LoadRawBundleFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/LoadRawBundleFileOperation.cs @@ -2,11 +2,6 @@ using System.Text; namespace YooAsset { - /// - /// 加载 RawBundle 的 Operation 工厂委托 - /// - public delegate LoadRawBundleOperation LoadRawBundleOperationFactory(bool bundleEncrypted, LoadRawBundleOptions options); - /// /// 加载 RawBundle 的抽象基类 /// 用户可继承此类实现自定义加载逻辑(如加密解密) diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/LoadRawBundleFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/LoadRawBundleFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/LoadRawBundleFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/LoadRawBundleFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/LoadRawBundleFileOptions.cs b/Assets/YooAsset/Runtime/FileCache/Services/LoadRawBundleFileOptions.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/LoadRawBundleFileOptions.cs rename to Assets/YooAsset/Runtime/FileCache/Services/LoadRawBundleFileOptions.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/LoadRawBundleFileOptions.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/LoadRawBundleFileOptions.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/LoadRawBundleFileOptions.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/LoadRawBundleFileOptions.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EFileClearMode.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileClearMode.cs similarity index 76% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EFileClearMode.cs rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileClearMode.cs index ff420fd4..9a62aa41 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EFileClearMode.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileClearMode.cs @@ -27,16 +27,5 @@ namespace YooAsset /// 说明:需要指定参数,可选:string, string[], List /// ClearBundleFilesByTags, - - - /// - /// 清理所有清单 - /// - ClearAllManifestFiles, - - /// - /// 清理未在使用的清单 - /// - ClearUnusedManifestFiles, } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileClearMode.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileClearMode.cs.meta new file mode 100644 index 00000000..f7460c87 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileClearMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 68695f6e6b992b3459b88b9dd0cbba9f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/EFileVerifyLevel.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileVerifyLevel.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/EFileVerifyLevel.cs rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileVerifyLevel.cs diff --git a/Assets/YooAsset/Runtime/FileCache/EFileVerifyLevel.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileVerifyLevel.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/EFileVerifyLevel.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileVerifyLevel.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/EFileVerifyResult.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileVerifyResult.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/EFileVerifyResult.cs rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileVerifyResult.cs diff --git a/Assets/YooAsset/Runtime/FileCache/EFileVerifyResult.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileVerifyResult.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/EFileVerifyResult.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/EFileVerifyResult.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/FileVerifyTools.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/FileVerifyTools.cs similarity index 94% rename from Assets/YooAsset/Runtime/FileCache/FileVerifyTools.cs rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/FileVerifyTools.cs index da804ea8..e262573d 100644 --- a/Assets/YooAsset/Runtime/FileCache/FileVerifyTools.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/FileVerifyTools.cs @@ -28,7 +28,7 @@ namespace YooAsset // 验证文件CRC if (fileCRC > 0) { - uint crc = HashUtility.FileCRC32Value(filePath); + uint crc = HashUtility.ComputeFileCRC32AsUInt(filePath); if (crc == fileCRC) return EFileVerifyResult.Succeed; else diff --git a/Assets/YooAsset/Runtime/FileCache/FileVerifyTools.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/FileVerifyTools.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/FileVerifyTools.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/FileVerifyTools.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/ClearCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/ClearCacheFilesOperation.cs new file mode 100644 index 00000000..3cf17ccb --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/ClearCacheFilesOperation.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using System.Linq; + +namespace YooAsset +{ + internal class ClearCacheFilesOperation : FCClearCacheOperation + { + private enum ESteps + { + None, + CheckParam, + ClearCache, + Done, + } + + private readonly SandboxFileCache _cache; + private readonly List _bundleGUIDs; + private int _clearFileTotalCount; + private ESteps _steps = ESteps.None; + + public ClearCacheFilesOperation(SandboxFileCache cache, List bundleGUIDs) + { + _cache = cache; + _bundleGUIDs = bundleGUIDs; + } + internal override void InternalStart() + { + _steps = ESteps.CheckParam; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckParam) + { + if (_bundleGUIDs == null || _bundleGUIDs.Count == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + return; + } + + _clearFileTotalCount = _bundleGUIDs.Count; + _steps = ESteps.ClearCache; + } + + if (_steps == ESteps.ClearCache) + { + for (int i = _bundleGUIDs.Count - 1; i >= 0; i--) + { + string bundleGUID = _bundleGUIDs[i]; + _cache.RemoveEntry(bundleGUID); + _bundleGUIDs.RemoveAt(i); + if (IsBusy) + break; + } + + if (_clearFileTotalCount == 0) + Progress = 1.0f; + else + Progress = 1.0f - ((float)_bundleGUIDs.Count / _clearFileTotalCount); + + if (_bundleGUIDs.Count == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + } +} diff --git a/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/ClearCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/ClearCacheFilesOperation.cs.meta new file mode 100644 index 00000000..efeb6639 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/ClearCacheFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fb3347395a55d3048bcec202aca0e4a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/SearchCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/SearchCacheFilesOperation.cs similarity index 72% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/SearchCacheFilesOperation.cs rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/SearchCacheFilesOperation.cs index 1bcf2161..0a83f9c9 100644 --- a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/SearchCacheFilesOperation.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/SearchCacheFilesOperation.cs @@ -16,8 +16,7 @@ namespace YooAsset Done, } - private readonly BundleCache _cache; - private readonly bool _appendFileExtension; + private readonly SandboxFileCache _cache; private IEnumerator _filesEnumerator = null; private double _verifyStartTime; private ESteps _steps = ESteps.None; @@ -28,10 +27,9 @@ namespace YooAsset public readonly List Result = new List(5000); - internal SearchCacheFilesOperation(BundleCache cache) + internal SearchCacheFilesOperation(SandboxFileCache cache) { _cache = cache; - _appendFileExtension = cache.AppendFileExtension; } internal override void InternalStart() { @@ -92,20 +90,9 @@ namespace YooAsset // 创建验证元素类 string fileRootPath = chidDirectory; - string dataFilePath = PathUtility.Combine(fileRootPath, BundleCacheDefine.BundleDataFileName); - string infoFilePath = PathUtility.Combine(fileRootPath, BundleCacheDefine.BundleInfoFileName); - - // 存储的数据文件追加文件格式 - if (_appendFileExtension) - { - string realFilePath = FindRealDataFilePath(chidDirectory); - if (string.IsNullOrEmpty(realFilePath) == false) - { - dataFilePath = realFilePath; - } - } - - var element = new VerifyFileInfo(_cache.PackageName, bundleGUID, fileRootPath, dataFilePath, infoFilePath); + string dataFilePath = PathUtility.Combine(fileRootPath, SandboxFileCacheDefine.BundleDataFileName); + string infoFilePath = PathUtility.Combine(fileRootPath, SandboxFileCacheDefine.BundleInfoFileName); + var element = new VerifyFileInfo(bundleGUID, fileRootPath, dataFilePath, infoFilePath); Result.Add(element); } @@ -115,11 +102,5 @@ namespace YooAsset return isFindItem; } - private string FindRealDataFilePath(string directory) - { - string searchPattern = BundleCacheDefine.BundleDataFileName + "*"; - var searchFiles = Directory.EnumerateFiles(directory, searchPattern); - return searchFiles.FirstOrDefault(); - } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/SearchCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/SearchCacheFilesOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/SearchCacheFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/SearchCacheFilesOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/VerifyCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/VerifyCacheFilesOperation.cs similarity index 87% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/VerifyCacheFilesOperation.cs rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/VerifyCacheFilesOperation.cs index 8f8df169..10233ea5 100644 --- a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/VerifyCacheFilesOperation.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/VerifyCacheFilesOperation.cs @@ -19,7 +19,7 @@ namespace YooAsset Done, } - private readonly BundleCache _cache; + private readonly SandboxFileCache _cache; private readonly EFileVerifyLevel _verifyLevel; private readonly int _fileVerifyMaxConcurrency; private readonly List _waitingList; @@ -32,7 +32,7 @@ namespace YooAsset private ESteps _steps = ESteps.None; - internal VerifyCacheFilesOperation(BundleCache cache, EFileVerifyLevel verifyLevel, int fileVerifyMaxConcurrency, List elements) + internal VerifyCacheFilesOperation(SandboxFileCache cache, EFileVerifyLevel verifyLevel, int fileVerifyMaxConcurrency, List elements) { _cache = cache; _verifyLevel = verifyLevel; @@ -76,7 +76,7 @@ namespace YooAsset if (verifyElement.Result == (int)EFileVerifyResult.Succeed) { _succeedCount++; - var cacheEntry = new BundleCacheEntry(verifyElement.BundleGUID, verifyElement.InfoFilePath, verifyElement.DataFilePath, verifyElement.DataFileCRC, verifyElement.DataFileSize); + var cacheEntry = new SandboxFileCacheEntry(verifyElement.BundleGUID, verifyElement.InfoFilePath, verifyElement.DataFilePath); _cache.AddEntry(verifyElement.BundleGUID, cacheEntry); } else @@ -138,20 +138,19 @@ namespace YooAsset if (File.Exists(element.DataFilePath) == false) return EFileVerifyResult.DataFileNotExisted; - // 解析信息文件填充验证数据 - // 注意:验证数据在后续流程会被使用。 - byte[] binaryData = FileUtility.ReadAllBytes(element.InfoFilePath); - BufferReader buffer = new BufferReader(binaryData); - uint dataFileCRC = buffer.ReadUInt32(); - long dataFileSize = buffer.ReadInt64(); - element.SetDataFileInfo(dataFileCRC, dataFileSize); - if (verifyLevel == EFileVerifyLevel.Low) { return EFileVerifyResult.Succeed; } else { + // 解析信息文件填充验证数据 + // 注意:验证数据在后续流程会被使用。 + byte[] binaryData = FileUtility.ReadAllBytes(element.InfoFilePath); + BufferReader buffer = new BufferReader(binaryData); + uint dataFileCRC = buffer.ReadUInt32(); + long dataFileSize = buffer.ReadInt64(); + if (verifyLevel == EFileVerifyLevel.Middle) return FileVerifyTools.FileVerify(element.DataFilePath, dataFileSize, 0); else if (verifyLevel == EFileVerifyLevel.High) diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/VerifyCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/VerifyCacheFilesOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/VerifyCacheFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/VerifyCacheFilesOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/VerifyTempFileOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/VerifyTempFileOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/VerifyTempFileOperation.cs rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/VerifyTempFileOperation.cs diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/VerifyTempFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/VerifyTempFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/Operations/internal/VerifyTempFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/Internal/VerifyTempFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCClearCacheOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCClearCacheOperation.cs new file mode 100644 index 00000000..d234b5a3 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCClearCacheOperation.cs @@ -0,0 +1,225 @@ +using System.Collections.Generic; + +namespace YooAsset +{ + /// + /// 清理沙盒文件缓存操作 + /// + internal abstract class SFCClearCacheOperation : FCClearCacheOperation + { + protected enum ESteps + { + None, + ParseOptions, + ClearCacheFiles, + Done, + } + + protected readonly SandboxFileCache _fileCache; + protected readonly ClearCacheOptions _options; + protected ClearCacheFilesOperation _clearCacheFilesOp; + protected List _bundleGUIDs; + protected ESteps _steps = ESteps.None; + + internal SFCClearCacheOperation(SandboxFileCache fileCache, ClearCacheOptions options) + { + _fileCache = fileCache; + _options = options; + } + internal override void InternalStart() + { + _steps = ESteps.ParseOptions; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ParseOptions) + { + if (ParseOptionsStep() == false) + return; + + _clearCacheFilesOp = new ClearCacheFilesOperation(_fileCache, _bundleGUIDs); + _clearCacheFilesOp.StartOperation(); + AddChildOperation(_clearCacheFilesOp); + _steps = ESteps.ClearCacheFiles; + } + + if (_steps == ESteps.ClearCacheFiles) + { + if (IsWaitForCompletion) + _clearCacheFilesOp.WaitForCompletion(); + + _clearCacheFilesOp.UpdateOperation(); + Progress = _clearCacheFilesOp.Progress; + if (_clearCacheFilesOp.IsDone == false) + return; + + if (_clearCacheFilesOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearCacheFilesOp.Error; + } + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + + protected abstract bool ParseOptionsStep(); + } + + internal sealed class SFCClearAllCacheOperation : SFCClearCacheOperation + { + internal SFCClearAllCacheOperation(SandboxFileCache fileCache, ClearCacheOptions options) + : base(fileCache, options) { } + + protected override bool ParseOptionsStep() + { + var allEntrys = _fileCache.GetAllEntries(); + _bundleGUIDs = new List(allEntrys.Count); + foreach (var entry in allEntrys) + { + _bundleGUIDs.Add(entry.BundleGUID); + } + return true; + } + } + internal sealed class SFCClearUnusedCacheOperation : SFCClearCacheOperation + { + internal SFCClearUnusedCacheOperation(SandboxFileCache fileCache, ClearCacheOptions options) + : base(fileCache, options) { } + + protected override bool ParseOptionsStep() + { + if (_options.Manifest == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Can not found active package manifest."; + return false; + } + + var allEntrys = _fileCache.GetAllEntries(); + _bundleGUIDs = new List(allEntrys.Count); + foreach (var entry in allEntrys) + { + if (_options.Manifest.IsIncludeBundleFile(entry.BundleGUID) == false) + { + _bundleGUIDs.Add(entry.BundleGUID); + } + } + return true; + } + } + internal sealed class SFCClearCacheByLocationsOperation : SFCClearCacheOperation + { + internal SFCClearCacheByLocationsOperation(SandboxFileCache fileCache, ClearCacheOptions options) + : base(fileCache, options) { } + + protected override bool ParseOptionsStep() + { + if (_options.Manifest == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Can not found active package manifest."; + return false; + } + + if (_options.ClearParam == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Clear param is null."; + return false; + } + + string[] locations; + if (_options.ClearParam is string str) + locations = new string[] { str }; + else if (_options.ClearParam is List list) + locations = list.ToArray(); + else if (_options.ClearParam is string[] array) + locations = array; + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Invalid clear param : {_options.ClearParam.GetType().FullName}"; + return false; + } + + _bundleGUIDs = new List(locations.Length); + foreach (var location in locations) + { + string assetPath = _options.Manifest.TryMappingToAssetPath(location); + if (_options.Manifest.TryGetPackageAsset(assetPath, out PackageAsset packageAsset)) + { + PackageBundle bundle = _options.Manifest.GetMainPackageBundle(packageAsset.BundleID); + _bundleGUIDs.Add(bundle.BundleGUID); + } + } + return true; + } + } + internal sealed class SFCClearCacheByTagsOperation : SFCClearCacheOperation + { + internal SFCClearCacheByTagsOperation(SandboxFileCache fileCache, ClearCacheOptions options) + : base(fileCache, options) { } + + protected override bool ParseOptionsStep() + { + if (_options.Manifest == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Can not found active package manifest."; + return false; + } + + if (_options.ClearParam == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Clear param is null."; + return false; + } + + string[] tags; + if (_options.ClearParam is string str) + tags = new string[] { str }; + else if (_options.ClearParam is List list) + tags = list.ToArray(); + else if (_options.ClearParam is string[] array) + tags = array; + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Invalid clear param : {_options.ClearParam.GetType().FullName}"; + return false; + } + + var allEntrys = _fileCache.GetAllEntries(); + _bundleGUIDs = new List(allEntrys.Count); + foreach (var entry in allEntrys) + { + if (_options.Manifest.TryGetPackageBundleByBundleGUID(entry.BundleGUID, out PackageBundle bundle)) + { + if (bundle.HasTag(tags)) + _bundleGUIDs.Add(bundle.BundleGUID); + } + } + return true; + } + } +} diff --git a/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCClearCacheOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCClearCacheOperation.cs.meta new file mode 100644 index 00000000..d056c6bc --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCClearCacheOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6b2b38871a288e4469d417e66999f18d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCInitializeOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCInitializeOperation.cs new file mode 100644 index 00000000..a0dfb23b --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCInitializeOperation.cs @@ -0,0 +1,77 @@ + +namespace YooAsset +{ + internal class SFCInitializeOperation : FCInitializeOperation + { + private enum ESteps + { + None, + SearchCacheFiles, + VerifyCacheFiles, + Done, + } + + private readonly SandboxFileCache _cache; + private SearchCacheFilesOperation _searchCacheFilesOp; + private VerifyCacheFilesOperation _verifyCacheFilesOp; + private ESteps _steps = ESteps.None; + + public SFCInitializeOperation(SandboxFileCache cache) + { + _cache = cache; + } + internal override void InternalStart() + { + _steps = ESteps.SearchCacheFiles; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.SearchCacheFiles) + { + if (_searchCacheFilesOp == null) + { + _searchCacheFilesOp = new SearchCacheFilesOperation(_cache); + _searchCacheFilesOp.StartOperation(); + AddChildOperation(_searchCacheFilesOp); + } + + _searchCacheFilesOp.UpdateOperation(); + Progress = _searchCacheFilesOp.Progress; + if (_searchCacheFilesOp.IsDone == false) + return; + + _steps = ESteps.VerifyCacheFiles; + } + + if (_steps == ESteps.VerifyCacheFiles) + { + if (_verifyCacheFilesOp == null) + { + _verifyCacheFilesOp = new VerifyCacheFilesOperation(_cache, _cache.Config.FileVerifyLevel, _cache.Config.FileVerifyMaxConcurrency, _searchCacheFilesOp.Result); + _verifyCacheFilesOp.StartOperation(); + AddChildOperation(_verifyCacheFilesOp); + } + + _verifyCacheFilesOp.UpdateOperation(); + Progress = _verifyCacheFilesOp.Progress; + if (_verifyCacheFilesOp.IsDone == false) + return; + + if (_verifyCacheFilesOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _verifyCacheFilesOp.Error; + } + } + } + } +} diff --git a/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCInitializeOperation.cs.meta new file mode 100644 index 00000000..a9820a38 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9be990c57fe162845ba3893188a68f8b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCLoadBundleOperation.cs new file mode 100644 index 00000000..016ee6ff --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCLoadBundleOperation.cs @@ -0,0 +1,225 @@ +using System; +using System.IO; +using UnityEngine; + +namespace YooAsset +{ + internal class SFCLoadAssetBundleOperation : FCLoadBundleOperation + { + private enum ESteps + { + None, + LoadAssetBundle, + CheckResult, + TryFallback, + Done, + } + + private readonly SandboxFileCache _fileCache; + private readonly PackageBundle _bundle; + private FCVerifyCacheOperation _verifyCacheOp; + private AssetBundleCreateRequest _createRequest; + private AssetBundle _assetBundle; + private string _filePath; + private ESteps _steps = ESteps.None; + + public SFCLoadAssetBundleOperation(SandboxFileCache fileCache, PackageBundle bundle) + { + _fileCache = fileCache; + _bundle = bundle; + } + internal override void InternalStart() + { + _steps = ESteps.LoadAssetBundle; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadAssetBundle) + { + var entry = _fileCache.GetEntry(_bundle.BundleGUID); + if (entry == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Not found file cache entry: {_bundle.BundleGUID}"; + return; + } + + _filePath = entry.DataFilePath; + if (IsWaitForCompletion) + _assetBundle = AssetBundle.LoadFromFile(_filePath); + else + _createRequest = AssetBundle.LoadFromFileAsync(_filePath); + + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (_createRequest != null) + { + if (IsWaitForCompletion) + { + // 强制挂起主线程(注意:该操作会很耗时) + 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) + { + _steps = ESteps.TryFallback; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + BundleResult = new AssetBundleResult(_filePath, _bundle, _assetBundle, null); + } + } + + if (_steps == ESteps.TryFallback) + { + // 注意:当缓存文件的校验等级为Low的时候,并不能保证缓存文件的完整性。 + // 说明:在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性! + if (_verifyCacheOp == null) + { + var options = new VerifyCacheOptions(); + options.Bundle = _bundle; + options.FailedDeleteCache = true; + _verifyCacheOp = _fileCache.VerifyCacheAsync(options); + _verifyCacheOp.StartOperation(); + AddChildOperation(_verifyCacheOp); + } + + if (IsWaitForCompletion) + _verifyCacheOp.WaitForCompletion(); + + _verifyCacheOp.UpdateOperation(); + if (_verifyCacheOp.IsDone == false) + return; + + if (_verifyCacheOp.Status == EOperationStatus.Succeeded) + { + // 调用后备加载方法 + // 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。 + // 说明:大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发! + AssetBundle assetBundle = LoadFromMemory(); + if (assetBundle != null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + BundleResult = new AssetBundleResult(_filePath, _bundle, assetBundle, null); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load asset bundle from memory : {_bundle.BundleName}"; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _verifyCacheOp.Error; + } + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + + private AssetBundle LoadFromMemory() + { + byte[] fileData = FileUtility.ReadAllBytes(_filePath); + if (fileData == null || fileData.Length == 0) + return null; + return AssetBundle.LoadFromMemory(fileData); + } + } + + internal class SFCLoadRawBundleOperation : FCLoadBundleOperation + { + private enum ESteps + { + None, + LoadRawBundle, + Done, + } + + private readonly SandboxFileCache _fileCache; + private readonly PackageBundle _bundle; + private ESteps _steps = ESteps.None; + + public SFCLoadRawBundleOperation(SandboxFileCache fileCache, PackageBundle bundle) + { + _fileCache = fileCache; + _bundle = bundle; + } + internal override void InternalStart() + { + _steps = ESteps.LoadRawBundle; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadRawBundle) + { + var entry = _fileCache.GetEntry(_bundle.BundleGUID); + if (entry == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Not found file cache entry: {_bundle.BundleGUID}"; + return; + } + + string filePath = entry.DataFilePath; + if (File.Exists(filePath)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + + byte[] data = File.ReadAllBytes(filePath); + var rawBundle = new RawBundle(data); + BundleResult = new RawBundleResult(filePath, _bundle, rawBundle); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Can not found raw bundle file : {filePath}"; + } + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + } + + internal abstract class SFCLoadAssetBundleFromOperation : FCLoadBundleOperation + { + internal abstract AssetBundle LoadFromOffset(); + internal abstract AssetBundleCreateRequest LoadFromOffsetAsync(); + + internal abstract AssetBundle LoadFromMemory(); + internal abstract AssetBundleCreateRequest LoadFromMemoryAsync(); + + internal abstract AssetBundle LoadFromStream(); + internal abstract AssetBundleCreateRequest LoadFromStreamAsync(); + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCLoadBundleOperation.cs.meta new file mode 100644 index 00000000..489ec177 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e2d1d282be4d504caae567b9c00dc18 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCVerifyCacheOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCVerifyCacheOperation.cs new file mode 100644 index 00000000..02d60e95 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCVerifyCacheOperation.cs @@ -0,0 +1,89 @@ + +namespace YooAsset +{ + internal class SFCVerifyCacheOperation : FCVerifyCacheOperation + { + private enum ESteps + { + None, + Check, + VerifyFile, + Done, + } + + private readonly SandboxFileCache _fileCache; + private readonly VerifyCacheOptions _options; + private VerifyTempFileOperation _verifyOperation; + private ESteps _steps = ESteps.None; + + public SFCVerifyCacheOperation(SandboxFileCache cache, VerifyCacheOptions options) + { + _fileCache = cache; + _options = options; + } + internal override void InternalStart() + { + _steps = ESteps.Check; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.Check) + { + if (_fileCache.IsCached(_options.Bundle.BundleGUID) == false) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Not found cached bundle."; + } + else + { + _steps = ESteps.VerifyFile; + } + } + + if (_steps == ESteps.VerifyFile) + { + if (_verifyOperation == null) + { + var entry = _fileCache.GetEntry(_options.Bundle.BundleGUID); + var element = new TempFileInfo(entry.DataFilePath, _options.Bundle.FileCRC, _options.Bundle.FileSize); + _verifyOperation = new VerifyTempFileOperation(element); + _verifyOperation.StartOperation(); + AddChildOperation(_verifyOperation); + } + + if (IsWaitForCompletion) + _verifyOperation.WaitForCompletion(); + + _verifyOperation.UpdateOperation(); + if (_verifyOperation.IsDone == false) + return; + + if (_verifyOperation.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _verifyOperation.Error; + + if (_options.FailedDeleteCache) + { + YooLogger.Error($"Find corrupted bundle file and remove cache entry : {_options.Bundle.BundleGUID}"); + _fileCache.RemoveEntry(_options.Bundle.BundleGUID); + } + } + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + } +} diff --git a/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCVerifyCacheOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCVerifyCacheOperation.cs.meta new file mode 100644 index 00000000..0c3f8f35 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCVerifyCacheOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d290fdbfa73ffa04a825cea659b23796 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCStoreCacheOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCWriteCacheOperation.cs similarity index 83% rename from Assets/YooAsset/Runtime/FileCache/Operations/FCStoreCacheOperation.cs rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCWriteCacheOperation.cs index 7a9d4309..a01c6205 100644 --- a/Assets/YooAsset/Runtime/FileCache/Operations/FCStoreCacheOperation.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCWriteCacheOperation.cs @@ -3,7 +3,7 @@ using System.IO; namespace YooAsset { - internal class FCStoreCacheOperation : AsyncOperationBase + internal class SFCWriteCacheOperation : FCWriteCacheOperation { private enum ESteps { @@ -14,12 +14,12 @@ namespace YooAsset Done, } - private BundleCache _cache; - private readonly FCStoreCacheOptions _options; + private readonly SandboxFileCache _cache; + private readonly WriteCacheOptions _options; private VerifyTempFileOperation _verifyOperation; private ESteps _steps = ESteps.None; - public FCStoreCacheOperation(BundleCache cache, FCStoreCacheOptions options) + public SFCWriteCacheOperation(SandboxFileCache cache, WriteCacheOptions options) { _cache = cache; _options = options; @@ -35,14 +35,6 @@ namespace YooAsset if (_steps == ESteps.Check) { - if (_cache.IsReadOnly) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"{nameof(BundleCache)} is readonly."; - return; - } - if (_cache.IsCached(_options.Bundle.BundleGUID)) { _steps = ESteps.Done; @@ -97,12 +89,12 @@ namespace YooAsset File.Delete(dataFilePath); // 拷贝数据文件 - FileUtility.CreateFileDirectory(dataFilePath); + FileUtility.EnsureFileDirectory(dataFilePath); FileInfo fileInfo = new FileInfo(_options.FilePath); fileInfo.CopyTo(dataFilePath, true); // 写入信息文件 - FileUtility.CreateFileDirectory(infoFilePath); + FileUtility.EnsureFileDirectory(infoFilePath); using (FileStream fs = new FileStream(infoFilePath, FileMode.Create, FileAccess.Write, FileShare.Read)) { _cache.SharedBuffer.Clear(); @@ -121,7 +113,7 @@ namespace YooAsset return; //失败后直接返回 } - var cacheEntry = new BundleCacheEntry(_options.Bundle.BundleGUID, infoFilePath, dataFilePath, _options.Bundle.FileCRC, _options.Bundle.FileSize); + var cacheEntry = new SandboxFileCacheEntry(_options.Bundle.BundleGUID, infoFilePath, dataFilePath); _cache.AddEntry(_options.Bundle.BundleGUID, cacheEntry); _steps = ESteps.Done; Status = EOperationStatus.Succeeded; diff --git a/Assets/YooAsset/Runtime/FileCache/Operations/FCStoreCacheOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCWriteCacheOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Operations/FCStoreCacheOperation.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/Operations/SFCWriteCacheOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCache.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCache.cs new file mode 100644 index 00000000..0971fc43 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCache.cs @@ -0,0 +1,230 @@ +using System; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class SandboxFileCache : IFileCache + { + internal struct CacheConfig + { + /// + /// 文件校验最大并发数 + /// + public int FileVerifyMaxConcurrency { get; set; } + + /// + /// 文件校验级别 + /// + public EFileVerifyLevel FileVerifyLevel { get; set; } + } + + private const int HashFolderLength = 2; + private readonly Dictionary _caches = new Dictionary(10000); + private readonly Dictionary _dataFilePathMapping = new Dictionary(10000); + private readonly Dictionary _infoFilePathMapping = new Dictionary(10000); + + // 缓存配置 + internal readonly CacheConfig Config; + + // 共享缓冲区 + internal readonly BufferWriter SharedBuffer = new BufferWriter(1024); + + #region 接口属性 + /// + /// 包裹名称 + /// + public string PackageName { get; } + + /// + /// 缓存根目录 + /// + public string RootPath { get; } + + /// + /// 只读属性 + /// + public bool IsReadOnly { get; } + + /// + /// 缓存文件数量 + /// + public int FileCount + { + get + { + return _caches.Count; + } + } + + /// + /// 已占用空间 + /// 说明:按缓存索引累计 + /// + public long SpaceOccupied { get; private set; } + #endregion + + public SandboxFileCache(string packageName, string rootPath, CacheConfig config) + { + PackageName = packageName; + RootPath = rootPath; + Config = config; + IsReadOnly = false; + } + public void Dispose() + { + } + public virtual FCInitializeOperation InitializeAsync() + { + var operation = new SFCInitializeOperation(this); + return operation; + } + public virtual FCWriteCacheOperation WriteCacheAsync(WriteCacheOptions options) + { + var operation = new SFCWriteCacheOperation(this, options); + return operation; + } + public virtual FCClearCacheOperation ClearCacheAsync(ClearCacheOptions options) + { + if (options.ClearMode == EFileClearMode.ClearAllBundleFiles.ToString()) + { + var operation = new SFCClearAllCacheOperation(this, options); + return operation; + } + else if (options.ClearMode == EFileClearMode.ClearUnusedBundleFiles.ToString()) + { + var operation = new SFCClearUnusedCacheOperation(this, options); + return operation; + } + else if (options.ClearMode == EFileClearMode.ClearBundleFilesByLocations.ToString()) + { + var operation = new SFCClearCacheByLocationsOperation(this, options); + return operation; + } + else if (options.ClearMode == EFileClearMode.ClearBundleFilesByTags.ToString()) + { + var operation = new SFCClearCacheByTagsOperation(this, options); + return operation; + } + else + { + string error = $"Invalid clear mode : {options.ClearMode}"; + var operation = new FCClearCacheCompleteOperation(error); + return operation; + } + } + public virtual FCVerifyCacheOperation VerifyCacheAsync(VerifyCacheOptions options) + { + var operation = new SFCVerifyCacheOperation(this, options); + return operation; + } + public virtual FCLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) + { + if (options.Bundle.BundleType == (int)EBundleType.AssetBundle) + { + var operation = new SFCLoadAssetBundleOperation(this, options.Bundle); + return operation; + } + else if (options.Bundle.BundleType == (int)EBundleType.RawBundle) + { + var operation = new SFCLoadRawBundleOperation(this, options.Bundle); + return operation; + } + else + { + string error = $"{nameof(SandboxFileCache)} not support load bundle type : {options.Bundle.BundleType}"; + var operation = new FCLoadBundleErrorOperation(error); + return operation; + } + } + public virtual bool IsCached(string bundleGUID) + { + return _caches.ContainsKey(bundleGUID); + } + + #region 内部方法 + /// + /// 获取 Bundle 数据文件路径 + /// + internal string GetDataFilePath(PackageBundle bundle) + { + if (_dataFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false) + { + string folderName = GetHashFolderName(bundle.FileHash); + filePath = PathUtility.Combine(RootPath, folderName, bundle.BundleGUID, SandboxFileCacheDefine.BundleDataFileName); + _dataFilePathMapping.Add(bundle.BundleGUID, filePath); + } + return filePath; + } + + /// + /// 获取 Bundle 信息文件路径 + /// + internal string GetInfoFilePath(PackageBundle bundle) + { + if (_infoFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false) + { + string folderName = GetHashFolderName(bundle.FileHash); + filePath = PathUtility.Combine(RootPath, folderName, bundle.BundleGUID, SandboxFileCacheDefine.BundleInfoFileName); + _infoFilePathMapping.Add(bundle.BundleGUID, filePath); + } + return filePath; + } + + /// + /// 获取指定缓存 + /// + internal SandboxFileCacheEntry GetEntry(string bundleGUID) + { + if (_caches.TryGetValue(bundleGUID, out SandboxFileCacheEntry entry)) + return entry; + else + return null; + } + + /// + /// 获取所有缓存 + /// + internal IReadOnlyCollection GetAllEntries() + { + return _caches.Values; + } + + /// + /// 添加指定缓存 + /// + internal void AddEntry(string bundleGUID, SandboxFileCacheEntry entry) + { + if (_caches.ContainsKey(bundleGUID)) + throw new YooInternalException($"Cache entry already existed: {bundleGUID}"); + + _caches.Add(bundleGUID, entry); + SpaceOccupied += entry.GetFileSize(); + } + + /// + /// 删除指定缓存 + /// + internal void RemoveEntry(string bundleGUID) + { + if (_caches.TryGetValue(bundleGUID, out SandboxFileCacheEntry entry)) + { + _caches.Remove(bundleGUID); + _dataFilePathMapping.Remove(bundleGUID); + _infoFilePathMapping.Remove(bundleGUID); + SpaceOccupied -= entry.GetFileSize(); + entry.Delete(); + } + } + + private string GetHashFolderName(string fileHash) + { + if (string.IsNullOrEmpty(fileHash)) + throw new YooInternalException(); + + if (fileHash.Length <= HashFolderLength) + return fileHash; + return fileHash.Substring(0, HashFolderLength); + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCache.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCache.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCache.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCache.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCacheDefine.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCacheDefine.cs similarity index 88% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCacheDefine.cs rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCacheDefine.cs index 0bcbef64..6f4ee2ab 100644 --- a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCacheDefine.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCacheDefine.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class BundleCacheDefine + internal class SandboxFileCacheDefine { /// /// 数据文件名称 diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCacheDefine.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCacheDefine.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCacheDefine.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCacheDefine.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCacheEntry.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCacheEntry.cs similarity index 61% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCacheEntry.cs rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCacheEntry.cs index 82bfe8fb..eb942296 100644 --- a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCacheEntry.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCacheEntry.cs @@ -3,30 +3,18 @@ using System.IO; namespace YooAsset { - internal class BundleCacheEntry : ICacheEntry + internal class SandboxFileCacheEntry : ICacheEntry { public string BundleGUID { get; private set; } public string InfoFilePath { get; private set; } public string DataFilePath { get; private set; } - public uint DataFileCRC { get; private set; } - public long DataFileSize { get; private set; } + private long _fileSize = 0; - public BundleCacheEntry(string bundleGUID, string infoFilePath, string dataFilePath, uint dataFileCRC, long dataFileSize) + public SandboxFileCacheEntry(string bundleGUID, string infoFilePath, string dataFilePath) { BundleGUID = bundleGUID; InfoFilePath = infoFilePath; DataFilePath = dataFilePath; - DataFileCRC = dataFileCRC; - DataFileSize = dataFileSize; - } - - /// - /// 移动文件 - /// - public void MoveFile(string destFilePath) - { - File.Move(DataFilePath, destFilePath); - DataFilePath = destFilePath; } /// @@ -50,9 +38,19 @@ namespace YooAsset } catch (Exception ex) { - YooLogger.Error($"Failed to delete cache file. Error: {ex.Message}"); + YooLogger.Error($"Failed to delete sandbox file. Error: {ex.Message}"); return false; } } + + public long GetFileSize() + { + if (_fileSize == 0) + { + _fileSize = FileUtility.GetFileSize(InfoFilePath); + _fileSize += FileUtility.GetFileSize(DataFilePath); + } + return _fileSize; + } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCacheEntry.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCacheEntry.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/BundleFileCacheEntry.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/SandboxFileCacheEntry.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/TempFileInfo.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/TempFileInfo.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/TempFileInfo.cs rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/TempFileInfo.cs diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/TempFileInfo.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/TempFileInfo.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/TempFileInfo.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/TempFileInfo.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/VerifyFileInfo.cs b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/VerifyFileInfo.cs similarity index 64% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/VerifyFileInfo.cs rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/VerifyFileInfo.cs index 3f759e63..24dd8e9d 100644 --- a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/VerifyFileInfo.cs +++ b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/VerifyFileInfo.cs @@ -4,35 +4,24 @@ namespace YooAsset { internal class VerifyFileInfo { - public string PackageName { get; private set; } public string BundleGUID { get; private set; } public string FolderPath { get; private set; } public string DataFilePath { get; private set; } public string InfoFilePath { get; private set; } - public uint DataFileCRC { get; private set; } - public long DataFileSize { get; private set; } - /// /// 注意:原子操作对象 /// public volatile int Result = 0; - public VerifyFileInfo(string packageName, string bundleGUID, string folderPath, string dataFilePath, string infoFilePath) + public VerifyFileInfo(string bundleGUID, string folderPath, string dataFilePath, string infoFilePath) { - PackageName = packageName; BundleGUID = bundleGUID; FolderPath = folderPath; DataFilePath = dataFilePath; InfoFilePath = infoFilePath; } - public void SetDataFileInfo(uint dataFileCRC, long dataFileSize) - { - DataFileCRC = dataFileCRC; - DataFileSize = dataFileSize; - } - public void DeleteFiles() { try diff --git a/Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/VerifyFileInfo.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/VerifyFileInfo.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileCache/Services/BundleFileCache/VerifyFileInfo.cs.meta rename to Assets/YooAsset/Runtime/FileCache/Services/SandboxFileCache/VerifyFileInfo.cs.meta diff --git a/Assets/YooAsset/Runtime/FileCache/Services/UnityFileCache.meta b/Assets/YooAsset/Runtime/FileCache/Services/UnityFileCache.meta new file mode 100644 index 00000000..f508a067 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/UnityFileCache.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0a0a41496ce76334a958424c79db1016 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/UnityFileCache/Operations.meta b/Assets/YooAsset/Runtime/FileCache/Services/UnityFileCache/Operations.meta new file mode 100644 index 00000000..3e017e14 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/UnityFileCache/Operations.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 65bba40cd16af3a47bddda520ab51d6b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache.meta new file mode 100644 index 00000000..79fbb997 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bc4cd72a390c1054a99c49a7c501c8f6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations.meta new file mode 100644 index 00000000..012833d8 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a466429abacca2f40aacb9ab5a9ffebf +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations/WRFCInitializeOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations/WRFCInitializeOperation.cs new file mode 100644 index 00000000..b833d930 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations/WRFCInitializeOperation.cs @@ -0,0 +1,20 @@ + +namespace YooAsset +{ + internal class WRFCInitializeOperation : FCInitializeOperation + { + private readonly WebRemoteFileCache _fileCache; + + public WRFCInitializeOperation(WebRemoteFileCache cache) + { + _fileCache = cache; + } + internal override void InternalStart() + { + Status = EOperationStatus.Succeeded; + } + internal override void InternalUpdate() + { + } + } +} diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations/WRFCInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations/WRFCInitializeOperation.cs.meta new file mode 100644 index 00000000..eea7a60c --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations/WRFCInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 476dbbea577819a43a807f22bb91f974 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations/WRFCLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations/WRFCLoadBundleOperation.cs new file mode 100644 index 00000000..dfd18939 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations/WRFCLoadBundleOperation.cs @@ -0,0 +1,126 @@ + +namespace YooAsset +{ + internal class WRFCLoadAssetBundleOperation : FCLoadBundleOperation + { + private enum ESteps + { + None, + CreateRequest, + CheckRequest, + TryAgain, + Done, + } + + private readonly WebRemoteFileCache _fileCache; + private readonly LoadBundleOptions _options; + private IDownloadAssetBundleRequest _downloadAssetBundleRequest; + private ESteps _steps = ESteps.None; + + // 失败重试 + private int _requestCount = 0; + private float _tryAgainTimer = 0; + private int _failedTryAgain; + + public WRFCLoadAssetBundleOperation(WebRemoteFileCache fileCache, LoadBundleOptions options) + { + _fileCache = fileCache; + _options = options; + _failedTryAgain = fileCache.Config.RetryCount; + } + internal override void InternalStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CreateRequest) + { + var entry = _fileCache.GetEntry(_options.Bundle); + if(entry == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Not found file cache entry: {_options.Bundle.BundleGUID}"; + return; + } + + string url = GetRequestURL(entry); + var args = new DownloadAssetBundleRequestArgs(url, 0, _fileCache.Config.WatchdogTimeout, _fileCache.Config.DisableUnityWebCache, _options.Bundle.FileHash, _options.Bundle.UnityCRC); + _downloadAssetBundleRequest = _fileCache.Config.DownloadBackend.CreateAssetBundleRequest(args); + _downloadAssetBundleRequest.SendRequest(); + _steps = ESteps.CheckRequest; + } + + if (_steps == ESteps.CheckRequest) + { + Progress = _downloadAssetBundleRequest.DownloadProgress; + if (_downloadAssetBundleRequest.IsDone == false) + return; + + if (_downloadAssetBundleRequest.Status == EDownloadRequestStatus.Succeeded) + { + var assetBundle = _downloadAssetBundleRequest.Result; + if (assetBundle == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load asset bundle : {_options.Bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + BundleResult = new AssetBundleResult(null, _options.Bundle, assetBundle, null); + } + } + else + { + if (_failedTryAgain > 0) + { + _steps = ESteps.TryAgain; + YooLogger.Warning($"Failed download : {_downloadAssetBundleRequest.Url} Try again."); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadAssetBundleRequest.Error; + YooLogger.Error(Error); + } + } + + // 最终释放请求器 + _downloadAssetBundleRequest.Dispose(); + } + + if (_steps == ESteps.TryAgain) + { + _tryAgainTimer += UnityEngine.Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + _tryAgainTimer = 0f; + _failedTryAgain--; + Progress = 0f; + _steps = ESteps.CreateRequest; + } + } + } + + /// + /// 获取网络请求地址 + /// + protected string GetRequestURL(WebRemoteFileCacheEntry entry) + { + // 轮流返回请求地址 + _requestCount++; + if (_requestCount % 2 == 0) + return entry.FallbackURL; + else + return entry.MainURL; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations/WRFCLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations/WRFCLoadBundleOperation.cs.meta new file mode 100644 index 00000000..8fc835f6 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/Operations/WRFCLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8821049e94e79ff4b9c83c24e7b10d49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/WebRemoteFileCache.cs b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/WebRemoteFileCache.cs new file mode 100644 index 00000000..8ab7b6fc --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/WebRemoteFileCache.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class WebRemoteFileCache : IFileCache + { + internal struct CacheConfig + { + /// + /// 禁用Unity的网络缓存 + /// + public bool DisableUnityWebCache { get; set; } + + public IRemoteServices RemoteServices { get; set; } + + /// + /// 下载后台接口 + /// + public IDownloadBackend DownloadBackend { get; set; } + + /// + /// 看门狗超时时间 + /// + public int WatchdogTimeout { get; set; } + + /// + /// 失败后重试次数 + /// + public int RetryCount { get; set; } + } + + private readonly Dictionary _caches = new Dictionary(10000); + + // 缓存配置 + internal readonly CacheConfig Config; + + #region 接口属性 + /// + /// 包裹名称 + /// + public string PackageName { get; } + + /// + /// 缓存根目录 + /// + public string RootPath { get; } + + /// + /// 只读属性 + /// + public bool IsReadOnly { get; } + + /// + /// 缓存文件数量 + /// + public int FileCount + { + get + { + return 0; + } + } + + /// + /// 已占用空间 + /// 说明:按缓存索引累计 + /// + public long SpaceOccupied { get; private set; } + #endregion + + public WebRemoteFileCache(string packageName, string rootPath, CacheConfig config) + { + PackageName = packageName; + RootPath = rootPath; + Config = config; + IsReadOnly = true; + } + public void Dispose() + { + } + public virtual FCInitializeOperation InitializeAsync() + { + var operation = new WRFCInitializeOperation(this); + return operation; + } + public virtual FCWriteCacheOperation WriteCacheAsync(WriteCacheOptions options) + { + var operation = new FCWriteCacheCompleteOperation($"{nameof(WebRemoteFileCache)} is readonly."); + return operation; + } + public virtual FCClearCacheOperation ClearCacheAsync(ClearCacheOptions options) + { + var operation = new FCClearCacheCompleteOperation($"{nameof(WebRemoteFileCache)} is readonly."); + return operation; + } + public virtual FCVerifyCacheOperation VerifyCacheAsync(VerifyCacheOptions options) + { + var operation = new FCVerifyCacheCompleteOperation(); + return operation; + } + public virtual FCLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) + { + var operation = new WRFCLoadAssetBundleOperation(this, options); + return operation; + } + public virtual bool IsCached(string bundleGUID) + { + return true; + } + + #region 内部方法 + public WebRemoteFileCacheEntry GetEntry(PackageBundle bundle) + { + if (_caches.TryGetValue(bundle.BundleGUID, out WebRemoteFileCacheEntry entry)) + { + return entry; + } + else + { + string mainURL = Config.RemoteServices.GetRemoteMainURL(bundle.FileName); + string fallbackURL = Config.RemoteServices.GetRemoteFallbackURL(bundle.FileName); + var newEntry = new WebRemoteFileCacheEntry(bundle.BundleGUID, mainURL, fallbackURL); + _caches.Add(bundle.BundleGUID, newEntry); + return newEntry; + } + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/WebRemoteFileCache.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/WebRemoteFileCache.cs.meta new file mode 100644 index 00000000..8137b7b1 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/WebRemoteFileCache.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ebc556c0bb6cbe146a502e678761ace1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/WebRemoteFileCacheEntry.cs b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/WebRemoteFileCacheEntry.cs new file mode 100644 index 00000000..5e7b519a --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/WebRemoteFileCacheEntry.cs @@ -0,0 +1,17 @@ + +namespace YooAsset +{ + internal class WebRemoteFileCacheEntry : ICacheEntry + { + public string BundleGUID { get; private set; } + public string MainURL { get; private set; } + public string FallbackURL { get; private set; } + + public WebRemoteFileCacheEntry(string bundleGUID, string mainURL, string fallbackURL) + { + BundleGUID = bundleGUID; + MainURL = mainURL; + FallbackURL = fallbackURL; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/WebRemoteFileCacheEntry.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/WebRemoteFileCacheEntry.cs.meta new file mode 100644 index 00000000..21233e0c --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebRemoteFileCache/WebRemoteFileCacheEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c5756c583ed1474c9abb56419b488d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache.meta new file mode 100644 index 00000000..ba975ee2 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5e50d99b8d687a745be0dd0edb2265aa +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations.meta new file mode 100644 index 00000000..c4c5d2e8 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4226fb773131d8944b33a10dbfb46b13 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/Internal.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/Internal.meta new file mode 100644 index 00000000..ecc5cf33 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/Internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a72d34ce1de343d4291428371af736a5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/Internal/LoadWebServerCatalogOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/Internal/LoadWebServerCatalogOperation.cs new file mode 100644 index 00000000..6792169a --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/Internal/LoadWebServerCatalogOperation.cs @@ -0,0 +1,96 @@ +using System; + +namespace YooAsset +{ + internal sealed class LoadWebServerCatalogOperation : AsyncOperationBase + { + private enum ESteps + { + None, + RequestFileData, + LoadCatalog, + CheckResut, + Done, + } + + private readonly WebServerFileCache _fileCache; + private IDownloadBytesRequest _webDataRequestOp; + private byte[] _fileData; + private ESteps _steps = ESteps.None; + + /// + /// 内置资源目录 + /// + public BuiltinFileCatalog Catalog; + + internal LoadWebServerCatalogOperation(WebServerFileCache fileCache) + { + _fileCache = fileCache; + } + internal override void InternalStart() + { + _steps = ESteps.RequestFileData; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestFileData) + { + if (_webDataRequestOp == null) + { + string filePath = _fileCache.GetCatalogBinaryFileLoadPath(); + string url = DownloadSystemTools.ToLocalUrl(filePath); + var args = new DownloadDataRequestArgs(url, 60, 0); + _webDataRequestOp = _fileCache.Config.DownloadBackend.CreateBytesRequest(args); + _webDataRequestOp.SendRequest(); + } + + if (_webDataRequestOp.IsDone == false) + return; + + if (_webDataRequestOp.Status == EDownloadRequestStatus.Succeeded) + { + _fileData = _webDataRequestOp.Result; + _steps = ESteps.LoadCatalog; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webDataRequestOp.Error; + } + } + + if (_steps == ESteps.LoadCatalog) + { + try + { + Catalog = BuiltinFileCatalogTools.DeserializeFromBinary(_fileData); + _steps = ESteps.CheckResut; + } + catch (Exception ex) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load catalog file : {ex.Message}"; + } + } + + if (_steps == ESteps.CheckResut) + { + if (Catalog.PackageName != _fileCache.PackageName) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Catalog file package name {Catalog.PackageName} cannot match the file cache package name {_fileCache.PackageName}"; + return; + } + + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/Internal/LoadWebServerCatalogOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/Internal/LoadWebServerCatalogOperation.cs.meta new file mode 100644 index 00000000..bc7c85d1 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/Internal/LoadWebServerCatalogOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 236fcfdca8d96624087432269508ccee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/WSFCInitializeOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/WSFCInitializeOperation.cs new file mode 100644 index 00000000..32727824 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/WSFCInitializeOperation.cs @@ -0,0 +1,68 @@ + +namespace YooAsset +{ + internal class WSFCInitializeOperation : FCInitializeOperation + { + private enum ESteps + { + None, + LoadCatalogFile, + RecordFiles, + Done, + } + + private readonly WebServerFileCache _fileCache; + private LoadWebServerCatalogOperation _loadWebCatalogFileOp; + private ESteps _steps = ESteps.None; + + public WSFCInitializeOperation(WebServerFileCache cache) + { + _fileCache = cache; + } + internal override void InternalStart() + { + _steps = ESteps.LoadCatalogFile; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadCatalogFile) + { + if (_loadWebCatalogFileOp == null) + { + _loadWebCatalogFileOp = new LoadWebServerCatalogOperation(_fileCache); + _loadWebCatalogFileOp.StartOperation(); + AddChildOperation(_loadWebCatalogFileOp); + } + + _loadWebCatalogFileOp.UpdateOperation(); + if (_loadWebCatalogFileOp.IsDone == false) + return; + + if (_loadWebCatalogFileOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.RecordFiles; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadWebCatalogFileOp.Error; + } + } + + if (_steps == ESteps.RecordFiles) + { + var catalog = _loadWebCatalogFileOp.Catalog; + foreach (var wrapper in catalog.Wrappers) + { + string filePath = PathUtility.Combine(_fileCache.RootPath, wrapper.FileName); + var entry = new WebServerFileCacheEntry(wrapper.BundleGUID, filePath); + _fileCache.AddEntry(wrapper.BundleGUID, entry); + } + } + } + } +} diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/WSFCInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/WSFCInitializeOperation.cs.meta new file mode 100644 index 00000000..78443540 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/WSFCInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2710cae107609a428017f2ead0bc30b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/WSFCLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/WSFCLoadBundleOperation.cs new file mode 100644 index 00000000..a0edc3ac --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/WSFCLoadBundleOperation.cs @@ -0,0 +1,112 @@ + +namespace YooAsset +{ + internal class WFCLoadAssetBundleOperation : FCLoadBundleOperation + { + private enum ESteps + { + None, + CreateRequest, + CheckRequest, + TryAgain, + Done, + } + + private readonly WebServerFileCache _fileCache; + private readonly LoadBundleOptions _options; + private IDownloadAssetBundleRequest _downloadAssetBundleRequest; + private ESteps _steps = ESteps.None; + + // 失败重试 + private float _tryAgainTimer = 0; + private int _failedTryAgain; + + public WFCLoadAssetBundleOperation(WebServerFileCache fileCache, LoadBundleOptions options) + { + _fileCache = fileCache; + _options = options; + _failedTryAgain = fileCache.Config.RetryCount; + } + internal override void InternalStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CreateRequest) + { + var entry = _fileCache.GetEntry(_options.Bundle.BundleGUID); + if (entry == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Not found file cache entry: {_options.Bundle.BundleGUID}"; + return; + } + + string url = DownloadSystemTools.ToLocalUrl(entry.FilePath); + var args = new DownloadAssetBundleRequestArgs(url, 0, _fileCache.Config.WatchdogTimeout, _fileCache.Config.DisableUnityWebCache, _options.Bundle.FileHash, _options.Bundle.UnityCRC); + _downloadAssetBundleRequest = _fileCache.Config.DownloadBackend.CreateAssetBundleRequest(args); + _downloadAssetBundleRequest.SendRequest(); + _steps = ESteps.CheckRequest; + } + + if (_steps == ESteps.CheckRequest) + { + Progress = _downloadAssetBundleRequest.DownloadProgress; + if (_downloadAssetBundleRequest.IsDone == false) + return; + + if (_downloadAssetBundleRequest.Status == EDownloadRequestStatus.Succeeded) + { + var assetBundle = _downloadAssetBundleRequest.Result; + if (assetBundle == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load asset bundle : {_options.Bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + BundleResult = new AssetBundleResult(null, _options.Bundle, assetBundle, null); + } + } + else + { + if (_failedTryAgain > 0) + { + _steps = ESteps.TryAgain; + YooLogger.Warning($"Failed download : {_downloadAssetBundleRequest.Url} Try again."); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadAssetBundleRequest.Error; + YooLogger.Error(Error); + } + } + + // 最终释放请求器 + _downloadAssetBundleRequest.Dispose(); + } + + if (_steps == ESteps.TryAgain) + { + _tryAgainTimer += UnityEngine.Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + _tryAgainTimer = 0f; + _failedTryAgain--; + Progress = 0f; + _steps = ESteps.CreateRequest; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/WSFCLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/WSFCLoadBundleOperation.cs.meta new file mode 100644 index 00000000..feafa2d1 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/Operations/WSFCLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88fc5dffb434550498b20a6615365d79 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/WebServerFileCache.cs b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/WebServerFileCache.cs new file mode 100644 index 00000000..0b8002f1 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/WebServerFileCache.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class WebServerFileCache : IFileCache + { + internal struct CacheConfig + { + /// + /// 禁用Unity的网络缓存 + /// + public bool DisableUnityWebCache { get; set; } + + /// + /// 下载后台接口 + /// + public IDownloadBackend DownloadBackend { get; set; } + + /// + /// 看门狗超时时间 + /// + public int WatchdogTimeout { get; set; } + + /// + /// 失败后重试次数 + /// + public int RetryCount { get; set; } + } + + private readonly Dictionary _caches = new Dictionary(10000); + + // 缓存配置 + internal readonly CacheConfig Config; + + #region 接口属性 + /// + /// 包裹名称 + /// + public string PackageName { get; } + + /// + /// 缓存根目录 + /// + public string RootPath { get; } + + /// + /// 只读属性 + /// + public bool IsReadOnly { get; } + + /// + /// 缓存文件数量 + /// + public int FileCount + { + get + { + return _caches.Count; + } + } + + /// + /// 已占用空间 + /// 说明:按缓存索引累计 + /// + public long SpaceOccupied { get; private set; } + #endregion + + public WebServerFileCache(string packageName, string rootPath, CacheConfig config) + { + PackageName = packageName; + RootPath = rootPath; + Config = config; + IsReadOnly = true; + } + public void Dispose() + { + } + public virtual FCInitializeOperation InitializeAsync() + { + var operation = new WSFCInitializeOperation(this); + return operation; + } + public virtual FCWriteCacheOperation WriteCacheAsync(WriteCacheOptions options) + { + var operation = new FCWriteCacheCompleteOperation($"{nameof(WebServerFileCache)} is readonly."); + return operation; + } + public virtual FCClearCacheOperation ClearCacheAsync(ClearCacheOptions options) + { + var operation = new FCClearCacheCompleteOperation($"{nameof(WebServerFileCache)} is readonly."); + return operation; + } + public virtual FCVerifyCacheOperation VerifyCacheAsync(VerifyCacheOptions options) + { + var operation = new FCVerifyCacheCompleteOperation(); + return operation; + } + public virtual FCLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) + { + var operation = new WFCLoadAssetBundleOperation(this, options); + return operation; + } + public virtual bool IsCached(string bundleGUID) + { + return _caches.ContainsKey(bundleGUID); + } + + #region 内部方法 + public WebServerFileCacheEntry GetEntry(string bundleGUID) + { + if (_caches.TryGetValue(bundleGUID, out WebServerFileCacheEntry entry)) + return entry; + else + return null; + } + + /// + /// 添加指定缓存 + /// + internal void AddEntry(string bundleGUID, WebServerFileCacheEntry entry) + { + if (_caches.ContainsKey(bundleGUID)) + throw new YooInternalException($"Cache entry already existed: {bundleGUID}"); + + _caches.Add(bundleGUID, entry); + } + + /// + /// 获取Catalog文件加载路径 + /// + internal string GetCatalogBinaryFileLoadPath() + { + return PathUtility.Combine(RootPath, BuiltinFileCatalogDefine.BinaryFileName); + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/WebServerFileCache.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/WebServerFileCache.cs.meta new file mode 100644 index 00000000..f5b628a7 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/WebServerFileCache.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b5ae230cefaf6b42acc88c66959e96e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/WebServerFileCacheEntry.cs b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/WebServerFileCacheEntry.cs new file mode 100644 index 00000000..47258ca3 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/WebServerFileCacheEntry.cs @@ -0,0 +1,15 @@ + +namespace YooAsset +{ + internal class WebServerFileCacheEntry : ICacheEntry + { + public string BundleGUID { get; private set; } + public string FilePath { get; private set; } + + public WebServerFileCacheEntry(string bundleGUID, string filePath) + { + BundleGUID = bundleGUID; + FilePath = filePath; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/WebServerFileCacheEntry.cs.meta b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/WebServerFileCacheEntry.cs.meta new file mode 100644 index 00000000..70a54fc4 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileCache/Services/WebServerFileCache/WebServerFileCacheEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e3532014be6b3c40bf7f1c6965f7b92 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Bundles/Interfaces.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Interfaces.meta new file mode 100644 index 00000000..2a35389e --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Bundles/Interfaces.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 28d3e3a0e46aa69409956804b57c6763 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Interfaces/IBundleResult.cs similarity index 54% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Interfaces/IBundleResult.cs index cc54bff6..403775f2 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Bundles/Interfaces/IBundleResult.cs @@ -2,37 +2,36 @@ namespace YooAsset { - internal abstract class BundleResult + internal interface IBundleResult { - /// - /// 卸载资源包文件 - /// - public abstract void UnloadBundleFile(); - /// /// 获取资源包文件的本地路径 /// - public abstract string GetBundleFilePath(); + string GetBundleFilePath(); + /// + /// 卸载资源包文件 + /// + void UnloadBundleFile(); /// /// 加载资源包内的资源对象 /// - public abstract FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo); + FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo); /// /// 加载资源包内的所有资源对象 /// - public abstract FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo); + FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo); /// /// 加载资源包内的资源对象及所有子资源对象 /// - public abstract FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo); + FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo); /// /// 加载资源包内的场景对象 /// - public abstract FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad); + FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad); } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Bundles/Interfaces/IBundleResult.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Interfaces/IBundleResult.cs.meta new file mode 100644 index 00000000..f06d5eb1 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Bundles/Interfaces/IBundleResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa22c10ed9b61b84b97c7210d37ef4f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Bundles/Operations.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Operations.meta new file mode 100644 index 00000000..22734bc4 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Bundles/Operations.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 41fa83d5319cbd545a1e8dde338daa2b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadAllAssetsOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadAllAssetsOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadAllAssetsOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadAllAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadAllAssetsOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadAllAssetsOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadAllAssetsOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadAssetOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadAssetOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadAssetOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadAssetOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadAssetOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadAssetOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadAssetOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadAssetOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadSceneOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadSceneOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadSceneOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadSceneOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadSceneOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadSceneOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadSceneOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadSceneOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadSubAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadSubAssetsOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadSubAssetsOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadSubAssetsOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadSubAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadSubAssetsOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadSubAssetsOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Operations/FSLoadSubAssetsOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Bundles/Services.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services.meta new file mode 100644 index 00000000..319ffdd9 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: eb7336783ded61a41b6a5ebccb17e310 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/AssetBundleResult.cs similarity index 61% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/AssetBundleResult.cs index 9d30d07e..abd271b9 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/AssetBundleResult.cs @@ -4,22 +4,25 @@ using UnityEngine.SceneManagement; namespace YooAsset { - internal class AssetBundleResult : BundleResult + internal class AssetBundleResult : IBundleResult { - private readonly IFileSystem _fileSystem; + private readonly string _bundleFilePath; private readonly PackageBundle _packageBundle; private readonly AssetBundle _assetBundle; private readonly Stream _managedStream; - public AssetBundleResult(IFileSystem fileSystem, PackageBundle packageBundle, AssetBundle assetBundle, Stream managedStream) + public AssetBundleResult(string bundleFilePath, PackageBundle packageBundle, AssetBundle assetBundle, Stream managedStream) { - _fileSystem = fileSystem; + _bundleFilePath = bundleFilePath; _packageBundle = packageBundle; _assetBundle = assetBundle; _managedStream = managedStream; } - - public override void UnloadBundleFile() + public string GetBundleFilePath() + { + return _bundleFilePath; + } + public void UnloadBundleFile() { if (_assetBundle != null) { @@ -32,27 +35,23 @@ namespace YooAsset _managedStream.Dispose(); } } - public override string GetBundleFilePath() - { - return _fileSystem.GetBundleFilePath(_packageBundle); - } - public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) + public FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) { var operation = new AssetBundleLoadAssetOperation(_packageBundle, _assetBundle, assetInfo); return operation; } - public override FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo) + public FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo) { var operation = new AssetBundleLoadAllAssetsOperation(_packageBundle, _assetBundle, assetInfo); return operation; } - public override FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo) + public FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo) { var operation = new AssetBundleLoadSubAssetsOperation(_packageBundle, _assetBundle, assetInfo); return operation; } - public override FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad) + public FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad) { var operation = new AssetBundleLoadSceneOperation(assetInfo, loadParams, suspendLoad); return operation; diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/AssetBundleResult.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/AssetBundleResult.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadAllAssetsOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadAllAssetsOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadAllAssetsOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadAllAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadAllAssetsOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadAllAssetsOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadAllAssetsOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadAssetOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadAssetOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadAssetOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadAssetOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadAssetOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadAssetOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadAssetOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadAssetOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadSceneOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadSceneOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadSceneOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadSceneOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadSceneOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadSceneOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadSceneOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadSceneOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadSubAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadSubAssetsOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadSubAssetsOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadSubAssetsOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadSubAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadSubAssetsOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/AssetBundleLoadSubAssetsOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/AssetBundleResult/Operations/AssetBundleLoadSubAssetsOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadAllAssetsOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadAllAssetsOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadAllAssetsOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadAllAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadAllAssetsOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadAllAssetsOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadAllAssetsOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadAssetOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadAssetOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadAssetOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadAssetOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadAssetOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadAssetOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadAssetOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadAssetOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadSceneOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadSceneOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadSceneOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadSceneOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadSceneOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadSceneOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadSceneOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadSceneOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadSubAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadSubAssetsOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadSubAssetsOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadSubAssetsOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadSubAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadSubAssetsOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operations/RawBundleLoadSubAssetsOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/Operations/RawBundleLoadSubAssetsOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawBundle.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawBundle.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawBundle.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawBundle.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawBundleResult.cs similarity index 53% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawBundleResult.cs index dfce426b..e4728beb 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawBundleResult.cs @@ -2,47 +2,46 @@ namespace YooAsset { - internal class RawBundleResult : BundleResult + internal class RawBundleResult : IBundleResult { - private readonly IFileSystem _fileSystem; + private readonly string _bundleFilePath; private readonly PackageBundle _packageBundle; private readonly RawBundle _rawBundle; - public RawBundleResult(IFileSystem fileSystem, PackageBundle packageBundle, RawBundle rawBundle) + public RawBundleResult(string bundleFilePath, PackageBundle packageBundle, RawBundle rawBundle) { - _fileSystem = fileSystem; + _bundleFilePath = bundleFilePath; _packageBundle = packageBundle; _rawBundle = rawBundle; } - - public override void UnloadBundleFile() + public string GetBundleFilePath() + { + return _bundleFilePath; + } + public void UnloadBundleFile() { if (_rawBundle != null) { _rawBundle.Unload(); } } - public override string GetBundleFilePath() - { - return _fileSystem.GetBundleFilePath(_packageBundle); - } - public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) + public FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) { var operation = new RawBundleLoadAssetOperation(_packageBundle, _rawBundle, assetInfo); return operation; } - public override FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo) + public FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo) { var operation = new RawBundleLoadAllAssetsOperation(); return operation; } - public override FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo) + public FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo) { var operation = new RawBundleLoadSubAssetsOperation(); return operation; } - public override FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad) + public FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad) { var operation = new RawBundleLoadSceneOperation(); return operation; diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawBundleResult.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawBundleResult.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawFileObject.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawFileObject.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawFileObject.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/RawBundleResult/RawFileObject.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadAllAssetsOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadAllAssetsOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadAllAssetsOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadAllAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadAllAssetsOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadAllAssetsOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadAllAssetsOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadAssetOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadAssetOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadAssetOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadAssetOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadAssetOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadAssetOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadAssetOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadAssetOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadSceneOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadSceneOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadSceneOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadSceneOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadSceneOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadSceneOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadSceneOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadSceneOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadSubAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadSubAssetsOperation.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadSubAssetsOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadSubAssetsOperation.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadSubAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadSubAssetsOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operations/VirtualBundleLoadSubAssetsOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/Operations/VirtualBundleLoadSubAssetsOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/VirtualBundleResult.cs similarity index 50% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/VirtualBundleResult.cs index 66c77e90..c1d2d7d8 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/VirtualBundleResult.cs @@ -2,41 +2,40 @@ namespace YooAsset { - internal class VirtualBundleResult : BundleResult + internal class VirtualBundleResult : IBundleResult { - private readonly IFileSystem _fileSystem; + private readonly string _bundleFilePath; private readonly PackageBundle _packageBundle; - public VirtualBundleResult(IFileSystem fileSystem, PackageBundle bundle) + public VirtualBundleResult(string bundleFilePath, PackageBundle bundle) { - _fileSystem = fileSystem; + _bundleFilePath = bundleFilePath; _packageBundle = bundle; } - - public override void UnloadBundleFile() + public void UnloadBundleFile() { } - public override string GetBundleFilePath() + public string GetBundleFilePath() { - return _fileSystem.GetBundleFilePath(_packageBundle); + return _bundleFilePath; } - public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) + public FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) { var operation = new VirtualBundleLoadAssetOperation(_packageBundle, assetInfo); return operation; } - public override FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo) + public FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo) { var operation = new VirtualBundleLoadAllAssetsOperation(_packageBundle, assetInfo); return operation; } - public override FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo) + public FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo) { var operation = new VirtualBundleLoadSubAssetsOperation(_packageBundle, assetInfo); return operation; } - public override FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad) + public FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad) { var operation = new VirtualBundleLoadSceneOperation(assetInfo, loadParams, suspendLoad); return operation; diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/VirtualBundleResult.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Bundles/Services/VirtualBundleResult/VirtualBundleResult.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersDefine.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersDefine.cs index 4009f23c..c726aa1f 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersDefine.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersDefine.cs @@ -14,7 +14,7 @@ namespace YooAsset public const string FILE_VERIFY_MAX_CONCURRENCY = "FILE_VERIFY_MAX_CONCURRENCY"; /// - /// 覆盖安装缓存清理模式 + /// 覆盖安装缓存清理模式 /// public const string INSTALL_CLEAR_MODE = "INSTALL_CLEAR_MODE"; @@ -23,31 +23,11 @@ namespace YooAsset /// public const string REMOTE_SERVICES = "REMOTE_SERVICES"; - /// - /// 加载 AssetBundle 的 Operation 工厂委托 - /// - public const string LOAD_ASSETBUNDLE_OPERATION_FACTORY = "LOAD_ASSETBUNDLE_OPERATION_FACTORY"; - - /// - /// 加载 RawBundle 的 Operation 工厂委托 - /// - public const string LOAD_RAWBUNDLE_OPERATION_FACTORY = "LOAD_RAWBUNDLE_OPERATION_FACTORY"; - /// /// 资源清单服务类 /// public const string MANIFEST_RESTORE_SERVICES = "MANIFEST_RESTORE_SERVICES"; - /// - /// 数据文件追加文件格式 - /// - public const string APPEND_FILE_EXTENSION = "APPEND_FILE_EXTENSION"; - - /// - /// 禁用Catalog目录查询文件 - /// - public const string DISABLE_CATALOG_FILE = "DISABLE_CATALOG_FILE"; - /// /// 禁用Unity的网络缓存 /// @@ -128,11 +108,6 @@ namespace YooAsset /// public const string COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT = "COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT"; - /// - /// 拷贝内置文件接口的实例类 - /// - public const string COPY_LOCAL_FILE_SERVICES = "COPY_LOCAL_FILE_SERVICES"; - /// /// 解压文件系统的根目录 /// diff --git a/Assets/YooAsset/Runtime/FileSystem/Interfaces/IFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/Interfaces/IFileSystem.cs index bf5908b5..ed62ce1f 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Interfaces/IFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Interfaces/IFileSystem.cs @@ -8,17 +8,6 @@ namespace YooAsset /// string PackageName { get; } - /// - /// 文件根目录 - /// - string FileRoot { get; } - - /// - /// 文件数量 - /// - int FileCount { get; } - - /// /// 初始化文件系统 /// @@ -71,11 +60,6 @@ namespace YooAsset /// bool Belong(PackageBundle bundle); - /// - /// 查询文件是否存在 - /// - bool Exists(PackageBundle bundle); - /// /// 是否需要下载 /// @@ -90,10 +74,5 @@ namespace YooAsset /// 是否需要导入 /// bool NeedImport(PackageBundle bundle); - - /// - /// 获取资源包本地路径 - /// - string GetBundleFilePath(PackageBundle bundle); } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operations/FSDownloadFileOptions.cs b/Assets/YooAsset/Runtime/FileSystem/Operations/FSDownloadFileOptions.cs index af3e5658..a026445b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Operations/FSDownloadFileOptions.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Operations/FSDownloadFileOptions.cs @@ -1,60 +1,34 @@  namespace YooAsset { - internal struct DownloadFileOptions + internal readonly struct DownloadFileOptions { /// - /// 资源包 + /// 资源包对象 /// public readonly PackageBundle Bundle; /// /// 失败后重试次数 /// - public readonly int FailedTryAgain; - - /// - /// 主资源地址 - /// - public string MainURL { private set; get; } - - /// - /// 备用资源地址 - /// - public string FallbackURL { private set; get; } + public readonly int RetryCount; /// /// 拷贝的本地文件路径 /// - public string ImportFilePath { set; get; } + public readonly string ImportFilePath; - public DownloadFileOptions(PackageBundle bundle, int failedTryAgain) + public DownloadFileOptions(PackageBundle bundle, int retryCount) { Bundle = bundle; - FailedTryAgain = failedTryAgain; - MainURL = null; - FallbackURL = null; + RetryCount = retryCount; ImportFilePath = null; } - - /// - /// 设置下载地址 - /// - public void SetURL(string mainURL, string fallbackURL) + public DownloadFileOptions(PackageBundle bundle, int retryCount, string importFilePath) { - MainURL = mainURL; - FallbackURL = fallbackURL; - } - - /// - /// 是否有效 - /// - public bool IsValid() - { - if (string.IsNullOrEmpty(MainURL) || string.IsNullOrEmpty(FallbackURL)) - return false; - - return true; + Bundle = bundle; + RetryCount = retryCount; + ImportFilePath = importFilePath; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadBundleOperation.cs index da57ee96..2c18b185 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Operations/FSLoadBundleOperation.cs @@ -6,7 +6,7 @@ namespace YooAsset /// /// 加载结果 /// - public BundleResult Result { protected set; get; } + public IBundleResult Result { protected set; get; } /// /// 下载进度 @@ -23,22 +23,4 @@ namespace YooAsset /// public bool AbortDownloadFile = false; } - - internal sealed class FSLoadBundleCompleteOperation : FSLoadBundleOperation - { - private readonly string _error; - - internal FSLoadBundleCompleteOperation(string error) - { - _error = error; - } - internal override void InternalStart() - { - Status = EOperationStatus.Failed; - Error = _error; - } - internal override void InternalUpdate() - { - } - } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/BuiltinFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/BuiltinFileSystem.cs index 38a312a2..abd66e68 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/BuiltinFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/BuiltinFileSystem.cs @@ -10,20 +10,27 @@ namespace YooAsset /// internal class BuiltinFileSystem : IFileSystem { - public class FileWrapper - { - public string FileName { private set; get; } - - public FileWrapper(string fileName) - { - FileName = fileName; - } - } - - protected readonly Dictionary _wrappers = new Dictionary(10000); protected readonly Dictionary _builtinFilePathMapping = new Dictionary(10000); - protected IFileSystem _unpackFileSystem; + protected readonly Dictionary _tempFilePathMapping = new Dictionary(10000); protected string _packageRoot; + protected string _unpackTempFilesRoot; + protected string _unpackManifestFilesRoot; + protected string _unpackBundleFilesRoot; + + /// + /// 内置文件缓存系统 + /// + public IFileCache BuiltinFileCache { private set; get; } + + /// + /// 沙盒文件缓存系统 + /// + public IFileCache UnpackFileCache { private set; get; } + + /// + /// 解压调度器 + /// + public DownloadSchedulerOperation UnpackScheduler { get; set; } /// /// 下载后台接口 @@ -35,28 +42,6 @@ namespace YooAsset /// public string PackageName { private set; get; } - /// - /// 文件根目录 - /// - public string FileRoot - { - get - { - return _packageRoot; - } - } - - /// - /// 文件数量 - /// - public int FileCount - { - get - { - return _wrappers.Count; - } - } - #region 自定义参数 /// /// 自定义参数:UnityWebRequest 创建委托 @@ -66,7 +51,7 @@ namespace YooAsset /// /// 自定义参数:覆盖安装缓存清理模式 /// - public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles; + public EInstallCleanupMode InstallClearMode { private set; get; } = EInstallCleanupMode.ClearAllManifestFiles; /// /// 自定义参数:初始化的时候缓存文件校验级别 @@ -78,16 +63,6 @@ namespace YooAsset /// public int FileVerifyMaxConcurrency { private set; get; } = 32; - /// - /// 自定义参数:数据文件追加文件格式 - /// - public bool AppendFileExtension { private set; get; } = false; - - /// - /// 自定义参数:禁用Catalog目录查询文件 - /// - public bool DisableCatalogFile { private set; get; } = false; - /// /// 自定义参数:拷贝内置清单 /// @@ -105,24 +80,22 @@ namespace YooAsset public string UnpackFileSystemRoot { private set; get; } /// - /// 自定义参数:加载 AssetBundle 的工厂委托 + /// 自定义参数:最大并发连接数 + /// 默认值:8(推荐范围 1-32) /// - public LoadAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; } + public int UnpackMaxConcurrency { private set; get; } /// - /// 自定义参数:加载 RawBundle 的工厂委托 + /// 自定义参数:每帧发起的最大请求数 + /// 默认值:8(推荐范围 1-32) + /// 说明:避免单帧发起过多请求导致卡顿 /// - public LoadRawBundleOperationFactory LoadRawBundleFactory { private set; get; } + public int UnpackMaxRequestPerFrame { private set; get; } /// /// 自定义参数:资源清单服务类 /// public IManifestRestoreServices ManifestRestoreServices { private set; get; } - - /// - /// 自定义参数:拷贝内置文件接口的实例类 - /// - public ILocalFileCopyServices CopyLocalFileServices { private set; get; } #endregion @@ -131,7 +104,7 @@ namespace YooAsset } public virtual FSInitializeOperation InitializeAsync() { - var operation = new DBFSInitializeOperation(this); + var operation = new BFSInitializeOperation(this); return operation; } public virtual FSRequestVersionOperation RequestVersionAsync(RequestVersionOptions options) @@ -146,45 +119,18 @@ namespace YooAsset } public virtual FSClearCacheOperation ClearCacheAsync(ClearCacheOptions options) { - return _unpackFileSystem.ClearCacheAsync(options); + var operation = new BFSClearCacheOperation(this, options); + return operation; } public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options) { - // 注意:业务层的解压器会依赖该方法 - options.ImportFilePath = GetBuiltinFileLoadPath(options.Bundle); - return _unpackFileSystem.DownloadFileAsync(options); + var operation = new BFSDownloadFileOperation(this, options); + return operation; } public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) { - PackageBundle bundle = options.Bundle; - if (IsUnpackBundleFile(bundle)) - { - return _unpackFileSystem.LoadBundleAsync(options); - } - - if (bundle.BundleType == (int)EBundleType.AssetBundle) - { - var operation = new BFSLoadAssetBundleOperation(this, bundle); - return operation; - } - else if (bundle.BundleType == (int)EBundleType.RawBundle) - { - var operation = new BFSLoadRawBundleOperation(this, bundle); - return operation; - } -#if TUANJIE_1_7_OR_NEWER - else if (bundle.BundleType == (int)EBundleType.InstantBundle) - { - var operation = new BFSLoadInstantBundleOperation(this, bundle); - return operation; - } -#endif - else - { - string error = $"{nameof(BuiltinFileSystem)} not support load bundle type : {bundle.BundleType}"; - var operation = new FSLoadBundleCompleteOperation(error); - return operation; - } + var operation = new BFSLoadBundleOperation(this, options); + return operation; } public virtual void SetParameter(string name, object value) @@ -199,7 +145,7 @@ namespace YooAsset } else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE) { - InstallClearMode = (EOverwriteInstallClearMode)value; + InstallClearMode = (EInstallCleanupMode)value; } else if (name == FileSystemParametersDefine.FILE_VERIFY_LEVEL) { @@ -210,14 +156,6 @@ namespace YooAsset int convertValue = Convert.ToInt32(value); FileVerifyMaxConcurrency = Mathf.Clamp(convertValue, 1, int.MaxValue); } - else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION) - { - AppendFileExtension = Convert.ToBoolean(value); - } - else if (name == FileSystemParametersDefine.DISABLE_CATALOG_FILE) - { - DisableCatalogFile = Convert.ToBoolean(value); - } else if (name == FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST) { CopyBuildinPackageManifest = Convert.ToBoolean(value); @@ -230,22 +168,32 @@ namespace YooAsset { UnpackFileSystemRoot = (string)value; } - else if (name == FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY) + else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY) { - LoadAssetBundleFactory = (LoadAssetBundleOperationFactory)value; + int convertValue = Convert.ToInt32(value); + if (convertValue > 32) + { + YooLogger.Warning($"DOWNLOAD_MAX_CONCURRENCY value {convertValue} is too large, clamped to 32. Recommended range: 1 - 32."); + } + + // 限制在合理范围内:1-32 + UnpackMaxConcurrency = Mathf.Clamp(convertValue, 1, 32); } - else if (name == FileSystemParametersDefine.LOAD_RAWBUNDLE_OPERATION_FACTORY) + else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_REQUEST_PER_FRAME) { - LoadRawBundleFactory = (LoadRawBundleOperationFactory)value; + int convertValue = Convert.ToInt32(value); + if (convertValue > 32) + { + YooLogger.Warning($"DOWNLOAD_MAX_REQUEST_PER_FRAME value {convertValue} is too large, clamped to 32. Recommended range: 1 - 32."); + } + + // 限制在合理范围内:1-32 + UnpackMaxRequestPerFrame = Mathf.Clamp(convertValue, 1, 32); } else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES) { ManifestRestoreServices = (IManifestRestoreServices)value; } - else if (name == FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES) - { - CopyLocalFileServices = (ILocalFileCopyServices)value; - } else { YooLogger.Warning($"Invalid parameter : {name}"); @@ -264,35 +212,49 @@ namespace YooAsset if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); - // 创建默认的 AssetBundle 加载工厂 - if (LoadAssetBundleFactory == null) - LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory; + // 创建解压缓存系统 + string unpackRoot; + if (string.IsNullOrEmpty(UnpackFileSystemRoot)) + unpackRoot = GetDefaultUnpackCacheRoot(packageName); + else + unpackRoot = UnpackFileSystemRoot; + _unpackManifestFilesRoot = PathUtility.Combine(unpackRoot, BuiltinFileSystemConstants.UnpackManifestFilesFolderName); + _unpackBundleFilesRoot = PathUtility.Combine(unpackRoot, BuiltinFileSystemConstants.UnpackBundleFilesFolderName); + _unpackTempFilesRoot = PathUtility.Combine(unpackRoot, BuiltinFileSystemConstants.UnpackTempFilesFolderName); - // 创建默认的 RawBundle 加载工厂 - if (LoadRawBundleFactory == null) - LoadRawBundleFactory = DefaultLoadRawBundleOperationFactory; + // 创建内置缓存对象 + { + var cacheConfig = new BuiltinFileCache.CacheConfig(); + cacheConfig.DownloadBackend = DownloadBackend; + BuiltinFileCache = new BuiltinFileCache(packageName, _packageRoot, cacheConfig); + } - // 创建解压文件系统 - var remoteServices = new UnpackRemoteService(_packageRoot); - _unpackFileSystem = new UnpackFileSystem(); - _unpackFileSystem.SetParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices); - _unpackFileSystem.SetParameter(FileSystemParametersDefine.DOWNLOAD_BACKEND, DownloadBackend); - _unpackFileSystem.SetParameter(FileSystemParametersDefine.UNITY_WEB_REQUEST_CREATOR, WebRequestCreator); - _unpackFileSystem.SetParameter(FileSystemParametersDefine.INSTALL_CLEAR_MODE, InstallClearMode); - _unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel); - _unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY, FileVerifyMaxConcurrency); - _unpackFileSystem.SetParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, AppendFileExtension); - _unpackFileSystem.SetParameter(FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY, LoadAssetBundleFactory); - _unpackFileSystem.SetParameter(FileSystemParametersDefine.LOAD_RAWBUNDLE_OPERATION_FACTORY, LoadRawBundleFactory); - _unpackFileSystem.SetParameter(FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES, CopyLocalFileServices); - _unpackFileSystem.OnCreate(packageName, UnpackFileSystemRoot); + // 创建沙盒缓存对象 + { + var cacheConfig = new SandboxFileCache.CacheConfig(); + cacheConfig.FileVerifyLevel = FileVerifyLevel; + cacheConfig.FileVerifyMaxConcurrency = FileVerifyMaxConcurrency; + UnpackFileCache = new SandboxFileCache(packageName, _unpackBundleFilesRoot, cacheConfig); + } } public virtual void OnDestroy() { - if (_unpackFileSystem != null) + if (BuiltinFileCache != null) { - _unpackFileSystem.OnDestroy(); - _unpackFileSystem = null; + BuiltinFileCache.Dispose(); + BuiltinFileCache = null; + } + + if (UnpackFileCache != null) + { + UnpackFileCache.Dispose(); + UnpackFileCache = null; + } + + if (UnpackScheduler != null) + { + UnpackScheduler.Dispose(); + UnpackScheduler = null; } if (DownloadBackend != null) @@ -304,15 +266,7 @@ namespace YooAsset public virtual bool Belong(PackageBundle bundle) { - if (DisableCatalogFile) - return true; - return _wrappers.ContainsKey(bundle.BundleGUID); - } - public virtual bool Exists(PackageBundle bundle) - { - if (DisableCatalogFile) - return true; - return _wrappers.ContainsKey(bundle.BundleGUID); + return BuiltinFileCache.IsCached(bundle.BundleGUID); } public virtual bool NeedDownload(PackageBundle bundle) { @@ -322,7 +276,7 @@ namespace YooAsset { if (IsUnpackBundleFile(bundle)) { - return _unpackFileSystem.Exists(bundle) == false; + return UnpackFileCache.IsCached(bundle.BundleGUID) == false; } else { @@ -333,26 +287,17 @@ namespace YooAsset { return false; } - public virtual string GetBundleFilePath(PackageBundle bundle) - { - if (IsUnpackBundleFile(bundle)) - { - return _unpackFileSystem.GetBundleFilePath(bundle); - } - - return GetBuiltinFileLoadPath(bundle); - } /// /// 是否属于解压资源包文件 /// - protected virtual bool IsUnpackBundleFile(PackageBundle bundle) + public virtual bool IsUnpackBundleFile(PackageBundle bundle) { if (Belong(bundle) == false) return false; #if UNITY_ANDROID || UNITY_OPENHARMONY - if (bundle.Encrypted) + if (bundle.IsEncrypted) return true; if (bundle.BundleType == (int)EBundleType.RawBundle) @@ -365,31 +310,7 @@ namespace YooAsset } #region 内部方法 - private LoadAssetBundleOperation DefaultLoadAssetBundleOperationFactory(bool bundleEncrypted, LoadAssetBundleOptions options) - { - if (bundleEncrypted) - { - string error = $"{nameof(DefaultLoadAssetBundleOperation)} cannot load encrypted bundle. Please provide a custom {nameof(LoadAssetBundleOperationFactory)}."; - return new LoadAssetBundleCompleteOperation(error, options); - } - else - { - return new DefaultLoadAssetBundleOperation(options); - } - } - private LoadRawBundleOperation DefaultLoadRawBundleOperationFactory(bool bundleEncrypted, LoadRawBundleOptions options) - { - if (bundleEncrypted) - { - string error = $"{nameof(DefaultLoadRawBundleOperation)} cannot load encrypted bundle. Please provide a custom {nameof(LoadRawBundleOperationFactory)}."; - return new LoadRawBundleCompleteOperation(error, options); - } - else - { - return new DefaultLoadRawBundleOperation(options); - } - } - protected string GetDefaultBuiltinPackageRoot(string packageName) + public string GetDefaultBuiltinPackageRoot(string packageName) { string rootDirectory = YooAssetSettingsData.GetYooDefaultBuildinRoot(); return PathUtility.Combine(rootDirectory, packageName); @@ -418,32 +339,42 @@ namespace YooAsset string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion); return PathUtility.Combine(_packageRoot, fileName); } - public string GetCatalogBinaryFileLoadPath() + public string GetSandboxAppFootPrintFilePath() { - return PathUtility.Combine(_packageRoot, BuiltinFileSystemConstants.BuiltinCatalogBinaryFileName); + return PathUtility.Combine(_unpackManifestFilesRoot, DefaultCacheFileSystemDefine.AppFootPrintFileName); } /// - /// 记录文件信息 + /// 删除所有缓存的资源文件 /// - public bool RecordCatalogFile(string bundleGUID, FileWrapper wrapper) + public void DeleteAllBundleFiles() { - if (_wrappers.ContainsKey(bundleGUID)) + if (Directory.Exists(_unpackBundleFilesRoot)) { - YooLogger.Error($"{nameof(BuiltinFileSystem)} has element : {bundleGUID}"); - return false; + Directory.Delete(_unpackBundleFilesRoot, true); } - - _wrappers.Add(bundleGUID, wrapper); - return true; } /// - /// 初始化解压文件系统 + /// 获取默认的解压缓存根目录 /// - public FSInitializeOperation InitializeUnpackFileSystem() + public string GetDefaultUnpackCacheRoot(string packageName) { - return _unpackFileSystem.InitializeAsync(); + string rootDirectory = YooAssetSettingsData.GetYooDefaultCacheRoot(); + return PathUtility.Combine(rootDirectory, packageName); + } + + /// + /// 获取解压的临时文件路径 + /// + public string GetUnpackTempFilePath(PackageBundle bundle) + { + if (_tempFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false) + { + filePath = PathUtility.Combine(_unpackTempFilesRoot, bundle.BundleGUID); + _tempFilePathMapping.Add(bundle.BundleGUID, filePath); + } + return filePath; } #endregion } diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/BuiltinFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/BuiltinFileSystemDefine.cs index a6f4ef65..4e2f8dae 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/BuiltinFileSystemDefine.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/BuiltinFileSystemDefine.cs @@ -1,16 +1,21 @@ - + namespace YooAsset { internal class BuiltinFileSystemConstants { /// - /// 内置清单JSON文件名称 + /// 解压清单文件的文件夹名称 /// - public const string BuiltinCatalogJsonFileName = "BuiltinCatalog.json"; + public const string UnpackManifestFilesFolderName = "UnpackManifestFiles"; + + /// + /// 解压资源文件的文件夹名称 + /// + public const string UnpackBundleFilesFolderName = "UnpackBundleFiles"; /// - /// 内置清单二进制文件名称 + /// 解压临时文件的文件夹名称 /// - public const string BuiltinCatalogBinaryFileName = "BuiltinCatalog.bytes"; + public const string UnpackTempFilesFolderName = "UnpackTempFiles"; } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSClearCacheOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSClearCacheOperation.cs new file mode 100644 index 00000000..61ce1a75 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSClearCacheOperation.cs @@ -0,0 +1,59 @@ + +namespace YooAsset +{ + internal class BFSClearCacheOperation : FSClearCacheOperation + { + private enum ESteps + { + None, + ClearCache, + Done, + } + + private readonly BuiltinFileSystem _fileSystem; + private readonly ClearCacheOptions _options; + private FCClearCacheOperation _clearCacheOp; + private ESteps _steps = ESteps.None; + + internal BFSClearCacheOperation(BuiltinFileSystem fileSystem, ClearCacheOptions options) + { + _fileSystem = fileSystem; + _options = options; + } + internal override void InternalStart() + { + _steps = ESteps.ClearCache; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearCache) + { + if (_clearCacheOp == null) + { + _clearCacheOp = _fileSystem.UnpackFileCache.ClearCacheAsync(_options); + _clearCacheOp.StartOperation(); + AddChildOperation(_clearCacheOp); + } + + _clearCacheOp.UpdateOperation(); + if (_clearCacheOp.IsDone == false) + return; + + if (_clearCacheOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearCacheOp.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSClearCacheOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSClearCacheOperation.cs.meta new file mode 100644 index 00000000..85efe059 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSClearCacheOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3852e5e9188e72d488f02467606a39e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSDownloadFileOperation.cs new file mode 100644 index 00000000..85d519c0 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSDownloadFileOperation.cs @@ -0,0 +1,131 @@ +using UnityEngine; + +namespace YooAsset +{ + internal class BFSDownloadFileOperation : FSDownloadFileOperation + { + private enum ESteps + { + None, + CheckExists, + UnpackAndCache, + TryAgain, + Done, + } + + private readonly BuiltinFileSystem _fileSystem; + private readonly DownloadFileOptions _options; + private DownloadFileBaseOperation _downloadFileOp; + private ESteps _steps = ESteps.None; + + // 失败重试 + private float _tryAgainTimer = 0; + private int _failedTryAgain; + + internal BFSDownloadFileOperation(BuiltinFileSystem fileSystem, DownloadFileOptions options) : base(options.Bundle) + { + _fileSystem = fileSystem; + _options = options; + _failedTryAgain = options.RetryCount; + } + internal override void InternalStart() + { + _steps = ESteps.CheckExists; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 检测文件是否存在 + if (_steps == ESteps.CheckExists) + { + if (_fileSystem.UnpackFileCache.IsCached(Bundle.BundleGUID)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + _steps = ESteps.UnpackAndCache; + } + } + + // 下载并缓存文件 + if (_steps == ESteps.UnpackAndCache) + { + if (_downloadFileOp == null) + { + _downloadFileOp = _fileSystem.UnpackScheduler.TryGetDownloadFile(Bundle); + if (_downloadFileOp == null) + { + string builtinFilePath = _fileSystem.GetBuiltinFileLoadPath(Bundle); + _downloadFileOp = new UnpackAndCacheFileOperation(_fileSystem, Bundle, builtinFilePath); + _fileSystem.UnpackScheduler.AddDownloadFile(_downloadFileOp); + } + } + + if (IsWaitForCompletion) + _downloadFileOp.WaitForCompletion(); + + _downloadFileOp.UpdateOperation(); + Progress = _downloadFileOp.Progress; + DownloadedBytes = _downloadFileOp.DownloadedBytes; + DownloadProgress = _downloadFileOp.DownloadProgress; + if (_downloadFileOp.IsDone == false) + return; + + if (_downloadFileOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + if (IsWaitForCompletion == false && _failedTryAgain > 0) + { + _steps = ESteps.TryAgain; + YooLogger.Warning($"Failed download : {_downloadFileOp.Url} Try again."); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadFileOp.Error; + YooLogger.Error(Error); + } + } + } + + // 重新尝试下载 + if (_steps == ESteps.TryAgain) + { + _tryAgainTimer += Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + _tryAgainTimer = 0f; + _failedTryAgain--; + Progress = 0f; + DownloadProgress = 0f; + DownloadedBytes = 0; + _steps = ESteps.UnpackAndCache; + } + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + internal override void InternalAbort() + { + // 注意:取消下载任务的时候引用计数减一 + if (_steps != ESteps.Done) + { + if (_downloadFileOp != null) + { + _downloadFileOp.Release(); + } + } + } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSDownloadFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSDownloadFileOperation.cs.meta new file mode 100644 index 00000000..e6cec9a6 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSDownloadFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 899d85c6278629e40a36bc616b53bd95 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSInitializeOperation.cs index 095eee45..3463b7f3 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSInitializeOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSInitializeOperation.cs @@ -1,30 +1,26 @@ -using System; -using System.IO; namespace YooAsset { - internal class DBFSInitializeOperation : FSInitializeOperation + internal class BFSInitializeOperation : FSInitializeOperation { private enum ESteps { None, - LoadBuildinPackageVersion, - CopyBuildinPackageHash, - CopyBuildinPackageManifest, - InitUnpackFileSystem, - LoadCatalogFile, + CheckAppFootprint, + CopyPackageManifest, + InitializeBuiltinFileCache, + InitializeUnpackFileCache, + CreateScheduler, Done, } private readonly BuiltinFileSystem _fileSystem; - private RequestBuiltinPackageVersionOperation _requestBuildinPackageVersionOp; - private CopyBuiltinFileOperation _copyBuildinHashFileOp; - private CopyBuiltinFileOperation _copyBuildinManifestFileOp; - private FSInitializeOperation _initUnpackFIleSystemOp; - private LoadBuiltinCatalogFileOperation _loadBuildinCatalogFileOp; + private FCInitializeOperation _initializeBuiltinFileCacheOp; + private FCInitializeOperation _initializeUnpackFileCacheOp; + private CopyBuiltinPackageManifest _copyBuiltinPackageManifestOp; private ESteps _steps = ESteps.None; - internal DBFSInitializeOperation(BuiltinFileSystem fileSystem) + internal BFSInitializeOperation(BuiltinFileSystem fileSystem) { _fileSystem = fileSystem; } @@ -35,10 +31,7 @@ namespace YooAsset Status = EOperationStatus.Failed; Error = $"{nameof(DefaultBuildinFileSystem)} is not support WEBGL platform."; #else - if (_fileSystem.CopyBuildinPackageManifest) - _steps = ESteps.LoadBuildinPackageVersion; - else - _steps = ESteps.InitUnpackFileSystem; + _steps = ESteps.CheckAppFootprint; #endif } internal override void InternalUpdate() @@ -46,193 +39,146 @@ namespace YooAsset if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.LoadBuildinPackageVersion) + if (_steps == ESteps.CheckAppFootprint) { - if (_requestBuildinPackageVersionOp == null) - { - _requestBuildinPackageVersionOp = new RequestBuiltinPackageVersionOperation(_fileSystem); - _requestBuildinPackageVersionOp.StartOperation(); - AddChildOperation(_requestBuildinPackageVersionOp); - } + string footprintFilePath = _fileSystem.GetSandboxAppFootPrintFilePath(); + var appFootprint = new ApplicationFootprint(footprintFilePath); + appFootprint.Load(_fileSystem.PackageName); - _requestBuildinPackageVersionOp.UpdateOperation(); - if (_requestBuildinPackageVersionOp.IsDone == false) - return; - - if (_requestBuildinPackageVersionOp.Status == EOperationStatus.Succeeded) + // ˮӡ仯˵ǰװ״δϷ + if (appFootprint.IsDirty()) { - _steps = ESteps.CopyBuildinPackageHash; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _requestBuildinPackageVersionOp.Error; - } - } - - if (_steps == ESteps.CopyBuildinPackageHash) - { - if (_copyBuildinHashFileOp == null) - { - string packageVersion = _requestBuildinPackageVersionOp.PackageVersion; - string destFilePath = GetCopyPackageHashDestPath(packageVersion); - string sourceFilePath = _fileSystem.GetBuiltinPackageHashFilePath(packageVersion); - _copyBuildinHashFileOp = new CopyBuiltinFileOperation(_fileSystem, sourceFilePath, destFilePath); - _copyBuildinHashFileOp.StartOperation(); - AddChildOperation(_copyBuildinHashFileOp); - } - - _copyBuildinHashFileOp.UpdateOperation(); - if (_copyBuildinHashFileOp.IsDone == false) - return; - - if (_copyBuildinHashFileOp.Status == EOperationStatus.Succeeded) - { - _steps = ESteps.CopyBuildinPackageManifest; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _copyBuildinHashFileOp.Error; - } - } - - if (_steps == ESteps.CopyBuildinPackageManifest) - { - if (_copyBuildinManifestFileOp == null) - { - string packageVersion = _requestBuildinPackageVersionOp.PackageVersion; - string destFilePath = GetCopyPackageManifestDestPath(packageVersion); - string sourceFilePath = _fileSystem.GetBuiltinPackageManifestFilePath(packageVersion); - _copyBuildinManifestFileOp = new CopyBuiltinFileOperation(_fileSystem, sourceFilePath, destFilePath); - _copyBuildinManifestFileOp.StartOperation(); - AddChildOperation(_copyBuildinManifestFileOp); - } - - _copyBuildinManifestFileOp.UpdateOperation(); - if (_copyBuildinManifestFileOp.IsDone == false) - return; - - if (_copyBuildinManifestFileOp.Status == EOperationStatus.Succeeded) - { - _steps = ESteps.InitUnpackFileSystem; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _copyBuildinManifestFileOp.Error; - } - } - - if (_steps == ESteps.InitUnpackFileSystem) - { - if (_initUnpackFIleSystemOp == null) - { - _initUnpackFIleSystemOp = _fileSystem.InitializeUnpackFileSystem(); - _initUnpackFIleSystemOp.StartOperation(); - AddChildOperation(_initUnpackFIleSystemOp); - } - - _initUnpackFIleSystemOp.UpdateOperation(); - Progress = _initUnpackFIleSystemOp.Progress; - if (_initUnpackFIleSystemOp.IsDone == false) - return; - - if (_initUnpackFIleSystemOp.Status == EOperationStatus.Succeeded) - { - if (_fileSystem.DisableCatalogFile) + if (_fileSystem.InstallClearMode == EInstallCleanupMode.None) { - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; + YooLogger.Warning("Do nothing when overwrite install application."); + } + else if (_fileSystem.InstallClearMode == EInstallCleanupMode.ClearAllCacheFiles) + { + _fileSystem.DeleteAllBundleFiles(); + YooLogger.Warning("Delete all cache files when overwrite install application."); + } + else if (_fileSystem.InstallClearMode == EInstallCleanupMode.ClearAllBundleFiles) + { + _fileSystem.DeleteAllBundleFiles(); + YooLogger.Warning("Delete all bundle files when overwrite install application."); + } + else if (_fileSystem.InstallClearMode == EInstallCleanupMode.ClearAllManifestFiles) + { + YooLogger.Warning("Do nothing when overwrite install application."); } else { - _steps = ESteps.LoadCatalogFile; + throw new System.NotImplementedException(_fileSystem.InstallClearMode.ToString()); + } + + appFootprint.Coverage(_fileSystem.PackageName); + } + + _steps = ESteps.CopyPackageManifest; + } + + if (_steps == ESteps.CopyPackageManifest) + { + if (_fileSystem.CopyBuildinPackageManifest) + { + if (_copyBuiltinPackageManifestOp == null) + { + _copyBuiltinPackageManifestOp = new CopyBuiltinPackageManifest(_fileSystem); + _copyBuiltinPackageManifestOp.StartOperation(); + AddChildOperation(_copyBuiltinPackageManifestOp); + } + + _copyBuiltinPackageManifestOp.UpdateOperation(); + if (_copyBuiltinPackageManifestOp.IsDone == false) + return; + + if (_copyBuiltinPackageManifestOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.InitializeBuiltinFileCache; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _copyBuiltinPackageManifestOp.Error; } } else { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _initUnpackFIleSystemOp.Error; + _steps = ESteps.InitializeBuiltinFileCache; } } - if (_steps == ESteps.LoadCatalogFile) + if (_steps == ESteps.InitializeBuiltinFileCache) { - if (_loadBuildinCatalogFileOp == null) + if (_initializeBuiltinFileCacheOp == null) { - _loadBuildinCatalogFileOp = new LoadBuiltinCatalogFileOperation(_fileSystem); - _loadBuildinCatalogFileOp.StartOperation(); - AddChildOperation(_loadBuildinCatalogFileOp); + _initializeBuiltinFileCacheOp = _fileSystem.BuiltinFileCache.InitializeAsync(); + _initializeBuiltinFileCacheOp.StartOperation(); + AddChildOperation(_initializeBuiltinFileCacheOp); } - _loadBuildinCatalogFileOp.UpdateOperation(); - if (_loadBuildinCatalogFileOp.IsDone == false) + _initializeBuiltinFileCacheOp.UpdateOperation(); + Progress = _initializeBuiltinFileCacheOp.Progress; + if (_initializeBuiltinFileCacheOp.IsDone == false) return; - if (_loadBuildinCatalogFileOp.Status == EOperationStatus.Succeeded) + if (_initializeBuiltinFileCacheOp.Status == EOperationStatus.Succeeded) { - var catalog = _loadBuildinCatalogFileOp.Catalog; - if (catalog == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Fatal error : catalog is null."; - return; - } - - if (catalog.PackageName != _fileSystem.PackageName) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Catalog file package name {catalog.PackageName} cannot match the file system package name {_fileSystem.PackageName}"; - return; - } - - foreach (var wrapper in catalog.Wrappers) - { - var fileWrapper = new BuiltinFileSystem.FileWrapper(wrapper.FileName); - _fileSystem.RecordCatalogFile(wrapper.BundleGUID, fileWrapper); - } - - YooLogger.Log($"Package '{_fileSystem.PackageName}' buildin catalog files count : {catalog.Wrappers.Count}"); - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; + _steps = ESteps.InitializeUnpackFileCache; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _loadBuildinCatalogFileOp.Error; + Error = _initializeBuiltinFileCacheOp.Error; } } - } - private string GetCopyManifestFileRoot() - { - string destRoot = _fileSystem.CopyBuildinPackageManifestDestRoot; - if (string.IsNullOrEmpty(destRoot)) + if (_steps == ESteps.InitializeUnpackFileCache) { - string defaultCacheRoot = YooAssetSettingsData.GetYooDefaultCacheRoot(); - destRoot = PathUtility.Combine(defaultCacheRoot, _fileSystem.PackageName, DefaultCacheFileSystemDefine.ManifestFilesFolderName); + if (_initializeUnpackFileCacheOp == null) + { + _initializeUnpackFileCacheOp = _fileSystem.UnpackFileCache.InitializeAsync(); + _initializeUnpackFileCacheOp.StartOperation(); + AddChildOperation(_initializeUnpackFileCacheOp); + } + + _initializeUnpackFileCacheOp.UpdateOperation(); + Progress = _initializeUnpackFileCacheOp.Progress; + if (_initializeUnpackFileCacheOp.IsDone == false) + return; + + if (_initializeUnpackFileCacheOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.CreateScheduler; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _initializeUnpackFileCacheOp.Error; + } + } + + if (_steps == ESteps.CreateScheduler) + { + // ע: صһֹʼʧܺ + // ע: صΪУ + if (_fileSystem.UnpackScheduler == null) + { + var schedulerConfig = new DownloadSchedulerOperation.SchedulerConfig(); + schedulerConfig.SchedulerName = _fileSystem.GetType().Name; + schedulerConfig.DownloadBackend = _fileSystem.DownloadBackend; + schedulerConfig.MaxConcurrency = _fileSystem.UnpackMaxConcurrency; + schedulerConfig.MaxRequestPerFrame = _fileSystem.UnpackMaxRequestPerFrame; + _fileSystem.UnpackScheduler = new DownloadSchedulerOperation(schedulerConfig); + AsyncOperationSystem.StartOperation(_fileSystem.PackageName, _fileSystem.UnpackScheduler); + } + + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; } - return destRoot; - } - private string GetCopyPackageHashDestPath(string packageVersion) - { - string fileRoot = GetCopyManifestFileRoot(); - string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, packageVersion); - return PathUtility.Combine(fileRoot, fileName); - } - private string GetCopyPackageManifestDestPath(string packageVersion) - { - string fileRoot = GetCopyManifestFileRoot(); - string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, packageVersion); - return PathUtility.Combine(fileRoot, fileName); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSLoadBundleOperation.cs index 17502ad5..f5e18871 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/BFSLoadBundleOperation.cs @@ -1,170 +1,167 @@ -using System.IO; -using UnityEngine; namespace YooAsset { - /// - /// 加载 AssetBundle 文件 - /// - internal class BFSLoadAssetBundleOperation : FSLoadBundleOperation + internal class BFSLoadBundleOperation : FSLoadBundleOperation { private enum ESteps { None, - LoadBuiltinAssetBundle, + Prepare, + UnpackFile, + AbortUnpack, + LoadUnpackBundle, + LoadBuiltinBundle, CheckResult, Done, } private readonly BuiltinFileSystem _fileSystem; - private readonly PackageBundle _bundle; - private LoadAssetBundleOperation _loadAssetBundleOp; + private readonly LoadBundleOptions _options; + private FSDownloadFileOperation _unpackFileOp; + private FCLoadBundleOperation _loadBundleOp; private ESteps _steps = ESteps.None; - - internal BFSLoadAssetBundleOperation(BuiltinFileSystem fileSystem, PackageBundle bundle) + internal BFSLoadBundleOperation(BuiltinFileSystem fileSystem, LoadBundleOptions options) { _fileSystem = fileSystem; - _bundle = bundle; + _options = options; } internal override void InternalStart() { - DownloadProgress = 1f; - DownloadedBytes = _bundle.FileSize; - _steps = ESteps.LoadBuiltinAssetBundle; + _steps = ESteps.Prepare; } internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.LoadBuiltinAssetBundle) + if (_steps == ESteps.Prepare) { - var options = new LoadAssetBundleOptions(); - options.FileLoadPath = _fileSystem.GetBuiltinFileLoadPath(_bundle); - options.Bundle = _bundle; - _loadAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options); - _loadAssetBundleOp.StartOperation(); - AddChildOperation(_loadAssetBundleOp); + if (_fileSystem.IsUnpackBundleFile(_options.Bundle)) + { + if (_fileSystem.UnpackFileCache.IsCached(_options.Bundle.BundleGUID)) + { + DownloadProgress = 1f; + DownloadedBytes = _options.Bundle.FileSize; + _steps = ESteps.LoadUnpackBundle; + } + else + { + _steps = ESteps.UnpackFile; + } + } + else + { + DownloadProgress = 1f; + DownloadedBytes = _options.Bundle.FileSize; + _steps = ESteps.LoadBuiltinBundle; + } + } + + if (_steps == ESteps.UnpackFile) + { + // 中断解压 + if (AbortDownloadFile) + { + if (_unpackFileOp != null) + _unpackFileOp.AbortOperation(); + _steps = ESteps.AbortUnpack; + } + } + + if (_steps == ESteps.UnpackFile) + { + if (_unpackFileOp == null) + { + var options = new DownloadFileOptions(_options.Bundle, int.MaxValue); + _unpackFileOp = _fileSystem.DownloadFileAsync(options); // 注意:异步任务的开启由调度器统一控制 + AddChildOperation(_unpackFileOp); + } + + if (IsWaitForCompletion) + _unpackFileOp.WaitForCompletion(); + + _unpackFileOp.UpdateOperation(); + DownloadProgress = _unpackFileOp.DownloadProgress; + DownloadedBytes = _unpackFileOp.DownloadedBytes; + if (_unpackFileOp.IsDone == false) + return; + + if (_unpackFileOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.LoadUnpackBundle; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _unpackFileOp.Error; + } + } + + if (_steps == ESteps.AbortUnpack) + { + if (_unpackFileOp != null) + { + if (IsWaitForCompletion) + _unpackFileOp.WaitForCompletion(); + + _unpackFileOp.UpdateOperation(); + if (_unpackFileOp.IsDone == false) + return; + } + + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Abort download file."; + } + + if (_steps == ESteps.LoadUnpackBundle) + { + _loadBundleOp = _fileSystem.UnpackFileCache.LoadBundleAsync(_options); + _loadBundleOp.StartOperation(); + AddChildOperation(_loadBundleOp); + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.LoadBuiltinBundle) + { + _loadBundleOp = _fileSystem.BuiltinFileCache.LoadBundleAsync(_options); + _loadBundleOp.StartOperation(); + AddChildOperation(_loadBundleOp); _steps = ESteps.CheckResult; } if (_steps == ESteps.CheckResult) { if (IsWaitForCompletion) - _loadAssetBundleOp.WaitForCompletion(); + _loadBundleOp.WaitForCompletion(); - _loadAssetBundleOp.UpdateOperation(); - if (_loadAssetBundleOp.IsDone == false) + _loadBundleOp.UpdateOperation(); + if (_loadBundleOp.IsDone == false) return; - if (_loadAssetBundleOp.Status == EOperationStatus.Succeeded) + if (_loadBundleOp.Status == EOperationStatus.Succeeded) { - if (_loadAssetBundleOp.Result == null) + if (_loadBundleOp.BundleResult == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Loaded builtin asset bundle is null."; + Error = "Loaded bundle result is null."; YooLogger.Error(Error); } else { _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, _loadAssetBundleOp.Result, _loadAssetBundleOp.ManagedStream); Status = EOperationStatus.Succeeded; + Result = _loadBundleOp.BundleResult; } } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _loadAssetBundleOp.Error; - YooLogger.Error(Error); - } - } - } - internal override void InternalWaitForCompletion() - { - ExecuteBatch(); - } - } - - /// - /// 加载 RawBundle 文件 - /// - internal class BFSLoadRawBundleOperation : FSLoadBundleOperation - { - private enum ESteps - { - None, - LoadBuiltinRawBundle, - CheckResult, - Done, - } - - private readonly BuiltinFileSystem _fileSystem; - private readonly PackageBundle _bundle; - private LoadRawBundleOperation _loadRawBundleOp; - private ESteps _steps = ESteps.None; - - - internal BFSLoadRawBundleOperation(BuiltinFileSystem fileSystem, PackageBundle bundle) - { - _fileSystem = fileSystem; - _bundle = bundle; - } - internal override void InternalStart() - { - DownloadProgress = 1f; - DownloadedBytes = _bundle.FileSize; - _steps = ESteps.LoadBuiltinRawBundle; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.LoadBuiltinRawBundle) - { - var options = new LoadRawBundleOptions(); - options.FileLoadPath = _fileSystem.GetBuiltinFileLoadPath(_bundle); - options.Bundle = _bundle; - _loadRawBundleOp = _fileSystem.LoadRawBundleFactory.Invoke(_bundle.Encrypted, options); - _loadRawBundleOp.StartOperation(); - AddChildOperation(_loadRawBundleOp); - _steps = ESteps.CheckResult; - } - - if (_steps == ESteps.CheckResult) - { - if (IsWaitForCompletion) - _loadRawBundleOp.WaitForCompletion(); - - _loadRawBundleOp.UpdateOperation(); - if (_loadRawBundleOp.IsDone == false) - return; - - if (_loadRawBundleOp.Status == EOperationStatus.Succeeded) - { - if (_loadRawBundleOp.Result == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Loaded builtin raw bundle is null."; - YooLogger.Error(Error); - } - else - { - _steps = ESteps.Done; - Result = new RawBundleResult(_fileSystem, _bundle, _loadRawBundleOp.Result); - Status = EOperationStatus.Succeeded; - } - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _loadRawBundleOp.Error; + Error = _loadBundleOp.Error; YooLogger.Error(Error); } } @@ -179,7 +176,7 @@ namespace YooAsset /// /// 加载团结文件 /// - internal class BFSLoadInstantBundleOperation : FSLoadBundleOperation + internal class BFSLoadInstantBundleOperation { private enum ESteps { diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/CopyBuiltinFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/CopyBuiltinFileOperation.cs index b0654d43..b131b97f 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/CopyBuiltinFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/CopyBuiltinFileOperation.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; namespace YooAsset @@ -77,7 +77,8 @@ namespace YooAsset { if (_webFileRequestOp == null) { - string url = DownloadSystemTools.ToLocalURL(_sourceFilePath); + //TODO Ž棬ijЩ׿ͣףͨUnityWebRequestļСʧܣҪʽļ + string url = DownloadSystemTools.ToLocalUrl(_sourceFilePath); var args = new DownloadFileRequestArgs(url, _destFilePath, 60, 0); _webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args); _webFileRequestOp.SendRequest(); @@ -86,7 +87,7 @@ namespace YooAsset if (_webFileRequestOp.IsDone == false) return; - if (_webFileRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webFileRequestOp.Status == EDownloadRequestStatus.Succeeded) { _steps = ESteps.Done; Status = EOperationStatus.Succeeded; @@ -99,5 +100,10 @@ namespace YooAsset } } } + internal override void InternalWaitForCompletion() + { + //TODO ȴѹļϣọ̀߳ + ExecuteUntilComplete(); + } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/CopyBuiltinPackageManifest.cs b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/CopyBuiltinPackageManifest.cs new file mode 100644 index 00000000..eafa7199 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/CopyBuiltinPackageManifest.cs @@ -0,0 +1,140 @@ + +namespace YooAsset +{ + internal class CopyBuiltinPackageManifest : AsyncOperationBase + { + private enum ESteps + { + None, + LoadBuiltinPackageVersion, + CopyBuiltinPackageHash, + CopyBuiltinPackageManifest, + Done, + } + + private readonly BuiltinFileSystem _fileSystem; + private RequestBuiltinPackageVersionOperation _requestBuildinPackageVersionOp; + private CopyBuiltinFileOperation _copyBuiltinHashFileOp; + private CopyBuiltinFileOperation _copyBuiltinManifestFileOp; + private ESteps _steps = ESteps.None; + + public CopyBuiltinPackageManifest(BuiltinFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalStart() + { + _steps = ESteps.LoadBuiltinPackageVersion; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadBuiltinPackageVersion) + { + if (_requestBuildinPackageVersionOp == null) + { + _requestBuildinPackageVersionOp = new RequestBuiltinPackageVersionOperation(_fileSystem); + _requestBuildinPackageVersionOp.StartOperation(); + AddChildOperation(_requestBuildinPackageVersionOp); + } + + _requestBuildinPackageVersionOp.UpdateOperation(); + if (_requestBuildinPackageVersionOp.IsDone == false) + return; + + if (_requestBuildinPackageVersionOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.CopyBuiltinPackageHash; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _requestBuildinPackageVersionOp.Error; + } + } + + if (_steps == ESteps.CopyBuiltinPackageHash) + { + if (_copyBuiltinHashFileOp == null) + { + string packageVersion = _requestBuildinPackageVersionOp.PackageVersion; + string destFilePath = GetCopyPackageHashDestPath(packageVersion); + string sourceFilePath = _fileSystem.GetBuiltinPackageHashFilePath(packageVersion); + _copyBuiltinHashFileOp = new CopyBuiltinFileOperation(_fileSystem, sourceFilePath, destFilePath); + _copyBuiltinHashFileOp.StartOperation(); + AddChildOperation(_copyBuiltinHashFileOp); + } + + _copyBuiltinHashFileOp.UpdateOperation(); + if (_copyBuiltinHashFileOp.IsDone == false) + return; + + if (_copyBuiltinHashFileOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.CopyBuiltinPackageManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _copyBuiltinHashFileOp.Error; + } + } + + if (_steps == ESteps.CopyBuiltinPackageManifest) + { + if (_copyBuiltinManifestFileOp == null) + { + string packageVersion = _requestBuildinPackageVersionOp.PackageVersion; + string destFilePath = GetCopyPackageManifestDestPath(packageVersion); + string sourceFilePath = _fileSystem.GetBuiltinPackageManifestFilePath(packageVersion); + _copyBuiltinManifestFileOp = new CopyBuiltinFileOperation(_fileSystem, sourceFilePath, destFilePath); + _copyBuiltinManifestFileOp.StartOperation(); + AddChildOperation(_copyBuiltinManifestFileOp); + } + + _copyBuiltinManifestFileOp.UpdateOperation(); + if (_copyBuiltinManifestFileOp.IsDone == false) + return; + + if (_copyBuiltinManifestFileOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _copyBuiltinManifestFileOp.Error; + } + } + } + + private string GetCopyManifestFileRoot() + { + string destRoot = _fileSystem.CopyBuildinPackageManifestDestRoot; + if (string.IsNullOrEmpty(destRoot)) + { + string defaultCacheRoot = YooAssetSettingsData.GetYooDefaultCacheRoot(); + destRoot = PathUtility.Combine(defaultCacheRoot, _fileSystem.PackageName, DefaultCacheFileSystemDefine.ManifestFilesFolderName); + } + return destRoot; + } + private string GetCopyPackageHashDestPath(string packageVersion) + { + string fileRoot = GetCopyManifestFileRoot(); + string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, packageVersion); + return PathUtility.Combine(fileRoot, fileName); + } + private string GetCopyPackageManifestDestPath(string packageVersion) + { + string fileRoot = GetCopyManifestFileRoot(); + string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, packageVersion); + return PathUtility.Combine(fileRoot, fileName); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/CopyBuiltinPackageManifest.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/CopyBuiltinPackageManifest.cs.meta new file mode 100644 index 00000000..a5556156 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/CopyBuiltinPackageManifest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9cbc466f7e0e94d4fb7ab6ba63c89497 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/LoadBuiltinPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/LoadBuiltinPackageManifestOperation.cs index d26f506a..9053b925 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/LoadBuiltinPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/LoadBuiltinPackageManifestOperation.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; namespace YooAsset { @@ -62,7 +62,7 @@ namespace YooAsset if (_webDataRequestOp == null) { string filePath = _fileSystem.GetBuiltinPackageManifestFilePath(_packageVersion); - string url = DownloadSystemTools.ToLocalURL(filePath); + string url = DownloadSystemTools.ToLocalUrl(filePath); var args = new DownloadDataRequestArgs(url, 60, 0); _webDataRequestOp = _fileSystem.DownloadBackend.CreateBytesRequest(args); _webDataRequestOp.SendRequest(); @@ -71,7 +71,7 @@ namespace YooAsset if (_webDataRequestOp.IsDone == false) return; - if (_webDataRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webDataRequestOp.Status == EDownloadRequestStatus.Succeeded) { _fileData = _webDataRequestOp.Result; _steps = ESteps.VerifyFileData; diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/RequestBuiltinPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/RequestBuiltinPackageHashOperation.cs index 7817c16b..8568a472 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/RequestBuiltinPackageHashOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/RequestBuiltinPackageHashOperation.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; namespace YooAsset { @@ -57,7 +57,7 @@ namespace YooAsset if (_webTextRequestOp == null) { string filePath = _fileSystem.GetBuiltinPackageHashFilePath(_packageVersion); - string url = DownloadSystemTools.ToLocalURL(filePath); + string url = DownloadSystemTools.ToLocalUrl(filePath); var args = new DownloadDataRequestArgs(url, 60, 0); _webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args); _webTextRequestOp.SendRequest(); @@ -66,7 +66,7 @@ namespace YooAsset if (_webTextRequestOp.IsDone == false) return; - if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeeded) { PackageHash = _webTextRequestOp.Result; _steps = ESteps.CheckResult; diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/RequestBuiltinPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/RequestBuiltinPackageVersionOperation.cs index 45ddce86..1a197312 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/RequestBuiltinPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/RequestBuiltinPackageVersionOperation.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; namespace YooAsset { @@ -55,7 +55,7 @@ namespace YooAsset if (_webTextRequestOp == null) { string filePath = _fileSystem.GetBuiltinPackageVersionFilePath(); - string url = DownloadSystemTools.ToLocalURL(filePath); + string url = DownloadSystemTools.ToLocalUrl(filePath); var args = new DownloadDataRequestArgs(url, 60, 0); _webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args); _webTextRequestOp.SendRequest(); @@ -64,7 +64,7 @@ namespace YooAsset if (_webTextRequestOp.IsDone == false) return; - if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeeded) { PackageVersion = _webTextRequestOp.Result; _steps = ESteps.CheckResult; diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/UnpackAndCacheFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/UnpackAndCacheFileOperation.cs new file mode 100644 index 00000000..142627f1 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/UnpackAndCacheFileOperation.cs @@ -0,0 +1,122 @@ +using System.IO; + +namespace YooAsset +{ + internal sealed class UnpackAndCacheFileOperation : DownloadFileBaseOperation + { + private enum ESteps + { + None, + CheckCopy, + CopyLocalFile, + CreateRequest, + CheckRequest, + CacheFile, + Done, + } + + private readonly BuiltinFileSystem _fileSystem; + private readonly string _builtinFilePath; + private readonly string _tempFilePath; + private CopyBuiltinFileOperation _copyBuiltinFileOp; + private FCWriteCacheOperation _bundleCacheOp; + private ESteps _steps = ESteps.None; + + internal UnpackAndCacheFileOperation(BuiltinFileSystem fileSystem, PackageBundle bundle, string builtinFilePath) : base(bundle, builtinFilePath) + { + _fileSystem = fileSystem; + _builtinFilePath = builtinFilePath; + _tempFilePath = _fileSystem.GetUnpackTempFilePath(bundle); + } + internal override void InternalStart() + { + _steps = ESteps.CheckCopy; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 检测文件拷贝 + if (_steps == ESteps.CheckCopy) + { + // 删除历史缓存文件 + FileUtility.EnsureFileDirectory(_tempFilePath); + if (File.Exists(_tempFilePath)) + File.Delete(_tempFilePath); + + _steps = ESteps.CopyLocalFile; + } + + // 拷贝本地文件 + if (_steps == ESteps.CopyLocalFile) + { + if (_copyBuiltinFileOp == null) + { + _copyBuiltinFileOp = new CopyBuiltinFileOperation(_fileSystem, _builtinFilePath, _tempFilePath); + _copyBuiltinFileOp.StartOperation(); + AddChildOperation(_copyBuiltinFileOp); + } + + if (IsWaitForCompletion) + _copyBuiltinFileOp.WaitForCompletion(); + + _copyBuiltinFileOp.UpdateOperation(); + if (_copyBuiltinFileOp.IsDone == false) + return; + + if (_copyBuiltinFileOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.CacheFile; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _copyBuiltinFileOp.Error; + } + } + + // 缓存文件 + if (_steps == ESteps.CacheFile) + { + if (_bundleCacheOp == null) + { + var options = new WriteCacheOptions(); + options.Bundle = Bundle; + options.FilePath = _tempFilePath; + _bundleCacheOp = _fileSystem.UnpackFileCache.WriteCacheAsync(options); + _bundleCacheOp.StartOperation(); + AddChildOperation(_bundleCacheOp); + } + + if (IsWaitForCompletion) + _bundleCacheOp.WaitForCompletion(); + + _bundleCacheOp.UpdateOperation(); + if (_bundleCacheOp.IsDone == false) + return; + + if (_bundleCacheOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _bundleCacheOp.Error; + } + + // 注意:缓存完成后直接删除临时文件 + if (File.Exists(_tempFilePath)) + File.Delete(_tempFilePath); + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/UnpackAndCacheFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/UnpackAndCacheFileOperation.cs.meta new file mode 100644 index 00000000..9998c71c --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/BuiltinFileSystem/Operations/internal/UnpackAndCacheFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: daa3aa418d6979b469437c30b7bbc05d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/ApplicationFootprint.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/ApplicationFootprint.cs index 8d0a4fdf..3c689fe7 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/ApplicationFootprint.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/ApplicationFootprint.cs @@ -8,13 +8,12 @@ namespace YooAsset /// internal class ApplicationFootprint { - private readonly CacheFileSystem _fileSystem; - private string _footPrint; + private readonly string _filePath; + private string _footprint; - - public ApplicationFootprint(CacheFileSystem fileSystem) + public ApplicationFootprint(string filePath) { - _fileSystem = fileSystem; + _filePath = filePath; } /// @@ -22,10 +21,9 @@ namespace YooAsset /// public void Load(string packageName) { - string footPrintFilePath = _fileSystem.GetSandboxAppFootPrintFilePath(); - if (File.Exists(footPrintFilePath)) + if (File.Exists(_filePath)) { - _footPrint = FileUtility.ReadAllText(footPrintFilePath); + _footprint = FileUtility.ReadAllText(_filePath); } else { @@ -39,9 +37,9 @@ namespace YooAsset public bool IsDirty() { #if UNITY_EDITOR - return _footPrint != Application.version; + return _footprint != Application.version; #else - return _footPrint != Application.buildGUID; + return _footprint != Application.buildGUID; #endif } @@ -51,13 +49,12 @@ namespace YooAsset public void Coverage(string packageName) { #if UNITY_EDITOR - _footPrint = Application.version; + _footprint = Application.version; #else - _footPrint = Application.buildGUID; + _footprint = Application.buildGUID; #endif - string footPrintFilePath = _fileSystem.GetSandboxAppFootPrintFilePath(); - FileUtility.WriteAllText(footPrintFilePath, _footPrint); - YooLogger.Log($"Save application foot print : {_footPrint}"); + FileUtility.WriteAllText(_filePath, _footprint); + YooLogger.Log($"Save application footprint : {_footprint}"); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/CacheFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/CacheFileSystem.cs index d9151130..ceaba2e4 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/CacheFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/CacheFileSystem.cs @@ -13,16 +13,15 @@ namespace YooAsset internal class CacheFileSystem : IFileSystem { protected readonly Dictionary _tempFilePathMapping = new Dictionary(10000); - protected string _packageRoot; protected string _tempFilesRoot; - protected string _cacheBundleFilesRoot; protected string _cacheManifestFilesRoot; + protected string _cacheBundleFilesRoot; /// - /// 文件缓存系统 + /// 沙盒文件缓存系统 /// - public BundleCache Cache { get; private set; } + public IFileCache FileCache { get; private set; } /// /// 下载调度器 @@ -39,28 +38,6 @@ namespace YooAsset /// public string PackageName { get; private set; } - /// - /// 文件根目录 - /// - public string FileRoot - { - get - { - return _packageRoot; - } - } - - /// - /// 文件数量 - /// - public int FileCount - { - get - { - return Cache.FileCount; - } - } - #region 自定义参数 /// /// 自定义参数:UnityWebRequest 创建委托 @@ -75,7 +52,7 @@ namespace YooAsset /// /// 自定义参数:覆盖安装缓存清理模式 /// - public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles; + public EInstallCleanupMode InstallClearMode { private set; get; } = EInstallCleanupMode.ClearAllManifestFiles; /// /// 自定义参数:初始化的时候缓存文件校验级别 @@ -89,11 +66,6 @@ namespace YooAsset /// public int FileVerifyMaxConcurrency { private set; get; } = 8; - /// - /// 自定义参数:数据文件追加文件格式 - /// - public bool AppendFileExtension { private set; get; } = false; - /// /// 自定义参数:禁用边玩边下机制 /// @@ -128,28 +100,12 @@ namespace YooAsset /// public List ResumeDownloadResponseCodes { private set; get; } = null; - /// - /// 自定义参数:加载 AssetBundle 的工厂委托 - /// - public LoadAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; } - - /// - /// 自定义参数:加载 RawBundle 的工厂委托 - /// - public LoadRawBundleOperationFactory LoadRawBundleFactory { private set; get; } - /// /// 自定义参数:资源清单服务类 /// public IManifestRestoreServices ManifestRestoreServices { private set; get; } - - /// - /// 自定义参数:拷贝内置文件接口的实例类 - /// - public ILocalFileCopyServices CopyLocalFileServices { private set; get; } #endregion - public CacheFileSystem() { } @@ -170,83 +126,31 @@ namespace YooAsset } public virtual FSClearCacheOperation ClearCacheAsync(ClearCacheOptions options) { - if (options.ClearMode == EFileClearMode.ClearAllBundleFiles.ToString()) + if (options.ClearMode == EManifestClearMode.ClearAllManifestFiles.ToString()) { - var operation = new ClearAllCacheBundleFilesOperation(this); + var operation = new CFSClearAllCacheManifestOperation(this); return operation; } - else if (options.ClearMode == EFileClearMode.ClearUnusedBundleFiles.ToString()) + else if (options.ClearMode == EManifestClearMode.ClearUnusedManifestFiles.ToString()) { - var operation = new ClearUnusedCacheBundleFilesOperation(this, options.Manifest); - return operation; - } - else if (options.ClearMode == EFileClearMode.ClearBundleFilesByLocations.ToString()) - { - var operation = new ClearCacheBundleFilesByLocationsOperation(this, options.Manifest, options.ClearParam); - return operation; - } - else if (options.ClearMode == EFileClearMode.ClearBundleFilesByTags.ToString()) - { - var operation = new ClearCacheBundleFilesByTagsOperation(this, options.Manifest, options.ClearParam); - return operation; - } - else if (options.ClearMode == EFileClearMode.ClearAllManifestFiles.ToString()) - { - var operation = new ClearAllCacheManifestFilesOperation(this); - return operation; - } - else if (options.ClearMode == EFileClearMode.ClearUnusedManifestFiles.ToString()) - { - var operation = new ClearUnusedCacheManifestFilesOperation(this, options.Manifest); + var operation = new CFSClearUnusedCacheManifestOperation(this, options.Manifest); return operation; } else { - string error = $"Invalid clear mode : {options.ClearMode}"; - var operation = new FSClearCacheCompleteOperation(error); + var operation = new CFSClearCacheOperation(this, options); return operation; } } public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options) { - // 获取下载地址 - PackageBundle bundle = options.Bundle; - if (string.IsNullOrEmpty(options.ImportFilePath)) - { - // 注意:如果是解压文件系统类,这里会返回本地内置文件的下载路径 - string mainURL = RemoteServices.GetRemoteMainURL(bundle.FileName); - string fallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName); - options.SetURL(mainURL, fallbackURL); - } - else - { - // 注意:把本地导入文件路径转换为下载器请求地址 - string mainURL = DownloadSystemTools.ToLocalURL(options.ImportFilePath); - options.SetURL(mainURL, mainURL); - } - - var downloader = new DownloadPackageBundleOperation(this, options); + var downloader = new CFSDownloadFileOperation(this, options); return downloader; } public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) { - PackageBundle bundle = options.Bundle; - if (bundle.BundleType == (int)EBundleType.AssetBundle) - { - var operation = new CFSLoadAssetBundleOperation(this, bundle); - return operation; - } - else if (bundle.BundleType == (int)EBundleType.RawBundle) - { - var operation = new CFSLoadRawBundleOperation(this, bundle); - return operation; - } - else - { - string error = $"{nameof(CacheFileSystem)} not support load bundle type : {bundle.BundleType}"; - var operation = new FSLoadBundleCompleteOperation(error); - return operation; - } + var operation = new CFSLoadBundleOperation(this, options); + return operation; } public virtual void SetParameter(string name, object value) @@ -265,7 +169,7 @@ namespace YooAsset } else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE) { - InstallClearMode = (EOverwriteInstallClearMode)value; + InstallClearMode = (EInstallCleanupMode)value; } else if (name == FileSystemParametersDefine.FILE_VERIFY_LEVEL) { @@ -282,10 +186,6 @@ namespace YooAsset // 限制在合理范围内:1-32 FileVerifyMaxConcurrency = Mathf.Clamp(convertValue, 1, 32); } - else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION) - { - AppendFileExtension = Convert.ToBoolean(value); - } else if (name == FileSystemParametersDefine.DISABLE_ONDEMAND_DOWNLOAD) { DisableOnDemandDownload = Convert.ToBoolean(value); @@ -325,22 +225,10 @@ namespace YooAsset { ResumeDownloadResponseCodes = (List)value; } - else if (name == FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY) - { - LoadAssetBundleFactory = (LoadAssetBundleOperationFactory)value; - } - else if (name == FileSystemParametersDefine.LOAD_RAWBUNDLE_OPERATION_FACTORY) - { - LoadRawBundleFactory = (LoadRawBundleOperationFactory)value; - } else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES) { ManifestRestoreServices = (IManifestRestoreServices)value; } - else if (name == FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES) - { - CopyLocalFileServices = (ILocalFileCopyServices)value; - } else { YooLogger.Warning($"Invalid parameter : {name}"); @@ -360,22 +248,25 @@ namespace YooAsset _tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName); // 创建文件缓存系统 - Cache = new BundleCache(PackageName, _cacheBundleFilesRoot, AppendFileExtension); + { + var cacheConfig = new SandboxFileCache.CacheConfig(); + cacheConfig.FileVerifyLevel = FileVerifyLevel; + cacheConfig.FileVerifyMaxConcurrency = FileVerifyMaxConcurrency; + FileCache = new SandboxFileCache(PackageName, _cacheBundleFilesRoot, cacheConfig); + } // 创建默认的下载后台接口 if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); - - // 创建默认的 AssetBundle 加载工厂 - if (LoadAssetBundleFactory == null) - LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory; - - // 创建默认的 RawBundle 加载工厂 - if (LoadRawBundleFactory == null) - LoadRawBundleFactory = DefaultLoadRawBundleOperationFactory; } public virtual void OnDestroy() { + if (FileCache != null) + { + FileCache.Dispose(); + FileCache = null; + } + if (DownloadScheduler != null) { DownloadScheduler.Dispose(); @@ -391,19 +282,15 @@ namespace YooAsset public virtual bool Belong(PackageBundle bundle) { - // 注意:缓存文件系统保底加载! + // 注意:沙盒文件系统保底加载! return true; } - public virtual bool Exists(PackageBundle bundle) - { - return Cache.IsCached(bundle.BundleGUID); - } public virtual bool NeedDownload(PackageBundle bundle) { if (Belong(bundle) == false) return false; - return Exists(bundle) == false; + return FileCache.IsCached(bundle.BundleGUID) == false; } public virtual bool NeedUnpack(PackageBundle bundle) { @@ -414,50 +301,18 @@ namespace YooAsset if (Belong(bundle) == false) return false; - return Exists(bundle) == false; - } - public virtual string GetBundleFilePath(PackageBundle bundle) - { - return GetCacheBundleFileLoadPath(bundle); + return FileCache.IsCached(bundle.BundleGUID) == false; } #region 内部方法 - private LoadAssetBundleOperation DefaultLoadAssetBundleOperationFactory(bool bundleEncrypted, LoadAssetBundleOptions options) - { - if (bundleEncrypted) - { - string error = $"{nameof(DefaultLoadAssetBundleOperation)} cannot load encrypted bundle. Please provide a custom {nameof(LoadAssetBundleOperationFactory)}."; - return new LoadAssetBundleCompleteOperation(error, options); - } - else - { - return new DefaultLoadAssetBundleOperation(options); - } - } - private LoadRawBundleOperation DefaultLoadRawBundleOperationFactory(bool bundleEncrypted, LoadRawBundleOptions options) - { - if (bundleEncrypted) - { - string error = $"{nameof(DefaultLoadRawBundleOperation)} cannot load encrypted bundle. Please provide a custom {nameof(LoadRawBundleOperationFactory)}."; - return new LoadRawBundleCompleteOperation(error, options); - } - else - { - return new DefaultLoadRawBundleOperation(options); - } - } public string GetDefaultCachePackageRoot(string packageName) { string rootDirectory = YooAssetSettingsData.GetYooDefaultCacheRoot(); return PathUtility.Combine(rootDirectory, packageName); } - public string GetCacheBundleFileLoadPath(PackageBundle bundle) + public string GetCacheManifestFilesRoot() { - var entry = Cache.GetEntry(bundle.BundleGUID); - if (entry == null) - throw new YooInternalException(); - - return entry.DataFilePath; + return _cacheManifestFilesRoot; } public string GetCachePackageHashFilePath(string packageVersion) { @@ -473,14 +328,6 @@ namespace YooAsset { return PathUtility.Combine(_cacheManifestFilesRoot, DefaultCacheFileSystemDefine.AppFootPrintFileName); } - public string GetCacheBundleFilesRoot() - { - return _cacheBundleFilesRoot; - } - public string GetCacheManifestFilesRoot() - { - return _cacheManifestFilesRoot; - } public string GetTempFilePath(PackageBundle bundle) { if (_tempFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false) diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/CacheFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/CacheFileSystemDefine.cs index 9b7efce0..2074edff 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/CacheFileSystemDefine.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/CacheFileSystemDefine.cs @@ -3,6 +3,16 @@ namespace YooAsset { internal class DefaultCacheFileSystemDefine { + /// + /// 记录应用程序版本的文件名称 + /// + public const string AppFootPrintFileName = "ApplicationFootPrint.bytes"; + + /// + /// 清单文件的文件夹名称 + /// + public const string ManifestFilesFolderName = "ManifestFiles"; + /// /// 资源文件的文件夹名称 /// @@ -12,15 +22,5 @@ namespace YooAsset /// 临时文件的文件夹名称 /// public const string TempFilesFolderName = "TempFiles"; - - /// - /// 清单文件的文件夹名称 - /// - public const string ManifestFilesFolderName = "ManifestFiles"; - - /// - /// 记录应用程序版本的文件名称 - /// - public const string AppFootPrintFileName = "ApplicationFootPrint.bytes"; } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EOverwriteInstallClearMode.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EInstallCleanupMode.cs similarity index 93% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EOverwriteInstallClearMode.cs rename to Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EInstallCleanupMode.cs index 0a1c4032..9c6688a7 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EOverwriteInstallClearMode.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EInstallCleanupMode.cs @@ -4,7 +4,7 @@ namespace YooAsset /// /// 覆盖安装清理模式 /// - public enum EOverwriteInstallClearMode + public enum EInstallCleanupMode { /// /// 不做任何处理 diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EOverwriteInstallClearMode.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EInstallCleanupMode.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EOverwriteInstallClearMode.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EInstallCleanupMode.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EManifestClearMode.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EManifestClearMode.cs new file mode 100644 index 00000000..76de164e --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EManifestClearMode.cs @@ -0,0 +1,19 @@ + +namespace YooAsset +{ + /// + /// 清单清理方式 + /// + public enum EManifestClearMode + { + /// + /// 清理所有清单 + /// + ClearAllManifestFiles, + + /// + /// 清理未在使用的清单 + /// + ClearUnusedManifestFiles, + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EFileClearMode.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EManifestClearMode.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EFileClearMode.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/EManifestClearMode.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSClearCacheOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSClearCacheOperation.cs new file mode 100644 index 00000000..7acd1553 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSClearCacheOperation.cs @@ -0,0 +1,197 @@ +using System; +using System.IO; + +namespace YooAsset +{ + internal class CFSClearCacheOperation : FSClearCacheOperation + { + private enum ESteps + { + None, + ClearCache, + Done, + } + + private readonly CacheFileSystem _fileSystem; + private readonly ClearCacheOptions _options; + private FCClearCacheOperation _clearCacheOp; + private ESteps _steps = ESteps.None; + + internal CFSClearCacheOperation(CacheFileSystem fileSystem, ClearCacheOptions options) + { + _fileSystem = fileSystem; + _options = options; + } + internal override void InternalStart() + { + _steps = ESteps.ClearCache; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearCache) + { + if (_clearCacheOp == null) + { + _clearCacheOp = _fileSystem.FileCache.ClearCacheAsync(_options); + _clearCacheOp.StartOperation(); + AddChildOperation(_clearCacheOp); + } + + _clearCacheOp.UpdateOperation(); + if (_clearCacheOp.IsDone == false) + return; + + if (_clearCacheOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearCacheOp.Error; + } + } + } + } + + internal class CFSClearAllCacheManifestOperation : FSClearCacheOperation + { + private enum ESteps + { + None, + ClearAllCacheFiles, + Done, + } + + private readonly CacheFileSystem _fileSystem; + private ESteps _steps = ESteps.None; + + internal CFSClearAllCacheManifestOperation(CacheFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalStart() + { + _steps = ESteps.ClearAllCacheFiles; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearAllCacheFiles) + { + try + { + // 注意:如果正在下载资源清单,会有几率触发异常! + string directoryRoot = _fileSystem.GetCacheManifestFilesRoot(); + DirectoryInfo directoryInfo = new DirectoryInfo(directoryRoot); + if (directoryInfo.Exists) + { + foreach (FileInfo fileInfo in directoryInfo.GetFiles()) + { + string fileName = fileInfo.Name; + if (fileName == DefaultCacheFileSystemDefine.AppFootPrintFileName) + continue; + + fileInfo.Delete(); + } + } + + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + catch (Exception ex) + { + _steps = ESteps.Done; + Error = ex.Message; + Status = EOperationStatus.Failed; + } + } + } + } + + internal class CFSClearUnusedCacheManifestOperation : FSClearCacheOperation + { + private enum ESteps + { + None, + CheckManifest, + ClearUnusedCacheFiles, + Done, + } + + private readonly CacheFileSystem _fileSystem; + private readonly PackageManifest _manifest; + private ESteps _steps = ESteps.None; + + internal CFSClearUnusedCacheManifestOperation(CacheFileSystem fileSystem, PackageManifest manifest) + { + _fileSystem = fileSystem; + _manifest = manifest; + } + internal override void InternalStart() + { + _steps = ESteps.CheckManifest; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckManifest) + { + if (_manifest == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Can not found active package manifest."; + } + else + { + _steps = ESteps.ClearUnusedCacheFiles; + } + } + + if (_steps == ESteps.ClearUnusedCacheFiles) + { + try + { + string activeManifestFileName = YooAssetSettingsData.GetManifestBinaryFileName(_manifest.PackageName, _manifest.PackageVersion); + string activeHashFileName = YooAssetSettingsData.GetPackageHashFileName(_manifest.PackageName, _manifest.PackageVersion); + + // 注意:如果正在下载资源清单,会有几率触发异常! + string directoryRoot = _fileSystem.GetCacheManifestFilesRoot(); + DirectoryInfo directoryInfo = new DirectoryInfo(directoryRoot); + if (directoryInfo.Exists) + { + foreach (FileInfo fileInfo in directoryInfo.GetFiles()) + { + string fileName = fileInfo.Name; + if (fileName == DefaultCacheFileSystemDefine.AppFootPrintFileName) + continue; + if (fileName == activeManifestFileName || fileName == activeHashFileName) + continue; + + fileInfo.Delete(); + } + } + + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + catch (Exception ex) + { + _steps = ESteps.Done; + Error = ex.Message; + Status = EOperationStatus.Failed; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearAllCacheManifestFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSClearCacheOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearAllCacheManifestFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSClearCacheOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSDownloadFileOperation.cs new file mode 100644 index 00000000..73bfd1b9 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSDownloadFileOperation.cs @@ -0,0 +1,157 @@ +using UnityEngine; + +namespace YooAsset +{ + internal class CFSDownloadFileOperation : FSDownloadFileOperation + { + protected enum ESteps + { + None, + CheckExists, + DownloadAndCache, + TryAgain, + Done, + } + + private readonly CacheFileSystem _fileSystem; + private readonly DownloadFileOptions _options; + private DownloadFileBaseOperation _downloadFileOp; + private ESteps _steps = ESteps.None; + + // 失败重试 + private int _requestCount = 0; + private float _tryAgainTimer = 0; + private int _failedTryAgain; + + internal CFSDownloadFileOperation(CacheFileSystem fileSystem, DownloadFileOptions options) : base(options.Bundle) + { + _fileSystem = fileSystem; + _options = options; + _failedTryAgain = options.RetryCount; + } + internal override void InternalStart() + { + _steps = ESteps.CheckExists; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 检测文件是否存在 + if (_steps == ESteps.CheckExists) + { + if (_fileSystem.FileCache.IsCached(Bundle.BundleGUID)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + _steps = ESteps.DownloadAndCache; + } + } + + // 下载并缓存文件 + if (_steps == ESteps.DownloadAndCache) + { + if (_downloadFileOp == null) + { + _downloadFileOp = _fileSystem.DownloadScheduler.TryGetDownloadFile(Bundle); + if (_downloadFileOp == null) + { + if (string.IsNullOrEmpty(_options.ImportFilePath)) + { + // 下载远端文件 + string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(Bundle.FileName); + string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(Bundle.FileName); + string url = GetRequestURL(mainURL, fallbackURL); + _downloadFileOp = new DownloadAndCacheFileOperation(_fileSystem, Bundle, url); + _fileSystem.DownloadScheduler.AddDownloadFile(_downloadFileOp); + } + else + { + // 导入本地文件 + _downloadFileOp = new ImportAndCacheFileOperation(_fileSystem, Bundle, _options.ImportFilePath); + _fileSystem.DownloadScheduler.AddDownloadFile(_downloadFileOp); + } + } + } + + if (IsWaitForCompletion) + _downloadFileOp.WaitForCompletion(); + + _downloadFileOp.UpdateOperation(); + Progress = _downloadFileOp.Progress; + DownloadedBytes = _downloadFileOp.DownloadedBytes; + DownloadProgress = _downloadFileOp.DownloadProgress; + if (_downloadFileOp.IsDone == false) + return; + + if (_downloadFileOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + if (IsWaitForCompletion == false && _failedTryAgain > 0) + { + _steps = ESteps.TryAgain; + YooLogger.Warning($"Failed download : {_downloadFileOp.Url} Try again."); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadFileOp.Error; + YooLogger.Error(Error); + } + } + } + + // 重新尝试下载 + if (_steps == ESteps.TryAgain) + { + _tryAgainTimer += Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + _tryAgainTimer = 0f; + _failedTryAgain--; + Progress = 0f; + DownloadProgress = 0f; + DownloadedBytes = 0; + _steps = ESteps.DownloadAndCache; + } + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + internal override void InternalAbort() + { + // 注意:取消下载任务的时候引用计数减一 + if (_steps != ESteps.Done) + { + if (_downloadFileOp != null) + { + _downloadFileOp.Release(); + } + } + } + + /// + /// 获取网络请求地址 + /// + private string GetRequestURL(string mainURL, string fallbackURL) + { + // 轮流返回请求地址 + _requestCount++; + if (_requestCount % 2 == 0) + return fallbackURL; + else + return mainURL; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSDownloadFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSDownloadFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSInitializeOperation.cs index 590dccab..b77c36ee 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSInitializeOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSInitializeOperation.cs @@ -6,14 +6,14 @@ namespace YooAsset private enum ESteps { None, - CheckAppFootPrint, - CacheInitialize, - CreateDownloadScheduler, + CheckAppFootprint, + InitializeFileCache, + CreateScheduler, Done, } private readonly CacheFileSystem _fileSystem; - private FCInitializeOperation _initializeCacheOp; + private FCInitializeOperation _initializeFileCacheOp; private ESteps _steps = ESteps.None; @@ -28,7 +28,7 @@ namespace YooAsset Status = EOperationStatus.Failed; Error = $"{nameof(DefaultCacheFileSystem)} is not support WEBGL platform."; #else - _steps = ESteps.CheckAppFootPrint; + _steps = ESteps.CheckAppFootprint; #endif } internal override void InternalUpdate() @@ -36,30 +36,31 @@ namespace YooAsset if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.CheckAppFootPrint) + if (_steps == ESteps.CheckAppFootprint) { - var appFootPrint = new ApplicationFootprint(_fileSystem); - appFootPrint.Load(_fileSystem.PackageName); + string footprintFilePath = _fileSystem.GetSandboxAppFootPrintFilePath(); + var appFootprint = new ApplicationFootprint(footprintFilePath); + appFootprint.Load(_fileSystem.PackageName); // 如果水印发生变化,则说明覆盖安装后首次打开游戏 - if (appFootPrint.IsDirty()) + if (appFootprint.IsDirty()) { - if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.None) + if (_fileSystem.InstallClearMode == EInstallCleanupMode.None) { YooLogger.Warning("Do nothing when overwrite install application."); } - else if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.ClearAllCacheFiles) + else if (_fileSystem.InstallClearMode == EInstallCleanupMode.ClearAllCacheFiles) { _fileSystem.DeleteAllBundleFiles(); _fileSystem.DeleteAllManifestFiles(); YooLogger.Warning("Delete all cache files when overwrite install application."); } - else if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.ClearAllBundleFiles) + else if (_fileSystem.InstallClearMode == EInstallCleanupMode.ClearAllBundleFiles) { _fileSystem.DeleteAllBundleFiles(); YooLogger.Warning("Delete all bundle files when overwrite install application."); } - else if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.ClearAllManifestFiles) + else if (_fileSystem.InstallClearMode == EInstallCleanupMode.ClearAllManifestFiles) { _fileSystem.DeleteAllManifestFiles(); YooLogger.Warning("Delete all manifest files when overwrite install application."); @@ -69,47 +70,50 @@ namespace YooAsset throw new System.NotImplementedException(_fileSystem.InstallClearMode.ToString()); } - appFootPrint.Coverage(_fileSystem.PackageName); + appFootprint.Coverage(_fileSystem.PackageName); } - _steps = ESteps.CacheInitialize; + _steps = ESteps.InitializeFileCache; } - if (_steps == ESteps.CacheInitialize) + if (_steps == ESteps.InitializeFileCache) { - if (_initializeCacheOp == null) + if (_initializeFileCacheOp == null) { - var options = new FCInitializeOptions(); - options.FileVerifyLevel = _fileSystem.FileVerifyLevel; - options.FileVerifyMaxConcurrency = _fileSystem.FileVerifyMaxConcurrency; - _initializeCacheOp = _fileSystem.Cache.InitializeAsync(options); - _initializeCacheOp.StartOperation(); - AddChildOperation(_initializeCacheOp); + _initializeFileCacheOp = _fileSystem.FileCache.InitializeAsync(); + _initializeFileCacheOp.StartOperation(); + AddChildOperation(_initializeFileCacheOp); } - _initializeCacheOp.UpdateOperation(); - Progress = _initializeCacheOp.Progress; - if (_initializeCacheOp.IsDone == false) + _initializeFileCacheOp.UpdateOperation(); + Progress = _initializeFileCacheOp.Progress; + if (_initializeFileCacheOp.IsDone == false) return; - if (_initializeCacheOp.Status != EOperationStatus.Succeeded) + if (_initializeFileCacheOp.Status == EOperationStatus.Succeeded) { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _initializeCacheOp.Error; + _steps = ESteps.CreateScheduler; } else { - _steps = ESteps.CreateDownloadScheduler; + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _initializeFileCacheOp.Error; } } - if (_steps == ESteps.CreateDownloadScheduler) + if (_steps == ESteps.CreateScheduler) { - // 注意:下载中心作为独立任务运行! + // 注意: 下载调度中心在最后一步创建,防止初始化失败后残留任务。 + // 注意: 下载调度中心作为独立任务运行! if (_fileSystem.DownloadScheduler == null) { - _fileSystem.DownloadScheduler = new DownloadSchedulerOperation(_fileSystem); + var schedulerConfig = new DownloadSchedulerOperation.SchedulerConfig(); + schedulerConfig.SchedulerName = _fileSystem.GetType().Name; + schedulerConfig.DownloadBackend = _fileSystem.DownloadBackend; + schedulerConfig.MaxConcurrency = _fileSystem.DownloadMaxConcurrency; + schedulerConfig.MaxRequestPerFrame = _fileSystem.DownloadMaxRequestPerFrame; + _fileSystem.DownloadScheduler = new DownloadSchedulerOperation(schedulerConfig); AsyncOperationSystem.StartOperation(_fileSystem.PackageName, _fileSystem.DownloadScheduler); } diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSLoadBundleOperation.cs index 64858742..bd38f4d8 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/CFSLoadBundleOperation.cs @@ -1,51 +1,46 @@ -using System; -using System.IO; -using UnityEngine; namespace YooAsset { - internal class CFSLoadAssetBundleOperation : FSLoadBundleOperation + internal class CFSLoadBundleOperation : FSLoadBundleOperation { - protected enum ESteps + private enum ESteps { None, - CheckExist, + Prepare, DownloadFile, AbortDownload, - LoadCacheAssetBundle, + LoadSandboxBundle, CheckResult, - TryFallback, Done, } - protected readonly CacheFileSystem _fileSystem; - protected readonly PackageBundle _bundle; - protected FSDownloadFileOperation _downloadFileOp; - protected LoadAssetBundleOperation _loadAssetBundleOp; - protected ESteps _steps = ESteps.None; + private readonly CacheFileSystem _fileSystem; + private readonly LoadBundleOptions _options; + private FSDownloadFileOperation _downloadFileOp; + private FCLoadBundleOperation _loadBundleOp; + private ESteps _steps = ESteps.None; - - internal CFSLoadAssetBundleOperation(CacheFileSystem fileSystem, PackageBundle bundle) + internal CFSLoadBundleOperation(CacheFileSystem fileSystem, LoadBundleOptions options) { _fileSystem = fileSystem; - _bundle = bundle; + _options = options; } internal override void InternalStart() { - _steps = ESteps.CheckExist; + _steps = ESteps.Prepare; } internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.CheckExist) + if (_steps == ESteps.Prepare) { - if (_fileSystem.Exists(_bundle)) + if (_fileSystem.FileCache.IsCached(_options.Bundle.BundleGUID)) { DownloadProgress = 1f; - DownloadedBytes = _bundle.FileSize; - _steps = ESteps.LoadCacheAssetBundle; + DownloadedBytes = _options.Bundle.FileSize; + _steps = ESteps.LoadSandboxBundle; } else { @@ -53,7 +48,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"The bundle not cached : {_bundle.BundleName}"; + Error = $"The bundle not cached : {_options.Bundle.BundleName}"; YooLogger.Warning(Error); } else @@ -78,9 +73,8 @@ namespace YooAsset { if (_downloadFileOp == null) { - DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue); - _downloadFileOp = _fileSystem.DownloadFileAsync(options); - _downloadFileOp.StartOperation(); + DownloadFileOptions options = new DownloadFileOptions(_options.Bundle, int.MaxValue); + _downloadFileOp = _fileSystem.DownloadFileAsync(options); // 注意:异步任务的开启由调度器统一控制 AddChildOperation(_downloadFileOp); } @@ -95,7 +89,7 @@ namespace YooAsset if (_downloadFileOp.Status == EOperationStatus.Succeeded) { - _steps = ESteps.LoadCacheAssetBundle; + _steps = ESteps.LoadSandboxBundle; } else { @@ -122,284 +116,47 @@ namespace YooAsset Error = "Abort download file."; } - if (_steps == ESteps.LoadCacheAssetBundle) + if (_steps == ESteps.LoadSandboxBundle) { - var options = new LoadAssetBundleOptions(); - options.FileLoadPath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); - options.Bundle = _bundle; - _loadAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options); - _loadAssetBundleOp.StartOperation(); - AddChildOperation(_loadAssetBundleOp); + _loadBundleOp = _fileSystem.FileCache.LoadBundleAsync(_options); + _loadBundleOp.StartOperation(); + AddChildOperation(_loadBundleOp); _steps = ESteps.CheckResult; } if (_steps == ESteps.CheckResult) { if (IsWaitForCompletion) - _loadAssetBundleOp.WaitForCompletion(); + _loadBundleOp.WaitForCompletion(); - _loadAssetBundleOp.UpdateOperation(); - if (_loadAssetBundleOp.IsDone == false) + _loadBundleOp.UpdateOperation(); + if (_loadBundleOp.IsDone == false) return; - if (_loadAssetBundleOp.Status == EOperationStatus.Succeeded) + if (_loadBundleOp.Status == EOperationStatus.Succeeded) { - if (_loadAssetBundleOp.Result == null) + if (_loadBundleOp.BundleResult == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Loaded cache asset bundle is null."; + Error = "Loaded bundle result is null."; YooLogger.Error(Error); } else { _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, _loadAssetBundleOp.Result, _loadAssetBundleOp.ManagedStream); - Status = EOperationStatus.Succeeded; - } - } - else - { - if (_loadAssetBundleOp is LoadAssetBundleCompleteOperation) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _loadAssetBundleOp.Error; - YooLogger.Error(Error); - } - else - { - // 加载失败,尝试后备加载 - _steps = ESteps.TryFallback; - } - } - } - - if (_steps == ESteps.TryFallback) - { - var entry = _fileSystem.Cache.GetEntry(_bundle.BundleGUID); - if (entry == null) - throw new YooInternalException(); - - // 注意:当缓存文件的校验等级为Low的时候,并不能保证缓存文件的完整性。 - // 说明:在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性! - var verifyResult = FileVerifyTools.FileVerify(entry.DataFilePath, _bundle.FileSize, _bundle.FileCRC); - if (verifyResult == EFileVerifyResult.Succeed) - { - // 调用后备加载方法 - // 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。 - // 说明:大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发! - AssetBundle assetBundle = _loadAssetBundleOp.LoadFromMemory(); - if (assetBundle != null) - { - _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, assetBundle, null); - Status = EOperationStatus.Succeeded; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Failed to load asset bundle from memory : {_bundle.BundleName}"; - YooLogger.Error(Error); - } - } - else - { - // 文件损坏,删除缓存 - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Find corrupted asset bundle file and delete : {_bundle.BundleName}"; - YooLogger.Error(Error); - _fileSystem.Cache.RemoveEntry(_bundle.BundleGUID); - } - } - } - internal override void InternalWaitForCompletion() - { - ExecuteBatch(); - } - } - - internal class CFSLoadRawBundleOperation : FSLoadBundleOperation - { - protected enum ESteps - { - None, - CheckExist, - DownloadFile, - AbortDownload, - LoadCacheRawBundle, - CheckResult, - Done, - } - - protected readonly CacheFileSystem _fileSystem; - protected readonly PackageBundle _bundle; - protected FSDownloadFileOperation _downloadFileOp; - protected LoadRawBundleOperation _loadRawBundleOp; - protected ESteps _steps = ESteps.None; - - - internal CFSLoadRawBundleOperation(CacheFileSystem fileSystem, PackageBundle bundle) - { - _fileSystem = fileSystem; - _bundle = bundle; - } - internal override void InternalStart() - { - _steps = ESteps.CheckExist; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.CheckExist) - { - if (_fileSystem.Exists(_bundle)) - { - // 注意:缓存的原生文件的格式,可能会在业务端根据需求发生变动! - // 注意:这里需要校验文件格式,如果不一致对本地文件进行修正! - var entry = _fileSystem.Cache.GetEntry(_bundle.BundleGUID); - if (entry == null) - throw new YooInternalException(); - - if (File.Exists(entry.DataFilePath) == false) - { - try - { - string destFilePath = _fileSystem.Cache.GetDataFilePath(_bundle); - entry.MoveFile(destFilePath); - _steps = ESteps.LoadCacheRawBundle; - } - catch (Exception ex) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Faild rename cached data file : {ex.Message}"; - } - } - else - { - DownloadProgress = 1f; - DownloadedBytes = _bundle.FileSize; - _steps = ESteps.LoadCacheRawBundle; - } - } - else - { - _steps = ESteps.DownloadFile; - } - } - - if (_steps == ESteps.DownloadFile) - { - // 中断下载 - if (AbortDownloadFile) - { - if (_downloadFileOp != null) - _downloadFileOp.AbortOperation(); - _steps = ESteps.AbortDownload; - } - } - - if (_steps == ESteps.DownloadFile) - { - if (_downloadFileOp == null) - { - DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue); - _downloadFileOp = _fileSystem.DownloadFileAsync(options); - _downloadFileOp.StartOperation(); - AddChildOperation(_downloadFileOp); - } - - if (IsWaitForCompletion) - _downloadFileOp.WaitForCompletion(); - - _downloadFileOp.UpdateOperation(); - DownloadProgress = _downloadFileOp.DownloadProgress; - DownloadedBytes = _downloadFileOp.DownloadedBytes; - if (_downloadFileOp.IsDone == false) - return; - - if (_downloadFileOp.Status == EOperationStatus.Succeeded) - { - _steps = ESteps.LoadCacheRawBundle; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloadFileOp.Error; - } - } - - if (_steps == ESteps.AbortDownload) - { - if (_downloadFileOp != null) - { - if (IsWaitForCompletion) - _downloadFileOp.WaitForCompletion(); - - _downloadFileOp.UpdateOperation(); - if (_downloadFileOp.IsDone == false) - return; - } - - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Abort download file."; - } - - if (_steps == ESteps.LoadCacheRawBundle) - { - var options = new LoadRawBundleOptions(); - options.FileLoadPath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); - options.Bundle = _bundle; - _loadRawBundleOp = _fileSystem.LoadRawBundleFactory.Invoke(_bundle.Encrypted, options); - _loadRawBundleOp.StartOperation(); - AddChildOperation(_loadRawBundleOp); - _steps = ESteps.CheckResult; - } - - if (_steps == ESteps.CheckResult) - { - if (IsWaitForCompletion) - _loadRawBundleOp.WaitForCompletion(); - - _loadRawBundleOp.UpdateOperation(); - if (_loadRawBundleOp.IsDone == false) - return; - - if (_loadRawBundleOp.Status == EOperationStatus.Succeeded) - { - if (_loadRawBundleOp.Result == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Loaded cache raw bundle is null."; - YooLogger.Error(Error); - } - else - { - _steps = ESteps.Done; - Result = new RawBundleResult(_fileSystem, _bundle, _loadRawBundleOp.Result); Status = EOperationStatus.Succeeded; + Result = _loadBundleOp.BundleResult; } } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _loadRawBundleOp.Error; + Error = _loadBundleOp.Error; YooLogger.Error(Error); } } } - internal override void InternalWaitForCompletion() - { - ExecuteBatch(); - } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearAllCacheBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearAllCacheBundleFilesOperation.cs deleted file mode 100644 index e23d0b22..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearAllCacheBundleFilesOperation.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset -{ - internal sealed class ClearAllCacheBundleFilesOperation : FSClearCacheOperation - { - private enum ESteps - { - None, - ClearCacheFiles, - Done, - } - - private readonly CacheFileSystem _fileSystem; - private FCClearCacheOperation _clearCacheFileOp; - private ESteps _steps = ESteps.None; - - - internal ClearAllCacheBundleFilesOperation(CacheFileSystem fileSystem) - { - _fileSystem = fileSystem; - } - internal override void InternalStart() - { - _steps = ESteps.ClearCacheFiles; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.ClearCacheFiles) - { - if (_clearCacheFileOp == null) - { - var options = new FCClearCacheOptions(); - options.BundleGUIDs = GetRemoveFiles(); - _clearCacheFileOp = _fileSystem.Cache.ClearCacheAsync(options); - _clearCacheFileOp.StartOperation(); - AddChildOperation(_clearCacheFileOp); - } - - _clearCacheFileOp.UpdateOperation(); - Progress = _clearCacheFileOp.Progress; - if (_clearCacheFileOp.IsDone == false) - return; - - if (_clearCacheFileOp.Status == EOperationStatus.Succeeded) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _clearCacheFileOp.Error; - } - } - } - - private List GetRemoveFiles() - { - var allEntrys = _fileSystem.Cache.GetAllEntries(); - List result = new List(allEntrys.Count); - foreach (var entry in allEntrys) - { - result.Add(entry.BundleGUID); - } - return result; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearAllCacheBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearAllCacheBundleFilesOperation.cs.meta deleted file mode 100644 index fc104aac..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearAllCacheBundleFilesOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: daed187502431d347bf11bddcf8d77de -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearAllCacheManifestFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearAllCacheManifestFilesOperation.cs deleted file mode 100644 index 4d425d8a..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearAllCacheManifestFilesOperation.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.IO; - -namespace YooAsset -{ - internal sealed class ClearAllCacheManifestFilesOperation : FSClearCacheOperation - { - private enum ESteps - { - None, - ClearAllCacheFiles, - Done, - } - - private readonly CacheFileSystem _fileSystem; - private ESteps _steps = ESteps.None; - - - internal ClearAllCacheManifestFilesOperation(CacheFileSystem fileSystem) - { - _fileSystem = fileSystem; - } - internal override void InternalStart() - { - _steps = ESteps.ClearAllCacheFiles; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.ClearAllCacheFiles) - { - try - { - // 注意:如果正在下载资源清单,会有几率触发异常! - string directoryRoot = _fileSystem.GetCacheManifestFilesRoot(); - DirectoryInfo directoryInfo = new DirectoryInfo(directoryRoot); - if (directoryInfo.Exists) - { - foreach (FileInfo fileInfo in directoryInfo.GetFiles()) - { - string fileName = fileInfo.Name; - if (fileName == DefaultCacheFileSystemDefine.AppFootPrintFileName) - continue; - - fileInfo.Delete(); - } - } - - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - } - catch (Exception ex) - { - _steps = ESteps.Done; - Error = ex.Message; - Status = EOperationStatus.Failed; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearCacheBundleFilesByLocationsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearCacheBundleFilesByLocationsOperation.cs deleted file mode 100644 index 131518fb..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearCacheBundleFilesByLocationsOperation.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System.Collections.Generic; - -namespace YooAsset -{ - internal class ClearCacheBundleFilesByLocationsOperation : FSClearCacheOperation - { - private enum ESteps - { - None, - CheckManifest, - CheckArgs, - ClearCacheFiles, - Done, - } - - private readonly CacheFileSystem _fileSystem; - private readonly PackageManifest _manifest; - private readonly object _clearParam; - private FCClearCacheOperation _clearCacheFileOp; - private string[] _locations; - private ESteps _steps = ESteps.None; - - internal ClearCacheBundleFilesByLocationsOperation(CacheFileSystem fileSystem, PackageManifest manifest, object clearParam) - { - _fileSystem = fileSystem; - _manifest = manifest; - _clearParam = clearParam; - } - - internal override void InternalStart() - { - _steps = ESteps.CheckManifest; - } - - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.CheckManifest) - { - if (_manifest == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Can not found active package manifest."; - } - else - { - _steps = ESteps.CheckArgs; - } - } - - if (_steps == ESteps.CheckArgs) - { - if (_clearParam == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Clear param is null."; - return; - } - - if (_clearParam is string) - { - _locations = new string[] { _clearParam as string }; - } - else if (_clearParam is List) - { - var tempList = _clearParam as List; - _locations = tempList.ToArray(); - } - else if (_clearParam is string[]) - { - _locations = _clearParam as string[]; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Invalid clear param : {_clearParam.GetType().FullName}"; - return; - } - - _steps = ESteps.ClearCacheFiles; - } - - if (_steps == ESteps.ClearCacheFiles) - { - if (_clearCacheFileOp == null) - { - var options = new FCClearCacheOptions(); - options.BundleGUIDs = GetRemoveFiles(); - _clearCacheFileOp = _fileSystem.Cache.ClearCacheAsync(options); - _clearCacheFileOp.StartOperation(); - AddChildOperation(_clearCacheFileOp); - } - - _clearCacheFileOp.UpdateOperation(); - Progress = _clearCacheFileOp.Progress; - if (_clearCacheFileOp.IsDone == false) - return; - - if (_clearCacheFileOp.Status == EOperationStatus.Succeeded) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _clearCacheFileOp.Error; - } - } - } - - private List GetRemoveFiles() - { - List result = new List(_locations.Length); - foreach (var location in _locations) - { - string assetPath = _manifest.TryMappingToAssetPath(location); - if (_manifest.TryGetPackageAsset(assetPath, out PackageAsset packageAsset)) - { - PackageBundle bundle = _manifest.GetMainPackageBundle(packageAsset.BundleID); - if (bundle != null) - { - result.Add(bundle.BundleGUID); - } - } - } - return result; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearCacheBundleFilesByLocationsOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearCacheBundleFilesByLocationsOperation.cs.meta deleted file mode 100644 index 089be6bf..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearCacheBundleFilesByLocationsOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0be6ffd570645bf4a95126958a8e8a86 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearCacheBundleFilesByTagsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearCacheBundleFilesByTagsOperation.cs deleted file mode 100644 index 03c15fd9..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearCacheBundleFilesByTagsOperation.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System.Collections.Generic; - -namespace YooAsset -{ - internal class ClearCacheBundleFilesByTagsOperation : FSClearCacheOperation - { - private enum ESteps - { - None, - CheckManifest, - CheckArgs, - ClearCacheFiles, - Done, - } - - private readonly CacheFileSystem _fileSystem; - private readonly PackageManifest _manifest; - private readonly object _clearParam; - private FCClearCacheOperation _clearCacheFileOp; - private string[] _tags; - private ESteps _steps = ESteps.None; - - internal ClearCacheBundleFilesByTagsOperation(CacheFileSystem fileSystem, PackageManifest manifest, object clearParam) - { - _fileSystem = fileSystem; - _manifest = manifest; - _clearParam = clearParam; - } - internal override void InternalStart() - { - _steps = ESteps.CheckManifest; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.CheckManifest) - { - if (_manifest == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Can not found active package manifest."; - } - else - { - _steps = ESteps.CheckArgs; - } - } - - if (_steps == ESteps.CheckArgs) - { - if (_clearParam == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Clear param is null."; - return; - } - - if (_clearParam is string) - { - _tags = new string[] { _clearParam as string }; - } - else if (_clearParam is List) - { - var tempList = _clearParam as List; - _tags = tempList.ToArray(); - } - else if (_clearParam is string[]) - { - _tags = _clearParam as string[]; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Invalid clear param : {_clearParam.GetType().FullName}"; - return; - } - - _steps = ESteps.ClearCacheFiles; - } - - if (_steps == ESteps.ClearCacheFiles) - { - if (_clearCacheFileOp == null) - { - var options = new FCClearCacheOptions(); - options.BundleGUIDs = GetRemoveFiles(); - _clearCacheFileOp = _fileSystem.Cache.ClearCacheAsync(options); - _clearCacheFileOp.StartOperation(); - AddChildOperation(_clearCacheFileOp); - } - - _clearCacheFileOp.UpdateOperation(); - Progress = _clearCacheFileOp.Progress; - if (_clearCacheFileOp.IsDone == false) - return; - - if (_clearCacheFileOp.Status == EOperationStatus.Succeeded) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _clearCacheFileOp.Error; - } - } - } - private List GetRemoveFiles() - { - var allEntrys = _fileSystem.Cache.GetAllEntries(); - List result = new List(allEntrys.Count); - foreach (var entry in allEntrys) - { - if (_manifest.TryGetPackageBundleByBundleGUID(entry.BundleGUID, out PackageBundle bundle)) - { - if (bundle.HasTag(_tags)) - { - result.Add(bundle.BundleGUID); - } - } - } - return result; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearCacheBundleFilesByTagsOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearCacheBundleFilesByTagsOperation.cs.meta deleted file mode 100644 index 36dff9df..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearCacheBundleFilesByTagsOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c42345c14a903274fb160a813ee174dc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearUnusedCacheBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearUnusedCacheBundleFilesOperation.cs deleted file mode 100644 index 42cfa166..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearUnusedCacheBundleFilesOperation.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset -{ - internal sealed class ClearUnusedCacheBundleFilesOperation : FSClearCacheOperation - { - private enum ESteps - { - None, - CheckManifest, - ClearCacheFiles, - Done, - } - - private readonly CacheFileSystem _fileSystem; - private readonly PackageManifest _manifest; - private FCClearCacheOperation _clearCacheFileOp; - private ESteps _steps = ESteps.None; - - - internal ClearUnusedCacheBundleFilesOperation(CacheFileSystem fileSystem, PackageManifest manifest) - { - _fileSystem = fileSystem; - _manifest = manifest; - } - internal override void InternalStart() - { - _steps = ESteps.CheckManifest; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.CheckManifest) - { - if (_manifest == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Can not found active package manifest."; - } - else - { - _steps = ESteps.ClearCacheFiles; - } - } - - if (_steps == ESteps.ClearCacheFiles) - { - if (_clearCacheFileOp == null) - { - var options = new FCClearCacheOptions(); - options.BundleGUIDs = GetRemoveFiles(); - _clearCacheFileOp = _fileSystem.Cache.ClearCacheAsync(options); - _clearCacheFileOp.StartOperation(); - AddChildOperation(_clearCacheFileOp); - } - - _clearCacheFileOp.UpdateOperation(); - Progress = _clearCacheFileOp.Progress; - if (_clearCacheFileOp.IsDone == false) - return; - - if (_clearCacheFileOp.Status == EOperationStatus.Succeeded) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _clearCacheFileOp.Error; - } - } - } - private List GetRemoveFiles() - { - var allEntrys = _fileSystem.Cache.GetAllEntries(); - List result = new List(allEntrys.Count); - foreach (var entry in allEntrys) - { - if (_manifest.IsIncludeBundleFile(entry.BundleGUID) == false) - { - result.Add(entry.BundleGUID); - } - } - return result; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearUnusedCacheBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearUnusedCacheBundleFilesOperation.cs.meta deleted file mode 100644 index b0863b70..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearUnusedCacheBundleFilesOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: be7b242f10abf524fa59e9ca0d12b052 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearUnusedCacheManifestFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearUnusedCacheManifestFilesOperation.cs deleted file mode 100644 index 6eacda2e..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearUnusedCacheManifestFilesOperation.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.IO; - -namespace YooAsset -{ - internal sealed class ClearUnusedCacheManifestFilesOperation : FSClearCacheOperation - { - private enum ESteps - { - None, - CheckManifest, - ClearUnusedCacheFiles, - Done, - } - - private readonly CacheFileSystem _fileSystem; - private readonly PackageManifest _manifest; - private ESteps _steps = ESteps.None; - - - internal ClearUnusedCacheManifestFilesOperation(CacheFileSystem fileSystem, PackageManifest manifest) - { - _fileSystem = fileSystem; - _manifest = manifest; - } - internal override void InternalStart() - { - _steps = ESteps.CheckManifest; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.CheckManifest) - { - if (_manifest == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Can not found active package manifest."; - } - else - { - _steps = ESteps.ClearUnusedCacheFiles; - } - } - - if (_steps == ESteps.ClearUnusedCacheFiles) - { - try - { - string activeManifestFileName = YooAssetSettingsData.GetManifestBinaryFileName(_manifest.PackageName, _manifest.PackageVersion); - string activeHashFileName = YooAssetSettingsData.GetPackageHashFileName(_manifest.PackageName, _manifest.PackageVersion); - - // 注意:如果正在下载资源清单,会有几率触发异常! - string directoryRoot = _fileSystem.GetCacheManifestFilesRoot(); - DirectoryInfo directoryInfo = new DirectoryInfo(directoryRoot); - if (directoryInfo.Exists) - { - foreach (FileInfo fileInfo in directoryInfo.GetFiles()) - { - string fileName = fileInfo.Name; - if (fileName == DefaultCacheFileSystemDefine.AppFootPrintFileName) - continue; - if (fileName == activeManifestFileName || fileName == activeHashFileName) - continue; - - fileInfo.Delete(); - } - } - - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - } - catch (Exception ex) - { - _steps = ESteps.Done; - Error = ex.Message; - Status = EOperationStatus.Failed; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearUnusedCacheManifestFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearUnusedCacheManifestFilesOperation.cs.meta deleted file mode 100644 index 58b93bd9..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ClearUnusedCacheManifestFilesOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d911513cf97d862448df570f0c8e9b38 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadAndCacheFileOperation.cs similarity index 67% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadAndCacheFileOperation.cs index 60737548..a0766e2d 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadAndCacheFileOperation.cs @@ -2,7 +2,7 @@ using System.IO; namespace YooAsset { - internal sealed class DownloadAndCacheRemoteFileOperation : DownloadAndCacheFileOperation + internal sealed class DownloadAndCacheFileOperation : DownloadFileBaseOperation { private enum ESteps { @@ -14,19 +14,17 @@ namespace YooAsset } private readonly CacheFileSystem _fileSystem; - private readonly PackageBundle _bundle; private readonly string _tempFilePath; private bool _enableResume = false; private long _fileOriginLength = 0; - private IDownloadRequest _request; - private FCStoreCacheOperation _bundleCacheOp; + private IDownloadRequest _downloadRequest; + private FCWriteCacheOperation _writeCacheOp; private ESteps _steps = ESteps.None; - internal DownloadAndCacheRemoteFileOperation(CacheFileSystem fileSystem, PackageBundle bundle, string url) : base(url) + internal DownloadAndCacheFileOperation(CacheFileSystem fileSystem, PackageBundle bundle, string url) : base(bundle, url) { _fileSystem = fileSystem; - _bundle = bundle; - _tempFilePath = _fileSystem.GetTempFilePath(_bundle); + _tempFilePath = _fileSystem.GetTempFilePath(bundle); } internal override void InternalStart() { @@ -40,19 +38,19 @@ namespace YooAsset // 创建下载请求 if (_steps == ESteps.CreateRequest) { - FileUtility.CreateFileDirectory(_tempFilePath); + FileUtility.EnsureFileDirectory(_tempFilePath); - _enableResume = _bundle.FileSize >= _fileSystem.ResumeDownloadMinimumSize; + _enableResume = Bundle.FileSize >= _fileSystem.ResumeDownloadMinimumSize; if (_enableResume) { - _request = CreateResumeRequest(); - _request.SendRequest(); + _downloadRequest = CreateResumeRequest(); + _downloadRequest.SendRequest(); _steps = ESteps.CheckRequest; } else { - _request = CreateNormalRequest(); - _request.SendRequest(); + _downloadRequest = CreateNormalRequest(); + _downloadRequest.SendRequest(); _steps = ESteps.CheckRequest; } } @@ -60,14 +58,14 @@ namespace YooAsset // 检测下载结果 if (_steps == ESteps.CheckRequest) { - DownloadProgress = _request.DownloadProgress; - DownloadedBytes = _fileOriginLength + _request.DownloadedBytes; + DownloadProgress = _downloadRequest.DownloadProgress; + DownloadedBytes = _fileOriginLength + _downloadRequest.DownloadedBytes; Progress = DownloadProgress; - if (_request.IsDone == false) + if (_downloadRequest.IsDone == false) return; // 检查网络错误 - if (_request.Status == EDownloadRequestStatus.Succeed) + if (_downloadRequest.Status == EDownloadRequestStatus.Succeeded) { _steps = ESteps.CacheFile; } @@ -75,35 +73,35 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _request.Error; + Error = _downloadRequest.Error; } // 在遇到特殊错误的时候删除文件 if (_enableResume) - ClearTempFileWhenError(_request.HttpCode); + ClearTempFileWhenError(_downloadRequest.HttpCode); // 最终释放请求器 - _request.Dispose(); + _downloadRequest.Dispose(); } // 缓存文件 if (_steps == ESteps.CacheFile) { - if (_bundleCacheOp == null) + if (_writeCacheOp == null) { - var options = new FCStoreCacheOptions(); - options.Bundle = _bundle; + var options = new WriteCacheOptions(); + options.Bundle = Bundle; options.FilePath = _tempFilePath; - _bundleCacheOp = _fileSystem.Cache.StoreCacheAsync(options); - _bundleCacheOp.StartOperation(); - AddChildOperation(_bundleCacheOp); + _writeCacheOp = _fileSystem.FileCache.WriteCacheAsync(options); + _writeCacheOp.StartOperation(); + AddChildOperation(_writeCacheOp); } - _bundleCacheOp.UpdateOperation(); - if (_bundleCacheOp.IsDone == false) + _writeCacheOp.UpdateOperation(); + if (_writeCacheOp.IsDone == false) return; - if (_bundleCacheOp.Status == EOperationStatus.Succeeded) + if (_writeCacheOp.Status == EOperationStatus.Succeeded) { _steps = ESteps.Done; Status = EOperationStatus.Succeeded; @@ -112,7 +110,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _bundleCacheOp.Error; + Error = _writeCacheOp.Error; } // 注意:缓存完成后直接删除临时文件 @@ -122,15 +120,15 @@ namespace YooAsset } internal override void InternalAbort() { - if (_request != null) - _request.Dispose(); + if (_downloadRequest != null) + _downloadRequest.Dispose(); } internal override void InternalWaitForCompletion() { if (_steps != ESteps.Done) { // 注意:不中断下载任务,保持后台继续下载 - YooLogger.Error($"Try load bundle {_bundle.BundleName} from remote : {URL}"); + YooLogger.Error($"Try load bundle {Bundle.BundleName} from remote : {Url}"); } } @@ -140,7 +138,7 @@ namespace YooAsset if (File.Exists(_tempFilePath)) { FileInfo fileInfo = new FileInfo(_tempFilePath); - if (fileInfo.Length >= _bundle.FileSize) + if (fileInfo.Length >= Bundle.FileSize) { File.Delete(_tempFilePath); } @@ -155,7 +153,7 @@ namespace YooAsset bool appendToFile = true; bool removeFileOnAbort = false; long resumeOffset = _fileOriginLength; - var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime, appendToFile, removeFileOnAbort, resumeOffset); + var args = new DownloadFileRequestArgs(Url, _tempFilePath, timeout, watchdogTime, appendToFile, removeFileOnAbort, resumeOffset); return _fileSystem.DownloadBackend.CreateFileRequest(args); } private IDownloadRequest CreateNormalRequest() @@ -166,7 +164,7 @@ namespace YooAsset int watchdogTime = _fileSystem.DownloadWatchDogTimeout; int timeout = 0; //注意:文件下载不做超时检测 - var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime); + var args = new DownloadFileRequestArgs(Url, _tempFilePath, timeout, watchdogTime); return _fileSystem.DownloadBackend.CreateFileRequest(args); } private void ClearTempFileWhenError(long httpCode) diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadAndCacheFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadAndCacheFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageHashOperation.cs index a6109d8a..de2f4b81 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageHashOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageHashOperation.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; namespace YooAsset { @@ -66,7 +66,7 @@ namespace YooAsset if (_webFileRequestOp.IsDone == false) return; - if (_webFileRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webFileRequestOp.Status == EDownloadRequestStatus.Succeeded) { _steps = ESteps.Done; Status = EOperationStatus.Succeeded; diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageManifestOperation.cs index aaa57b83..44b12974 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageManifestOperation.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; namespace YooAsset { @@ -66,7 +66,7 @@ namespace YooAsset if (_webFileRequestOp.IsDone == false) return; - if (_webFileRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webFileRequestOp.Status == EDownloadRequestStatus.Succeeded) { _steps = ESteps.Done; Status = EOperationStatus.Succeeded; diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ImportAndCacheFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ImportAndCacheFileOperation.cs new file mode 100644 index 00000000..f73ea2ae --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ImportAndCacheFileOperation.cs @@ -0,0 +1,106 @@ +using System.IO; + +namespace YooAsset +{ + internal sealed class ImportAndCacheFileOperation : DownloadFileBaseOperation + { + private enum ESteps + { + None, + CheckTempFile, + CopyLocalFile, + CacheFile, + Done, + } + + private readonly CacheFileSystem _fileSystem; + private readonly string _sourceFilePath; + private readonly string _tempFilePath; + private FCWriteCacheOperation _bundleCacheOp; + private ESteps _steps = ESteps.None; + + internal ImportAndCacheFileOperation(CacheFileSystem fileSystem, PackageBundle bundle, string sourceFilePath) : base(bundle, sourceFilePath) + { + _fileSystem = fileSystem; + _sourceFilePath = sourceFilePath; + _tempFilePath = _fileSystem.GetTempFilePath(bundle); + } + internal override void InternalStart() + { + _steps = ESteps.CheckTempFile; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 检测临时文件 + if (_steps == ESteps.CheckTempFile) + { + // 注意:删除历史临时文件 + FileUtility.EnsureFileDirectory(_tempFilePath); + if (File.Exists(_tempFilePath)) + File.Delete(_tempFilePath); + + _steps = ESteps.CopyLocalFile; + } + + // 拷贝本地文件 + if (_steps == ESteps.CopyLocalFile) + { + try + { + File.Copy(_sourceFilePath, _tempFilePath, true); + _steps = ESteps.CacheFile; + } + catch (System.Exception ex) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed copy local file : {ex.Message}"; + } + } + + // 缓存文件 + if (_steps == ESteps.CacheFile) + { + if (_bundleCacheOp == null) + { + var options = new WriteCacheOptions(); + options.Bundle = Bundle; + options.FilePath = _tempFilePath; + _bundleCacheOp = _fileSystem.FileCache.WriteCacheAsync(options); + _bundleCacheOp.StartOperation(); + AddChildOperation(_bundleCacheOp); + } + + if (IsWaitForCompletion) + _bundleCacheOp.WaitForCompletion(); + + _bundleCacheOp.UpdateOperation(); + if (_bundleCacheOp.IsDone == false) + return; + + if (_bundleCacheOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _bundleCacheOp.Error; + } + + // 注意:缓存完成后直接删除临时文件 + if (File.Exists(_tempFilePath)) + File.Delete(_tempFilePath); + } + } + internal override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ImportAndCacheFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/ImportAndCacheFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/RequestRemotePackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/RequestRemotePackageVersionOperation.cs index daf00f0b..0c1b36c1 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/RequestRemotePackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/RequestRemotePackageVersionOperation.cs @@ -1,4 +1,4 @@ - + namespace YooAsset { internal class RequestRemotePackageVersionOperation : AsyncOperationBase @@ -55,7 +55,7 @@ namespace YooAsset if (_webTextRequestOp.IsDone == false) return; - if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeeded) { PackageVersion = _webTextRequestOp.Result; if (string.IsNullOrEmpty(PackageVersion)) diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs deleted file mode 100644 index e9db1ade..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System.IO; - -namespace YooAsset -{ - internal sealed class DownloadAndCacheLocalFileOperation : DownloadAndCacheFileOperation - { - private enum ESteps - { - None, - CheckCopy, - CopyLocalFile, - CreateRequest, - CheckRequest, - CacheFile, - Done, - } - - private readonly CacheFileSystem _fileSystem; - private readonly PackageBundle _bundle; - private readonly string _tempFilePath; - private IDownloadRequest _request; - private FCStoreCacheOperation _bundleCacheOp; - private ESteps _steps = ESteps.None; - - internal DownloadAndCacheLocalFileOperation(CacheFileSystem fileSystem, PackageBundle bundle, string url) : base(url) - { - _fileSystem = fileSystem; - _bundle = bundle; - _tempFilePath = _fileSystem.GetTempFilePath(_bundle); - } - internal override void InternalStart() - { - _steps = ESteps.CheckCopy; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - // 检测文件拷贝 - if (_steps == ESteps.CheckCopy) - { - // 删除历史缓存文件 - FileUtility.CreateFileDirectory(_tempFilePath); - if (File.Exists(_tempFilePath)) - File.Delete(_tempFilePath); - - if (_fileSystem.CopyLocalFileServices != null) - _steps = ESteps.CopyLocalFile; - else - _steps = ESteps.CreateRequest; - } - - // 拷贝本地文件 - if (_steps == ESteps.CopyLocalFile) - { - try - { - //TODO 团结引擎,在某些机型(红米),拷贝包内文件会小概率失败!需要借助其它方式来拷贝包内文件。 - var localFileInfo = new LocalFileInfo(); - localFileInfo.PackageName = _fileSystem.PackageName; - localFileInfo.BundleName = _bundle.BundleName; - localFileInfo.SourceFileURL = URL; - _fileSystem.CopyLocalFileServices.CopyFile(localFileInfo, _tempFilePath); - if (File.Exists(_tempFilePath)) - { - DownloadProgress = 1f; - DownloadedBytes = _bundle.FileSize; - _steps = ESteps.CacheFile; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Failed copy local file : {URL}"; - } - } - catch (System.Exception ex) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Failed copy local file : {ex.Message}"; - } - } - - // 创建下载请求 - if (_steps == ESteps.CreateRequest) - { - int watchdogTime = _fileSystem.DownloadWatchDogTimeout; - int timeout = 0; //注意:文件下载不做超时检测 - var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime); - _request = _fileSystem.DownloadBackend.CreateFileRequest(args); - _request.SendRequest(); - _steps = ESteps.CheckRequest; - } - - // 检测下载结果 - if (_steps == ESteps.CheckRequest) - { - //TODO 更新下载后台,防止无限挂起 - if (IsWaitForCompletion) - _fileSystem.DownloadBackend.Update(); - - DownloadProgress = _request.DownloadProgress; - DownloadedBytes = _request.DownloadedBytes; - Progress = DownloadProgress; - if (_request.IsDone == false) - return; - - // 检查网络错误 - if (_request.Status == EDownloadRequestStatus.Succeed) - { - _steps = ESteps.CacheFile; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _request.Error; - } - - // 最终释放请求器 - _request.Dispose(); - } - - // 缓存文件 - if (_steps == ESteps.CacheFile) - { - if (_bundleCacheOp == null) - { - var options = new FCStoreCacheOptions(); - options.Bundle = _bundle; - options.FilePath = _tempFilePath; - _bundleCacheOp = _fileSystem.Cache.StoreCacheAsync(options); - _bundleCacheOp.StartOperation(); - AddChildOperation(_bundleCacheOp); - } - - if (IsWaitForCompletion) - _bundleCacheOp.WaitForCompletion(); - - _bundleCacheOp.UpdateOperation(); - if (_bundleCacheOp.IsDone == false) - return; - - if (_bundleCacheOp.Status == EOperationStatus.Succeeded) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _bundleCacheOp.Error; - } - - // 注意:缓存完成后直接删除临时文件 - if (File.Exists(_tempFilePath)) - File.Delete(_tempFilePath); - } - } - internal override void InternalAbort() - { - if (_request != null) - _request.Dispose(); - } - internal override void InternalWaitForCompletion() - { - //TODO 等待导入或解压本地文件完毕,该操作会挂起主线程! - ExecuteUntilComplete(); - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/EditorFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/EditorFileSystem.cs index 7a8b686e..99ae7861 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/EditorFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/EditorFileSystem.cs @@ -1,5 +1,5 @@ using System; -using System.Collections.Generic; +using UnityEngine; namespace YooAsset { @@ -8,9 +8,18 @@ namespace YooAsset /// internal class EditorFileSystem : IFileSystem { - protected readonly Dictionary _records = new Dictionary(10000); protected string _packageRoot; + /// + /// 虚拟文件缓存系统 + /// + public IFileCache FileCache { private set; get; } + + /// + /// 解压调度器 + /// + public DownloadSchedulerOperation DownloadScheduler { get; set; } + /// /// 下载后台接口 /// @@ -21,28 +30,6 @@ namespace YooAsset /// public string PackageName { private set; get; } - /// - /// 文件根目录 - /// - public string FileRoot - { - get - { - return _packageRoot; - } - } - - /// - /// 文件数量 - /// - public int FileCount - { - get - { - return 0; - } - } - #region 自定义参数 /// /// 自定义参数:UnityWebRequest 创建委托 @@ -50,27 +37,41 @@ namespace YooAsset public UnityWebRequestCreator WebRequestCreator { private set; get; } /// - /// 模拟WebGL平台模式 + /// 自定义参数:模拟WebGL平台模式 /// public bool VirtualWebGLMode { private set; get; } = false; /// - /// 模拟虚拟下载模式 + /// 自定义参数:模拟虚拟下载模式 /// public bool VirtualDownloadMode { private set; get; } = false; /// - /// 模拟虚拟下载的网速(单位:字节) + /// 自定义参数:模拟虚拟下载的网速(单位:字节) /// public int VirtualDownloadSpeed { private set; get; } = 1024; /// - /// 异步模拟加载最小帧数 + /// 自定义参数:最大并发连接数 + /// 默认值:8(推荐范围 1-32) + /// 说明:过大的并发数可能被服务器限流,也会增加本地资源消耗 + /// + public int DownloadMaxConcurrency { private set; get; } = 8; + + /// + /// 自定义参数:每帧发起的最大请求数 + /// 默认值:8(推荐范围 1-32) + /// 说明:避免单帧发起过多请求导致卡顿 + /// + public int DownloadMaxRequestPerFrame { private set; get; } = 8; + + /// + /// 自定义参数:异步模拟加载最小帧数 /// public int AsyncSimulateMinFrame { private set; get; } = 1; /// - /// 异步模拟加载最大帧数 + /// 自定义参数:异步模拟加载最大帧数 /// public int AsyncSimulateMaxFrame { private set; get; } = 1; #endregion @@ -100,25 +101,13 @@ namespace YooAsset } public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options) { - string mainURL = options.Bundle.BundleName; - options.SetURL(mainURL, mainURL); - var downloader = new DownloadVirtualBundleOperation(this, options); + var downloader = new EFSDownloadFileOperation(this, options); return downloader; } public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) { - PackageBundle bundle = options.Bundle; - if (bundle.BundleType == (int)EBundleType.VirtualBundle) - { - var operation = new EFSLoadBundleOperation(this, bundle); - return operation; - } - else - { - string error = $"{nameof(EditorFileSystem)} not support load bundle type : {bundle.BundleType}"; - var operation = new FSLoadBundleCompleteOperation(error); - return operation; - } + var operation = new EFSLoadBundleOperation(this, options); + return operation; } public virtual void SetParameter(string name, object value) @@ -143,6 +132,28 @@ namespace YooAsset { VirtualDownloadSpeed = Convert.ToInt32(value); } + else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY) + { + int convertValue = Convert.ToInt32(value); + if (convertValue > 32) + { + YooLogger.Warning($"DOWNLOAD_MAX_CONCURRENCY value {convertValue} is too large, clamped to 32. Recommended range: 1 - 32."); + } + + // 限制在合理范围内:1-32 + DownloadMaxConcurrency = Mathf.Clamp(convertValue, 1, 32); + } + else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_REQUEST_PER_FRAME) + { + int convertValue = Convert.ToInt32(value); + if (convertValue > 32) + { + YooLogger.Warning($"DOWNLOAD_MAX_REQUEST_PER_FRAME value {convertValue} is too large, clamped to 32. Recommended range: 1 - 32."); + } + + // 限制在合理范围内:1-32 + DownloadMaxRequestPerFrame = Mathf.Clamp(convertValue, 1, 32); + } else if (name == FileSystemParametersDefine.ASYNC_SIMULATE_MIN_FRAME) { AsyncSimulateMinFrame = Convert.ToInt32(value); @@ -168,9 +179,31 @@ namespace YooAsset // 创建默认的下载后台接口 if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); + + // 创建编辑器文件缓存系统 + if (AsyncSimulateMinFrame > AsyncSimulateMaxFrame) + AsyncSimulateMinFrame = AsyncSimulateMaxFrame; + var cacheConfig = new EditorFileCache.CacheConfig(); + cacheConfig.VirtualDownloadMode = VirtualDownloadMode; + cacheConfig.VirtualWebGLMode = VirtualWebGLMode; + cacheConfig.AsyncSimulateMinFrame = AsyncSimulateMinFrame; + cacheConfig.AsyncSimulateMaxFrame = AsyncSimulateMaxFrame; + FileCache = new EditorFileCache(packageName, _packageRoot, cacheConfig); } public virtual void OnDestroy() { + if (FileCache != null) + { + FileCache.Dispose(); + FileCache = null; + } + + if (DownloadScheduler != null) + { + DownloadScheduler.Dispose(); + DownloadScheduler = null; + } + if (DownloadBackend != null) { DownloadBackend.Dispose(); @@ -182,23 +215,12 @@ namespace YooAsset { return true; } - public virtual bool Exists(PackageBundle bundle) - { - if (VirtualDownloadMode) - { - return _records.ContainsKey(bundle.BundleGUID); - } - else - { - return true; - } - } public virtual bool NeedDownload(PackageBundle bundle) { if (Belong(bundle) == false) return false; - return Exists(bundle) == false; + return FileCache.IsCached(bundle.BundleGUID) == false; } public virtual bool NeedUnpack(PackageBundle bundle) { @@ -208,7 +230,9 @@ namespace YooAsset { return false; } - public virtual string GetBundleFilePath(PackageBundle bundle) + + #region 内部方法 + public string GetBundleFilePath(PackageBundle bundle) { if (bundle.IncludeMainAssets.Count == 0) return string.Empty; @@ -216,13 +240,6 @@ namespace YooAsset var pacakgeAsset = bundle.IncludeMainAssets[0]; return pacakgeAsset.AssetPath; } - - #region 内部方法 - public void RecordDownloadFile(PackageBundle bundle) - { - if (_records.ContainsKey(bundle.BundleGUID) == false) - _records.Add(bundle.BundleGUID, bundle.BundleName); - } public string GetEditorPackageVersionFilePath() { string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName); @@ -238,15 +255,6 @@ namespace YooAsset string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion); return PathUtility.Combine(_packageRoot, fileName); } - public int GetAsyncSimulateFrame() - { - if (AsyncSimulateMinFrame > AsyncSimulateMaxFrame) - { - AsyncSimulateMinFrame = AsyncSimulateMaxFrame; - } - - return UnityEngine.Random.Range(AsyncSimulateMinFrame, AsyncSimulateMaxFrame + 1); - } #endregion } } diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSDownloadFileOperation.cs similarity index 62% rename from Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageBundleOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSDownloadFileOperation.cs index 0d7b7642..7bb34fa1 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/CacheFileSystem/Operations/internal/DownloadPackageBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSDownloadFileOperation.cs @@ -1,36 +1,32 @@ -using System.IO; using UnityEngine; namespace YooAsset { - internal class DownloadPackageBundleOperation : FSDownloadFileOperation + internal class EFSDownloadFileOperation : FSDownloadFileOperation { protected enum ESteps { None, CheckExists, - CreateRequest, - CheckRequest, + DownloadAndCache, TryAgain, Done, } - // 下载参数 - protected readonly CacheFileSystem _fileSystem; - protected readonly DownloadFileOptions _options; - private DownloadAndCacheFileOperation _downloadFileOp; - - protected int _requestCount = 0; - protected float _tryAgainTimer = 0; - protected int _failedTryAgain; + private readonly EditorFileSystem _fileSystem; + private readonly DownloadFileOptions _options; + private DownloadFileBaseOperation _downloadFileOp; private ESteps _steps = ESteps.None; + // 失败重试 + private float _tryAgainTimer = 0; + private int _failedTryAgain; - internal DownloadPackageBundleOperation(CacheFileSystem fileSystem, DownloadFileOptions options) : base(options.Bundle) + internal EFSDownloadFileOperation(EditorFileSystem fileSystem, DownloadFileOptions options) : base(options.Bundle) { _fileSystem = fileSystem; _options = options; - _failedTryAgain = options.FailedTryAgain; + _failedTryAgain = options.RetryCount; } internal override void InternalStart() { @@ -44,37 +40,31 @@ namespace YooAsset // 检测文件是否存在 if (_steps == ESteps.CheckExists) { - if (_fileSystem.Exists(Bundle)) + if (_fileSystem.FileCache.IsCached(_options.Bundle.BundleGUID)) { _steps = ESteps.Done; Status = EOperationStatus.Succeeded; } else { - _steps = ESteps.CreateRequest; + _steps = ESteps.DownloadAndCache; } } - // 创建下载器 - if (_steps == ESteps.CreateRequest) + // 下载并缓存文件 + if (_steps == ESteps.DownloadAndCache) { - if (_options.IsValid() == false) + if (_downloadFileOp == null) { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Download file options is invalid."; - Debug.Log(Error); - return; + _downloadFileOp = _fileSystem.DownloadScheduler.TryGetDownloadFile(Bundle); + if (_downloadFileOp == null) + { + string editorFilePath = _fileSystem.GetBundleFilePath(Bundle); + _downloadFileOp = new SimulateAndCacheFileOperation(_fileSystem, Bundle, editorFilePath); + _fileSystem.DownloadScheduler.AddDownloadFile(_downloadFileOp); + } } - string url = GetRequestURL(); - _downloadFileOp = _fileSystem.DownloadScheduler.DownloadAndCacheFileAsync(Bundle, url); - _steps = ESteps.CheckRequest; - } - - // 检测下载结果 - if (_steps == ESteps.CheckRequest) - { if (IsWaitForCompletion) _downloadFileOp.WaitForCompletion(); @@ -95,7 +85,7 @@ namespace YooAsset if (IsWaitForCompletion == false && _failedTryAgain > 0) { _steps = ESteps.TryAgain; - YooLogger.Warning($"Failed download : {_downloadFileOp.URL} Try again."); + YooLogger.Warning($"Failed download : {_downloadFileOp.Url} Try again."); } else { @@ -118,7 +108,7 @@ namespace YooAsset Progress = 0f; DownloadProgress = 0f; DownloadedBytes = 0; - _steps = ESteps.CreateRequest; + _steps = ESteps.DownloadAndCache; } } } @@ -137,18 +127,5 @@ namespace YooAsset } } } - - /// - /// 获取网络请求地址 - /// - protected string GetRequestURL() - { - // 轮流返回请求地址 - _requestCount++; - if (_requestCount % 2 == 0) - return _options.FallbackURL; - else - return _options.MainURL; - } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/internal/DownloadVirtualBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSDownloadFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/internal/DownloadVirtualBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSDownloadFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSInitializeOperation.cs index a02badab..0d584036 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSInitializeOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSInitializeOperation.cs @@ -3,18 +3,73 @@ namespace YooAsset { internal class EFSInitializeOperation : FSInitializeOperation { - private readonly EditorFileSystem _fileSytem; + private enum ESteps + { + None, + InitializeFileCache, + CreateScheduler, + Done, + } + + + private readonly EditorFileSystem _fileSystem; + private FCInitializeOperation _initializeFileCacheOp; + private ESteps _steps = ESteps.None; internal EFSInitializeOperation(EditorFileSystem fileSystem) { - _fileSytem = fileSystem; + _fileSystem = fileSystem; } internal override void InternalStart() { - Status = EOperationStatus.Succeeded; + _steps = ESteps.InitializeFileCache; } internal override void InternalUpdate() { + if (_steps == ESteps.InitializeFileCache) + { + if (_initializeFileCacheOp == null) + { + _initializeFileCacheOp = _fileSystem.FileCache.InitializeAsync(); + _initializeFileCacheOp.StartOperation(); + AddChildOperation(_initializeFileCacheOp); + } + + _initializeFileCacheOp.UpdateOperation(); + Progress = _initializeFileCacheOp.Progress; + if (_initializeFileCacheOp.IsDone == false) + return; + + if (_initializeFileCacheOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.CreateScheduler; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _initializeFileCacheOp.Error; + } + } + + if (_steps == ESteps.CreateScheduler) + { + // 注意: 下载调度中心在最后一步创建,防止初始化失败后残留任务。 + // 注意: 下载调度中心作为独立任务运行! + if (_fileSystem.DownloadScheduler == null) + { + var schedulerConfig = new DownloadSchedulerOperation.SchedulerConfig(); + schedulerConfig.SchedulerName = _fileSystem.GetType().Name; + schedulerConfig.DownloadBackend = _fileSystem.DownloadBackend; + schedulerConfig.MaxConcurrency = _fileSystem.DownloadMaxConcurrency; + schedulerConfig.MaxRequestPerFrame = _fileSystem.DownloadMaxRequestPerFrame; + _fileSystem.DownloadScheduler = new DownloadSchedulerOperation(schedulerConfig); + AsyncOperationSystem.StartOperation(_fileSystem.PackageName, _fileSystem.DownloadScheduler); + } + + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSLoadBundleOperation.cs index 0cdb1257..889ab172 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/EFSLoadBundleOperation.cs @@ -3,45 +3,44 @@ namespace YooAsset { internal class EFSLoadBundleOperation : FSLoadBundleOperation { - protected enum ESteps + private enum ESteps { None, - CheckExist, + Prepare, DownloadFile, AbortDownload, - LoadAssetBundle, + LoadVirtualBundle, CheckResult, Done, } private readonly EditorFileSystem _fileSystem; - private readonly PackageBundle _bundle; - protected FSDownloadFileOperation _downloadFileOp; - private int _asyncSimulateFrame; + private readonly LoadBundleOptions _options; + private FSDownloadFileOperation _downloadFileOp; + private FCLoadBundleOperation _loadBundleOp; private ESteps _steps = ESteps.None; - internal EFSLoadBundleOperation(EditorFileSystem fileSystem, PackageBundle bundle) + internal EFSLoadBundleOperation(EditorFileSystem fileSystem, LoadBundleOptions options) { _fileSystem = fileSystem; - _bundle = bundle; + _options = options; } internal override void InternalStart() { - _steps = ESteps.CheckExist; - _asyncSimulateFrame = _fileSystem.GetAsyncSimulateFrame(); + _steps = ESteps.Prepare; } internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.CheckExist) + if (_steps == ESteps.Prepare) { - if (_fileSystem.Exists(_bundle)) + if (_fileSystem.FileCache.IsCached(_options.Bundle.BundleGUID)) { DownloadProgress = 1f; - DownloadedBytes = _bundle.FileSize; - _steps = ESteps.LoadAssetBundle; + DownloadedBytes = _options.Bundle.FileSize; + _steps = ESteps.LoadVirtualBundle; } else { @@ -64,7 +63,7 @@ namespace YooAsset { if (_downloadFileOp == null) { - DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue); + DownloadFileOptions options = new DownloadFileOptions(_options.Bundle, int.MaxValue); _downloadFileOp = _fileSystem.DownloadFileAsync(options); _downloadFileOp.StartOperation(); AddChildOperation(_downloadFileOp); @@ -81,7 +80,7 @@ namespace YooAsset if (_downloadFileOp.Status == EOperationStatus.Succeeded) { - _steps = ESteps.LoadAssetBundle; + _steps = ESteps.LoadVirtualBundle; } else { @@ -108,36 +107,46 @@ namespace YooAsset Error = "Abort download file."; } - if (_steps == ESteps.LoadAssetBundle) + if (_steps == ESteps.LoadVirtualBundle) { - if (IsWaitForCompletion) - { - if (_fileSystem.VirtualWebGLMode) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Virtual WebGL Mode only support asyn load method."; - YooLogger.Error(Error); - } - else - { - _steps = ESteps.CheckResult; - } - } - else - { - if (_asyncSimulateFrame <= 0) - _steps = ESteps.CheckResult; - else - _asyncSimulateFrame--; - } + _loadBundleOp = _fileSystem.FileCache.LoadBundleAsync(_options); + _loadBundleOp.StartOperation(); + AddChildOperation(_loadBundleOp); + _steps = ESteps.CheckResult; } if (_steps == ESteps.CheckResult) { - _steps = ESteps.Done; - Result = new VirtualBundleResult(_fileSystem, _bundle); - Status = EOperationStatus.Succeeded; + if (IsWaitForCompletion) + _loadBundleOp.WaitForCompletion(); + + _loadBundleOp.UpdateOperation(); + if (_loadBundleOp.IsDone == false) + return; + + if (_loadBundleOp.Status == EOperationStatus.Succeeded) + { + if (_loadBundleOp.BundleResult == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Loaded bundle result is null."; + YooLogger.Error(Error); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + Result = _loadBundleOp.BundleResult; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadBundleOp.Error; + YooLogger.Error(Error); + } } } internal override void InternalWaitForCompletion() diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/internal/DownloadVirtualBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/internal/DownloadVirtualBundleOperation.cs deleted file mode 100644 index 5168ef88..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/internal/DownloadVirtualBundleOperation.cs +++ /dev/null @@ -1,148 +0,0 @@ -using UnityEngine; - -namespace YooAsset -{ - internal class DownloadVirtualBundleOperation : FSDownloadFileOperation - { - protected enum ESteps - { - None, - CheckExists, - CreateRequest, - CheckRequest, - TryAgain, - Done, - } - - // 下载参数 - protected readonly EditorFileSystem _fileSystem; - protected readonly DownloadFileOptions _options; - protected IDownloadFileRequest _downloadFileOp; - - protected int _requestCount = 0; - protected float _tryAgainTimer = 0; - protected int _failedTryAgain; - private ESteps _steps = ESteps.None; - - - internal DownloadVirtualBundleOperation(EditorFileSystem fileSystem, DownloadFileOptions options) : base(options.Bundle) - { - _fileSystem = fileSystem; - _options = options; - _failedTryAgain = options.FailedTryAgain; - } - internal override void InternalStart() - { - _steps = ESteps.CheckExists; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - // 检测文件是否存在 - if (_steps == ESteps.CheckExists) - { - if (_fileSystem.Exists(Bundle)) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - } - else - { - _steps = ESteps.CreateRequest; - } - } - - // 创建下载器 - if (_steps == ESteps.CreateRequest) - { - if (_options.IsValid() == false) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Download file options is invalid."; - Debug.Log(Error); - return; - } - - string url = GetRequestURL(); - int speed = _fileSystem.VirtualDownloadSpeed; - var args = new DownloadSimulateRequestArgs(url, Bundle.FileSize, speed); - _downloadFileOp = _fileSystem.DownloadBackend.CreateSimulateRequest(args); - _downloadFileOp.SendRequest(); - _steps = ESteps.CheckRequest; - } - - // 检测下载结果 - if (_steps == ESteps.CheckRequest) - { - Progress = _downloadFileOp.DownloadProgress; - DownloadedBytes = _downloadFileOp.DownloadedBytes; - DownloadProgress = _downloadFileOp.DownloadProgress; - if (_downloadFileOp.IsDone == false) - return; - - if (_downloadFileOp.Status == EDownloadRequestStatus.Succeed) - { - _fileSystem.RecordDownloadFile(Bundle); - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - } - else - { - if (IsWaitForCompletion == false && _failedTryAgain > 0) - { - _steps = ESteps.TryAgain; - YooLogger.Warning($"Failed download : {_downloadFileOp.URL} Try again."); - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloadFileOp.Error; - YooLogger.Error(Error); - } - } - } - - // 重新尝试下载 - if (_steps == ESteps.TryAgain) - { - _tryAgainTimer += Time.unscaledDeltaTime; - if (_tryAgainTimer > 1f) - { - _tryAgainTimer = 0f; - _failedTryAgain--; - Progress = 0f; - DownloadProgress = 0f; - DownloadedBytes = 0; - _steps = ESteps.CreateRequest; - } - } - } - internal override void InternalWaitForCompletion() - { - if (_steps != ESteps.Done) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Try load bundle {Bundle.BundleName} from remote."; - YooLogger.Error(Error); - } - } - - /// - /// 获取网络请求地址 - /// - protected string GetRequestURL() - { - // 轮流返回请求地址 - _requestCount++; - if (_requestCount % 2 == 0) - return _options.FallbackURL; - else - return _options.MainURL; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/internal/SimulateAndCacheFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/internal/SimulateAndCacheFileOperation.cs new file mode 100644 index 00000000..3fda45b4 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/internal/SimulateAndCacheFileOperation.cs @@ -0,0 +1,112 @@ + +namespace YooAsset +{ + internal class SimulateAndCacheFileOperation : DownloadFileBaseOperation + { + protected enum ESteps + { + None, + CreateRequest, + CheckRequest, + CacheFile, + Done, + } + + protected readonly EditorFileSystem _fileSystem; + protected IDownloadRequest _downloadRequest; + private FCWriteCacheOperation _writeCacheOp; + private ESteps _steps = ESteps.None; + + internal SimulateAndCacheFileOperation(EditorFileSystem fileSystem, PackageBundle bundle, string filePath) : base(bundle, filePath) + { + _fileSystem = fileSystem; + } + internal override void InternalStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 创建下载请求 + if (_steps == ESteps.CreateRequest) + { + int speed = _fileSystem.VirtualDownloadSpeed; + var args = new SimulateDownloadRequestArgs(Url, Bundle.FileSize, speed); + _downloadRequest = _fileSystem.DownloadBackend.CreateSimulateRequest(args); + _downloadRequest.SendRequest(); + _steps = ESteps.CheckRequest; + } + + // 检测下载结果 + if (_steps == ESteps.CheckRequest) + { + DownloadedBytes = _downloadRequest.DownloadedBytes; + DownloadProgress = _downloadRequest.DownloadProgress; + Progress = DownloadProgress; + if (_downloadRequest.IsDone == false) + return; + + // 检查网络错误 + if (_downloadRequest.Status == EDownloadRequestStatus.Succeeded) + { + _steps = ESteps.CacheFile; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadRequest.Error; + } + + // 最终释放请求器 + _downloadRequest.Dispose(); + } + + // 缓存文件 + if (_steps == ESteps.CacheFile) + { + if (_writeCacheOp == null) + { + var options = new WriteCacheOptions(); + options.Bundle = Bundle; + options.FilePath = Url; + _writeCacheOp = _fileSystem.FileCache.WriteCacheAsync(options); + _writeCacheOp.StartOperation(); + AddChildOperation(_writeCacheOp); + } + + _writeCacheOp.UpdateOperation(); + if (_writeCacheOp.IsDone == false) + return; + + if (_writeCacheOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _writeCacheOp.Error; + } + } + } + internal override void InternalAbort() + { + if (_downloadRequest != null) + _downloadRequest.Dispose(); + } + internal override void InternalWaitForCompletion() + { + if (_steps != ESteps.Done) + { + // 注意:不中断下载任务,保持后台继续下载 + YooLogger.Error($"Try load bundle {Bundle.BundleName} from remote : {Url}"); + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/internal/SimulateAndCacheFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/internal/SimulateAndCacheFileOperation.cs.meta new file mode 100644 index 00000000..1f4af341 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Services/EditorFileSystem/Operations/internal/SimulateAndCacheFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fcd5dd2d445745b4189568a255b85609 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackFileSystem.cs deleted file mode 100644 index 597e964b..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackFileSystem.cs +++ /dev/null @@ -1,22 +0,0 @@ - -namespace YooAsset -{ - /// - /// 解压文件系统 - /// - internal class UnpackFileSystem : CacheFileSystem - { - public UnpackFileSystem() - { - } - public override void OnCreate(string packageName, string rootDirectory) - { - base.OnCreate(packageName, rootDirectory); - - // 注意:重写保存根目录和临时目录 - _cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, UnpackFileSystemConstants.SaveBundleFilesFolderName); - _cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, UnpackFileSystemConstants.SaveManifestFilesFolderName); - _tempFilesRoot = PathUtility.Combine(_packageRoot, UnpackFileSystemConstants.TempFilesFolderName); - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackFileSystem.cs.meta deleted file mode 100644 index 9d0d1db6..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackFileSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0bb4584d46f520741bcf6f52b67746d5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackFileSystemDefine.cs deleted file mode 100644 index a23fda1a..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackFileSystemDefine.cs +++ /dev/null @@ -1,21 +0,0 @@ - -namespace YooAsset -{ - internal class UnpackFileSystemConstants - { - /// - /// 保存的资源文件的文件夹名称 - /// - public const string SaveBundleFilesFolderName = "UnpackBundleFiles"; - - /// - /// 保存的清单文件的文件夹名称 - /// - public const string SaveManifestFilesFolderName = "UnpackManifestFiles"; - - /// - /// 下载的临时文件的文件夹名称 - /// - public const string TempFilesFolderName = "UnpackTempFiles"; - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackFileSystemDefine.cs.meta deleted file mode 100644 index ca2e3da2..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackFileSystemDefine.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ee46c041e2affd349929df43af3f21c1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackRemoteService.cs b/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackRemoteService.cs deleted file mode 100644 index 378bd197..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackRemoteService.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Collections.Generic; - -namespace YooAsset -{ - internal class UnpackRemoteService : IRemoteServices - { - private readonly string _buildinPackageRoot; - protected readonly Dictionary _mapping = new Dictionary(10000); - - public UnpackRemoteService(string buildinPackRoot) - { - _buildinPackageRoot = buildinPackRoot; - } - string IRemoteServices.GetRemoteMainURL(string fileName) - { - return GetFileLoadURL(fileName); - } - string IRemoteServices.GetRemoteFallbackURL(string fileName) - { - return GetFileLoadURL(fileName); - } - - private string GetFileLoadURL(string fileName) - { - if (_mapping.TryGetValue(fileName, out string url) == false) - { - string filePath = PathUtility.Combine(_buildinPackageRoot, fileName); - url = DownloadSystemTools.ToLocalURL(filePath); - _mapping.Add(fileName, url); - } - return url; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackRemoteService.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackRemoteService.cs.meta deleted file mode 100644 index 8cc2f829..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/UnpackFileSystem/UnpackRemoteService.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 32c355598c9dff847af87f4a867a2d5c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadWebAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebAssetBundleOperation.cs similarity index 87% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadWebAssetBundleOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebAssetBundleOperation.cs index 10ef0441..0debfd7c 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadWebAssetBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebAssetBundleOperation.cs @@ -2,11 +2,6 @@ using UnityEngine; namespace YooAsset { - /// - /// 加载 AssetBundle 的 Operation 工厂委托 - /// - public delegate LoadWebAssetBundleOperation LoadWebAssetBundleOperationFactory(bool bundleEncrypted, LoadWebAssetBundleOptions options); - /// /// 加载 AssetBundle 的抽象基类 /// 用户可继承此类实现自定义加载逻辑(如加密解密) diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadWebAssetBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebAssetBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadWebAssetBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebAssetBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadWebAssetBundleOptions.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebAssetBundleOptions.cs similarity index 95% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadWebAssetBundleOptions.cs rename to Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebAssetBundleOptions.cs index 1c3af9ac..b33b8e74 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadWebAssetBundleOptions.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebAssetBundleOptions.cs @@ -14,7 +14,7 @@ namespace YooAsset /// /// 失败后重试次数 /// - internal int FailedTryAgain { get; set; } + internal int RetryCount { get; set; } /// /// 看门狗超时时间 diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadWebAssetBundleOptions.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebAssetBundleOptions.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operations/LoadWebAssetBundleOptions.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebAssetBundleOptions.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebPackageManifestOperation.cs index 1de66c03..8ad69073 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/LoadWebPackageManifestOperation.cs @@ -1,4 +1,4 @@ -using YooAsset; +using YooAsset; internal class LoadWebPackageManifestOperation : AsyncOperationBase { @@ -65,7 +65,7 @@ internal class LoadWebPackageManifestOperation : AsyncOperationBase if (_webDataRequestOp.IsDone == false) return; - if (_webDataRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webDataRequestOp.Status == EDownloadRequestStatus.Succeeded) { _steps = ESteps.VerifyFileData; } diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/RequestWebPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/RequestWebPackageHashOperation.cs index e509f4c3..5f018531 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/RequestWebPackageHashOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/RequestWebPackageHashOperation.cs @@ -1,4 +1,4 @@ -using YooAsset; +using YooAsset; internal class RequestWebPackageHashOperation : AsyncOperationBase { @@ -57,7 +57,7 @@ internal class RequestWebPackageHashOperation : AsyncOperationBase if (_webTextRequestOp.IsDone == false) return; - if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeeded) { PackageHash = _webTextRequestOp.Result; if (string.IsNullOrEmpty(PackageHash)) diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/RequestWebPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/RequestWebPackageVersionOperation.cs index 3ce7d2f1..cb71ea34 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/RequestWebPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebGameFileSystem/Operations/RequestWebPackageVersionOperation.cs @@ -1,4 +1,4 @@ -using YooAsset; +using YooAsset; internal class RequestWebPackageVersionOperation : AsyncOperationBase { @@ -57,7 +57,7 @@ internal class RequestWebPackageVersionOperation : AsyncOperationBase if (_webTextRequestOp.IsDone == false) return; - if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeeded) { PackageVersion = _webTextRequestOp.Result; if (string.IsNullOrEmpty(PackageVersion)) diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebRemoteFileSystem/Operations/WRFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebRemoteFileSystem/Operations/WRFSInitializeOperation.cs index 63bbaf78..e2560494 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebRemoteFileSystem/Operations/WRFSInitializeOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebRemoteFileSystem/Operations/WRFSInitializeOperation.cs @@ -3,7 +3,16 @@ namespace YooAsset { internal class WRFSInitializeOperation : FSInitializeOperation { + private enum ESteps + { + None, + InitializeFileCache, + Done, + } + private readonly WebRemoteFileSystem _fileSystem; + private FCInitializeOperation _initializeFileCacheOp; + private ESteps _steps = ESteps.None; public WRFSInitializeOperation(WebRemoteFileSystem fileSystem) { @@ -11,10 +20,39 @@ namespace YooAsset } internal override void InternalStart() { - Status = EOperationStatus.Succeeded; + _steps = ESteps.InitializeFileCache; } internal override void InternalUpdate() { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.InitializeFileCache) + { + if (_initializeFileCacheOp == null) + { + _initializeFileCacheOp = _fileSystem.FileCache.InitializeAsync(); + _initializeFileCacheOp.StartOperation(); + AddChildOperation(_initializeFileCacheOp); + } + + _initializeFileCacheOp.UpdateOperation(); + Progress = _initializeFileCacheOp.Progress; + if (_initializeFileCacheOp.IsDone == false) + return; + + if (_initializeFileCacheOp.Status == EOperationStatus.Succeeded) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeeded; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _initializeFileCacheOp.Error; + } + } } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebRemoteFileSystem/Operations/WRFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebRemoteFileSystem/Operations/WRFSLoadBundleOperation.cs index 406f645d..c62586da 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebRemoteFileSystem/Operations/WRFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebRemoteFileSystem/Operations/WRFSLoadBundleOperation.cs @@ -1,79 +1,71 @@  namespace YooAsset { - internal class WRFSLoadAssetBundleOperation : FSLoadBundleOperation + internal class WRFSLoadBundleOperation : FSLoadBundleOperation { private enum ESteps { None, - LoadWebAssetBundle, + LoadWebBundle, Done, } private readonly WebRemoteFileSystem _fileSystem; - private readonly PackageBundle _bundle; - private LoadWebAssetBundleOperation _loadWebAssetBundleOp; + private readonly LoadBundleOptions _options; + private FCLoadBundleOperation _loadBundleOp; private ESteps _steps = ESteps.None; - internal WRFSLoadAssetBundleOperation(WebRemoteFileSystem fileSystem, PackageBundle bundle) + internal WRFSLoadBundleOperation(WebRemoteFileSystem fileSystem, LoadBundleOptions options) { _fileSystem = fileSystem; - _bundle = bundle; + _options = options; } internal override void InternalStart() { - _steps = ESteps.LoadWebAssetBundle; + _steps = ESteps.LoadWebBundle; } internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.LoadWebAssetBundle) + if (_steps == ESteps.LoadWebBundle) { - if (_loadWebAssetBundleOp == null) + if (_loadBundleOp == null) { - var options = new LoadWebAssetBundleOptions(); - options.Bundle = _bundle; - options.FailedTryAgain = int.MaxValue; - options.WatchdogTimeout = _fileSystem.DownloadWatchDogTimeout; - options.DownloadBackend = _fileSystem.DownloadBackend; - options.DisableUnityWebCache = _fileSystem.DisableUnityWebCache; - options.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); - options.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName); - _loadWebAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options); - _loadWebAssetBundleOp.StartOperation(); - AddChildOperation(_loadWebAssetBundleOp); + _loadBundleOp = _fileSystem.FileCache.LoadBundleAsync(_options); + _loadBundleOp.StartOperation(); + AddChildOperation(_loadBundleOp); } - _loadWebAssetBundleOp.UpdateOperation(); - DownloadProgress = _loadWebAssetBundleOp.DownloadProgress; - DownloadedBytes = _loadWebAssetBundleOp.DownloadedBytes; - Progress = _loadWebAssetBundleOp.Progress; - if (_loadWebAssetBundleOp.IsDone == false) + _loadBundleOp.UpdateOperation(); + Progress = _loadBundleOp.Progress; + DownloadProgress = Progress; + DownloadedBytes = 0; + if (_loadBundleOp.IsDone == false) return; - if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeeded) + if (_loadBundleOp.Status == EOperationStatus.Succeeded) { - if (_loadWebAssetBundleOp.Result == null) + if (_loadBundleOp.BundleResult == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Loaded asset bundle object is null."; + Error = $"Loaded bundle result is null."; } else { _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, _loadWebAssetBundleOp.Result, null); Status = EOperationStatus.Succeeded; + Result = _loadBundleOp.BundleResult; } } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _loadWebAssetBundleOp.Error; + Error = _loadBundleOp.Error; } } } diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebRemoteFileSystem/WebRemoteFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebRemoteFileSystem/WebRemoteFileSystem.cs index 0d0b7d5a..4547342a 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebRemoteFileSystem/WebRemoteFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebRemoteFileSystem/WebRemoteFileSystem.cs @@ -10,37 +10,20 @@ namespace YooAsset /// internal class WebRemoteFileSystem : IFileSystem { + /// + /// Web文件缓存系统 + /// + public IFileCache FileCache { get; private set; } + /// /// 下载后台接口 /// - public IDownloadBackend DownloadBackend { private set; get; } + public IDownloadBackend DownloadBackend { get; private set; } /// /// 包裹名称 /// - public string PackageName { private set; get; } - - /// - /// 文件根目录 - /// - public string FileRoot - { - get - { - return string.Empty; - } - } - - /// - /// 文件数量 - /// - public int FileCount - { - get - { - return 0; - } - } + public string PackageName { get; private set; } #region 自定义参数 /// @@ -63,11 +46,6 @@ namespace YooAsset /// public IRemoteServices RemoteServices { private set; get; } - /// - /// 自定义参数:加载 AssetBundle 的工厂委托 - /// - public LoadWebAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; } - /// /// 自定义参数:资源清单服务类 /// @@ -104,18 +82,8 @@ namespace YooAsset } public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) { - PackageBundle bundle = options.Bundle; - if (bundle.BundleType == (int)EBundleType.AssetBundle) - { - var operation = new WRFSLoadAssetBundleOperation(this, bundle); - return operation; - } - else - { - string error = $"{nameof(WebRemoteFileSystem)} not support load bundle type : {bundle.BundleType}"; - var operation = new FSLoadBundleCompleteOperation(error); - return operation; - } + var operation = new WRFSLoadBundleOperation(this, options); + return operation; } public virtual void SetParameter(string name, object value) @@ -141,10 +109,6 @@ namespace YooAsset { RemoteServices = (IRemoteServices)value; } - else if (name == FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY) - { - LoadAssetBundleFactory = (LoadWebAssetBundleOperationFactory)value; - } else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES) { ManifestRestoreServices = (IManifestRestoreServices)value; @@ -162,12 +126,23 @@ namespace YooAsset if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); - // 创建默认的 AssetBundle 加载工厂 - if (LoadAssetBundleFactory == null) - LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory; + // 创建Web文件缓存系统 + var cacheConfig = new WebRemoteFileCache.CacheConfig(); + cacheConfig.DisableUnityWebCache = DisableUnityWebCache; + cacheConfig.RemoteServices = RemoteServices; + cacheConfig.DownloadBackend = DownloadBackend; + cacheConfig.WatchdogTimeout = DownloadWatchDogTimeout; + cacheConfig.RetryCount = int.MaxValue; + FileCache = new WebRemoteFileCache(packageName, packageRoot, cacheConfig); } public virtual void OnDestroy() { + if (FileCache != null) + { + FileCache.Dispose(); + FileCache = null; + } + if (DownloadBackend != null) { DownloadBackend.Dispose(); @@ -177,11 +152,7 @@ namespace YooAsset public virtual bool Belong(PackageBundle bundle) { - return true; - } - public virtual bool Exists(PackageBundle bundle) - { - return true; + return FileCache.IsCached(bundle.BundleGUID); } public virtual bool NeedDownload(PackageBundle bundle) { @@ -195,24 +166,5 @@ namespace YooAsset { return false; } - public virtual string GetBundleFilePath(PackageBundle bundle) - { - throw new System.NotImplementedException(); - } - - #region 内部方法 - private LoadWebAssetBundleOperation DefaultLoadAssetBundleOperationFactory(bool bundleEncrypted, LoadWebAssetBundleOptions options) - { - if (bundleEncrypted) - { - string error = $"{nameof(DefaultLoadWebAssetBundleOperation)} cannot load encrypted bundle. Please provide a custom {nameof(LoadWebAssetBundleOperationFactory)}."; - return new LoadWebAssetBundleCompleteOperation(error, options); - } - else - { - return new DefaultLoadWebAssetBundleOperation(options); - } - } - #endregion } } diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/WSFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/WSFSInitializeOperation.cs index 5aa744f8..5d1c5478 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/WSFSInitializeOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/WSFSInitializeOperation.cs @@ -6,12 +6,12 @@ namespace YooAsset private enum ESteps { None, - LoadCatalogFile, + InitializeFileCache, Done, } private readonly WebServerFileSystem _fileSystem; - private LoadWebServerCatalogFileOperation _loadCatalogFileOp; + private FCInitializeOperation _initializeFileCacheOp; private ESteps _steps = ESteps.None; @@ -21,27 +21,28 @@ namespace YooAsset } internal override void InternalStart() { - _steps = ESteps.LoadCatalogFile; + _steps = ESteps.InitializeFileCache; } internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.LoadCatalogFile) + if (_steps == ESteps.InitializeFileCache) { - if (_loadCatalogFileOp == null) + if (_initializeFileCacheOp == null) { - _loadCatalogFileOp = new LoadWebServerCatalogFileOperation(_fileSystem, 60); - _loadCatalogFileOp.StartOperation(); - AddChildOperation(_loadCatalogFileOp); + _initializeFileCacheOp = _fileSystem.FileCache.InitializeAsync(); + _initializeFileCacheOp.StartOperation(); + AddChildOperation(_initializeFileCacheOp); } - _loadCatalogFileOp.UpdateOperation(); - if (_loadCatalogFileOp.IsDone == false) + _initializeFileCacheOp.UpdateOperation(); + Progress = _initializeFileCacheOp.Progress; + if (_initializeFileCacheOp.IsDone == false) return; - if (_loadCatalogFileOp.Status == EOperationStatus.Succeeded) + if (_initializeFileCacheOp.Status == EOperationStatus.Succeeded) { _steps = ESteps.Done; Status = EOperationStatus.Succeeded; @@ -50,7 +51,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _loadCatalogFileOp.Error; + Error = _initializeFileCacheOp.Error; } } } diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/WSFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/WSFSLoadBundleOperation.cs index 3ce26980..bcb386aa 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/WSFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/WSFSLoadBundleOperation.cs @@ -1,4 +1,4 @@ - + namespace YooAsset { internal class WSFSLoadAssetBundleOperation : FSLoadBundleOperation @@ -6,77 +6,66 @@ namespace YooAsset private enum ESteps { None, - LoadWebAssetBundle, + LoadWebBundle, Done, } private readonly WebServerFileSystem _fileSystem; - private readonly PackageBundle _bundle; - private LoadWebAssetBundleOperation _loadWebAssetBundleOp; + private readonly LoadBundleOptions _options; + private FCLoadBundleOperation _loadBundleOp; private ESteps _steps = ESteps.None; - internal WSFSLoadAssetBundleOperation(WebServerFileSystem fileSystem, PackageBundle bundle) + internal WSFSLoadAssetBundleOperation(WebServerFileSystem fileSystem, LoadBundleOptions options) { _fileSystem = fileSystem; - _bundle = bundle; + _options = options; } internal override void InternalStart() { - _steps = ESteps.LoadWebAssetBundle; + _steps = ESteps.LoadWebBundle; } internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.LoadWebAssetBundle) + if (_steps == ESteps.LoadWebBundle) { - if (_loadWebAssetBundleOp == null) + if (_loadBundleOp == null) { - string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle); - string mainURL = DownloadSystemTools.ToLocalURL(fileLoadPath); - - var options = new LoadWebAssetBundleOptions(); - options.Bundle = _bundle; - options.FailedTryAgain = int.MaxValue; - options.WatchdogTimeout = _fileSystem.DownloadWatchDogTimeout; - options.DownloadBackend = _fileSystem.DownloadBackend; - options.DisableUnityWebCache = _fileSystem.DisableUnityWebCache; - options.MainURL = mainURL; - options.FallbackURL = mainURL; - _loadWebAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options); - _loadWebAssetBundleOp.StartOperation(); - AddChildOperation(_loadWebAssetBundleOp); + _loadBundleOp = _fileSystem.FileCache.LoadBundleAsync(_options); + _loadBundleOp.StartOperation(); + AddChildOperation(_loadBundleOp); } - _loadWebAssetBundleOp.UpdateOperation(); - DownloadProgress = _loadWebAssetBundleOp.DownloadProgress; - DownloadedBytes = _loadWebAssetBundleOp.DownloadedBytes; - Progress = _loadWebAssetBundleOp.Progress; - if (_loadWebAssetBundleOp.IsDone == false) + _loadBundleOp.UpdateOperation(); + Progress = _loadBundleOp.Progress; + DownloadProgress = Progress; + DownloadedBytes = 0; + if (_loadBundleOp.IsDone == false) return; - if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeeded) + if (_loadBundleOp.Status == EOperationStatus.Succeeded) { - if (_loadWebAssetBundleOp.Result == null) + if (_loadBundleOp.BundleResult == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Loaded asset bundle object is null."; + Error = $"Loaded bundle result is null."; } else { _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, _loadWebAssetBundleOp.Result, null); Status = EOperationStatus.Succeeded; + Result = _loadBundleOp.BundleResult; } } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _loadWebAssetBundleOp.Error; + Error = _loadBundleOp.Error; } } } diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/LoadWebServerCatalogFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/LoadWebServerCatalogFileOperation.cs deleted file mode 100644 index db9bd559..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/LoadWebServerCatalogFileOperation.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; - -namespace YooAsset -{ - internal sealed class LoadWebServerCatalogFileOperation : AsyncOperationBase - { - private enum ESteps - { - None, - RequestData, - LoadCatalog, - Done, - } - - private readonly WebServerFileSystem _fileSystem; - private readonly int _timeout; - private IDownloadBytesRequest _webDataRequestOp; - private ESteps _steps = ESteps.None; - - internal LoadWebServerCatalogFileOperation(WebServerFileSystem fileSystem, int timeout) - { - _fileSystem = fileSystem; - _timeout = timeout; - } - internal override void InternalStart() - { - _steps = ESteps.RequestData; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.RequestData) - { - if (_webDataRequestOp == null) - { - string filePath = _fileSystem.GetCatalogBinaryFileLoadPath(); - string url = DownloadSystemTools.ToLocalURL(filePath); - var args = new DownloadDataRequestArgs(url, _timeout, 0); - _webDataRequestOp = _fileSystem.DownloadBackend.CreateBytesRequest(args); - _webDataRequestOp.SendRequest(); - } - - if (_webDataRequestOp.IsDone == false) - return; - - if (_webDataRequestOp.Status == EDownloadRequestStatus.Succeed) - { - _steps = ESteps.LoadCatalog; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _webDataRequestOp.Error; - } - } - - if (_steps == ESteps.LoadCatalog) - { - try - { - var catalog = CatalogFileTools.DeserializeFromBinary(_webDataRequestOp.Result); - if (catalog.PackageName != _fileSystem.PackageName) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Catalog file package name {catalog.PackageName} cannot match the file system package name {_fileSystem.PackageName}"; - return; - } - - foreach (var wrapper in catalog.Wrappers) - { - var fileWrapper = new WebServerFileSystem.FileWrapper(wrapper.FileName); - _fileSystem.RecordCatalogFile(wrapper.BundleGUID, fileWrapper); - } - - YooLogger.Log($"Package '{_fileSystem.PackageName}' buildin catalog files count : {catalog.Wrappers.Count}"); - _steps = ESteps.Done; - Status = EOperationStatus.Succeeded; - } - catch (Exception ex) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Failed to load catalog file : {ex.Message}"; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/LoadWebServerCatalogFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/LoadWebServerCatalogFileOperation.cs.meta deleted file mode 100644 index e5931448..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/LoadWebServerCatalogFileOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4c34c01e10454c842819e066eef488cf -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/LoadWebServerPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/LoadWebServerPackageManifestOperation.cs index a1c2aa9c..ac86e566 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/LoadWebServerPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/LoadWebServerPackageManifestOperation.cs @@ -1,4 +1,4 @@ - + namespace YooAsset { internal class LoadWebServerPackageManifestOperation : AsyncOperationBase @@ -47,7 +47,7 @@ namespace YooAsset if (_webDataRequestOp == null) { string filePath = _fileSystem.GetWebPackageManifestFilePath(_packageVersion); - string url = DownloadSystemTools.ToLocalURL(filePath); + string url = DownloadSystemTools.ToLocalUrl(filePath); var args = new DownloadDataRequestArgs(url, _timeout, 0); _webDataRequestOp = _fileSystem.DownloadBackend.CreateBytesRequest(args); _webDataRequestOp.SendRequest(); @@ -56,7 +56,7 @@ namespace YooAsset if (_webDataRequestOp.IsDone == false) return; - if (_webDataRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webDataRequestOp.Status == EDownloadRequestStatus.Succeeded) { _steps = ESteps.VerifyFileData; } diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/RequestWebServerPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/RequestWebServerPackageHashOperation.cs index 4a2dfc71..09bf153b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/RequestWebServerPackageHashOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/RequestWebServerPackageHashOperation.cs @@ -1,4 +1,4 @@ - + namespace YooAsset { internal class RequestWebServerPackageHashOperation : AsyncOperationBase @@ -42,7 +42,7 @@ namespace YooAsset if (_webTextRequestOp == null) { string filePath = _fileSystem.GetWebPackageHashFilePath(_packageVersion); - string url = DownloadSystemTools.ToLocalURL(filePath); + string url = DownloadSystemTools.ToLocalUrl(filePath); var args = new DownloadDataRequestArgs(url, _timeout, 0); _webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args); _webTextRequestOp.SendRequest(); @@ -52,7 +52,7 @@ namespace YooAsset if (_webTextRequestOp.IsDone == false) return; - if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeeded) { PackageHash = _webTextRequestOp.Result; if (string.IsNullOrEmpty(PackageHash)) diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/RequestWebServerPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/RequestWebServerPackageVersionOperation.cs index 08a0381b..28c3ad8b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/RequestWebServerPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/Operations/internal/RequestWebServerPackageVersionOperation.cs @@ -1,4 +1,4 @@ - + namespace YooAsset { internal class RequestWebServerPackageVersionOperation : AsyncOperationBase @@ -40,7 +40,7 @@ namespace YooAsset if (_webTextRequestOp == null) { string filePath = _fileSystem.GetWebPackageVersionFilePath(); - string url = DownloadSystemTools.ToLocalURL(filePath); + string url = DownloadSystemTools.ToLocalUrl(filePath); var args = new DownloadDataRequestArgs(url, _timeout, 0); _webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args); _webTextRequestOp.SendRequest(); @@ -49,7 +49,7 @@ namespace YooAsset if (_webTextRequestOp.IsDone == false) return; - if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeeded) { PackageVersion = _webTextRequestOp.Result; if (string.IsNullOrEmpty(PackageVersion)) diff --git a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/WebServerFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/WebServerFileSystem.cs index 50381076..7e799b6c 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/WebServerFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Services/WebServerFileSystem/WebServerFileSystem.cs @@ -10,51 +10,23 @@ namespace YooAsset /// internal class WebServerFileSystem : IFileSystem { - public class FileWrapper - { - public string FileName { private set; get; } - - public FileWrapper(string fileName) - { - FileName = fileName; - } - } - - protected readonly Dictionary _wrappers = new Dictionary(10000); protected readonly Dictionary _webFilePathMapping = new Dictionary(10000); - protected string _webPackageRoot = string.Empty; + protected string _packageRoot = string.Empty; + + /// + /// Web文件缓存系统 + /// + public IFileCache FileCache { get; private set; } /// /// 下载后台接口 /// - public IDownloadBackend DownloadBackend { private set; get; } + public IDownloadBackend DownloadBackend { get; private set; } /// /// 包裹名称 /// - public string PackageName { private set; get; } - - /// - /// 文件根目录 - /// - public string FileRoot - { - get - { - return _webPackageRoot; - } - } - - /// - /// 文件数量 - /// - public int FileCount - { - get - { - return 0; - } - } + public string PackageName { get; private set; } #region 自定义参数 /// @@ -72,11 +44,6 @@ namespace YooAsset /// public int DownloadWatchDogTimeout { private set; get; } = 0; - /// - /// 自定义参数:加载 AssetBundle 的工厂委托 - /// - public LoadWebAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; } - /// /// 自定义参数:资源清单服务类 /// @@ -113,18 +80,8 @@ namespace YooAsset } public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) { - PackageBundle bundle = options.Bundle; - if (bundle.BundleType == (int)EBundleType.AssetBundle) - { - var operation = new WSFSLoadAssetBundleOperation(this, bundle); - return operation; - } - else - { - string error = $"{nameof(WebServerFileSystem)} not support load bundle type : {bundle.BundleType}"; - var operation = new FSLoadBundleCompleteOperation(error); - return operation; - } + var operation = new WSFSLoadAssetBundleOperation(this, options); + return operation; } public virtual void SetParameter(string name, object value) @@ -146,10 +103,6 @@ namespace YooAsset int convertValue = Convert.ToInt32(value); DownloadWatchDogTimeout = Mathf.Clamp(convertValue, 0, int.MaxValue); } - else if (name == FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY) - { - LoadAssetBundleFactory = (LoadWebAssetBundleOperationFactory)value; - } else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES) { ManifestRestoreServices = (IManifestRestoreServices)value; @@ -164,20 +117,30 @@ namespace YooAsset PackageName = packageName; if (string.IsNullOrEmpty(packageRoot)) - _webPackageRoot = GetDefaultWebPackageRoot(packageName); + _packageRoot = GetDefaultWebPackageRoot(packageName); else - _webPackageRoot = packageRoot; + _packageRoot = packageRoot; // 创建默认的下载后台接口 if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); - // 创建默认的 AssetBundle 加载工厂 - if (LoadAssetBundleFactory == null) - LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory; + // 创建Web文件缓存系统 + var cacheConfig = new WebServerFileCache.CacheConfig(); + cacheConfig.DisableUnityWebCache = DisableUnityWebCache; + cacheConfig.DownloadBackend = DownloadBackend; + cacheConfig.WatchdogTimeout = DownloadWatchDogTimeout; + cacheConfig.RetryCount = int.MaxValue; + FileCache = new WebServerFileCache(packageName, _packageRoot, cacheConfig); } public virtual void OnDestroy() { + if (FileCache != null) + { + FileCache.Dispose(); + FileCache = null; + } + if (DownloadBackend != null) { DownloadBackend.Dispose(); @@ -187,11 +150,7 @@ namespace YooAsset public virtual bool Belong(PackageBundle bundle) { - return _wrappers.ContainsKey(bundle.BundleGUID); - } - public virtual bool Exists(PackageBundle bundle) - { - return _wrappers.ContainsKey(bundle.BundleGUID); + return FileCache.IsCached(bundle.BundleGUID); } public virtual bool NeedDownload(PackageBundle bundle) { @@ -205,71 +164,27 @@ namespace YooAsset { return false; } - public virtual string GetBundleFilePath(PackageBundle bundle) - { - throw new System.NotImplementedException(); - } #region 内部方法 - private LoadWebAssetBundleOperation DefaultLoadAssetBundleOperationFactory(bool bundleEncrypted, LoadWebAssetBundleOptions options) - { - if (bundleEncrypted) - { - string error = $"{nameof(DefaultLoadWebAssetBundleOperation)} cannot load encrypted bundle. Please provide a custom {nameof(LoadWebAssetBundleOperationFactory)}."; - return new LoadWebAssetBundleCompleteOperation(error, options); - } - else - { - return new DefaultLoadWebAssetBundleOperation(options); - } - } protected string GetDefaultWebPackageRoot(string packageName) { string rootDirectory = YooAssetSettingsData.GetYooDefaultBuildinRoot(); return PathUtility.Combine(rootDirectory, packageName); } - public string GetWebFileLoadPath(PackageBundle bundle) - { - if (_webFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false) - { - filePath = PathUtility.Combine(_webPackageRoot, bundle.FileName); - _webFilePathMapping.Add(bundle.BundleGUID, filePath); - } - return filePath; - } public string GetWebPackageVersionFilePath() { string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName); - return PathUtility.Combine(FileRoot, fileName); + return PathUtility.Combine(_packageRoot, fileName); } public string GetWebPackageHashFilePath(string packageVersion) { string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion); - return PathUtility.Combine(FileRoot, fileName); + return PathUtility.Combine(_packageRoot, fileName); } public string GetWebPackageManifestFilePath(string packageVersion) { string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion); - return PathUtility.Combine(FileRoot, fileName); - } - public string GetCatalogBinaryFileLoadPath() - { - return PathUtility.Combine(_webPackageRoot, BuiltinFileSystemConstants.BuiltinCatalogBinaryFileName); - } - - /// - /// 记录内置文件信息 - /// - public bool RecordCatalogFile(string bundleGUID, FileWrapper wrapper) - { - if (_wrappers.ContainsKey(bundleGUID)) - { - YooLogger.Error($"{nameof(WebServerFileSystem)} has element : {bundleGUID}"); - return false; - } - - _wrappers.Add(bundleGUID, wrapper); - return true; + return PathUtility.Combine(_packageRoot, fileName); } #endregion } diff --git a/Assets/YooAsset/Runtime/Interfaces/ILocalFileCopyServices.cs b/Assets/YooAsset/Runtime/Interfaces/ILocalFileCopyServices.cs deleted file mode 100644 index 79af5a35..00000000 --- a/Assets/YooAsset/Runtime/Interfaces/ILocalFileCopyServices.cs +++ /dev/null @@ -1,30 +0,0 @@ - -namespace YooAsset -{ - public struct LocalFileInfo - { - /// - /// 包裹名称 - /// - public string PackageName; - - /// - /// 资源包名称 - /// - public string BundleName; - - /// - /// 源文件请求地址 - /// - public string SourceFileURL; - } - - /// - /// 本地文件拷贝服务类 - /// 备注:包体内文件拷贝,沙盒内文件导入都会触发该服务! - /// - public interface ILocalFileCopyServices - { - void CopyFile(LocalFileInfo sourceFileInfo, string destFilePath); - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Interfaces/ILocalFileCopyServices.cs.meta b/Assets/YooAsset/Runtime/Interfaces/ILocalFileCopyServices.cs.meta deleted file mode 100644 index 83d8e001..00000000 --- a/Assets/YooAsset/Runtime/Interfaces/ILocalFileCopyServices.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e2eb3bd510fd41c48a01dcc26dd9b985 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/DownloadStatus.cs b/Assets/YooAsset/Runtime/ResourceManager/DownloadStatus.cs index 4443c838..9aa2f3bd 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/DownloadStatus.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/DownloadStatus.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 下载状态信息结构体 + /// public struct DownloadStatus { /// @@ -23,7 +26,10 @@ namespace YooAsset /// public long DownloadedBytes { get; set; } - public static DownloadStatus CreateDefaultStatus() + /// + /// 创建默认的下载状态实例 + /// + public static DownloadStatus CreateDefault() { DownloadStatus status = new DownloadStatus(); return status; diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handles/AllAssetsHandle.cs b/Assets/YooAsset/Runtime/ResourceManager/Handles/AllAssetsHandle.cs index 6dfc54d6..a208dd02 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handles/AllAssetsHandle.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handles/AllAssetsHandle.cs @@ -1,12 +1,15 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace YooAsset { + /// + /// 全资源句柄,用于加载资源包内所有资源对象 + /// public sealed class AllAssetsHandle : HandleBase { private System.Action _callback; - internal AllAssetsHandle(ProviderOperation provider) : base(provider) + internal AllAssetsHandle(ProviderBase provider) : base(provider) { } internal override void InvokeCallback() diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handles/AssetHandle.cs b/Assets/YooAsset/Runtime/ResourceManager/Handles/AssetHandle.cs index 93bfd97e..75d7aa72 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handles/AssetHandle.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handles/AssetHandle.cs @@ -1,12 +1,15 @@ -using UnityEngine; +using UnityEngine; namespace YooAsset { + /// + /// 资源句柄,用于管理单个资源对象的加载和访问 + /// public sealed class AssetHandle : HandleBase { private System.Action _callback; - internal AssetHandle(ProviderOperation provider) : base(provider) + internal AssetHandle(ProviderBase provider) : base(provider) { } internal override void InvokeCallback() diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handles/HandleBase.cs b/Assets/YooAsset/Runtime/ResourceManager/Handles/HandleBase.cs index 26100cb5..2a7aa8c8 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handles/HandleBase.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handles/HandleBase.cs @@ -1,14 +1,21 @@ -using System; +using System; using System.Collections; namespace YooAsset { + /// + /// 资源句柄基类,提供资源加载状态查询和释放功能 + /// public abstract class HandleBase : IEnumerator, IDisposable { private readonly AssetInfo _assetInfo; - internal ProviderOperation Provider { private set; get; } - internal HandleBase(ProviderOperation provider) + /// + /// 关联的资源提供者 + /// + internal ProviderBase Provider { private set; get; } + + internal HandleBase(ProviderBase provider) { Provider = provider; _assetInfo = provider.MainAssetInfo; @@ -53,7 +60,7 @@ namespace YooAsset public DownloadStatus GetDownloadStatus() { if (IsValidWithWarning == false) - return DownloadStatus.CreateDefaultStatus(); + return DownloadStatus.CreateDefault(); return Provider.GetDownloadStatus(); } @@ -71,9 +78,9 @@ namespace YooAsset } /// - /// 最近的错误信息 + /// 错误信息 /// - public string LastError + public string Error { get { @@ -137,9 +144,9 @@ namespace YooAsset else { if (Provider == null) - YooLogger.Warning($"Operation handle is released : {_assetInfo.AssetPath}"); + YooLogger.Warning($"Operation handle is released: {_assetInfo.AssetPath}"); else if (Provider.IsDestroyed) - YooLogger.Warning($"Provider is destroyed : {_assetInfo.AssetPath}"); + YooLogger.Warning($"Provider is destroyed: {_assetInfo.AssetPath}"); return false; } } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handles/HandleFactory.cs b/Assets/YooAsset/Runtime/ResourceManager/Handles/HandleFactory.cs index c84d8d1b..62afd04d 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handles/HandleFactory.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handles/HandleFactory.cs @@ -1,11 +1,14 @@ -using System; +using System; using System.Collections.Generic; namespace YooAsset { + /// + /// 资源句柄工厂,根据类型创建对应的句柄实例 + /// internal static class HandleFactory { - private static readonly Dictionary> _handleFactory = new Dictionary>() + private static readonly Dictionary> _handleFactory = new Dictionary>() { { typeof(AssetHandle), op => new AssetHandle(op) }, { typeof(SceneHandle), op => new SceneHandle(op) }, @@ -14,13 +17,18 @@ namespace YooAsset { typeof(RawFileHandle), op => new RawFileHandle(op) } }; - public static HandleBase CreateHandle(ProviderOperation operation, Type type) + /// + /// 根据类型创建资源句柄 + /// + /// 资源提供者 + /// 句柄类型 + public static HandleBase CreateHandle(ProviderBase provider, Type type) { if (_handleFactory.TryGetValue(type, out var factory) == false) { throw new NotImplementedException($"Handle type {type.FullName} is not supported."); } - return factory(operation); + return factory(provider); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handles/RawFileHandle.cs b/Assets/YooAsset/Runtime/ResourceManager/Handles/RawFileHandle.cs index 7ae436e1..e3efd5a5 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handles/RawFileHandle.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handles/RawFileHandle.cs @@ -1,11 +1,14 @@ - + namespace YooAsset { + /// + /// 原生文件句柄,用于访问未经 Unity 处理的原始文件 + /// public class RawFileHandle : HandleBase { private System.Action _callback; - internal RawFileHandle(ProviderOperation provider) : base(provider) + internal RawFileHandle(ProviderBase provider) : base(provider) { } internal override void InvokeCallback() diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handles/SceneHandle.cs b/Assets/YooAsset/Runtime/ResourceManager/Handles/SceneHandle.cs index 826f917f..08644b11 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handles/SceneHandle.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handles/SceneHandle.cs @@ -1,13 +1,20 @@ -using UnityEngine.SceneManagement; +using UnityEngine.SceneManagement; namespace YooAsset { + /// + /// 场景句柄,用于管理场景的加载、激活和卸载 + /// public class SceneHandle : HandleBase { private System.Action _callback; + + /// + /// 所属资源包名称 + /// internal string PackageName { set; get; } - internal SceneHandle(ProviderOperation provider) : base(provider) + internal SceneHandle(ProviderBase provider) : base(provider) { } internal override void InvokeCallback() @@ -87,7 +94,7 @@ namespace YooAsset } else { - YooLogger.Warning($"Scene is invalid or not loaded : {SceneObject.name}"); + YooLogger.Warning($"Scene is invalid or not loaded: {SceneObject.name}"); return false; } } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handles/SubAssetsHandle.cs b/Assets/YooAsset/Runtime/ResourceManager/Handles/SubAssetsHandle.cs index 95cf7076..24b38e0a 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handles/SubAssetsHandle.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handles/SubAssetsHandle.cs @@ -1,12 +1,15 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace YooAsset { + /// + /// 子资源句柄,用于管理资源包内子资源对象的加载和访问 + /// public sealed class SubAssetsHandle : HandleBase { private System.Action _callback; - internal SubAssetsHandle(ProviderOperation provider) : base(provider) + internal SubAssetsHandle(ProviderBase provider) : base(provider) { } internal override void InvokeCallback() @@ -76,7 +79,7 @@ namespace YooAsset return assetObject as TObject; } - YooLogger.Warning($"Not found sub asset object : {assetName}"); + YooLogger.Warning($"Sub asset object not found: {assetName}"); return null; } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operations/InstantiateOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operations/InstantiateOperation.cs index 139a1d94..16a3dbb1 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operations/InstantiateOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operations/InstantiateOperation.cs @@ -1,7 +1,10 @@ -using UnityEngine; +using UnityEngine; namespace YooAsset { + /// + /// 游戏对象实例化操作 + /// public sealed class InstantiateOperation : AsyncOperationBase { private enum ESteps @@ -95,7 +98,7 @@ namespace YooAsset _instantiateAsync = InstantiateAsyncInternal(_handle.AssetObject, _options); } - if (IsWaitingForAsyncComplete) + if (IsWaitForCompletion) _instantiateAsync.WaitForCompletion(); if (_instantiateAsync.isDone == false) @@ -110,20 +113,20 @@ namespace YooAsset Result.SetActive(false); _steps = ESteps.Done; - Status = EOperationStatus.Succeed; + Status = EOperationStatus.Succeeded; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Instantiate game object is null."; + Error = $"Instantiated game object is null."; } } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Instantiate async results is null."; + Error = $"Async instantiate results are null."; } } #endif diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operations/InstantiateOptions.cs b/Assets/YooAsset/Runtime/ResourceManager/Operations/InstantiateOptions.cs index 6cef708d..c8e90fa2 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operations/InstantiateOptions.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operations/InstantiateOptions.cs @@ -1,7 +1,10 @@ -using UnityEngine; +using UnityEngine; namespace YooAsset { + /// + /// 游戏对象实例化选项 + /// public struct InstantiateOptions { /// @@ -33,6 +36,10 @@ namespace YooAsset internal bool SetPositionAndRotation { private set; get; } + /// + /// 创建实例化选项(仅指定激活状态) + /// + /// 是否激活实例化对象 public InstantiateOptions(bool actived) { Actived = actived; @@ -43,6 +50,13 @@ namespace YooAsset Position = Vector3.zero; Rotation = Quaternion.identity; } + + /// + /// 创建实例化选项(指定父对象) + /// + /// 是否激活实例化对象 + /// 父对象 + /// 是否在世界空间中定位 public InstantiateOptions(bool actived, Transform parent, bool inWorldSpace) { Actived = actived; @@ -53,7 +67,15 @@ namespace YooAsset Position = Vector3.zero; Rotation = Quaternion.identity; } - public InstantiateOptions(bool actived, Transform parent, Vector3 position, Quaternion rotation) + + /// + /// 创建实例化选项(指定父对象和位置旋转) + /// + /// 是否激活实例化对象 + /// 父对象 + /// 位置 + /// 旋转 + public InstantiateOptions(bool actived, Transform parent, Vector3 position, Quaternion rotation) { Actived = actived; Parent = parent; @@ -63,6 +85,13 @@ namespace YooAsset Position = position; Rotation = rotation; } + + /// + /// 创建实例化选项(指定位置旋转) + /// + /// 是否激活实例化对象 + /// 位置 + /// 旋转 public InstantiateOptions(bool actived, Vector3 position, Quaternion rotation) { Actived = actived; diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operations/Internal/LoadBundleOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operations/Internal/LoadBundleOperation.cs index 137fa681..b790ec60 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operations/Internal/LoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operations/Internal/LoadBundleOperation.cs @@ -1,9 +1,12 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; namespace YooAsset { + /// + /// 资源包加载操作 + /// internal class LoadBundleOperation : AsyncOperationBase { private enum ESteps @@ -14,9 +17,9 @@ namespace YooAsset Done, } - private readonly ResourceManager _resManager; - private readonly List _providers = new List(100); - private readonly List _removeList = new List(100); + private readonly ResourceManager _resourceManager; + private readonly List _providers = new List(100); + private readonly List _removeList = new List(100); private FSLoadBundleOperation _loadBundleOp; private ESteps _steps = ESteps.None; @@ -48,12 +51,12 @@ namespace YooAsset /// /// 加载结果 /// - public BundleResult Result { set; get; } + public IBundleResult Result { set; get; } internal LoadBundleOperation(ResourceManager resourceManager, BundleInfo bundleInfo) { - _resManager = resourceManager; + _resourceManager = resourceManager; LoadBundleInfo = bundleInfo; } internal override void InternalStart() @@ -73,7 +76,7 @@ namespace YooAsset } else { - if (_resManager.BundleLoadingIsBusy()) + if (_resourceManager.IsBundleLoadingBusy()) return; _steps = ESteps.LoadBundleFile; } @@ -84,7 +87,7 @@ namespace YooAsset if (_loadBundleOp == null) { // 统计计数增加 - _resManager.IncrementBundleLoadingCounter(); + _resourceManager.IncrementBundleLoadingCounter(); _loadBundleOp = LoadBundleInfo.CreateBundleLoader(); _loadBundleOp.StartOperation(); AddChildOperation(_loadBundleOp); @@ -122,7 +125,7 @@ namespace YooAsset } // 统计计数减少 - _resManager.DecrementBundleLoadingCounter(); + _resourceManager.DecrementBundleLoadingCounter(); } } internal override void InternalWaitForCompletion() @@ -159,10 +162,10 @@ namespace YooAsset // 注意:正在加载中的任务不可以销毁 if (_steps == ESteps.LoadBundleFile) - throw new YooInternalException($"Cannot destroy loader while loading bundle : {LoadBundleInfo.Bundle.BundleName}"); + throw new YooInternalException($"Cannot destroy loader while loading bundle: {LoadBundleInfo.Bundle.BundleName}"); if (RefCount > 0) - throw new YooInternalException($"Cannot destroy loader with non-zero ref count {RefCount} : {LoadBundleInfo.Bundle.BundleName}"); + throw new YooInternalException($"Cannot destroy loader with non-zero ref count {RefCount}: {LoadBundleInfo.Bundle.BundleName}"); if (Result != null) Result.UnloadBundleFile(); @@ -180,7 +183,7 @@ namespace YooAsset /// public bool CanDestroyLoader() { - if (CanReleasableLoader() == false) + if (IsReleasable() == false) return false; // YOOASSET_LEGACY_DEPENDENCY @@ -191,10 +194,10 @@ namespace YooAsset foreach (var bundleID in LoadBundleInfo.Bundle.ReferenceBundleIDs) { #if YOOASSET_EXPERIMENTAL - if (_resManager.CheckBundleReleasable(bundleID) == false) + if (_resourceManager.CheckBundleReleasable(bundleID) == false) return false; #else - if (_resManager.CheckBundleDestroyed(bundleID) == false) + if (_resourceManager.CheckBundleDestroyed(bundleID) == false) return false; #endif } @@ -206,7 +209,7 @@ namespace YooAsset /// /// 是否可以释放 /// - public bool CanReleasableLoader() + public bool IsReleasable() { // 注意:正在加载中的任务不可以销毁 if (_steps == ESteps.LoadBundleFile) @@ -221,7 +224,7 @@ namespace YooAsset /// /// 添加附属的资源提供者 /// - public void AddProvider(ProviderOperation provider) + public void AddProvider(ProviderBase provider) { if (_providers.Contains(provider) == false) _providers.Add(provider); @@ -252,7 +255,7 @@ namespace YooAsset // 移除资源提供者 if (_removeList.Count > 0) { - _resManager.RemoveBundleProviders(_removeList); + _resourceManager.RemoveBundleProviders(_removeList); _removeList.Clear(); } } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadAllAssetsOperation.cs index e779ca05..e8248dd7 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadAllAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadAllAssetsOperation.cs @@ -1,8 +1,11 @@ -using System; +using System; using UnityEngine; namespace YooAsset { + /// + /// 卸载所有资源的异步操作 + /// public sealed class UnloadAllAssetsOperation : AsyncOperationBase { private enum ESteps @@ -16,13 +19,13 @@ namespace YooAsset Done, } - private readonly ResourceManager _resManager; + private readonly ResourceManager _resourceManager; private readonly UnloadAllAssetsOptions _options; private ESteps _steps = ESteps.None; internal UnloadAllAssetsOperation(ResourceManager resourceManager, UnloadAllAssetsOptions options) { - _resManager = resourceManager; + _resourceManager = resourceManager; _options = options; } internal override void InternalStart() @@ -38,7 +41,7 @@ namespace YooAsset { // 设置锁定状态 if (_options.LockLoadOperation) - _resManager.LockLoadOperation = true; + _resourceManager.LockLoadOperation = true; _steps = ESteps.ReleaseAll; } @@ -46,12 +49,12 @@ namespace YooAsset if (_steps == ESteps.ReleaseAll) { // 清空所有场景句柄 - _resManager.SceneHandles.Clear(); + _resourceManager.SceneHandles.Clear(); // 释放所有资源句柄 if (_options.ReleaseAllHandles) { - foreach (var provider in _resManager.ProviderDic.Values) + foreach (var provider in _resourceManager.ProviderDict.Values) { provider.ReleaseAllHandles(); } @@ -64,7 +67,7 @@ namespace YooAsset { // 尝试终止所有加载任务 // 注意:正在加载AssetBundle的任务无法终止 - foreach (var loader in _resManager.LoaderDic.Values) + foreach (var loader in _resourceManager.BundleLoaderDict.Values) { loader.TryAbortLoader(); } @@ -74,7 +77,7 @@ namespace YooAsset if (_steps == ESteps.CheckLoading) { // 注意:等待所有任务完成 - foreach (var provider in _resManager.ProviderDic.Values) + foreach (var provider in _resourceManager.ProviderDict.Values) { if (provider.IsDone == false) return; @@ -85,21 +88,21 @@ namespace YooAsset if (_steps == ESteps.DestroyAll) { // 强制销毁资源提供者 - foreach (var provider in _resManager.ProviderDic.Values) + foreach (var provider in _resourceManager.ProviderDict.Values) { provider.DestroyProvider(); } // 强制销毁文件加载器 - foreach (var loader in _resManager.LoaderDic.Values) + foreach (var loader in _resourceManager.BundleLoaderDict.Values) { loader.DestroyLoader(); } // 清空数据 - _resManager.ProviderDic.Clear(); - _resManager.LoaderDic.Clear(); - _resManager.LockLoadOperation = false; + _resourceManager.ProviderDict.Clear(); + _resourceManager.BundleLoaderDict.Clear(); + _resourceManager.LockLoadOperation = false; // 注意:调用底层接口释放所有资源 Resources.UnloadUnusedAssets(); diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadAllAssetsOptions.cs b/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadAllAssetsOptions.cs index 23272d1b..43b2a53a 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadAllAssetsOptions.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadAllAssetsOptions.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 卸载所有资源的选项配置 + /// public struct UnloadAllAssetsOptions { /// @@ -13,6 +16,11 @@ namespace YooAsset /// public bool LockLoadOperation { set; get; } + /// + /// 创建卸载所有资源的选项 + /// + /// 是否释放所有句柄 + /// 是否锁定加载操作 public UnloadAllAssetsOptions(bool releaseAllHandles, bool lockLoadOperation) { ReleaseAllHandles = releaseAllHandles; diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadSceneOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadSceneOperation.cs index 8a83efa2..0ff43639 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadSceneOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadSceneOperation.cs @@ -19,14 +19,14 @@ namespace YooAsset private ESteps _steps = ESteps.None; private readonly string _error; - private readonly ProviderOperation _provider; + private readonly ProviderBase _provider; private AsyncOperation _asyncOp = null; internal UnloadSceneOperation(string error) { _error = error; } - internal UnloadSceneOperation(ProviderOperation provider) + internal UnloadSceneOperation(ProviderBase provider) { _error = null; _provider = provider; diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadUnusedAssetsOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadUnusedAssetsOperation.cs index 0de58b0a..8dbbd66c 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadUnusedAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadUnusedAssetsOperation.cs @@ -1,8 +1,11 @@ -using System.Collections; +using System.Collections; using System.Collections.Generic; namespace YooAsset { + /// + /// 卸载未使用资源的异步操作 + /// public sealed class UnloadUnusedAssetsOperation : AsyncOperationBase { private enum ESteps @@ -12,14 +15,14 @@ namespace YooAsset Done, } - private readonly ResourceManager _resManager; + private readonly ResourceManager _resourceManager; private readonly UnloadUnusedAssetsOptions _options; private int _loopCounter = 0; private ESteps _steps = ESteps.None; internal UnloadUnusedAssetsOperation(ResourceManager resourceManager, UnloadUnusedAssetsOptions options) { - _resManager = resourceManager; + _resourceManager = resourceManager; _options = options; } internal override void InternalStart() @@ -64,16 +67,16 @@ namespace YooAsset /// private void LoopUnloadUnused() { - var removeList = new List(_resManager.LoaderDic.Count); + var removeList = new List(_resourceManager.BundleLoaderDict.Count); // 注意:优先销毁资源提供者 - foreach (var loader in _resManager.LoaderDic.Values) + foreach (var loader in _resourceManager.BundleLoaderDict.Values) { loader.TryDestroyProviders(); } // 获取销毁列表 - foreach (var loader in _resManager.LoaderDic.Values) + foreach (var loader in _resourceManager.BundleLoaderDict.Values) { if (loader.CanDestroyLoader()) { @@ -86,7 +89,7 @@ namespace YooAsset { string bundleName = loader.LoadBundleInfo.Bundle.BundleName; loader.DestroyLoader(); - _resManager.LoaderDic.Remove(bundleName); + _resourceManager.BundleLoaderDict.Remove(bundleName); } } } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadUnusedAssetsOptions.cs b/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadUnusedAssetsOptions.cs index 4e2839c3..34bc4646 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadUnusedAssetsOptions.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operations/UnloadUnusedAssetsOptions.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 卸载未使用资源的选项配置 + /// public struct UnloadUnusedAssetsOptions { /// @@ -8,6 +11,10 @@ namespace YooAsset /// public int LoopCount { set; get; } + /// + /// 创建卸载未使用资源的选项 + /// + /// 循环迭代次数 public UnloadUnusedAssetsOptions(int loopCount) { LoopCount = loopCount; diff --git a/Assets/YooAsset/Runtime/ResourceManager/Providers/AllAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Providers/AllAssetsProvider.cs index 05427ec1..081c77e1 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Providers/AllAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Providers/AllAssetsProvider.cs @@ -1,7 +1,10 @@ - + namespace YooAsset { - internal sealed class AllAssetsProvider : ProviderOperation + /// + /// 全资源提供者,负责加载资源包内所有资源 + /// + internal sealed class AllAssetsProvider : ProviderBase { private FSLoadAllAssetsOperation _loadAllAssetsOp; @@ -17,7 +20,7 @@ namespace YooAsset AddChildOperation(_loadAllAssetsOp); #if UNITY_WEBGL - if (_resManager.WebGLForceSyncLoadAsset) + if (_resourceManager.WebGLForceSyncLoadAsset) _loadAllAssetsOp.WaitForAsyncComplete(); #endif } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Providers/AssetProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Providers/AssetProvider.cs index bb300f93..2f129be3 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Providers/AssetProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Providers/AssetProvider.cs @@ -1,7 +1,10 @@ - + namespace YooAsset { - internal sealed class AssetProvider : ProviderOperation + /// + /// 资源提供者,负责加载单个资源对象 + /// + internal sealed class AssetProvider : ProviderBase { private FSLoadAssetOperation _loadAssetOp; @@ -17,7 +20,7 @@ namespace YooAsset AddChildOperation(_loadAssetOp); #if UNITY_WEBGL - if (_resManager.WebGLForceSyncLoadAsset) + if (_resourceManager.WebGLForceSyncLoadAsset) _loadAssetOp.WaitForAsyncComplete(); #endif } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Providers/CompletedProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Providers/CompletedProvider.cs deleted file mode 100644 index 5a81585e..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Providers/CompletedProvider.cs +++ /dev/null @@ -1,18 +0,0 @@ - -namespace YooAsset -{ - internal sealed class CompletedProvider : ProviderOperation - { - public CompletedProvider(ResourceManager manager, AssetInfo assetInfo) : base(manager, string.Empty, assetInfo) - { - } - protected override void ProcessBundleResult() - { - } - - public void SetCompletedWithError(string error) - { - InvokeCompletion(error, EOperationStatus.Failed); - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Providers/ErrorProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Providers/ErrorProvider.cs new file mode 100644 index 00000000..5a350d18 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Providers/ErrorProvider.cs @@ -0,0 +1,34 @@ + +namespace YooAsset +{ + /// + /// 错误提供者,用于处理加载失败的情况 + /// + internal sealed class ErrorProvider : ProviderBase + { + /// + /// 创建错误提供者实例 + /// + /// 资源管理器 + /// 资源信息 + public ErrorProvider(ResourceManager manager, AssetInfo assetInfo) : base(manager, string.Empty, assetInfo) + { + } + + /// + /// 处理资源包加载结果(空实现) + /// + protected override void ProcessBundleResult() + { + } + + /// + /// 设置错误完成状态 + /// + /// 错误信息 + public void SetCompletedWithError(string error) + { + InvokeCompletion(error, EOperationStatus.Failed); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Providers/CompletedProvider.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Providers/ErrorProvider.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourceManager/Providers/CompletedProvider.cs.meta rename to Assets/YooAsset/Runtime/ResourceManager/Providers/ErrorProvider.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourceManager/Providers/ProviderOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Providers/ProviderBase.cs similarity index 86% rename from Assets/YooAsset/Runtime/ResourceManager/Providers/ProviderOperation.cs rename to Assets/YooAsset/Runtime/ResourceManager/Providers/ProviderBase.cs index 502dad59..1dede9e1 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Providers/ProviderOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Providers/ProviderBase.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -6,7 +6,10 @@ using System; namespace YooAsset { - internal abstract class ProviderOperation : AsyncOperationBase + /// + /// 资源提供者基类,负责管理资源的加载和句柄创建 + /// + internal abstract class ProviderBase : AsyncOperationBase { protected enum ESteps { @@ -50,7 +53,7 @@ namespace YooAsset /// /// 加载的资源包结果 /// - public BundleResult LoadedBundleResult { protected set; get; } + public IBundleResult LoadedBundleResult { protected set; get; } /// /// 加载的场景名称 @@ -79,26 +82,32 @@ namespace YooAsset } private ESteps _steps = ESteps.None; - protected readonly ResourceManager _resManager; + protected readonly ResourceManager _resourceManager; private readonly LoadBundleOperation _mainBundleLoader; private readonly List _bundleLoaders = new List(10); private readonly HashSet _handles = new HashSet(); - public ProviderOperation(ResourceManager manager, string providerGUID, AssetInfo assetInfo) + /// + /// 创建资源提供者实例 + /// + /// 资源管理器 + /// 提供者唯一标识符 + /// 资源信息 + public ProviderBase(ResourceManager manager, string providerGUID, AssetInfo assetInfo) { - _resManager = manager; + _resourceManager = manager; ProviderGUID = providerGUID; MainAssetInfo = assetInfo; if (string.IsNullOrEmpty(providerGUID) == false) { // 主资源包加载器 - _mainBundleLoader = manager.CreateMainBundleFileLoader(assetInfo); + _mainBundleLoader = manager.GetOrCreateMainBundleLoader(assetInfo); _mainBundleLoader.AddProvider(this); _bundleLoaders.Add(_mainBundleLoader); // 依赖资源包加载器集合 - var dependLoaders = manager.CreateDependBundleFileLoaders(assetInfo); + var dependLoaders = manager.GetOrCreateDependBundleLoaders(assetInfo); if (dependLoaders.Count > 0) _bundleLoaders.AddRange(dependLoaders); @@ -189,6 +198,10 @@ namespace YooAsset { return $"AssetPath : {MainAssetInfo.AssetPath}"; } + + /// + /// 处理资源包加载结果,由子类实现具体逻辑 + /// protected abstract void ProcessBundleResult(); /// @@ -203,7 +216,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "User abort !"; + Error = "Aborted by user!"; } // 减少引用计数 @@ -244,7 +257,7 @@ namespace YooAsset public void ReleaseHandle(HandleBase handle) { if (RefCount <= 0) - throw new YooInternalException($"Attempting to release handle when RefCount is already zero. Asset : {MainAssetInfo.AssetPath}"); + throw new YooInternalException($"Attempting to release handle when RefCount is already zero. Asset: {MainAssetInfo.AssetPath}"); if (_handles.Remove(handle) == false) throw new YooInternalException($"Handle not found in cache list. Asset: {MainAssetInfo.AssetPath}"); @@ -258,8 +271,8 @@ namespace YooAsset /// public void ReleaseAllHandles() { - List tempers = _handles.ToList(); - foreach (var handle in tempers) + List tempHandles = _handles.ToList(); + foreach (var handle in tempHandles) { handle.Release(); } @@ -270,9 +283,9 @@ namespace YooAsset /// public void TryUnloadBundle() { - if (_resManager.AutoUnloadBundleWhenUnused) + if (_resourceManager.AutoUnloadBundleWhenUnused) { - _resManager.TryUnloadUnusedAsset(MainAssetInfo, 10); + _resourceManager.TryUnloadUnusedAsset(MainAssetInfo, 10); } } @@ -286,8 +299,8 @@ namespace YooAsset Status = status; // 注意:创建临时列表是为了防止外部逻辑在回调函数内创建或者释放资源句柄。 - List tempers = _handles.ToList(); - foreach (var handle in tempers) + List tempHandles = _handles.ToList(); + foreach (var handle in tempHandles) { if (handle.IsValid) { @@ -316,7 +329,7 @@ namespace YooAsset } if (status.TotalBytes == 0) - throw new YooInternalException("Download total size can not be zero."); + throw new YooInternalException("Download total size cannot be zero."); status.IsDone = status.DownloadedBytes == status.TotalBytes; status.Progress = (float)status.DownloadedBytes / status.TotalBytes; diff --git a/Assets/YooAsset/Runtime/ResourceManager/Providers/ProviderOperation.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Providers/ProviderBase.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourceManager/Providers/ProviderOperation.cs.meta rename to Assets/YooAsset/Runtime/ResourceManager/Providers/ProviderBase.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourceManager/Providers/RawFileProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Providers/RawFileProvider.cs index d62d4607..cd3032cd 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Providers/RawFileProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Providers/RawFileProvider.cs @@ -1,7 +1,10 @@ - + namespace YooAsset { - internal class RawFileProvider : ProviderOperation + /// + /// 原生文件提供者,负责加载原始文件资源 + /// + internal class RawFileProvider : ProviderBase { public RawFileProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo) { diff --git a/Assets/YooAsset/Runtime/ResourceManager/Providers/SceneProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Providers/SceneProvider.cs index 1a83b1c2..3287ade1 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Providers/SceneProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Providers/SceneProvider.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; @@ -6,7 +6,10 @@ using UnityEngine.SceneManagement; namespace YooAsset { - internal sealed class SceneProvider : ProviderOperation + /// + /// 场景提供者,负责场景资源的加载 + /// + internal sealed class SceneProvider : ProviderBase { private readonly LoadSceneParameters _loadParams; private bool _suspendLoad; diff --git a/Assets/YooAsset/Runtime/ResourceManager/Providers/SubAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Providers/SubAssetsProvider.cs index 4137ca86..9109ab73 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Providers/SubAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Providers/SubAssetsProvider.cs @@ -1,7 +1,10 @@ - + namespace YooAsset { - internal sealed class SubAssetsProvider : ProviderOperation + /// + /// 子资源提供者,负责加载资源包内的子资源 + /// + internal sealed class SubAssetsProvider : ProviderBase { private FSLoadSubAssetsOperation _loadSubAssetsOp; @@ -17,7 +20,7 @@ namespace YooAsset AddChildOperation(_loadSubAssetsOp); #if UNITY_WEBGL - if (_resManager.WebGLForceSyncLoadAsset) + if (_resourceManager.WebGLForceSyncLoadAsset) _loadSubAssetsOp.WaitForAsyncComplete(); #endif } diff --git a/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs b/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs index a5a67af5..c2424c81 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -13,17 +13,35 @@ namespace YooAsset /// internal class ResourceManager { - internal readonly Dictionary ProviderDic = new Dictionary(5000); - internal readonly Dictionary LoaderDic = new Dictionary(5000); + /// + /// 资源提供者字典,Key 为 ProviderGUID + /// + internal readonly Dictionary ProviderDict = new Dictionary(5000); + + /// + /// 资源包加载器字典,Key 为 BundleName + /// + internal readonly Dictionary BundleLoaderDict = new Dictionary(5000); + + /// + /// 已加载的场景句柄列表 + /// internal readonly List SceneHandles = new List(100); + private readonly List _tempSceneHandles = new List(100); private FileSystemHost _fileSystemHost; private int _bundleLoadingMaxConcurrency; private int _bundleLoadingCounter; - private long _sceneCreateIndex; + private long _sceneInstanceCounter; - // 开发者配置选项 + /// + /// 当资源句柄引用计数为零时,是否自动卸载对应的资源包 + /// public bool AutoUnloadBundleWhenUnused { get; private set; } + + /// + /// WebGL 平台是否强制同步加载资源 + /// public bool WebGLForceSyncLoadAsset { get; private set; } /// @@ -36,6 +54,11 @@ namespace YooAsset /// public bool LockLoadOperation = false; + + /// + /// 创建资源管理器实例 + /// + /// 资源包名称 public ResourceManager(string packageName) { PackageName = packageName; @@ -86,29 +109,29 @@ namespace YooAsset // 卸载主资源包加载器 string mainBundleName = _fileSystemHost.GetMainBundleName(assetInfo.Asset.BundleID); - var mainLoader = TryGetBundleFileLoader(mainBundleName); + var mainLoader = TryGetBundleLoader(mainBundleName); if (mainLoader != null) { mainLoader.TryDestroyProviders(); if (mainLoader.CanDestroyLoader()) { mainLoader.DestroyLoader(); - LoaderDic.Remove(mainBundleName); + BundleLoaderDict.Remove(mainBundleName); hasUnloaded = true; } } // 卸载依赖资源包加载器 - foreach (var dependID in assetInfo.Asset.DependBundleIDs) + foreach (var dependID in assetInfo.Asset.DependentBundleIDs) { string dependBundleName = _fileSystemHost.GetMainBundleName(dependID); - var dependLoader = TryGetBundleFileLoader(dependBundleName); + var dependLoader = TryGetBundleLoader(dependBundleName); if (dependLoader != null) { if (dependLoader.CanDestroyLoader()) { dependLoader.DestroyLoader(); - LoaderDic.Remove(dependBundleName); + BundleLoaderDict.Remove(dependBundleName); hasUnloaded = true; } } @@ -129,28 +152,28 @@ namespace YooAsset { if (LockLoadOperation) { - string error = $"The load operation locked."; + string error = $"The load operation is locked."; YooLogger.Error(error); - CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); - completedProvider.SetCompletedWithError(error); - return completedProvider.CreateHandle(); + ErrorProvider errorProvider = new ErrorProvider(this, assetInfo); + errorProvider.SetCompletedWithError(error); + return errorProvider.CreateHandle(); } if (assetInfo.IsInvalid) { YooLogger.Error($"Failed to load scene. Error: {assetInfo.Error}"); - CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); - completedProvider.SetCompletedWithError(assetInfo.Error); - return completedProvider.CreateHandle(); + ErrorProvider errorProvider = new ErrorProvider(this, assetInfo); + errorProvider.SetCompletedWithError(assetInfo.Error); + return errorProvider.CreateHandle(); } // 注意:同一个场景的ProviderGUID每次加载都会变化 - string providerGUID = $"{assetInfo.GUID}-{++_sceneCreateIndex}"; - ProviderOperation provider; + string providerGUID = $"{assetInfo.GUID}-{++_sceneInstanceCounter}"; + ProviderBase provider; { provider = new SceneProvider(this, providerGUID, assetInfo, loadSceneParams, suspendLoad); provider.InitProviderDebugInfo(); - ProviderDic.Add(providerGUID, provider); + ProviderDict.Add(providerGUID, provider); AsyncOperationSystem.StartOperation(PackageName, provider); } @@ -168,28 +191,28 @@ namespace YooAsset { if (LockLoadOperation) { - string error = $"The load operation locked."; + string error = $"The load operation is locked."; YooLogger.Error(error); - CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); - completedProvider.SetCompletedWithError(error); - return completedProvider.CreateHandle(); + ErrorProvider errorProvider = new ErrorProvider(this, assetInfo); + errorProvider.SetCompletedWithError(error); + return errorProvider.CreateHandle(); } if (assetInfo.IsInvalid) { YooLogger.Error($"Failed to load asset. Error: {assetInfo.Error}"); - CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); - completedProvider.SetCompletedWithError(assetInfo.Error); - return completedProvider.CreateHandle(); + ErrorProvider errorProvider = new ErrorProvider(this, assetInfo); + errorProvider.SetCompletedWithError(assetInfo.Error); + return errorProvider.CreateHandle(); } string providerGUID = nameof(LoadAssetAsync) + assetInfo.GUID; - ProviderOperation provider = TryGetAssetProvider(providerGUID); + ProviderBase provider = TryGetAssetProvider(providerGUID); if (provider == null) { provider = new AssetProvider(this, providerGUID, assetInfo); provider.InitProviderDebugInfo(); - ProviderDic.Add(providerGUID, provider); + ProviderDict.Add(providerGUID, provider); AsyncOperationSystem.StartOperation(PackageName, provider); } @@ -204,28 +227,28 @@ namespace YooAsset { if (LockLoadOperation) { - string error = $"The load operation locked."; + string error = $"The load operation is locked."; YooLogger.Error(error); - CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); - completedProvider.SetCompletedWithError(error); - return completedProvider.CreateHandle(); + ErrorProvider errorProvider = new ErrorProvider(this, assetInfo); + errorProvider.SetCompletedWithError(error); + return errorProvider.CreateHandle(); } if (assetInfo.IsInvalid) { YooLogger.Error($"Failed to load sub assets. Error: {assetInfo.Error}"); - CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); - completedProvider.SetCompletedWithError(assetInfo.Error); - return completedProvider.CreateHandle(); + ErrorProvider errorProvider = new ErrorProvider(this, assetInfo); + errorProvider.SetCompletedWithError(assetInfo.Error); + return errorProvider.CreateHandle(); } string providerGUID = nameof(LoadSubAssetsAsync) + assetInfo.GUID; - ProviderOperation provider = TryGetAssetProvider(providerGUID); + ProviderBase provider = TryGetAssetProvider(providerGUID); if (provider == null) { provider = new SubAssetsProvider(this, providerGUID, assetInfo); provider.InitProviderDebugInfo(); - ProviderDic.Add(providerGUID, provider); + ProviderDict.Add(providerGUID, provider); AsyncOperationSystem.StartOperation(PackageName, provider); } @@ -240,28 +263,28 @@ namespace YooAsset { if (LockLoadOperation) { - string error = $"The load operation locked."; + string error = $"The load operation is locked."; YooLogger.Error(error); - CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); - completedProvider.SetCompletedWithError(error); - return completedProvider.CreateHandle(); + ErrorProvider errorProvider = new ErrorProvider(this, assetInfo); + errorProvider.SetCompletedWithError(error); + return errorProvider.CreateHandle(); } if (assetInfo.IsInvalid) { YooLogger.Error($"Failed to load all assets. Error: {assetInfo.Error}"); - CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); - completedProvider.SetCompletedWithError(assetInfo.Error); - return completedProvider.CreateHandle(); + ErrorProvider errorProvider = new ErrorProvider(this, assetInfo); + errorProvider.SetCompletedWithError(assetInfo.Error); + return errorProvider.CreateHandle(); } string providerGUID = nameof(LoadAllAssetsAsync) + assetInfo.GUID; - ProviderOperation provider = TryGetAssetProvider(providerGUID); + ProviderBase provider = TryGetAssetProvider(providerGUID); if (provider == null) { provider = new AllAssetsProvider(this, providerGUID, assetInfo); provider.InitProviderDebugInfo(); - ProviderDic.Add(providerGUID, provider); + ProviderDict.Add(providerGUID, provider); AsyncOperationSystem.StartOperation(PackageName, provider); } @@ -276,28 +299,28 @@ namespace YooAsset { if (LockLoadOperation) { - string error = $"The load operation locked."; + string error = $"The load operation is locked."; YooLogger.Error(error); - CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); - completedProvider.SetCompletedWithError(error); - return completedProvider.CreateHandle(); + ErrorProvider errorProvider = new ErrorProvider(this, assetInfo); + errorProvider.SetCompletedWithError(error); + return errorProvider.CreateHandle(); } if (assetInfo.IsInvalid) { YooLogger.Error($"Failed to load raw file. Error: {assetInfo.Error}"); - CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); - completedProvider.SetCompletedWithError(assetInfo.Error); - return completedProvider.CreateHandle(); + ErrorProvider errorProvider = new ErrorProvider(this, assetInfo); + errorProvider.SetCompletedWithError(assetInfo.Error); + return errorProvider.CreateHandle(); } string providerGUID = nameof(LoadRawFileAsync) + assetInfo.GUID; - ProviderOperation provider = TryGetAssetProvider(providerGUID); + ProviderBase provider = TryGetAssetProvider(providerGUID); if (provider == null) { provider = new RawFileProvider(this, providerGUID, assetInfo); provider.InitProviderDebugInfo(); - ProviderDic.Add(providerGUID, provider); + ProviderDict.Add(providerGUID, provider); AsyncOperationSystem.StartOperation(PackageName, provider); } @@ -305,53 +328,84 @@ namespace YooAsset return provider.CreateHandle(); } - internal LoadBundleOperation CreateMainBundleFileLoader(AssetInfo assetInfo) + /// + /// 获取或创建主资源包加载器 + /// + internal LoadBundleOperation GetOrCreateMainBundleLoader(AssetInfo assetInfo) { BundleInfo bundleInfo = _fileSystemHost.GetMainBundleInfo(assetInfo); - return CreateBundleFileLoaderInternal(bundleInfo); + return GetOrCreateBundleLoader(bundleInfo); } - internal List CreateDependBundleFileLoaders(AssetInfo assetInfo) + + /// + /// 获取或创建依赖资源包加载器列表 + /// + internal List GetOrCreateDependBundleLoaders(AssetInfo assetInfo) { List bundleInfos = _fileSystemHost.GetDependBundleInfos(assetInfo); List result = new List(bundleInfos.Count); foreach (var bundleInfo in bundleInfos) { - var bundleLoader = CreateBundleFileLoaderInternal(bundleInfo); + var bundleLoader = GetOrCreateBundleLoader(bundleInfo); result.Add(bundleLoader); } return result; } - internal void RemoveBundleProviders(List removeList) + + /// + /// 从字典中移除指定的资源提供者 + /// + internal void RemoveBundleProviders(List removeList) { foreach (var provider in removeList) { - ProviderDic.Remove(provider.ProviderGUID); + ProviderDict.Remove(provider.ProviderGUID); } } + + /// + /// 检查指定资源包是否已销毁 + /// internal bool CheckBundleDestroyed(int bundleID) { string bundleName = _fileSystemHost.GetMainBundleName(bundleID); - var bundleFileLoader = TryGetBundleFileLoader(bundleName); + var bundleFileLoader = TryGetBundleLoader(bundleName); if (bundleFileLoader == null) return true; return bundleFileLoader.IsDestroyed; } + + /// + /// 检查指定资源包是否可以释放 + /// internal bool CheckBundleReleasable(int bundleID) { string bundleName = _fileSystemHost.GetMainBundleName(bundleID); - var bundleFileLoader = TryGetBundleFileLoader(bundleName); + var bundleFileLoader = TryGetBundleLoader(bundleName); if (bundleFileLoader == null) return true; - return bundleFileLoader.CanReleasableLoader(); + return bundleFileLoader.IsReleasable(); } + + /// + /// 检查是否存在任何资源包加载器 + /// internal bool HasAnyLoader() { - return LoaderDic.Count > 0; + return BundleLoaderDict.Count > 0; } + + /// + /// 增加资源包加载计数器 + /// internal void IncrementBundleLoadingCounter() { _bundleLoadingCounter++; } + + /// + /// 减少资源包加载计数器 + /// internal void DecrementBundleLoadingCounter() { _bundleLoadingCounter--; @@ -361,38 +415,46 @@ namespace YooAsset _bundleLoadingCounter = 0; } } + + /// + /// 获取当前资源包加载计数 + /// internal int GetBundleLoadingCounter() { return _bundleLoadingCounter; } - internal bool BundleLoadingIsBusy() + + /// + /// 检查资源包加载是否繁忙(达到并发上限) + /// + internal bool IsBundleLoadingBusy() { return _bundleLoadingCounter >= _bundleLoadingMaxConcurrency; } - private LoadBundleOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo) + private LoadBundleOperation GetOrCreateBundleLoader(BundleInfo bundleInfo) { // 如果加载器已经存在 string bundleName = bundleInfo.Bundle.BundleName; - LoadBundleOperation loaderOperation = TryGetBundleFileLoader(bundleName); + LoadBundleOperation loaderOperation = TryGetBundleLoader(bundleName); if (loaderOperation != null) return loaderOperation; // 新增下载需求 loaderOperation = new LoadBundleOperation(this, bundleInfo); - LoaderDic.Add(bundleName, loaderOperation); + BundleLoaderDict.Add(bundleName, loaderOperation); return loaderOperation; } - private LoadBundleOperation TryGetBundleFileLoader(string bundleName) + private LoadBundleOperation TryGetBundleLoader(string bundleName) { - if (LoaderDic.TryGetValue(bundleName, out LoadBundleOperation value)) + if (BundleLoaderDict.TryGetValue(bundleName, out LoadBundleOperation value)) return value; else return null; } - private ProviderOperation TryGetAssetProvider(string providerGUID) + private ProviderBase TryGetAssetProvider(string providerGUID) { - if (ProviderDic.TryGetValue(providerGUID, out ProviderOperation value)) + if (ProviderDict.TryGetValue(providerGUID, out ProviderBase value)) return value; else return null; @@ -418,14 +480,17 @@ namespace YooAsset } #region 调试信息 + /// + /// 获取所有资源提供者的调试信息 + /// internal List GetDebugProviderInfos() { - List result = new List(ProviderDic.Count); - foreach (var provider in ProviderDic.Values) + List result = new List(ProviderDict.Count); + foreach (var provider in ProviderDict.Values) { DiagnosticProviderInfo providerInfo = new DiagnosticProviderInfo(); providerInfo.AssetPath = provider.MainAssetInfo.AssetPath; - providerInfo.SpawnScene= provider.SpawnScene; + providerInfo.SpawnScene = provider.SpawnScene; providerInfo.StartTime = provider.StartTime; providerInfo.ElapsedMilliseconds = provider.ElapsedMilliseconds; providerInfo.ReferenceCount = provider.RefCount; @@ -435,10 +500,14 @@ namespace YooAsset } return result; } + + /// + /// 获取所有资源包加载器的调试信息 + /// internal List GetDebugBundleInfos() { - List result = new List(LoaderDic.Values.Count); - foreach (var bundleLoader in LoaderDic.Values) + List result = new List(BundleLoaderDict.Values.Count); + foreach (var bundleLoader in BundleLoaderDict.Values) { var packageBundle = bundleLoader.LoadBundleInfo.Bundle; var bundleInfo = new DiagnosticBundleInfo(); @@ -450,6 +519,10 @@ namespace YooAsset } return result; } + + /// + /// 过滤出当前已加载的引用资源包 + /// internal List FilterReferenceBundles(PackageBundle packageBundle) { // 注意:引用的资源包不一定在内存中,所以需要过滤 @@ -457,7 +530,7 @@ namespace YooAsset List result = new List(referenceBundles.Count); foreach (var bundleName in referenceBundles) { - if (LoaderDic.ContainsKey(bundleName)) + if (BundleLoaderDict.ContainsKey(bundleName)) result.Add(bundleName); } return result; diff --git a/Assets/YooAsset/Runtime/ResourcePackage/AssetInfo.cs b/Assets/YooAsset/Runtime/ResourcePackage/AssetInfo.cs index 468c90bf..184ccd9d 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/AssetInfo.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/AssetInfo.cs @@ -1,15 +1,44 @@ - + namespace YooAsset { + /// + /// 资源信息类 + /// public class AssetInfo { + /// + /// 资源加载方法枚举 + /// internal enum ELoadMethod { + /// + /// 无加载方法 + /// None = 0, + + /// + /// 加载单个资源 + /// LoadAsset, + + /// + /// 加载子资源集合 + /// LoadSubAssets, + + /// + /// 加载所有资源 + /// LoadAllAssets, + + /// + /// 加载场景 + /// LoadScene, + + /// + /// 加载原生文件 + /// LoadRawFile, } @@ -63,8 +92,9 @@ namespace YooAsset } /// - /// 身份是否无效 + /// 资源信息是否无效 /// + /// 当内部PackageAsset为空时返回true public bool IsInvalid { get @@ -99,10 +129,16 @@ namespace YooAsset } } + /// + /// 创建有效的资源信息 + /// + /// 所属包裹名称 + /// 清单中的资源对象 + /// 资源类型 internal AssetInfo(string packageName, PackageAsset packageAsset, System.Type assetType) { if (packageAsset == null) - throw new YooInternalException("Package asset can not be null."); + throw new YooInternalException("Package asset cannot be null."); _providerGUID = string.Empty; _packageAsset = packageAsset; @@ -110,6 +146,12 @@ namespace YooAsset AssetType = assetType; Error = string.Empty; } + + /// + /// 创建无效的资源信息 + /// + /// 所属包裹名称 + /// 错误信息 internal AssetInfo(string packageName, string error) { _providerGUID = string.Empty; diff --git a/Assets/YooAsset/Runtime/ResourcePackage/BundleInfo.cs b/Assets/YooAsset/Runtime/ResourcePackage/BundleInfo.cs index 9d29ef58..ee577e25 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/BundleInfo.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/BundleInfo.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 资源包信息类 + /// internal class BundleInfo { private readonly IFileSystem _fileSystem; @@ -12,12 +15,24 @@ namespace YooAsset public readonly PackageBundle Bundle; + /// + /// 创建资源包信息 + /// + /// 所属文件系统 + /// 资源包对象 public BundleInfo(IFileSystem fileSystem, PackageBundle bundle) { _fileSystem = fileSystem; Bundle = bundle; _importFilePath = null; } + + /// + /// 创建资源包信息(带导入路径) + /// + /// 所属文件系统 + /// 资源包对象 + /// 导入文件路径 public BundleInfo(IFileSystem fileSystem, PackageBundle bundle, string importFilePath) { _fileSystem = fileSystem; @@ -26,8 +41,9 @@ namespace YooAsset } /// - /// 创建加载器 + /// 创建资源包加载器 /// + /// 返回资源包加载操作对象 public FSLoadBundleOperation CreateBundleLoader() { var options = new LoadBundleOptions(Bundle); @@ -35,26 +51,29 @@ namespace YooAsset } /// - /// 创建下载器 + /// 创建资源包下载器 /// - public FSDownloadFileOperation CreateBundleDownloader(int failedTryAgain) + /// 下载失败后的重试次数 + /// 返回文件下载操作对象 + public FSDownloadFileOperation CreateBundleDownloader(int retryCount) { - DownloadFileOptions options = new DownloadFileOptions(Bundle, failedTryAgain); - options.ImportFilePath = _importFilePath; + var options = new DownloadFileOptions(Bundle, retryCount, _importFilePath); return _fileSystem.DownloadFileAsync(options); } /// /// 是否需要从远端下载 /// + /// 如果需要下载返回true,否则返回false public bool IsNeedDownloadFromRemote() { return _fileSystem.NeedDownload(Bundle); } /// - /// 下载器合并识别码 + /// 获取下载器合并识别码 /// + /// 返回用于合并下载器的唯一标识符 public string GetDownloadCombineGUID() { return $"{_fileSystem.GetHashCode()}_{Bundle.BundleGUID}"; diff --git a/Assets/YooAsset/Runtime/ResourcePackage/EBundleType.cs b/Assets/YooAsset/Runtime/ResourcePackage/EBundleType.cs index e67e72dd..b254bbfd 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/EBundleType.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/EBundleType.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 资源包类型枚举 + /// public enum EBundleType { /// diff --git a/Assets/YooAsset/Runtime/ResourcePackage/EFileNameStyle.cs b/Assets/YooAsset/Runtime/ResourcePackage/EFileNameStyle.cs index 4e1fd0c9..07199373 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/EFileNameStyle.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/EFileNameStyle.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 远端资源文件命名风格 + /// public enum EFileNameStyle { /// diff --git a/Assets/YooAsset/Runtime/ResourcePackage/FileSystemHost.cs b/Assets/YooAsset/Runtime/ResourcePackage/FileSystemHost.cs index 9a65d316..72c8f13b 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/FileSystemHost.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/FileSystemHost.cs @@ -1,12 +1,22 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; namespace YooAsset { + /// + /// 文件系统宿主,管理多个文件系统 + /// internal class FileSystemHost { + /// + /// 所属包裹名称 + /// public readonly string PackageName; + + /// + /// 文件系统列表 + /// public readonly List FileSystems = new List(10); /// @@ -15,14 +25,20 @@ namespace YooAsset public PackageManifest ActiveManifest { get; private set; } + /// + /// 创建文件系统宿主 + /// + /// 所属包裹名称 public FileSystemHost(string packageName) { PackageName = packageName; } /// - /// 异步初始化 + /// 异步初始化文件系统 /// + /// 文件系统初始化参数 + /// 返回文件系统初始化操作对象 public InitializeFileSystemOperation InitializeAsync(FileSystemParameters fileSystemParameter) { var fileSystemParamList = new List(); @@ -32,8 +48,11 @@ namespace YooAsset } /// - /// 异步初始化 + /// 异步初始化文件系统(双文件系统) /// + /// 第一个文件系统初始化参数 + /// 第二个文件系统初始化参数 + /// 返回文件系统初始化操作对象 public InitializeFileSystemOperation InitializeAsync(FileSystemParameters fileSystemParameterA, FileSystemParameters fileSystemParameterB) { var fileSystemParamList = new List(); @@ -45,8 +64,10 @@ namespace YooAsset } /// - /// 异步初始化 + /// 异步初始化文件系统(多文件系统) /// + /// 文件系统初始化参数列表 + /// 返回文件系统初始化操作对象 public InitializeFileSystemOperation InitializeAsync(List fileSystemParameterList) { var operation = new InitializeFileSystemOperation(this, fileSystemParameterList); @@ -68,6 +89,7 @@ namespace YooAsset /// /// 设置当前激活的资源清单 /// + /// 资源清单对象 public void SetActiveManifest(PackageManifest manifest) { ActiveManifest = manifest; @@ -76,9 +98,8 @@ namespace YooAsset /// /// 获取主文件系统 /// - /// - /// 文件系统列表里,最后一个属于主文件系统 - /// + /// 返回主文件系统,如果没有文件系统则返回null + /// 文件系统列表里,最后一个属于主文件系统 public IFileSystem GetMainFileSystem() { int count = FileSystems.Count; @@ -88,8 +109,10 @@ namespace YooAsset } /// - /// 获取资源包所属文件系统 + /// 获取资源包所属的文件系统 /// + /// 资源包对象 + /// 返回资源包所属的文件系统,如果未找到则返回null private IFileSystem GetBelongFileSystem(PackageBundle packageBundle) { for (int i = 0; i < FileSystems.Count; i++) @@ -101,11 +124,16 @@ namespace YooAsset } } - YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}"); + YooLogger.Error($"Cannot find the file system for bundle: {packageBundle.BundleName}"); return null; } #region 资源包相关 + /// + /// 创建资源包信息对象 + /// + /// 资源包对象 + /// 返回资源包信息对象 private BundleInfo CreateBundleInfo(PackageBundle packageBundle) { if (packageBundle == null) @@ -118,8 +146,14 @@ namespace YooAsset return bundleInfo; } - throw new YooFileSystemException($"Can not found belong file system : {packageBundle.BundleName}"); + throw new YooFileSystemException($"Cannot find the file system for bundle: {packageBundle.BundleName}"); } + + /// + /// 获取资源对象的主资源包信息 + /// + /// 资源信息对象 + /// 返回主资源包信息对象 public BundleInfo GetMainBundleInfo(AssetInfo assetInfo) { if (assetInfo == null || assetInfo.IsInvalid) @@ -129,12 +163,24 @@ namespace YooAsset var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.Asset); return CreateBundleInfo(packageBundle); } + + /// + /// 获取主资源包名称 + /// + /// 资源包ID + /// 返回资源包名称 public string GetMainBundleName(int bundleID) { // 注意:如果清单里未找到资源包会抛出异常! var packageBundle = ActiveManifest.GetMainPackageBundle(bundleID); return packageBundle.BundleName; } + + /// + /// 获取资源对象的依赖资源包信息列表 + /// + /// 资源信息对象 + /// 返回依赖的资源包信息列表 public List GetDependBundleInfos(AssetInfo assetInfo) { if (assetInfo == null || assetInfo.IsInvalid) @@ -165,6 +211,11 @@ namespace YooAsset #region 下载器相关 private const int DefaultBundleInfoCapacity = 1000; + /// + /// 检查资源是否需要从远端下载(内部方法) + /// + /// 资源信息对象 + /// 如果需要下载返回true,否则返回false public bool IsNeedDownloadFromRemoteInternal(AssetInfo assetInfo) { if (assetInfo.IsInvalid) @@ -201,66 +252,114 @@ namespace YooAsset return fileSystem.NeedImport(bundle); } + /// + /// 创建资源下载器 + /// + /// 资源下载选项 + /// 返回资源下载操作对象 public ResourceDownloaderOperation CreateResourceDownloader(ResourceDownloaderOptions options) { return CreateResourceDownloader(ActiveManifest, options); } + + /// + /// 创建资源下载器 + /// + /// 资源清单对象 + /// 资源下载选项 + /// 返回资源下载操作对象 public ResourceDownloaderOperation CreateResourceDownloader(PackageManifest manifest, ResourceDownloaderOptions options) { List downloadList; if (options.Tags == null) - downloadList = GetBundleInfoListByAll(manifest, NeedDownload); + downloadList = GetAllBundleInfos(manifest, NeedDownload); else - downloadList = GetBundleInfoListByTags(manifest, options.Tags, NeedDownload); + downloadList = GetBundleInfosByTags(manifest, options.Tags, NeedDownload); - var operation = new ResourceDownloaderOperation(PackageName, downloadList, options.MaximumConcurrency, options.FailedTryAgain); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, options.MaximumConcurrency, options.RetryCount); return operation; } + /// + /// 创建资源下载器(按资源信息) + /// + /// Bundle下载选项 + /// 返回资源下载操作对象 public ResourceDownloaderOperation CreateResourceDownloader(BundleDownloaderOptions options) { return CreateResourceDownloader(ActiveManifest, options); } + + /// + /// 创建资源下载器(按资源信息) + /// + /// 资源清单对象 + /// Bundle下载选项 + /// 返回资源下载操作对象 public ResourceDownloaderOperation CreateResourceDownloader(PackageManifest manifest, BundleDownloaderOptions options) { List downloadList; if (options.AssetInfos == null) - downloadList = GetBundleInfoListByAll(manifest, NeedDownload); + downloadList = GetAllBundleInfos(manifest, NeedDownload); else - downloadList = GetBundleInfoListByAssetInfos(manifest, options.AssetInfos, options.DownloadBundleDependencies, NeedDownload); + downloadList = GetBundleInfosByAssetInfos(manifest, options.AssetInfos, options.DownloadBundleDependencies, NeedDownload); - var operation = new ResourceDownloaderOperation(PackageName, downloadList, options.MaximumConcurrency, options.FailedTryAgain); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, options.MaximumConcurrency, options.RetryCount); return operation; } + /// + /// 创建资源解压器 + /// + /// 资源解压选项 + /// 返回资源解压操作对象 public ResourceUnpackerOperation CreateResourceUnpacker(ResourceUnpackerOptions options) { return CreateResourceUnpacker(ActiveManifest, options); } + + /// + /// 创建资源解压器 + /// + /// 资源清单对象 + /// 资源解压选项 + /// 返回资源解压操作对象 public ResourceUnpackerOperation CreateResourceUnpacker(PackageManifest manifest, ResourceUnpackerOptions options) { List unpackList; if (options.Tags == null) - unpackList = GetBundleInfoListByAll(manifest, NeedUnpack); + unpackList = GetAllBundleInfos(manifest, NeedUnpack); else - unpackList = GetBundleInfoListByTags(manifest, options.Tags, NeedUnpack); + unpackList = GetBundleInfosByTags(manifest, options.Tags, NeedUnpack); - var operation = new ResourceUnpackerOperation(PackageName, unpackList, options.MaximumConcurrency, options.FailedTryAgain); + var operation = new ResourceUnpackerOperation(PackageName, unpackList, options.MaximumConcurrency, options.RetryCount); return operation; } + /// + /// 创建资源导入器 + /// + /// 资源导入选项 + /// 返回资源导入操作对象 public ResourceImporterOperation CreateResourceImporter(BundleImporterOptions options) { return CreateResourceImporter(ActiveManifest, options); } + + /// + /// 创建资源导入器 + /// + /// 资源清单对象 + /// 资源导入选项 + /// 返回资源导入操作对象 public ResourceImporterOperation CreateResourceImporter(PackageManifest manifest, BundleImporterOptions options) { - List importerList = GetBundleInfoListByBundleInfos(manifest, options.BundleInfos, NeedImport); - var operation = new ResourceImporterOperation(PackageName, importerList, options.MaximumConcurrency, options.FailedTryAgain); + List importerList = GetBundleInfosByImportInfos(manifest, options.BundleInfos, NeedImport); + var operation = new ResourceImporterOperation(PackageName, importerList, options.MaximumConcurrency, options.RetryCount); return operation; } - private List GetBundleInfoListByAll(PackageManifest manifest, Func predicate) + private List GetAllBundleInfos(PackageManifest manifest, Func predicate) { if (manifest == null) return new List(); @@ -280,7 +379,7 @@ namespace YooAsset } return result; } - private List GetBundleInfoListByTags(PackageManifest manifest, string[] tags, Func predicate) + private List GetBundleInfosByTags(PackageManifest manifest, string[] tags, Func predicate) { if (manifest == null) return new List(); @@ -295,7 +394,7 @@ namespace YooAsset if (predicate(fileSystem, packageBundle)) { // 注意:如果未带任何标记,则统一处理 - if (packageBundle.HasAnyTags() == false) + if (packageBundle.HasTags() == false) { var bundleInfo = new BundleInfo(fileSystem, packageBundle); result.Add(bundleInfo); @@ -312,7 +411,7 @@ namespace YooAsset } return result; } - private List GetBundleInfoListByAssetInfos(PackageManifest manifest, AssetInfo[] assetInfos, bool recursiveDepend, Func predicate) + private List GetBundleInfosByAssetInfos(PackageManifest manifest, AssetInfo[] assetInfos, bool recursiveDepend, Func predicate) { if (manifest == null) return new List(); @@ -387,7 +486,7 @@ namespace YooAsset } return result; } - private List GetBundleInfoListByBundleInfos(PackageManifest manifest, ImportBundleInfo[] fileInfos, Func predicate) + private List GetBundleInfosByImportInfos(PackageManifest manifest, ImportBundleInfo[] fileInfos, Func predicate) { if (manifest == null) return new List(); @@ -404,7 +503,7 @@ namespace YooAsset { if (manifest.TryGetPackageBundleByBundleName(fileInfo.BundleName, out packageBundle) == false) { - YooLogger.Warning($"Not found package bundle, bundle name : {fileInfo.BundleName}"); + YooLogger.Warning($"Package bundle not found, bundle name: {fileInfo.BundleName}"); continue; } } @@ -412,7 +511,7 @@ namespace YooAsset { if (manifest.TryGetPackageBundleByBundleGUID(fileInfo.BundleGUID, out packageBundle) == false) { - YooLogger.Warning($"Not found package bundle, bundle guid : {fileInfo.BundleGUID}"); + YooLogger.Warning($"Package bundle not found, bundle GUID: {fileInfo.BundleGUID}"); continue; } } @@ -421,7 +520,7 @@ namespace YooAsset string fileName = System.IO.Path.GetFileName(filePath); if (manifest.TryGetPackageBundleByFileName(fileName, out packageBundle) == false) { - YooLogger.Warning($"Not found package bundle, file name : {fileName}"); + YooLogger.Warning($"Package bundle not found, file name: {fileName}"); continue; } } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/ClearCacheOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/ClearCacheOperation.cs index 326eaae5..36e8b6d5 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/ClearCacheOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/ClearCacheOperation.cs @@ -1,8 +1,11 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace YooAsset { + /// + /// 清理缓存操作 + /// public sealed class ClearCacheOperation : AsyncOperationBase { private enum ESteps diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/ClearCacheOptions.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/ClearCacheOptions.cs index 3e0f4895..8c2e6156 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/ClearCacheOptions.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/ClearCacheOptions.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 清理缓存选项 + /// public struct ClearCacheOptions { /// @@ -18,18 +21,57 @@ namespace YooAsset /// internal PackageManifest Manifest { get; set; } + /// + /// 创建清理缓存选项 + /// + /// 清理模式 public ClearCacheOptions(EFileClearMode clearMode) { ClearMode = clearMode.ToString(); ClearParam = null; Manifest = null; } + + /// + /// 创建清理缓存选项 + /// + /// 清理模式 + /// 附加参数 public ClearCacheOptions(EFileClearMode clearMode, object clearParam) { ClearMode = clearMode.ToString(); ClearParam = clearParam; Manifest = null; } + + /// + /// 创建清理缓存选项 + /// + /// 清理模式 + public ClearCacheOptions(EManifestClearMode clearMode) + { + ClearMode = clearMode.ToString(); + ClearParam = null; + Manifest = null; + } + + /// + /// 创建清理缓存选项 + /// + /// 清理模式 + /// 附加参数 + public ClearCacheOptions(EManifestClearMode clearMode, object clearParam) + { + ClearMode = clearMode.ToString(); + ClearParam = clearParam; + Manifest = null; + } + + /// + /// 创建清理缓存选项 + /// + /// 清理模式名称 + /// 附加参数 public ClearCacheOptions(string clearMode, object clearParam) { ClearMode = clearMode; diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/DestroyPackageOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/DestroyPackageOperation.cs index cd5b3808..65ce479a 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/DestroyPackageOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/DestroyPackageOperation.cs @@ -1,6 +1,9 @@ namespace YooAsset { + /// + /// 销毁资源包裹操作 + /// public class DestroyPackageOperation : AsyncOperationBase { private enum ESteps diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderDefine.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderEventArgs.cs similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderDefine.cs rename to Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderEventArgs.cs diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderDefine.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderEventArgs.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderDefine.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderEventArgs.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderOperation.cs index ebcd40db..d1f1916a 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderOperation.cs @@ -1,8 +1,11 @@ -using System.Collections; +using System.Collections; using System.Collections.Generic; namespace YooAsset { + /// + /// 下载操作基类,提供资源下载、暂停、恢复和取消功能 + /// public abstract class DownloaderOperation : AsyncOperationBase { private enum ESteps @@ -16,8 +19,8 @@ namespace YooAsset private const int MAX_LOADER_COUNT = 64; private readonly string _packageName; - private readonly int _maximumConcurrency; - private readonly int _failedTryAgain; + private readonly int _maxConcurrency; + private readonly int _retryCount; private readonly List _bundleInfoList; private readonly List _downloaders = new List(MAX_LOADER_COUNT); private readonly List _removeList = new List(MAX_LOADER_COUNT); @@ -27,8 +30,8 @@ namespace YooAsset private bool _isPause = false; private long _lastDownloadBytes = 0; private int _lastDownloadCount = 0; - private long _cachedDownloadBytes = 0; - private int _cachedDownloadCount = 0; + private long _completedDownloadBytes = 0; + private int _completedDownloadCount = 0; private ESteps _steps = ESteps.None; @@ -79,15 +82,22 @@ namespace YooAsset public DownloadFileStartedEventHandler DownloadFileStartedHandler { get; set; } - internal DownloaderOperation(string packageName, List downloadList, int maximumConcurrency, int failedTryAgain) + /// + /// 创建下载操作实例 + /// + /// 所属包裹名称 + /// 下载列表 + /// 最大并发数量 + /// 失败重试次数 + internal DownloaderOperation(string packageName, List downloadList, int maximumConcurrency, int retryCount) { _packageName = packageName; _bundleInfoList = downloadList; - _maximumConcurrency = UnityEngine.Mathf.Clamp(maximumConcurrency, 1, MAX_LOADER_COUNT); - _failedTryAgain = failedTryAgain; + _maxConcurrency = UnityEngine.Mathf.Clamp(maximumConcurrency, 1, MAX_LOADER_COUNT); + _retryCount = retryCount; // 统计下载信息 - CalculateDownloaderInfo(); + CalculateStatistics(); } internal override void InternalStart() { @@ -135,7 +145,7 @@ namespace YooAsset { // 检测下载器结果 _removeList.Clear(); - long downloadBytes = _cachedDownloadBytes; + long downloadBytes = _completedDownloadBytes; foreach (var downloader in _downloaders) { downloader.UpdateOperation(); @@ -153,8 +163,8 @@ namespace YooAsset // 下载成功 _removeList.Add(downloader); - _cachedDownloadCount++; - _cachedDownloadBytes += downloader.DownloadedBytes; + _completedDownloadCount++; + _completedDownloadBytes += downloader.DownloadedBytes; } // 移除已经完成的下载器(无论成功或失败) @@ -164,10 +174,10 @@ namespace YooAsset } // 如果下载进度发生变化 - if (_lastDownloadBytes != downloadBytes || _lastDownloadCount != _cachedDownloadCount) + if (_lastDownloadBytes != downloadBytes || _lastDownloadCount != _completedDownloadCount) { _lastDownloadBytes = downloadBytes; - _lastDownloadCount = _cachedDownloadCount; + _lastDownloadCount = _completedDownloadCount; Progress = CalculateProgress(); if (DownloadProgressChangedHandler != null) @@ -190,11 +200,11 @@ namespace YooAsset if (_isPause) return; - if (_downloaders.Count < _maximumConcurrency) + if (_downloaders.Count < _maxConcurrency) { int index = _bundleInfoList.Count - 1; var bundleInfo = _bundleInfoList[index]; - var downloader = bundleInfo.CreateBundleDownloader(_failedTryAgain); + var downloader = bundleInfo.CreateBundleDownloader(_retryCount); downloader.StartOperation(); this.AddChildOperation(downloader); @@ -259,7 +269,11 @@ namespace YooAsset } } } - private void CalculateDownloaderInfo() + + /// + /// 计算下载统计信息 + /// + private void CalculateStatistics() { if (_bundleInfoList != null) { @@ -277,6 +291,10 @@ namespace YooAsset } } + /// + /// 计算下载进度 + /// + /// 返回下载进度值(0-1) private float CalculateProgress() { if (TotalDownloadBytes == 0) @@ -299,7 +317,7 @@ namespace YooAsset if (Status != EOperationStatus.None) { - YooLogger.Error("The downloader is running, can not combine with other downloader."); + YooLogger.Error("The downloader is running and cannot combine with another downloader."); return; } @@ -324,7 +342,7 @@ namespace YooAsset } // 重新统计下载信息 - CalculateDownloaderInfo(); + CalculateStatistics(); } /// @@ -373,10 +391,13 @@ namespace YooAsset } } + /// + /// 资源下载操作类 + /// public sealed class ResourceDownloaderOperation : DownloaderOperation { - internal ResourceDownloaderOperation(string packageName, List downloadList, int maximumConcurrency, int failedTryAgain) - : base(packageName, downloadList, maximumConcurrency, failedTryAgain) + internal ResourceDownloaderOperation(string packageName, List downloadList, int maximumConcurrency, int retryCount) + : base(packageName, downloadList, maximumConcurrency, retryCount) { } @@ -390,10 +411,13 @@ namespace YooAsset return operation; } } + /// + /// 资源解压操作类 + /// public sealed class ResourceUnpackerOperation : DownloaderOperation { - internal ResourceUnpackerOperation(string packageName, List downloadList, int maximumConcurrency, int failedTryAgain) - : base(packageName, downloadList, maximumConcurrency, failedTryAgain) + internal ResourceUnpackerOperation(string packageName, List downloadList, int maximumConcurrency, int retryCount) + : base(packageName, downloadList, maximumConcurrency, retryCount) { } @@ -407,10 +431,13 @@ namespace YooAsset return operation; } } + /// + /// 资源导入操作类 + /// public sealed class ResourceImporterOperation : DownloaderOperation { - internal ResourceImporterOperation(string packageName, List downloadList, int maximumConcurrency, int failedTryAgain) - : base(packageName, downloadList, maximumConcurrency, failedTryAgain) + internal ResourceImporterOperation(string packageName, List downloadList, int maximumConcurrency, int retryCount) + : base(packageName, downloadList, maximumConcurrency, retryCount) { } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderOptions.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderOptions.cs index b5d09678..11dbcf7f 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderOptions.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/DownloaderOptions.cs @@ -1,4 +1,4 @@ - + namespace YooAsset { /// @@ -14,7 +14,7 @@ namespace YooAsset /// /// 失败后的重试次数 /// - public int FailedTryAgain { get; set; } + public int RetryCount { get; set; } /// /// 下载资源对象所属资源包内所有资源对象依赖的资源包 @@ -27,19 +27,34 @@ namespace YooAsset /// public AssetInfo[] AssetInfos { get; set; } - public BundleDownloaderOptions(AssetInfo assetInfo, bool downloadDependencies, int maximumConcurrency, int failedTryAgain) + /// + /// 创建资源下载选项(单个资源) + /// + /// 资源信息 + /// 是否下载依赖资源包 + /// 最大并发数量 + /// 失败后的重试次数 + public BundleDownloaderOptions(AssetInfo assetInfo, bool downloadDependencies, int maximumConcurrency, int retryCount) { AssetInfos = new AssetInfo[] { assetInfo }; DownloadBundleDependencies = downloadDependencies; MaximumConcurrency = maximumConcurrency; - FailedTryAgain = failedTryAgain; + RetryCount = retryCount; } - public BundleDownloaderOptions(AssetInfo[] assetInfos, bool downloadDependencies, int maximumConcurrency, int failedTryAgain) + + /// + /// 创建资源下载选项(多个资源) + /// + /// 资源信息数组 + /// 是否下载依赖资源包 + /// 最大并发数量 + /// 失败后的重试次数 + public BundleDownloaderOptions(AssetInfo[] assetInfos, bool downloadDependencies, int maximumConcurrency, int retryCount) { AssetInfos = assetInfos; DownloadBundleDependencies = downloadDependencies; MaximumConcurrency = maximumConcurrency; - FailedTryAgain = failedTryAgain; + RetryCount = retryCount; } } @@ -56,7 +71,7 @@ namespace YooAsset /// /// 失败后的重试次数 /// - public int FailedTryAgain { get; set; } + public int RetryCount { get; set; } /// /// 资源标签列表 @@ -64,23 +79,42 @@ namespace YooAsset /// public string[] Tags { get; set; } - public ResourceDownloaderOptions(int maximumConcurrency, int failedTryAgain) + /// + /// 创建资源下载选项(下载所有资源) + /// + /// 最大并发数量 + /// 失败后的重试次数 + public ResourceDownloaderOptions(int maximumConcurrency, int retryCount) { Tags = null; MaximumConcurrency = maximumConcurrency; - FailedTryAgain = failedTryAgain; + RetryCount = retryCount; } - public ResourceDownloaderOptions(string tag, int maximumConcurrency, int failedTryAgain) + + /// + /// 创建资源下载选项(按标签下载) + /// + /// 资源标签 + /// 最大并发数量 + /// 失败后的重试次数 + public ResourceDownloaderOptions(string tag, int maximumConcurrency, int retryCount) { Tags = new string[] { tag }; MaximumConcurrency = maximumConcurrency; - FailedTryAgain = failedTryAgain; + RetryCount = retryCount; } - public ResourceDownloaderOptions(string[] tags, int maximumConcurrency, int failedTryAgain) + + /// + /// 创建资源下载选项(按多个标签下载) + /// + /// 资源标签数组 + /// 最大并发数量 + /// 失败后的重试次数 + public ResourceDownloaderOptions(string[] tags, int maximumConcurrency, int retryCount) { Tags = tags; MaximumConcurrency = maximumConcurrency; - FailedTryAgain = failedTryAgain; + RetryCount = retryCount; } } @@ -97,7 +131,7 @@ namespace YooAsset /// /// 失败后的重试次数 /// - public int FailedTryAgain { get; set; } + public int RetryCount { get; set; } /// /// 资源标签列表 @@ -105,23 +139,42 @@ namespace YooAsset /// public string[] Tags { get; set; } - public ResourceUnpackerOptions(int maximumConcurrency, int failedTryAgain) + /// + /// 创建资源解压选项(解压所有资源) + /// + /// 最大并发数量 + /// 失败后的重试次数 + public ResourceUnpackerOptions(int maximumConcurrency, int retryCount) { Tags = null; MaximumConcurrency = maximumConcurrency; - FailedTryAgain = failedTryAgain; + RetryCount = retryCount; } - public ResourceUnpackerOptions(string tag, int maximumConcurrency, int failedTryAgain) + + /// + /// 创建资源解压选项(按标签解压) + /// + /// 资源标签 + /// 最大并发数量 + /// 失败后的重试次数 + public ResourceUnpackerOptions(string tag, int maximumConcurrency, int retryCount) { Tags = new string[] { tag }; MaximumConcurrency = maximumConcurrency; - FailedTryAgain = failedTryAgain; + RetryCount = retryCount; } - public ResourceUnpackerOptions(string[] tags, int maximumConcurrency, int failedTryAgain) + + /// + /// 创建资源解压选项(按多个标签解压) + /// + /// 资源标签数组 + /// 最大并发数量 + /// 失败后的重试次数 + public ResourceUnpackerOptions(string[] tags, int maximumConcurrency, int retryCount) { Tags = tags; MaximumConcurrency = maximumConcurrency; - FailedTryAgain = failedTryAgain; + RetryCount = retryCount; } } @@ -138,18 +191,24 @@ namespace YooAsset /// /// 失败后的重试次数 /// - public int FailedTryAgain { get; set; } + public int RetryCount { get; set; } /// /// 资源包信息列表 /// public ImportBundleInfo[] BundleInfos { get; set; } - public BundleImporterOptions(ImportBundleInfo[] bundleInfos, int maximumConcurrency, int failedTryAgain) + /// + /// 创建资源导入选项 + /// + /// 资源包信息数组 + /// 最大并发数量 + /// 失败后的重试次数 + public BundleImporterOptions(ImportBundleInfo[] bundleInfos, int maximumConcurrency, int retryCount) { BundleInfos = bundleInfos; MaximumConcurrency = maximumConcurrency; - FailedTryAgain = failedTryAgain; + RetryCount = retryCount; } } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/InitializePackageOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/InitializePackageOperation.cs index 8c24bd77..bee62014 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/InitializePackageOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/InitializePackageOperation.cs @@ -1,7 +1,10 @@ -using System; +using System; namespace YooAsset { + /// + /// 初始化资源包裹操作 + /// public class InitializePackageOperation : AsyncOperationBase { private enum ESteps @@ -89,7 +92,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"{_playMode} can not support WebGL plateform."; + Error = $"{_playMode} does not support WebGL platform."; YooLogger.Error(Error); return; } @@ -103,7 +106,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"{nameof(EPlayMode.WebPlayMode)} only support WebGL plateform."; + Error = $"{nameof(EPlayMode.WebPlayMode)} only supports WebGL platform."; YooLogger.Error(Error); return; } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/InitializePackageOptions.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/InitializePackageOptions.cs index b16ba623..a7877015 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/InitializePackageOptions.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/InitializePackageOptions.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace YooAsset { @@ -28,6 +28,9 @@ namespace YooAsset /// public class EditorSimulateModeOptions : InitializePackageOptions { + /// + /// 编辑器文件系统初始化参数 + /// public FileSystemParameters EditorFileSystemParameters; } @@ -36,6 +39,9 @@ namespace YooAsset /// public class OfflinePlayModeOptions : InitializePackageOptions { + /// + /// 内置文件系统初始化参数 + /// public FileSystemParameters BuildinFileSystemParameters; } @@ -44,7 +50,14 @@ namespace YooAsset /// public class HostPlayModeOptions : InitializePackageOptions { + /// + /// 内置文件系统初始化参数 + /// public FileSystemParameters BuildinFileSystemParameters; + + /// + /// 缓存文件系统初始化参数 + /// public FileSystemParameters CacheFileSystemParameters; } @@ -53,7 +66,14 @@ namespace YooAsset /// public class WebPlayModeOptions : InitializePackageOptions { + /// + /// Web服务器文件系统初始化参数 + /// public FileSystemParameters WebServerFileSystemParameters; + + /// + /// Web远程文件系统初始化参数 + /// public FileSystemParameters WebRemoteFileSystemParameters; } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/Internal/DeserializeManifestOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/Internal/DeserializeManifestOperation.cs index 2121b0d8..a6677822 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/Internal/DeserializeManifestOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/Internal/DeserializeManifestOperation.cs @@ -1,10 +1,13 @@ -using System.IO; +using System.IO; using System.Collections; using System.Collections.Generic; using System; namespace YooAsset { + /// + /// 反序列化清单文件操作 + /// internal class DeserializeManifestOperation : AsyncOperationBase { private enum ESteps @@ -152,7 +155,7 @@ namespace YooAsset packageAsset.AssetGUID = _buffer.ReadUTF8(); packageAsset.AssetTags = _buffer.ReadUTF8Array(); packageAsset.BundleID = _buffer.ReadInt32(); - packageAsset.DependBundleIDs = _buffer.ReadInt32Array(); + packageAsset.DependentBundleIDs = _buffer.ReadInt32Array(); FillAssetCollection(Manifest, packageAsset, replaceAssetPath); _packageAssetCount--; @@ -184,9 +187,9 @@ namespace YooAsset packageBundle.FileHash = _buffer.ReadUTF8(); packageBundle.FileCRC = _buffer.ReadUInt32(); packageBundle.FileSize = _buffer.ReadInt64(); - packageBundle.Encrypted = _buffer.ReadBool(); + packageBundle.IsEncrypted = _buffer.ReadBool(); packageBundle.Tags = _buffer.ReadUTF8Array(); - packageBundle.DependBundleIDs = _buffer.ReadInt32Array(); + packageBundle.DependentBundleIDs = _buffer.ReadInt32Array(); FillBundleCollection(Manifest, packageBundle); _packageBundleCount--; @@ -220,20 +223,20 @@ namespace YooAsset if (manifest.EnableAddressable) { - manifest.AssetPathMapping1 = new Dictionary(assetCount * 3); + manifest.AssetPathByLocation = new Dictionary(assetCount * 3); } else { if (manifest.LocationToLower) - manifest.AssetPathMapping1 = new Dictionary(assetCount * 2, StringComparer.OrdinalIgnoreCase); + manifest.AssetPathByLocation = new Dictionary(assetCount * 2, StringComparer.OrdinalIgnoreCase); else - manifest.AssetPathMapping1 = new Dictionary(assetCount * 2); + manifest.AssetPathByLocation = new Dictionary(assetCount * 2); } if (manifest.IncludeAssetGUID) - manifest.AssetPathMapping2 = new Dictionary(assetCount); + manifest.AssetPathByAssetGUID = new Dictionary(assetCount); else - manifest.AssetPathMapping2 = new Dictionary(); + manifest.AssetPathByAssetGUID = new Dictionary(); } private void FillAssetCollection(PackageManifest manifest, PackageAsset packageAsset, bool replaceAssetPath) { @@ -243,7 +246,7 @@ namespace YooAsset // 注意:我们不允许原始路径存在重名 string assetPath = packageAsset.AssetPath; if (manifest.AssetDic.ContainsKey(assetPath)) - throw new YooManifestException($"AssetPath have existed : {assetPath}"); + throw new YooManifestException($"Asset path already exists: {assetPath}"); else manifest.AssetDic.Add(assetPath, packageAsset); @@ -252,10 +255,10 @@ namespace YooAsset string location = packageAsset.AssetPath; // 添加原生路径的映射 - if (manifest.AssetPathMapping1.ContainsKey(location)) - throw new YooManifestException($"Location have existed : {location}"); + if (manifest.AssetPathByLocation.ContainsKey(location)) + throw new YooManifestException($"Location already exists: {location}"); else - manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath); + manifest.AssetPathByLocation.Add(location, packageAsset.AssetPath); // 添加无后缀名路径的映射 if (manifest.SupportExtensionless) @@ -263,10 +266,10 @@ namespace YooAsset string locationWithoutExtension = Path.ChangeExtension(location, null); if (ReferenceEquals(location, locationWithoutExtension) == false) { - if (manifest.AssetPathMapping1.ContainsKey(locationWithoutExtension)) - YooLogger.Warning($"Location have existed : {locationWithoutExtension}"); + if (manifest.AssetPathByLocation.ContainsKey(locationWithoutExtension)) + YooLogger.Warning($"Location already exists: {locationWithoutExtension}"); else - manifest.AssetPathMapping1.Add(locationWithoutExtension, packageAsset.AssetPath); + manifest.AssetPathByLocation.Add(locationWithoutExtension, packageAsset.AssetPath); } } } @@ -274,10 +277,10 @@ namespace YooAsset // 填充AssetPathMapping2 if (manifest.IncludeAssetGUID) { - if (manifest.AssetPathMapping2.ContainsKey(packageAsset.AssetGUID)) - throw new YooManifestException($"AssetGUID have existed : {packageAsset.AssetGUID}"); + if (manifest.AssetPathByAssetGUID.ContainsKey(packageAsset.AssetGUID)) + throw new YooManifestException($"Asset GUID already exists: {packageAsset.AssetGUID}"); else - manifest.AssetPathMapping2.Add(packageAsset.AssetGUID, packageAsset.AssetPath); + manifest.AssetPathByAssetGUID.Add(packageAsset.AssetGUID, packageAsset.AssetPath); } // 添加可寻址地址 @@ -286,10 +289,10 @@ namespace YooAsset string location = packageAsset.Address; if (string.IsNullOrEmpty(location) == false) { - if (manifest.AssetPathMapping1.ContainsKey(location)) - throw new YooManifestException($"Location have existed : {location}"); + if (manifest.AssetPathByLocation.ContainsKey(location)) + throw new YooManifestException($"Location already exists: {location}"); else - manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath); + manifest.AssetPathByLocation.Add(location, packageAsset.AssetPath); } } } @@ -297,21 +300,21 @@ namespace YooAsset private void CreateBundleCollection(PackageManifest manifest, int bundleCount) { manifest.BundleList = new List(bundleCount); - manifest.BundleDic1 = new Dictionary(bundleCount); - manifest.BundleDic2 = new Dictionary(bundleCount); - manifest.BundleDic3 = new Dictionary(bundleCount); + manifest.BundleByBundleName = new Dictionary(bundleCount); + manifest.BundleByFileName = new Dictionary(bundleCount); + manifest.BundleByBundleGUID = new Dictionary(bundleCount); } private void FillBundleCollection(PackageManifest manifest, PackageBundle packageBundle) { // 初始化资源包 - packageBundle.InitBundle(manifest); + packageBundle.Initialize(manifest); // 添加到列表集合 manifest.BundleList.Add(packageBundle); - manifest.BundleDic1.Add(packageBundle.BundleName, packageBundle); - manifest.BundleDic2.Add(packageBundle.FileName, packageBundle); - manifest.BundleDic3.Add(packageBundle.BundleGUID, packageBundle); + manifest.BundleByBundleName.Add(packageBundle.BundleName, packageBundle); + manifest.BundleByFileName.Add(packageBundle.FileName, packageBundle); + manifest.BundleByBundleGUID.Add(packageBundle.BundleGUID, packageBundle); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/Internal/InitializeFileSystemOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/Internal/InitializeFileSystemOperation.cs index ba4eaf19..695ae56a 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/Internal/InitializeFileSystemOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/Internal/InitializeFileSystemOperation.cs @@ -1,8 +1,11 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace YooAsset { + /// + /// 初始化文件系统操作 + /// public class InitializeFileSystemOperation : AsyncOperationBase { private enum ESteps diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/LoadManifestOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/LoadManifestOperation.cs index 05e17c89..c6a10587 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/LoadManifestOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/LoadManifestOperation.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 加载资源清单操作 + /// public sealed class LoadManifestOperation : AsyncOperationBase { private enum ESteps diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/LoadManifestOptions.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/LoadManifestOptions.cs index 43e91ced..b250fa41 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/LoadManifestOptions.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/LoadManifestOptions.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 加载清单选项 + /// public struct LoadManifestOptions { /// @@ -13,6 +16,11 @@ namespace YooAsset /// public int Timeout { get; set; } + /// + /// 创建加载清单选项 + /// + /// 包裹版本 + /// 超时时间(秒) public LoadManifestOptions(string packageVersion, int timeout) { PackageVersion = packageVersion; diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/PreDownloaderOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/PreDownloaderOperation.cs index 5db0f11e..de6627d2 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/PreDownloaderOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/PreDownloaderOperation.cs @@ -1,9 +1,12 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; namespace YooAsset { + /// + /// 预下载操作,用于提前下载指定版本的资源 + /// public sealed class PreDownloaderOperation : AsyncOperationBase { private enum ESteps @@ -102,7 +105,7 @@ namespace YooAsset { if (Status != EOperationStatus.Succeeded) { - YooLogger.Error($"{nameof(PreDownloaderOperation)} status is not succeed."); + YooLogger.Error($"{nameof(PreDownloaderOperation)} did not succeed."); return ResourceDownloaderOperation.CreateEmptyDownloader(_host.PackageName); } @@ -116,7 +119,7 @@ namespace YooAsset { if (Status != EOperationStatus.Succeeded) { - YooLogger.Error($"{nameof(PreDownloaderOperation)} status is not succeed."); + YooLogger.Error($"{nameof(PreDownloaderOperation)} did not succeed."); return ResourceDownloaderOperation.CreateEmptyDownloader(_host.PackageName); } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/PreDownloaderOptions.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/PreDownloaderOptions.cs index 9921df90..284b54e3 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/PreDownloaderOptions.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/PreDownloaderOptions.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 预下载选项 + /// public struct PreDownloaderOptions { /// @@ -13,6 +16,11 @@ namespace YooAsset /// public int Timeout { get; set; } + /// + /// 创建预下载选项 + /// + /// 预下载的包裹版本 + /// 资源清单请求超时时间(秒) public PreDownloaderOptions(string packageVersion, int timeout) { PackageVersion = packageVersion; diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/RequestVersionOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/RequestVersionOperation.cs index 00eea6c9..ec07b390 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/RequestVersionOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/RequestVersionOperation.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 请求包裹版本操作 + /// public sealed class RequestVersionOperation : AsyncOperationBase { private enum ESteps diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operations/RequestVersionOptions.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operations/RequestVersionOptions.cs index d5f21c45..72660759 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operations/RequestVersionOptions.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operations/RequestVersionOptions.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 请求版本选项 + /// public struct RequestVersionOptions { /// @@ -13,6 +16,11 @@ namespace YooAsset /// public int Timeout { get; set; } + /// + /// 创建请求版本选项 + /// + /// 是否在URL末尾添加时间戳 + /// 超时时间(秒) public RequestVersionOptions(bool appendTimeTicks, int timeout) { AppendTimeTicks = appendTimeTicks; diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageAsset.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageAsset.cs index bfc19760..f222ef73 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PackageAsset.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageAsset.cs @@ -1,8 +1,11 @@ -using System; +using System; using System.Linq; namespace YooAsset { + /// + /// 清单中的资源对象 + /// [Serializable] internal class PackageAsset { @@ -35,7 +38,7 @@ namespace YooAsset /// 依赖的资源包ID集合 /// 说明:框架层收集查询结果 /// - public int[] DependBundleIDs; + public int[] DependentBundleIDs; /// /// 临时数据对象(仅编辑器有效) @@ -44,8 +47,10 @@ namespace YooAsset public object TempDataInEditor; /// - /// 是否包含Tag + /// 是否包含指定的标签 /// + /// 要检查的标签数组 + /// 如果包含任意一个标签返回true,否则返回false public bool HasTag(string[] tags) { if (tags == null || tags.Length == 0) diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs index a1c3a290..276d28a7 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs @@ -1,9 +1,12 @@ -using System; +using System; using System.Linq; using System.Collections.Generic; namespace YooAsset { + /// + /// 清单中的资源包对象 + /// [Serializable] internal class PackageBundle { @@ -35,7 +38,7 @@ namespace YooAsset /// /// 文件是否加密 /// - public bool Encrypted; + public bool IsEncrypted; /// /// 资源包的分类标签 @@ -46,11 +49,12 @@ namespace YooAsset /// 依赖的资源包ID集合 /// 注意:引擎层构建查询结果 /// - public int[] DependBundleIDs; + public int[] DependentBundleIDs; /// - /// 资源包GUID + /// 资源包唯一标识符 /// + /// 使用FileHash作为GUID public string BundleGUID { get { return FileHash; } @@ -76,7 +80,7 @@ namespace YooAsset get { if (string.IsNullOrEmpty(_fileName)) - throw new YooInternalException("File name can not be null or empty."); + throw new YooInternalException("File name cannot be null or empty."); return _fileName; } } @@ -90,7 +94,7 @@ namespace YooAsset get { if (string.IsNullOrEmpty(_fileExtension)) - throw new YooInternalException("File extension can not be null or empty."); + throw new YooInternalException("File extension cannot be null or empty."); return _fileExtension; } } @@ -111,6 +115,9 @@ namespace YooAsset private readonly HashSet _referenceBundleIDs = new HashSet(); + /// + /// 创建资源包实例 + /// public PackageBundle() { } @@ -118,9 +125,10 @@ namespace YooAsset /// /// 初始化资源包 /// - public void InitBundle(PackageManifest manifest) + /// 所属的资源清单 + public void Initialize(PackageManifest manifest) { - _mainfest = manifest; + _manifest = manifest; _bundleType = manifest.BuildBundleType; _fileExtension = PackageManifestTools.GetRemoteBundleFileExtension(BundleName); _fileName = PackageManifestTools.GetRemoteBundleFileName(manifest.OutputNameStyle, BundleName, _fileExtension, FileHash); @@ -128,8 +136,9 @@ namespace YooAsset /// /// 添加引用该资源包的资源包ID - /// 说明:谁引用了该资源包 /// + /// 引用该资源包的资源包ID + /// 记录谁引用了该资源包 public void AddReferenceBundleID(int bundleID) { if (_referenceBundleIDs.Contains(bundleID) == false) @@ -140,8 +149,10 @@ namespace YooAsset } /// - /// 是否包含Tag + /// 是否包含指定的标签 /// + /// 要检查的标签数组 + /// 如果包含任意一个标签返回true,否则返回false public bool HasTag(string[] tags) { if (tags == null || tags.Length == 0) @@ -158,9 +169,10 @@ namespace YooAsset } /// - /// 是否包含任意Tags + /// 是否包含任意标签 /// - public bool HasAnyTags() + /// 如果包含至少一个标签返回true,否则返回false + public bool HasTags() { return Tags != null && Tags.Length > 0; } @@ -168,6 +180,8 @@ namespace YooAsset /// /// 检测资源包文件内容是否相同 /// + /// 要比较的资源包对象 + /// 如果文件哈希值相同返回true,否则返回false public bool Equals(PackageBundle otherBundle) { if (FileHash == otherBundle.FileHash) @@ -177,8 +191,13 @@ namespace YooAsset } #region 调试信息 - private PackageManifest _mainfest; + private PackageManifest _manifest; private List _debugReferenceBundles; + + /// + /// 获取引用该资源包的资源包名称列表(仅调试用) + /// + /// 返回引用该资源包的所有资源包名称列表 public List GetDebugReferenceBundles() { if (_debugReferenceBundles == null) @@ -186,7 +205,7 @@ namespace YooAsset _debugReferenceBundles = new List(ReferenceBundleIDs.Count); foreach (int bundleID in ReferenceBundleIDs) { - var packageBundle = _mainfest.BundleList[bundleID]; + var packageBundle = _manifest.BundleList[bundleID]; _debugReferenceBundles.Add(packageBundle.BundleName); } } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageDetail.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageDetails.cs similarity index 94% rename from Assets/YooAsset/Runtime/ResourcePackage/PackageDetail.cs rename to Assets/YooAsset/Runtime/ResourcePackage/PackageDetails.cs index 3c1e0585..54cd97de 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PackageDetail.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageDetails.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 资源包裹的详细信息,用于外部查询包裹配置 + /// public class PackageDetails { /// diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageDetail.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/PackageDetails.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/PackageDetail.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/PackageDetails.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs index d433d70b..8f389048 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Collections; using System.Collections.Generic; @@ -91,31 +91,31 @@ namespace YooAsset /// 资源路径映射集合(提供Location获取AssetPath) /// [NonSerialized] - public Dictionary AssetPathMapping1; + public Dictionary AssetPathByLocation; /// /// 资源路径映射集合(提供AssetGUID获取AssetPath) /// [NonSerialized] - public Dictionary AssetPathMapping2; + public Dictionary AssetPathByAssetGUID; /// /// 资源包集合(提供BundleName获取PackageBundle) /// [NonSerialized] - public Dictionary BundleDic1; + public Dictionary BundleByBundleName; /// /// 资源包集合(提供FileName获取PackageBundle) /// [NonSerialized] - public Dictionary BundleDic2; + public Dictionary BundleByFileName; /// /// 资源包集合(提供BundleGUID获取PackageBundle) /// [NonSerialized] - public Dictionary BundleDic3; + public Dictionary BundleByBundleGUID; /// @@ -142,7 +142,7 @@ namespace YooAsset for (int index = 0; index < BundleList.Count; index++) { var sourceBundle = BundleList[index]; - foreach (int dependIndex in sourceBundle.DependBundleIDs) + foreach (int dependIndex in sourceBundle.DependentBundleIDs) { var dependBundle = BundleList[dependIndex]; dependBundle.AddReferenceBundleID(index); @@ -153,6 +153,7 @@ namespace YooAsset /// /// 获取包裹的详细信息 /// + /// 返回包含包裹配置信息的详细信息对象 public PackageDetails GetPackageDetails() { PackageDetails details = new PackageDetails(); @@ -174,14 +175,16 @@ namespace YooAsset } /// - /// 尝试映射为资源路径 + /// 尝试将定位地址映射为资源路径 /// + /// 资源定位地址 + /// 如果映射成功返回资源路径,否则返回空字符串 public string TryMappingToAssetPath(string location) { if (string.IsNullOrEmpty(location)) return string.Empty; - if (AssetPathMapping1.TryGetValue(location, out string assetPath)) + if (AssetPathByLocation.TryGetValue(location, out string assetPath)) return assetPath; else return string.Empty; @@ -189,8 +192,10 @@ namespace YooAsset /// /// 获取主资源包 - /// 注意:传入的资源包ID一定合法有效! /// + /// 资源包ID + /// 返回对应的资源包对象 + /// 传入的资源包ID必须合法有效,否则会抛出异常 public PackageBundle GetMainPackageBundle(int bundleID) { if (bundleID >= 0 && bundleID < BundleList.Count) @@ -208,21 +213,25 @@ namespace YooAsset /// /// 获取主资源包 - /// 注意:传入的资源对象一定合法有效! /// + /// 资源对象 + /// 返回资源对象所属的资源包 + /// 传入的资源对象必须合法有效,否则会抛出异常 public PackageBundle GetMainPackageBundle(PackageAsset packageAsset) { return GetMainPackageBundle(packageAsset.BundleID); } /// - /// 获取资源对象的依赖列表(框架层查询结果) - /// 注意:传入的资源对象一定合法有效! + /// 获取资源对象的所有依赖资源包列表 /// + /// 资源对象 + /// 返回依赖的资源包列表 + /// 框架层查询结果,传入的资源对象必须合法有效 public List GetAssetAllDependencies(PackageAsset packageAsset) { - List result = new List(packageAsset.DependBundleIDs.Length); - foreach (var dependID in packageAsset.DependBundleIDs) + List result = new List(packageAsset.DependentBundleIDs.Length); + foreach (var dependID in packageAsset.DependentBundleIDs) { var dependBundle = GetMainPackageBundle(dependID); result.Add(dependBundle); @@ -231,13 +240,15 @@ namespace YooAsset } /// - /// 获取资源包的依赖列表(引擎层查询结果) - /// 注意:传入的资源包对象一定合法有效! + /// 获取资源包的所有依赖资源包列表 /// + /// 资源包对象 + /// 返回依赖的资源包列表 + /// 引擎层查询结果,传入的资源包对象必须合法有效 public List GetBundleAllDependencies(PackageBundle packageBundle) { - List result = new List(packageBundle.DependBundleIDs.Length); - foreach (var dependID in packageBundle.DependBundleIDs) + List result = new List(packageBundle.DependentBundleIDs.Length); + foreach (var dependID in packageBundle.DependentBundleIDs) { var dependBundle = GetMainPackageBundle(dependID); result.Add(dependBundle); @@ -248,46 +259,61 @@ namespace YooAsset /// /// 尝试获取包裹的资源 /// + /// 资源路径 + /// 输出的资源对象 + /// 如果找到返回true,否则返回false public bool TryGetPackageAsset(string assetPath, out PackageAsset result) { return AssetDic.TryGetValue(assetPath, out result); } /// - /// 尝试获取包裹的资源包 + /// 尝试通过文件名获取包裹的资源包 /// + /// 文件名称 + /// 输出的资源包对象 + /// 如果找到返回true,否则返回false public bool TryGetPackageBundleByFileName(string fileName, out PackageBundle result) { - return BundleDic2.TryGetValue(fileName, out result); + return BundleByFileName.TryGetValue(fileName, out result); } /// - /// 尝试获取包裹的资源包 + /// 尝试通过资源包名称获取包裹的资源包 /// + /// 资源包名称 + /// 输出的资源包对象 + /// 如果找到返回true,否则返回false public bool TryGetPackageBundleByBundleName(string bundleName, out PackageBundle result) { - return BundleDic1.TryGetValue(bundleName, out result); + return BundleByBundleName.TryGetValue(bundleName, out result); } /// - /// 尝试获取包裹的资源包 + /// 尝试通过资源包GUID获取包裹的资源包 /// + /// 资源包GUID + /// 输出的资源包对象 + /// 如果找到返回true,否则返回false public bool TryGetPackageBundleByBundleGUID(string bundleGUID, out PackageBundle result) { - return BundleDic3.TryGetValue(bundleGUID, out result); + return BundleByBundleGUID.TryGetValue(bundleGUID, out result); } /// - /// 是否包含资源文件 + /// 是否包含指定的资源文件 /// + /// 资源包GUID + /// 如果包含返回true,否则返回false public bool IsIncludeBundleFile(string bundleGUID) { - return BundleDic3.ContainsKey(bundleGUID); + return BundleByBundleGUID.ContainsKey(bundleGUID); } /// /// 获取所有的资源信息 /// + /// 返回包含所有资源信息的数组 public AssetInfo[] GetAllAssetInfos() { AssetInfo[] result = new AssetInfo[AssetList.Count]; @@ -301,8 +327,10 @@ namespace YooAsset } /// - /// 获取资源信息列表 + /// 根据标签获取资源信息列表 /// + /// 资源标签数组 + /// 返回包含指定标签的资源信息数组 public AssetInfo[] GetAssetInfosByTags(string[] tags) { List result = new List(AssetList.Count); @@ -318,9 +346,11 @@ namespace YooAsset } /// - /// 资源定位地址转换为资源信息。 + /// 将资源定位地址转换为资源信息 /// - /// 如果转换失败会返回一个无效的资源信息类 + /// 资源定位地址 + /// 资源类型 + /// 返回资源信息对象,如果转换失败会返回一个无效的资源信息 public AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType) { DebugCheckLocation(location); @@ -346,30 +376,32 @@ namespace YooAsset { if (string.IsNullOrEmpty(location)) { - YooLogger.Error("Failed to mapping location to asset path, The location is null or empty."); + YooLogger.Error("Failed to map location to asset path, the location is null or empty."); return string.Empty; } - if (AssetPathMapping1.TryGetValue(location, out string assetPath)) + if (AssetPathByLocation.TryGetValue(location, out string assetPath)) { return assetPath; } else { - YooLogger.Warning($"Failed to mapping location to asset path : {location}"); + YooLogger.Warning($"Failed to map location to asset path: {location}"); return string.Empty; } } /// - /// 资源GUID转换为资源信息。 + /// 将资源GUID转换为资源信息 /// - /// 如果转换失败会返回一个无效的资源信息类 + /// 资源GUID + /// 资源类型 + /// 返回资源信息对象,如果转换失败会返回一个无效的资源信息 public AssetInfo ConvertAssetGUIDToAssetInfo(string assetGUID, System.Type assetType) { if (IncludeAssetGUID == false) { - YooLogger.Warning("Package manifest not include asset guid. Please check asset bundle collector settings."); + YooLogger.Warning("Package manifest does not include asset GUID. Please check asset bundle collector settings."); AssetInfo assetInfo = new AssetInfo(PackageName, "AssetGUID data is empty."); return assetInfo; } @@ -395,17 +427,17 @@ namespace YooAsset { if (string.IsNullOrEmpty(assetGUID)) { - YooLogger.Error("Failed to mapping assetGUID to asset path, The assetGUID is null or empty."); + YooLogger.Error("Failed to map asset GUID to asset path, the asset GUID is null or empty."); return string.Empty; } - if (AssetPathMapping2.TryGetValue(assetGUID, out string assetPath)) + if (AssetPathByAssetGUID.TryGetValue(assetGUID, out string assetPath)) { return assetPath; } else { - YooLogger.Warning($"Failed to mapping assetGUID to asset path : {assetGUID}"); + YooLogger.Warning($"Failed to map asset GUID to asset path: {assetGUID}"); return string.Empty; } } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestDefine.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestDefine.cs index 6914b1ca..8553cb8b 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestDefine.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestDefine.cs @@ -1,6 +1,9 @@ - + namespace YooAsset { + /// + /// 清单文件常量定义 + /// internal class PackageManifestDefine { /// @@ -14,10 +17,18 @@ namespace YooAsset public const uint FileSign = 0x594F4F; /// - /// 文件格式版本 + /// 当前文件格式版本 /// public const string FileVersion = "2025.9.30"; + + /// + /// 兼容的最低版本号 + /// public const string VERSION_2025_8_28 = "2025.8.28"; + + /// + /// 版本号 2025.9.30 + /// public const string VERSION_2025_9_30 = "2025.9.30"; } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestHelper.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestTools.cs similarity index 70% rename from Assets/YooAsset/Runtime/ResourcePackage/PackageManifestHelper.cs rename to Assets/YooAsset/Runtime/ResourcePackage/PackageManifestTools.cs index 905eec74..1e342f3b 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestHelper.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestTools.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Collections; using System.Collections.Generic; @@ -6,13 +6,22 @@ using UnityEngine; namespace YooAsset { + /// + /// 清单文件工具类 + /// internal static class PackageManifestTools { - private const int MD5HashLength = 32; //MD5的哈希值通常为32个字符 + /// + /// MD5哈希值长度(32个字符) + /// + private const int MD5HashLength = 32; /// /// 验证清单文件的二进制数据 /// + /// 文件二进制数据 + /// 期望的哈希值 + /// 如果验证通过返回true,否则返回false public static bool VerifyManifestData(byte[] fileData, string hashValue) { if (fileData == null || fileData.Length == 0) @@ -23,26 +32,31 @@ namespace YooAsset // 注意:兼容两种验证方式 string fileHash; if (hashValue.Length == MD5HashLength) - fileHash = HashUtility.BytesMD5(fileData); + fileHash = HashUtility.ComputeBytesMD5(fileData); else - fileHash = HashUtility.BytesCRC32(fileData); + fileHash = HashUtility.ComputeBytesCRC32(fileData); return fileHash == hashValue; } /// - /// 序列化(JSON文件) + /// 将清单文件序列化为JSON格式 /// - public static void SerializeToJson(string savePath, PackageManifest manifest) + /// 保存路径 + /// 清单对象 + public static void SerializeManifestToJson(string savePath, PackageManifest manifest) { string json = JsonUtility.ToJson(manifest, true); FileUtility.WriteAllText(savePath, json); } /// - /// 序列化(二进制文件) + /// 将清单文件序列化为二进制格式 /// - public static void SerializeToBinary(string savePath, PackageManifest manifest, IManifestProcessServices services) + /// 保存路径 + /// 清单对象 + /// 清单处理服务(可为null) + public static void SerializeManifestToBinary(string savePath, PackageManifest manifest, IManifestProcessServices services) { using (FileStream fs = new FileStream(savePath, FileMode.Create)) { @@ -78,7 +92,7 @@ namespace YooAsset buffer.WriteUTF8(packageAsset.AssetGUID); buffer.WriteUTF8Array(packageAsset.AssetTags); buffer.WriteInt32(packageAsset.BundleID); - buffer.WriteInt32Array(packageAsset.DependBundleIDs); + buffer.WriteInt32Array(packageAsset.DependentBundleIDs); } // 写入资源包列表 @@ -91,9 +105,9 @@ namespace YooAsset buffer.WriteUTF8(packageBundle.FileHash); buffer.WriteUInt32(packageBundle.FileCRC); buffer.WriteInt64(packageBundle.FileSize); - buffer.WriteBool(packageBundle.Encrypted); + buffer.WriteBool(packageBundle.IsEncrypted); buffer.WriteUTF8Array(packageBundle.Tags); - buffer.WriteInt32Array(packageBundle.DependBundleIDs); + buffer.WriteInt32Array(packageBundle.DependentBundleIDs); } // 清单处理操作 @@ -114,9 +128,11 @@ namespace YooAsset } /// - /// 反序列化(JSON文件) + /// 从JSON字符串反序列化清单文件 /// - public static PackageManifest DeserializeFromJson(string jsonContent) + /// JSON内容字符串 + /// 返回反序列化后的清单对象 + public static PackageManifest DeserializeManifestFromJson(string jsonContent) { var manifest = JsonUtility.FromJson(jsonContent); @@ -124,7 +140,7 @@ namespace YooAsset for (int i = 0; i < manifest.BundleList.Count; i++) { var packageBundle = manifest.BundleList[i]; - packageBundle.InitBundle(manifest); + packageBundle.Initialize(manifest); } // 初始化资源清单 @@ -133,9 +149,12 @@ namespace YooAsset } /// - /// 反序列化(二进制文件) + /// 从二进制数据反序列化清单文件 /// - public static PackageManifest DeserializeFromBinary(byte[] binaryData, IManifestRestoreServices services) + /// 二进制数据 + /// 清单恢复服务(可为null) + /// 返回反序列化后的清单对象 + public static PackageManifest DeserializeManifestFromBinary(byte[] binaryData, IManifestRestoreServices services) { DeserializeManifestOperation operation = new DeserializeManifestOperation(services, binaryData); operation.StartOperation(); @@ -146,6 +165,8 @@ namespace YooAsset /// /// 获取资源文件的后缀名 /// + /// 资源包名称 + /// 返回文件后缀名(包含点号) public static string GetRemoteBundleFileExtension(string bundleName) { string fileExtension = Path.GetExtension(bundleName); @@ -155,6 +176,11 @@ namespace YooAsset /// /// 获取远端的资源文件名 /// + /// 文件名称样式 + /// 资源包名称 + /// 文件后缀名 + /// 文件哈希值 + /// 返回根据命名样式生成的远端文件名 public static string GetRemoteBundleFileName(int nameStyle, string bundleName, string fileExtension, string fileHash) { EFileNameStyle style = (EFileNameStyle)nameStyle; diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestHelper.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestTools.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/PackageManifestHelper.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/PackageManifestTools.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs index 88cd55f2..35cff453 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs @@ -6,6 +6,9 @@ using UnityEngine.SceneManagement; namespace YooAsset { + /// + /// 资源包裹类 + /// public class ResourcePackage { private InitializePackageOperation _initializeOp; @@ -84,6 +87,8 @@ namespace YooAsset /// /// 异步初始化包裹 /// + /// 初始化参数 + /// 返回初始化操作对象 public InitializePackageOperation InitializePackageAsync(InitializePackageOptions options) { // 注意:联机平台因为网络原因可能会初始化失败! @@ -131,6 +136,8 @@ namespace YooAsset /// /// 请求最新的资源版本 /// + /// 请求版本选项 + /// 返回请求版本操作对象 public RequestVersionOperation RequestVersionAsync(RequestVersionOptions options) { CheckInitialized(false); @@ -142,6 +149,8 @@ namespace YooAsset /// /// 加载指定版本的资源清单 /// + /// 加载清单选项 + /// 返回加载清单操作对象 public LoadManifestOperation LoadManifestAsync(LoadManifestOptions options) { CheckInitialized(false); @@ -149,7 +158,7 @@ namespace YooAsset // 注意:强烈建议在更新之前保持加载器为空! if (_resourceManager.HasAnyLoader()) { - YooLogger.Warning($"Found loaded bundle before update manifest. Recommended to call the {nameof(UnloadAllAssetsAsync)} method to release loaded bundle."); + YooLogger.Warning($"Found loaded bundles before updating the manifest. It is recommended to call the {nameof(UnloadAllAssetsAsync)} method to release loaded bundles."); } var operation = new LoadManifestOperation(_fileSystemHost, options); @@ -160,6 +169,8 @@ namespace YooAsset /// /// 预下载指定版本的包裹资源 /// + /// 预下载选项 + /// 返回预下载操作对象 public PreDownloaderOperation PreDownloaderAsync(PreDownloaderOptions options) { CheckInitialized(false); @@ -171,6 +182,8 @@ namespace YooAsset /// /// 清理缓存文件 /// + /// 清理缓存选项 + /// 返回清理缓存操作对象 public ClearCacheOperation ClearCacheAsync(ClearCacheOptions options) { CheckInitialized(false); diff --git a/Assets/YooAsset/Runtime/Settings/YooAssetSettingsData.cs b/Assets/YooAsset/Runtime/Settings/YooAssetSettingsData.cs index e67f2c47..ed3d40c7 100644 --- a/Assets/YooAsset/Runtime/Settings/YooAssetSettingsData.cs +++ b/Assets/YooAsset/Runtime/Settings/YooAssetSettingsData.cs @@ -114,14 +114,14 @@ namespace YooAsset if (string.IsNullOrEmpty(Setting.DefaultYooFolderName)) { string projectPath = Path.GetDirectoryName(Application.dataPath); - projectPath = PathUtility.RegularPath(projectPath); + projectPath = PathUtility.NormalizePath(projectPath); return projectPath; } else { // 注意:为了方便调试查看,编辑器下把存储目录放到项目根目录下。 string projectPath = Path.GetDirectoryName(Application.dataPath); - projectPath = PathUtility.RegularPath(projectPath); + projectPath = PathUtility.NormalizePath(projectPath); return PathUtility.Combine(projectPath, Setting.DefaultYooFolderName); } } diff --git a/Assets/YooAsset/Runtime/Utility/BufferReader.cs b/Assets/YooAsset/Runtime/Utility/BufferReader.cs index 2221a1b4..0e9369e7 100644 --- a/Assets/YooAsset/Runtime/Utility/BufferReader.cs +++ b/Assets/YooAsset/Runtime/Utility/BufferReader.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Text; @@ -6,11 +6,17 @@ using System.Diagnostics; namespace YooAsset { + /// + /// 二进制缓冲区读取器,数据以小端字节序存储 + /// internal class BufferReader { private readonly byte[] _buffer; private int _index = 0; + /// + /// 使用指定的字节数组创建缓冲区读取器 + /// public BufferReader(byte[] data) { _buffer = data; @@ -38,6 +44,9 @@ namespace YooAsset get { return _buffer.Length; } } + /// + /// 读取指定数量的字节 + /// public byte[] ReadBytes(int count) { CheckReaderIndex(count); @@ -46,17 +55,28 @@ namespace YooAsset _index += count; return data; } + + /// + /// 读取单个字节 + /// public byte ReadByte() { CheckReaderIndex(1); return _buffer[_index++]; } + /// + /// 读取布尔值 + /// public bool ReadBool() { CheckReaderIndex(1); return _buffer[_index++] == 1; } + + /// + /// 读取16位有符号整数 + /// public short ReadInt16() { CheckReaderIndex(2); @@ -73,10 +93,17 @@ namespace YooAsset return value; } } + /// + /// 读取16位无符号整数 + /// public ushort ReadUInt16() { return (ushort)ReadInt16(); } + + /// + /// 读取32位有符号整数 + /// public int ReadInt32() { CheckReaderIndex(4); @@ -93,10 +120,17 @@ namespace YooAsset return value; } } + /// + /// 读取32位无符号整数 + /// public uint ReadUInt32() { return (uint)ReadInt32(); } + + /// + /// 读取64位有符号整数 + /// public long ReadInt64() { CheckReaderIndex(8); @@ -115,11 +149,17 @@ namespace YooAsset return (uint)i2 | ((long)i1 << 32); } } + /// + /// 读取64位无符号整数 + /// public ulong ReadUInt64() { return (ulong)ReadInt64(); } + /// + /// 跳过一个UTF8编码的字符串 + /// public void SkipUTF8() { ushort count = ReadUInt16(); @@ -129,6 +169,10 @@ namespace YooAsset CheckReaderIndex(count); _index += count; } + + /// + /// 读取UTF8编码的字符串 + /// public string ReadUTF8() { ushort count = ReadUInt16(); @@ -140,6 +184,10 @@ namespace YooAsset _index += count; return value; } + + /// + /// 读取32位有符号整数数组 + /// public int[] ReadInt32Array() { ushort count = ReadUInt16(); @@ -150,6 +198,10 @@ namespace YooAsset } return values; } + + /// + /// 读取64位有符号整数数组 + /// public long[] ReadInt64Array() { ushort count = ReadUInt16(); @@ -160,6 +212,10 @@ namespace YooAsset } return values; } + + /// + /// 读取UTF8编码的字符串数组 + /// public string[] ReadUTF8Array() { ushort count = ReadUInt16(); diff --git a/Assets/YooAsset/Runtime/Utility/BufferWriter.cs b/Assets/YooAsset/Runtime/Utility/BufferWriter.cs index c002f5e9..4a9a3568 100644 --- a/Assets/YooAsset/Runtime/Utility/BufferWriter.cs +++ b/Assets/YooAsset/Runtime/Utility/BufferWriter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Text; @@ -15,6 +15,9 @@ namespace YooAsset private readonly byte[] _buffer; private int _index = 0; + /// + /// 创建指定容量的缓冲区写入器 + /// public BufferWriter(int capacity) { _buffer = new byte[capacity]; @@ -54,6 +57,9 @@ namespace YooAsset fileStream.Write(_buffer, 0, _index); } + /// + /// 写入字节数组 + /// public void WriteBytes(byte[] data) { int count = data.Length; @@ -61,30 +67,53 @@ namespace YooAsset Buffer.BlockCopy(data, 0, _buffer, _index, count); _index += count; } + + /// + /// 写入单个字节 + /// public void WriteByte(byte value) { CheckWriterIndex(1); _buffer[_index++] = value; } + /// + /// 写入布尔值 + /// public void WriteBool(bool value) { WriteByte((byte)(value ? 1 : 0)); } + + /// + /// 写入16位有符号整数 + /// public void WriteInt16(short value) { WriteUInt16((ushort)value); } + + /// + /// 写入16位无符号整数 + /// public void WriteUInt16(ushort value) { CheckWriterIndex(2); _buffer[_index++] = (byte)value; _buffer[_index++] = (byte)(value >> 8); } + + /// + /// 写入32位有符号整数 + /// public void WriteInt32(int value) { WriteUInt32((uint)value); } + + /// + /// 写入32位无符号整数 + /// public void WriteUInt32(uint value) { CheckWriterIndex(4); @@ -93,10 +122,18 @@ namespace YooAsset _buffer[_index++] = (byte)(value >> 16); _buffer[_index++] = (byte)(value >> 24); } + + /// + /// 写入64位有符号整数 + /// public void WriteInt64(long value) { WriteUInt64((ulong)value); } + + /// + /// 写入64位无符号整数 + /// public void WriteUInt64(ulong value) { CheckWriterIndex(8); @@ -110,6 +147,9 @@ namespace YooAsset _buffer[_index++] = (byte)(value >> 56); } + /// + /// 写入UTF8编码的字符串 + /// public void WriteUTF8(string value) { if (string.IsNullOrEmpty(value)) @@ -127,6 +167,10 @@ namespace YooAsset WriteBytes(bytes); } } + + /// + /// 写入32位有符号整数数组 + /// public void WriteInt32Array(int[] values) { if (values == null) @@ -146,6 +190,10 @@ namespace YooAsset } } } + + /// + /// 写入64位有符号整数数组 + /// public void WriteInt64Array(long[] values) { if (values == null) @@ -165,6 +213,10 @@ namespace YooAsset } } } + + /// + /// 写入UTF8编码的字符串数组 + /// public void WriteUTF8Array(string[] values) { if (values == null) diff --git a/Assets/YooAsset/Runtime/Utility/CRC32Algorithm.cs b/Assets/YooAsset/Runtime/Utility/CRC32Algorithm.cs index 22a92b5f..48c95844 100644 --- a/Assets/YooAsset/Runtime/Utility/CRC32Algorithm.cs +++ b/Assets/YooAsset/Runtime/Utility/CRC32Algorithm.cs @@ -1,69 +1,8 @@ -using System; +using System; using System.Security.Cryptography; namespace YooAsset { - internal class SafeProxy - { - private const uint Poly = 0xedb88320u; - private readonly uint[] _table = new uint[16 * 256]; - - internal SafeProxy() - { - Init(Poly); - } - public void Init(uint poly) - { - var table = _table; - for (uint i = 0; i < 256; i++) - { - uint res = i; - for (int t = 0; t < 16; t++) - { - for (int k = 0; k < 8; k++) res = (res & 1) == 1 ? poly ^ (res >> 1) : (res >> 1); - table[(t * 256) + i] = res; - } - } - } - public uint Append(uint crc, byte[] input, int offset, int length) - { - uint crcLocal = uint.MaxValue ^ crc; - - uint[] table = _table; - while (length >= 16) - { - var a = table[(3 * 256) + input[offset + 12]] - ^ table[(2 * 256) + input[offset + 13]] - ^ table[(1 * 256) + input[offset + 14]] - ^ table[(0 * 256) + input[offset + 15]]; - - var b = table[(7 * 256) + input[offset + 8]] - ^ table[(6 * 256) + input[offset + 9]] - ^ table[(5 * 256) + input[offset + 10]] - ^ table[(4 * 256) + input[offset + 11]]; - - var c = table[(11 * 256) + input[offset + 4]] - ^ table[(10 * 256) + input[offset + 5]] - ^ table[(9 * 256) + input[offset + 6]] - ^ table[(8 * 256) + input[offset + 7]]; - - var d = table[(15 * 256) + ((byte)crcLocal ^ input[offset])] - ^ table[(14 * 256) + ((byte)(crcLocal >> 8) ^ input[offset + 1])] - ^ table[(13 * 256) + ((byte)(crcLocal >> 16) ^ input[offset + 2])] - ^ table[(12 * 256) + ((crcLocal >> 24) ^ input[offset + 3])]; - - crcLocal = d ^ c ^ b ^ a; - offset += 16; - length -= 16; - } - - while (--length >= 0) - crcLocal = table[(byte)(crcLocal ^ input[offset++])] ^ crcLocal >> 8; - - return crcLocal ^ uint.MaxValue; - } - } - /// /// This is .NET safe implementation of Crc32 algorithm. /// Implementation of CRC-32. @@ -71,12 +10,73 @@ namespace YooAsset /// internal class CRC32Algorithm : HashAlgorithm { + private class CRC32Table + { + private const uint Poly = 0xedb88320u; + private readonly uint[] _table = new uint[16 * 256]; + + internal CRC32Table() + { + Init(Poly); + } + public void Init(uint poly) + { + var table = _table; + for (uint i = 0; i < 256; i++) + { + uint res = i; + for (int t = 0; t < 16; t++) + { + for (int k = 0; k < 8; k++) res = (res & 1) == 1 ? poly ^ (res >> 1) : (res >> 1); + table[(t * 256) + i] = res; + } + } + } + public uint Append(uint crc, byte[] input, int offset, int length) + { + uint crcLocal = uint.MaxValue ^ crc; + + uint[] table = _table; + while (length >= 16) + { + var a = table[(3 * 256) + input[offset + 12]] + ^ table[(2 * 256) + input[offset + 13]] + ^ table[(1 * 256) + input[offset + 14]] + ^ table[(0 * 256) + input[offset + 15]]; + + var b = table[(7 * 256) + input[offset + 8]] + ^ table[(6 * 256) + input[offset + 9]] + ^ table[(5 * 256) + input[offset + 10]] + ^ table[(4 * 256) + input[offset + 11]]; + + var c = table[(11 * 256) + input[offset + 4]] + ^ table[(10 * 256) + input[offset + 5]] + ^ table[(9 * 256) + input[offset + 6]] + ^ table[(8 * 256) + input[offset + 7]]; + + var d = table[(15 * 256) + ((byte)crcLocal ^ input[offset])] + ^ table[(14 * 256) + ((byte)(crcLocal >> 8) ^ input[offset + 1])] + ^ table[(13 * 256) + ((byte)(crcLocal >> 16) ^ input[offset + 2])] + ^ table[(12 * 256) + ((crcLocal >> 24) ^ input[offset + 3])]; + + crcLocal = d ^ c ^ b ^ a; + offset += 16; + length -= 16; + } + + while (--length >= 0) + crcLocal = table[(byte)(crcLocal ^ input[offset++])] ^ crcLocal >> 8; + + return crcLocal ^ uint.MaxValue; + } + } + private uint _currentCrc; /// /// Gets the computed hash value. /// - public uint CRCValue { private set; get; } + public uint Crc32Value { private set; get; } /// /// Initializes a new instance of the class. @@ -109,7 +109,7 @@ namespace YooAsset /// protected override byte[] HashFinal() { - CRCValue = _currentCrc; + Crc32Value = _currentCrc; if (BitConverter.IsLittleEndian) return new[] { (byte)_currentCrc, (byte)(_currentCrc >> 8), (byte)(_currentCrc >> 16), (byte)(_currentCrc >> 24) }; @@ -188,7 +188,7 @@ namespace YooAsset public static uint ComputeAndWriteToEnd(byte[] input, int offset, int length) { if (length + 4 > input.Length) - throw new ArgumentOutOfRangeException("length", "Length of data should be less than array length - 4 bytes of CRC data"); + throw new ArgumentOutOfRangeException("length", "Data length exceeds buffer capacity (need 4 bytes reserved for CRC)"); var crc = Append(0, input, offset, length); var r = offset + length; input[r] = (byte)crc; @@ -206,7 +206,7 @@ namespace YooAsset public static uint ComputeAndWriteToEnd(byte[] input) { if (input.Length < 4) - throw new ArgumentOutOfRangeException("input", "Input array should be 4 bytes at least"); + throw new ArgumentOutOfRangeException("input", "Input array must be at least 4 bytes"); return ComputeAndWriteToEnd(input, 0, input.Length - 4); } @@ -230,17 +230,17 @@ namespace YooAsset public static bool IsValidWithCrcAtEnd(byte[] input) { if (input.Length < 4) - throw new ArgumentOutOfRangeException("input", "Input array should be 4 bytes at least"); + throw new ArgumentOutOfRangeException("input", "Input array must be at least 4 bytes"); return Append(0, input, 0, input.Length) == 0x2144DF1C; } - private static readonly SafeProxy _proxy = new SafeProxy(); + private static readonly CRC32Table _table = new CRC32Table(); private static uint AppendInternal(uint initial, byte[] input, int offset, int length) { if (length > 0) { - return _proxy.Append(initial, input, offset, length); + return _table.Append(initial, input, offset, length); } else return initial; diff --git a/Assets/YooAsset/Runtime/Utility/FileUtility.cs b/Assets/YooAsset/Runtime/Utility/FileUtility.cs new file mode 100644 index 00000000..1ee12edd --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/FileUtility.cs @@ -0,0 +1,85 @@ +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace YooAsset +{ + /// + /// 文件工具类 + /// + internal static class FileUtility + { + /// + /// 读取文件的文本数据 + /// + public static string ReadAllText(string filePath) + { + if (File.Exists(filePath) == false) + return null; + return File.ReadAllText(filePath, Encoding.UTF8); + } + + /// + /// 读取文件的字节数据 + /// + public static byte[] ReadAllBytes(string filePath) + { + if (File.Exists(filePath) == false) + return null; + return File.ReadAllBytes(filePath); + } + + /// + /// 写入文本数据(会覆盖指定路径的文件) + /// + public static void WriteAllText(string filePath, string content) + { + // 创建文件夹路径 + EnsureFileDirectory(filePath); + + byte[] bytes = Encoding.UTF8.GetBytes(content); + File.WriteAllBytes(filePath, bytes); //避免写入BOM标记 + } + + /// + /// 写入字节数据(会覆盖指定路径的文件) + /// + public static void WriteAllBytes(string filePath, byte[] data) + { + // 创建文件夹路径 + EnsureFileDirectory(filePath); + + File.WriteAllBytes(filePath, data); + } + + /// + /// 确保文件的父目录存在,如不存在则创建 + /// + public static void EnsureFileDirectory(string filePath) + { + // 获取文件的文件夹路径 + string directory = Path.GetDirectoryName(filePath); + EnsureDirectory(directory); + } + + /// + /// 确保目录存在,如不存在则创建 + /// + public static void EnsureDirectory(string directory) + { + // If the directory doesn't exist, create it. + if (Directory.Exists(directory) == false) + Directory.CreateDirectory(directory); + } + + /// + /// 获取文件大小(字节数) + /// + public static long GetFileSize(string filePath) + { + FileInfo fileInfo = new FileInfo(filePath); + return fileInfo.Length; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Utility/FileUtility.cs.meta b/Assets/YooAsset/Runtime/Utility/FileUtility.cs.meta new file mode 100644 index 00000000..7c915397 --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/FileUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d3d37a19fa5b3144db5b0a0c82fde362 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/Utility/HashUtility.cs b/Assets/YooAsset/Runtime/Utility/HashUtility.cs new file mode 100644 index 00000000..4b835dda --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/HashUtility.cs @@ -0,0 +1,188 @@ +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace YooAsset +{ + /// + /// 哈希工具类 + /// + public static class HashUtility + { + private static string ToHexString(byte[] hashBytes) + { + string result = BitConverter.ToString(hashBytes); + result = result.Replace("-", ""); + return result.ToLower(); + } + + #region SHA1 + /// + /// 计算字符串的SHA1哈希值 + /// + public static string ComputeSHA1(string str) + { + byte[] buffer = Encoding.UTF8.GetBytes(str); + return ComputeBytesSHA1(buffer); + } + + /// + /// 计算文件的SHA1哈希值 + /// + public static string ComputeFileSHA1(string filePath) + { + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + return ComputeStreamSHA1(fs); + } + } + + /// + /// 计算数据流的SHA1哈希值 + /// + public static string ComputeStreamSHA1(Stream stream) + { + // 说明:创建的是SHA1类的实例,生成的是160位的散列码 + HashAlgorithm hash = HashAlgorithm.Create(); + byte[] hashBytes = hash.ComputeHash(stream); + return ToHexString(hashBytes); + } + + /// + /// 计算字节数组的SHA1哈希值 + /// + public static string ComputeBytesSHA1(byte[] buffer) + { + // 说明:创建的是SHA1类的实例,生成的是160位的散列码 + HashAlgorithm hash = HashAlgorithm.Create(); + byte[] hashBytes = hash.ComputeHash(buffer); + return ToHexString(hashBytes); + } + #endregion + + #region MD5 + /// + /// 获取字符串的MD5 + /// + public static string ComputeMD5(string str) + { + byte[] buffer = Encoding.UTF8.GetBytes(str); + return ComputeBytesMD5(buffer); + } + + /// + /// 获取文件的MD5 + /// + public static string ComputeFileMD5(string filePath) + { + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + return ComputeStreamMD5(fs); + } + } + + /// + /// 获取数据流的MD5 + /// + public static string ComputeStreamMD5(Stream stream) + { + MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider(); + byte[] hashBytes = provider.ComputeHash(stream); + return ToHexString(hashBytes); + } + + /// + /// 获取字节数组的MD5 + /// + public static string ComputeBytesMD5(byte[] buffer) + { + MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider(); + byte[] hashBytes = provider.ComputeHash(buffer); + return ToHexString(hashBytes); + } + #endregion + + #region CRC32 + /// + /// 获取字符串的CRC32 + /// + public static string ComputeCRC32(string str) + { + byte[] buffer = Encoding.UTF8.GetBytes(str); + return ComputeBytesCRC32(buffer); + } + + /// + /// 计算字符串的CRC32值(返回无符号整数) + /// + public static uint ComputeCRC32AsUInt(string str) + { + byte[] buffer = Encoding.UTF8.GetBytes(str); + return ComputeBytesCRC32AsUInt(buffer); + } + + /// + /// 获取文件的CRC32 + /// + public static string ComputeFileCRC32(string filePath) + { + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + return ComputeStreamCRC32(fs); + } + } + + /// + /// 计算文件的CRC32值(返回无符号整数) + /// + public static uint ComputeFileCRC32AsUInt(string filePath) + { + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + return ComputeStreamCRC32AsUInt(fs); + } + } + + /// + /// 获取数据流的CRC32 + /// + public static string ComputeStreamCRC32(Stream stream) + { + CRC32Algorithm hash = new CRC32Algorithm(); + byte[] hashBytes = hash.ComputeHash(stream); + return ToHexString(hashBytes); + } + + /// + /// 计算数据流的CRC32值(返回无符号整数) + /// + public static uint ComputeStreamCRC32AsUInt(Stream stream) + { + CRC32Algorithm hash = new CRC32Algorithm(); + hash.ComputeHash(stream); + return hash.Crc32Value; + } + + /// + /// 获取字节数组的CRC32 + /// + public static string ComputeBytesCRC32(byte[] buffer) + { + CRC32Algorithm hash = new CRC32Algorithm(); + byte[] hashBytes = hash.ComputeHash(buffer); + return ToHexString(hashBytes); + } + + /// + /// 计算字节数组的CRC32值(返回无符号整数) + /// + public static uint ComputeBytesCRC32AsUInt(byte[] buffer) + { + CRC32Algorithm hash = new CRC32Algorithm(); + hash.ComputeHash(buffer); + return hash.Crc32Value; + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Utility/YooUtility.cs.meta b/Assets/YooAsset/Runtime/Utility/HashUtility.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/Utility/YooUtility.cs.meta rename to Assets/YooAsset/Runtime/Utility/HashUtility.cs.meta diff --git a/Assets/YooAsset/Runtime/Utility/PathUtility.cs b/Assets/YooAsset/Runtime/Utility/PathUtility.cs new file mode 100644 index 00000000..f14bf6b2 --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/PathUtility.cs @@ -0,0 +1,72 @@ +using System; + +namespace YooAsset +{ + /// + /// 路径工具类 + /// + internal static class PathUtility + { + /// + /// 路径归一化 + /// 注意:替换为Linux路径格式 + /// + public static string NormalizePath(string path) + { + return path.Replace('\\', '/').Replace("\\", "/"); + } + + /// + /// 移除路径里的后缀名 + /// + public static string RemoveExtension(string str) + { + if (string.IsNullOrEmpty(str)) + return str; + + int index = str.LastIndexOf('.'); + if (index == -1) + return str; + else + return str.Remove(index); //"assets/config/test.unity3d" --> "assets/config/test" + } + + /// + /// URL地址是否包含双斜杠 + /// 注意:只检查协议之后的部分 + /// + public static bool HasDoubleSlashes(string url) + { + if (url == null) + throw new ArgumentNullException(); + + int protocolIndex = url.IndexOf("://"); + string partToCheck = protocolIndex == -1 ? url : url.Substring(protocolIndex + 3); + return partToCheck.Contains("//") || partToCheck.Contains(@"\\"); + } + + /// + /// 合并路径 + /// + public static string Combine(string path1, string path2) + { + return StringUtility.Format("{0}/{1}", path1, path2); + } + + /// + /// 合并路径 + /// + public static string Combine(string path1, string path2, string path3) + { + return StringUtility.Format("{0}/{1}/{2}", path1, path2, path3); + } + + /// + /// 合并路径 + /// + public static string Combine(string path1, string path2, string path3, string path4) + { + return StringUtility.Format("{0}/{1}/{2}/{3}", path1, path2, path3, path4); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Utility/PathUtility.cs.meta b/Assets/YooAsset/Runtime/Utility/PathUtility.cs.meta new file mode 100644 index 00000000..1ed1a18c --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/PathUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 96e908879b2b8f74da528cf9704ccdf8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/Utility/StringUtility.cs b/Assets/YooAsset/Runtime/Utility/StringUtility.cs new file mode 100644 index 00000000..5fc09eb9 --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/StringUtility.cs @@ -0,0 +1,69 @@ +using System; +using System.Text; + +namespace YooAsset +{ + /// + /// 字符串工具类 + /// + internal static class StringUtility + { + [ThreadStatic] + private static StringBuilder _cacheBuilder = new StringBuilder(2048); + + /// + /// 格式化字符串(无GC优化版本) + /// + public static string Format(string format, object arg0) + { + if (string.IsNullOrEmpty(format)) + throw new ArgumentNullException(); + + _cacheBuilder.Length = 0; + _cacheBuilder.AppendFormat(format, arg0); + return _cacheBuilder.ToString(); + } + + /// + /// 格式化字符串(无GC优化版本) + /// + public static string Format(string format, object arg0, object arg1) + { + if (string.IsNullOrEmpty(format)) + throw new ArgumentNullException(); + + _cacheBuilder.Length = 0; + _cacheBuilder.AppendFormat(format, arg0, arg1); + return _cacheBuilder.ToString(); + } + + /// + /// 格式化字符串(无GC优化版本) + /// + public static string Format(string format, object arg0, object arg1, object arg2) + { + if (string.IsNullOrEmpty(format)) + throw new ArgumentNullException(); + + _cacheBuilder.Length = 0; + _cacheBuilder.AppendFormat(format, arg0, arg1, arg2); + return _cacheBuilder.ToString(); + } + + /// + /// 格式化字符串(无GC优化版本) + /// + public static string Format(string format, params object[] args) + { + if (string.IsNullOrEmpty(format)) + throw new ArgumentNullException(); + + if (args == null) + throw new ArgumentNullException(); + + _cacheBuilder.Length = 0; + _cacheBuilder.AppendFormat(format, args); + return _cacheBuilder.ToString(); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Utility/StringUtility.cs.meta b/Assets/YooAsset/Runtime/Utility/StringUtility.cs.meta new file mode 100644 index 00000000..c785a419 --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/StringUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 04da321c528fbcc449457cfcc3650f15 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/Utility/TimeUtility.cs b/Assets/YooAsset/Runtime/Utility/TimeUtility.cs new file mode 100644 index 00000000..51b64db9 --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/TimeUtility.cs @@ -0,0 +1,24 @@ + +namespace YooAsset +{ + /// + /// 时间工具类 + /// + internal static class TimeUtility + { + /// + /// 游戏启动以来的真实时间(秒) + /// + public static double RealtimeSinceStartup + { + get + { +#if UNITY_2020_3_OR_NEWER + return UnityEngine.Time.realtimeSinceStartupAsDouble; +#else + return UnityEngine.Time.realtimeSinceStartup; +#endif + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Utility/TimeUtility.cs.meta b/Assets/YooAsset/Runtime/Utility/TimeUtility.cs.meta new file mode 100644 index 00000000..f5655822 --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/TimeUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a9d49371363336648817d517d5b0067e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/Utility/YooLogger.cs b/Assets/YooAsset/Runtime/Utility/YooLogger.cs index 6bf555c9..37bb0230 100644 --- a/Assets/YooAsset/Runtime/Utility/YooLogger.cs +++ b/Assets/YooAsset/Runtime/Utility/YooLogger.cs @@ -1,21 +1,42 @@ -using System.Diagnostics; +using System.Diagnostics; namespace YooAsset { /// - /// 自定义日志处理 + /// 自定义日志处理接口 /// public interface ILogger { + /// + /// 输出普通日志 + /// void Log(string message); + + /// + /// 输出警告日志 + /// void Warning(string message); + + /// + /// 输出错误日志 + /// void Error(string message); + + /// + /// 输出异常日志 + /// void Exception(System.Exception exception); } + /// + /// YooAsset内部日志系统 + /// internal static class YooLogger { - public static ILogger Logger = null; + /// + /// 自定义日志处理器实例 + /// + public static ILogger LoggerInstance = null; /// /// 日志 @@ -23,9 +44,9 @@ namespace YooAsset [Conditional("DEBUG")] public static void Log(string info) { - if (Logger != null) + if (LoggerInstance != null) { - Logger.Log(info); + LoggerInstance.Log(info); } else { @@ -38,9 +59,9 @@ namespace YooAsset /// public static void Warning(string info) { - if (Logger != null) + if (LoggerInstance != null) { - Logger.Warning(info); + LoggerInstance.Warning(info); } else { @@ -53,9 +74,9 @@ namespace YooAsset /// public static void Error(string info) { - if (Logger != null) + if (LoggerInstance != null) { - Logger.Error(info); + LoggerInstance.Error(info); } else { @@ -68,9 +89,9 @@ namespace YooAsset /// public static void Exception(System.Exception exception) { - if (Logger != null) + if (LoggerInstance != null) { - Logger.Exception(exception); + LoggerInstance.Exception(exception); } else { diff --git a/Assets/YooAsset/Runtime/Utility/YooUtility.cs b/Assets/YooAsset/Runtime/Utility/YooUtility.cs deleted file mode 100644 index 64c09062..00000000 --- a/Assets/YooAsset/Runtime/Utility/YooUtility.cs +++ /dev/null @@ -1,448 +0,0 @@ -using System; -using System.IO; -using System.Security.Cryptography; -using System.Text; - -namespace YooAsset -{ - /// - /// 时间工具类 - /// - internal static class TimeUtility - { - /// - /// The real time in seconds since the game started - /// - public static double RealtimeSinceStartup - { - get - { -#if UNITY_2020_3_OR_NEWER - return UnityEngine.Time.realtimeSinceStartupAsDouble; -#else - return UnityEngine.Time.realtimeSinceStartup; -#endif - } - } - } - - /// - /// 路径工具类 - /// - internal static class PathUtility - { - /// - /// 路径归一化 - /// 注意:替换为Linux路径格式 - /// - public static string RegularPath(string path) - { - return path.Replace('\\', '/').Replace("\\", "/"); - } - - /// - /// 移除路径里的后缀名 - /// - public static string RemoveExtension(string str) - { - if (string.IsNullOrEmpty(str)) - return str; - - int index = str.LastIndexOf('.'); - if (index == -1) - return str; - else - return str.Remove(index); //"assets/config/test.unity3d" --> "assets/config/test" - } - - /// - /// URL地址是否包含双斜杠 - /// 注意:只检查协议之后的部分 - /// - public static bool HasDoubleSlashes(string url) - { - if (url == null) - throw new ArgumentNullException(); - - int protocolIndex = url.IndexOf("://"); - string partToCheck = protocolIndex == -1 ? url : url.Substring(protocolIndex + 3); - return partToCheck.Contains("//") || partToCheck.Contains(@"\\"); - } - - /// - /// 合并路径 - /// - public static string Combine(string path1, string path2) - { - return StringUtility.Format("{0}/{1}", path1, path2); - } - - /// - /// 合并路径 - /// - public static string Combine(string path1, string path2, string path3) - { - return StringUtility.Format("{0}/{1}/{2}", path1, path2, path3); - } - - /// - /// 合并路径 - /// - public static string Combine(string path1, string path2, string path3, string path4) - { - return StringUtility.Format("{0}/{1}/{2}/{3}", path1, path2, path3, path4); - } - } - - /// - /// 字符串工具类 - /// - internal static class StringUtility - { - [ThreadStatic] - private static StringBuilder _cacheBuilder = new StringBuilder(2048); - - public static string Format(string format, object arg0) - { - if (string.IsNullOrEmpty(format)) - throw new ArgumentNullException(); - - _cacheBuilder.Length = 0; - _cacheBuilder.AppendFormat(format, arg0); - return _cacheBuilder.ToString(); - } - public static string Format(string format, object arg0, object arg1) - { - if (string.IsNullOrEmpty(format)) - throw new ArgumentNullException(); - - _cacheBuilder.Length = 0; - _cacheBuilder.AppendFormat(format, arg0, arg1); - return _cacheBuilder.ToString(); - } - public static string Format(string format, object arg0, object arg1, object arg2) - { - if (string.IsNullOrEmpty(format)) - throw new ArgumentNullException(); - - _cacheBuilder.Length = 0; - _cacheBuilder.AppendFormat(format, arg0, arg1, arg2); - return _cacheBuilder.ToString(); - } - public static string Format(string format, params object[] args) - { - if (string.IsNullOrEmpty(format)) - throw new ArgumentNullException(); - - if (args == null) - throw new ArgumentNullException(); - - _cacheBuilder.Length = 0; - _cacheBuilder.AppendFormat(format, args); - return _cacheBuilder.ToString(); - } - } - - /// - /// 文件工具类 - /// - internal static class FileUtility - { - /// - /// 读取文件的文本数据 - /// - public static string ReadAllText(string filePath) - { - if (File.Exists(filePath) == false) - return null; - return File.ReadAllText(filePath, Encoding.UTF8); - } - - /// - /// 读取文件的字节数据 - /// - public static byte[] ReadAllBytes(string filePath) - { - if (File.Exists(filePath) == false) - return null; - return File.ReadAllBytes(filePath); - } - - /// - /// 写入文本数据(会覆盖指定路径的文件) - /// - public static void WriteAllText(string filePath, string content) - { - // 创建文件夹路径 - CreateFileDirectory(filePath); - - byte[] bytes = Encoding.UTF8.GetBytes(content); - File.WriteAllBytes(filePath, bytes); //避免写入BOM标记 - } - - /// - /// 写入字节数据(会覆盖指定路径的文件) - /// - public static void WriteAllBytes(string filePath, byte[] data) - { - // 创建文件夹路径 - CreateFileDirectory(filePath); - - File.WriteAllBytes(filePath, data); - } - - /// - /// 创建文件的文件夹路径 - /// - public static void CreateFileDirectory(string filePath) - { - // 获取文件的文件夹路径 - string directory = Path.GetDirectoryName(filePath); - CreateDirectory(directory); - } - - /// - /// 创建文件夹路径 - /// - public static void CreateDirectory(string directory) - { - // If the directory doesn't exist, create it. - if (Directory.Exists(directory) == false) - Directory.CreateDirectory(directory); - } - - /// - /// 获取文件大小(字节数) - /// - public static long GetFileSize(string filePath) - { - FileInfo fileInfo = new FileInfo(filePath); - return fileInfo.Length; - } - } - - /// - /// 哈希工具类 - /// - public static class HashUtility - { - private static string ToString(byte[] hashBytes) - { - string result = BitConverter.ToString(hashBytes); - result = result.Replace("-", ""); - return result.ToLower(); - } - - #region SHA1 - /// - /// 获取字符串的Hash值 - /// - public static string StringSHA1(string str) - { - byte[] buffer = Encoding.UTF8.GetBytes(str); - return BytesSHA1(buffer); - } - - /// - /// 获取文件的Hash值 - /// - public static string FileSHA1(string filePath) - { - using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - return StreamSHA1(fs); - } - } - - /// - /// 获取文件的Hash值 - /// - public static string FileSHA1Safely(string filePath) - { - try - { - return FileSHA1(filePath); - } - catch (Exception ex) - { - YooLogger.Exception(ex); - return string.Empty; - } - } - - /// - /// 获取数据流的Hash值 - /// - public static string StreamSHA1(Stream stream) - { - // 说明:创建的是SHA1类的实例,生成的是160位的散列码 - HashAlgorithm hash = HashAlgorithm.Create(); - byte[] hashBytes = hash.ComputeHash(stream); - return ToString(hashBytes); - } - - /// - /// 获取字节数组的Hash值 - /// - public static string BytesSHA1(byte[] buffer) - { - // 说明:创建的是SHA1类的实例,生成的是160位的散列码 - HashAlgorithm hash = HashAlgorithm.Create(); - byte[] hashBytes = hash.ComputeHash(buffer); - return ToString(hashBytes); - } - #endregion - - #region MD5 - /// - /// 获取字符串的MD5 - /// - public static string StringMD5(string str) - { - byte[] buffer = Encoding.UTF8.GetBytes(str); - return BytesMD5(buffer); - } - - /// - /// 获取文件的MD5 - /// - public static string FileMD5(string filePath) - { - using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - return StreamMD5(fs); - } - } - - /// - /// 获取文件的MD5 - /// - public static string FileMD5Safely(string filePath) - { - try - { - return FileMD5(filePath); - } - catch (Exception ex) - { - YooLogger.Exception(ex); - return string.Empty; - } - } - - /// - /// 获取数据流的MD5 - /// - public static string StreamMD5(Stream stream) - { - MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider(); - byte[] hashBytes = provider.ComputeHash(stream); - return ToString(hashBytes); - } - - /// - /// 获取字节数组的MD5 - /// - public static string BytesMD5(byte[] buffer) - { - MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider(); - byte[] hashBytes = provider.ComputeHash(buffer); - return ToString(hashBytes); - } - #endregion - - #region CRC32 - /// - /// 获取字符串的CRC32 - /// - public static string StringCRC32(string str) - { - byte[] buffer = Encoding.UTF8.GetBytes(str); - return BytesCRC32(buffer); - } - public static uint StringCRC32Value(string str) - { - byte[] buffer = Encoding.UTF8.GetBytes(str); - return BytesCRC32Value(buffer); - } - - /// - /// 获取文件的CRC32 - /// - public static string FileCRC32(string filePath) - { - using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - return StreamCRC32(fs); - } - } - public static uint FileCRC32Value(string filePath) - { - using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - return StreamCRC32Value(fs); - } - } - - /// - /// 获取文件的CRC32 - /// - public static string FileCRC32Safely(string filePath) - { - try - { - return FileCRC32(filePath); - } - catch (Exception ex) - { - YooLogger.Exception(ex); - return string.Empty; - } - } - public static uint FileCRC32ValueSafely(string filePath) - { - try - { - return FileCRC32Value(filePath); - } - catch (Exception ex) - { - YooLogger.Exception(ex); - return 0; - } - } - - /// - /// 获取数据流的CRC32 - /// - public static string StreamCRC32(Stream stream) - { - CRC32Algorithm hash = new CRC32Algorithm(); - byte[] hashBytes = hash.ComputeHash(stream); - return ToString(hashBytes); - } - public static uint StreamCRC32Value(Stream stream) - { - CRC32Algorithm hash = new CRC32Algorithm(); - hash.ComputeHash(stream); - return hash.CRCValue; - } - - /// - /// 获取字节数组的CRC32 - /// - public static string BytesCRC32(byte[] buffer) - { - CRC32Algorithm hash = new CRC32Algorithm(); - byte[] hashBytes = hash.ComputeHash(buffer); - return ToString(hashBytes); - } - public static uint BytesCRC32Value(byte[] buffer) - { - CRC32Algorithm hash = new CRC32Algorithm(); - hash.ComputeHash(buffer); - return hash.CRCValue; - } - #endregion - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/YooAssets.cs b/Assets/YooAsset/Runtime/YooAssets.cs index b3d73cf4..ccf4c830 100644 --- a/Assets/YooAsset/Runtime/YooAssets.cs +++ b/Assets/YooAsset/Runtime/YooAssets.cs @@ -42,7 +42,7 @@ namespace YooAsset return; } - YooLogger.Logger = logger; + YooLogger.LoggerInstance = logger; // 创建驱动器 _isInitialized = true; diff --git a/Assets/YooAsset/Samples~/Extension Sample/Editor/CreateBuildinCatalog/CreateBuildinCatalogWindow.cs b/Assets/YooAsset/Samples~/Extension Sample/Editor/CreateBuildinCatalog/CreateBuildinCatalogWindow.cs index 6b52a644..e6ed9b0e 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Editor/CreateBuildinCatalog/CreateBuildinCatalogWindow.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Editor/CreateBuildinCatalog/CreateBuildinCatalogWindow.cs @@ -55,7 +55,7 @@ namespace YooAsset.Editor string packageName = directoryInfo.Name; try { - bool result = CatalogFileTools.CreateFile(null, packageName, packageRoot); //TODO 自行处理解密 + bool result = BuiltinFileCatalogTools.CreateFile(null, packageName, packageRoot); //TODO 自行处理解密 if (result == false) { Debug.LogError($"Create package {packageName} catalog file failed ! See the detail error in console !"); diff --git a/Assets/YooAsset/Samples~/Extension Sample/Editor/CreateBuildinCatalog/CreateEmptyCatalogWindow.cs b/Assets/YooAsset/Samples~/Extension Sample/Editor/CreateBuildinCatalog/CreateEmptyCatalogWindow.cs index 6cd2e902..6a57744c 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Editor/CreateBuildinCatalog/CreateEmptyCatalogWindow.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Editor/CreateBuildinCatalog/CreateEmptyCatalogWindow.cs @@ -47,7 +47,7 @@ namespace YooAsset.Editor { try { - bool result = CatalogFileTools.CreateEmptyFile(_packageName, string.Empty, outputPath); + bool result = BuiltinFileCatalogTools.CreateEmptyFile(_packageName, string.Empty, outputPath); if (result == false) { Debug.LogError($"Create package {_packageName} catalog file failed ! See the detail error in console !"); diff --git a/Assets/YooAsset/Samples~/Extension Sample/Editor/PackageComparator/PackageComparatorWindow.cs b/Assets/YooAsset/Samples~/Extension Sample/Editor/PackageComparator/PackageComparatorWindow.cs index e0d28f00..65ad69a4 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Editor/PackageComparator/PackageComparatorWindow.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Editor/PackageComparator/PackageComparatorWindow.cs @@ -106,11 +106,11 @@ namespace YooAsset.Editor // 加载补丁清单1 byte[] bytesData1 = FileUtility.ReadAllBytes(_manifestPath1); - PackageManifest manifest1 = PackageManifestTools.DeserializeFromBinary(bytesData1, null); //TODO 自行处理解密 + PackageManifest manifest1 = PackageManifestTools.DeserializeManifestFromBinary(bytesData1, null); //TODO 自行处理解密 // 加载补丁清单1 byte[] bytesData2 = FileUtility.ReadAllBytes(_manifestPath2); - PackageManifest manifest2 = PackageManifestTools.DeserializeFromBinary(bytesData2, null); //TODO 自行处理解密 + PackageManifest manifest2 = PackageManifestTools.DeserializeManifestFromBinary(bytesData2, null); //TODO 自行处理解密 // 拷贝文件列表 foreach (var bundle2 in manifest2.BundleList) diff --git a/Assets/YooAsset/Samples~/Extension Sample/Editor/PackageImporter/PackageImporterWindow.cs b/Assets/YooAsset/Samples~/Extension Sample/Editor/PackageImporter/PackageImporterWindow.cs index 7a1ba040..66fa09c3 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Editor/PackageImporter/PackageImporterWindow.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Editor/PackageImporter/PackageImporterWindow.cs @@ -71,7 +71,7 @@ namespace YooAsset.Editor // 加载补丁清单 byte[] bytesData = FileUtility.ReadAllBytes(manifestFilePath); - PackageManifest manifest = PackageManifestTools.DeserializeFromBinary(bytesData, null); //TODO 自行处理解密 + PackageManifest manifest = PackageManifestTools.DeserializeManifestFromBinary(bytesData, null); //TODO 自行处理解密 // 拷贝文件列表 int fileCount = 0; diff --git a/Assets/YooAsset/Samples~/Extension Sample/Editor/PreprocessBuild/PreprocessBuildCatalog.cs b/Assets/YooAsset/Samples~/Extension Sample/Editor/PreprocessBuild/PreprocessBuildCatalog.cs index e569c12c..c5f3b0f1 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Editor/PreprocessBuild/PreprocessBuildCatalog.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Editor/PreprocessBuild/PreprocessBuildCatalog.cs @@ -32,7 +32,7 @@ namespace YooAsset string pacakgeDirectory = subDirectory.FullName; try { - bool result = CatalogFileTools.CreateFile(null, packageName, pacakgeDirectory); //TODO 自行处理解密 + bool result = BuiltinFileCatalogTools.CreateFile(null, packageName, pacakgeDirectory); //TODO 自行处理解密 if (result == false) { Debug.LogError($"Create package {packageName} catalog file failed ! See the detail error in console !"); diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/CopyBuildinManifestOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/CopyBuildinManifestOperation.cs index 3b946780..813a87ba 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/CopyBuildinManifestOperation.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/CopyBuildinManifestOperation.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.IO; @@ -59,7 +59,7 @@ public class CopyBuildinManifestOperation : AsyncOperationBase { string sourcePath = GetBuildinHashFilePath(); string destPath = GetCacheHashFilePath(); - string url = DownloadSystemTools.ToLocalURL(sourcePath); + string url = DownloadSystemTools.ToLocalUrl(sourcePath); var args = new DownloadFileRequestArgs(url, destPath, 60, 0); _hashFileRequestOp = _backend.CreateFileRequest(args); _hashFileRequestOp.SendRequest(); @@ -68,7 +68,7 @@ public class CopyBuildinManifestOperation : AsyncOperationBase if (_hashFileRequestOp.IsDone == false) return; - if (_hashFileRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_hashFileRequestOp.Status == EDownloadRequestStatus.Succeeded) { _steps = ESteps.CheckManifestFile; } @@ -99,7 +99,7 @@ public class CopyBuildinManifestOperation : AsyncOperationBase { string sourcePath = GetBuildinManifestFilePath(); string destPath = GetCacheManifestFilePath(); - string url = DownloadSystemTools.ToLocalURL(sourcePath); + string url = DownloadSystemTools.ToLocalUrl(sourcePath); var args = new DownloadFileRequestArgs(url, destPath, 60, 0); _manifestFileRequestOp = _backend.CreateFileRequest(args); _manifestFileRequestOp.SendRequest(); @@ -108,7 +108,7 @@ public class CopyBuildinManifestOperation : AsyncOperationBase if (_manifestFileRequestOp.IsDone == false) return; - if (_manifestFileRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_manifestFileRequestOp.Status == EDownloadRequestStatus.Succeeded) { _steps = ESteps.Done; Status = EOperationStatus.Succeeded; diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/GetBuildinPackageVersionOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/GetBuildinPackageVersionOperation.cs index b597f1f3..56b62fb2 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/GetBuildinPackageVersionOperation.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/GetBuildinPackageVersionOperation.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.IO; @@ -45,7 +45,7 @@ public class GetBuildinPackageVersionOperation : AsyncOperationBase if (_versionFileRequestOp == null) { string filePath = GetBuildinPackageVersionFilePath(); - string url = DownloadSystemTools.ToLocalURL(filePath); + string url = DownloadSystemTools.ToLocalUrl(filePath); var args = new DownloadDataRequestArgs(url, 60, 0); _versionFileRequestOp = _backend.CreateTextRequest(args); _versionFileRequestOp.SendRequest(); @@ -54,7 +54,7 @@ public class GetBuildinPackageVersionOperation : AsyncOperationBase if (_versionFileRequestOp.IsDone == false) return; - if (_versionFileRequestOp.Status == EDownloadRequestStatus.Succeed) + if (_versionFileRequestOp.Status == EDownloadRequestStatus.Succeeded) { _steps = ESteps.Done; Status = EOperationStatus.Succeeded; diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadAssetsByTagOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadAssetsByTagOperation.cs index bf50fbe9..6d30471a 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadAssetsByTagOperation.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadAssetsByTagOperation.cs @@ -86,9 +86,9 @@ public class LoadAssetsByTagOperation : AsyncOperationBase where TObjec } else { - Debug.LogError($"{handle.LastError}"); + Debug.LogError($"{handle.Error}"); AssetObjects.Clear(); - SetFailed(handle.LastError); + SetFailed(handle.Error); return; } } diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadGameObjectOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadGameObjectOperation.cs index 3a71e59c..e67bc2ee 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadGameObjectOperation.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadGameObjectOperation.cs @@ -70,7 +70,7 @@ public class LoadGameObjectOperation : AsyncOperationBase if (_handle.Status != EOperationStatus.Succeeded) { - Error = _handle.LastError; + Error = _handle.Error; Status = EOperationStatus.Failed; _steps = ESteps.Done; } diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/SpriteAtlasLoader/SpriteAtlasLoader.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/SpriteAtlasLoader/SpriteAtlasLoader.cs index 28074422..03f6ea2d 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/SpriteAtlasLoader/SpriteAtlasLoader.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/SpriteAtlasLoader/SpriteAtlasLoader.cs @@ -33,7 +33,7 @@ public class SpriteAtlasLoader : MonoBehaviour var loadHandle = package.LoadAssetSync(atlasName); if (loadHandle.Status != EOperationStatus.Succeeded) { - Debug.LogWarning($"Failed to load sprite atlas : {atlasName} ! {loadHandle.LastError}"); + Debug.LogWarning($"Failed to load sprite atlas : {atlasName} ! {loadHandle.Error}"); return; } diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/T2_TestBuldinFileSystem.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/T2_TestBuldinFileSystem.cs index 0528ee0b..dd87c7fd 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/T2_TestBuldinFileSystem.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/T2_TestBuldinFileSystem.cs @@ -62,7 +62,6 @@ public class T2_TestBuldinFileSystem : IPrebuildSetup, IPostBuildCleanup var initParams = new OfflinePlayModeOptions(); var manifestServices = new TestRestoreManifest(); initParams.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(packageRoot); - initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.DISABLE_CATALOG_FILE, true); initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES, manifestServices); var initializeOp = package.InitializePackageAsync(initParams); yield return initializeOp; @@ -100,8 +99,6 @@ public class T2_TestBuldinFileSystem : IPrebuildSetup, IPostBuildCleanup // 初始化资源包 var initParams = new OfflinePlayModeOptions(); initParams.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(packageRoot); - initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, true); - initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.DISABLE_CATALOG_FILE, true); var initializeOp = package.InitializePackageAsync(initParams); yield return initializeOp; if (initializeOp.Status != EOperationStatus.Succeeded) diff --git a/Assets/YooAsset/Samples~/UniTask Sample/UniTask/Runtime/External/YooAsset/OperationHandleBaseExtensions.cs b/Assets/YooAsset/Samples~/UniTask Sample/UniTask/Runtime/External/YooAsset/OperationHandleBaseExtensions.cs index 864dc8ee..1ab37b7d 100644 --- a/Assets/YooAsset/Samples~/UniTask Sample/UniTask/Runtime/External/YooAsset/OperationHandleBaseExtensions.cs +++ b/Assets/YooAsset/Samples~/UniTask Sample/UniTask/Runtime/External/YooAsset/OperationHandleBaseExtensions.cs @@ -153,7 +153,7 @@ namespace Cysharp.Threading.Tasks _completed = true; if (_handle.Status == EOperationStatus.Failed) { - _core.TrySetException(new Exception(_handle.LastError)); + _core.TrySetException(new Exception(_handle.Error)); } else {