diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleSimulateBuilder.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleSimulateBuilder.cs index 4930d7df..965f952c 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleSimulateBuilder.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleSimulateBuilder.cs @@ -19,7 +19,7 @@ namespace YooAsset.Editor buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(); buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildPipeline = EBuildPipeline.EditorSimulateBuildPipeline.ToString(); - buildParameters.BuildBundleType = (int)EBuildBundleType.VirtualBundle; + buildParameters.BuildBundleType = (int)EBundleType.VirtualBundle; buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget; buildParameters.PackageName = packageName; buildParameters.PackageVersion = "Simulate"; diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParameters.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParameters.cs index 95db7e3c..673567d3 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParameters.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParameters.cs @@ -96,7 +96,7 @@ namespace YooAsset.Editor /// /// 资源包加密服务类 /// - public IEncryptionServices EncryptionServices; + public IBundleEncryptionServices EncryptionServices; /// /// 资源清单加密服务类 @@ -146,7 +146,7 @@ namespace YooAsset.Editor string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineIsNullOrEmpty, "Build pipeline is null or empty !"); throw new Exception(message); } - if (BuildBundleType == (int)EBuildBundleType.Unknown) + if (BuildBundleType == (int)EBundleType.Unknown) { string message = BuildLogger.GetErrorMessage(ErrorCode.BuildBundleTypeIsUnknown, $"Build bundle type is unknown {BuildBundleType} !"); throw new Exception(message); diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateCatalog.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateCatalog.cs index e408a20e..4cc79274 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; - CatalogTools.CreateCatalogFile(manifestServices, buildPackageName, buildinRootDirectory); + CatalogFileTools.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 af912fd6..eb00708b 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateManifest.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskCreateManifest.cs @@ -31,7 +31,7 @@ namespace YooAsset.Editor // 创建新补丁清单 PackageManifest manifest = new PackageManifest(); - manifest.FileVersion = ManifestDefine.FileVersion; + manifest.FileVersion = PackageManifestDefine.FileVersion; manifest.EnableAddressable = buildMapContext.Command.EnableAddressable; manifest.SupportExtensionless = buildMapContext.Command.SupportExtensionless; manifest.LocationToLower = buildMapContext.Command.LocationToLower; @@ -71,7 +71,7 @@ namespace YooAsset.Editor { string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion); string filePath = $"{packageOutputDirectory}/{fileName}"; - ManifestTools.SerializeToJson(filePath, manifest); + PackageManifestTools.SerializeToJson(filePath, manifest); BuildLogger.Log($"Create package manifest file: {filePath}"); } @@ -81,7 +81,7 @@ namespace YooAsset.Editor { string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion); packagePath = $"{packageOutputDirectory}/{fileName}"; - ManifestTools.SerializeToBinary(packagePath, manifest, buildParameters.ManifestProcessServices); + PackageManifestTools.SerializeToBinary(packagePath, manifest, buildParameters.ManifestProcessServices); packageHash = HashUtility.FileCRC32(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 = ManifestTools.DeserializeFromBinary(bytesData, buildParameters.ManifestRestoreServices); + manifestContext.Manifest = PackageManifestTools.DeserializeFromBinary(bytesData, buildParameters.ManifestRestoreServices); context.SetContextObject(manifestContext); } } diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskEncryption.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskEncryption.cs index 7e9369d7..051bb09f 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskEncryption.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskEncryption.cs @@ -24,7 +24,7 @@ namespace YooAsset.Editor string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); foreach (var bundleInfo in buildMapContext.Collection) { - EncryptFileInfo fileInfo = new EncryptFileInfo(); + BundleEncryptionContext fileInfo = new BundleEncryptionContext(); fileInfo.BundleName = bundleInfo.BundleName; fileInfo.FileLoadPath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; var encryptResult = encryptionServices.Encrypt(fileInfo); diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskUpdateBundleInfo.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskUpdateBundleInfo.cs index e9654680..1d6ea1a8 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskUpdateBundleInfo.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskUpdateBundleInfo.cs @@ -54,8 +54,8 @@ namespace YooAsset.Editor { string bundleName = bundleInfo.BundleName; string fileHash = bundleInfo.PackageFileHash; - string fileExtension = ManifestTools.GetRemoteBundleFileExtension(bundleName); - string fileName = ManifestTools.GetRemoteBundleFileName(outputNameStyle, bundleName, fileExtension, fileHash); + string fileExtension = PackageManifestTools.GetRemoteBundleFileExtension(bundleName); + string fileName = PackageManifestTools.GetRemoteBundleFileName(outputNameStyle, bundleName, fileExtension, fileHash); bundleInfo.PackageDestFilePath = $"{packageOutputDirectory}/{fileName}"; } } diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/ScriptableBuildPipeline/SBPBuildTasks.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/ScriptableBuildPipeline/ScriptableBuildTasks.cs similarity index 100% rename from Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/ScriptableBuildPipeline/SBPBuildTasks.cs rename to Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/ScriptableBuildPipeline/ScriptableBuildTasks.cs diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/ScriptableBuildPipeline/SBPBuildTasks.cs.meta b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/ScriptableBuildPipeline/ScriptableBuildTasks.cs.meta similarity index 100% rename from Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/ScriptableBuildPipeline/SBPBuildTasks.cs.meta rename to Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/ScriptableBuildPipeline/ScriptableBuildTasks.cs.meta diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/DefaultEncryptionServices.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/DefaultEncryptionServices.cs index 8cdb2b10..049a2988 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/DefaultEncryptionServices.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/DefaultEncryptionServices.cs @@ -1,9 +1,9 @@  namespace YooAsset.Editor { - public class EncryptionNone : IEncryptionServices + public class EncryptionNone : IBundleEncryptionServices { - public EncryptResult Encrypt(EncryptFileInfo fileInfo) + public BundleEncryptionResult Encrypt(BundleEncryptionContext fileInfo) { throw new System.NotImplementedException(); } diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/BuildPipelineViewerBase.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/BuildPipelineViewerBase.cs index 4b65e3b5..3c105b00 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/BuildPipelineViewerBase.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/BuildPipelineViewerBase.cs @@ -46,13 +46,13 @@ namespace YooAsset.Editor /// /// 创建资源包加密服务类实例 /// - protected IEncryptionServices CreateEncryptionServicesInstance() + protected IBundleEncryptionServices CreateEncryptionServicesInstance() { var className = AssetBundleBuilderSetting.GetPackageEncyptionServicesClassName(PackageName, PipelineName); - var classTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices)); + var classTypes = EditorTools.GetAssignableTypes(typeof(IBundleEncryptionServices)); var classType = classTypes.Find(x => x.FullName.Equals(className)); if (classType != null) - return (IEncryptionServices)Activator.CreateInstance(classType); + return (IBundleEncryptionServices)Activator.CreateInstance(classType); else return null; } @@ -184,7 +184,7 @@ namespace YooAsset.Editor protected PopupField CreateEncryptionServicesField(VisualElement container) { // 资源包加密服务类 - var classTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices)); + var classTypes = EditorTools.GetAssignableTypes(typeof(IBundleEncryptionServices)); if (classTypes.Count > 0) { var className = AssetBundleBuilderSetting.GetPackageEncyptionServicesClassName(PackageName, PipelineName); diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/BuiltinBuildPipeline/BuiltinBuildPipelineViewer.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/BuiltinBuildPipeline/BuiltinBuildPipelineViewer.cs index 48fcc692..62a447f8 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/BuiltinBuildPipeline/BuiltinBuildPipelineViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/BuiltinBuildPipeline/BuiltinBuildPipelineViewer.cs @@ -109,7 +109,7 @@ namespace YooAsset.Editor buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(); buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildPipeline = PipelineName.ToString(); - buildParameters.BuildBundleType = (int)EBuildBundleType.AssetBundle; + buildParameters.BuildBundleType = (int)EBundleType.AssetBundle; buildParameters.BuildTarget = BuildTarget; buildParameters.PackageName = PackageName; buildParameters.PackageVersion = _buildVersionField.value; diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/EditorSimulateBuildpipeline/EditorSimulateBuildPipelineViewer.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/EditorSimulateBuildpipeline/EditorSimulateBuildPipelineViewer.cs index be1dbd13..7e2ea295 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/EditorSimulateBuildpipeline/EditorSimulateBuildPipelineViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/EditorSimulateBuildpipeline/EditorSimulateBuildPipelineViewer.cs @@ -66,7 +66,7 @@ namespace YooAsset.Editor buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(); buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildPipeline = PipelineName.ToString(); - buildParameters.BuildBundleType = (int)EBuildBundleType.VirtualBundle; + buildParameters.BuildBundleType = (int)EBundleType.VirtualBundle; buildParameters.BuildTarget = BuildTarget; buildParameters.PackageName = PackageName; buildParameters.PackageVersion = _buildVersionField.value; diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/RawfileBuildpipeline/RawfileBuildPipelineViewer.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/RawfileBuildpipeline/RawfileBuildPipelineViewer.cs index af06e30d..dd78c58d 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/RawfileBuildpipeline/RawfileBuildPipelineViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/RawfileBuildpipeline/RawfileBuildPipelineViewer.cs @@ -103,7 +103,7 @@ namespace YooAsset.Editor buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(); buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildPipeline = PipelineName.ToString(); - buildParameters.BuildBundleType = (int)EBuildBundleType.RawBundle; + buildParameters.BuildBundleType = (int)EBundleType.RawBundle; buildParameters.BuildTarget = BuildTarget; buildParameters.PackageName = PackageName; buildParameters.PackageVersion = _buildVersionField.value; diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/ScriptableBuildPipeline/ScriptableBuildPipelineViewer.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/ScriptableBuildPipeline/ScriptableBuildPipelineViewer.cs index 0ca3183f..e3be3b05 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/ScriptableBuildPipeline/ScriptableBuildPipelineViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/VisualViewers/ScriptableBuildPipeline/ScriptableBuildPipelineViewer.cs @@ -109,7 +109,7 @@ namespace YooAsset.Editor buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(); buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildPipeline = PipelineName.ToString(); - buildParameters.BuildBundleType = (int)EBuildBundleType.AssetBundle; + buildParameters.BuildBundleType = (int)EBundleType.AssetBundle; buildParameters.BuildTarget = BuildTarget; buildParameters.PackageName = PackageName; buildParameters.PackageVersion = _buildVersionField.value; diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs index 4e3fef76..0c549e21 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs @@ -57,7 +57,7 @@ namespace YooAsset.Editor private EViewMode _viewMode; private string _searchKeyWord; - private DebugReport _currentReport; + private DiagnosticReport _currentReport; private RemotePlayerSession _currentPlayerSession; private double _lastRepaintTime = 0; @@ -147,9 +147,9 @@ namespace YooAsset.Editor EditorConnection.instance.Initialize(); EditorConnection.instance.RegisterConnection(OnHandleConnectionEvent); EditorConnection.instance.RegisterDisconnection(OnHandleDisconnectionEvent); - EditorConnection.instance.Register(RemoteDebuggerDefine.kMsgPlayerSendToEditor, OnHandlePlayerMessage); - RemoteEditorConnection.Instance.Initialize(); - RemoteEditorConnection.Instance.Register(RemoteDebuggerDefine.kMsgPlayerSendToEditor, OnHandlePlayerMessage); + EditorConnection.instance.Register(DiagnosticSystemDefine.PlayerToEditorMessageId, OnHandlePlayerMessage); + MockEditorConnection.Instance.Initialize(); + MockEditorConnection.Instance.Register(DiagnosticSystemDefine.PlayerToEditorMessageId, OnHandlePlayerMessage); } catch (Exception e) { @@ -161,8 +161,8 @@ namespace YooAsset.Editor // 远程调试 EditorConnection.instance.UnregisterConnection(OnHandleConnectionEvent); EditorConnection.instance.UnregisterDisconnection(OnHandleDisconnectionEvent); - EditorConnection.instance.Unregister(RemoteDebuggerDefine.kMsgPlayerSendToEditor, OnHandlePlayerMessage); - RemoteEditorConnection.Instance.Unregister(RemoteDebuggerDefine.kMsgPlayerSendToEditor); + EditorConnection.instance.Unregister(DiagnosticSystemDefine.PlayerToEditorMessageId, OnHandlePlayerMessage); + MockEditorConnection.Instance.Unregister(DiagnosticSystemDefine.PlayerToEditorMessageId); _playerSessions.Clear(); } public void Update() @@ -192,11 +192,11 @@ namespace YooAsset.Editor private void OnHandlePlayerMessage(MessageEventArgs args) { int playerId = args.playerId; - var debugReport = DebugReport.Deserialize(args.data); + var debugReport = DiagnosticReport.Deserialize(args.data); - if (debugReport.DebuggerVersion != RemoteDebuggerDefine.DebuggerVersion) + if (debugReport.DebuggerVersion != DiagnosticSystemDefine.DebuggerVersion) { - Debug.LogWarning($"Debugger versions are inconsistent : {debugReport.DebuggerVersion} != {RemoteDebuggerDefine.DebuggerVersion}"); + Debug.LogWarning($"Debugger versions are inconsistent : {debugReport.DebuggerVersion} != {DiagnosticSystemDefine.DebuggerVersion}"); return; } @@ -254,23 +254,23 @@ namespace YooAsset.Editor private void OnRecordToggleValueChange(ChangeEvent evt) { // 发送采集数据的命令 - RemoteCommand command = new RemoteCommand(); - command.CommandType = (int)ERemoteCommand.SampleAuto; - command.CommandParam = evt.newValue ? "open" : "close"; - byte[] data = RemoteCommand.Serialize(command); - EditorConnection.instance.Send(RemoteDebuggerDefine.kMsgEditorSendToPlayer, data); - RemoteEditorConnection.Instance.Send(RemoteDebuggerDefine.kMsgEditorSendToPlayer, data); + RemoteDebugCommand command = new RemoteDebugCommand(); + command.CommandType = (int)EDebugCommandType.AutoSampling; + command.Parameter = evt.newValue ? "open" : "close"; + byte[] data = RemoteDebugCommand.Serialize(command); + EditorConnection.instance.Send(DiagnosticSystemDefine.EditorToPlayerMessageId, data); + MockEditorConnection.Instance.Send(DiagnosticSystemDefine.EditorToPlayerMessageId, data); } private void SampleBtn_onClick() { // 发送采集数据的命令 - RemoteCommand command = new RemoteCommand(); - command.CommandType = (int)ERemoteCommand.SampleOnce; - command.CommandParam = string.Empty; - byte[] data = RemoteCommand.Serialize(command); - EditorConnection.instance.Send(RemoteDebuggerDefine.kMsgEditorSendToPlayer, data); - RemoteEditorConnection.Instance.Send(RemoteDebuggerDefine.kMsgEditorSendToPlayer, data); + RemoteDebugCommand command = new RemoteDebugCommand(); + command.CommandType = (int)EDebugCommandType.SampleOnce; + command.Parameter = string.Empty; + byte[] data = RemoteDebugCommand.Serialize(command); + EditorConnection.instance.Send(DiagnosticSystemDefine.EditorToPlayerMessageId, data); + MockEditorConnection.Instance.Send(DiagnosticSystemDefine.EditorToPlayerMessageId, data); } private void ExportBtn_clicked() { @@ -284,16 +284,16 @@ namespace YooAsset.Editor if (resultPath != null) { // 注意:排序保证生成配置的稳定性 - foreach (var packageData in _currentReport.PackageDatas) + foreach (var packageData in _currentReport.PackageDataList) { packageData.ProviderInfos.Sort(); foreach (var providerInfo in packageData.ProviderInfos) { - providerInfo.DependBundles.Sort(); + providerInfo.DependentBundles.Sort(); } } - string filePath = $"{resultPath}/{nameof(DebugReport)}_{_currentReport.FrameCount}.json"; + string filePath = $"{resultPath}/{nameof(DiagnosticReport)}_{_currentReport.FrameCount}.json"; string fileContent = JsonUtility.ToJson(_currentReport, true); FileUtility.WriteAllText(filePath, fileContent); Debug.Log($"Debug report file saved : {filePath}"); diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/RemotePlayerSession.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/RemotePlayerSession.cs index 68a990ce..83bd1d4d 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/RemotePlayerSession.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/RemotePlayerSession.cs @@ -7,7 +7,7 @@ namespace YooAsset.Editor { internal class RemotePlayerSession { - private readonly Queue _reports = new Queue(); + private readonly Queue _reports = new Queue(); /// /// 用户ID @@ -55,7 +55,7 @@ namespace YooAsset.Editor /// /// 添加一个调试报告 /// - public void AddDebugReport(DebugReport report) + public void AddDebugReport(DiagnosticReport report) { if (report == null) Debug.LogWarning("Invalid debug report data !"); @@ -68,7 +68,7 @@ namespace YooAsset.Editor /// /// 获取调试报告 /// - public DebugReport GetDebugReport(int rangeIndex) + public DiagnosticReport GetDebugReport(int rangeIndex) { if (_reports.Count == 0) return null; diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerAssetListViewer.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerAssetListViewer.cs index c41c82a9..51ba7146 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerAssetListViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerAssetListViewer.cs @@ -13,12 +13,12 @@ namespace YooAsset.Editor { private class ProviderTableData : DefaultTableData { - public DebugPackageData PackageData; - public DebugProviderInfo ProviderInfo; + public DiagnosticPackageData PackageData; + public DiagnosticProviderInfo ProviderInfo; } private class DependTableData : DefaultTableData { - public DebugBundleInfo BundleInfo; + public DiagnosticBundleInfo BundleInfo; } private VisualTreeAsset _visualAsset; @@ -125,13 +125,13 @@ namespace YooAsset.Editor _providerTableView.AddColumn(column); } - // BeginTime + // StartTime { var columnStyle = new ColumnStyle(100); columnStyle.Stretchable = false; columnStyle.Searchable = false; columnStyle.Sortable = true; - var column = new TableColumn("BeginTime", "Begin Time", columnStyle); + var column = new TableColumn("StartTime", "Start Time", columnStyle); column.MakeCell = () => { var label = new Label(); @@ -206,7 +206,8 @@ namespace YooAsset.Editor { StyleColor textColor; var providerTableData = data as ProviderTableData; - if (providerTableData.ProviderInfo.Status == EOperationStatus.Failed.ToString()) + if (providerTableData.ProviderInfo.Status == EOperationStatus.Failed.ToString() || + providerTableData.ProviderInfo.Status == EOperationStatus.Aborted.ToString()) textColor = new StyleColor(Color.yellow); else textColor = new StyleColor(Color.white); @@ -280,7 +281,8 @@ namespace YooAsset.Editor { StyleColor textColor; var dependTableData = data as DependTableData; - if (dependTableData.BundleInfo.Status == EOperationStatus.Failed.ToString()) + if (dependTableData.BundleInfo.Status == EOperationStatus.Failed.ToString() || + dependTableData.BundleInfo.Status == EOperationStatus.Aborted.ToString()) textColor = new StyleColor(Color.yellow); else textColor = new StyleColor(Color.white); @@ -296,7 +298,7 @@ namespace YooAsset.Editor /// /// 填充页面数据 /// - public void FillViewData(DebugReport debugReport) + public void FillViewData(DiagnosticReport debugReport) { // 清空旧数据 _providerTableView.ClearAll(false, true); @@ -304,7 +306,7 @@ namespace YooAsset.Editor // 填充数据源 _sourceDatas = new List(1000); - foreach (var packageData in debugReport.PackageDatas) + foreach (var packageData in debugReport.PackageDataList) { foreach (var providerInfo in packageData.ProviderInfos) { @@ -313,10 +315,10 @@ namespace YooAsset.Editor rowData.ProviderInfo = providerInfo; rowData.AddAssetPathCell("PackageName", packageData.PackageName); rowData.AddStringValueCell("AssetPath", providerInfo.AssetPath); - rowData.AddStringValueCell("SpawnScene", providerInfo.SpawnScene); - rowData.AddStringValueCell("BeginTime", providerInfo.BeginTime); - rowData.AddLongValueCell("LoadingTime", providerInfo.LoadingTime); - rowData.AddLongValueCell("RefCount", providerInfo.RefCount); + rowData.AddStringValueCell("SpawnScene", providerInfo.OriginScene); + rowData.AddStringValueCell("StartTime", providerInfo.StartTime); + rowData.AddLongValueCell("LoadingTime", providerInfo.ElapsedMS); + rowData.AddLongValueCell("RefCount", providerInfo.ReferenceCount); rowData.AddStringValueCell("Status", providerInfo.Status.ToString()); _sourceDatas.Add(rowData); } @@ -372,18 +374,18 @@ namespace YooAsset.Editor private void OnProviderTableViewSelectionChanged(ITableData data) { var providerTableData = data as ProviderTableData; - DebugPackageData packageData = providerTableData.PackageData; - DebugProviderInfo providerInfo = providerTableData.ProviderInfo; + DiagnosticPackageData packageData = providerTableData.PackageData; + DiagnosticProviderInfo providerInfo = providerTableData.ProviderInfo; // 填充依赖数据 - var sourceDatas = new List(providerInfo.DependBundles.Count); - foreach (var bundleName in providerInfo.DependBundles) + var sourceDatas = new List(providerInfo.DependentBundles.Count); + foreach (var bundleName in providerInfo.DependentBundles) { var dependBundleInfo = packageData.GetBundleInfo(bundleName); var rowData = new DependTableData(); rowData.BundleInfo = dependBundleInfo; rowData.AddStringValueCell("DependBundles", dependBundleInfo.BundleName); - rowData.AddLongValueCell("RefCount", dependBundleInfo.RefCount); + rowData.AddLongValueCell("RefCount", dependBundleInfo.ReferenceCount); rowData.AddStringValueCell("Status", dependBundleInfo.Status.ToString()); sourceDatas.Add(rowData); } diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs index d434e0af..0a96a0b9 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs @@ -13,16 +13,16 @@ namespace YooAsset.Editor { private class BundleTableData : DefaultTableData { - public DebugPackageData PackageData; - public DebugBundleInfo BundleInfo; + public DiagnosticPackageData PackageData; + public DiagnosticBundleInfo BundleInfo; } private class UsingTableData : DefaultTableData { - public DebugProviderInfo ProviderInfo; + public DiagnosticProviderInfo ProviderInfo; } private class ReferenceTableData : DefaultTableData { - public DebugBundleInfo BundleInfo; + public DiagnosticBundleInfo BundleInfo; } private VisualTreeAsset _visualAsset; @@ -151,7 +151,8 @@ namespace YooAsset.Editor { StyleColor textColor; var bundleTableData = data as BundleTableData; - if (bundleTableData.BundleInfo.Status == EOperationStatus.Failed.ToString()) + if (bundleTableData.BundleInfo.Status == EOperationStatus.Failed.ToString() || + bundleTableData.BundleInfo.Status == EOperationStatus.Aborted.ToString()) textColor = new StyleColor(Color.yellow); else textColor = new StyleColor(Color.white); @@ -208,13 +209,13 @@ namespace YooAsset.Editor _usingTableView.AddColumn(column); } - // BeginTime + // StartTime { var columnStyle = new ColumnStyle(100); columnStyle.Stretchable = false; columnStyle.Searchable = false; columnStyle.Sortable = true; - var column = new TableColumn("BeginTime", "Begin Time", columnStyle); + var column = new TableColumn("StartTime", "Start Time", columnStyle); column.MakeCell = () => { var label = new Label(); @@ -267,7 +268,8 @@ namespace YooAsset.Editor { StyleColor textColor; var usingTableData = data as UsingTableData; - if (usingTableData.ProviderInfo.Status == EOperationStatus.Failed.ToString()) + if (usingTableData.ProviderInfo.Status == EOperationStatus.Failed.ToString() || + usingTableData.ProviderInfo.Status == EOperationStatus.Aborted.ToString()) textColor = new StyleColor(Color.yellow); else textColor = new StyleColor(Color.white); @@ -341,7 +343,8 @@ namespace YooAsset.Editor { StyleColor textColor; var feferenceTableData = data as ReferenceTableData; - if (feferenceTableData.BundleInfo.Status == EOperationStatus.Failed.ToString()) + if (feferenceTableData.BundleInfo.Status == EOperationStatus.Failed.ToString() || + feferenceTableData.BundleInfo.Status == EOperationStatus.Aborted.ToString()) textColor = new StyleColor(Color.yellow); else textColor = new StyleColor(Color.white); @@ -357,7 +360,7 @@ namespace YooAsset.Editor /// /// 填充页面数据 /// - public void FillViewData(DebugReport debugReport) + public void FillViewData(DiagnosticReport debugReport) { // 清空旧数据 _bundleTableView.ClearAll(false, true); @@ -366,7 +369,7 @@ namespace YooAsset.Editor // 填充数据源 _sourceDatas = new List(1000); - foreach (var packageData in debugReport.PackageDatas) + foreach (var packageData in debugReport.PackageDataList) { foreach (var bundleInfo in packageData.BundleInfos) { @@ -375,7 +378,7 @@ namespace YooAsset.Editor rowData.BundleInfo = bundleInfo; rowData.AddAssetPathCell("PackageName", packageData.PackageName); rowData.AddStringValueCell("BundleName", bundleInfo.BundleName); - rowData.AddLongValueCell("RefCount", bundleInfo.RefCount); + rowData.AddLongValueCell("RefCount", bundleInfo.ReferenceCount); rowData.AddStringValueCell("Status", bundleInfo.Status.ToString()); _sourceDatas.Add(rowData); } @@ -443,16 +446,16 @@ namespace YooAsset.Editor var sourceDatas = new List(1000); foreach (var providerInfo in packageData.ProviderInfos) { - foreach (var dependBundleName in providerInfo.DependBundles) + foreach (var dependBundleName in providerInfo.DependentBundles) { if (dependBundleName == selectBundleInfo.BundleName) { var rowData = new UsingTableData(); rowData.ProviderInfo = providerInfo; rowData.AddStringValueCell("UsingAssets", providerInfo.AssetPath); - rowData.AddStringValueCell("SpawnScene", providerInfo.SpawnScene); - rowData.AddStringValueCell("BeginTime", providerInfo.BeginTime); - rowData.AddLongValueCell("RefCount", providerInfo.RefCount); + rowData.AddStringValueCell("SpawnScene", providerInfo.OriginScene); + rowData.AddStringValueCell("StartTime", providerInfo.StartTime); + rowData.AddLongValueCell("RefCount", providerInfo.ReferenceCount); rowData.AddStringValueCell("Status", providerInfo.Status); sourceDatas.Add(rowData); break; @@ -466,13 +469,13 @@ namespace YooAsset.Editor // 填充ReferenceTableView { var sourceDatas = new List(1000); - foreach (string referenceBundleName in selectBundleInfo.ReferenceBundles) + foreach (string referenceBundleName in selectBundleInfo.ReferencedByBundles) { var bundleInfo = packageData.GetBundleInfo(referenceBundleName); var rowData = new ReferenceTableData(); rowData.BundleInfo = bundleInfo; rowData.AddStringValueCell("BundleName", bundleInfo.BundleName); - rowData.AddLongValueCell("RefCount", bundleInfo.RefCount); + rowData.AddLongValueCell("RefCount", bundleInfo.ReferenceCount); rowData.AddStringValueCell("Status", bundleInfo.Status.ToString()); sourceDatas.Add(rowData); } diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerOperationListViewer.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerOperationListViewer.cs index 4b5aa990..9af278ce 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerOperationListViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerOperationListViewer.cs @@ -13,8 +13,8 @@ namespace YooAsset.Editor { private class OperationTableData : DefaultTableData { - public DebugPackageData PackageData; - public DebugOperationInfo OperationInfo; + public DiagnosticPackageData PackageData; + public DiagnosticOperationInfo OperationInfo; } private VisualTreeAsset _visualAsset; @@ -147,13 +147,13 @@ namespace YooAsset.Editor _operationTableView.AddColumn(column); } - // BeginTime + // StartTime { var columnStyle = new ColumnStyle(100); columnStyle.Stretchable = false; columnStyle.Searchable = false; columnStyle.Sortable = true; - var column = new TableColumn("BeginTime", "Begin Time", columnStyle); + var column = new TableColumn("StartTime", "Start Time", columnStyle); column.MakeCell = () => { var label = new Label(); @@ -168,14 +168,14 @@ namespace YooAsset.Editor _operationTableView.AddColumn(column); } - // ProcessTime + // ElapsedMS { var columnStyle = new ColumnStyle(130); columnStyle.Stretchable = false; columnStyle.Searchable = false; columnStyle.Sortable = true; columnStyle.Units = "ms"; - var column = new TableColumn("ProcessTime", "Process Time", columnStyle); + var column = new TableColumn("ElapsedMS", "Elapsed MS", columnStyle); column.MakeCell = () => { var label = new Label(); @@ -207,7 +207,8 @@ namespace YooAsset.Editor { StyleColor textColor; var operationTableData = data as OperationTableData; - if (operationTableData.OperationInfo.Status == EOperationStatus.Failed.ToString()) + if (operationTableData.OperationInfo.Status == EOperationStatus.Failed.ToString() || + operationTableData.OperationInfo.Status == EOperationStatus.Aborted.ToString()) textColor = new StyleColor(Color.yellow); else textColor = new StyleColor(Color.white); @@ -259,19 +260,19 @@ namespace YooAsset.Editor _bottomToolbar.Add(button); } - // BeginTime + // StartTime { ToolbarButton button = new ToolbarButton(); - button.text = "BeginTime"; + button.text = "StartTime"; button.style.flexGrow = 0; button.style.width = 100; _bottomToolbar.Add(button); } - // ProcessTime + // ElapsedMS { ToolbarButton button = new ToolbarButton(); - button.text = "ProcessTime (ms)"; + button.text = "ElapsedMS"; button.style.flexGrow = 0; button.style.width = 130; _bottomToolbar.Add(button); @@ -299,7 +300,7 @@ namespace YooAsset.Editor /// /// 填充页面数据 /// - public void FillViewData(DebugReport debugReport) + public void FillViewData(DiagnosticReport debugReport) { // 清空旧数据 _operationTableView.ClearAll(false, true); @@ -308,7 +309,7 @@ namespace YooAsset.Editor // 填充数据源 _sourceDatas = new List(1000); - foreach (var packageData in debugReport.PackageDatas) + foreach (var packageData in debugReport.PackageDataList) { foreach (var operationInfo in packageData.OperationInfos) { @@ -319,8 +320,8 @@ namespace YooAsset.Editor rowData.AddStringValueCell("OperationName", operationInfo.OperationName); rowData.AddLongValueCell("Priority", operationInfo.Priority); rowData.AddDoubleValueCell("Progress", operationInfo.Progress); - rowData.AddStringValueCell("BeginTime", operationInfo.BeginTime); - rowData.AddLongValueCell("LoadingTime", operationInfo.ProcessTime); + rowData.AddStringValueCell("StartTime", operationInfo.StartTime); + rowData.AddLongValueCell("ElapsedMS", operationInfo.ElapsedMS); rowData.AddStringValueCell("Status", operationInfo.Status.ToString()); rowData.AddStringValueCell("Desc", operationInfo.OperationDesc); _sourceDatas.Add(rowData); @@ -377,8 +378,8 @@ namespace YooAsset.Editor private void OnOperationTableViewSelectionChanged(ITableData data) { var operationTableData = data as OperationTableData; - DebugPackageData packageData = operationTableData.PackageData; - DebugOperationInfo operationInfo = operationTableData.OperationInfo; + DiagnosticPackageData packageData = operationTableData.PackageData; + DiagnosticOperationInfo operationInfo = operationTableData.OperationInfo; TreeNode rootNode = new TreeNode(operationInfo); FillTreeData(operationInfo, rootNode); @@ -408,20 +409,20 @@ namespace YooAsset.Editor container.Add(label); } - // BeginTime + // StartTime { var label = new Label(); - label.name = "BeginTime"; + label.name = "StartTime"; label.style.flexGrow = 0f; label.style.width = 100; label.style.unityTextAlign = TextAnchor.MiddleLeft; container.Add(label); } - // ProcessTime + // ElapsedMS { var label = new Label(); - label.name = "ProcessTime"; + label.name = "ElapsedMS"; label.style.flexGrow = 0f; label.style.width = 130; label.style.unityTextAlign = TextAnchor.MiddleLeft; @@ -450,7 +451,7 @@ namespace YooAsset.Editor } private void BindTreeViewItem(VisualElement container, object userData) { - var operationInfo = (DebugOperationInfo)userData; + var operationInfo = (DiagnosticOperationInfo)userData; // OperationName { @@ -464,22 +465,23 @@ namespace YooAsset.Editor label.text = operationInfo.Progress.ToString(); } - // BeginTime + // StartTime { - var label = container.Q /// - /// 推荐由后端自动设置 Range 请求头:"bytes={ResumeFromBytes}-"。 + /// 推荐由后端自动设置 Range 请求头:"bytes={ResumeOffset}-"。 /// - public readonly long ResumeFromBytes; + public readonly long ResumeOffset; /// /// 自定义请求头(可选) /// + /// + /// 使用 AddRequestHeader 方法添加请求头。 + /// 注意:相同 key 重复添加会抛出异常。 + /// public Dictionary Headers; /// /// 构造文件下载请求参数 /// + /// 请求地址 + /// 文件保存路径 + /// 响应超时时间(秒),0 表示不应用超时 + /// 看门狗超时时间(秒),0 表示禁用 + /// 是否追加写入文件(用于断点续传) + /// 中止时是否删除目标文件 + /// 断点续传的起始字节位置 public DownloadFileRequestArgs( string url, string savePath, int timeout, - int watchdogTime, + int watchdogTimeout, bool appendToFile = false, bool removeFileOnAbort = true, - long resumeFromBytes = 0) + long resumeOffset = 0) { URL = url; SavePath = savePath; Timeout = timeout; - WatchdogTime = watchdogTime; + WatchdogTimeout = watchdogTimeout; AppendToFile = appendToFile; RemoveFileOnAbort = removeFileOnAbort; - ResumeFromBytes = resumeFromBytes; + ResumeOffset = resumeOffset; Headers = null; } @@ -281,23 +145,28 @@ namespace YooAsset /// 2. 每次接收到下载数据时,看门狗计时器会重置。 /// 3. 若在设定的时间范围内未收到任何数据,任务将被自动终止。 /// - public readonly int WatchdogTime; + public readonly int WatchdogTimeout; /// /// 自定义请求头(可选) /// + /// + /// 使用 AddRequestHeader 方法添加请求头。 + /// 注意:相同 key 重复添加会抛出异常。 + /// public Dictionary Headers; /// /// 构造数据下载请求参数 /// /// 请求地址 - /// 通用请求参数 - public DownloadDataRequestArgs(string url, int timeout, int watchdogTime) + /// 响应超时时间(秒),0 表示不应用超时 + /// 看门狗超时时间(秒),0 表示禁用 + public DownloadDataRequestArgs(string url, int timeout, int watchdogTimeout) { URL = url; Timeout = timeout; - WatchdogTime = watchdogTime; + WatchdogTimeout = watchdogTimeout; Headers = null; } @@ -345,7 +214,7 @@ namespace YooAsset /// 2. 每次接收到下载数据时,看门狗计时器会重置。 /// 3. 若在设定的时间范围内未收到任何数据,任务将被自动终止。 /// - public readonly int WatchdogTime; + public readonly int WatchdogTimeout; /// /// 禁用 Unity 的网络缓存 @@ -368,22 +237,32 @@ namespace YooAsset /// /// 自定义请求头(可选) /// + /// + /// 使用 AddRequestHeader 方法添加请求头。 + /// 注意:相同 key 重复添加会抛出异常。 + /// public Dictionary Headers; /// /// 构造 AssetBundle 下载请求参数 /// + /// 请求地址 + /// 响应超时时间(秒),0 表示不应用超时 + /// 看门狗超时时间(秒),0 表示禁用 + /// 是否禁用 Unity 内置缓存 + /// 文件哈希(启用缓存时必须提供) + /// Unity CRC 校验值 public DownloadAssetBundleRequestArgs( string url, int timeout, - int watchdogTime, + int watchdogTimeout, bool disableUnityWebCache = true, string fileHash = null, uint unityCrc = 0) { URL = url; Timeout = timeout; - WatchdogTime = watchdogTime; + WatchdogTimeout = watchdogTimeout; DisableUnityWebCache = disableUnityWebCache; FileHash = fileHash; UnityCRC = unityCrc; diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemDefine.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/DownloadRequestArgs.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemDefine.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/DownloadRequestArgs.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemTools.cs similarity index 71% rename from Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs rename to Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemTools.cs index 626840b6..145aad0c 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemTools.cs @@ -1,14 +1,20 @@ -using UnityEngine.Networking; -using UnityEngine; namespace YooAsset { - internal class DownloadSystemHelper + /// + /// 下载系统工具类 + /// + /// + /// 提供跨平台的 URL 转换和判断功能。 + /// + internal class DownloadSystemTools { /// - /// 获取WWW加载本地资源的路径 + /// 转换为本地文件请求地址 /// - public static string ConvertToWWWPath(string path) + /// 本地文件路径 + /// 可用于 UnityWebRequest 的文件协议 URL + public static string ToLocalURL(string path) { string url; @@ -57,17 +63,19 @@ namespace YooAsset #elif UNITY_STANDALONE_LINUX url = StringUtility.Format("file:///root/{0}", path); #else - throw new System.NotSupportedException($"[{nameof(DownloadSystemHelper.ConvertToWWWPath)}] not implemented platform: {UnityEngine.Application.platform}"); + throw new System.NotSupportedException($"Platform '{UnityEngine.Application.platform}' is not supported."); #endif - // For some special cases when users have special characters in their devices, url paths can not be identified correctly. + // 处理特殊字符:用户设备路径可能包含特殊字符导致 URL 无法正确识别 return url.Replace("+", "%2B").Replace("#", "%23").Replace("?", "%3F"); } /// - /// 是否请求的本地文件 + /// 判断是否为本地文件 URL /// - public static bool IsRequestLocalFile(string url) + /// 要判断的 URL + /// 如果是本地文件 URL 返回 true,否则返回 false + public static bool IsLocalFileURL(string url) { //TODO UNITY_STANDALONE_OSX平台目前无法确定 diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemTools.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemTools.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/EDownloadRequestStatus.cs b/Assets/YooAsset/Runtime/DownloadSystem/EDownloadRequestStatus.cs new file mode 100644 index 00000000..357ad62b --- /dev/null +++ b/Assets/YooAsset/Runtime/DownloadSystem/EDownloadRequestStatus.cs @@ -0,0 +1,37 @@ + +namespace YooAsset +{ + /// + /// 下载请求状态 + /// + internal enum EDownloadRequestStatus + { + /// + /// 未开始 + /// + None, + + /// + /// 进行中 + /// + Running, + + /// + /// 已成功 + /// + Succeed, + + /// + /// 已失败 + /// + Failed, + + /// + /// 已中止 + /// + /// + /// 可能由用户主动调用 AbortRequest() 或看门狗超时触发。 + /// + Aborted, + } +} diff --git a/Assets/YooAsset/Runtime/DownloadSystem/EDownloadRequestStatus.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/EDownloadRequestStatus.cs.meta new file mode 100644 index 00000000..4ed1bcda --- /dev/null +++ b/Assets/YooAsset/Runtime/DownloadSystem/EDownloadRequestStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8f72782591f59046a052b566bfa865e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Interface/IDownloadRequest.cs b/Assets/YooAsset/Runtime/DownloadSystem/Interface/IDownloadRequest.cs index 4feac65b..f7712ac6 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Interface/IDownloadRequest.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Interface/IDownloadRequest.cs @@ -6,7 +6,7 @@ namespace YooAsset /// 可轮询的下载请求接口 /// /// - /// 上层通常会在每帧轮询 Status IsDone,并在完成后读取结果。 + /// 上层通常在每帧检查 IsDone 属性,完成后读取结果并调用 Dispose() 释放资源。 /// internal interface IDownloadRequest : IDisposable { @@ -18,6 +18,9 @@ namespace YooAsset /// /// 是否完成(成功/失败/中止) /// + /// + /// 注意:访问此属性时会自动调用 PollingRequest() 进行轮询。 + /// bool IsDone { get; } /// diff --git a/Assets/YooAsset/Runtime/DownloadSystem/README.md b/Assets/YooAsset/Runtime/DownloadSystem/README.md index 1f857d95..c227d511 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/README.md +++ b/Assets/YooAsset/Runtime/DownloadSystem/README.md @@ -4,6 +4,10 @@ DownloadSystem 是 YooAsset 资源管理系统的**底层网络下载层**,负责处理所有 HTTP 网络请求。该模块提供了统一的下载接口抽象,支持文件下载、断点续传、并发请求(由上层调度)、看门狗监控等功能。 +### 可见性说明 + +DownloadSystem 属于 YooAsset Runtime 的内部基础模块,目录内大多数类型为 `internal`(仅供 YooAsset Runtime 内部程序集使用)。本文示例以"模块内部调用方式"展示;业务层建议优先通过 `ResourcePackage / FileSystem / ResourceManager` 等上层接口使用下载能力,避免直接依赖本模块的内部类型。 + ### 核心职责 - HTTP/HTTPS 文件下载 @@ -16,7 +20,7 @@ DownloadSystem 是 YooAsset 资源管理系统的**底层网络下载层**,负 ## 边界与上层协作 -DownloadSystem 的职责是提供“可替换后端 + 统一请求接口 + 轮询式生命周期”的基础能力: +DownloadSystem 的职责是提供"可替换后端 + 统一请求接口 + 轮询式生命周期"的基础能力: - **本模块不负责并发队列/限流调度**:并发通常由上层同时创建多个 request 并自行控制并发数。 - **本模块不负责重试/回退策略**:失败后的重试、切换 CDN、降级等策略通常由上层系统实现。 @@ -41,20 +45,20 @@ DownloadSystem 的职责是提供“可替换后端 + 统一请求接口 + 轮 ``` ┌─────────────────────────────────────────────────────────┐ -│ 上层调用者 │ -│ (FileSystem / ResourceManager) │ +│ 上层调用者 │ +│ (FileSystem / ResourceManager) │ └─────────────────────────┬───────────────────────────────┘ │ ┌─────────────────────────▼───────────────────────────────┐ -│ IDownloadBackend │ +│ IDownloadBackend │ │ (后端接口) │ -│ 定义网络库合约,工厂模式创建请求 │ +│ 定义网络库合约,工厂模式创建请求 │ └─────────────────────────┬───────────────────────────────┘ │ ┌─────────────────────────▼───────────────────────────────┐ -│ IDownloadRequest │ +│ IDownloadRequest │ │ (请求接口) │ -│ 轮询式生命周期管理,状态机驱动 │ +│ 轮询式生命周期管理,状态机驱动 │ └─────────────────────────┬───────────────────────────────┘ │ ┌─────────────────────────▼───────────────────────────────┐ @@ -79,22 +83,23 @@ DownloadSystem/ │ ├── IDownloadBackend.cs # 后端接口(工厂模式) │ └── IDownloadRequest.cs # 请求接口层次结构 │ -├── DefaultDownloadBackend/ # 默认后端实现 +├── UnityWebBackend/ # 默认后端实现 │ ├── UnityWebRequestBackend.cs # UnityWebRequest 后端 │ └── UnityWebRequestCreator.cs # UnityWebRequest 创建委托 │ -├── DefaultDownloadRequest/ # 默认请求实现 -│ ├── UnityWebRequestDownloaderBase.cs # 基础下载器(抽象类) -│ ├── UnityWebRequestFileDownloader.cs # 文件下载器 -│ ├── UnityWebRequestHeadDownloader.cs # HEAD 请求器 -│ ├── UnityWebRequestBytesDownloader.cs # 字节下载器 -│ ├── UnityWebRequestTextDownloader.cs # 文本下载器 -│ ├── UnityWebRequestAssetBundleDownloader.cs # AssetBundle 下载器 -│ └── VirtualFileDownloader.cs # 模拟下载器(编辑器用) +├── UnityWebRequest/ # 默认请求实现 +│ ├── UnityWebRequestBase.cs # 基础下载器(抽象类) +│ ├── UnityWebRequestFile.cs # 文件下载器 +│ ├── UnityWebRequestHead.cs # HEAD 请求器 +│ ├── UnityWebRequestBytes.cs # 字节下载器 +│ ├── UnityWebRequestText.cs # 文本下载器 +│ ├── UnityWebRequestAssetBundle.cs # AssetBundle 下载器 +│ └── SimulateRequestFile.cs # 模拟下载器(编辑器用) │ -├── DownloadSystemDefine.cs # 枚举、结构体定义 -├── DownloadSystemHelper.cs # 工具函数 -└── WebRequestCounter.cs # 请求失败计数器 +├── EDownloadRequestStatus.cs # 下载请求状态枚举 +├── DownloadRequestArgs.cs # 请求参数结构体定义 +├── DownloadSystemTools.cs # 工具函数 +└── DownloadFailureCounter.cs # 请求失败计数器 ``` --- @@ -106,7 +111,7 @@ DownloadSystem/ 定义网络库实现的合约,通过工厂方法创建各类下载请求。 ```csharp -public interface IDownloadBackend +internal interface IDownloadBackend : IDisposable { /// /// 后端标识名称(用于日志/调试) @@ -133,13 +138,13 @@ public interface IDownloadBackend 所有下载请求的通用接口,定义生命周期和状态管理。 ```csharp -public interface IDownloadRequest : IDisposable +internal interface IDownloadRequest : IDisposable { // 元信息 string URL { get; } // 生命周期 - bool IsDone { get; } // 每次访问自动轮询 + bool IsDone { get; } // 访问时自动调用 PollingRequest() EDownloadRequestStatus Status { get; } // 进度跟踪 @@ -159,9 +164,9 @@ public interface IDownloadRequest : IDisposable ### 专化请求接口 -| 接口 | 用途 | 特有属性 | +| 接口 | 用途 | 特有能力 | |------|------|----------| -| `IDownloadHeadRequest` | HEAD 请求,获取响应头 | `ETag`, `LastModified`, `ContentLength`, `ContentType` | +| `IDownloadHeadRequest` | HEAD 请求,获取响应头 | `ETag`, `LastModified`, `ContentLength`, `ContentType`, `GetResponseHeader(name)` | | `IDownloadFileRequest` | 文件下载到本地 | `SavePath` | | `IDownloadBytesRequest` | 下载到内存(字节数组) | `byte[] Result` | | `IDownloadTextRequest` | 下载文本内容 | `string Result` | @@ -174,7 +179,7 @@ public interface IDownloadRequest : IDisposable ### 请求状态枚举 ```csharp -public enum EDownloadRequestStatus +internal enum EDownloadRequestStatus { None, // 未开始 Running, // 进行中 @@ -189,71 +194,97 @@ public enum EDownloadRequestStatus #### DownloadFileRequestArgs(文件下载参数) ```csharp -public struct DownloadFileRequestArgs +internal struct DownloadFileRequestArgs { - public string URL; // 请求地址 - public int Timeout; // 响应超时(秒),0=无限制 - public int WatchdogTime; // 看门狗超时(秒) + public readonly string URL; // 请求地址 + public readonly int Timeout; // 响应超时(秒),0=不应用超时 + public readonly int WatchdogTimeout; // 看门狗超时(秒),0=禁用 - public string SavePath; // 文件保存路径 - public bool AppendToFile; // 追加写入(断点续传) - public bool RemoveFileOnAbort; // 中止时删除文件 - public long ResumeFromBytes; // 断点续传起始位置 + public readonly string SavePath; // 文件保存路径 + public readonly bool AppendToFile; // 追加写入(断点续传) + public readonly bool RemoveFileOnAbort; // 中止时删除文件 + public readonly long ResumeOffset; // 断点续传起始位置(>0 时推荐由后端设置 Range 头) - public Dictionary Headers; // 自定义请求头 + public Dictionary Headers; // 自定义请求头(可选) + + public DownloadFileRequestArgs( + string url, + string savePath, + int timeout, + int watchdogTimeout, + bool appendToFile = false, + bool removeFileOnAbort = true, + long resumeOffset = 0); + + /// + /// 添加请求头(注意:相同 key 重复添加会抛异常) + /// + public void AddRequestHeader(string name, string value); } ``` #### DownloadDataRequestArgs(数据下载参数) ```csharp -public struct DownloadDataRequestArgs +internal struct DownloadDataRequestArgs { - public string URL; // 请求地址 - public int Timeout; // 响应超时(秒) - public int WatchdogTime; // 看门狗超时(秒) - public Dictionary Headers; // 自定义请求头 + public readonly string URL; // 请求地址 + public readonly int Timeout; // 响应超时(秒),0=不应用超时 + public readonly int WatchdogTimeout; // 看门狗超时(秒),0=禁用 + public Dictionary Headers; // 自定义请求头(可选) + + public DownloadDataRequestArgs(string url, int timeout, int watchdogTimeout); + + /// + /// 添加请求头(注意:相同 key 重复添加会抛异常) + /// + public void AddRequestHeader(string name, string value); } ``` #### DownloadAssetBundleRequestArgs(AssetBundle 下载参数) ```csharp -public struct DownloadAssetBundleRequestArgs +internal struct DownloadAssetBundleRequestArgs { - public string URL; // 请求地址 - public int Timeout; // 响应超时 - public int WatchdogTime; // 看门狗超时 + public readonly string URL; // 请求地址 + public readonly int Timeout; // 响应超时(秒),0=不应用超时 + public readonly int WatchdogTimeout; // 看门狗超时(秒),0=禁用 - public bool DisableUnityWebCache; // 禁用 Unity 缓存(推荐 true) - public string FileHash; // 文件哈希(缓存启用时需要) - public uint UnityCRC; // Unity CRC 校验值 + public readonly bool DisableUnityWebCache; // 禁用 Unity 缓存(默认 true) + public readonly string FileHash; // 文件哈希(缓存启用时需要,且不能为空) + public readonly uint UnityCRC; // Unity CRC 校验值 - public Dictionary Headers; + public Dictionary Headers; // 自定义请求头(可选) + + public DownloadAssetBundleRequestArgs( + string url, + int timeout, + int watchdogTimeout, + bool disableUnityWebCache = true, + string fileHash = null, + uint unityCrc = 0); + + /// + /// 添加请求头(注意:相同 key 重复添加会抛异常) + /// + public void AddRequestHeader(string name, string value); } ``` #### DownloadSimulateRequestArgs(模拟下载参数) ```csharp -public struct DownloadSimulateRequestArgs +internal struct DownloadSimulateRequestArgs { - public string URL; // 标识符 - public long FileSize; // 模拟文件大小 - public long DownloadSpeed; // 模拟速度(字节/秒),默认 1MB/s + public readonly string URL; // 标识符 + public readonly long FileSize; // 模拟文件大小 + public readonly long DownloadSpeed; // 模拟速度(字节/秒),默认 1MB/s + + public DownloadSimulateRequestArgs(string url, long fileSize, long downloadSpeed = 1024 * 1024); } ``` -### 回调数据结构体 - -| 结构体 | 用途 | 关键字段 | -|--------|------|----------| -| `DownloaderFinishData` | 下载完成回调 | `PackageName`, `Succeed` | -| `DownloadUpdateData` | 进度更新回调 | `Progress`, `TotalDownloadBytes`, `CurrentDownloadBytes` | -| `DownloadErrorData` | 下载错误回调 | `FileName`, `ErrorInfo` | -| `DownloadFileData` | 文件完成回调 | `FileName`, `FileSize` | -| `ImportFileInfo` | 导入文件元数据 | `FilePath`, `BundleName`, `BundleGUID` | - --- ## 核心类说明 @@ -278,7 +309,7 @@ UnityWebRequestCreator creator = (url, method) => IDownloadBackend backend = new UnityWebRequestBackend(creator); ``` -### UnityWebRequestDownloaderBase +### UnityWebRequestBase 抽象基类,封装所有下载器的通用逻辑。 @@ -300,12 +331,12 @@ None ──► SendRequest() ──► Running ──► PollingRequest() ── | 下载器 | 实现接口 | 使用场景 | |--------|----------|----------| -| `UnityWebRequestFileDownloader` | `IDownloadFileRequest` | 大文件下载到本地 | -| `UnityWebRequestHeadDownloader` | `IDownloadHeadRequest` | 检查资源信息 | -| `UnityWebRequestBytesDownloader` | `IDownloadBytesRequest` | 小文件内存加载 | -| `UnityWebRequestTextDownloader` | `IDownloadTextRequest` | 文本文件下载 | -| `UnityWebRequestAssetBundleDownloader` | `IDownloadAssetBundleRequest` | AB 包下载加载 | -| `VirtualFileDownloader` | `IDownloadFileRequest` | 编辑器模拟下载 | +| `UnityWebRequestFile` | `IDownloadFileRequest` | 大文件下载到本地 | +| `UnityWebRequestHead` | `IDownloadHeadRequest` | 检查资源信息 | +| `UnityWebRequestBytes` | `IDownloadBytesRequest` | 小文件内存加载 | +| `UnityWebRequestText` | `IDownloadTextRequest` | 文本文件下载 | +| `UnityWebRequestAssetBundle` | `IDownloadAssetBundleRequest` | AB 包下载加载 | +| `SimulateRequestFile` | `IDownloadFileRequest` | 编辑器模拟下载 | --- @@ -314,36 +345,38 @@ None ──► SendRequest() ──► Running ──► PollingRequest() ── ### 基础文件下载 ```csharp -// 1. 创建后端和请求 IDownloadBackend backend = new UnityWebRequestBackend(); -var args = new DownloadFileRequestArgs( - url: "https://example.com/file.zip", - savePath: "/path/to/save/file.zip", - timeout: 30, - watchdogTime: 0); -IDownloadFileRequest request = backend.CreateFileRequest(args); - -// 2. 发起并轮询 -request.SendRequest(); -while (!request.IsDone) +IDownloadFileRequest request = null; +try { - await Task.Yield(); - // 可选:显示进度 - float progress = request.DownloadProgress; -} + // 1. 创建请求 + var args = new DownloadFileRequestArgs( + url: "https://example.com/file.zip", + savePath: "/path/to/save/file.zip", + timeout: 30, + watchdogTimeout: 0); + request = backend.CreateFileRequest(args); -// 3. 检查结果 -if (request.Status == EDownloadRequestStatus.Succeed) -{ - Debug.Log("下载成功"); -} -else -{ - Debug.LogError($"下载失败: {request.Error}"); -} + // 2. 发起并轮询 + request.SendRequest(); + while (!request.IsDone) + { + await Task.Yield(); + float progress = request.DownloadProgress; + } -// 4. 清理资源 -request.Dispose(); + // 3. 检查结果 + if (request.Status == EDownloadRequestStatus.Succeed) + Debug.Log("下载成功"); + else + Debug.LogError($"下载失败: {request.Error}"); +} +finally +{ + // 4. 清理资源 + request?.Dispose(); + backend.Dispose(); +} ``` ### 断点续传 @@ -356,10 +389,10 @@ var args = new DownloadFileRequestArgs( url: url, savePath: savePath, timeout: 30, - watchdogTime: 0, - appendToFile: true, // 追加写入 - removeFileOnAbort: false, // 中止时保留文件 - resumeFromBytes: existingFileSize); // 断点位置 + watchdogTimeout: 0, + appendToFile: true, // 追加写入 + removeFileOnAbort: false, // 中止时保留文件 + resumeOffset: existingFileSize); // 断点位置 IDownloadFileRequest request = backend.CreateFileRequest(args); request.SendRequest(); @@ -373,7 +406,7 @@ var args = new DownloadFileRequestArgs( url: url, savePath: path, timeout: 30, - watchdogTime: 30); // 30秒无数据自动中止 + watchdogTimeout: 30); // 30秒无数据自动中止 IDownloadFileRequest request = backend.CreateFileRequest(args); request.SendRequest(); @@ -396,7 +429,7 @@ if (request.Status == EDownloadRequestStatus.Aborted) var args = new DownloadDataRequestArgs( url: "https://example.com/file.zip", timeout: 30, - watchdogTime: 0); + watchdogTimeout: 0); IDownloadHeadRequest request = backend.CreateHeadRequest(args); request.SendRequest(); @@ -422,7 +455,7 @@ if (request.Status == EDownloadRequestStatus.Succeed) var args = new DownloadDataRequestArgs( url: "https://example.com/data.json", timeout: 30, - watchdogTime: 0); + watchdogTimeout: 0); IDownloadBytesRequest request = backend.CreateBytesRequest(args); request.SendRequest(); @@ -495,7 +528,7 @@ IDownloadBackend (接口) │ └── 未收到数据 ──► 计时器累加 │ - └── 超过 WatchdogTime ──► AbortRequest() + └── 超过 WatchdogTimeout ──► AbortRequest() ``` --- @@ -511,44 +544,49 @@ IDownloadRequest (基础接口) ├── IDownloadTextRequest (文本下载) └── IDownloadAssetBundleRequest (AssetBundle 下载) -UnityWebRequestDownloaderBase (抽象基类) +UnityWebRequestBase (抽象基类) │ - ├── UnityWebRequestFileDownloader ──► IDownloadFileRequest - ├── UnityWebRequestHeadDownloader ──► IDownloadHeadRequest - ├── UnityWebRequestBytesDownloader ──► IDownloadBytesRequest - ├── UnityWebRequestTextDownloader ──► IDownloadTextRequest - └── UnityWebRequestAssetBundleDownloader ──► IDownloadAssetBundleRequest + ├── UnityWebRequestFile ──► IDownloadFileRequest + ├── UnityWebRequestHead ──► IDownloadHeadRequest + ├── UnityWebRequestBytes ──► IDownloadBytesRequest + ├── UnityWebRequestText ──► IDownloadTextRequest + └── UnityWebRequestAssetBundle ──► IDownloadAssetBundleRequest -VirtualFileDownloader (独立实现) ──► IDownloadFileRequest +SimulateRequestFile (独立实现) ──► IDownloadFileRequest ``` --- ## 工具类 -### DownloadSystemHelper +### DownloadSystemTools -提供跨平台的工具函数: +提供跨平台的 URL 转换和判断功能: -| 方法 | 说明 | -|------|------| -| `ConvertToWWWPath()` | 转换本地路径为 WWW 协议 URL | -| `IsRequestLocalFile()` | 判断是否本地文件请求 | +| 方法 | 参数 | 返回值 | 说明 | +|------|------|--------|------| +| `ToLocalURL(path)` | `string path` 本地文件路径 | 可用于 UnityWebRequest 的文件协议 URL | 转换本地路径为文件协议 URL(自动处理特殊字符) | +| `IsLocalFileURL(url)` | `string url` 要判断的 URL | `bool` 是否为本地文件 URL | 判断 URL 是否为 `file:` 或 `jar:file:` 协议 | -### WebRequestCounter +### DownloadFailureCounter -请求失败计数器,用于诊断统计: +网络请求失败计数器(诊断用): -- 线程安全:内部使用 `Dictionary` 且未加锁,约定只在主线程调用;如需多线程统计请在外层加锁或改造实现 -- Key 规则:`$"{packageName}_{eventName}"` -- 统计口径:**仅统计网络请求失败**(`IDownloadRequest.Status != Succeed` 时记录),不统计内容为空、校验失败、解析失败等业务层失败 +- **线程安全**:内部使用 `Dictionary` 且未加锁,约定只在 Unity 主线程调用;如需在多线程/回调线程调用,请在外层加锁或改为并发容器实现 +- **Key 格式**:`$"{packageName}_{eventName}"` +- **统计口径**:**仅统计网络请求失败**(`IDownloadRequest.Status != Succeed` 时记录),不统计内容为空、校验失败、解析失败等业务层失败 + +| 方法 | 参数 | 返回值 | 说明 | +|------|------|--------|------| +| `RecordFailure(packageName, eventName)` | `string packageName` 资源包名称, `string eventName` 事件名称 | `void` | 记录一次失败 | +| `GetFailureCount(packageName, eventName)` | `string packageName` 资源包名称, `string eventName` 事件名称 | `int` 失败次数(未记录过返回 0) | 获取失败次数 | ```csharp // 记录失败 -WebRequestCounter.RecordRequestFailed(packageName, eventName); +DownloadFailureCounter.RecordFailure(packageName, eventName); // 查询失败次数 -int count = WebRequestCounter.GetRequestFailedCount(packageName, eventName); +int count = DownloadFailureCounter.GetFailureCount(packageName, eventName); ``` --- @@ -557,6 +595,7 @@ int count = WebRequestCounter.GetRequestFailedCount(packageName, eventName); 1. **资源释放**:使用完毕后务必调用 `Dispose()` 释放资源 - `AbortRequest()` 仅用于中止请求与切换状态,不等同于释放资源;无论成功/失败/中止都需要 `Dispose()` + - 第三方 `IDownloadBackend` 可能持有原生资源/线程/连接池等,上层在不再使用时也应调用 `backend.Dispose()` - 推荐使用 `try/finally` 确保释放(尤其是上层可能提前中止的场景) 2. **断点续传**:需要服务器支持 `Range` 请求头和 `206 Partial Content` 响应 - 若服务端不支持 Range 仍返回 200,全量内容可能会被追加写入,导致文件损坏 @@ -565,3 +604,4 @@ int count = WebRequestCounter.GetRequestFailedCount(packageName, eventName); 5. **驱动更新**:部分第三方网络库实现的 backend 可能需要每帧调用 `IDownloadBackend.Update()` 进行驱动 6. **中止语义**:`Aborted` 可能来自用户主动 `AbortRequest()` 或看门狗超时;中止场景下 `HttpCode/Error` 可能为默认值(例如 0/空) 7. **线程安全**:所有下载请求的创建和轮询应在主线程进行 +8. **模拟下载器**:`SimulateRequestFile` 仅用于模拟进度,不会落盘,且 `SavePath` 始终为 `null`;成功时 `HttpCode` 固定为 `200` diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadBackend.meta b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebBackend.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadBackend.meta rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebBackend.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadBackend/UnityWebRequestBackend.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebBackend/UnityWebRequestBackend.cs similarity index 86% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadBackend/UnityWebRequestBackend.cs rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebBackend/UnityWebRequestBackend.cs index 394aaed9..5e052294 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadBackend/UnityWebRequestBackend.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebBackend/UnityWebRequestBackend.cs @@ -64,7 +64,7 @@ namespace YooAsset /// public IDownloadHeadRequest CreateHeadRequest(DownloadDataRequestArgs args) { - return new UnityWebRequestHeadDownloader(args, _webRequestCreator); + return new UnityWebRequestHead(args, _webRequestCreator); } /// @@ -72,7 +72,7 @@ namespace YooAsset /// public IDownloadFileRequest CreateFileRequest(DownloadFileRequestArgs args) { - return new UnityWebRequestFileDownloader(args, _webRequestCreator); + return new UnityWebRequestFile(args, _webRequestCreator); } /// @@ -80,7 +80,7 @@ namespace YooAsset /// public IDownloadBytesRequest CreateBytesRequest(DownloadDataRequestArgs args) { - return new UnityWebRequestBytesDownloader(args, _webRequestCreator); + return new UnityWebRequestBytes(args, _webRequestCreator); } /// @@ -88,7 +88,7 @@ namespace YooAsset /// public IDownloadTextRequest CreateTextRequest(DownloadDataRequestArgs args) { - return new UnityWebRequestTextDownloader(args, _webRequestCreator); + return new UnityWebRequestText(args, _webRequestCreator); } /// @@ -96,7 +96,7 @@ namespace YooAsset /// public IDownloadAssetBundleRequest CreateAssetBundleRequest(DownloadAssetBundleRequestArgs args) { - return new UnityWebRequestAssetBundleDownloader(args, _webRequestCreator); + return new UnityWebRequestAssetBundle(args, _webRequestCreator); } /// @@ -104,7 +104,7 @@ namespace YooAsset /// public IDownloadFileRequest CreateSimulateRequest(DownloadSimulateRequestArgs args) { - return new VirtualFileDownloader(args); + return new SimulateRequestFile(args); } } } diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadBackend/UnityWebRequestBackend.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebBackend/UnityWebRequestBackend.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadBackend/UnityWebRequestBackend.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebBackend/UnityWebRequestBackend.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebBackend/UnityWebRequestCreator.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebBackend/UnityWebRequestCreator.cs new file mode 100644 index 00000000..dca8a8f9 --- /dev/null +++ b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebBackend/UnityWebRequestCreator.cs @@ -0,0 +1,16 @@ +using UnityEngine.Networking; + +namespace YooAsset +{ + /// + /// 自定义 UnityWebRequest 创建委托 + /// + /// + /// 用于自定义 UnityWebRequest 的创建方式,例如添加证书验证、代理设置等。 + /// 通过 UnityWebRequestBackend 构造函数传入。 + /// + /// 请求地址 + /// HTTP 方法(如 GET、HEAD) + /// 自定义配置的 UnityWebRequest 实例 + public delegate UnityWebRequest UnityWebRequestCreator(string url, string method); +} diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadBackend/UnityWebRequestCreator.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebBackend/UnityWebRequestCreator.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadBackend/UnityWebRequestCreator.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebBackend/UnityWebRequestCreator.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest.meta b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest.meta rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/VirtualFileDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/SimulateRequestFile.cs similarity index 84% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/VirtualFileDownloader.cs rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/SimulateRequestFile.cs index 96010902..78287e81 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/VirtualFileDownloader.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/SimulateRequestFile.cs @@ -9,10 +9,10 @@ namespace YooAsset /// 用于编辑器模式下模拟下载进度,不进行实际网络请求。 /// 根据配置的下载速度模拟进度变化。 /// - internal sealed class VirtualFileDownloader : IDownloadFileRequest + internal sealed class SimulateRequestFile : IDownloadFileRequest { private readonly DownloadSimulateRequestArgs _args; - private double _lastUpdateTime; + private double _lastTickTime; /// /// 文件保存路径(模拟下载不需要) @@ -72,7 +72,7 @@ namespace YooAsset /// 构造模拟下载器 /// /// 模拟下载参数 - public VirtualFileDownloader(DownloadSimulateRequestArgs args) + public SimulateRequestFile(DownloadSimulateRequestArgs args) { _args = args; URL = args.URL; @@ -87,7 +87,7 @@ namespace YooAsset if (Status == EDownloadRequestStatus.None) { Status = EDownloadRequestStatus.Running; - _lastUpdateTime = GetUnityEngineRealtime(); + _lastTickTime = TimeUtility.RealtimeSinceStartup; } } @@ -99,9 +99,9 @@ namespace YooAsset if (Status != EDownloadRequestStatus.Running) return; - double currentTime = GetUnityEngineRealtime(); - double deltaTime = currentTime - _lastUpdateTime; - _lastUpdateTime = currentTime; + double currentTime = TimeUtility.RealtimeSinceStartup; + double deltaTime = currentTime - _lastTickTime; + _lastTickTime = currentTime; // 计算本帧下载的字节数 long downloadBytes = (long)(_args.DownloadSpeed * deltaTime); @@ -137,14 +137,5 @@ namespace YooAsset public void Dispose() { } - - private double GetUnityEngineRealtime() - { -#if UNITY_2020_3_OR_NEWER - return UnityEngine.Time.realtimeSinceStartupAsDouble; -#else - return UnityEngine.Time.realtimeSinceStartup; -#endif - } } } diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/VirtualFileDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/SimulateRequestFile.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/VirtualFileDownloader.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/SimulateRequestFile.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestAssetBundleDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestAssetBundle.cs similarity index 86% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestAssetBundleDownloader.cs rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestAssetBundle.cs index feea31a9..cbe1c17d 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestAssetBundleDownloader.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestAssetBundle.cs @@ -11,7 +11,7 @@ namespace YooAsset /// 下载并加载 Unity AssetBundle 资源包。 /// 支持 Unity 内置缓存机制和 CRC 校验。 /// - internal sealed class UnityWebRequestAssetBundleDownloader : UnityWebRequestDownloaderBase, IDownloadAssetBundleRequest + internal sealed class UnityWebRequestAssetBundle : UnityWebRequestBase, IDownloadAssetBundleRequest { private readonly DownloadAssetBundleRequestArgs _args; private DownloadHandlerAssetBundle _downloadHandler; @@ -26,7 +26,7 @@ namespace YooAsset /// /// AssetBundle 下载参数 /// UnityWebRequest 创建器(可选) - public UnityWebRequestAssetBundleDownloader(DownloadAssetBundleRequestArgs args, UnityWebRequestCreator webRequestCreator) + public UnityWebRequestAssetBundle(DownloadAssetBundleRequestArgs args, UnityWebRequestCreator webRequestCreator) : base(args.URL, webRequestCreator) { _args = args; @@ -38,10 +38,10 @@ namespace YooAsset protected override void CreateWebRequest() { _downloadHandler = CreateAssetBundleDownloadHandler(); - _webRequest = CreateUnityWebRequestGet(URL); + _webRequest = CreateGetRequest(URL); _webRequest.downloadHandler = _downloadHandler; _webRequest.disposeDownloadHandlerOnDispose = true; - ApplyRequestOptions(_args.Timeout, _args.WatchdogTime, _args.Headers); + ConfigureRequest(_args.Timeout, _args.WatchdogTimeout, _args.Headers); } /// @@ -76,7 +76,7 @@ namespace YooAsset else { if (string.IsNullOrEmpty(_args.FileHash)) - throw new YooInternalException("File hash is null or empty !"); + throw new YooInternalException("File hash is null or empty."); // 使用 Unity 缓存 // 说明:The file hash defining the version of the asset bundle. diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestAssetBundleDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestAssetBundle.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestAssetBundleDownloader.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestAssetBundle.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestDownloaderBase.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestBase.cs similarity index 84% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestDownloaderBase.cs rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestBase.cs index f6e6f680..92790b40 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestDownloaderBase.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestBase.cs @@ -11,16 +11,16 @@ namespace YooAsset /// 封装 UnityWebRequest 的通用下载逻辑,包括状态管理、进度追踪等。 /// 子类只需实现 CreateWebRequest 方法来创建特定类型的下载请求。 /// - internal abstract class UnityWebRequestDownloaderBase : IDownloadRequest + internal abstract class UnityWebRequestBase : IDownloadRequest { private readonly UnityWebRequestCreator _webRequestCreator; protected UnityWebRequest _webRequest; // 看门狗相关 - private int _watchdogTime = 0; + private int _watchdogTimeout = 0; private bool _watchdogAborted = false; private long _lastDownloadBytes = -1; - private double _lastGetDataTime; + private double _lastDataReceivedTime; #region 接口实现 /// @@ -76,7 +76,7 @@ namespace YooAsset /// /// 请求地址 /// UnityWebRequest 创建器(可选) - protected UnityWebRequestDownloaderBase(string url, UnityWebRequestCreator webRequestCreator) + protected UnityWebRequestBase(string url, UnityWebRequestCreator webRequestCreator) { URL = url; _webRequestCreator = webRequestCreator; @@ -109,7 +109,7 @@ namespace YooAsset catch (Exception ex) { Status = EDownloadRequestStatus.Failed; - Error = $"[{GetType().Name}] Failed to create web request : {ex.Message}"; + Error = $"[{GetType().Name}] Failed to create web request: {ex.Message}"; } } } @@ -125,7 +125,7 @@ namespace YooAsset DownloadProgress = _webRequest.downloadProgress; DownloadedBytes = (long)_webRequest.downloadedBytes; - CheckWatchdog(); + TickWatchdog(); if (_webRequest.isDone == false) return; @@ -144,12 +144,12 @@ namespace YooAsset else { Status = EDownloadRequestStatus.Failed; - Error = $"[{GetType().Name}] URL: {URL} - 错误: {_webRequest.error}"; + Error = $"[{GetType().Name}] URL: {URL} - Error: {_webRequest.error}"; OnRequestFailed(); } // 完成后释放 - DisposeWebRequest(); + CleanupWebRequest(); } /// @@ -170,7 +170,7 @@ namespace YooAsset /// public void Dispose() { - DisposeWebRequest(); + CleanupWebRequest(); } @@ -199,7 +199,7 @@ namespace YooAsset /// /// 请求地址 /// UnityWebRequest 实例 - protected UnityWebRequest CreateUnityWebRequestGet(string requestUrl) + protected UnityWebRequest CreateGetRequest(string requestUrl) { if (_webRequestCreator != null) return _webRequestCreator.Invoke(requestUrl, UnityWebRequest.kHttpVerbGET); @@ -212,7 +212,7 @@ namespace YooAsset /// /// 请求地址 /// UnityWebRequest 实例 - protected UnityWebRequest CreateUnityWebRequestHead(string requestUrl) + protected UnityWebRequest CreateHeadRequest(string requestUrl) { if (_webRequestCreator != null) return _webRequestCreator.Invoke(requestUrl, UnityWebRequest.kHttpVerbHEAD); @@ -221,21 +221,21 @@ namespace YooAsset } /// - /// 应用通用请求参数 + /// 配置通用请求参数 /// - protected void ApplyRequestOptions(int timeout, int watchdogTime, Dictionary headers) + protected void ConfigureRequest(int timeout, int watchdogTimeout, Dictionary headers) { if (_webRequest == null) - throw new YooInternalException("Web request is null !"); + throw new YooInternalException("Web request is null."); // 设置看门狗超时时间 - _watchdogTime = watchdogTime; + _watchdogTimeout = watchdogTimeout; // 设置响应的超时时间 if (timeout > 0) _webRequest.timeout = timeout; - // 设置响应头 + // 设置请求头 if (headers != null) { foreach (var header in headers) @@ -248,28 +248,23 @@ namespace YooAsset /// /// 检测看门狗 /// - private void CheckWatchdog() + private void TickWatchdog() { - if (_watchdogTime == 0) + if (_watchdogTimeout == 0) return; if (_watchdogAborted) return; -#if UNITY_2020_3_OR_NEWER - double realtimeSinceStartup = UnityEngine.Time.realtimeSinceStartupAsDouble; -#else - double realtimeSinceStartup = UnityEngine.Time.realtimeSinceStartup; -#endif - + double realtimeSinceStartup = TimeUtility.RealtimeSinceStartup; if (DownloadedBytes != _lastDownloadBytes) { _lastDownloadBytes = DownloadedBytes; - _lastGetDataTime = realtimeSinceStartup; + _lastDataReceivedTime = realtimeSinceStartup; } else { - double deltaTime = realtimeSinceStartup - _lastGetDataTime; - if (deltaTime > _watchdogTime) + double deltaTime = realtimeSinceStartup - _lastDataReceivedTime; + if (deltaTime > _watchdogTimeout) { _watchdogAborted = true; AbortRequest(); //看门狗终止网络请求 @@ -278,9 +273,9 @@ namespace YooAsset } /// - /// 释放资源 + /// 清理 WebRequest 资源 /// - private void DisposeWebRequest() + private void CleanupWebRequest() { if (_webRequest != null) { diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestDownloaderBase.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestBase.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestDownloaderBase.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestBase.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestBytesDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestBytes.cs similarity index 77% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestBytesDownloader.cs rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestBytes.cs index db887947..9cc25068 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestBytesDownloader.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestBytes.cs @@ -9,7 +9,7 @@ namespace YooAsset /// /// 将下载内容保存到内存中的字节数组。 /// - internal sealed class UnityWebRequestBytesDownloader : UnityWebRequestDownloaderBase, IDownloadBytesRequest + internal sealed class UnityWebRequestBytes : UnityWebRequestBase, IDownloadBytesRequest { private readonly DownloadDataRequestArgs _args; @@ -23,7 +23,7 @@ namespace YooAsset /// /// 数据下载参数 /// UnityWebRequest 创建器(可选) - public UnityWebRequestBytesDownloader(DownloadDataRequestArgs args, UnityWebRequestCreator webRequestCreator) + public UnityWebRequestBytes(DownloadDataRequestArgs args, UnityWebRequestCreator webRequestCreator) : base(args.URL, webRequestCreator) { _args = args; @@ -35,10 +35,10 @@ namespace YooAsset protected override void CreateWebRequest() { var handler = new DownloadHandlerBuffer(); - _webRequest = CreateUnityWebRequestGet(URL); + _webRequest = CreateGetRequest(URL); _webRequest.downloadHandler = handler; _webRequest.disposeDownloadHandlerOnDispose = true; - ApplyRequestOptions(_args.Timeout, _args.WatchdogTime, _args.Headers); + ConfigureRequest(_args.Timeout, _args.WatchdogTimeout, _args.Headers); } /// diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestBytesDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestBytes.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestBytesDownloader.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestBytes.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestFileDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestFile.cs similarity index 76% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestFileDownloader.cs rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestFile.cs index 342a96ae..602b3a9f 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestFileDownloader.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestFile.cs @@ -9,7 +9,7 @@ namespace YooAsset /// /// 将下载内容保存到本地文件,支持断点续传和追加写入。 /// - internal sealed class UnityWebRequestFileDownloader : UnityWebRequestDownloaderBase, IDownloadFileRequest + internal sealed class UnityWebRequestFile : UnityWebRequestBase, IDownloadFileRequest { private readonly DownloadFileRequestArgs _args; @@ -26,7 +26,7 @@ namespace YooAsset /// /// 文件下载参数 /// UnityWebRequest 创建器(可选) - public UnityWebRequestFileDownloader(DownloadFileRequestArgs args, UnityWebRequestCreator webRequestCreator) + public UnityWebRequestFile(DownloadFileRequestArgs args, UnityWebRequestCreator webRequestCreator) : base(args.URL, webRequestCreator) { _args = args; @@ -40,17 +40,17 @@ namespace YooAsset var handler = new DownloadHandlerFile(_args.SavePath, _args.AppendToFile); handler.removeFileOnAbort = _args.RemoveFileOnAbort; - _webRequest = CreateUnityWebRequestGet(URL); + _webRequest = CreateGetRequest(URL); _webRequest.downloadHandler = handler; _webRequest.disposeDownloadHandlerOnDispose = true; // 断点续传:设置 Range 请求头 - if (_args.ResumeFromBytes > 0) + if (_args.ResumeOffset > 0) { - _webRequest.SetRequestHeader("Range", $"bytes={_args.ResumeFromBytes}-"); + _webRequest.SetRequestHeader("Range", $"bytes={_args.ResumeOffset}-"); } - ApplyRequestOptions(_args.Timeout, _args.WatchdogTime, _args.Headers); + ConfigureRequest(_args.Timeout, _args.WatchdogTimeout, _args.Headers); } } } diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestFileDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestFile.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestFileDownloader.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestFile.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestHeadDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestHead.cs similarity index 91% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestHeadDownloader.cs rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestHead.cs index 62e13004..de8a1e81 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestHeadDownloader.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestHead.cs @@ -11,7 +11,7 @@ namespace YooAsset /// 仅获取响应头信息,不下载实际内容。 /// 用于检查资源是否存在、获取资源大小、检查缓存有效性等场景。 /// - internal sealed class UnityWebRequestHeadDownloader : UnityWebRequestDownloaderBase, IDownloadHeadRequest + internal sealed class UnityWebRequestHead : UnityWebRequestBase, IDownloadHeadRequest { // 注意:缓存响应头(因为 WebRequest 释放后无法获取) private Dictionary _cachedResponseHeaders; @@ -69,7 +69,7 @@ namespace YooAsset /// /// 数据下载参数 /// UnityWebRequest 创建器(可选) - public UnityWebRequestHeadDownloader(DownloadDataRequestArgs args, UnityWebRequestCreator webRequestCreator) + public UnityWebRequestHead(DownloadDataRequestArgs args, UnityWebRequestCreator webRequestCreator) : base(args.URL, webRequestCreator) { _args = args; @@ -98,9 +98,9 @@ namespace YooAsset /// protected override void CreateWebRequest() { - _webRequest = CreateUnityWebRequestHead(URL); + _webRequest = CreateHeadRequest(URL); _webRequest.downloadHandler = null; // HEAD 请求不需要 DownloadHandler - ApplyRequestOptions(_args.Timeout, _args.WatchdogTime, _args.Headers); + ConfigureRequest(_args.Timeout, _args.WatchdogTimeout, _args.Headers); } /// diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestHeadDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestHead.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestHeadDownloader.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestHead.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestTextDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestText.cs similarity index 78% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestTextDownloader.cs rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestText.cs index ee4a0e06..b054e2a0 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestTextDownloader.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestText.cs @@ -9,7 +9,7 @@ namespace YooAsset /// /// 将下载内容解析为 UTF-8 文本字符串。 /// - internal sealed class UnityWebRequestTextDownloader : UnityWebRequestDownloaderBase, IDownloadTextRequest + internal sealed class UnityWebRequestText : UnityWebRequestBase, IDownloadTextRequest { private readonly DownloadDataRequestArgs _args; @@ -23,7 +23,7 @@ namespace YooAsset /// /// 数据下载参数 /// UnityWebRequest 创建器(可选) - public UnityWebRequestTextDownloader(DownloadDataRequestArgs args, UnityWebRequestCreator webRequestCreator) + public UnityWebRequestText(DownloadDataRequestArgs args, UnityWebRequestCreator webRequestCreator) : base(args.URL, webRequestCreator) { _args = args; @@ -35,10 +35,10 @@ namespace YooAsset protected override void CreateWebRequest() { var handler = new DownloadHandlerBuffer(); - _webRequest = CreateUnityWebRequestGet(URL); + _webRequest = CreateGetRequest(URL); _webRequest.downloadHandler = handler; _webRequest.disposeDownloadHandlerOnDispose = true; - ApplyRequestOptions(_args.Timeout, _args.WatchdogTime, _args.Headers); + ConfigureRequest(_args.Timeout, _args.WatchdogTimeout, _args.Headers); } /// diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestTextDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestText.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DefaultDownloadRequest/UnityWebRequestTextDownloader.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequest/UnityWebRequestText.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs index 587674ff..9d30d07e 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs @@ -36,14 +36,6 @@ namespace YooAsset { return _fileSystem.GetBundleFilePath(_packageBundle); } - public override byte[] ReadBundleFileData() - { - return _fileSystem.ReadBundleFileData(_packageBundle); - } - public override string ReadBundleFileText() - { - return _fileSystem.ReadBundleFileText(_packageBundle); - } public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) { diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadAllAssetsOperation.cs index f5bd7f35..d8393a8f 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadAllAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadAllAssetsOperation.cs @@ -39,7 +39,7 @@ namespace YooAsset if (_assetBundle == null) { _steps = ESteps.Done; - Error = $"The bundle {_packageBundle.BundleName} has been destroyed due to unity engine bugs !"; + Error = $"The bundle {_packageBundle.BundleName} has been destroyed due to unity engine bugs."; Status = EOperationStatus.Failed; return; } @@ -49,7 +49,7 @@ namespace YooAsset if (_steps == ESteps.LoadAsset) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { if (_assetInfo.AssetType == null) Result = _assetBundle.LoadAllAssets(); @@ -71,7 +71,7 @@ namespace YooAsset { if (_request != null) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { // 强制挂起主线程(注意:该操作会很耗时) YooLogger.Warning("Suspend the main thread to load unity asset."); @@ -108,14 +108,7 @@ namespace YooAsset } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadAssetOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadAssetOperation.cs index 78cc5bfc..9b4f5a7d 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadAssetOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadAssetOperation.cs @@ -39,7 +39,7 @@ namespace YooAsset if (_assetBundle == null) { _steps = ESteps.Done; - Error = $"The bundle {_packageBundle.BundleName} has been destroyed due to unity engine bugs !"; + Error = $"The bundle {_packageBundle.BundleName} has been destroyed due to unity engine bugs."; Status = EOperationStatus.Failed; return; } @@ -49,7 +49,7 @@ namespace YooAsset if (_steps == ESteps.LoadAsset) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { if (_assetInfo.AssetType == null) Result = _assetBundle.LoadAsset(_assetInfo.AssetPath); @@ -71,7 +71,7 @@ namespace YooAsset { if (_request != null) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { // 强制挂起主线程(注意:该操作会很耗时) YooLogger.Warning("Suspend the main thread to load unity asset."); @@ -93,11 +93,11 @@ namespace YooAsset error = $"Failed to load asset : {_assetInfo.AssetPath} AssetType : null AssetBundle : {_packageBundle.BundleName}"; else error = $"Failed to load asset : {_assetInfo.AssetPath} AssetType : {_assetInfo.AssetType} AssetBundle : {_packageBundle.BundleName}"; - YooLogger.Error(error); _steps = ESteps.Done; - Error = error; Status = EOperationStatus.Failed; + Error = error; + YooLogger.Error(Error); } else { @@ -108,14 +108,7 @@ namespace YooAsset } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadSceneOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadSceneOperation.cs index a7ef41a2..f0ccc738 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadSceneOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadSceneOperation.cs @@ -36,7 +36,7 @@ namespace YooAsset if (_steps == ESteps.LoadScene) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { // 注意:场景同步加载方法不会立即加载场景,而是在下一帧加载。 Result = SceneManager.LoadScene(_assetInfo.AssetPath, _loadParams); @@ -69,10 +69,10 @@ namespace YooAsset { if (_asyncOperation != null) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { //注意:场景加载无法强制异步转同步 - YooLogger.Error("The scene is loading asyn !"); + YooLogger.Error("The scene is loading asyn."); } else { @@ -107,7 +107,7 @@ namespace YooAsset internal override void InternalWaitForAsyncComplete() { //注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法! - InternalUpdate(); + RunOnceExecution(); } public override void UnSuspendLoad() { diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadSubAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadSubAssetsOperation.cs index c3b9ccae..b5f91923 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadSubAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadSubAssetsOperation.cs @@ -39,7 +39,7 @@ namespace YooAsset if (_assetBundle == null) { _steps = ESteps.Done; - Error = $"The bundle {_packageBundle.BundleName} has been destroyed due to unity engine bugs !"; + Error = $"The bundle {_packageBundle.BundleName} has been destroyed due to unity engine bugs."; Status = EOperationStatus.Failed; return; } @@ -49,7 +49,7 @@ namespace YooAsset if (_steps == ESteps.LoadAsset) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { if (_assetInfo.AssetType == null) Result = _assetBundle.LoadAssetWithSubAssets(_assetInfo.AssetPath); @@ -71,7 +71,7 @@ namespace YooAsset { if (_request != null) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { // 强制挂起主线程(注意:该操作会很耗时) YooLogger.Warning("Suspend the main thread to load unity asset."); @@ -108,14 +108,7 @@ namespace YooAsset } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadAssetBundleOperation.cs new file mode 100644 index 00000000..e221fd74 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadAssetBundleOperation.cs @@ -0,0 +1,416 @@ +using System; +using System.IO; +using UnityEngine; + +namespace YooAsset +{ + /// + /// 默认的 AssetBundle 加载操作(非加密) + /// 通用实现,适用于 BuiltinFileSystem 和 CacheFileSystem + /// + public class DefaultLoadAssetBundleOperation : LoadAssetBundleOperation + { + private enum ESteps + { + None, + LoadAssetBundle, + CheckResult, + Done, + } + + private AssetBundleCreateRequest _createRequest; + private ESteps _steps = ESteps.None; + + public DefaultLoadAssetBundleOperation(LoadAssetBundleOptions opionts) : base(opionts) { } + internal override void InternalStart() + { + _steps = ESteps.LoadAssetBundle; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadAssetBundle) + { + if (IsWaitingForAsyncComplete) + Result = AssetBundle.LoadFromFile(_options.FileLoadPath); + else + _createRequest = AssetBundle.LoadFromFileAsync(_options.FileLoadPath); + + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (_createRequest != null) + { + if (IsWaitingForAsyncComplete) + { + // 强制挂起主线程(注意:该操作会很耗时) + YooLogger.Warning("Suspend the main thread to load unity bundle."); + Result = _createRequest.assetBundle; + } + else + { + if (_createRequest.isDone == false) + return; + Result = _createRequest.assetBundle; + } + } + + if (Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load asset bundle file : {_options.Bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + + public override AssetBundle LoadFromMemory() + { + byte[] fileData = FileUtility.ReadAllBytes(_options.FileLoadPath); + if (fileData == null || fileData.Length == 0) + return null; + + return AssetBundle.LoadFromMemory(fileData); + } + } + + /// + /// 默认的 AssetBundle 加载操作(加密) + /// 通用实现,适用于 BuiltinFileSystem 和 CacheFileSystem + /// + public abstract class DefaultLoadAssetBundleFromOffsetOperation : LoadAssetBundleOperation + { + private enum ESteps + { + None, + LoadAssetBundle, + CheckResult, + Done, + } + + private AssetBundleCreateRequest _createRequest; + private ESteps _steps = ESteps.None; + + public DefaultLoadAssetBundleFromOffsetOperation(LoadAssetBundleOptions options) : base(options) { } + internal override void InternalStart() + { + _steps = ESteps.LoadAssetBundle; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadAssetBundle) + { + ulong offset = GetFileOffset(); + if (IsWaitingForAsyncComplete) + Result = AssetBundle.LoadFromFile(_options.FileLoadPath, 0, offset); + else + _createRequest = AssetBundle.LoadFromFileAsync(_options.FileLoadPath, 0, offset); + + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (_createRequest != null) + { + if (IsWaitingForAsyncComplete) + { + // 强制挂起主线程(注意:该操作会很耗时) + YooLogger.Warning("Suspend the main thread to load unity bundle."); + Result = _createRequest.assetBundle; + } + else + { + if (_createRequest.isDone == false) + return; + Result = _createRequest.assetBundle; + } + } + + if (Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load asset bundle file : {_options.Bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + + /// + /// 获取偏移值 + /// + protected abstract uint GetFileOffset(); + + public override AssetBundle LoadFromMemory() + { + int offset = (int)GetFileOffset(); + byte[] fileData = File.ReadAllBytes(_options.FileLoadPath); + if (fileData == null || fileData.Length <= offset) + return null; + + // 跳过偏移量 + byte[] bundleData = new byte[fileData.Length - offset]; + Buffer.BlockCopy(fileData, offset, bundleData, 0, bundleData.Length); + + return AssetBundle.LoadFromMemory(bundleData); + } + } + + /// + /// 默认的 AssetBundle 加载操作(加密) + /// 通用实现,适用于 CacheFileSystem + /// + public abstract class DefaultLoadAssetBundleFromMemoryOperation : LoadAssetBundleOperation + { + private enum ESteps + { + None, + CheckFilePath, + LoadAssetBundle, + CheckResult, + Done, + } + + private AssetBundleCreateRequest _createRequest; + private ESteps _steps = ESteps.None; + + public DefaultLoadAssetBundleFromMemoryOperation(LoadAssetBundleOptions options) : base(options) { } + internal override void InternalStart() + { + _steps = ESteps.CheckFilePath; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckFilePath) + { + string filePath = _options.FileLoadPath; + if (IsSupportFileIO(filePath) == false) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"FileIO not supported for builtin path : {filePath}"; + } + else + { + _steps = ESteps.LoadAssetBundle; + } + } + + if (_steps == ESteps.LoadAssetBundle) + { + byte[] fileData = File.ReadAllBytes(_options.FileLoadPath); + byte[] rawData = DecryptData(fileData); + if (rawData == null || rawData.Length == 0) + { + _steps = ESteps.None; + Status = EOperationStatus.Failed; + Error = "Decrypted raw data is null or empty."; + return; + } + + if (IsWaitingForAsyncComplete) + Result = AssetBundle.LoadFromMemory(rawData); + else + _createRequest = AssetBundle.LoadFromMemoryAsync(rawData); + + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (_createRequest != null) + { + if (IsWaitingForAsyncComplete) + { + // 强制挂起主线程(注意:该操作会很耗时) + YooLogger.Warning("Suspend the main thread to load unity bundle."); + Result = _createRequest.assetBundle; + } + else + { + if (_createRequest.isDone == false) + return; + Result = _createRequest.assetBundle; + } + } + + if (Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load asset bundle file : {_options.Bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + + /// + /// 文件数据解密 + /// + protected abstract byte[] DecryptData(byte[] data); + + public override AssetBundle LoadFromMemory() + { + byte[] fileData = File.ReadAllBytes(_options.FileLoadPath); + byte[] rawData = DecryptData(fileData); + if (rawData == null || rawData.Length == 0) + return null; + + return AssetBundle.LoadFromMemory(rawData); + } + } + + /// + /// 默认的 AssetBundle 加载操作(加密) + /// 通用实现,适用于 CacheFileSystem + /// + public abstract class DefaultLoadAssetBundleFromStreamOperation : LoadAssetBundleOperation + { + private enum ESteps + { + None, + CheckFilePath, + LoadAssetBundle, + CheckResult, + Done, + } + + private AssetBundleCreateRequest _createRequest; + private ESteps _steps = ESteps.None; + + public DefaultLoadAssetBundleFromStreamOperation(LoadAssetBundleOptions options) : base(options) { } + internal override void InternalStart() + { + _steps = ESteps.CheckFilePath; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckFilePath) + { + string filePath = _options.FileLoadPath; + if (IsSupportFileIO(filePath) == false) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"FileIO not supported for builtin path : {filePath}"; + } + else + { + _steps = ESteps.LoadAssetBundle; + } + } + + if (_steps == ESteps.LoadAssetBundle) + { + ManagedStream = CreateManagedFileStream(); + uint bufferSize = GetManagedReadBufferSize(); + + if (IsWaitingForAsyncComplete) + Result = AssetBundle.LoadFromStream(ManagedStream, 0, bufferSize); + else + _createRequest = AssetBundle.LoadFromStreamAsync(ManagedStream, 0, bufferSize); + + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (_createRequest != null) + { + if (IsWaitingForAsyncComplete) + { + // 强制挂起主线程(注意:该操作会很耗时) + YooLogger.Warning("Suspend the main thread to load unity bundle."); + Result = _createRequest.assetBundle; + } + else + { + if (_createRequest.isDone == false) + return; + Result = _createRequest.assetBundle; + } + } + + if (Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load asset bundle file : {_options.Bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + + /// + /// 获取文件流 + /// + protected abstract FileStream CreateManagedFileStream(); + + /// + /// 获取缓冲池大小 + /// + protected abstract uint GetManagedReadBufferSize(); + + /// + /// 文件数据解密 + /// + protected abstract byte[] DecryptData(byte[] data); + + public override AssetBundle LoadFromMemory() + { + byte[] fileData = File.ReadAllBytes(_options.FileLoadPath); + byte[] rawData = DecryptData(fileData); + if (rawData == null || rawData.Length == 0) + return null; + + return AssetBundle.LoadFromMemory(rawData); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebNormalAssetBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadAssetBundleOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebNormalAssetBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadAssetBundleOperation.cs.meta index 08958f56..64719f4f 100644 --- a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebNormalAssetBundleOperation.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadAssetBundleOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3b82b4b846083d34b958320b584d8d9b +guid: 067ac2067f265624bac214127575d7d5 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadWebAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadWebAssetBundleOperation.cs new file mode 100644 index 00000000..8057f1a2 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadWebAssetBundleOperation.cs @@ -0,0 +1,249 @@ +using UnityEngine; + +namespace YooAsset +{ + /// + /// 默认的 AssetBundle 加载操作(非加密) + /// 通用实现,适用于 WebRemoteFileSystem 和 WebServerFileSystem + /// + public class DefaultLoadWebAssetBundleOperation : LoadWebAssetBundleOperation + { + private enum ESteps + { + None, + CreateRequest, + CheckRequest, + TryAgain, + Done, + } + + private IDownloadAssetBundleRequest _downloadAssetBundleRequest; + private ESteps _steps = ESteps.None; + + private int _requestCount = 0; + private float _tryAgainTimer = 0; + private int _failedTryAgain; + + public DefaultLoadWebAssetBundleOperation(LoadWebAssetBundleOptions opionts) : base(opionts) + { + _failedTryAgain = opionts.FailedTryAgain; + } + internal override void InternalStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 创建下载器 + if (_steps == ESteps.CreateRequest) + { + string url = GetRequestURL(); + var args = new DownloadAssetBundleRequestArgs(url, 0, _options.WatchdogTimeout, _options.DisableUnityWebCache, _options.Bundle.FileHash, _options.Bundle.UnityCRC); + _downloadAssetBundleRequest = _options.DownloadBackend.CreateAssetBundleRequest(args); + _downloadAssetBundleRequest.SendRequest(); + _steps = ESteps.CheckRequest; + } + + // 检测下载结果 + if (_steps == ESteps.CheckRequest) + { + Progress = _downloadAssetBundleRequest.DownloadProgress; + DownloadedBytes = _downloadAssetBundleRequest.DownloadedBytes; + DownloadProgress = _downloadAssetBundleRequest.DownloadProgress; + if (_downloadAssetBundleRequest.IsDone == false) + return; + + if (_downloadAssetBundleRequest.Status == EDownloadRequestStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + Result = _downloadAssetBundleRequest.Result; + } + 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 += Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + _tryAgainTimer = 0f; + _failedTryAgain--; + Progress = 0f; + DownloadProgress = 0f; + DownloadedBytes = 0; + _steps = ESteps.CreateRequest; + } + } + } + + /// + /// 获取网络请求地址 + /// + protected string GetRequestURL() + { + // 轮流返回请求地址 + _requestCount++; + if (_requestCount % 2 == 0) + return _options.FallbackURL; + else + return _options.MainURL; + } + } + + /// + /// 默认的 AssetBundle 加载操作(加密) + /// 通用实现,适用于 WebRemoteFileSystem 和 WebServerFileSystem + /// + public abstract class DefaultLoadWebAssetBundleFromMemoryOperation : LoadWebAssetBundleOperation + { + private enum ESteps + { + None, + CreateRequest, + CheckRequest, + TryAgain, + Done, + } + + private IDownloadBytesRequest _downloadBytesRequest; + private ESteps _steps = ESteps.None; + + private int _requestCount = 0; + private float _tryAgainTimer = 0; + private int _failedTryAgain; + + public DefaultLoadWebAssetBundleFromMemoryOperation(LoadWebAssetBundleOptions opionts) : base(opionts) + { + _failedTryAgain = opionts.FailedTryAgain; + } + internal override void InternalStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 创建下载器 + if (_steps == ESteps.CreateRequest) + { + string url = GetRequestURL(); + var args = new DownloadDataRequestArgs(url, 0, _options.WatchdogTimeout); + _downloadBytesRequest = _options.DownloadBackend.CreateBytesRequest(args); + _downloadBytesRequest.SendRequest(); + _steps = ESteps.CheckRequest; + } + + // 检测下载结果 + if (_steps == ESteps.CheckRequest) + { + Progress = _downloadBytesRequest.DownloadProgress; + DownloadProgress = _downloadBytesRequest.DownloadProgress; + DownloadedBytes = _downloadBytesRequest.DownloadedBytes; + if (_downloadBytesRequest.IsDone == false) + return; + + // 检查网络错误 + if (_downloadBytesRequest.Status == EDownloadRequestStatus.Succeed) + { + var rawData = Decryption(_downloadBytesRequest.Result); + if (rawData == null || rawData.Length == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "AssetBundle raw data is null or empty."; + } + else + { + AssetBundle assetBundle = AssetBundle.LoadFromMemory(rawData); + if (assetBundle == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed load encrypted AssetBundle: {_options.Bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + Result = assetBundle; + } + } + } + else + { + if (_failedTryAgain > 0) + { + _steps = ESteps.TryAgain; + YooLogger.Warning($"Failed download : {_downloadBytesRequest.URL} Try again."); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadBytesRequest.Error; + YooLogger.Error(Error); + } + } + + // 最终释放请求器 + _downloadBytesRequest.Dispose(); + } + + // 重新尝试下载 + if (_steps == ESteps.TryAgain) + { + _tryAgainTimer += Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + _tryAgainTimer = 0f; + _failedTryAgain--; + Progress = 0f; + DownloadProgress = 0f; + DownloadedBytes = 0; + _steps = ESteps.CreateRequest; + } + } + } + + /// + /// 文件数据解密 + /// + protected abstract byte[] Decryption(byte[] data); + + /// 获取网络请求地址 + /// + protected string GetRequestURL() + { + // 轮流返回请求地址 + _requestCount++; + if (_requestCount % 2 == 0) + return _options.FallbackURL; + else + return _options.MainURL; + } + } +} diff --git a/Assets/YooAsset/Runtime/OperationSystem/GameAsyncOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadWebAssetBundleOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/OperationSystem/GameAsyncOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadWebAssetBundleOperation.cs.meta index 90cbe4b2..50c254b1 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/GameAsyncOperation.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadWebAssetBundleOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ff8a96dd005f55346986f8a98aff8c99 +guid: 05b4aa37709184a408090202f98b93d3 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOperation.cs new file mode 100644 index 00000000..dccb53cf --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOperation.cs @@ -0,0 +1,80 @@ +using System.IO; +using UnityEngine; + +namespace YooAsset +{ + /// + /// 加载 AssetBundle 的 Operation 工厂委托 + /// + public delegate LoadAssetBundleOperation LoadAssetBundleOperationFactory(bool bundleEncrypted, LoadAssetBundleOptions options); + + /// + /// 加载 AssetBundle 的抽象基类 + /// 用户可继承此类实现自定义加载逻辑(如加密解密) + /// + public abstract class LoadAssetBundleOperation : AsyncOperationBase + { + protected readonly LoadAssetBundleOptions _options; + + /// + /// 加载结果:AssetBundle 对象 + /// + public AssetBundle Result { get; protected set; } + + /// + /// 托管流对象(如果使用流加载) + /// 注意:流对象在资源包对象释放的时候会自动释放 + /// + public Stream ManagedStream { get; protected set; } + + public LoadAssetBundleOperation(LoadAssetBundleOptions options) + { + _options = options; + } + + /// + /// 后备加载方法:从内存加载 AssetBundle + /// 当主加载方式失败时,FileSystem 会调用此方法作为后备机制 + /// + /// 加载成功返回 AssetBundle 对象,失败返回 null + public abstract AssetBundle LoadFromMemory(); + + /// + /// 检查文件路径是否支持 FileIO 读取 + /// + protected static bool IsSupportFileIO(string filePath) + { + if (string.IsNullOrEmpty(filePath)) + return true; + if (filePath.StartsWith("jar:") || filePath.StartsWith("content:")) + return false; + return true; + } + } + + /// + /// 立即完成(失败)的 AssetBundle 加载操作 + /// 用途:当 Factory 判定某种场景不支持(例如默认实现不支持加密包)时,返回该 Operation + /// + public sealed class LoadAssetBundleCompleteOperation : LoadAssetBundleOperation + { + private readonly string _error; + + public LoadAssetBundleCompleteOperation(string error, LoadAssetBundleOptions options) : base(options) + { + _error = error; + } + internal override void InternalStart() + { + Status = EOperationStatus.Failed; + Error = _error; + } + internal override void InternalUpdate() + { + } + public override AssetBundle LoadFromMemory() + { + return null; + } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOperation.cs.meta index 75b6d175..f0483f47 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d6d4ba58bf1a1bb4db469b2cdd741ad0 +guid: 32e01cb4600c49f42b8ec19be8f0fb22 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOptions.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOptions.cs new file mode 100644 index 00000000..a90807cc --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOptions.cs @@ -0,0 +1,19 @@ + +namespace YooAsset +{ + /// + /// 加载 AssetBundle 的上下文信息 + /// + public struct LoadAssetBundleOptions + { + /// + /// 文件加载路径 + /// + internal string FileLoadPath { get; set; } + + /// + /// 资源包信息 + /// + internal PackageBundle Bundle { get; set; } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOptions.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOptions.cs.meta new file mode 100644 index 00000000..7cac3dfc --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b866c4ec2f032aa4eb0d4f9094273100 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOperation.cs new file mode 100644 index 00000000..10ef0441 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOperation.cs @@ -0,0 +1,60 @@ +using UnityEngine; + +namespace YooAsset +{ + /// + /// 加载 AssetBundle 的 Operation 工厂委托 + /// + public delegate LoadWebAssetBundleOperation LoadWebAssetBundleOperationFactory(bool bundleEncrypted, LoadWebAssetBundleOptions options); + + /// + /// 加载 AssetBundle 的抽象基类 + /// 用户可继承此类实现自定义加载逻辑(如加密解密) + /// + public abstract class LoadWebAssetBundleOperation : AsyncOperationBase + { + protected readonly LoadWebAssetBundleOptions _options; + + /// + /// 加载结果:AssetBundle 对象 + /// + public AssetBundle Result { get; protected set; } + + /// + /// 下载进度 + /// + public float DownloadProgress { protected set; get; } + + /// + /// 下载大小 + /// + public long DownloadedBytes { protected set; get; } + + public LoadWebAssetBundleOperation(LoadWebAssetBundleOptions options) + { + _options = options; + } + } + + /// + /// 立即完成(失败)的 AssetBundle 加载操作 + /// 用途:当 Factory 判定某种场景不支持(例如默认实现不支持加密包)时,返回该 Operation + /// + public sealed class LoadWebAssetBundleCompleteOperation : LoadWebAssetBundleOperation + { + private readonly string _error; + + public LoadWebAssetBundleCompleteOperation(string error, LoadWebAssetBundleOptions options) : base(options) + { + _error = error; + } + internal override void InternalStart() + { + Status = EOperationStatus.Failed; + Error = _error; + } + internal override void InternalUpdate() + { + } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebAssetBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebAssetBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOperation.cs.meta index 70966c59..179d0179 100644 --- a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebAssetBundleOperation.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0f65d2f6038b95246b7a09cec4055b3a +guid: f0fd9af541471154d9fc968abd450d31 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOptions.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOptions.cs new file mode 100644 index 00000000..1c3af9ac --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOptions.cs @@ -0,0 +1,44 @@ + +namespace YooAsset +{ + /// + /// 加载 AssetBundle 的上下文信息 + /// + public struct LoadWebAssetBundleOptions + { + /// + /// 资源包信息 + /// + internal PackageBundle Bundle { get; set; } + + /// + /// 失败后重试次数 + /// + internal int FailedTryAgain { get; set; } + + /// + /// 看门狗超时时间 + /// + internal int WatchdogTimeout { get; set; } + + /// + /// 下载后台接口 + /// + internal IDownloadBackend DownloadBackend { get; set; } + + /// + /// 禁用Unity的网络缓存 + /// + internal bool DisableUnityWebCache { get; set; } + + /// + /// 主资源地址 + /// + internal string MainURL { get; set; } + + /// + /// 备用资源地址 + /// + internal string FallbackURL { get; set; } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOptions.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOptions.cs.meta new file mode 100644 index 00000000..615d1299 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c79e03ac8bcbef4aa0e2eede5bf63fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs index 9b3e2a1e..cc54bff6 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs @@ -10,20 +10,10 @@ namespace YooAsset public abstract void UnloadBundleFile(); /// - /// 获取资源包文件的路径 + /// 获取资源包文件的本地路径 /// public abstract string GetBundleFilePath(); - /// - /// 读取资源包文件的二进制数据 - /// - public abstract byte[] ReadBundleFileData(); - - /// - /// 读取资源包文件的文本数据 - /// - public abstract string ReadBundleFileText(); - /// /// 加载资源包内的资源对象 diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/DefaultLoadRawBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/DefaultLoadRawBundleOperation.cs new file mode 100644 index 00000000..bb186001 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/DefaultLoadRawBundleOperation.cs @@ -0,0 +1,149 @@ +using System.IO; + +namespace YooAsset +{ + /// + /// 默认的 RawBundle 加载操作(非加密) + /// 通用实现,适用于 BuiltinFileSystem 和 CacheFileSystem + /// + public class DefaultLoadRawBundleOperation : LoadRawBundleOperation + { + private enum ESteps + { + None, + CheckFilePath, + LoadRawBundle, + Done + } + + private ESteps _steps = ESteps.None; + + public DefaultLoadRawBundleOperation(LoadRawBundleOptions options) : base(options) { } + internal override void InternalStart() + { + _steps = ESteps.CheckFilePath; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckFilePath) + { + string filePath = _options.FileLoadPath; + if (IsSupportFileIO(filePath) == false) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"FileIO not supported for builtin path : {filePath}"; + } + else + { + _steps = ESteps.LoadRawBundle; + } + } + + if (_steps == ESteps.LoadRawBundle) + { + string filePath = _options.FileLoadPath; + if (File.Exists(filePath)) + { + byte[] data = File.ReadAllBytes(filePath); + Result = new RawBundle(data); + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Can not found raw bundle file : {filePath}"; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + } + + /// + /// 默认的 RawBundle 加载操作(加密) + /// 通用实现,适用于 CacheFileSystem + /// + public abstract class DefaultLoadRawBundleFromMemoryOperation : LoadRawBundleOperation + { + private enum ESteps + { + None, + CheckFilePath, + LoadRawBundle, + Done + } + + private ESteps _steps = ESteps.None; + + public DefaultLoadRawBundleFromMemoryOperation(LoadRawBundleOptions options) : base(options) { } + internal override void InternalStart() + { + _steps = ESteps.CheckFilePath; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckFilePath) + { + string filePath = _options.FileLoadPath; + if (IsSupportFileIO(filePath) == false) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"FileIO not supported for builtin path : {filePath}"; + } + else + { + _steps = ESteps.LoadRawBundle; + } + } + + if (_steps == ESteps.LoadRawBundle) + { + string filePath = _options.FileLoadPath; + if (File.Exists(filePath)) + { + byte[] fileData = File.ReadAllBytes(filePath); + byte[] rawData = DecryptData(fileData); + if (rawData == null || rawData.Length == 0) + { + _steps = ESteps.None; + Status = EOperationStatus.Failed; + Error = "Decrypted raw data is null or empty."; + } + else + { + Result = new RawBundle(rawData); + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Can not found raw bundle file : {filePath}"; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + + /// + /// 文件数据解密 + /// + protected abstract byte[] DecryptData(byte[] data); + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/DefaultLoadRawBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/DefaultLoadRawBundleOperation.cs.meta new file mode 100644 index 00000000..94400673 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/DefaultLoadRawBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc25b8eb3bf83474f942e36bf7b3210d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOperation.cs new file mode 100644 index 00000000..2fcb02cf --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOperation.cs @@ -0,0 +1,62 @@ +using System.Text; + +namespace YooAsset +{ + /// + /// 加载 RawBundle 的 Operation 工厂委托 + /// + public delegate LoadRawBundleOperation LoadRawBundleOperationFactory(bool bundleEncrypted, LoadRawBundleOptions options); + + /// + /// 加载 RawBundle 的抽象基类 + /// 用户可继承此类实现自定义加载逻辑(如加密解密) + /// + public abstract class LoadRawBundleOperation : AsyncOperationBase + { + protected readonly LoadRawBundleOptions _options; + + /// + /// 加载结果:RawBundle 对象 + /// + public RawBundle Result { get; protected set; } + + public LoadRawBundleOperation(LoadRawBundleOptions options) + { + _options = options; + } + + /// + /// 检查文件路径是否支持 FileIO 读取 + /// + protected static bool IsSupportFileIO(string filePath) + { + if (string.IsNullOrEmpty(filePath)) + return true; + if (filePath.StartsWith("jar:") || filePath.StartsWith("content:")) + return false; + return true; + } + } + + /// + /// 立即完成(失败)的 RawBundle 加载操作 + /// 用途:当 Factory 判定某种场景不支持(例如默认实现不支持加密包)时,返回该 Operation + /// + public sealed class LoadRawBundleCompleteOperation : LoadRawBundleOperation + { + private readonly string _error; + + public LoadRawBundleCompleteOperation(string error, LoadRawBundleOptions options) : base(options) + { + _error = error; + } + internal override void InternalStart() + { + Status = EOperationStatus.Failed; + Error = _error; + } + internal override void InternalUpdate() + { + } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOperation.cs.meta new file mode 100644 index 00000000..48b4ee28 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 445c03f3efb27eb4c91ce4b387997ac7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOptions.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOptions.cs new file mode 100644 index 00000000..00c8e31f --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOptions.cs @@ -0,0 +1,19 @@ + +namespace YooAsset +{ + /// + /// 加载 RawBundle 的上下文信息 + /// + public struct LoadRawBundleOptions + { + /// + /// 文件加载路径 + /// + internal string FileLoadPath { get; set; } + + /// + /// 资源包信息 + /// + internal PackageBundle Bundle { get; set; } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOptions.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOptions.cs.meta new file mode 100644 index 00000000..b6ed2181 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8637bbd2c5bb97d428e45a76466af9c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadAllAssetsOperation.cs index 1c227032..1bb4949a 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadAllAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadAllAssetsOperation.cs @@ -5,7 +5,7 @@ namespace YooAsset { internal override void InternalStart() { - Error = $"{nameof(RawBundleLoadAllAssetsOperation)} not support load all assets !"; + Error = $"{nameof(RawBundleLoadAllAssetsOperation)} not support load all assets."; Status = EOperationStatus.Failed; } internal override void InternalUpdate() diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadAssetOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadAssetOperation.cs index e3bdd18e..3f96e8f6 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadAssetOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadAssetOperation.cs @@ -3,13 +3,55 @@ namespace YooAsset { internal class RawBundleLoadAssetOperation : FSLoadAssetOperation { + protected enum ESteps + { + None, + LoadObject, + CheckResult, + Done, + } + + private readonly PackageBundle _packageBundle; + private readonly RawBundle _rawBundle; + private readonly AssetInfo _assetInfo; + private ESteps _steps = ESteps.None; + + public RawBundleLoadAssetOperation(PackageBundle packageBundle, RawBundle rawBundle, AssetInfo assetInfo) + { + _packageBundle = packageBundle; + _rawBundle = rawBundle; + _assetInfo = assetInfo; + } internal override void InternalStart() { - Error = $"{nameof(RawBundleLoadAssetOperation)} not support load asset !"; - Status = EOperationStatus.Failed; + _steps = ESteps.LoadObject; } internal override void InternalUpdate() { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadObject) + { + Result = _rawBundle.LoadRawFileObject(); + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load raw file object : {_assetInfo.AssetPath}"; + YooLogger.Error(Error); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadSceneOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadSceneOperation.cs index 763f1d86..cfaf775c 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadSceneOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadSceneOperation.cs @@ -5,7 +5,7 @@ namespace YooAsset { internal override void InternalStart() { - Error = $"{nameof(RawBundleLoadSceneOperation)} not support load scene !"; + Error = $"{nameof(RawBundleLoadSceneOperation)} not support load scene."; Status = EOperationStatus.Failed; } internal override void InternalUpdate() diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadSubAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadSubAssetsOperation.cs index b8e8635e..de2d389e 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadSubAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadSubAssetsOperation.cs @@ -5,7 +5,7 @@ namespace YooAsset { internal override void InternalStart() { - Error = $"{nameof(RawBundleLoadSubAssetsOperation)} not support load sub assets !"; + Error = $"{nameof(RawBundleLoadSubAssetsOperation)} not support load sub assets."; Status = EOperationStatus.Failed; } internal override void InternalUpdate() diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs new file mode 100644 index 00000000..216f7f04 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs @@ -0,0 +1,26 @@ + +namespace YooAsset +{ + public class RawBundle + { + private byte[] _data; + + public RawBundle(byte[] data) + { + _data = data; + } + + /// + /// 加载原生文件对象 + /// + public RawFileObject LoadRawFileObject() + { + return RawFileObject.Create(_data); + } + + public void Unload() + { + _data = null; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs.meta new file mode 100644 index 00000000..06ee5659 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c5157b3021ed3074192933520404544d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs index 6a42ddc2..dfce426b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs @@ -6,32 +6,30 @@ namespace YooAsset { private readonly IFileSystem _fileSystem; private readonly PackageBundle _packageBundle; + private readonly RawBundle _rawBundle; - public RawBundleResult(IFileSystem fileSystem, PackageBundle packageBundle) + public RawBundleResult(IFileSystem fileSystem, PackageBundle packageBundle, RawBundle rawBundle) { _fileSystem = fileSystem; _packageBundle = packageBundle; + _rawBundle = rawBundle; } public override void UnloadBundleFile() { + if (_rawBundle != null) + { + _rawBundle.Unload(); + } } public override string GetBundleFilePath() { return _fileSystem.GetBundleFilePath(_packageBundle); } - public override byte[] ReadBundleFileData() - { - return _fileSystem.ReadBundleFileData(_packageBundle); - } - public override string ReadBundleFileText() - { - return _fileSystem.ReadBundleFileText(_packageBundle); - } public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) { - var operation = new RawBundleLoadAssetOperation(); + var operation = new RawBundleLoadAssetOperation(_packageBundle, _rawBundle, assetInfo); return operation; } public override FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo) diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs new file mode 100644 index 00000000..c106f7eb --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs @@ -0,0 +1,39 @@ +using System.Text; +using UnityEngine; + +namespace YooAsset +{ + /// + /// 原生文件对象 + /// + public class RawFileObject : ScriptableObject + { + private byte[] _fileData; + private string _fileText; + + public byte[] Data => _fileData; + + public string Text + { + get + { + if (_fileData == null || _fileData.Length == 0) + return null; + + if (string.IsNullOrEmpty(_fileText)) + _fileText = Encoding.UTF8.GetString(_fileData); + return _fileText; + } + } + + /// + /// 创建原生文件对象实例 + /// + public static RawFileObject Create(byte[] data) + { + var obj = CreateInstance(); + obj._fileData = data; + return obj; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs.meta new file mode 100644 index 00000000..7b1ffdeb --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ffa40d12948b6c74e95a1cd42c3c3b7e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadAllAssetsOperation.cs index 3b9a0a14..5d6fc26b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadAllAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadAllAssetsOperation.cs @@ -28,7 +28,7 @@ namespace YooAsset _steps = ESteps.CheckBundle; #else _steps = ESteps.Done; - Error = $"{nameof(VirtualBundleLoadAllAssetsOperation)} only support unity editor platform !"; + Error = $"{nameof(VirtualBundleLoadAllAssetsOperation)} only support unity editor platform."; Status = EOperationStatus.Failed; #endif } @@ -109,14 +109,7 @@ namespace YooAsset } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadAssetOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadAssetOperation.cs index 64d4ae34..08483d39 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadAssetOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadAssetOperation.cs @@ -27,7 +27,7 @@ namespace YooAsset _steps = ESteps.CheckBundle; #else _steps = ESteps.Done; - Error = $"{nameof(VirtualBundleLoadAssetOperation)} only support unity editor platform !"; + Error = $"{nameof(VirtualBundleLoadAssetOperation)} only support unity editor platform."; Status = EOperationStatus.Failed; #endif } @@ -88,14 +88,7 @@ namespace YooAsset } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadSceneOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadSceneOperation.cs index cdbe006c..15613652 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadSceneOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadSceneOperation.cs @@ -31,7 +31,7 @@ namespace YooAsset _steps = ESteps.LoadScene; #else _steps = ESteps.Done; - Error = $"{nameof(VirtualBundleLoadSceneOperation)} only support unity editor platform !"; + Error = $"{nameof(VirtualBundleLoadSceneOperation)} only support unity editor platform."; Status = EOperationStatus.Failed; #endif } @@ -43,7 +43,7 @@ namespace YooAsset if (_steps == ESteps.LoadScene) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { Result = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneInPlayMode(_assetInfo.AssetPath, _loadParams); _steps = ESteps.CheckResult; @@ -74,10 +74,10 @@ namespace YooAsset { if (_asyncOperation != null) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { // 注意:场景加载无法强制异步转同步 - YooLogger.Error("The scene is loading asyn !"); + YooLogger.Error("The scene is loading asyn."); } else { @@ -113,7 +113,7 @@ namespace YooAsset internal override void InternalWaitForAsyncComplete() { //注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法! - InternalUpdate(); + RunOnceExecution(); } public override void UnSuspendLoad() { diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadSubAssetsOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadSubAssetsOperation.cs index 587c3a42..f333e2cf 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadSubAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/Operation/VirtualBundleLoadSubAssetsOperation.cs @@ -28,7 +28,7 @@ namespace YooAsset _steps = ESteps.CheckBundle; #else _steps = ESteps.Done; - Error = $"{nameof(VirtualBundleLoadSubAssetsOperation)} only support unity editor platform !"; + Error = $"{nameof(VirtualBundleLoadSubAssetsOperation)} only support unity editor platform."; Status = EOperationStatus.Failed; #endif } @@ -100,14 +100,7 @@ namespace YooAsset } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs index 3ed31901..66c77e90 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs @@ -20,14 +20,6 @@ namespace YooAsset { return _fileSystem.GetBundleFilePath(_packageBundle); } - public override byte[] ReadBundleFileData() - { - return _fileSystem.ReadBundleFileData(_packageBundle); - } - public override string ReadBundleFileText() - { - return _fileSystem.ReadBundleFileText(_packageBundle); - } public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) { diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs deleted file mode 100644 index 0aa56daf..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs +++ /dev/null @@ -1,89 +0,0 @@ - -namespace YooAsset -{ - internal class DBFSLoadPackageManifestOperation : FSLoadPackageManifestOperation - { - private enum ESteps - { - None, - RequestBuildinPackageHash, - LoadBuildinPackageManifest, - Done, - } - - private readonly DefaultBuildinFileSystem _fileSystem; - private readonly string _packageVersion; - private RequestBuildinPackageHashOperation _requestBuildinPackageHashOp; - private LoadBuildinPackageManifestOperation _loadBuildinPackageManifestOp; - private ESteps _steps = ESteps.None; - - - public DBFSLoadPackageManifestOperation(DefaultBuildinFileSystem fileSystem, string packageVersion) - { - _fileSystem = fileSystem; - _packageVersion = packageVersion; - } - internal override void InternalStart() - { - _steps = ESteps.RequestBuildinPackageHash; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.RequestBuildinPackageHash) - { - if (_requestBuildinPackageHashOp == null) - { - _requestBuildinPackageHashOp = new RequestBuildinPackageHashOperation(_fileSystem, _packageVersion); - _requestBuildinPackageHashOp.StartOperation(); - AddChildOperation(_requestBuildinPackageHashOp); - } - - _requestBuildinPackageHashOp.UpdateOperation(); - if (_requestBuildinPackageHashOp.IsDone == false) - return; - - if (_requestBuildinPackageHashOp.Status == EOperationStatus.Succeed) - { - _steps = ESteps.LoadBuildinPackageManifest; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _requestBuildinPackageHashOp.Error; - } - } - - if (_steps == ESteps.LoadBuildinPackageManifest) - { - if (_loadBuildinPackageManifestOp == null) - { - string packageHash = _requestBuildinPackageHashOp.PackageHash; - _loadBuildinPackageManifestOp = new LoadBuildinPackageManifestOperation(_fileSystem, _packageVersion, packageHash); - _loadBuildinPackageManifestOp.StartOperation(); - AddChildOperation(_loadBuildinPackageManifestOp); - } - - _loadBuildinPackageManifestOp.UpdateOperation(); - if (_loadBuildinPackageManifestOp.IsDone == false) - return; - - if (_loadBuildinPackageManifestOp.Status == EOperationStatus.Succeed) - { - _steps = ESteps.Done; - Manifest = _loadBuildinPackageManifestOp.Manifest; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _loadBuildinPackageManifestOp.Error; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/README.md b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/README.md deleted file mode 100644 index e5b80558..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/README.md +++ /dev/null @@ -1,488 +0,0 @@ -# DefaultBuildinFileSystem 内置文件系统 - -## 模块概述 - -DefaultBuildinFileSystem 是 YooAsset 的**内置资源文件系统**,用于管理打包到应用程序中的资源文件(StreamingAssets)。该文件系统支持 AssetBundle 和原生文件的加载,并内置解压文件系统以处理 Android/OpenHarmony 平台的特殊需求。 - -### 核心特性 - -- **内置资源管理**:管理 StreamingAssets 目录下的资源文件 -- **Catalog 目录系统**:使用目录文件快速查询内置资源 -- **自动解压机制**:Android/OpenHarmony 平台自动解压加密和原生文件 -- **清单拷贝功能**:支持将内置清单拷贝到沙盒目录 -- **加密资源支持**:通过解密服务接口支持加密资源加载 - ---- - -## 设计目标 - -| 目标 | 说明 | -|------|------| -| **跨平台支持** | 统一处理各平台 StreamingAssets 的访问差异 | -| **高效查询** | 通过 Catalog 文件快速判断资源是否内置 | -| **自动解压** | 自动处理 Android 平台无法直接访问的资源 | -| **灵活配置** | 支持多种参数配置适应不同需求 | - ---- - -## 文件结构 - -``` -DefaultBuildinFileSystem/ -├── DefaultBuildinFileSystem.cs # 文件系统主类 -├── DefaultBuildinFileSystemDefine.cs # 常量定义 -├── DefaultBuildinFileCatalog.cs # 内置资源目录结构 -├── CatalogDefine.cs # Catalog 文件格式定义 -├── CatalogTools.cs # Catalog 序列化工具 -└── Operation/ # 操作类 - ├── DBFSInitializeOperation.cs # 初始化操作 - ├── DBFSRequestPackageVersionOperation.cs # 请求版本操作 - ├── DBFSLoadPackageManifestOperation.cs # 加载清单操作 - ├── DBFSLoadBundleOperation.cs # 加载资源包操作 - └── internal/ # 内部操作类 - ├── CopyBuildinFileOperation.cs # 拷贝内置文件操作 - ├── LoadBuildinCatalogFileOperation.cs # 加载 Catalog 文件操作 - ├── LoadBuildinPackageManifestOperation.cs# 加载清单文件操作 - ├── RequestBuildinPackageHashOperation.cs # 请求哈希文件操作 - └── RequestBuildinPackageVersionOperation.cs # 请求版本文件操作 -``` - ---- - -## 核心类说明 - -### DefaultBuildinFileSystem - -内置文件系统的主类,实现 `IFileSystem` 接口。 - -#### 基本属性 - -| 属性 | 类型 | 说明 | -|------|------|------| -| `PackageName` | `string` | 包裹名称 | -| `FileRoot` | `string` | 文件根目录(StreamingAssets 下的包裹目录) | -| `FileCount` | `int` | 已记录的内置文件数量 | -| `DownloadBackend` | `IDownloadBackend` | 下载后台接口 | - -#### 自定义参数 - -| 参数 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `InstallClearMode` | `EOverwriteInstallClearMode` | `ClearAllManifestFiles` | 覆盖安装时的缓存清理模式 | -| `FileVerifyLevel` | `EFileVerifyLevel` | `Middle` | 文件校验级别 | -| `FileVerifyMaxConcurrency` | `int` | `32` | 文件校验最大并发数 | -| `AppendFileExtension` | `bool` | `false` | 是否追加文件扩展名 | -| `DisableCatalogFile` | `bool` | `false` | 禁用 Catalog 目录文件 | -| `CopyBuildinPackageManifest` | `bool` | `false` | 是否拷贝内置清单到沙盒 | -| `CopyBuildinPackageManifestDestRoot` | `string` | `null` | 清单拷贝目标目录 | -| `UnpackFileSystemRoot` | `string` | `null` | 解压文件系统根目录 | -| `DecryptionServices` | `IDecryptionServices` | `null` | 解密服务接口 | -| `ManifestServices` | `IManifestRestoreServices` | `null` | 清单恢复服务接口 | -| `CopyLocalFileServices` | `ICopyLocalFileServices` | `null` | 本地文件拷贝服务接口 | - -#### 核心方法 - -```csharp -// 生命周期 -void OnCreate(string packageName, string packageRoot); -void OnDestroy(); -void SetParameter(string name, object value); - -// 异步操作 -FSInitializeFileSystemOperation InitializeFileSystemAsync(); -FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout); -FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout); -FSLoadBundleOperation LoadBundleFile(PackageBundle bundle); -FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options); -FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options); - -// 文件查询 -bool Belong(PackageBundle bundle); // 检查是否属于内置文件 -bool Exists(PackageBundle bundle); // 检查文件是否存在 -bool NeedDownload(PackageBundle bundle);// 始终返回 false -bool NeedUnpack(PackageBundle bundle); // 检查是否需要解压 -bool NeedImport(PackageBundle bundle); // 始终返回 false - -// 文件访问 -string GetBundleFilePath(PackageBundle bundle); -byte[] ReadBundleFileData(PackageBundle bundle); -string ReadBundleFileText(PackageBundle bundle); -``` - ---- - -## Catalog 目录系统 - -### DefaultBuildinFileCatalog - -内置资源目录结构,记录所有内置资源文件的信息。 - -```csharp -[Serializable] -internal class DefaultBuildinFileCatalog -{ - [Serializable] - public class FileWrapper - { - public string BundleGUID; // 资源包 GUID - public string FileName; // 文件名 - } - - public string FileVersion; // 文件版本 - public string PackageName; // 包裹名称 - public string PackageVersion; // 包裹版本 - public List Wrappers; // 文件列表 -} -``` - -### CatalogDefine - -Catalog 文件格式常量定义。 - -```csharp -internal class CatalogDefine -{ - public const int FileMaxSize = 104857600; // 文件极限大小(100MB) - public const uint FileSign = 0x133C5EE; // 文件头标记 - public const string FileVersion = "1.0.0"; // 文件格式版本 -} -``` - -### CatalogTools - -Catalog 文件的序列化和反序列化工具。 - -| 方法 | 说明 | -|------|------| -| `CreateCatalogFile()` | 生成包裹的内置资源目录文件(编辑器) | -| `CreateEmptyCatalogFile()` | 生成空的内置资源目录文件(编辑器) | -| `SerializeToJson()` | 序列化为 JSON 文件 | -| `DeserializeFromJson()` | 从 JSON 文件反序列化 | -| `SerializeToBinary()` | 序列化为二进制文件 | -| `DeserializeFromBinary()` | 从二进制文件反序列化 | - ---- - -## 操作类说明 - -### DBFSInitializeOperation - -初始化操作,执行以下步骤: - -``` -状态流程: -┌─────────────────────────────────────────────────────────────┐ -│ CopyBuildinPackageManifest = true ? │ -│ │ │ -│ ├── Yes ──► LoadBuildinPackageVersion │ -│ │ └── RequestBuildinPackageVersionOp │ -│ │ ↓ │ -│ │ CopyBuildinPackageHash │ -│ │ └── CopyBuildinFileOperation │ -│ │ ↓ │ -│ │ CopyBuildinPackageManifest │ -│ │ └── CopyBuildinFileOperation │ -│ │ ↓ │ -│ └── No ─────────────────┘ │ -│ ↓ │ -│ InitUnpackFileSystem │ -│ └── DefaultUnpackFileSystem.Init │ -│ ↓ │ -│ DisableCatalogFile = true ? │ -│ ├── Yes ──► Done (Succeed) │ -│ └── No ──► LoadCatalogFile │ -│ └── LoadBuildinCatalog │ -│ ↓ │ -│ RecordCatalogFile │ -│ ↓ │ -│ Done (Succeed) │ -└─────────────────────────────────────────────────────────────┘ -``` - -### DBFSLoadBundleOperation - -加载资源包操作,支持多种资源类型。 - -#### DBFSLoadAssetBundleOperation - -加载 AssetBundle 文件。 - -``` -状态流程: -LoadAssetBundle - ├── 加密资源 ──► DecryptionServices.LoadAssetBundle[Async] - └── 普通资源 ──► AssetBundle.LoadFromFile[Async] - ↓ -CheckResult - ├── 成功 ──► AssetBundleResult - └── 失败 ──► Error -``` - -#### DBFSLoadRawBundleOperation - -加载原生文件。 - -``` -状态流程: -LoadBuildinRawBundle - ├── Android 平台 ──► Error(不支持直接读取) - └── 其他平台 ──► RawBundleResult -``` - -#### DBFSLoadInstantBundleOperation - -加载团结引擎(Tuanjie)专用资源包(需要 `TUANJIE_1_7_OR_NEWER` 宏)。 - ---- - -## 内部操作类 - -### LoadBuildinCatalogFileOperation - -加载 Catalog 目录文件。 - -``` -状态流程: -TryLoadFileData - ├── 文件存在 ──► File.ReadAllBytes - └── 文件不存在 ──► RequestFileData (UnityWebRequest) - ↓ -LoadCatalog - └── CatalogTools.DeserializeFromBinary -``` - -### CopyBuildinFileOperation - -拷贝内置文件到目标路径。 - -``` -状态流程: -CheckFileExist - ├── 目标已存在 ──► Done (Succeed) - └── 目标不存在 ──► TryCopyFile - ↓ -TryCopyFile - ├── 源文件存在 ──► File.Copy - └── 源文件不存在 ──► UnpackFile (UnityWebRequest) -``` - ---- - -## 解压机制 - -### 自动解压条件 - -在 Android/OpenHarmony 平台上,以下情况需要解压到沙盒: - -```csharp -protected virtual bool IsUnpackBundleFile(PackageBundle bundle) -{ -#if UNITY_ANDROID || UNITY_OPENHARMONY - if (bundle.Encrypted) // 加密资源 - return true; - if (bundle.BundleType == RawBundle) // 原生文件 - return true; - return false; -#else - return false; -#endif -} -``` - -### 解压文件系统 - -内置文件系统在创建时会自动创建一个 `DefaultUnpackFileSystem` 实例: - -```csharp -public virtual void OnCreate(string packageName, string packageRoot) -{ - // 创建解压文件系统 - var remoteServices = new DefaultUnpackRemoteServices(_packageRoot); - _unpackFileSystem = new DefaultUnpackFileSystem(); - _unpackFileSystem.SetParameter(REMOTE_SERVICES, remoteServices); - _unpackFileSystem.SetParameter(FILE_VERIFY_LEVEL, FileVerifyLevel); - // ... 其他参数 - _unpackFileSystem.OnCreate(packageName, UnpackFileSystemRoot); -} -``` - ---- - -## 平台差异处理 - -### Android 平台限制 - -``` -┌─────────────────────────────────────────────────────────────┐ -│ Android 平台特殊处理 │ -├─────────────────────────────────────────────────────────────┤ -│ StreamingAssets 文件位于 APK 压缩包内,无法直接访问: │ -│ │ -│ ✓ AssetBundle.LoadFromFile 支持(Unity 内部处理) │ -│ ✗ File.ReadAllBytes 不支持 │ -│ ✗ File.Exists 不支持 │ -│ ✓ UnityWebRequest 支持(jar:file:// 协议) │ -│ │ -│ 解决方案: │ -│ 1. 加密资源 → 自动解压到沙盒 │ -│ 2. 原生文件 → 自动解压到沙盒 │ -│ 3. Catalog → 使用 UnityWebRequest 读取 │ -└─────────────────────────────────────────────────────────────┘ -``` - -### WebGL 平台 - -```csharp -#if UNITY_WEBGL - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"{nameof(DefaultBuildinFileSystem)} is not support WEBGL platform !"; -#endif -``` - -WebGL 平台不支持 DefaultBuildinFileSystem,应使用 `DefaultWebServerFileSystem`。 - ---- - -## 使用示例 - -### 基础配置 - -```csharp -// 创建内置文件系统参数 -var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(); - -// 初始化包裹 -var initParams = new OfflinePlayModeParameters(); -initParams.BuildinFileSystemParameters = buildinParams; -var initOp = package.InitializeAsync(initParams); -``` - -### 配置解密服务 - -```csharp -var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(); - -// 设置解密服务 -buildinParams.AddParameter( - FileSystemParametersDefine.DECRYPTION_SERVICES, - new MyDecryptionServices() -); -``` - -### 配置清单拷贝 - -```csharp -var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(); - -// 启用清单拷贝(用于离线模式切换到联机模式) -buildinParams.AddParameter( - FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST, - true -); - -// 可选:指定拷贝目标目录 -buildinParams.AddParameter( - FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT, - "/custom/path" -); -``` - -### 禁用 Catalog 文件 - -```csharp -var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(); - -// 禁用 Catalog(所有资源视为内置) -buildinParams.AddParameter( - FileSystemParametersDefine.DISABLE_CATALOG_FILE, - true -); -``` - -### 配置解压文件系统根目录 - -```csharp -var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(); - -// 设置解压文件系统的根目录 -buildinParams.AddParameter( - FileSystemParametersDefine.UNPACK_FILE_SYSTEM_ROOT, - "/custom/unpack/path" -); -``` - ---- - -## 参数常量 - -```csharp -// 安装清理 -FileSystemParametersDefine.INSTALL_CLEAR_MODE // EOverwriteInstallClearMode - -// 文件校验 -FileSystemParametersDefine.FILE_VERIFY_LEVEL // EFileVerifyLevel -FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY // int - -// 文件配置 -FileSystemParametersDefine.APPEND_FILE_EXTENSION // bool -FileSystemParametersDefine.DISABLE_CATALOG_FILE // bool - -// 清单拷贝 -FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST // bool -FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT // string - -// 解压配置 -FileSystemParametersDefine.UNPACK_FILE_SYSTEM_ROOT // string - -// 服务接口 -FileSystemParametersDefine.DECRYPTION_SERVICES // IDecryptionServices -FileSystemParametersDefine.MANIFEST_SERVICES // IManifestRestoreServices -FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES // ICopyLocalFileServices -``` - ---- - -## 类继承关系 - -``` -IFileSystem - └── DefaultBuildinFileSystem - └── (内部持有) DefaultUnpackFileSystem - -FSInitializeFileSystemOperation - └── DBFSInitializeOperation - -FSRequestPackageVersionOperation - └── DBFSRequestPackageVersionOperation - -FSLoadPackageManifestOperation - └── DBFSLoadPackageManifestOperation - -FSLoadBundleOperation - ├── DBFSLoadAssetBundleOperation - ├── DBFSLoadRawBundleOperation - └── DBFSLoadInstantBundleOperation (Tuanjie) - -AsyncOperationBase - ├── LoadBuildinCatalogFileOperation - ├── CopyBuildinFileOperation - ├── LoadBuildinPackageManifestOperation - ├── RequestBuildinPackageHashOperation - └── RequestBuildinPackageVersionOperation - -BundleResult - ├── AssetBundleResult ← AssetBundle 资源 - └── RawBundleResult ← 原生文件 -``` - ---- - -## 注意事项 - -1. **WebGL 不支持**:DefaultBuildinFileSystem 不支持 WebGL 平台 -2. **Android 限制**:Android 平台无法直接读取 StreamingAssets 中的原生文件 -3. **Catalog 文件**:构建时需要生成 Catalog 文件,否则需要禁用 Catalog 功能 -4. **解压目录**:解压的文件存储在 `UnpackFileSystemRoot` 指定的目录 -5. **加密资源**:加密资源在 Android/OpenHarmony 平台会自动解压到沙盒 -6. **清单拷贝**:启用清单拷贝可以支持从离线模式平滑切换到联机模式 diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/README.md.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/README.md.meta deleted file mode 100644 index 9eb6cb8e..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/README.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 7ec531875d1515b4496e0e9035e63661 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements.meta deleted file mode 100644 index de5fe429..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: da6402a4b93d31943b26fb99cebc0dfd -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/README.md b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/README.md deleted file mode 100644 index 2e49b9d9..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/README.md +++ /dev/null @@ -1,791 +0,0 @@ -# DefaultCacheFileSystem 缓存文件系统 - -## 模块概述 - -DefaultCacheFileSystem 是 YooAsset 的**缓存文件系统**,负责管理从远程服务器下载并缓存到本地沙盒的资源文件。该文件系统是联机运行模式(HostPlayMode)的核心组件,提供完整的下载、验证、缓存和加载功能。 - -### 核心特性 - -- **智能缓存管理**:基于 GUID 的文件索引,支持增量更新 -- **断点续传**:大文件下载支持从断点继续 -- **多线程验证**:后台线程验证文件完整性,不阻塞主线程 -- **并发下载**:可配置的下载并发数和请求速率 -- **覆盖安装检测**:App 版本变更时自动清理过期缓存 -- **加密支持**:支持加密资源包的解密加载 - ---- - -## 设计目标 - -| 目标 | 说明 | -|------|------| -| **高性能** | 多线程验证、并发下载、路径缓存优化 | -| **高可靠** | CRC/Hash 验证、损坏文件自动清理、加载失败重试 | -| **可扩展** | 支持自定义解密服务、远程服务、本地拷贝服务 | -| **易配置** | 丰富的参数配置,适应不同网络环境 | - ---- - -## 文件结构 - -``` -DefaultCacheFileSystem/ -├── DefaultCacheFileSystem.cs # 文件系统主类 -├── DefaultCacheFileSystemDefine.cs # 常量定义 -├── EOverwriteInstallClearMode.cs # 覆盖安装清理模式枚举 -├── ApplicationFootPrint.cs # 应用版本足迹 -├── Elements/ # 元素类 -│ ├── RecordFileElement.cs # 缓存文件记录元素 -│ ├── TempFileElement.cs # 临时文件元素 -│ └── VerifyFileElement.cs # 验证文件元素 -└── Operation/ # 操作类 - ├── DCFSInitializeOperation.cs # 初始化操作 - ├── DCFSRequestPackageVersionOperation.cs # 请求版本操作 - ├── DCFSLoadPackageManifestOperation.cs # 加载清单操作 - ├── DCFSLoadBundleOperation.cs # 加载资源包操作 - └── internal/ # 内部操作类 - ├── SearchCacheFilesOperation.cs # 搜索缓存文件 - ├── VerifyCacheFilesOperation.cs # 验证缓存文件 - ├── VerifyTempFileOperation.cs # 验证临时文件 - ├── DownloadPackageHashOperation.cs # 下载哈希文件 - ├── DownloadPackageManifestOperation.cs # 下载清单文件 - ├── DownloadPackageBundleOperation.cs # 下载资源包 - ├── LoadCachePackageHashOperation.cs # 加载缓存哈希 - ├── LoadCachePackageManifestOperation.cs # 加载缓存清单 - ├── ClearAllCacheBundleFilesOperation.cs # 清理所有缓存 - ├── ClearUnusedCacheBundleFilesOperation.cs # 清理未使用缓存 - ├── ClearCacheBundleFilesByTagsOperaiton.cs # 按标签清理 - ├── ClearCacheBundleFilesByLocationsOperaiton.cs # 按位置清理 - ├── ClearAllCacheManifestFilesOperation.cs # 清理所有清单 - ├── ClearUnusedCacheManifestFilesOperation.cs # 清理未使用清单 - └── Scheduler/ # 下载调度器 - ├── DownloadSchedulerOperation.cs # 下载调度器 - ├── DownloadAndCacheFileOperation.cs # 下载并缓存基类 - ├── DownloadAndCacheRemoteFileOperation.cs # 远程文件下载 - └── DownloadAndCacheLocalFileOperation.cs # 本地文件拷贝 -``` - ---- - -## 核心类说明 - -### DefaultCacheFileSystem - -缓存文件系统的主类,实现 `IFileSystem` 接口。 - -#### 基本属性 - -| 属性 | 类型 | 说明 | -|------|------|------| -| `PackageName` | `string` | 包裹名称 | -| `FileRoot` | `string` | 缓存根目录 | -| `FileCount` | `int` | 已缓存文件数量 | -| `DownloadBackend` | `IDownloadBackend` | 下载后台接口 | -| `DownloadScheduler` | `DownloadSchedulerOperation` | 下载调度器 | - -#### 自定义参数 - -| 参数 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `RemoteServices` | `IRemoteServices` | - | 远程服务接口(必需) | -| `InstallClearMode` | `EOverwriteInstallClearMode` | `ClearAllManifestFiles` | 覆盖安装缓存清理模式 | -| `FileVerifyLevel` | `EFileVerifyLevel` | `Middle` | 初始化时文件校验级别 | -| `FileVerifyMaxConcurrency` | `int` | `32` | 文件校验最大并发数(1-256) | -| `AppendFileExtension` | `bool` | `false` | 数据文件追加文件扩展名 | -| `DisableOnDemandDownload` | `bool` | `false` | 禁用边玩边下机制 | -| `DownloadMaxConcurrency` | `int` | `10` | 最大并发下载数(1-64) | -| `DownloadMaxRequestPerFrame` | `int` | `5` | 每帧最大请求数(1-20) | -| `DownloadWatchDogTime` | `int` | `0` | 下载看门狗超时时间(秒) | -| `ResumeDownloadMinimumSize` | `long` | `long.MaxValue` | 启用断点续传的最小文件大小 | -| `ResumeDownloadResponseCodes` | `List` | `null` | 断点续传关注的HTTP错误码 | -| `DecryptionServices` | `IDecryptionServices` | `null` | 解密服务接口 | -| `ManifestServices` | `IManifestRestoreServices` | `null` | 清单服务接口 | -| `CopyLocalFileServices` | `ICopyLocalFileServices` | `null` | 本地文件拷贝服务 | - -#### 核心方法 - -```csharp -// 生命周期 -void OnCreate(string packageName, string packageRoot); -void OnDestroy(); -void SetParameter(string name, object value); - -// 异步操作 -FSInitializeFileSystemOperation InitializeFileSystemAsync(); -FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout); -FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout); -FSLoadBundleOperation LoadBundleFile(PackageBundle bundle); -FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options); -FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options); - -// 文件查询 -bool Belong(PackageBundle bundle); // 始终返回 true(保底加载) -bool Exists(PackageBundle bundle); // 检查文件是否已缓存 -bool NeedDownload(PackageBundle bundle); // 检查是否需要下载 -bool NeedUnpack(PackageBundle bundle); // 始终返回 false -bool NeedImport(PackageBundle bundle); // 检查是否需要导入 - -// 文件访问 -string GetBundleFilePath(PackageBundle bundle); -byte[] ReadBundleFileData(PackageBundle bundle); -string ReadBundleFileText(PackageBundle bundle); -``` - ---- - -## 缓存目录结构 - -``` -{CacheRoot}/{PackageName}/ -├── BundleFiles/ # 资源包文件目录 -│ ├── {Hash[0:2]}/ # 哈希前两位分组(256个目录) -│ │ ├── {BundleGUID}/ # 资源包 GUID 目录 -│ │ │ ├── __data # 数据文件(或 __data.bundle) -│ │ │ └── __info # 信息文件(CRC + Size) -│ │ └── ... -│ └── ... -├── ManifestFiles/ # 清单文件目录 -│ ├── {PackageName}_{Version}.bytes # 清单二进制文件 -│ ├── {PackageName}_{Version}.hash # 清单哈希文件 -│ └── __app_footprint.txt # 应用版本足迹文件 -└── TempFiles/ # 临时文件目录 - ├── {BundleGUID} # 下载中的临时文件 - └── ... -``` - -### 信息文件格式(__info) - -``` -| 字段 | 类型 | 大小 | 说明 | -|------|------|------|------| -| DataFileCRC | uint32 | 4 bytes | 数据文件 CRC | -| DataFileSize | int64 | 8 bytes | 数据文件大小 | -``` - ---- - -## 操作类说明 - -### DCFSInitializeOperation - -初始化操作,执行完整的缓存系统初始化流程。 - -``` -状态流程: -CheckAppFootPrint - ├── 版本相同 → 继续 - └── 版本不同 → 根据 InstallClearMode 清理缓存 - ↓ -SearchCacheFiles - └── SearchCacheFilesOperation - └── 遍历 BundleFiles 目录 - └── 收集需要验证的文件 - ↓ -VerifyCacheFiles - └── VerifyCacheFilesOperation(多线程) - ├── 验证成功 → 记录到 _records - └── 验证失败 → 删除损坏文件 - ↓ -CreateDownloadScheduler - └── 创建 DownloadSchedulerOperation - ↓ -Done → Status = Succeed -``` - -#### 状态机枚举 - -```csharp -private enum ESteps -{ - None, - CheckAppFootPrint, // 检查应用版本足迹 - SearchCacheFiles, // 搜索缓存文件 - VerifyCacheFiles, // 验证缓存文件 - CreateDownloadScheduler,// 创建下载调度器 - Done // 完成 -} -``` - -### DCFSLoadAssetBundleOperation - -加载 AssetBundle 操作,支持按需下载和多重容错机制。 - -``` -状态流程: -CheckExist - ├── 已缓存 → LoadAssetBundle - └── 未缓存 → 检查 DisableOnDemandDownload - ├── 禁用 → Failed - └── 启用 → DownloadFile - ↓ -DownloadFile - └── DownloadFileAsync() - ├── 下载成功 → LoadAssetBundle - └── 下载失败 → Failed - ↓ -LoadAssetBundle - ├── 未加密 → AssetBundle.LoadFromFile[Async] - └── 已加密 → DecryptionServices.LoadAssetBundle[Async] - ↓ -CheckResult - ├── 加载成功 → AssetBundleResult → Succeed - └── 加载失败 → 验证文件完整性 - ├── 验证通过 → LoadFromMemory 重试 - └── 验证失败 → 删除损坏文件 → Failed -``` - -#### 移动平台容错机制 - -```csharp -// 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。 -// 说明:大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发! -string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); -byte[] fileData = FileUtility.ReadAllBytes(filePath); -if (fileData != null && fileData.Length > 0) -{ - _assetBundle = AssetBundle.LoadFromMemory(fileData); - // ... -} -``` - -### DCFSLoadRawBundleOperation - -加载原生资源包操作,处理文件格式变更场景。 - -```csharp -// 注意:缓存的原生文件的格式,可能会在业务端根据需求发生变动! -// 注意:这里需要校验文件格式,如果不一致对本地文件进行修正! -if (File.Exists(filePath) == false) -{ - var recordFileElement = _fileSystem.GetRecordFileElement(_bundle); - File.Move(recordFileElement.DataFilePath, filePath); -} -``` - ---- - -## 下载调度器 - -### DownloadSchedulerOperation - -管理所有活跃的下载任务,控制并发数量。 - -#### 核心属性 - -| 属性 | 类型 | 说明 | -|------|------|------| -| `Paused` | `bool` | 是否已暂停 | -| `ActiveDownloadCount` | `int` | 当前活跃的下载任务数 | -| `PendingDownloadCount` | `int` | 当前等待中的下载任务数 | - -#### 工作原理 - -``` -InternalUpdate() - │ - ├── 1. 驱动下载后台 _fileSystem.DownloadBackend.Update() - │ - ├── 2. 遍历下载器集合 - │ ├── 已完成 → 加入移除列表 - │ └── RefCount <= 0 → 中止并移除 - │ - ├── 3. 移除已完成/中止的下载器 - │ - └── 4. 启动新下载任务(如未暂停) - ├── 计算可启动数量 = min(maxConcurrency - active, maxRequestPerFrame) - └── 启动等待中的下载器 -``` - -#### 引用计数机制 - -```csharp -// 查询旧的下载器(复用) -if (_downloaders.TryGetValue(bundle.BundleGUID, out var oldDownloader)) -{ - oldDownloader.Reference(); // 引用计数 +1 - return oldDownloader; -} - -// 创建新的下载器 -DownloadAndCacheFileOperation newDownloader; -// ... -newDownloader.Reference(); // 引用计数 +1 -``` - -### DownloadAndCacheRemoteFileOperation - -远程文件下载操作,支持断点续传。 - -``` -状态流程: -CreateRequest - ├── 文件大小 >= ResumeDownloadMinimumSize - │ └── CreateResumeRequest(断点续传) - └── 文件大小 < ResumeDownloadMinimumSize - └── CreateNormalRequest(普通下载) - ↓ -CheckRequest - ├── 下载成功 → VerifyBundleFile - └── 下载失败 → ClearTempFileWhenError → Failed - ↓ -VerifyBundleFile - └── VerifyTempFileOperation(多线程验证) - ├── 验证成功 → CacheBundleFile - └── 验证失败 → 删除临时文件 → Failed - ↓ -CacheBundleFile - └── WriteCacheBundleFile() - ├── 成功 → 删除临时文件 → Succeed - └── 失败 → Failed -``` - -#### 断点续传实现 - -```csharp -private IDownloadRequest CreateResumeRequest() -{ - // 获取下载起始位置 - if (File.Exists(_tempFilePath)) - { - FileInfo fileInfo = new FileInfo(_tempFilePath); - if (fileInfo.Length >= _bundle.FileSize) - { - File.Delete(_tempFilePath); // 文件已完整,删除重下 - } - else - { - _fileOriginLength = fileInfo.Length; // 记录已下载大小 - } - } - - var args = new DownloadFileRequestArgs( - URL, _tempFilePath, timeout, watchdogTime, - appendToFile: true, // 追加写入 - removeFileOnAbort: false, // 中止时保留文件 - resumeFromBytes: _fileOriginLength // 断点位置 - ); - return _fileSystem.DownloadBackend.CreateFileRequest(args); -} -``` - ---- - -## 缓存验证系统 - -### VerifyCacheFilesOperation - -多线程缓存文件验证,在初始化时执行。 - -#### 验证流程 - -``` -InitVerify - ├── 获取系统线程池信息 - └── 计算实际并发数 = min(threads, FileVerifyMaxConcurrency) - ↓ -UpdateVerify(循环) - ├── 检测已完成的验证任务 - │ ├── 验证成功 → RecordBundleFile - │ └── 验证失败 → DeleteFiles - │ - └── 启动新的验证任务 - └── ThreadPool.QueueUserWorkItem(VerifyInThread) -``` - -#### 验证级别 - -```csharp -private EFileVerifyResult VerifyingCacheFile(VerifyFileElement element, EFileVerifyLevel verifyLevel) -{ - if (verifyLevel == EFileVerifyLevel.Low) - { - // Low:仅检查文件存在 - if (File.Exists(element.InfoFilePath) == false) - return EFileVerifyResult.InfoFileNotExisted; - if (File.Exists(element.DataFilePath) == false) - return EFileVerifyResult.DataFileNotExisted; - return EFileVerifyResult.Succeed; - } - else - { - // Middle/High:检查文件存在 + CRC/Size 验证 - _fileSystem.ReadBundleInfoFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize); - return FileVerifyHelper.FileVerify(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel); - } -} -``` - -### VerifyTempFileOperation - -下载文件验证,在线程池中执行。 - -```csharp -private void VerifyInThread(object obj) -{ - TempFileElement element = (TempFileElement)obj; - int result = (int)FileVerifyHelper.FileVerify( - element.TempFilePath, - element.TempFileSize, - element.TempFileCRC, - EFileVerifyLevel.High // 始终使用高级验证 - ); - element.Result = result; // 线程安全的结果设置 -} -``` - ---- - -## 覆盖安装检测 - -### ApplicationFootPrint - -应用版本足迹,用于检测 App 覆盖安装。 - -```csharp -public static bool IsDirty(DefaultCacheFileSystem fileSystem) -{ - string filePath = fileSystem.GetSandboxAppFootPrintFilePath(); - if (File.Exists(filePath)) - { - string footPrint = FileUtility.ReadAllText(filePath); - return IsValidVersion(footPrint) == false; // 版本不同 - } - return true; // 文件不存在 -} -``` - -### EOverwriteInstallClearMode - -覆盖安装时的缓存清理模式。 - -| 枚举值 | 说明 | -|--------|------| -| `NeverClear` | 不清理任何缓存 | -| `ClearAllManifestFiles` | 清理所有清单文件(默认) | -| `ClearAllBundleAndManifestFiles` | 清理所有资源包和清单文件 | - ---- - -## 缓存清理操作 - -### 清理模式对照表 - -| 清理模式 | 操作类 | 说明 | -|----------|--------|------| -| `ClearAllBundleFiles` | `ClearAllCacheBundleFilesOperation` | 清理所有缓存资源包 | -| `ClearUnusedBundleFiles` | `ClearUnusedCacheBundleFilesOperation` | 清理不在清单中的资源包 | -| `ClearBundleFilesByTags` | `ClearCacheBundleFilesByTagsOperaiton` | 按标签清理 | -| `ClearBundleFilesByLocations` | `ClearCacheBundleFilesByLocationsOperaiton` | 按资源路径清理 | -| `ClearAllManifestFiles` | `ClearAllCacheManifestFilesOperation` | 清理所有清单文件 | -| `ClearUnusedManifestFiles` | `ClearUnusedCacheManifestFilesOperation` | 清理未使用的清单文件 | - -### 时间切片清理 - -```csharp -for (int i = _allBundleGUIDs.Count - 1; i >= 0; i--) -{ - string bundleGUID = _allBundleGUIDs[i]; - _fileSystem.DeleteCacheBundleFile(bundleGUID); - _allBundleGUIDs.RemoveAt(i); - - // 检查操作系统是否繁忙,避免阻塞主线程 - if (OperationSystem.IsBusy) - break; -} -``` - ---- - -## 元素类说明 - -### RecordFileElement - -缓存文件记录元素,存储已验证的缓存文件信息。 - -```csharp -internal class RecordFileElement -{ - public readonly string InfoFilePath; // 信息文件路径 - public readonly string DataFilePath; // 数据文件路径 - public readonly uint DataFileCRC; // 数据文件 CRC - public readonly long DataFileSize; // 数据文件大小 - - public bool DeleteFolder(); // 删除整个文件夹 -} -``` - -### TempFileElement - -临时文件元素,用于下载文件验证。 - -```csharp -internal class TempFileElement -{ - public readonly string TempFilePath; // 临时文件路径 - public readonly uint TempFileCRC; // 预期 CRC - public readonly long TempFileSize; // 预期文件大小 - - private int _result = 0; - public int Result // 线程安全的验证结果 - { - get => Interlocked.CompareExchange(ref _result, 0, 0); - set => Interlocked.Exchange(ref _result, value); - } -} -``` - -### VerifyFileElement - -验证文件元素,用于缓存文件批量验证。 - -```csharp -internal class VerifyFileElement -{ - public readonly string PackageName; // 包裹名称 - public readonly string BundleGUID; // 资源包 GUID - public readonly string FileRootPath; // 文件根目录 - public readonly string DataFilePath; // 数据文件路径 - public readonly string InfoFilePath; // 信息文件路径 - - public uint DataFileCRC; // 数据文件 CRC - public long DataFileSize; // 数据文件大小 - - private int _result = 0; - public int Result // 线程安全的验证结果 - { - get => Interlocked.CompareExchange(ref _result, 0, 0); - set => Interlocked.Exchange(ref _result, value); - } - - public void DeleteFiles(); // 删除所有相关文件 -} -``` - ---- - -## 使用示例 - -### 基础配置 - -```csharp -// 创建远程服务接口 -class GameRemoteServices : IRemoteServices -{ - public string GetRemoteMainURL(string fileName) - { - return $"https://cdn.example.com/bundles/{fileName}"; - } - public string GetRemoteFallbackURL(string fileName) - { - return $"https://cdn-backup.example.com/bundles/{fileName}"; - } -} - -// 创建缓存文件系统参数 -var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters( - remoteServices: new GameRemoteServices() -); - -// 初始化包裹 -var initParams = new HostPlayModeParameters(); -initParams.BuildinFileSystemParameters = buildinParams; -initParams.CacheFileSystemParameters = cacheParams; -var initOp = package.InitializeAsync(initParams); -``` - -### 配置下载参数 - -```csharp -var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters( - remoteServices: new GameRemoteServices() -); - -// 设置下载并发数 -cacheParams.AddParameter(FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY, 8); - -// 设置每帧最大请求数 -cacheParams.AddParameter(FileSystemParametersDefine.DOWNLOAD_MAX_REQUEST_PER_FRAME, 3); - -// 设置下载看门狗时间(秒) -cacheParams.AddParameter(FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME, 30); -``` - -### 配置断点续传 - -```csharp -var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters( - remoteServices: new GameRemoteServices() -); - -// 启用断点续传的最小文件大小(1MB) -cacheParams.AddParameter(FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE, 1024 * 1024); - -// 断点续传关注的HTTP错误码(这些错误码时删除临时文件重新下载) -var responseCodes = new List { 416 }; // Range Not Satisfiable -cacheParams.AddParameter(FileSystemParametersDefine.RESUME_DOWNLOAD_RESPONSE_CODES, responseCodes); -``` - -### 配置文件验证 - -```csharp -var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters( - remoteServices: new GameRemoteServices() -); - -// 设置验证级别 -cacheParams.AddParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, EFileVerifyLevel.High); - -// 设置验证并发数 -cacheParams.AddParameter(FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY, 64); -``` - -### 配置加密支持 - -```csharp -// 自定义解密服务 -class GameDecryptionServices : IDecryptionServices -{ - public DecryptResult LoadAssetBundle(DecryptFileInfo fileInfo) - { - // 实现解密逻辑 - byte[] data = DecryptFile(fileInfo.FileLoadPath); - AssetBundle bundle = AssetBundle.LoadFromMemory(data); - return new DecryptResult { Result = bundle }; - } - // ... -} - -var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters( - remoteServices: new GameRemoteServices() -); - -// 设置解密服务 -cacheParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, new GameDecryptionServices()); -``` - -### 配置覆盖安装行为 - -```csharp -var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters( - remoteServices: new GameRemoteServices() -); - -// 覆盖安装时清理所有资源包和清单 -cacheParams.AddParameter( - FileSystemParametersDefine.INSTALL_CLEAR_MODE, - EOverwriteInstallClearMode.ClearAllBundleAndManifestFiles -); -``` - -### 清理缓存 - -```csharp -// 清理所有缓存 -var clearOp = package.ClearCacheFilesAsync(EFileClearMode.ClearAllBundleFiles); -await clearOp.ToTask(); - -// 清理未使用的缓存 -var clearOp = package.ClearCacheFilesAsync(EFileClearMode.ClearUnusedBundleFiles); -await clearOp.ToTask(); - -// 按标签清理 -var clearOp = package.ClearCacheFilesAsync(EFileClearMode.ClearBundleFilesByTags, "dlc1"); -await clearOp.ToTask(); -``` - ---- - -## 参数常量 - -```csharp -// 远程服务 -FileSystemParametersDefine.REMOTE_SERVICES // IRemoteServices: 远程服务接口 - -// 覆盖安装 -FileSystemParametersDefine.INSTALL_CLEAR_MODE // EOverwriteInstallClearMode: 清理模式 - -// 文件验证 -FileSystemParametersDefine.FILE_VERIFY_LEVEL // EFileVerifyLevel: 验证级别 -FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY // int: 验证并发数 - -// 文件格式 -FileSystemParametersDefine.APPEND_FILE_EXTENSION // bool: 追加文件扩展名 - -// 下载控制 -FileSystemParametersDefine.DISABLE_ONDEMAND_DOWNLOAD // bool: 禁用边玩边下 -FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY // int: 下载并发数 -FileSystemParametersDefine.DOWNLOAD_MAX_REQUEST_PER_FRAME // int: 每帧请求数 -FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME // int: 看门狗时间 - -// 断点续传 -FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE // long: 最小文件大小 -FileSystemParametersDefine.RESUME_DOWNLOAD_RESPONSE_CODES // List: 关注错误码 - -// 服务接口 -FileSystemParametersDefine.DECRYPTION_SERVICES // IDecryptionServices: 解密服务 -FileSystemParametersDefine.MANIFEST_SERVICES // IManifestRestoreServices: 清单服务 -FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES // ICopyLocalFileServices: 本地拷贝服务 -``` - ---- - -## 类继承关系 - -``` -IFileSystem - └── DefaultCacheFileSystem - -FSInitializeFileSystemOperation - └── DCFSInitializeOperation - -FSRequestPackageVersionOperation - └── DCFSRequestPackageVersionOperation - -FSLoadPackageManifestOperation - └── DCFSLoadPackageManifestOperation - -FSLoadBundleOperation - ├── DCFSLoadAssetBundleOperation - └── DCFSLoadRawBundleOperation - -FSDownloadFileOperation - └── DownloadPackageBundleOperation - -FSClearCacheFilesOperation - ├── ClearAllCacheBundleFilesOperation - ├── ClearUnusedCacheBundleFilesOperation - ├── ClearCacheBundleFilesByTagsOperaiton - ├── ClearCacheBundleFilesByLocationsOperaiton - ├── ClearAllCacheManifestFilesOperation - └── ClearUnusedCacheManifestFilesOperation - -AsyncOperationBase - ├── DownloadSchedulerOperation - ├── DownloadAndCacheFileOperation (abstract) - │ ├── DownloadAndCacheRemoteFileOperation - │ └── DownloadAndCacheLocalFileOperation - ├── SearchCacheFilesOperation - ├── VerifyCacheFilesOperation - ├── VerifyTempFileOperation - ├── DownloadPackageHashOperation - ├── DownloadPackageManifestOperation - ├── LoadCachePackageHashOperation - ├── LoadCachePackageManifestOperation - └── RequestRemotePackageVersionOperation - -BundleResult - ├── AssetBundleResult ← AssetBundle 资源 - └── RawBundleResult ← 原生文件资源 -``` - ---- - -## 注意事项 - -1. **远程服务必需**:使用缓存文件系统必须配置 `IRemoteServices` 接口 -2. **保底加载**:缓存文件系统的 `Belong()` 始终返回 true,作为资源加载的保底方案 -3. **线程安全**:文件验证和下载使用后台线程,但核心逻辑仍在主线程执行 -4. **并发限制**:合理设置下载和验证的并发数,避免系统过载 -5. **移动平台**:Android 平台存在极小概率的 AssetBundle 加载失败,系统会自动尝试 LoadFromMemory 作为备选方案 -6. **断点续传**:启用断点续传时,需要合理设置 `ResumeDownloadMinimumSize` 和 `ResumeDownloadResponseCodes` -7. **覆盖安装**:App 版本更新时会自动检测并根据配置清理缓存,避免旧缓存导致问题 diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/README.md.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/README.md.meta deleted file mode 100644 index e822c168..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/README.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 8292f707fbf60854e852e1a75824d892 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs deleted file mode 100644 index eb0771e2..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs +++ /dev/null @@ -1,7 +0,0 @@ - -namespace YooAsset -{ - internal class DefaultEditorFileSystemDefine - { - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/README.md b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/README.md deleted file mode 100644 index b8c65e5d..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/README.md +++ /dev/null @@ -1,424 +0,0 @@ -# DefaultEditorFileSystem 编辑器模拟文件系统 - -## 模块概述 - -DefaultEditorFileSystem 是 YooAsset 的**编辑器模拟文件系统**,专为 Unity 编辑器开发环境设计。该文件系统无需构建实际的 AssetBundle 文件,直接使用 Unity 的 AssetDatabase API 加载资源,实现快速迭代开发。 - -### 核心特性 - -- **无需构建资源包**:直接使用 AssetDatabase 加载资源 -- **模拟下载流程**:支持模拟网络下载行为(用于 UI 调试) -- **模拟异步延迟**:可配置异步加载的模拟帧数 -- **WebGL 模式模拟**:支持模拟 WebGL 平台行为 - ---- - -## 设计目标 - -| 目标 | 说明 | -|------|------| -| **快速迭代** | 无需构建 AssetBundle,修改资源后立即生效 | -| **行为模拟** | 模拟真实环境的下载和加载行为 | -| **调试友好** | 支持 UI 进度条等功能的调试 | -| **零配置** | 开箱即用,最小化配置需求 | - ---- - -## 文件结构 - -``` -DefaultEditorFileSystem/ -├── DefaultEditorFileSystem.cs # 文件系统主类 -├── DefaultEditorFileSystemDefine.cs # 常量定义(预留) -└── Operation/ # 操作类 - ├── DEFSInitializeOperation.cs # 初始化操作 - ├── DEFSRequestPackageVersionOperation.cs # 请求版本操作 - ├── DEFSLoadPackageManifestOperation.cs # 加载清单操作 - ├── DEFSLoadBundleOperation.cs # 加载资源包操作 - └── internal/ # 内部操作类 - ├── DownloadVirutalBundleOperation.cs # 虚拟下载操作 - ├── LoadEditorPackageVersionOperation.cs # 加载版本文件操作 - ├── LoadEditorPackageHashOperation.cs # 加载哈希文件操作 - └── LoadEditorPackageManifestOperation.cs # 加载清单文件操作 -``` - ---- - -## 核心类说明 - -### DefaultEditorFileSystem - -编辑器模拟文件系统的主类,实现 `IFileSystem` 接口。 - -#### 基本属性 - -| 属性 | 类型 | 说明 | -|------|------|------| -| `PackageName` | `string` | 包裹名称 | -| `FileRoot` | `string` | 文件根目录(清单文件所在目录) | -| `FileCount` | `int` | 文件数量(始终返回 0) | -| `DownloadBackend` | `IDownloadBackend` | 下载后台接口 | - -#### 自定义参数 - -| 参数 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `VirtualWebGLMode` | `bool` | `false` | 模拟 WebGL 平台模式 | -| `VirtualDownloadMode` | `bool` | `false` | 模拟虚拟下载模式 | -| `VirtualDownloadSpeed` | `int` | `1024` | 模拟下载速度(字节/秒) | -| `AsyncSimulateMinFrame` | `int` | `1` | 异步加载最小模拟帧数 | -| `AsyncSimulateMaxFrame` | `int` | `1` | 异步加载最大模拟帧数 | - -#### 核心方法 - -```csharp -// 生命周期 -void OnCreate(string packageName, string packageRoot); -void OnDestroy(); -void SetParameter(string name, object value); - -// 异步操作 -FSInitializeFileSystemOperation InitializeFileSystemAsync(); -FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout); -FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout); -FSLoadBundleOperation LoadBundleFile(PackageBundle bundle); -FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options); -FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options); - -// 文件查询 -bool Belong(PackageBundle bundle); // 始终返回 true -bool Exists(PackageBundle bundle); // VirtualDownloadMode 时检查记录 -bool NeedDownload(PackageBundle bundle);// VirtualDownloadMode 时返回未记录的文件 -bool NeedUnpack(PackageBundle bundle); // 始终返回 false -bool NeedImport(PackageBundle bundle); // 始终返回 false - -// 文件访问 -string GetBundleFilePath(PackageBundle bundle); // 返回资源路径 -byte[] ReadBundleFileData(PackageBundle bundle); // 读取文件二进制 -string ReadBundleFileText(PackageBundle bundle); // 读取文件文本 -``` - ---- - -## 操作类说明 - -### DEFSInitializeOperation - -初始化操作,立即完成(无需任何初始化工作)。 - -``` -状态流程:InternalStart() → Status = Succeed -``` - -### DEFSRequestPackageVersionOperation - -请求包裹版本操作,从本地版本文件读取版本号。 - -``` -状态流程: -LoadPackageVersion - └── LoadEditorPackageVersionOperation - └── 读取 {PackageName}_Version.txt - ├── 成功 → PackageVersion = 文件内容 - └── 失败 → Error -``` - -### DEFSLoadPackageManifestOperation - -加载资源清单操作,从本地清单文件加载并解析清单。 - -``` -状态流程: -LoadEditorPackageHash - └── LoadEditorPackageHashOperation - └── 读取 {PackageName}_{Version}.hash - ├── 成功 → PackageHash - └── 失败 → Error - ↓ -LoadEditorPackageManifest - └── LoadEditorPackageManifestOperation - ├── 读取 {PackageName}_{Version}.bytes - ├── 验证哈希值 - └── 反序列化清单 - ├── 成功 → Manifest - └── 失败 → Error -``` - -### DEFSLoadBundleOperation - -加载资源包操作,支持虚拟下载模式和异步模拟延迟。 - -``` -状态流程: -CheckExist - ├── 文件存在 → LoadAssetBundle - └── 文件不存在 → DownloadFile - ↓ -DownloadFile - └── DownloadVirtualBundleOperation - ├── 模拟下载进度 - └── 记录下载完成 - ↓ -LoadAssetBundle - └── 等待模拟帧数 - ↓ -CheckResult - └── 创建 VirtualBundleResult → Status = Succeed -``` - -#### 状态机枚举 - -```csharp -private enum ESteps -{ - None, - CheckExist, // 检查文件是否存在 - DownloadFile, // 下载文件(虚拟下载) - AbortDownload, // 中断下载 - LoadAssetBundle, // 加载资源包(模拟延迟) - CheckResult, // 检查结果 - Done // 完成 -} -``` - -### DownloadVirtualBundleOperation - -虚拟下载操作,模拟网络下载行为。 - -**特性:** -- 使用 `VirtualFileDownloader` 模拟下载进度 -- 支持失败重试机制 -- 下载完成后记录到 `_records` 字典 - -``` -状态流程: -CheckExists - ├── 文件已记录 → Status = Succeed - └── 文件未记录 → CreateRequest - ↓ -CreateRequest - └── DownloadSimulateRequestArgs - ├── URL = BundleName - ├── FileSize = Bundle.FileSize - └── DownloadSpeed = VirtualDownloadSpeed - ↓ -CheckRequest - ├── 下载成功 → RecordDownloadFile() → Status = Succeed - └── 下载失败 → TryAgain 或 Status = Failed -``` - ---- - -## 内部操作类 - -### LoadEditorPackageVersionOperation - -从本地文件加载包裹版本号。 - -| 属性 | 说明 | -|------|------| -| `PackageVersion` | 读取到的版本号字符串 | - -### LoadEditorPackageHashOperation - -从本地文件加载包裹哈希值。 - -| 属性 | 说明 | -|------|------| -| `PackageHash` | 读取到的哈希值字符串 | - -### LoadEditorPackageManifestOperation - -加载并反序列化资源清单。 - -| 属性 | 说明 | -|------|------| -| `Manifest` | 反序列化后的清单对象 | - -**处理流程:** -1. 读取清单二进制文件 -2. 使用哈希值验证文件完整性 -3. 反序列化为 `PackageManifest` 对象 - ---- - -## 工作原理 - -### 资源加载机制 - -``` -用户请求加载资源 - │ - ▼ -DefaultEditorFileSystem.LoadBundleFile() - │ - ▼ -DEFSLoadBundleOperation - │ - ▼ -创建 VirtualBundleResult - │ - ▼ -VirtualBundleResult.LoadAssetAsync() - │ - ▼ -VirtualBundleLoadAssetOperation - │ - ▼ -AssetDatabase.LoadAssetAtPath() ← Unity 编辑器 API - │ - ▼ -返回资源对象 -``` - -### 虚拟下载模式 - -当 `VirtualDownloadMode = true` 时: - -1. **首次加载**:资源被视为"未下载",需要执行虚拟下载 -2. **虚拟下载**:使用 `VirtualFileDownloader` 模拟下载进度 -3. **记录完成**:下载完成后将 BundleGUID 记录到 `_records` 字典 -4. **后续加载**:检查 `_records` 字典,已记录的资源直接加载 - -```csharp -// 记录下载完成的文件 -protected readonly Dictionary _records; - -// 检查文件是否存在 -public virtual bool Exists(PackageBundle bundle) -{ - if (VirtualDownloadMode) - return _records.ContainsKey(bundle.BundleGUID); - else - return true; -} -``` - -### 异步模拟延迟 - -通过 `AsyncSimulateMinFrame` 和 `AsyncSimulateMaxFrame` 参数模拟异步加载延迟: - -```csharp -// 获取随机模拟帧数 -public int GetAsyncSimulateFrame() -{ - return UnityEngine.Random.Range(AsyncSimulateMinFrame, AsyncSimulateMaxFrame + 1); -} - -// 在 DEFSLoadBundleOperation 中等待 -if (_steps == ESteps.LoadAssetBundle) -{ - if (_asyncSimulateFrame <= 0) - _steps = ESteps.CheckResult; - else - _asyncSimulateFrame--; -} -``` - ---- - -## 使用示例 - -### 基础配置 - -```csharp -// 创建编辑器文件系统参数 -var editorParams = FileSystemParameters.CreateDefaultEditorFileSystemParameters( - packageRoot: "Assets/GameRes/Bundles/DefaultPackage" -); - -// 初始化包裹 -var initParams = new EditorSimulateModeParameters(); -initParams.EditorFileSystemParameters = editorParams; -var initOp = package.InitializeAsync(initParams); -``` - -### 启用虚拟下载模式 - -```csharp -var editorParams = FileSystemParameters.CreateDefaultEditorFileSystemParameters( - packageRoot: "Assets/GameRes/Bundles/DefaultPackage" -); - -// 启用虚拟下载模式 -editorParams.AddParameter(FileSystemParametersDefine.VIRTUAL_DOWNLOAD_MODE, true); -editorParams.AddParameter(FileSystemParametersDefine.VIRTUAL_DOWNLOAD_SPEED, 1024 * 100); // 100KB/s -``` - -### 配置异步模拟延迟 - -```csharp -var editorParams = FileSystemParameters.CreateDefaultEditorFileSystemParameters( - packageRoot: "Assets/GameRes/Bundles/DefaultPackage" -); - -// 设置异步加载延迟 1-3 帧 -editorParams.AddParameter(FileSystemParametersDefine.ASYNC_SIMULATE_MIN_FRAME, 1); -editorParams.AddParameter(FileSystemParametersDefine.ASYNC_SIMULATE_MAX_FRAME, 3); -``` - -### 模拟 WebGL 模式 - -```csharp -var editorParams = FileSystemParameters.CreateDefaultEditorFileSystemParameters( - packageRoot: "Assets/GameRes/Bundles/DefaultPackage" -); - -// 启用 WebGL 模拟模式 -editorParams.AddParameter(FileSystemParametersDefine.VIRTUAL_WEBGL_MODE, true); -``` - ---- - -## 参数常量 - -```csharp -// 模拟模式参数 -FileSystemParametersDefine.VIRTUAL_WEBGL_MODE // bool: 模拟 WebGL 模式 -FileSystemParametersDefine.VIRTUAL_DOWNLOAD_MODE // bool: 模拟下载模式 -FileSystemParametersDefine.VIRTUAL_DOWNLOAD_SPEED // int: 模拟下载速度(字节/秒) -FileSystemParametersDefine.ASYNC_SIMULATE_MIN_FRAME // int: 异步模拟最小帧数 -FileSystemParametersDefine.ASYNC_SIMULATE_MAX_FRAME // int: 异步模拟最大帧数 -``` - ---- - -## 类继承关系 - -``` -IFileSystem - └── DefaultEditorFileSystem - -FSInitializeFileSystemOperation - └── DEFSInitializeOperation - -FSRequestPackageVersionOperation - └── DEFSRequestPackageVersionOperation - -FSLoadPackageManifestOperation - └── DEFSLoadPackageManifestOperation - -FSLoadBundleOperation - └── DEFSLoadBundleOperation - -FSDownloadFileOperation - └── DownloadVirtualBundleOperation - -AsyncOperationBase - ├── LoadEditorPackageVersionOperation - ├── LoadEditorPackageHashOperation - └── LoadEditorPackageManifestOperation - -BundleResult - └── VirtualBundleResult ← 编辑器模式专用 -``` - ---- - -## 注意事项 - -1. **仅限编辑器**:此文件系统仅在 Unity 编辑器中有效 -2. **需要构建清单**:虽然不需要构建 AssetBundle,但需要构建资源清单文件 -3. **VirtualBundle 类型**:只支持 `EBuildBundleType.VirtualBundle` 类型的资源包 -4. **WebGL 模式限制**:`VirtualWebGLMode` 下不支持同步加载(`WaitForAsyncComplete`) -5. **性能差异**:编辑器模式下的加载性能与真机不同,仅供开发调试使用 diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/README.md.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/README.md.meta deleted file mode 100644 index 1d1a98f7..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/README.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 10ca037f4f07977458b8e94e4ea0f32c -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/README.md b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/README.md deleted file mode 100644 index 35eb1a09..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/README.md +++ /dev/null @@ -1,385 +0,0 @@ -# DefaultUnpackFileSystem 解压文件系统 - -## 模块概述 - -DefaultUnpackFileSystem 是 YooAsset 的**解压文件系统**,专为处理 Android 和 OpenHarmony 平台的内置资源解压需求而设计。该文件系统继承自 `DefaultCacheFileSystem`,复用其完整的下载、验证、缓存功能,仅重定义存储目录结构。 - -### 核心特性 - -- **继承复用**:完全继承 DefaultCacheFileSystem 的所有功能 -- **独立存储**:使用独立的目录存储解压后的资源 -- **本地下载**:通过 WWW 路径从 StreamingAssets "下载"资源 -- **平台适配**:解决 Android APK 内文件无法直接访问的问题 - ---- - -## 设计目标 - -| 目标 | 说明 | -|------|------| -| **平台兼容** | 解决 Android/OpenHarmony 平台 APK 内文件访问限制 | -| **代码复用** | 继承 DefaultCacheFileSystem,避免重复实现 | -| **资源隔离** | 解压资源与下载缓存分开存储,便于管理 | -| **透明集成** | 作为 DefaultBuildinFileSystem 的内部组件工作 | - ---- - -## 文件结构 - -``` -DefaultUnpackFileSystem/ -├── DefaultUnpackFileSystem.cs # 解压文件系统主类 -├── DefaultUnpackFileSystemDefine.cs # 常量定义 -└── DefaultUnpackRemoteServices.cs # 本地资源服务接口 -``` - ---- - -## 核心类说明 - -### DefaultUnpackFileSystem - -解压文件系统主类,继承自 `DefaultCacheFileSystem`。 - -```csharp -internal class DefaultUnpackFileSystem : DefaultCacheFileSystem -{ - public override void OnCreate(string packageName, string rootDirectory) - { - base.OnCreate(packageName, rootDirectory); - - // 重写保存根目录和临时目录 - _cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, "UnpackBundleFiles"); - _cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, "UnpackManifestFiles"); - _tempFilesRoot = PathUtility.Combine(_packageRoot, "UnpackTempFiles"); - } -} -``` - -#### 继承的功能 - -由于继承自 `DefaultCacheFileSystem`,DefaultUnpackFileSystem 拥有以下完整功能: - -| 功能 | 说明 | -|------|------| -| 文件下载 | 通过 DownloadScheduler 下载资源 | -| 断点续传 | 支持大文件断点续传 | -| 文件验证 | 多线程 CRC/Hash 验证 | -| 缓存管理 | 记录已解压文件,避免重复解压 | -| 加密支持 | 支持 IDecryptionServices 解密 | -| 覆盖安装检测 | App 版本变更时清理解压缓存 | - -### DefaultUnpackFileSystemDefine - -常量定义类,定义解压目录名称。 - -```csharp -internal class DefaultUnpackFileSystemDefine -{ - /// - /// 保存的资源文件的文件夹名称 - /// - public const string SaveBundleFilesFolderName = "UnpackBundleFiles"; - - /// - /// 保存的清单文件的文件夹名称 - /// - public const string SaveManifestFilesFolderName = "UnpackManifestFiles"; - - /// - /// 下载的临时文件的文件夹名称 - /// - public const string TempFilesFolderName = "UnpackTempFiles"; -} -``` - -### DefaultUnpackRemoteServices - -本地资源服务接口,将 StreamingAssets 路径转换为 WWW 请求路径。 - -```csharp -internal class DefaultUnpackRemoteServices : IRemoteServices -{ - private readonly string _buildinPackageRoot; - protected readonly Dictionary _mapping = new Dictionary(10000); - - public DefaultUnpackRemoteServices(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 = DownloadSystemHelper.ConvertToWWWPath(filePath); - _mapping.Add(fileName, url); - } - return url; - } -} -``` - -#### 路径转换示例 - -``` -输入文件名: bundle_abc123.bundle - -StreamingAssets 路径: - {Application.streamingAssetsPath}/DefaultPackage/bundle_abc123.bundle - -WWW 请求路径 (Android): - jar:file:///data/app/com.example.game.apk!/assets/DefaultPackage/bundle_abc123.bundle -``` - ---- - -## 目录结构 - -### 与 DefaultCacheFileSystem 对比 - -| 目录类型 | DefaultCacheFileSystem | DefaultUnpackFileSystem | -|----------|----------------------|------------------------| -| 资源文件 | `BundleFiles/` | `UnpackBundleFiles/` | -| 清单文件 | `ManifestFiles/` | `UnpackManifestFiles/` | -| 临时文件 | `TempFiles/` | `UnpackTempFiles/` | - -### 实际目录结构 - -``` -{SandboxRoot}/{PackageName}/ -├── BundleFiles/ # DefaultCacheFileSystem 下载缓存 -│ └── ... -├── ManifestFiles/ # DefaultCacheFileSystem 清单缓存 -│ └── ... -├── UnpackBundleFiles/ # DefaultUnpackFileSystem 解压缓存 -│ ├── {Hash[0:2]}/ -│ │ └── {BundleGUID}/ -│ │ ├── __data -│ │ └── __info -│ └── ... -├── UnpackManifestFiles/ # DefaultUnpackFileSystem 清单 -│ └── ... -└── UnpackTempFiles/ # DefaultUnpackFileSystem 临时文件 - └── ... -``` - ---- - -## 工作原理 - -### 解压触发条件 - -在 `DefaultBuildinFileSystem` 中,以下情况会触发解压: - -```csharp -protected virtual bool IsUnpackBundleFile(PackageBundle bundle) -{ - if (Belong(bundle) == false) - return false; - -#if UNITY_ANDROID || UNITY_OPENHARMONY - // Android/OpenHarmony 平台 - if (bundle.Encrypted) - return true; // 加密资源需要解压 - - if (bundle.BundleType == (int)EBuildBundleType.RawBundle) - return true; // 原生文件需要解压 - - return false; // 普通 AssetBundle 不需要解压 -#else - return false; // 其他平台不需要解压 -#endif -} -``` - -### 解压流程 - -``` -DefaultBuildinFileSystem - │ - ├── NeedUnpack(bundle) 检查 - │ └── IsUnpackBundleFile(bundle) - │ ├── Android/OpenHarmony 平台 - │ │ ├── 加密资源 → true - │ │ └── RawBundle → true - │ └── 其他平台 → false - │ - ├── 需要解压时 - │ └── _unpackFileSystem.DownloadFileAsync(bundle, options) - │ └── DefaultUnpackRemoteServices.GetRemoteMainURL() - │ └── 返回 StreamingAssets 的 WWW 路径 - │ ↓ - │ └── DownloadAndCacheRemoteFileOperation - │ ├── 从 APK 内 "下载" 资源 - │ ├── 验证文件完整性 - │ └── 保存到 UnpackBundleFiles 目录 - │ - └── 加载资源时 - └── _unpackFileSystem.LoadBundleFile(bundle) - └── 从 UnpackBundleFiles 加载 -``` - -### 资源加载委托 - -```csharp -// DefaultBuildinFileSystem.LoadBundleFile() -public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) -{ - // 需要解压的资源,委托给解压文件系统加载 - if (IsUnpackBundleFile(bundle)) - { - return _unpackFileSystem.LoadBundleFile(bundle); - } - - // 普通资源直接从 StreamingAssets 加载 - // ... -} -``` - ---- - -## 与 DefaultBuildinFileSystem 集成 - -### 初始化流程 - -```csharp -// DefaultBuildinFileSystem.OnCreate() -public virtual void OnCreate(string packageName, string packageRoot) -{ - // ... 基础初始化 ... - - // 创建解压文件系统 - var remoteServices = new DefaultUnpackRemoteServices(_packageRoot); - _unpackFileSystem = new DefaultUnpackFileSystem(); - - // 传递配置参数 - _unpackFileSystem.SetParameter(REMOTE_SERVICES, remoteServices); - _unpackFileSystem.SetParameter(INSTALL_CLEAR_MODE, InstallClearMode); - _unpackFileSystem.SetParameter(FILE_VERIFY_LEVEL, FileVerifyLevel); - _unpackFileSystem.SetParameter(FILE_VERIFY_MAX_CONCURRENCY, FileVerifyMaxConcurrency); - _unpackFileSystem.SetParameter(APPEND_FILE_EXTENSION, AppendFileExtension); - _unpackFileSystem.SetParameter(DECRYPTION_SERVICES, DecryptionServices); - _unpackFileSystem.SetParameter(COPY_LOCAL_FILE_SERVICES, CopyLocalFileServices); - - // 使用指定的解压根目录 - _unpackFileSystem.OnCreate(packageName, UnpackFileSystemRoot); -} -``` - -### 方法委托关系 - -| DefaultBuildinFileSystem 方法 | 解压资源时的委托目标 | -|------------------------------|-------------------| -| `LoadBundleFile()` | `_unpackFileSystem.LoadBundleFile()` | -| `GetBundleFilePath()` | `_unpackFileSystem.GetBundleFilePath()` | -| `ReadBundleFileData()` | `_unpackFileSystem.ReadBundleFileData()` | -| `ReadBundleFileText()` | `_unpackFileSystem.ReadBundleFileText()` | -| `DownloadFileAsync()` | `_unpackFileSystem.DownloadFileAsync()` | -| `ClearCacheFilesAsync()` | `_unpackFileSystem.ClearCacheFilesAsync()` | - ---- - -## 使用场景 - -### 场景 1:Android 加密资源 - -``` -问题:Android 平台无法直接从 APK 内读取文件进行解密 -解决:先解压到沙盒,再从沙盒读取并解密 - -流程: -1. 检测到加密资源 → IsUnpackBundleFile() = true -2. 首次加载 → NeedUnpack() = true -3. 执行解压 → DownloadFileAsync() 从 APK 复制到沙盒 -4. 后续加载 → NeedUnpack() = false,直接从沙盒加载 -``` - -### 场景 2:Android 原生文件 - -``` -问题:RawBundle 需要通过文件路径访问,APK 内路径不可直接访问 -解决:解压到沙盒,返回沙盒内的文件路径 - -流程: -1. 检测到 RawBundle → IsUnpackBundleFile() = true -2. 首次访问 → 解压到 UnpackBundleFiles -3. GetBundleFilePath() 返回沙盒路径 -4. 业务代码使用标准文件 API 访问 -``` - -### 场景 3:普通 AssetBundle - -``` -情况:Android 平台的普通(未加密)AssetBundle -处理:不需要解压,Unity 可以直接从 APK 内加载 - -流程: -1. IsUnpackBundleFile() = false -2. 直接使用 AssetBundle.LoadFromFile() 加载 -3. Unity 内部处理 APK 访问 -``` - ---- - -## 类继承关系 - -``` -IFileSystem - └── DefaultCacheFileSystem - └── DefaultUnpackFileSystem ← 仅重写目录名称 - -IRemoteServices - └── DefaultUnpackRemoteServices ← 本地 WWW 路径服务 -``` - ---- - -## 配置参数 - -DefaultUnpackFileSystem 继承 DefaultCacheFileSystem 的所有参数: - -| 参数 | 类型 | 说明 | -|------|------|------| -| `REMOTE_SERVICES` | `IRemoteServices` | 由 DefaultUnpackRemoteServices 提供 | -| `INSTALL_CLEAR_MODE` | `EOverwriteInstallClearMode` | 覆盖安装清理模式 | -| `FILE_VERIFY_LEVEL` | `EFileVerifyLevel` | 文件验证级别 | -| `FILE_VERIFY_MAX_CONCURRENCY` | `int` | 验证并发数 | -| `APPEND_FILE_EXTENSION` | `bool` | 追加文件扩展名 | -| `DECRYPTION_SERVICES` | `IDecryptionServices` | 解密服务 | -| `COPY_LOCAL_FILE_SERVICES` | `ICopyLocalFileServices` | 本地拷贝服务 | - ---- - -## 注意事项 - -1. **内部组件**:DefaultUnpackFileSystem 是 DefaultBuildinFileSystem 的内部组件,不建议单独使用 -2. **平台限定**:解压功能仅在 Android 和 OpenHarmony 平台生效 -3. **存储占用**:解压会额外占用设备存储空间(相当于资源的两份拷贝) -4. **首次加载**:需要解压的资源首次加载会有额外耗时 -5. **自动管理**:解压缓存由系统自动管理,包括覆盖安装时的清理 -6. **继承完整性**:继承了 DefaultCacheFileSystem 的所有功能,包括断点续传、多线程验证等 - ---- - -## 与其他文件系统对比 - -| 特性 | DefaultUnpackFileSystem | DefaultCacheFileSystem | -|------|------------------------|----------------------| -| 数据来源 | StreamingAssets (本地) | 远程服务器 | -| 主/备用地址 | 相同(本地路径) | 不同(CDN 地址) | -| 存储目录 | UnpackXxxFiles | XxxFiles | -| 使用方式 | 作为内部组件 | 独立使用 | -| 继承关系 | 子类 | 父类 | diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/README.md.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/README.md.meta deleted file mode 100644 index 4ab2604c..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/README.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 402224e40b04b0d458f12f5925d229b7 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/README.md b/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/README.md deleted file mode 100644 index c1169028..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/README.md +++ /dev/null @@ -1,504 +0,0 @@ -# DefaultWebRemoteFileSystem Web远程文件系统 - -## 模块概述 - -DefaultWebRemoteFileSystem 是 YooAsset 的 **Web 远程文件系统**,专为从远程服务器直接加载资源而设计。该文件系统不缓存文件到本地,每次都从远程 URL 加载资源,适用于 WebGL 平台的跨域资源加载或特殊的网络资源场景。 - -### 核心特性 - -- **无本地缓存**:直接从远程 URL 加载,不写入本地文件 -- **跨域支持**:通过 `IRemoteServices` 支持跨域资源下载 -- **Unity 缓存控制**:可选择禁用 Unity 的 Web 请求缓存 -- **加密支持**:支持 `IWebDecryptionServices` 解密 Web 资源 -- **失败重试**:内置下载失败自动重试机制 - ---- - -## 设计目标 - -| 目标 | 说明 | -|------|------| -| **轻量级** | 无缓存管理,结构简洁 | -| **即时加载** | 每次从远程获取最新资源 | -| **跨域兼容** | 支持 WebGL 平台的跨域限制处理 | -| **可配置** | 支持 Unity Web 缓存控制和自定义解密 | - ---- - -## 文件结构 - -``` -DefaultWebRemoteFileSystem/ -├── DefaultWebRemoteFileSystem.cs # 文件系统主类 -└── Operation/ # 操作类 - ├── DWRFSInitializeOperation.cs # 初始化操作 - ├── DWRFSRequestPackageVersionOperation.cs # 请求版本操作 - ├── DWRFSLoadPackageManifestOperation.cs # 加载清单操作 - └── DWRFSLoadBundleOperation.cs # 加载资源包操作 -``` - -### 依赖的共享模块 - -DefaultWebRemoteFileSystem 依赖 `WebGame` 目录下的共享操作类: - -``` -FileSystem/WebGame/Operation/ -├── LoadWebAssetBundleOperation.cs # Web 资源包加载基类 -├── LoadWebNormalAssetBundleOperation.cs # 普通资源包加载 -├── LoadWebEncryptAssetBundleOperation.cs # 加密资源包加载 -├── RequestWebPackageVersionOperation.cs # 请求版本文件 -├── RequestWebPackageHashOperation.cs # 请求哈希文件 -└── LoadWebPackageManifestOperation.cs # 加载清单文件 -``` - ---- - -## 核心类说明 - -### DefaultWebRemoteFileSystem - -Web 远程文件系统的主类,实现 `IFileSystem` 接口。 - -#### 基本属性 - -| 属性 | 类型 | 说明 | -|------|------|------| -| `PackageName` | `string` | 包裹名称 | -| `FileRoot` | `string` | 始终返回空字符串(无本地存储) | -| `FileCount` | `int` | 始终返回 0(无本地文件) | -| `DownloadBackend` | `IDownloadBackend` | 下载后台接口 | - -#### 自定义参数 - -| 参数 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `DisableUnityWebCache` | `bool` | `false` | 禁用 Unity 的网络缓存 | -| `RemoteServices` | `IRemoteServices` | - | 远程服务接口(必需) | -| `DecryptionServices` | `IWebDecryptionServices` | `null` | Web 解密服务接口 | -| `ManifestServices` | `IManifestRestoreServices` | `null` | 清单服务接口 | - -#### 核心方法 - -```csharp -// 生命周期 -void OnCreate(string packageName, string packageRoot); -void OnDestroy(); -void SetParameter(string name, object value); - -// 异步操作 -FSInitializeFileSystemOperation InitializeFileSystemAsync(); -FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout); -FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout); -FSLoadBundleOperation LoadBundleFile(PackageBundle bundle); -FSClearCacheFilesOperation ClearCacheFilesAsync(...); // 直接返回完成 - -// 不支持的操作 -FSDownloadFileOperation DownloadFileAsync(...); // 抛出 NotImplementedException -string GetBundleFilePath(...); // 抛出 NotImplementedException -byte[] ReadBundleFileData(...); // 抛出 NotImplementedException -string ReadBundleFileText(...); // 抛出 NotImplementedException - -// 文件查询(固定返回值) -bool Belong(PackageBundle bundle); // 始终返回 true -bool Exists(PackageBundle bundle); // 始终返回 true -bool NeedDownload(PackageBundle bundle);// 始终返回 false -bool NeedUnpack(PackageBundle bundle); // 始终返回 false -bool NeedImport(PackageBundle bundle); // 始终返回 false -``` - ---- - -## 操作类说明 - -### DWRFSInitializeOperation - -初始化操作,立即完成(无需任何初始化工作)。 - -```csharp -internal override void InternalStart() -{ - Status = EOperationStatus.Succeed; // 直接成功 -} -``` - -### DWRFSRequestPackageVersionOperation - -请求包裹版本操作,从远程服务器获取版本文件。 - -``` -状态流程: -RequestPackageVersion - └── RequestWebPackageVersionOperation - └── 请求 {PackageName}_Version.txt - ├── 成功 → PackageVersion = 文件内容 → Succeed - └── 失败 → Failed -``` - -#### 请求地址轮换 - -```csharp -// 轮流使用主地址和备用地址 -if (_requestCount % 2 == 0) - url = _remoteServices.GetRemoteMainURL(fileName); -else - url = _remoteServices.GetRemoteFallbackURL(fileName); - -// 可选:添加时间戳防止缓存 -if (_appendTimeTicks) - return $"{url}?{System.DateTime.UtcNow.Ticks}"; -``` - -### DWRFSLoadPackageManifestOperation - -加载资源清单操作,从远程下载并解析清单。 - -``` -状态流程: -RequestWebPackageHash - └── RequestWebPackageHashOperation - └── 请求 {PackageName}_{Version}.hash - ├── 成功 → PackageHash - └── 失败 → Failed - ↓ -LoadWebPackageManifest - └── LoadWebPackageManifestOperation - └── 请求 {PackageName}_{Version}.bytes - ├── 验证哈希 - └── 反序列化清单 - ├── 成功 → Manifest → Succeed - └── 失败 → Failed -``` - -### DWRFSLoadAssetBundleOperation - -加载资源包操作,从远程 URL 直接加载 AssetBundle。 - -``` -状态流程: -LoadWebAssetBundle - ├── 未加密 → LoadWebNormalAssetBundleOperation - │ └── UnityWebRequestAssetBundle.GetAssetBundle() - │ ├── 成功 → AssetBundle → AssetBundleResult - │ └── 失败 → TryAgain 或 Failed - │ - └── 已加密 → LoadWebEncryptAssetBundleOperation - └── DownloadBytesRequest - └── 下载原始字节 - └── IWebDecryptionServices.LoadAssetBundle() - ├── 成功 → AssetBundle → AssetBundleResult - └── 失败 → TryAgain 或 Failed -``` - -#### 状态机枚举 - -```csharp -private enum ESteps -{ - None, - LoadWebAssetBundle, // 加载 Web 资源包 - Done // 完成 -} -``` - -#### 同步加载限制 - -```csharp -internal override void InternalWaitForAsyncComplete() -{ - if (_steps != ESteps.Done) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "WebGL platform not support sync load method !"; - UnityEngine.Debug.LogError(Error); - } -} -``` - ---- - -## 共享 Web 操作类 - -### LoadWebNormalAssetBundleOperation - -普通(未加密)AssetBundle 的 Web 加载操作。 - -``` -CreateRequest - └── DownloadAssetBundleRequest - ├── URL: 主地址或备用地址(轮换) - ├── DisableUnityWebCache: 是否禁用缓存 - ├── FileHash: 用于 Unity 缓存键 - └── UnityCRC: CRC 验证 - ↓ -CheckRequest - ├── 成功 → Result = AssetBundle - └── 失败 → TryAgain(重试)或 Failed -``` - -#### Unity Web 缓存机制 - -```csharp -// 使用 Unity 的内置缓存 -var args = new DownloadAssetBundleRequestArgs( - url, - timeout: 0, - watchdogTime: 0, - disableUnityWebCache: _disableUnityWebCache, - cacheHash: _bundle.FileHash, // 缓存键 - unityCRC: _bundle.UnityCRC // CRC 验证 -); -``` - -### LoadWebEncryptAssetBundleOperation - -加密 AssetBundle 的 Web 加载操作。 - -``` -CreateRequest - └── 检查 DecryptionServices - ├── null → Failed - └── 有效 → DownloadBytesRequest - ↓ -CheckRequest - ├── 下载成功 → LoadEncryptedAssetBundle() - │ └── IWebDecryptionServices.LoadAssetBundle(fileData) - │ ├── 解密成功 → Result = AssetBundle - │ └── 解密失败 → Failed - └── 下载失败 → TryAgain 或 Failed -``` - -#### 加密资源加载 - -```csharp -private AssetBundle LoadEncryptedAssetBundle(byte[] fileData) -{ - var fileInfo = new WebDecryptFileInfo(); - fileInfo.BundleName = _bundle.BundleName; - fileInfo.FileLoadCRC = _bundle.UnityCRC; - fileInfo.FileData = fileData; // 下载的原始字节 - var decryptResult = _decryptionServices.LoadAssetBundle(fileInfo); - return decryptResult.Result; -} -``` - ---- - -## 失败重试机制 - -Web 加载操作内置失败重试机制: - -```csharp -// 检测下载结果 -if (_unityAssetBundleRequestOp.Status == EDownloadRequestStatus.Succeed) -{ - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - Result = _unityAssetBundleRequestOp.Result; -} -else -{ - if (_failedTryAgain > 0) - { - _steps = ESteps.TryAgain; - YooLogger.Warning($"Failed download : {url} Try again !"); - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _unityAssetBundleRequestOp.Error; - } -} - -// 重新尝试下载(1秒后) -if (_steps == ESteps.TryAgain) -{ - _tryAgainTimer += Time.unscaledDeltaTime; - if (_tryAgainTimer > 1f) - { - _tryAgainTimer = 0f; - _failedTryAgain--; - _steps = ESteps.CreateRequest; // 重新创建请求 - } -} -``` - ---- - -## 使用示例 - -### 基础配置 - -```csharp -// 创建远程服务接口 -class GameRemoteServices : IRemoteServices -{ - public string GetRemoteMainURL(string fileName) - { - return $"https://cdn.example.com/bundles/{fileName}"; - } - public string GetRemoteFallbackURL(string fileName) - { - return $"https://cdn-backup.example.com/bundles/{fileName}"; - } -} - -// 创建 Web 远程文件系统参数 -var webRemoteParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters( - remoteServices: new GameRemoteServices() -); - -// 初始化包裹(WebGL 模式) -var initParams = new WebPlayModeParameters(); -initParams.WebServerFileSystemParameters = webServerParams; -initParams.WebRemoteFileSystemParameters = webRemoteParams; -var initOp = package.InitializeAsync(initParams); -``` - -### 禁用 Unity Web 缓存 - -```csharp -var webRemoteParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters( - remoteServices: new GameRemoteServices() -); - -// 禁用 Unity 的 Web 请求缓存(始终获取最新资源) -webRemoteParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, true); -``` - -### 配置 Web 解密服务 - -```csharp -// 自定义 Web 解密服务 -class GameWebDecryptionServices : IWebDecryptionServices -{ - public WebDecryptResult LoadAssetBundle(WebDecryptFileInfo fileInfo) - { - // 解密下载的字节数据 - byte[] decryptedData = Decrypt(fileInfo.FileData); - AssetBundle bundle = AssetBundle.LoadFromMemory(decryptedData); - return new WebDecryptResult { Result = bundle }; - } -} - -var webRemoteParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters( - remoteServices: new GameRemoteServices() -); - -// 设置 Web 解密服务 -webRemoteParams.AddParameter( - FileSystemParametersDefine.DECRYPTION_SERVICES, - new GameWebDecryptionServices() -); -``` - -### 跨域资源加载 - -```csharp -// 跨域远程服务 -class CrossDomainRemoteServices : IRemoteServices -{ - private readonly string _mainDomain; - private readonly string _fallbackDomain; - - public CrossDomainRemoteServices(string mainDomain, string fallbackDomain) - { - _mainDomain = mainDomain; - _fallbackDomain = fallbackDomain; - } - - public string GetRemoteMainURL(string fileName) - { - // 主 CDN 域名 - return $"https://{_mainDomain}/assets/{fileName}"; - } - - public string GetRemoteFallbackURL(string fileName) - { - // 备用 CDN 域名 - return $"https://{_fallbackDomain}/assets/{fileName}"; - } -} - -// 使用跨域服务 -var remoteServices = new CrossDomainRemoteServices( - mainDomain: "cdn-us.example.com", - fallbackDomain: "cdn-eu.example.com" -); - -var webRemoteParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters( - remoteServices: remoteServices -); -``` - ---- - -## 参数常量 - -```csharp -// Unity 缓存控制 -FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE // bool: 禁用 Unity Web 缓存 - -// 服务接口 -FileSystemParametersDefine.REMOTE_SERVICES // IRemoteServices: 远程服务接口 -FileSystemParametersDefine.DECRYPTION_SERVICES // IWebDecryptionServices: Web 解密服务 -FileSystemParametersDefine.MANIFEST_SERVICES // IManifestRestoreServices: 清单服务 -``` - ---- - -## 类继承关系 - -``` -IFileSystem - └── DefaultWebRemoteFileSystem - -FSInitializeFileSystemOperation - └── DWRFSInitializeOperation - -FSRequestPackageVersionOperation - └── DWRFSRequestPackageVersionOperation - -FSLoadPackageManifestOperation - └── DWRFSLoadPackageManifestOperation - -FSLoadBundleOperation - └── DWRFSLoadAssetBundleOperation - -AsyncOperationBase - ├── LoadWebAssetBundleOperation (abstract) - │ ├── LoadWebNormalAssetBundleOperation - │ └── LoadWebEncryptAssetBundleOperation - ├── RequestWebPackageVersionOperation - ├── RequestWebPackageHashOperation - └── LoadWebPackageManifestOperation - -BundleResult - └── AssetBundleResult -``` - ---- - -## 与其他文件系统对比 - -| 特性 | DefaultWebRemoteFileSystem | DefaultCacheFileSystem | DefaultWebServerFileSystem | -|------|---------------------------|------------------------|---------------------------| -| 本地缓存 | ❌ 无 | ✅ 有 | ❌ 无 | -| 支持 RawBundle | ❌ | ✅ | ❌ | -| 同步加载 | ❌ | ✅ | ❌ | -| 断点续传 | ❌ | ✅ | ❌ | -| 跨域支持 | ✅ | ✅ | ✅ | -| 适用场景 | WebGL 跨域 | 常规游戏 | WebGL 同域 | - ---- - -## 注意事项 - -1. **仅支持 AssetBundle**:不支持 RawBundle 类型的资源加载 -2. **不支持同步加载**:WebGL 平台限制,`WaitForAsyncComplete()` 会直接返回失败 -3. **无本地缓存**:每次加载都从远程获取,注意网络流量 -4. **部分方法未实现**:`DownloadFileAsync`、`GetBundleFilePath`、`ReadBundleFileData`、`ReadBundleFileText` 会抛出异常 -5. **远程服务必需**:必须配置 `IRemoteServices` 接口 -6. **Unity 缓存**:默认使用 Unity 的 Web 请求缓存,可通过参数禁用 -7. **加密资源**:加密资源需要配置 `IWebDecryptionServices`(注意是 Web 专用接口,非 `IDecryptionServices`) diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/README.md.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/README.md.meta deleted file mode 100644 index b752b4fb..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/README.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 9f6744d0bcd43f84ea4279925784afb2 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/README.md b/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/README.md deleted file mode 100644 index 9cfffd8c..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/README.md +++ /dev/null @@ -1,525 +0,0 @@ -# DefaultWebServerFileSystem Web服务器文件系统 - -## 模块概述 - -DefaultWebServerFileSystem 是 YooAsset 的 **Web 服务器文件系统**,专为 WebGL 平台的**同域资源加载**而设计。该文件系统从与 WebGL 构建相同的服务器(StreamingAssets 目录)加载资源,通过 Catalog 目录文件管理内置资源清单。 - -### 核心特性 - -- **同域加载**:从 WebGL 构建所在服务器加载资源 -- **Catalog 管理**:通过目录文件追踪可用资源 -- **路径映射**:自动将本地路径转换为 WWW 路径 -- **Unity 缓存控制**:可选择禁用 Unity 的 Web 请求缓存 -- **加密支持**:支持 `IWebDecryptionServices` 解密 Web 资源 - ---- - -## 设计目标 - -| 目标 | 说明 | -|------|------| -| **WebGL 内置资源** | 加载与 WebGL 构建一起部署的资源 | -| **资源追踪** | 通过 Catalog 文件精确知道哪些资源可用 | -| **无跨域问题** | 从同一服务器加载,避免 CORS 问题 | -| **与 Buildin 对应** | WebGL 版本的 DefaultBuildinFileSystem | - ---- - -## 文件结构 - -``` -DefaultWebServerFileSystem/ -├── DefaultWebServerFileSystem.cs # 文件系统主类 -└── Operation/ # 操作类 - ├── DWSFSInitializeOperation.cs # 初始化操作 - ├── DWSFSRequestPackageVersionOperation.cs # 请求版本操作 - ├── DWSFSLoadPackageManifestOperation.cs # 加载清单操作 - ├── DWSFSLoadBundleOperation.cs # 加载资源包操作 - └── internal/ # 内部操作类 - ├── LoadWebServerCatalogFileOperation.cs # 加载目录文件 - ├── RequestWebServerPackageVersionOperation.cs # 请求版本文件 - ├── RequestWebServerPackageHashOperation.cs # 请求哈希文件 - └── LoadWebServerPackageManifestOperation.cs # 加载清单文件 -``` - -### 依赖的共享模块 - -DefaultWebServerFileSystem 依赖 `WebGame` 目录下的共享操作类: - -``` -FileSystem/WebGame/Operation/ -├── LoadWebAssetBundleOperation.cs # Web 资源包加载基类 -├── LoadWebNormalAssetBundleOperation.cs # 普通资源包加载 -└── LoadWebEncryptAssetBundleOperation.cs # 加密资源包加载 -``` - ---- - -## 核心类说明 - -### DefaultWebServerFileSystem - -Web 服务器文件系统的主类,实现 `IFileSystem` 接口。 - -#### 内部类 - -```csharp -public class FileWrapper -{ - public string FileName { private set; get; } - - public FileWrapper(string fileName) - { - FileName = fileName; - } -} -``` - -#### 基本属性 - -| 属性 | 类型 | 说明 | -|------|------|------| -| `PackageName` | `string` | 包裹名称 | -| `FileRoot` | `string` | Web 包裹根目录 | -| `FileCount` | `int` | 始终返回 0 | -| `DownloadBackend` | `IDownloadBackend` | 下载后台接口 | - -#### 自定义参数 - -| 参数 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `DisableUnityWebCache` | `bool` | `false` | 禁用 Unity 的网络缓存 | -| `DecryptionServices` | `IWebDecryptionServices` | `null` | Web 解密服务接口 | -| `ManifestServices` | `IManifestRestoreServices` | `null` | 清单服务接口 | - -#### 核心方法 - -```csharp -// 生命周期 -void OnCreate(string packageName, string packageRoot); -void OnDestroy(); -void SetParameter(string name, object value); - -// 异步操作 -FSInitializeFileSystemOperation InitializeFileSystemAsync(); -FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout); -FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout); -FSLoadBundleOperation LoadBundleFile(PackageBundle bundle); -FSClearCacheFilesOperation ClearCacheFilesAsync(...); // 直接返回完成 - -// 不支持的操作 -FSDownloadFileOperation DownloadFileAsync(...); // 抛出 NotImplementedException -string GetBundleFilePath(...); // 抛出 NotImplementedException -byte[] ReadBundleFileData(...); // 抛出 NotImplementedException -string ReadBundleFileText(...); // 抛出 NotImplementedException - -// 文件查询(基于 Catalog) -bool Belong(PackageBundle bundle); // 检查是否在 _wrappers 字典中 -bool Exists(PackageBundle bundle); // 检查是否在 _wrappers 字典中 -bool NeedDownload(PackageBundle bundle);// 始终返回 false -bool NeedUnpack(PackageBundle bundle); // 始终返回 false -bool NeedImport(PackageBundle bundle); // 始终返回 false -``` - -#### 内部方法 - -```csharp -// 路径获取 -string GetDefaultWebPackageRoot(string packageName); // 默认包裹根目录 -string GetWebFileLoadPath(PackageBundle bundle); // 资源文件加载路径 -string GetWebPackageVersionFilePath(); // 版本文件路径 -string GetWebPackageHashFilePath(string packageVersion); // 哈希文件路径 -string GetWebPackageManifestFilePath(string packageVersion); // 清单文件路径 -string GetCatalogBinaryFileLoadPath(); // Catalog 文件路径 - -// Catalog 管理 -bool RecordCatalogFile(string bundleGUID, FileWrapper wrapper); -``` - ---- - -## Catalog 目录系统 - -DefaultWebServerFileSystem 使用 Catalog 文件追踪可用的内置资源,这与 DefaultBuildinFileSystem 的机制相同。 - -### Catalog 文件 - -| 文件 | 路径 | 说明 | -|------|------|------| -| Catalog 二进制文件 | `{PackageRoot}/{PackageName}_buildin.bytes` | 资源目录信息 | - -### Catalog 数据结构 - -```csharp -// _wrappers 字典:BundleGUID → FileWrapper -protected readonly Dictionary _wrappers; - -// FileWrapper 包含文件名信息 -public class FileWrapper -{ - public string FileName { private set; get; } -} -``` - -### Belong 与 Exists 判断 - -```csharp -public virtual bool Belong(PackageBundle bundle) -{ - // 检查 Catalog 中是否包含该资源 - return _wrappers.ContainsKey(bundle.BundleGUID); -} - -public virtual bool Exists(PackageBundle bundle) -{ - // 同样基于 Catalog 判断 - return _wrappers.ContainsKey(bundle.BundleGUID); -} -``` - ---- - -## 操作类说明 - -### DWSFSInitializeOperation - -初始化操作,加载 Catalog 目录文件。 - -``` -状态流程: -LoadCatalogFile - └── LoadWebServerCatalogFileOperation - └── 请求 {PackageName}_buildin.bytes - ├── 下载二进制数据 - └── 反序列化 Catalog - ├── 验证 PackageName - └── 遍历 Wrappers - └── RecordCatalogFile() - ├── 成功 → Succeed - └── 失败 → Failed -``` - -### LoadWebServerCatalogFileOperation - -加载 Web 服务器 Catalog 文件的内部操作。 - -```csharp -// 关键流程 -if (_steps == ESteps.LoadCatalog) -{ - var catalog = CatalogTools.DeserializeFromBinary(_webDataRequestOp.Result); - - // 验证包裹名称 - if (catalog.PackageName != _fileSystem.PackageName) - { - Error = $"Catalog file package name {catalog.PackageName} cannot match..."; - return; - } - - // 记录所有内置资源 - foreach (var wrapper in catalog.Wrappers) - { - var fileWrapper = new DefaultWebServerFileSystem.FileWrapper(wrapper.FileName); - _fileSystem.RecordCatalogFile(wrapper.BundleGUID, fileWrapper); - } -} -``` - -### DWSFSRequestPackageVersionOperation - -请求包裹版本操作,从 Web 服务器获取版本文件。 - -``` -状态流程: -RequestPackageVersion - └── RequestWebServerPackageVersionOperation - └── 请求 {FileRoot}/{PackageName}_Version.txt - ├── 转换为 WWW 路径 - └── 下载文本内容 - ├── 成功 → PackageVersion - └── 失败 → Failed -``` - -### DWSFSLoadPackageManifestOperation - -加载资源清单操作,从 Web 服务器加载并解析清单。 - -``` -状态流程: -RequestWebPackageHash - └── RequestWebServerPackageHashOperation - └── 请求 {PackageName}_{Version}.hash - ├── 成功 → PackageHash - └── 失败 → Failed - ↓ -LoadWebPackageManifest - └── LoadWebServerPackageManifestOperation - ├── 请求 {PackageName}_{Version}.bytes - ├── 验证哈希 - └── 反序列化清单 - ├── 成功 → Manifest - └── 失败 → Failed -``` - -### LoadWebServerPackageManifestOperation - -加载清单文件的内部操作,包含哈希验证。 - -``` -状态流程: -RequestFileData - └── DownloadBytesRequest - └── 下载清单二进制数据 - ↓ -VerifyFileData - └── ManifestTools.VerifyManifestData() - ├── 验证成功 → LoadManifest - └── 验证失败 → Failed - ↓ -LoadManifest - └── DeserializeManifestOperation - ├── 反序列化成功 → Manifest → Succeed - └── 反序列化失败 → Failed -``` - -### DWSFSLoadAssetBundleOperation - -加载资源包操作,从 Web 服务器加载 AssetBundle。 - -``` -状态流程: -LoadWebAssetBundle - ├── 获取文件路径 → 转换为 WWW 路径 - │ - ├── 未加密 → LoadWebNormalAssetBundleOperation - │ └── UnityWebRequestAssetBundle - │ ├── 成功 → AssetBundleResult - │ └── 失败 → Failed - │ - └── 已加密 → LoadWebEncryptAssetBundleOperation - └── DownloadBytesRequest - └── IWebDecryptionServices.LoadAssetBundle() - ├── 成功 → AssetBundleResult - └── 失败 → Failed -``` - -#### 路径转换 - -```csharp -// 获取本地文件路径 -string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle); - -// 转换为 WWW 请求路径 -string mainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath); - -// 主 URL 和备用 URL 相同(同域加载) -DownloadFileOptions options = new DownloadFileOptions(int.MaxValue); -options.SetURL(mainURL, mainURL); -``` - -#### 同步加载限制 - -```csharp -internal override void InternalWaitForAsyncComplete() -{ - if (_steps != ESteps.Done) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "WebGL platform not support sync load method !"; - UnityEngine.Debug.LogError(Error); - } -} -``` - ---- - -## 路径映射机制 - -DefaultWebServerFileSystem 使用路径缓存优化性能: - -```csharp -// 文件路径缓存 -protected readonly Dictionary _webFilePathMapping = new Dictionary(10000); - -public string GetWebFileLoadPath(PackageBundle bundle) -{ - if (_webFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false) - { - // 组合路径:{WebPackageRoot}/{FileName} - filePath = PathUtility.Combine(_webPackageRoot, bundle.FileName); - _webFilePathMapping.Add(bundle.BundleGUID, filePath); - } - return filePath; -} -``` - -### 默认路径 - -```csharp -protected string GetDefaultWebPackageRoot(string packageName) -{ - // 使用默认的内置资源根目录(StreamingAssets) - string rootDirectory = YooAssetSettingsData.GetYooDefaultBuildinRoot(); - return PathUtility.Combine(rootDirectory, packageName); -} -``` - ---- - -## 与 DefaultWebRemoteFileSystem 对比 - -| 特性 | DefaultWebServerFileSystem | DefaultWebRemoteFileSystem | -|------|---------------------------|---------------------------| -| 用途 | WebGL 同域内置资源 | WebGL 跨域远程资源 | -| Catalog 系统 | ✅ 有 | ❌ 无 | -| Belong/Exists | 基于 Catalog 判断 | 始终返回 true | -| 远程服务 | ❌ 不需要 | ✅ 需要 IRemoteServices | -| URL 生成 | 本地路径转 WWW | 远程服务接口生成 | -| 主/备用地址 | 相同(同域) | 不同(可配置) | - ---- - -## 使用示例 - -### 基础配置 - -```csharp -// 创建 Web 服务器文件系统参数 -var webServerParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters(); - -// 初始化包裹(WebGL 模式) -var initParams = new WebPlayModeParameters(); -initParams.WebServerFileSystemParameters = webServerParams; -initParams.WebRemoteFileSystemParameters = webRemoteParams; // 可选:跨域资源 -var initOp = package.InitializeAsync(initParams); -``` - -### 自定义包裹根目录 - -```csharp -// 创建参数时指定自定义路径 -var webServerParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters( - packageRoot: "Assets/StreamingAssets/MyCustomPath/DefaultPackage" -); -``` - -### 禁用 Unity Web 缓存 - -```csharp -var webServerParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters(); - -// 禁用 Unity 的 Web 请求缓存 -webServerParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, true); -``` - -### 配置 Web 解密服务 - -```csharp -// 自定义 Web 解密服务 -class GameWebDecryptionServices : IWebDecryptionServices -{ - public WebDecryptResult LoadAssetBundle(WebDecryptFileInfo fileInfo) - { - byte[] decryptedData = Decrypt(fileInfo.FileData); - AssetBundle bundle = AssetBundle.LoadFromMemory(decryptedData); - return new WebDecryptResult { Result = bundle }; - } -} - -var webServerParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters(); - -// 设置 Web 解密服务 -webServerParams.AddParameter( - FileSystemParametersDefine.DECRYPTION_SERVICES, - new GameWebDecryptionServices() -); -``` - -### WebGL 双文件系统配置 - -```csharp -// WebGL 典型配置:内置 + 远程 -var webServerParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters(); -var webRemoteParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters( - remoteServices: new GameRemoteServices() -); - -var initParams = new WebPlayModeParameters(); -initParams.WebServerFileSystemParameters = webServerParams; // 同域内置资源 -initParams.WebRemoteFileSystemParameters = webRemoteParams; // 跨域热更资源 - -var initOp = package.InitializeAsync(initParams); -``` - ---- - -## 参数常量 - -```csharp -// Unity 缓存控制 -FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE // bool: 禁用 Unity Web 缓存 - -// 服务接口 -FileSystemParametersDefine.DECRYPTION_SERVICES // IWebDecryptionServices: Web 解密服务 -FileSystemParametersDefine.MANIFEST_SERVICES // IManifestRestoreServices: 清单服务 -``` - ---- - -## 类继承关系 - -``` -IFileSystem - └── DefaultWebServerFileSystem - -FSInitializeFileSystemOperation - └── DWSFSInitializeOperation - -FSRequestPackageVersionOperation - └── DWSFSRequestPackageVersionOperation - -FSLoadPackageManifestOperation - └── DWSFSLoadPackageManifestOperation - -FSLoadBundleOperation - └── DWSFSLoadAssetBundleOperation - -AsyncOperationBase - ├── LoadWebServerCatalogFileOperation - ├── RequestWebServerPackageVersionOperation - ├── RequestWebServerPackageHashOperation - ├── LoadWebServerPackageManifestOperation - └── LoadWebAssetBundleOperation (共享) - ├── LoadWebNormalAssetBundleOperation - └── LoadWebEncryptAssetBundleOperation - -BundleResult - └── AssetBundleResult -``` - ---- - -## 与 DefaultBuildinFileSystem 对比 - -| 特性 | DefaultWebServerFileSystem | DefaultBuildinFileSystem | -|------|---------------------------|-------------------------| -| 平台 | WebGL | 非 WebGL(移动端、PC) | -| 加载方式 | UnityWebRequest | AssetBundle.LoadFromFile | -| Catalog 系统 | ✅ 相同机制 | ✅ 相同机制 | -| 同步加载 | ❌ 不支持 | ✅ 支持 | -| 解包机制 | ❌ 无 | ✅ 有(Android APK) | -| 文件访问 | WWW 路径 | 本地文件路径 | - ---- - -## 注意事项 - -1. **WebGL 专用**:此文件系统专为 WebGL 平台设计,非 WebGL 平台应使用 DefaultBuildinFileSystem -2. **仅支持 AssetBundle**:不支持 RawBundle 类型的资源加载 -3. **不支持同步加载**:WebGL 平台限制,`WaitForAsyncComplete()` 会直接返回失败 -4. **Catalog 必需**:初始化时必须成功加载 Catalog 文件,否则无法确定资源归属 -5. **同域加载**:资源文件必须与 WebGL 构建在同一服务器上 -6. **部分方法未实现**:`DownloadFileAsync`、`GetBundleFilePath`、`ReadBundleFileData`、`ReadBundleFileText` 会抛出异常 -7. **加密资源**:加密资源需要配置 `IWebDecryptionServices`(Web 专用接口) -8. **路径缓存**:内部使用字典缓存路径映射,提升重复访问性能 diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/README.md.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/README.md.meta deleted file mode 100644 index fdb00a4d..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/README.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: ac4e3eb80a469df408bb2af7d57b3f8c -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystemParameters.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystemParameters.cs index 6a927ae5..881c763c 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystemParameters.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystemParameters.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace YooAsset @@ -73,7 +73,7 @@ namespace YooAsset /// public static FileSystemParameters CreateDefaultEditorFileSystemParameters(string packageRoot) { - string fileSystemClass = typeof(DefaultEditorFileSystem).FullName; + string fileSystemClass = typeof(EditorFileSystem).FullName; var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot); return fileSystemParams; } @@ -81,13 +81,11 @@ namespace YooAsset /// /// 创建默认的内置文件系统参数 /// - /// 加密文件解密服务类 /// 文件系统的根目录 - public static FileSystemParameters CreateDefaultBuildinFileSystemParameters(IDecryptionServices decryptionServices = null, string packageRoot = null) + public static FileSystemParameters CreateDefaultBuildinFileSystemParameters(string packageRoot = null) { - string fileSystemClass = typeof(DefaultBuildinFileSystem).FullName; + string fileSystemClass = typeof(BuiltinFileSystem).FullName; var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot); - fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices); return fileSystemParams; } @@ -95,14 +93,12 @@ namespace YooAsset /// 创建默认的缓存文件系统参数 /// /// 远端资源地址查询服务类 - /// 加密文件解密服务类 /// 文件系统的根目录 - public static FileSystemParameters CreateDefaultCacheFileSystemParameters(IRemoteServices remoteServices, IDecryptionServices decryptionServices = null, string packageRoot = null) + public static FileSystemParameters CreateDefaultCacheFileSystemParameters(IRemoteServices remoteServices, string packageRoot = null) { - string fileSystemClass = typeof(DefaultCacheFileSystem).FullName; + string fileSystemClass = typeof(CacheFileSystem).FullName; var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot); fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices); - fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices); return fileSystemParams; } @@ -111,11 +107,10 @@ namespace YooAsset /// /// 加密文件解密服务类 /// 禁用Unity的网络缓存 - public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(IWebDecryptionServices decryptionServices = null, bool disableUnityWebCache = false) + public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(bool disableUnityWebCache = false) { - string fileSystemClass = typeof(DefaultWebServerFileSystem).FullName; + string fileSystemClass = typeof(WebServerFileSystem).FullName; var fileSystemParams = new FileSystemParameters(fileSystemClass, null); - fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices); fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache); return fileSystemParams; } @@ -126,12 +121,11 @@ namespace YooAsset /// 远端资源地址查询服务类 /// 加密文件解密服务类 /// 禁用Unity的网络缓存 - public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteServices remoteServices, IWebDecryptionServices decryptionServices = null, bool disableUnityWebCache = false) + public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteServices remoteServices, bool disableUnityWebCache = false) { - string fileSystemClass = typeof(DefaultWebRemoteFileSystem).FullName; + string fileSystemClass = typeof(WebRemoteFileSystem).FullName; var fileSystemParams = new FileSystemParameters(fileSystemClass, null); fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices); - fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices); fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache); return fileSystemParams; } diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersDefine.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersConstants.cs similarity index 88% rename from Assets/YooAsset/Runtime/FileSystem/FileSystemParametersDefine.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystemParametersConstants.cs index b177c743..4009f23c 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersDefine.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersConstants.cs @@ -1,4 +1,4 @@ - + namespace YooAsset { public class FileSystemParametersDefine @@ -7,102 +7,132 @@ namespace YooAsset /// 初始化的时候缓存文件校验级别 /// public const string FILE_VERIFY_LEVEL = "FILE_VERIFY_LEVEL"; + /// /// 初始化的时候缓存文件校验最大并发数 /// public const string FILE_VERIFY_MAX_CONCURRENCY = "FILE_VERIFY_MAX_CONCURRENCY"; + /// /// 覆盖安装缓存清理模式 /// public const string INSTALL_CLEAR_MODE = "INSTALL_CLEAR_MODE"; + /// /// 远端资源地址查询服务类 /// public const string REMOTE_SERVICES = "REMOTE_SERVICES"; - /// - /// 解密服务接口的实例类 + + /// + /// 加载 AssetBundle 的 Operation 工厂委托 /// - public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES"; + 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_SERVICES = "MANIFEST_SERVICES"; + 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的网络缓存 /// public const string DISABLE_UNITY_WEB_CACHE = "DISABLE_UNITY_WEB_CACHE"; + /// /// 禁用边玩边下机制 /// public const string DISABLE_ONDEMAND_DOWNLOAD = "DISABLE_ONDEMAND_DOWNLOAD"; + /// /// UnityWebRequest 创建委托 /// public const string UNITY_WEB_REQUEST_CREATOR = "UNITY_WEB_REQUEST_CREATOR"; + /// /// 下载后台接口 /// public const string DOWNLOAD_BACKEND = "DOWNLOAD_BACKEND"; + /// /// 最大并发连接数 默认值:10(推荐范围 1-32) /// public const string DOWNLOAD_MAX_CONCURRENCY = "DOWNLOAD_MAX_CONCURRENCY"; + /// /// 每帧发起的最大请求数 默认值:5(推荐范围 1-10) /// public const string DOWNLOAD_MAX_REQUEST_PER_FRAME = "DOWNLOAD_MAX_REQUEST_PER_FRAME"; + /// - /// 下载任务的看门狗机制监控时间 + /// 下载任务的看门狗机制超时时间 /// public const string DOWNLOAD_WATCH_DOG_TIME = "DOWNLOAD_WATCH_DOG_TIME"; + /// /// 启用断点续传的最小尺寸 /// public const string RESUME_DOWNLOAD_MINMUM_SIZE = "RESUME_DOWNLOAD_MINMUM_SIZE"; + /// /// 断点续传下载器关注的错误码 > /// public const string RESUME_DOWNLOAD_RESPONSE_CODES = "RESUME_DOWNLOAD_RESPONSE_CODES"; + /// /// 模拟WebGL平台模式 /// public const string VIRTUAL_WEBGL_MODE = "VIRTUAL_WEBGL_MODE"; + /// /// 模拟虚拟下载模式 /// public const string VIRTUAL_DOWNLOAD_MODE = "VIRTUAL_DOWNLOAD_MODE"; + /// /// 模拟虚拟下载的网速(单位:字节) /// public const string VIRTUAL_DOWNLOAD_SPEED = "VIRTUAL_DOWNLOAD_SPEED"; + /// /// 异步模拟加载最小帧数 /// public const string ASYNC_SIMULATE_MIN_FRAME = "ASYNC_SIMULATE_MIN_FRAME"; + /// /// 异步模拟加载最大帧数 /// public const string ASYNC_SIMULATE_MAX_FRAME = "ASYNC_SIMULATE_MAX_FRAME"; + /// /// 拷贝内置清单 /// public const string COPY_BUILDIN_PACKAGE_MANIFEST = "COPY_BUILDIN_PACKAGE_MANIFEST"; + /// /// 拷贝内置清单的目标目录 /// 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/FileSystemParametersDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersConstants.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/FileSystemParametersDefine.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystemParametersConstants.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Interface.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems.meta similarity index 77% rename from Assets/YooAsset/Runtime/ResourcePackage/Interface.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems.meta index 8643af0d..8f69d97f 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Interface.meta +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e7f5776546411834d9ed949d54a6f241 +guid: e5d12b3682189a047b23ef6b5251a8fb folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileCatalog.cs similarity index 94% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileCatalog.cs index 6c59e986..7ef344c3 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileCatalog.cs @@ -8,7 +8,7 @@ namespace YooAsset /// 内置资源清单目录 /// [Serializable] - internal class DefaultBuildinFileCatalog + internal class BuiltinFileCatalog { [Serializable] public class FileWrapper diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileCatalog.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileCatalog.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystem.cs similarity index 63% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystem.cs index 9e339af6..38a312a2 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystem.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Collections.Generic; using UnityEngine; @@ -8,7 +8,7 @@ namespace YooAsset /// /// 内置文件系统 /// - internal class DefaultBuildinFileSystem : IFileSystem + internal class BuiltinFileSystem : IFileSystem { public class FileWrapper { @@ -21,7 +21,7 @@ namespace YooAsset } protected readonly Dictionary _wrappers = new Dictionary(10000); - protected readonly Dictionary _buildinFilePathMapping = new Dictionary(10000); + protected readonly Dictionary _builtinFilePathMapping = new Dictionary(10000); protected IFileSystem _unpackFileSystem; protected string _packageRoot; @@ -105,77 +105,83 @@ namespace YooAsset public string UnpackFileSystemRoot { private set; get; } /// - /// 自定义参数:解密服务接口的实例类 + /// 自定义参数:加载 AssetBundle 的工厂委托 /// - public IDecryptionServices DecryptionServices { private set; get; } + public LoadAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; } + + /// + /// 自定义参数:加载 RawBundle 的工厂委托 + /// + public LoadRawBundleOperationFactory LoadRawBundleFactory { private set; get; } /// /// 自定义参数:资源清单服务类 /// - public IManifestRestoreServices ManifestServices { private set; get; } + public IManifestRestoreServices ManifestRestoreServices { private set; get; } /// /// 自定义参数:拷贝内置文件接口的实例类 /// - public ICopyLocalFileServices CopyLocalFileServices { private set; get; } + public ILocalFileCopyServices CopyLocalFileServices { private set; get; } #endregion - public DefaultBuildinFileSystem() + public BuiltinFileSystem() { } - public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + public virtual FSInitializeOperation InitializeAsync() { var operation = new DBFSInitializeOperation(this); return operation; } - public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) + public virtual FSRequestVersionOperation RequestVersionAsync(RequestVersionOptions options) { - var operation = new DBFSLoadPackageManifestOperation(this, packageVersion); + var operation = new BFSRequestVersionOperation(this); return operation; } - public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout) + public virtual FSLoadManifestOperation LoadManifestAsync(LoadManifestOptions options) { - var operation = new DBFSRequestPackageVersionOperation(this); + var operation = new BFSLoadManifestOperation(this, options.PackageVersion); return operation; } - public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options) + public virtual FSClearCacheOperation ClearCacheAsync(ClearCacheOptions options) { - return _unpackFileSystem.ClearCacheFilesAsync(manifest, options); + return _unpackFileSystem.ClearCacheAsync(options); } - public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) + public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options) { // 注意:业务层的解压器会依赖该方法 - options.ImportFilePath = GetBuildinFileLoadPath(bundle); - return _unpackFileSystem.DownloadFileAsync(bundle, options); + options.ImportFilePath = GetBuiltinFileLoadPath(options.Bundle); + return _unpackFileSystem.DownloadFileAsync(options); } - public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) { + PackageBundle bundle = options.Bundle; if (IsUnpackBundleFile(bundle)) { - return _unpackFileSystem.LoadBundleFile(bundle); + return _unpackFileSystem.LoadBundleAsync(options); } - if (bundle.BundleType == (int)EBuildBundleType.AssetBundle) + if (bundle.BundleType == (int)EBundleType.AssetBundle) { - var operation = new DBFSLoadAssetBundleOperation(this, bundle); + var operation = new BFSLoadAssetBundleOperation(this, bundle); return operation; } - else if (bundle.BundleType == (int)EBuildBundleType.RawBundle) + else if (bundle.BundleType == (int)EBundleType.RawBundle) { - var operation = new DBFSLoadRawBundleOperation(this, bundle); + var operation = new BFSLoadRawBundleOperation(this, bundle); return operation; } #if TUANJIE_1_7_OR_NEWER - else if (bundle.BundleType == (int)EBuildBundleType.InstantBundle) + else if (bundle.BundleType == (int)EBundleType.InstantBundle) { - var operation = new DBFSLoadInstantBundleOperation(this, bundle); + var operation = new BFSLoadInstantBundleOperation(this, bundle); return operation; } #endif else { - string error = $"{nameof(DefaultBuildinFileSystem)} not support load bundle type : {bundle.BundleType}"; + string error = $"{nameof(BuiltinFileSystem)} not support load bundle type : {bundle.BundleType}"; var operation = new FSLoadBundleCompleteOperation(error); return operation; } @@ -224,17 +230,21 @@ namespace YooAsset { UnpackFileSystemRoot = (string)value; } - else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES) + else if (name == FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY) { - DecryptionServices = (IDecryptionServices)value; + LoadAssetBundleFactory = (LoadAssetBundleOperationFactory)value; } - else if (name == FileSystemParametersDefine.MANIFEST_SERVICES) + else if (name == FileSystemParametersDefine.LOAD_RAWBUNDLE_OPERATION_FACTORY) { - ManifestServices = (IManifestRestoreServices)value; + LoadRawBundleFactory = (LoadRawBundleOperationFactory)value; + } + else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES) + { + ManifestRestoreServices = (IManifestRestoreServices)value; } else if (name == FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES) { - CopyLocalFileServices = (ICopyLocalFileServices)value; + CopyLocalFileServices = (ILocalFileCopyServices)value; } else { @@ -246,7 +256,7 @@ namespace YooAsset PackageName = packageName; if (string.IsNullOrEmpty(packageRoot)) - _packageRoot = GetDefaultBuildinPackageRoot(packageName); + _packageRoot = GetDefaultBuiltinPackageRoot(packageName); else _packageRoot = packageRoot; @@ -254,9 +264,17 @@ namespace YooAsset if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); + // 创建默认的 AssetBundle 加载工厂 + if (LoadAssetBundleFactory == null) + LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory; + + // 创建默认的 RawBundle 加载工厂 + if (LoadRawBundleFactory == null) + LoadRawBundleFactory = DefaultLoadRawBundleOperationFactory; + // 创建解压文件系统 - var remoteServices = new DefaultUnpackRemoteServices(_packageRoot); - _unpackFileSystem = new DefaultUnpackFileSystem(); + 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); @@ -264,7 +282,8 @@ namespace YooAsset _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.DECRYPTION_SERVICES, DecryptionServices); + _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); } @@ -314,87 +333,14 @@ namespace YooAsset { return false; } - public virtual string GetBundleFilePath(PackageBundle bundle) { if (IsUnpackBundleFile(bundle)) + { return _unpackFileSystem.GetBundleFilePath(bundle); - - return GetBuildinFileLoadPath(bundle); - } - public virtual byte[] ReadBundleFileData(PackageBundle bundle) - { - if (IsUnpackBundleFile(bundle)) - return _unpackFileSystem.ReadBundleFileData(bundle); - - if (Exists(bundle) == false) - return null; - -#if UNITY_ANDROID - //TODO : 安卓平台内置文件属于APK压缩包内的文件。 - YooLogger.Error($"Android platform not support read buildin bundle file data !"); - return null; -#else - if (bundle.Encrypted) - { - if (DecryptionServices == null) - { - YooLogger.Error($"The {nameof(IDecryptionServices)} is null !"); - return null; - } - - string filePath = GetBuildinFileLoadPath(bundle); - var fileInfo = new DecryptFileInfo() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return DecryptionServices.ReadFileData(fileInfo); } - else - { - string filePath = GetBuildinFileLoadPath(bundle); - return FileUtility.ReadAllBytes(filePath); - } -#endif - } - public virtual string ReadBundleFileText(PackageBundle bundle) - { - if (IsUnpackBundleFile(bundle)) - return _unpackFileSystem.ReadBundleFileText(bundle); - if (Exists(bundle) == false) - return null; - -#if UNITY_ANDROID - //TODO : 安卓平台内置文件属于APK压缩包内的文件。 - YooLogger.Error($"Android platform not support read buildin bundle file text !"); - return null; -#else - if (bundle.Encrypted) - { - if (DecryptionServices == null) - { - YooLogger.Error($"The {nameof(IDecryptionServices)} is null !"); - return null; - } - - string filePath = GetBuildinFileLoadPath(bundle); - var fileInfo = new DecryptFileInfo() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return DecryptionServices.ReadFileText(fileInfo); - } - else - { - string filePath = GetBuildinFileLoadPath(bundle); - return FileUtility.ReadAllText(filePath); - } -#endif + return GetBuiltinFileLoadPath(bundle); } /// @@ -409,7 +355,7 @@ namespace YooAsset if (bundle.Encrypted) return true; - if (bundle.BundleType == (int)EBuildBundleType.RawBundle) + if (bundle.BundleType == (int)EBundleType.RawBundle) return true; return false; @@ -419,38 +365,62 @@ namespace YooAsset } #region 内部方法 - protected string GetDefaultBuildinPackageRoot(string packageName) + 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) { string rootDirectory = YooAssetSettingsData.GetYooDefaultBuildinRoot(); return PathUtility.Combine(rootDirectory, packageName); } - public string GetBuildinFileLoadPath(PackageBundle bundle) + public string GetBuiltinFileLoadPath(PackageBundle bundle) { - if (_buildinFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false) + if (_builtinFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false) { filePath = PathUtility.Combine(_packageRoot, bundle.FileName); - _buildinFilePathMapping.Add(bundle.BundleGUID, filePath); + _builtinFilePathMapping.Add(bundle.BundleGUID, filePath); } return filePath; } - public string GetBuildinPackageVersionFilePath() + public string GetBuiltinPackageVersionFilePath() { string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName); return PathUtility.Combine(_packageRoot, fileName); } - public string GetBuildinPackageHashFilePath(string packageVersion) + public string GetBuiltinPackageHashFilePath(string packageVersion) { string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion); return PathUtility.Combine(_packageRoot, fileName); } - public string GetBuildinPackageManifestFilePath(string packageVersion) + public string GetBuiltinPackageManifestFilePath(string packageVersion) { string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion); return PathUtility.Combine(_packageRoot, fileName); } public string GetCatalogBinaryFileLoadPath() { - return PathUtility.Combine(_packageRoot, DefaultBuildinFileSystemDefine.BuildinCatalogBinaryFileName); + return PathUtility.Combine(_packageRoot, BuiltinFileSystemConstants.BuiltinCatalogBinaryFileName); } /// @@ -460,7 +430,7 @@ namespace YooAsset { if (_wrappers.ContainsKey(bundleGUID)) { - YooLogger.Error($"{nameof(DefaultBuildinFileSystem)} has element : {bundleGUID}"); + YooLogger.Error($"{nameof(BuiltinFileSystem)} has element : {bundleGUID}"); return false; } @@ -471,39 +441,9 @@ namespace YooAsset /// /// 初始化解压文件系统 /// - public FSInitializeFileSystemOperation InitializeUpackFileSystem() + public FSInitializeOperation InitializeUnpackFileSystem() { - return _unpackFileSystem.InitializeFileSystemAsync(); - } - - /// - /// 加载加密的资源文件 - /// - public DecryptResult LoadEncryptedAssetBundle(PackageBundle bundle) - { - string filePath = GetBuildinFileLoadPath(bundle); - var fileInfo = new DecryptFileInfo() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return DecryptionServices.LoadAssetBundle(fileInfo); - } - - /// - /// 加载加密的资源文件 - /// - public DecryptResult LoadEncryptedAssetBundleAsync(PackageBundle bundle) - { - string filePath = GetBuildinFileLoadPath(bundle); - var fileInfo = new DecryptFileInfo() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return DecryptionServices.LoadAssetBundleAsync(fileInfo); + return _unpackFileSystem.InitializeAsync(); } #endregion } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystem.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystem.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystemConstants.cs similarity index 54% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystemConstants.cs index 59a67980..a6f4ef65 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystemConstants.cs @@ -1,16 +1,16 @@  namespace YooAsset { - internal class DefaultBuildinFileSystemDefine + internal class BuiltinFileSystemConstants { /// /// 内置清单JSON文件名称 /// - public const string BuildinCatalogJsonFileName = "BuildinCatalog.json"; + public const string BuiltinCatalogJsonFileName = "BuiltinCatalog.json"; /// /// 内置清单二进制文件名称 /// - public const string BuildinCatalogBinaryFileName = "BuildinCatalog.bytes"; + public const string BuiltinCatalogBinaryFileName = "BuiltinCatalog.bytes"; } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystemConstants.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystemConstants.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/CatalogDefine.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/CatalogFileConstants.cs similarity index 91% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/CatalogDefine.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/CatalogFileConstants.cs index 918e7718..f7cf1eb5 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/CatalogDefine.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/CatalogFileConstants.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class CatalogDefine + internal class CatalogFileConstants { /// /// 文件极限大小(100MB) diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/CatalogDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/CatalogFileConstants.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/CatalogDefine.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/CatalogFileConstants.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/CatalogTools.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/CatalogFileTools.cs similarity index 75% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/CatalogTools.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/CatalogFileTools.cs index 446c2ee1..a916eafc 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/CatalogTools.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/CatalogFileTools.cs @@ -5,14 +5,14 @@ using UnityEngine; namespace YooAsset { - internal static class CatalogTools + internal static class CatalogFileTools { #if UNITY_EDITOR /// /// 生成包裹的内置资源目录文件 /// 说明:根据指定目录下的文件生成清单文件。 /// - public static bool CreateCatalogFile(IManifestRestoreServices services, string packageName, string packageDirectory) + public static bool CreateFile(IManifestRestoreServices services, string packageName, string packageDirectory) { // 获取资源清单版本 string packageVersion; @@ -40,7 +40,7 @@ namespace YooAsset } var binaryData = FileUtility.ReadAllBytes(manifestFilePath); - packageManifest = ManifestTools.DeserializeFromBinary(binaryData, services); + packageManifest = PackageManifestTools.DeserializeFromBinary(binaryData, services); } // 获取文件名映射关系 @@ -53,8 +53,8 @@ namespace YooAsset } // 创建内置清单实例 - var buildinFileCatalog = new DefaultBuildinFileCatalog(); - buildinFileCatalog.FileVersion = CatalogDefine.FileVersion; + var buildinFileCatalog = new BuiltinFileCatalog(); + buildinFileCatalog.FileVersion = CatalogFileConstants.FileVersion; buildinFileCatalog.PackageName = packageName; buildinFileCatalog.PackageVersion = packageVersion; @@ -63,8 +63,8 @@ namespace YooAsset { "link.xml", "buildlogtep.json", - DefaultBuildinFileSystemDefine.BuildinCatalogJsonFileName, - DefaultBuildinFileSystemDefine.BuildinCatalogBinaryFileName + BuiltinFileSystemConstants.BuiltinCatalogJsonFileName, + BuiltinFileSystemConstants.BuiltinCatalogBinaryFileName }; string packageVersionFileName = YooAssetSettingsData.GetPackageVersionFileName(packageName); string packageHashFileName = YooAssetSettingsData.GetPackageHashFileName(packageName, packageVersion); @@ -91,7 +91,7 @@ namespace YooAsset string fileName = fileInfo.Name; if (fileMapping.TryGetValue(fileName, out string bundleGUID)) { - var wrapper = new DefaultBuildinFileCatalog.FileWrapper(); + var wrapper = new BuiltinFileCatalog.FileWrapper(); wrapper.BundleGUID = bundleGUID; wrapper.FileName = fileName; buildinFileCatalog.Wrappers.Add(wrapper); @@ -103,13 +103,13 @@ namespace YooAsset } // 创建输出文件 - string jsonFilePath = $"{packageDirectory}/{DefaultBuildinFileSystemDefine.BuildinCatalogJsonFileName}"; + string jsonFilePath = $"{packageDirectory}/{BuiltinFileSystemConstants.BuiltinCatalogJsonFileName}"; if (File.Exists(jsonFilePath)) File.Delete(jsonFilePath); SerializeToJson(jsonFilePath, buildinFileCatalog); // 创建输出文件 - string binaryFilePath = $"{packageDirectory}/{DefaultBuildinFileSystemDefine.BuildinCatalogBinaryFileName}"; + string binaryFilePath = $"{packageDirectory}/{BuiltinFileSystemConstants.BuiltinCatalogBinaryFileName}"; if (File.Exists(binaryFilePath)) File.Delete(binaryFilePath); SerializeToBinary(binaryFilePath, buildinFileCatalog); @@ -122,22 +122,22 @@ namespace YooAsset /// /// 生成空的包裹内置资源目录文件 /// - public static bool CreateEmptyCatalogFile(string packageName, string packageVersion, string outputPath) + public static bool CreateEmptyFile(string packageName, string packageVersion, string outputPath) { // 创建内置清单实例 - var buildinFileCatalog = new DefaultBuildinFileCatalog(); - buildinFileCatalog.FileVersion = CatalogDefine.FileVersion; + var buildinFileCatalog = new BuiltinFileCatalog(); + buildinFileCatalog.FileVersion = CatalogFileConstants.FileVersion; buildinFileCatalog.PackageName = packageName; buildinFileCatalog.PackageVersion = packageVersion; // 创建输出文件 - string jsonFilePath = $"{outputPath}/{DefaultBuildinFileSystemDefine.BuildinCatalogJsonFileName}"; + string jsonFilePath = $"{outputPath}/{BuiltinFileSystemConstants.BuiltinCatalogJsonFileName}"; if (File.Exists(jsonFilePath)) File.Delete(jsonFilePath); SerializeToJson(jsonFilePath, buildinFileCatalog); // 创建输出文件 - string binaryFilePath = $"{outputPath}/{DefaultBuildinFileSystemDefine.BuildinCatalogBinaryFileName}"; + string binaryFilePath = $"{outputPath}/{BuiltinFileSystemConstants.BuiltinCatalogBinaryFileName}"; if (File.Exists(binaryFilePath)) File.Delete(binaryFilePath); SerializeToBinary(binaryFilePath, buildinFileCatalog); @@ -151,7 +151,7 @@ namespace YooAsset /// /// 序列化(JSON文件) /// - public static void SerializeToJson(string savePath, DefaultBuildinFileCatalog catalog) + public static void SerializeToJson(string savePath, BuiltinFileCatalog catalog) { string json = JsonUtility.ToJson(catalog, true); FileUtility.WriteAllText(savePath, json); @@ -160,26 +160,26 @@ namespace YooAsset /// /// 反序列化(JSON文件) /// - public static DefaultBuildinFileCatalog DeserializeFromJson(string jsonContent) + public static BuiltinFileCatalog DeserializeFromJson(string jsonContent) { - return JsonUtility.FromJson(jsonContent); + return JsonUtility.FromJson(jsonContent); } /// /// 序列化(二进制文件) /// - public static void SerializeToBinary(string savePath, DefaultBuildinFileCatalog catalog) + public static void SerializeToBinary(string savePath, BuiltinFileCatalog catalog) { using (FileStream fs = new FileStream(savePath, FileMode.Create)) { // 创建缓存器 - BufferWriter buffer = new BufferWriter(CatalogDefine.FileMaxSize); + BufferWriter buffer = new BufferWriter(CatalogFileConstants.FileMaxSize); // 写入文件标记 - buffer.WriteUInt32(CatalogDefine.FileSign); + buffer.WriteUInt32(CatalogFileConstants.FileSign); // 写入文件版本 - buffer.WriteUTF8(CatalogDefine.FileVersion); + buffer.WriteUTF8(CatalogFileConstants.FileVersion); // 写入文件头信息 buffer.WriteUTF8(catalog.PackageName); @@ -203,25 +203,25 @@ namespace YooAsset /// /// 反序列化(二进制文件) /// - public static DefaultBuildinFileCatalog DeserializeFromBinary(byte[] binaryData) + public static BuiltinFileCatalog DeserializeFromBinary(byte[] binaryData) { if (binaryData == null || binaryData.Length == 0) - throw new Exception("Catalog file data is null or empty !"); + throw new Exception("Catalog file data is null or empty."); // 创建缓存器 BufferReader buffer = new BufferReader(binaryData); // 读取文件标记 uint fileSign = buffer.ReadUInt32(); - if (fileSign != CatalogDefine.FileSign) - throw new Exception("Invalid catalog file !"); + if (fileSign != CatalogFileConstants.FileSign) + throw new Exception("Invalid catalog file."); // 读取文件版本 string fileVersion = buffer.ReadUTF8(); - if (fileVersion != CatalogDefine.FileVersion) - throw new Exception($"The catalog file version are not compatible : {fileVersion} != {CatalogDefine.FileVersion}"); + if (fileVersion != CatalogFileConstants.FileVersion) + throw new Exception($"The catalog file version are not compatible : {fileVersion} != {CatalogFileConstants.FileVersion}"); - DefaultBuildinFileCatalog catalog = new DefaultBuildinFileCatalog(); + BuiltinFileCatalog catalog = new BuiltinFileCatalog(); { // 读取文件头信息 catalog.FileVersion = fileVersion; @@ -230,10 +230,10 @@ namespace YooAsset // 读取资源包列表 int fileCount = buffer.ReadInt32(); - catalog.Wrappers = new List(fileCount); + catalog.Wrappers = new List(fileCount); for (int i = 0; i < fileCount; i++) { - var fileWrapper = new DefaultBuildinFileCatalog.FileWrapper(); + var fileWrapper = new BuiltinFileCatalog.FileWrapper(); fileWrapper.BundleGUID = buffer.ReadUTF8(); fileWrapper.FileName = buffer.ReadUTF8(); catalog.Wrappers.Add(fileWrapper); diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/CatalogTools.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/CatalogFileTools.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/CatalogTools.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/CatalogFileTools.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSInitializeOperation.cs similarity index 88% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSInitializeOperation.cs index efbedff9..e99fc525 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSInitializeOperation.cs @@ -3,7 +3,7 @@ using System.IO; namespace YooAsset { - internal class DBFSInitializeOperation : FSInitializeFileSystemOperation + internal class DBFSInitializeOperation : FSInitializeOperation { private enum ESteps { @@ -16,15 +16,15 @@ namespace YooAsset Done, } - private readonly DefaultBuildinFileSystem _fileSystem; - private RequestBuildinPackageVersionOperation _requestBuildinPackageVersionOp; - private CopyBuildinFileOperation _copyBuildinHashFileOp; - private CopyBuildinFileOperation _copyBuildinManifestFileOp; - private FSInitializeFileSystemOperation _initUnpackFIleSystemOp; - private LoadBuildinCatalogFileOperation _loadBuildinCatalogFileOp; + private readonly BuiltinFileSystem _fileSystem; + private RequestBuiltinPackageVersionOperation _requestBuildinPackageVersionOp; + private CopyBuiltinFileOperation _copyBuildinHashFileOp; + private CopyBuiltinFileOperation _copyBuildinManifestFileOp; + private FSInitializeOperation _initUnpackFIleSystemOp; + private LoadBuiltinCatalogFileOperation _loadBuildinCatalogFileOp; private ESteps _steps = ESteps.None; - internal DBFSInitializeOperation(DefaultBuildinFileSystem fileSystem) + internal DBFSInitializeOperation(BuiltinFileSystem fileSystem) { _fileSystem = fileSystem; } @@ -33,7 +33,7 @@ namespace YooAsset #if UNITY_WEBGL _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"{nameof(DefaultBuildinFileSystem)} is not support WEBGL platform !"; + Error = $"{nameof(DefaultBuildinFileSystem)} is not support WEBGL platform."; #else if (_fileSystem.CopyBuildinPackageManifest) _steps = ESteps.LoadBuildinPackageVersion; @@ -50,7 +50,7 @@ namespace YooAsset { if (_requestBuildinPackageVersionOp == null) { - _requestBuildinPackageVersionOp = new RequestBuildinPackageVersionOperation(_fileSystem); + _requestBuildinPackageVersionOp = new RequestBuiltinPackageVersionOperation(_fileSystem); _requestBuildinPackageVersionOp.StartOperation(); AddChildOperation(_requestBuildinPackageVersionOp); } @@ -77,8 +77,8 @@ namespace YooAsset { string packageVersion = _requestBuildinPackageVersionOp.PackageVersion; string destFilePath = GetCopyPackageHashDestPath(packageVersion); - string sourceFilePath = _fileSystem.GetBuildinPackageHashFilePath(packageVersion); - _copyBuildinHashFileOp = new CopyBuildinFileOperation(_fileSystem, sourceFilePath, destFilePath); + string sourceFilePath = _fileSystem.GetBuiltinPackageHashFilePath(packageVersion); + _copyBuildinHashFileOp = new CopyBuiltinFileOperation(_fileSystem, sourceFilePath, destFilePath); _copyBuildinHashFileOp.StartOperation(); AddChildOperation(_copyBuildinHashFileOp); } @@ -105,8 +105,8 @@ namespace YooAsset { string packageVersion = _requestBuildinPackageVersionOp.PackageVersion; string destFilePath = GetCopyPackageManifestDestPath(packageVersion); - string sourceFilePath = _fileSystem.GetBuildinPackageManifestFilePath(packageVersion); - _copyBuildinManifestFileOp = new CopyBuildinFileOperation(_fileSystem, sourceFilePath, destFilePath); + string sourceFilePath = _fileSystem.GetBuiltinPackageManifestFilePath(packageVersion); + _copyBuildinManifestFileOp = new CopyBuiltinFileOperation(_fileSystem, sourceFilePath, destFilePath); _copyBuildinManifestFileOp.StartOperation(); AddChildOperation(_copyBuildinManifestFileOp); } @@ -131,7 +131,7 @@ namespace YooAsset { if (_initUnpackFIleSystemOp == null) { - _initUnpackFIleSystemOp = _fileSystem.InitializeUpackFileSystem(); + _initUnpackFIleSystemOp = _fileSystem.InitializeUnpackFileSystem(); _initUnpackFIleSystemOp.StartOperation(); AddChildOperation(_initUnpackFIleSystemOp); } @@ -165,7 +165,7 @@ namespace YooAsset { if (_loadBuildinCatalogFileOp == null) { - _loadBuildinCatalogFileOp = new LoadBuildinCatalogFileOperation(_fileSystem); + _loadBuildinCatalogFileOp = new LoadBuiltinCatalogFileOperation(_fileSystem); _loadBuildinCatalogFileOp.StartOperation(); AddChildOperation(_loadBuildinCatalogFileOp); } @@ -181,7 +181,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Fatal error : catalog is null !"; + Error = "Fatal error : catalog is null."; return; } @@ -195,7 +195,7 @@ namespace YooAsset foreach (var wrapper in catalog.Wrappers) { - var fileWrapper = new DefaultBuildinFileSystem.FileWrapper(wrapper.FileName); + var fileWrapper = new BuiltinFileSystem.FileWrapper(wrapper.FileName); _fileSystem.RecordCatalogFile(wrapper.BundleGUID, fileWrapper); } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSInitializeOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSInitializeOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadBundleOperation.cs similarity index 50% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadBundleOperation.cs index 9c363233..37670f3b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadBundleOperation.cs @@ -1,17 +1,190 @@ -using System.IO; +using System.IO; using UnityEngine; namespace YooAsset { /// - /// 加载AssetBundle文件 + /// 加载 AssetBundle 文件 /// - internal class DBFSLoadAssetBundleOperation : FSLoadBundleOperation + internal class BFSLoadAssetBundleOperation : FSLoadBundleOperation { private enum ESteps { None, - LoadAssetBundle, + LoadBuiltinAssetBundle, + CheckResult, + Done, + } + + private readonly BuiltinFileSystem _fileSystem; + private readonly PackageBundle _bundle; + private LoadAssetBundleOperation _loadAssetBundleOp; + private ESteps _steps = ESteps.None; + + + internal BFSLoadAssetBundleOperation(BuiltinFileSystem fileSystem, PackageBundle bundle) + { + _fileSystem = fileSystem; + _bundle = bundle; + } + internal override void InternalStart() + { + DownloadProgress = 1f; + DownloadedBytes = _bundle.FileSize; + _steps = ESteps.LoadBuiltinAssetBundle; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadBuiltinAssetBundle) + { + var options = new LoadAssetBundleOptions(); + options.FileLoadPath = _fileSystem.GetBuiltinFileLoadPath(_bundle); + options.Bundle = _bundle; + _loadAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options); + _loadAssetBundleOp.StartOperation(); + AddChildOperation(_loadAssetBundleOp); + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (IsWaitingForAsyncComplete) + _loadAssetBundleOp.WaitForAsyncComplete(); + + _loadAssetBundleOp.UpdateOperation(); + if (_loadAssetBundleOp.IsDone == false) + return; + + if (_loadAssetBundleOp.Status == EOperationStatus.Succeed) + { + if (_loadAssetBundleOp.Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Loaded builtin asset bundle is null."; + YooLogger.Error(Error); + } + else + { + _steps = ESteps.Done; + Result = new AssetBundleResult(_fileSystem, _bundle, _loadAssetBundleOp.Result, _loadAssetBundleOp.ManagedStream); + Status = EOperationStatus.Succeed; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadAssetBundleOp.Error; + YooLogger.Error(Error); + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + } + + /// + /// 加载 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 (IsWaitingForAsyncComplete) + _loadRawBundleOp.WaitForAsyncComplete(); + + _loadRawBundleOp.UpdateOperation(); + if (_loadRawBundleOp.IsDone == false) + return; + + if (_loadRawBundleOp.Status == EOperationStatus.Succeed) + { + 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.Succeed; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadRawBundleOp.Error; + YooLogger.Error(Error); + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + } + +#if TUANJIE_1_7_OR_NEWER + /// + /// 加载团结文件 + /// + internal class BFSLoadInstantBundleOperation : FSLoadBundleOperation + { + private enum ESteps + { + None, + LoadInstantBundle, CheckResult, Done, } @@ -24,7 +197,7 @@ namespace YooAsset private ESteps _steps = ESteps.None; - internal DBFSLoadAssetBundleOperation(DefaultBuildinFileSystem fileSystem, PackageBundle bundle) + internal BFSLoadInstantBundleOperation(DefaultBuildinFileSystem fileSystem, PackageBundle bundle) { _fileSystem = fileSystem; _bundle = bundle; @@ -33,14 +206,14 @@ namespace YooAsset { DownloadProgress = 1f; DownloadedBytes = _bundle.FileSize; - _steps = ESteps.LoadAssetBundle; + _steps = ESteps.LoadInstantBundle; } internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.LoadAssetBundle) + if (_steps == ESteps.LoadInstantBundle) { if (_bundle.Encrypted) { @@ -48,13 +221,13 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"The {nameof(IDecryptionServices)} is null !"; + Error = $"The {nameof(IDecryptionServices)} is null."; YooLogger.Error(Error); return; } } - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { if (_bundle.Encrypted) { @@ -90,7 +263,7 @@ namespace YooAsset { if (_createRequest != null) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { // 强制挂起主线程(注意:该操作会很耗时) YooLogger.Warning("Suspend the main thread to load unity bundle."); @@ -131,87 +304,8 @@ namespace YooAsset } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } } - - /// - /// 加载原生文件 - /// - internal class DBFSLoadRawBundleOperation : FSLoadBundleOperation - { - private enum ESteps - { - None, - LoadBuildinRawBundle, - Done, - } - - private readonly DefaultBuildinFileSystem _fileSystem; - private readonly PackageBundle _bundle; - private ESteps _steps = ESteps.None; - - - internal DBFSLoadRawBundleOperation(DefaultBuildinFileSystem fileSystem, PackageBundle bundle) - { - _fileSystem = fileSystem; - _bundle = bundle; - } - internal override void InternalStart() - { - DownloadProgress = 1f; - DownloadedBytes = _bundle.FileSize; - _steps = ESteps.LoadBuildinRawBundle; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.LoadBuildinRawBundle) - { - string filePath = _fileSystem.GetBuildinFileLoadPath(_bundle); - -#if UNITY_ANDROID - //TODO : 安卓平台内置文件属于APK压缩包内的文件。 - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Can not load android buildin raw bundle file : {filePath}"; - YooLogger.Error(Error); -#else - if (File.Exists(filePath)) - { - _steps = ESteps.Done; - Result = new RawBundleResult(_fileSystem, _bundle); - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Can not found buildin raw bundle file : {filePath}"; - YooLogger.Error(Error); - } #endif - } - } - internal override void InternalWaitForAsyncComplete() - { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } - } - } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadManifestOperation.cs new file mode 100644 index 00000000..aa3b24f9 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadManifestOperation.cs @@ -0,0 +1,89 @@ + +namespace YooAsset +{ + internal class BFSLoadManifestOperation : FSLoadManifestOperation + { + private enum ESteps + { + None, + RequestBuiltinPackageHash, + LoadBuiltinPackageManifest, + Done, + } + + private readonly BuiltinFileSystem _fileSystem; + private readonly string _packageVersion; + private RequestBuiltinPackageHashOperation _requestBuiltinPackageHashOp; + private LoadBuiltinPackageManifestOperation _loadBuiltinPackageManifestOp; + private ESteps _steps = ESteps.None; + + + public BFSLoadManifestOperation(BuiltinFileSystem fileSystem, string packageVersion) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + } + internal override void InternalStart() + { + _steps = ESteps.RequestBuiltinPackageHash; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestBuiltinPackageHash) + { + if (_requestBuiltinPackageHashOp == null) + { + _requestBuiltinPackageHashOp = new RequestBuiltinPackageHashOperation(_fileSystem, _packageVersion); + _requestBuiltinPackageHashOp.StartOperation(); + AddChildOperation(_requestBuiltinPackageHashOp); + } + + _requestBuiltinPackageHashOp.UpdateOperation(); + if (_requestBuiltinPackageHashOp.IsDone == false) + return; + + if (_requestBuiltinPackageHashOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadBuiltinPackageManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _requestBuiltinPackageHashOp.Error; + } + } + + if (_steps == ESteps.LoadBuiltinPackageManifest) + { + if (_loadBuiltinPackageManifestOp == null) + { + string packageHash = _requestBuiltinPackageHashOp.PackageHash; + _loadBuiltinPackageManifestOp = new LoadBuiltinPackageManifestOperation(_fileSystem, _packageVersion, packageHash); + _loadBuiltinPackageManifestOp.StartOperation(); + AddChildOperation(_loadBuiltinPackageManifestOp); + } + + _loadBuiltinPackageManifestOp.UpdateOperation(); + if (_loadBuiltinPackageManifestOp.IsDone == false) + return; + + if (_loadBuiltinPackageManifestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Manifest = _loadBuiltinPackageManifestOp.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadBuiltinPackageManifestOp.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSRequestPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSRequestVersionOperation.cs similarity index 52% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSRequestPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSRequestVersionOperation.cs index 24b4a6e8..fc807360 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSRequestPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSRequestVersionOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DBFSRequestPackageVersionOperation : FSRequestPackageVersionOperation + internal class BFSRequestVersionOperation : FSRequestVersionOperation { private enum ESteps { @@ -10,12 +10,12 @@ namespace YooAsset Done, } - private readonly DefaultBuildinFileSystem _fileSystem; - private RequestBuildinPackageVersionOperation _requestBuildinPackageVersionOp; + private readonly BuiltinFileSystem _fileSystem; + private RequestBuiltinPackageVersionOperation _requestBuiltinPackageVersionOp; private ESteps _steps = ESteps.None; - internal DBFSRequestPackageVersionOperation(DefaultBuildinFileSystem fileSystem) + internal BFSRequestVersionOperation(BuiltinFileSystem fileSystem) { _fileSystem = fileSystem; } @@ -30,28 +30,28 @@ namespace YooAsset if (_steps == ESteps.RequestPackageVersion) { - if (_requestBuildinPackageVersionOp == null) + if (_requestBuiltinPackageVersionOp == null) { - _requestBuildinPackageVersionOp = new RequestBuildinPackageVersionOperation(_fileSystem); - _requestBuildinPackageVersionOp.StartOperation(); - AddChildOperation(_requestBuildinPackageVersionOp); + _requestBuiltinPackageVersionOp = new RequestBuiltinPackageVersionOperation(_fileSystem); + _requestBuiltinPackageVersionOp.StartOperation(); + AddChildOperation(_requestBuiltinPackageVersionOp); } - _requestBuildinPackageVersionOp.UpdateOperation(); - if (_requestBuildinPackageVersionOp.IsDone == false) + _requestBuiltinPackageVersionOp.UpdateOperation(); + if (_requestBuiltinPackageVersionOp.IsDone == false) return; - if (_requestBuildinPackageVersionOp.Status == EOperationStatus.Succeed) + if (_requestBuiltinPackageVersionOp.Status == EOperationStatus.Succeed) { _steps = ESteps.Done; - PackageVersion = _requestBuildinPackageVersionOp.PackageVersion; + PackageVersion = _requestBuiltinPackageVersionOp.PackageVersion; Status = EOperationStatus.Succeed; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _requestBuildinPackageVersionOp.Error; + Error = _requestBuiltinPackageVersionOp.Error; } } } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSRequestVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSRequestPackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSRequestVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/CopyBuildinFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/CopyBuiltinFileOperation.cs similarity index 90% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/CopyBuildinFileOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/CopyBuiltinFileOperation.cs index 7f0b8c9a..44e0fa7d 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/CopyBuildinFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/CopyBuiltinFileOperation.cs @@ -3,7 +3,7 @@ using System.IO; namespace YooAsset { - internal class CopyBuildinFileOperation : AsyncOperationBase + internal class CopyBuiltinFileOperation : AsyncOperationBase { private enum ESteps { @@ -14,13 +14,13 @@ namespace YooAsset Done, } - private readonly DefaultBuildinFileSystem _fileSystem; + private readonly BuiltinFileSystem _fileSystem; private readonly string _sourceFilePath; private readonly string _destFilePath; private IDownloadFileRequest _webFileRequestOp; private ESteps _steps = ESteps.None; - public CopyBuildinFileOperation(DefaultBuildinFileSystem fileSystem, string sourceFilePath, string destFilePath) + public CopyBuiltinFileOperation(BuiltinFileSystem fileSystem, string sourceFilePath, string destFilePath) { _fileSystem = fileSystem; _sourceFilePath = sourceFilePath; @@ -77,7 +77,7 @@ namespace YooAsset { if (_webFileRequestOp == null) { - string url = DownloadSystemHelper.ConvertToWWWPath(_sourceFilePath); + string url = DownloadSystemTools.ToLocalURL(_sourceFilePath); var args = new DownloadFileRequestArgs(url, _destFilePath, 60, 0); _webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args); _webFileRequestOp.SendRequest(); diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/CopyBuildinFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/CopyBuiltinFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/CopyBuildinFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/CopyBuiltinFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/LoadBuiltinCatalogFileOperation.cs similarity index 86% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/LoadBuiltinCatalogFileOperation.cs index 22702aa4..179126ff 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/LoadBuiltinCatalogFileOperation.cs @@ -3,7 +3,7 @@ using System.IO; namespace YooAsset { - internal sealed class LoadBuildinCatalogFileOperation : AsyncOperationBase + internal sealed class LoadBuiltinCatalogFileOperation : AsyncOperationBase { private enum ESteps { @@ -14,7 +14,7 @@ namespace YooAsset Done, } - private readonly DefaultBuildinFileSystem _fileSystem; + private readonly BuiltinFileSystem _fileSystem; private IDownloadBytesRequest _webDataRequestOp; private byte[] _fileData; private ESteps _steps = ESteps.None; @@ -22,9 +22,9 @@ namespace YooAsset /// /// 内置资源目录 /// - public DefaultBuildinFileCatalog Catalog; + public BuiltinFileCatalog Catalog; - internal LoadBuildinCatalogFileOperation(DefaultBuildinFileSystem fileSystem) + internal LoadBuiltinCatalogFileOperation(BuiltinFileSystem fileSystem) { _fileSystem = fileSystem; } @@ -56,7 +56,7 @@ namespace YooAsset if (_webDataRequestOp == null) { string filePath = _fileSystem.GetCatalogBinaryFileLoadPath(); - string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + string url = DownloadSystemTools.ToLocalURL(filePath); var args = new DownloadDataRequestArgs(url, 60, 0); _webDataRequestOp = _fileSystem.DownloadBackend.CreateBytesRequest(args); _webDataRequestOp.SendRequest(); @@ -82,7 +82,7 @@ namespace YooAsset { try { - Catalog = CatalogTools.DeserializeFromBinary(_fileData); + Catalog = CatalogFileTools.DeserializeFromBinary(_fileData); _steps = ESteps.Done; Status = EOperationStatus.Succeed; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/LoadBuiltinCatalogFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/LoadBuiltinCatalogFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/LoadBuiltinPackageManifestOperation.cs similarity index 85% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/LoadBuiltinPackageManifestOperation.cs index 2e28c6e5..0a60f4a9 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/LoadBuiltinPackageManifestOperation.cs @@ -2,7 +2,7 @@ namespace YooAsset { - internal class LoadBuildinPackageManifestOperation : AsyncOperationBase + internal class LoadBuiltinPackageManifestOperation : AsyncOperationBase { private enum ESteps { @@ -14,7 +14,7 @@ namespace YooAsset Done, } - private readonly DefaultBuildinFileSystem _fileSystem; + private readonly BuiltinFileSystem _fileSystem; private readonly string _packageVersion; private readonly string _packageHash; private IDownloadBytesRequest _webDataRequestOp; @@ -28,7 +28,7 @@ namespace YooAsset public PackageManifest Manifest { private set; get; } - internal LoadBuildinPackageManifestOperation(DefaultBuildinFileSystem fileSystem, string packageVersion, string packageHash) + internal LoadBuiltinPackageManifestOperation(BuiltinFileSystem fileSystem, string packageVersion, string packageHash) { _fileSystem = fileSystem; _packageVersion = packageVersion; @@ -45,7 +45,7 @@ namespace YooAsset if (_steps == ESteps.TryLoadFileData) { - string filePath = _fileSystem.GetBuildinPackageManifestFilePath(_packageVersion); + string filePath = _fileSystem.GetBuiltinPackageManifestFilePath(_packageVersion); if (File.Exists(filePath)) { _fileData = File.ReadAllBytes(filePath); @@ -61,8 +61,8 @@ namespace YooAsset { if (_webDataRequestOp == null) { - string filePath = _fileSystem.GetBuildinPackageManifestFilePath(_packageVersion); - string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + string filePath = _fileSystem.GetBuiltinPackageManifestFilePath(_packageVersion); + string url = DownloadSystemTools.ToLocalURL(filePath); var args = new DownloadDataRequestArgs(url, 60, 0); _webDataRequestOp = _fileSystem.DownloadBackend.CreateBytesRequest(args); _webDataRequestOp.SendRequest(); @@ -86,7 +86,7 @@ namespace YooAsset if (_steps == ESteps.VerifyFileData) { - if (ManifestTools.VerifyManifestData(_fileData, _packageHash)) + if (PackageManifestTools.VerifyManifestData(_fileData, _packageHash)) { _steps = ESteps.LoadManifest; } @@ -94,7 +94,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Failed to verify buildin package manifest file !"; + Error = "Failed to verify buildin package manifest file."; } } @@ -102,7 +102,7 @@ namespace YooAsset { if (_deserializer == null) { - _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _fileData); + _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestRestoreServices, _fileData); _deserializer.StartOperation(); AddChildOperation(_deserializer); } @@ -126,7 +126,7 @@ namespace YooAsset } } } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { return $"PackageVersion : {_packageVersion} PackageHash : {_packageHash}"; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/LoadBuiltinPackageManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/LoadBuiltinPackageManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/RequestBuiltinPackageHashOperation.cs similarity index 83% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/RequestBuiltinPackageHashOperation.cs index f4ec7f0a..436d1f0d 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/RequestBuiltinPackageHashOperation.cs @@ -2,7 +2,7 @@ namespace YooAsset { - internal class RequestBuildinPackageHashOperation : AsyncOperationBase + internal class RequestBuiltinPackageHashOperation : AsyncOperationBase { private enum ESteps { @@ -13,7 +13,7 @@ namespace YooAsset Done, } - private readonly DefaultBuildinFileSystem _fileSystem; + private readonly BuiltinFileSystem _fileSystem; private readonly string _packageVersion; private IDownloadTextRequest _webTextRequestOp; private ESteps _steps = ESteps.None; @@ -24,7 +24,7 @@ namespace YooAsset public string PackageHash { private set; get; } - internal RequestBuildinPackageHashOperation(DefaultBuildinFileSystem fileSystem, string packageVersion) + internal RequestBuiltinPackageHashOperation(BuiltinFileSystem fileSystem, string packageVersion) { _fileSystem = fileSystem; _packageVersion = packageVersion; @@ -40,7 +40,7 @@ namespace YooAsset if (_steps == ESteps.TryLoadPackageHash) { - string filePath = _fileSystem.GetBuildinPackageHashFilePath(_packageVersion); + string filePath = _fileSystem.GetBuiltinPackageHashFilePath(_packageVersion); if (File.Exists(filePath)) { PackageHash = File.ReadAllText(filePath); @@ -56,8 +56,8 @@ namespace YooAsset { if (_webTextRequestOp == null) { - string filePath = _fileSystem.GetBuildinPackageHashFilePath(_packageVersion); - string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + string filePath = _fileSystem.GetBuiltinPackageHashFilePath(_packageVersion); + string url = DownloadSystemTools.ToLocalURL(filePath); var args = new DownloadDataRequestArgs(url, 60, 0); _webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args); _webTextRequestOp.SendRequest(); @@ -85,7 +85,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Buildin package hash file content is empty !"; + Error = $"Builtin package hash file content is empty."; } else { diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/RequestBuiltinPackageHashOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/RequestBuiltinPackageHashOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/RequestBuiltinPackageVersionOperation.cs similarity index 83% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/RequestBuiltinPackageVersionOperation.cs index 6e07d9ab..f5c9a807 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/RequestBuiltinPackageVersionOperation.cs @@ -2,7 +2,7 @@ namespace YooAsset { - internal class RequestBuildinPackageVersionOperation : AsyncOperationBase + internal class RequestBuiltinPackageVersionOperation : AsyncOperationBase { private enum ESteps { @@ -13,7 +13,7 @@ namespace YooAsset Done, } - private readonly DefaultBuildinFileSystem _fileSystem; + private readonly BuiltinFileSystem _fileSystem; private IDownloadTextRequest _webTextRequestOp; private ESteps _steps = ESteps.None; @@ -23,7 +23,7 @@ namespace YooAsset public string PackageVersion { private set; get; } - internal RequestBuildinPackageVersionOperation(DefaultBuildinFileSystem fileSystem) + internal RequestBuiltinPackageVersionOperation(BuiltinFileSystem fileSystem) { _fileSystem = fileSystem; } @@ -38,7 +38,7 @@ namespace YooAsset if (_steps == ESteps.TryLoadPackageVersion) { - string filePath = _fileSystem.GetBuildinPackageVersionFilePath(); + string filePath = _fileSystem.GetBuiltinPackageVersionFilePath(); if (File.Exists(filePath)) { PackageVersion = File.ReadAllText(filePath); @@ -54,8 +54,8 @@ namespace YooAsset { if (_webTextRequestOp == null) { - string filePath = _fileSystem.GetBuildinPackageVersionFilePath(); - string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + string filePath = _fileSystem.GetBuiltinPackageVersionFilePath(); + string url = DownloadSystemTools.ToLocalURL(filePath); var args = new DownloadDataRequestArgs(url, 60, 0); _webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args); _webTextRequestOp.SendRequest(); @@ -83,7 +83,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Buildin package version file content is empty !"; + Error = $"Builtin package version file content is empty."; } else { diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/RequestBuiltinPackageVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/internal/RequestBuiltinPackageVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/ApplicationFootPrint.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/ApplicationFootPrint.cs similarity index 91% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/ApplicationFootPrint.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/ApplicationFootPrint.cs index cb492ce9..0f4c3b8d 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/ApplicationFootPrint.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/ApplicationFootPrint.cs @@ -8,11 +8,11 @@ namespace YooAsset /// internal class ApplicationFootPrint { - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private string _footPrint; - public ApplicationFootPrint(DefaultCacheFileSystem fileSystem) + public ApplicationFootPrint(CacheFileSystem fileSystem) { _fileSystem = fileSystem; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/ApplicationFootPrint.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/ApplicationFootPrint.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/ApplicationFootPrint.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/ApplicationFootPrint.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystem.cs similarity index 74% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystem.cs index 849abfe0..979cd93c 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystem.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Collections.Generic; using System.Linq; @@ -10,9 +10,9 @@ namespace YooAsset /// 缓存文件系统 /// 说明:正在进行的下载器会在ResourcePackage销毁的时候执行Abort操作! /// - internal class DefaultCacheFileSystem : IFileSystem + internal class CacheFileSystem : IFileSystem { - protected readonly Dictionary _records = new Dictionary(10000); + protected readonly Dictionary _records = new Dictionary(10000); protected readonly Dictionary _bundleDataFilePathMapping = new Dictionary(10000); protected readonly Dictionary _bundleInfoFilePathMapping = new Dictionary(10000); protected readonly Dictionary _tempFilePathMapping = new Dictionary(10000); @@ -112,9 +112,9 @@ namespace YooAsset public int DownloadMaxRequestPerFrame { private set; get; } = 5; /// - /// 自定义参数:下载任务的看门狗机制监控时间 + /// 自定义参数:下载任务的看门狗机制超时时间 /// - public int DownloadWatchDogTime { private set; get; } = 0; + public int DownloadWatchDogTimeout { private set; get; } = 0; /// /// 自定义参数:启用断点续传的最小尺寸 @@ -127,41 +127,46 @@ namespace YooAsset public List ResumeDownloadResponseCodes { private set; get; } = null; /// - /// 自定义参数:解密服务接口的实例类 + /// 自定义参数:加载 AssetBundle 的工厂委托 /// - public IDecryptionServices DecryptionServices { private set; get; } + public LoadAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; } + + /// + /// 自定义参数:加载 RawBundle 的工厂委托 + /// + public LoadRawBundleOperationFactory LoadRawBundleFactory { private set; get; } /// /// 自定义参数:资源清单服务类 /// - public IManifestRestoreServices ManifestServices { private set; get; } + public IManifestRestoreServices ManifestRestoreServices { private set; get; } /// /// 自定义参数:拷贝内置文件接口的实例类 /// - public ICopyLocalFileServices CopyLocalFileServices { private set; get; } + public ILocalFileCopyServices CopyLocalFileServices { private set; get; } #endregion - public DefaultCacheFileSystem() + public CacheFileSystem() { } - public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + public virtual FSInitializeOperation InitializeAsync() { - var operation = new DCFSInitializeOperation(this); + var operation = new CFSInitializeOperation(this); return operation; } - public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) + public virtual FSRequestVersionOperation RequestVersionAsync(RequestVersionOptions options) { - var operation = new DCFSLoadPackageManifestOperation(this, packageVersion, timeout); + var operation = new CFSRequestPackageVersionOperation(this, options.AppendTimeTicks, options.Timeout); return operation; } - public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout) + public virtual FSLoadManifestOperation LoadManifestAsync(LoadManifestOptions options) { - var operation = new DCFSRequestPackageVersionOperation(this, appendTimeTicks, timeout); + var operation = new CFSLoadPackageManifestOperation(this, options.PackageVersion, options.Timeout); return operation; } - public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options) + public virtual FSClearCacheOperation ClearCacheAsync(ClearCacheOptions options) { if (options.ClearMode == EFileClearMode.ClearAllBundleFiles.ToString()) { @@ -170,17 +175,17 @@ namespace YooAsset } else if (options.ClearMode == EFileClearMode.ClearUnusedBundleFiles.ToString()) { - var operation = new ClearUnusedCacheBundleFilesOperation(this, manifest); + var operation = new ClearUnusedCacheBundleFilesOperation(this, options.Manifest); return operation; } else if (options.ClearMode == EFileClearMode.ClearBundleFilesByLocations.ToString()) { - var operation = new ClearCacheBundleFilesByLocationsOperaiton(this, manifest, options.ClearParam); + var operation = new ClearCacheBundleFilesByLocationsOperaiton(this, options.Manifest, options.ClearParam); return operation; } else if (options.ClearMode == EFileClearMode.ClearBundleFilesByTags.ToString()) { - var operation = new ClearCacheBundleFilesByTagsOperaiton(this, manifest, options.ClearParam); + var operation = new ClearCacheBundleFilesByTagsOperaiton(this, options.Manifest, options.ClearParam); return operation; } else if (options.ClearMode == EFileClearMode.ClearAllManifestFiles.ToString()) @@ -190,19 +195,20 @@ namespace YooAsset } else if (options.ClearMode == EFileClearMode.ClearUnusedManifestFiles.ToString()) { - var operation = new ClearUnusedCacheManifestFilesOperation(this, manifest); + var operation = new ClearUnusedCacheManifestFilesOperation(this, options.Manifest); return operation; } else { string error = $"Invalid clear mode : {options.ClearMode}"; - var operation = new FSClearCacheFilesCompleteOperation(error); + var operation = new FSClearCacheCompleteOperation(error); return operation; } } - public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) + public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options) { // 获取下载地址 + PackageBundle bundle = options.Bundle; if (string.IsNullOrEmpty(options.ImportFilePath)) { // 注意:如果是解压文件系统类,这里会返回本地内置文件的下载路径 @@ -213,28 +219,29 @@ namespace YooAsset else { // 注意:把本地导入文件路径转换为下载器请求地址 - string mainURL = DownloadSystemHelper.ConvertToWWWPath(options.ImportFilePath); + string mainURL = DownloadSystemTools.ToLocalURL(options.ImportFilePath); options.SetURL(mainURL, mainURL); } - var downloader = new DownloadPackageBundleOperation(this, bundle, options); + var downloader = new DownloadPackageBundleOperation(this, options); return downloader; } - public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) { - if (bundle.BundleType == (int)EBuildBundleType.AssetBundle) + PackageBundle bundle = options.Bundle; + if (bundle.BundleType == (int)EBundleType.AssetBundle) { - var operation = new DCFSLoadAssetBundleOperation(this, bundle); + var operation = new CFSLoadAssetBundleOperation(this, bundle); return operation; } - else if (bundle.BundleType == (int)EBuildBundleType.RawBundle) + else if (bundle.BundleType == (int)EBundleType.RawBundle) { - var operation = new DCFSLoadRawBundleOperation(this, bundle); + var operation = new CFSLoadRawBundleOperation(this, bundle); return operation; } else { - string error = $"{nameof(DefaultCacheFileSystem)} not support load bundle type : {bundle.BundleType}"; + string error = $"{nameof(CacheFileSystem)} not support load bundle type : {bundle.BundleType}"; var operation = new FSLoadBundleCompleteOperation(error); return operation; } @@ -305,7 +312,7 @@ namespace YooAsset else if (name == FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME) { int convertValue = Convert.ToInt32(value); - DownloadWatchDogTime = Mathf.Clamp(convertValue, 0, int.MaxValue); + DownloadWatchDogTimeout = Mathf.Clamp(convertValue, 0, int.MaxValue); } else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE) { @@ -315,17 +322,21 @@ namespace YooAsset { ResumeDownloadResponseCodes = (List)value; } - else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES) + else if (name == FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY) { - DecryptionServices = (IDecryptionServices)value; + LoadAssetBundleFactory = (LoadAssetBundleOperationFactory)value; } - else if (name == FileSystemParametersDefine.MANIFEST_SERVICES) + else if (name == FileSystemParametersDefine.LOAD_RAWBUNDLE_OPERATION_FACTORY) { - ManifestServices = (IManifestRestoreServices)value; + LoadRawBundleFactory = (LoadRawBundleOperationFactory)value; + } + else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES) + { + ManifestRestoreServices = (IManifestRestoreServices)value; } else if (name == FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES) { - CopyLocalFileServices = (ICopyLocalFileServices)value; + CopyLocalFileServices = (ILocalFileCopyServices)value; } else { @@ -348,6 +359,14 @@ namespace YooAsset // 创建默认的下载后台接口 if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); + + // 创建默认的 AssetBundle 加载工厂 + if (LoadAssetBundleFactory == null) + LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory; + + // 创建默认的 RawBundle 加载工厂 + if (LoadRawBundleFactory == null) + LoadRawBundleFactory = DefaultLoadRawBundleOperationFactory; } public virtual void OnDestroy() { @@ -391,76 +410,19 @@ namespace YooAsset return Exists(bundle) == false; } - public virtual string GetBundleFilePath(PackageBundle bundle) { return GetCacheBundleFileLoadPath(bundle); } - public virtual byte[] ReadBundleFileData(PackageBundle bundle) - { - if (Exists(bundle) == false) - return null; - - if (bundle.Encrypted) - { - if (DecryptionServices == null) - { - YooLogger.Error($"The {nameof(IDecryptionServices)} is null !"); - return null; - } - - string filePath = GetCacheBundleFileLoadPath(bundle); - var fileInfo = new DecryptFileInfo() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return DecryptionServices.ReadFileData(fileInfo); - } - else - { - string filePath = GetCacheBundleFileLoadPath(bundle); - return FileUtility.ReadAllBytes(filePath); - } - } - public virtual string ReadBundleFileText(PackageBundle bundle) - { - if (Exists(bundle) == false) - return null; - - if (bundle.Encrypted) - { - if (DecryptionServices == null) - { - YooLogger.Error($"The {nameof(IDecryptionServices)} is null !"); - return null; - } - - string filePath = GetCacheBundleFileLoadPath(bundle); - var fileInfo = new DecryptFileInfo() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return DecryptionServices.ReadFileText(fileInfo); - } - else - { - string filePath = GetCacheBundleFileLoadPath(bundle); - return FileUtility.ReadAllText(filePath); - } - } #region 缓存相关 public List GetAllCachedBundleGUIDs() { return _records.Keys.ToList(); } - public RecordFileElement GetRecordFileElement(PackageBundle bundle) + public FileCacheEntry GetRecordFileEntry(PackageBundle bundle) { - if (_records.TryGetValue(bundle.BundleGUID, out RecordFileElement element)) + if (_records.TryGetValue(bundle.BundleGUID, out FileCacheEntry element)) return element; else return null; @@ -502,24 +464,24 @@ namespace YooAsset { return _records.ContainsKey(bundleGUID); } - public bool RecordBundleFile(string bundleGUID, RecordFileElement element) + public bool RecordBundleFile(string bundleGUID, FileCacheEntry entry) { if (_records.ContainsKey(bundleGUID)) { - YooLogger.Error($"{nameof(DefaultCacheFileSystem)} has element : {bundleGUID}"); + YooLogger.Error($"{nameof(CacheFileSystem)} has element : {bundleGUID}"); return false; } - _records.Add(bundleGUID, element); + _records.Add(bundleGUID, entry); return true; } public EFileVerifyResult VerifyCacheFile(PackageBundle bundle) { - if (_records.TryGetValue(bundle.BundleGUID, out RecordFileElement element) == false) + if (_records.TryGetValue(bundle.BundleGUID, out FileCacheEntry element) == false) return EFileVerifyResult.CacheNotFound; - EFileVerifyResult result = FileVerifyHelper.FileVerify(element.DataFilePath, element.DataFileSize, element.DataFileCRC, EFileVerifyLevel.High); + EFileVerifyResult result = FileVerifyTools.FileVerify(element.DataFilePath, element.DataFileSize, element.DataFileCRC, EFileVerifyLevel.High); return result; } public bool WriteCacheBundleFile(PackageBundle bundle, string copyPath) @@ -550,16 +512,16 @@ namespace YooAsset } catch (Exception ex) { - YooLogger.Error($"Failed to write cache file ! {ex.Message}"); + YooLogger.Error($"Failed to write cache file. Error: {ex.Message}"); return false; } - var recordFileElement = new RecordFileElement(infoFilePath, dataFilePath, bundle.FileCRC, bundle.FileSize); + var recordFileElement = new FileCacheEntry(infoFilePath, dataFilePath, bundle.FileCRC, bundle.FileSize); return RecordBundleFile(bundle.BundleGUID, recordFileElement); } public bool DeleteCacheBundleFile(string bundleGUID) { - if (_records.TryGetValue(bundleGUID, out RecordFileElement element)) + if (_records.TryGetValue(bundleGUID, out FileCacheEntry element)) { _records.Remove(bundleGUID); return element.DeleteFolder(); @@ -592,6 +554,30 @@ namespace YooAsset #endregion #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(); @@ -645,51 +631,6 @@ namespace YooAsset Directory.Delete(_cacheManifestFilesRoot, true); } } - - /// - /// 加载加密资源文件 - /// - public DecryptResult LoadEncryptedAssetBundle(PackageBundle bundle) - { - string filePath = GetCacheBundleFileLoadPath(bundle); - var fileInfo = new DecryptFileInfo() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return DecryptionServices.LoadAssetBundle(fileInfo); - } - - /// - /// 加载加密资源文件 - /// - public DecryptResult LoadEncryptedAssetBundleAsync(PackageBundle bundle) - { - string filePath = GetCacheBundleFileLoadPath(bundle); - var fileInfo = new DecryptFileInfo() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return DecryptionServices.LoadAssetBundleAsync(fileInfo); - } - - /// - /// 加载加密资源文件 - /// - public DecryptResult LoadEncryptedAssetBundleFallback(PackageBundle bundle) - { - string filePath = GetCacheBundleFileLoadPath(bundle); - var fileInfo = new DecryptFileInfo() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return DecryptionServices.LoadAssetBundleFallback(fileInfo); - } #endregion } } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystem.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystem.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystemConstants.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystemConstants.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystemConstants.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystemConstants.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileClearMode.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EFileClearMode.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/EFileClearMode.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EFileClearMode.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileClearMode.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EFileClearMode.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/EFileClearMode.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EFileClearMode.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EFileVerifyLevel.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EFileVerifyLevel.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EFileVerifyLevel.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EFileVerifyLevel.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EFileVerifyResult.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EFileVerifyResult.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EFileVerifyResult.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EFileVerifyResult.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/EOverwriteInstallClearMode.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EOverwriteInstallClearMode.cs similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/EOverwriteInstallClearMode.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EOverwriteInstallClearMode.cs diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/EOverwriteInstallClearMode.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EOverwriteInstallClearMode.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/EOverwriteInstallClearMode.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/EOverwriteInstallClearMode.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/RecordFileElement.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileCacheEntry.cs similarity index 73% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/RecordFileElement.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileCacheEntry.cs index ef1f5841..3b028a19 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/RecordFileElement.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileCacheEntry.cs @@ -3,14 +3,14 @@ using System.IO; namespace YooAsset { - internal class RecordFileElement + internal class FileCacheEntry { public string InfoFilePath { private set; get; } public string DataFilePath { private set; get; } public uint DataFileCRC { private set; get; } public long DataFileSize { private set; get; } - public RecordFileElement(string infoFilePath, string dataFilePath, uint dataFileCRC, long dataFileSize) + public FileCacheEntry(string infoFilePath, string dataFilePath, uint dataFileCRC, long dataFileSize) { InfoFilePath = infoFilePath; DataFilePath = dataFilePath; @@ -18,6 +18,14 @@ namespace YooAsset DataFileSize = dataFileSize; } + /// + /// 修正内容 + /// + public void Modify(string dataFilePath) + { + DataFilePath = dataFilePath; + } + /// /// 删除记录文件 /// @@ -39,7 +47,7 @@ namespace YooAsset } catch (Exception ex) { - YooLogger.Error($"Failed to delete cache file ! {ex.Message}"); + YooLogger.Error($"Failed to delete cache file. Error: {ex.Message}"); return false; } } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/RecordFileElement.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileCacheEntry.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/RecordFileElement.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileCacheEntry.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/FileVerifyHelper.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileVerifyTools.cs similarity index 97% rename from Assets/YooAsset/Runtime/FileSystem/FileVerifyHelper.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileVerifyTools.cs index b2633319..c7ade1dc 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileVerifyHelper.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileVerifyTools.cs @@ -3,7 +3,7 @@ using System.IO; namespace YooAsset { - internal class FileVerifyHelper + internal class FileVerifyTools { /// /// 文件校验 diff --git a/Assets/YooAsset/Runtime/FileSystem/FileVerifyHelper.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileVerifyTools.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/FileVerifyHelper.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileVerifyTools.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSInitializeOperation.cs similarity index 92% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSInitializeOperation.cs index 7ec366b7..ad6c3e62 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSInitializeOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DCFSInitializeOperation : FSInitializeFileSystemOperation + internal class CFSInitializeOperation : FSInitializeOperation { private enum ESteps { @@ -13,13 +13,13 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private SearchCacheFilesOperation _searchCacheFilesOp; private VerifyCacheFilesOperation _verifyCacheFilesOp; private ESteps _steps = ESteps.None; - internal DCFSInitializeOperation(DefaultCacheFileSystem fileSystem) + internal CFSInitializeOperation(CacheFileSystem fileSystem) { _fileSystem = fileSystem; } @@ -28,7 +28,7 @@ namespace YooAsset #if UNITY_WEBGL _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"{nameof(DefaultCacheFileSystem)} is not support WEBGL platform !"; + Error = $"{nameof(DefaultCacheFileSystem)} is not support WEBGL platform."; #else _steps = ESteps.CheckAppFootPrint; #endif @@ -48,23 +48,23 @@ namespace YooAsset { if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.None) { - YooLogger.Warning("Do nothing when overwrite install application !"); + YooLogger.Warning("Do nothing when overwrite install application."); } else if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.ClearAllCacheFiles) { _fileSystem.DeleteAllBundleFiles(); _fileSystem.DeleteAllManifestFiles(); - YooLogger.Warning("Delete all cache files when overwrite install application !"); + YooLogger.Warning("Delete all cache files when overwrite install application."); } else if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.ClearAllBundleFiles) { _fileSystem.DeleteAllBundleFiles(); - YooLogger.Warning("Delete all bundle files when overwrite install application !"); + YooLogger.Warning("Delete all bundle files when overwrite install application."); } else if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.ClearAllManifestFiles) { _fileSystem.DeleteAllManifestFiles(); - YooLogger.Warning("Delete all manifest files when overwrite install application !"); + YooLogger.Warning("Delete all manifest files when overwrite install application."); } else { diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSInitializeOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSInitializeOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadBundleOperation.cs similarity index 61% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadBundleOperation.cs index e5d1ee50..6660db52 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadBundleOperation.cs @@ -1,10 +1,10 @@ -using System; +using System; using System.IO; using UnityEngine; namespace YooAsset { - internal class DCFSLoadAssetBundleOperation : FSLoadBundleOperation + internal class CFSLoadAssetBundleOperation : FSLoadBundleOperation { protected enum ESteps { @@ -12,21 +12,20 @@ namespace YooAsset CheckExist, DownloadFile, AbortDownload, - LoadAssetBundle, + LoadCacheAssetBundle, CheckResult, + TryFallback, Done, } - protected readonly DefaultCacheFileSystem _fileSystem; + protected readonly CacheFileSystem _fileSystem; protected readonly PackageBundle _bundle; protected FSDownloadFileOperation _downloadFileOp; - protected AssetBundleCreateRequest _createRequest; - private AssetBundle _assetBundle; - private Stream _managedStream; + protected LoadAssetBundleOperation _loadAssetBundleOp; protected ESteps _steps = ESteps.None; - internal DCFSLoadAssetBundleOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle) + internal CFSLoadAssetBundleOperation(CacheFileSystem fileSystem, PackageBundle bundle) { _fileSystem = fileSystem; _bundle = bundle; @@ -46,7 +45,7 @@ namespace YooAsset { DownloadProgress = 1f; DownloadedBytes = _bundle.FileSize; - _steps = ESteps.LoadAssetBundle; + _steps = ESteps.LoadCacheAssetBundle; } else { @@ -79,13 +78,13 @@ namespace YooAsset { if (_downloadFileOp == null) { - DownloadFileOptions options = new DownloadFileOptions(int.MaxValue); - _downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, options); + DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue); + _downloadFileOp = _fileSystem.DownloadFileAsync(options); _downloadFileOp.StartOperation(); AddChildOperation(_downloadFileOp); } - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _downloadFileOp.WaitForAsyncComplete(); _downloadFileOp.UpdateOperation(); @@ -96,7 +95,7 @@ namespace YooAsset if (_downloadFileOp.Status == EOperationStatus.Succeed) { - _steps = ESteps.LoadAssetBundle; + _steps = ESteps.LoadCacheAssetBundle; } else { @@ -110,7 +109,7 @@ namespace YooAsset { if (_downloadFileOp != null) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _downloadFileOp.WaitForAsyncComplete(); _downloadFileOp.UpdateOperation(); @@ -120,160 +119,105 @@ namespace YooAsset _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Abort download file !"; + Error = "Abort download file."; } - if (_steps == ESteps.LoadAssetBundle) + if (_steps == ESteps.LoadCacheAssetBundle) { - if (_bundle.Encrypted) - { - if (_fileSystem.DecryptionServices == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"The {nameof(IDecryptionServices)} is null !"; - YooLogger.Error(Error); - return; - } - } - - if (IsWaitForAsyncComplete) - { - if (_bundle.Encrypted) - { - var decryptResult = _fileSystem.LoadEncryptedAssetBundle(_bundle); - _assetBundle = decryptResult.Result; - _managedStream = decryptResult.ManagedStream; - } - else - { - string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); - _assetBundle = AssetBundle.LoadFromFile(filePath); - } - } - else - { - if (_bundle.Encrypted) - { - var decryptResult = _fileSystem.LoadEncryptedAssetBundleAsync(_bundle); - _createRequest = decryptResult.CreateRequest; - _managedStream = decryptResult.ManagedStream; - } - else - { - string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); - _createRequest = AssetBundle.LoadFromFileAsync(filePath); - } - } - + var options = new LoadAssetBundleOptions(); + options.FileLoadPath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); + options.Bundle = _bundle; + _loadAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options); + _loadAssetBundleOp.StartOperation(); + AddChildOperation(_loadAssetBundleOp); _steps = ESteps.CheckResult; } if (_steps == ESteps.CheckResult) { - if (_createRequest != null) + if (IsWaitingForAsyncComplete) + _loadAssetBundleOp.WaitForAsyncComplete(); + + _loadAssetBundleOp.UpdateOperation(); + if (_loadAssetBundleOp.IsDone == false) + return; + + if (_loadAssetBundleOp.Status == EOperationStatus.Succeed) { - if (IsWaitForAsyncComplete) + if (_loadAssetBundleOp.Result == null) { - // 强制挂起主线程(注意:该操作会很耗时) - YooLogger.Warning("Suspend the main thread to load unity bundle."); - _assetBundle = _createRequest.assetBundle; + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Loaded cache asset bundle is null."; + YooLogger.Error(Error); } else { - if (_createRequest.isDone == false) - return; - _assetBundle = _createRequest.assetBundle; + _steps = ESteps.Done; + Result = new AssetBundleResult(_fileSystem, _bundle, _loadAssetBundleOp.Result, _loadAssetBundleOp.ManagedStream); + Status = EOperationStatus.Succeed; } } - - if (_assetBundle != null) + else { - _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, _managedStream); - Status = EOperationStatus.Succeed; - return; + if (_loadAssetBundleOp is LoadAssetBundleCompleteOperation) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadAssetBundleOp.Error; + YooLogger.Error(Error); + } + else + { + // 加载失败,尝试后备加载 + _steps = ESteps.TryFallback; + } } + } + if (_steps == ESteps.TryFallback) + { // 注意:当缓存文件的校验等级为Low的时候,并不能保证缓存文件的完整性。 // 说明:在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性! EFileVerifyResult verifyResult = _fileSystem.VerifyCacheFile(_bundle); if (verifyResult == EFileVerifyResult.Succeed) { - if (_bundle.Encrypted) - { - var decryptResult = _fileSystem.LoadEncryptedAssetBundleFallback(_bundle); - _assetBundle = decryptResult.Result; - if (_assetBundle != null) - { - _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, _managedStream); - Status = EOperationStatus.Succeed; - return; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Failed to load encrypted asset bundle file : {_bundle.BundleName}"; - YooLogger.Error(Error); - return; - } - } - + // 调用后备加载方法 // 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。 // 说明:大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发! - string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); - byte[] fileData = FileUtility.ReadAllBytes(filePath); - if (fileData != null && fileData.Length > 0) + AssetBundle assetBundle = _loadAssetBundleOp.LoadFromMemory(); + if (assetBundle != null) { - _assetBundle = AssetBundle.LoadFromMemory(fileData); - if (_assetBundle == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Failed to load asset bundle from memory : {_bundle.BundleName}"; - YooLogger.Error(Error); - } - else - { - _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, null); - Status = EOperationStatus.Succeed; - } + _steps = ESteps.Done; + Result = new AssetBundleResult(_fileSystem, _bundle, assetBundle, null); + Status = EOperationStatus.Succeed; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Failed to read asset bundle file bytes : {_bundle.BundleName}"; + Error = $"Failed to load asset bundle from memory : {_bundle.BundleName}"; YooLogger.Error(Error); } } else { + // 文件损坏,删除缓存 _steps = ESteps.Done; - _fileSystem.DeleteCacheBundleFile(_bundle.BundleGUID); Status = EOperationStatus.Failed; Error = $"Find corrupted asset bundle file and delete : {_bundle.BundleName}"; YooLogger.Error(Error); + _fileSystem.DeleteCacheBundleFile(_bundle.BundleGUID); } } } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } } - internal class DCFSLoadRawBundleOperation : FSLoadBundleOperation + internal class CFSLoadRawBundleOperation : FSLoadBundleOperation { protected enum ESteps { @@ -282,16 +226,18 @@ namespace YooAsset DownloadFile, AbortDownload, LoadCacheRawBundle, + CheckResult, Done, } - protected readonly DefaultCacheFileSystem _fileSystem; + protected readonly CacheFileSystem _fileSystem; protected readonly PackageBundle _bundle; protected FSDownloadFileOperation _downloadFileOp; + protected LoadRawBundleOperation _loadRawBundleOp; protected ESteps _steps = ESteps.None; - internal DCFSLoadRawBundleOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle) + internal CFSLoadRawBundleOperation(CacheFileSystem fileSystem, PackageBundle bundle) { _fileSystem = fileSystem; _bundle = bundle; @@ -316,15 +262,16 @@ namespace YooAsset { try { - var recordFileElement = _fileSystem.GetRecordFileElement(_bundle); - File.Move(recordFileElement.DataFilePath, filePath); + var entry = _fileSystem.GetRecordFileEntry(_bundle); + File.Move(entry.DataFilePath, filePath); + entry.Modify(filePath); _steps = ESteps.LoadCacheRawBundle; } catch (Exception ex) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Faild rename raw data file : {ex.Message}"; + Error = $"Faild rename cached data file : {ex.Message}"; } } else @@ -355,13 +302,13 @@ namespace YooAsset { if (_downloadFileOp == null) { - DownloadFileOptions options = new DownloadFileOptions(int.MaxValue); - _downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, options); + DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue); + _downloadFileOp = _fileSystem.DownloadFileAsync(options); _downloadFileOp.StartOperation(); AddChildOperation(_downloadFileOp); } - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _downloadFileOp.WaitForAsyncComplete(); _downloadFileOp.UpdateOperation(); @@ -386,7 +333,7 @@ namespace YooAsset { if (_downloadFileOp != null) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _downloadFileOp.WaitForAsyncComplete(); _downloadFileOp.UpdateOperation(); @@ -396,37 +343,57 @@ namespace YooAsset _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Abort download file !"; + Error = "Abort download file."; } if (_steps == ESteps.LoadCacheRawBundle) { - string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); - if (File.Exists(filePath)) + 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 (IsWaitingForAsyncComplete) + _loadRawBundleOp.WaitForAsyncComplete(); + + _loadRawBundleOp.UpdateOperation(); + if (_loadRawBundleOp.IsDone == false) + return; + + if (_loadRawBundleOp.Status == EOperationStatus.Succeed) { - _steps = ESteps.Done; - Result = new RawBundleResult(_fileSystem, _bundle); - Status = EOperationStatus.Succeed; + 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.Succeed; + } } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Can not found cache raw bundle file : {filePath}"; + Error = _loadRawBundleOp.Error; YooLogger.Error(Error); } } } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadManifestOperation.cs similarity index 95% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadManifestOperation.cs index 6b30db83..ffc15429 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadManifestOperation.cs @@ -2,7 +2,7 @@ namespace YooAsset { - internal class DCFSLoadPackageManifestOperation : FSLoadPackageManifestOperation + internal class CFSLoadPackageManifestOperation : FSLoadManifestOperation { private enum ESteps { @@ -14,7 +14,7 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly string _packageVersion; private readonly int _timeout; private DownloadPackageHashOperation _downloadPackageHashOp; @@ -24,7 +24,7 @@ namespace YooAsset private ESteps _steps = ESteps.None; - internal DCFSLoadPackageManifestOperation(DefaultCacheFileSystem fileSystem, string packageVersion, int timeout) + internal CFSLoadPackageManifestOperation(CacheFileSystem fileSystem, string packageVersion, int timeout) { _fileSystem = fileSystem; _packageVersion = packageVersion; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSRequestVersionOperation.cs similarity index 87% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSRequestVersionOperation.cs index ac68534b..56e9cb4a 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSRequestVersionOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DCFSRequestPackageVersionOperation : FSRequestPackageVersionOperation + internal class CFSRequestPackageVersionOperation : FSRequestVersionOperation { private enum ESteps { @@ -10,14 +10,14 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly bool _appendTimeTicks; private readonly int _timeout; private RequestRemotePackageVersionOperation _requestRemotePackageVersionOp; private ESteps _steps = ESteps.None; - internal DCFSRequestPackageVersionOperation(DefaultCacheFileSystem fileSystem, bool appendTimeTicks, int timeout) + internal CFSRequestPackageVersionOperation(CacheFileSystem fileSystem, bool appendTimeTicks, int timeout) { _fileSystem = fileSystem; _appendTimeTicks = appendTimeTicks; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSRequestVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSRequestVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearAllCacheBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearAllCacheBundleFilesOperation.cs similarity index 91% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearAllCacheBundleFilesOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearAllCacheBundleFilesOperation.cs index b5258fd9..7810ec81 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearAllCacheBundleFilesOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearAllCacheBundleFilesOperation.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace YooAsset { - internal sealed class ClearAllCacheBundleFilesOperation : FSClearCacheFilesOperation + internal sealed class ClearAllCacheBundleFilesOperation : FSClearCacheOperation { private enum ESteps { @@ -13,13 +13,13 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private List _allBundleGUIDs; private int _fileTotalCount = 0; private ESteps _steps = ESteps.None; - internal ClearAllCacheBundleFilesOperation(DefaultCacheFileSystem fileSystem) + internal ClearAllCacheBundleFilesOperation(CacheFileSystem fileSystem) { _fileSystem = fileSystem; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearAllCacheBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearAllCacheBundleFilesOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearAllCacheBundleFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearAllCacheBundleFilesOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearAllCacheManifestFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearAllCacheManifestFilesOperation.cs similarity index 91% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearAllCacheManifestFilesOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearAllCacheManifestFilesOperation.cs index 407dc381..86abc61b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearAllCacheManifestFilesOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearAllCacheManifestFilesOperation.cs @@ -3,7 +3,7 @@ using System.IO; namespace YooAsset { - internal sealed class ClearAllCacheManifestFilesOperation : FSClearCacheFilesOperation + internal sealed class ClearAllCacheManifestFilesOperation : FSClearCacheOperation { private enum ESteps { @@ -12,11 +12,11 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private ESteps _steps = ESteps.None; - internal ClearAllCacheManifestFilesOperation(DefaultCacheFileSystem fileSystem) + internal ClearAllCacheManifestFilesOperation(CacheFileSystem fileSystem) { _fileSystem = fileSystem; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearAllCacheManifestFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearAllCacheManifestFilesOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearAllCacheManifestFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearAllCacheManifestFilesOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearCacheBundleFilesByLocationsOperaiton.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearCacheBundleFilesByLocationsOperaiton.cs similarity index 93% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearCacheBundleFilesByLocationsOperaiton.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearCacheBundleFilesByLocationsOperaiton.cs index 79b1397a..af26354d 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearCacheBundleFilesByLocationsOperaiton.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearCacheBundleFilesByLocationsOperaiton.cs @@ -2,7 +2,7 @@ namespace YooAsset { - internal class ClearCacheBundleFilesByLocationsOperaiton : FSClearCacheFilesOperation + internal class ClearCacheBundleFilesByLocationsOperaiton : FSClearCacheOperation { private enum ESteps { @@ -14,7 +14,7 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly PackageManifest _manifest; private readonly object _clearParam; private string[] _locations; @@ -22,7 +22,7 @@ namespace YooAsset private int _clearFileTotalCount = 0; private ESteps _steps = ESteps.None; - internal ClearCacheBundleFilesByLocationsOperaiton(DefaultCacheFileSystem fileSystem, PackageManifest manifest, object clearParam) + internal ClearCacheBundleFilesByLocationsOperaiton(CacheFileSystem fileSystem, PackageManifest manifest, object clearParam) { _fileSystem = fileSystem; _manifest = manifest; @@ -45,7 +45,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Can not found active package manifest !"; + Error = "Can not found active package manifest."; } else { @@ -59,7 +59,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Clear param is null !"; + Error = "Clear param is null."; return; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearCacheBundleFilesByLocationsOperaiton.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearCacheBundleFilesByLocationsOperaiton.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearCacheBundleFilesByLocationsOperaiton.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearCacheBundleFilesByLocationsOperaiton.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearCacheBundleFilesByTagsOperaiton.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearCacheBundleFilesByTagsOperaiton.cs similarity index 93% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearCacheBundleFilesByTagsOperaiton.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearCacheBundleFilesByTagsOperaiton.cs index 247bc01c..aebc7b84 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearCacheBundleFilesByTagsOperaiton.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearCacheBundleFilesByTagsOperaiton.cs @@ -2,7 +2,7 @@ namespace YooAsset { - internal class ClearCacheBundleFilesByTagsOperaiton : FSClearCacheFilesOperation + internal class ClearCacheBundleFilesByTagsOperaiton : FSClearCacheOperation { private enum ESteps { @@ -14,7 +14,7 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly PackageManifest _manifest; private readonly object _clearParam; private string[] _tags; @@ -22,7 +22,7 @@ namespace YooAsset private int _clearFileTotalCount = 0; private ESteps _steps = ESteps.None; - internal ClearCacheBundleFilesByTagsOperaiton(DefaultCacheFileSystem fileSystem, PackageManifest manifest, object clearParam) + internal ClearCacheBundleFilesByTagsOperaiton(CacheFileSystem fileSystem, PackageManifest manifest, object clearParam) { _fileSystem = fileSystem; _manifest = manifest; @@ -43,7 +43,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Can not found active package manifest !"; + Error = "Can not found active package manifest."; } else { @@ -57,7 +57,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Clear param is null !"; + Error = "Clear param is null."; return; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearCacheBundleFilesByTagsOperaiton.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearCacheBundleFilesByTagsOperaiton.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearCacheBundleFilesByTagsOperaiton.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearCacheBundleFilesByTagsOperaiton.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearUnusedCacheBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearUnusedCacheBundleFilesOperation.cs similarity index 93% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearUnusedCacheBundleFilesOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearUnusedCacheBundleFilesOperation.cs index fd0bf90e..be344df5 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearUnusedCacheBundleFilesOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearUnusedCacheBundleFilesOperation.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace YooAsset { - internal sealed class ClearUnusedCacheBundleFilesOperation : FSClearCacheFilesOperation + internal sealed class ClearUnusedCacheBundleFilesOperation : FSClearCacheOperation { private enum ESteps { @@ -14,14 +14,14 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly PackageManifest _manifest; private List _unusedBundleGUIDs; private int _unusedFileTotalCount = 0; private ESteps _steps = ESteps.None; - internal ClearUnusedCacheBundleFilesOperation(DefaultCacheFileSystem fileSystem, PackageManifest manifest) + internal ClearUnusedCacheBundleFilesOperation(CacheFileSystem fileSystem, PackageManifest manifest) { _fileSystem = fileSystem; _manifest = manifest; @@ -41,7 +41,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Can not found active package manifest !"; + Error = "Can not found active package manifest."; } else { diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearUnusedCacheBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearUnusedCacheBundleFilesOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearUnusedCacheBundleFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearUnusedCacheBundleFilesOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearUnusedCacheManifestFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearUnusedCacheManifestFilesOperation.cs similarity index 92% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearUnusedCacheManifestFilesOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearUnusedCacheManifestFilesOperation.cs index 0de2013f..59dc1179 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearUnusedCacheManifestFilesOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearUnusedCacheManifestFilesOperation.cs @@ -3,7 +3,7 @@ using System.IO; namespace YooAsset { - internal sealed class ClearUnusedCacheManifestFilesOperation : FSClearCacheFilesOperation + internal sealed class ClearUnusedCacheManifestFilesOperation : FSClearCacheOperation { private enum ESteps { @@ -13,12 +13,12 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly PackageManifest _manifest; private ESteps _steps = ESteps.None; - internal ClearUnusedCacheManifestFilesOperation(DefaultCacheFileSystem fileSystem, PackageManifest manifest) + internal ClearUnusedCacheManifestFilesOperation(CacheFileSystem fileSystem, PackageManifest manifest) { _fileSystem = fileSystem; _manifest = manifest; @@ -38,7 +38,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Can not found active package manifest !"; + Error = "Can not found active package manifest."; } else { diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearUnusedCacheManifestFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearUnusedCacheManifestFilesOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ClearUnusedCacheManifestFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/ClearUnusedCacheManifestFilesOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageBundleOperation.cs similarity index 87% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageBundleOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageBundleOperation.cs index 3f47bc22..449c4488 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageBundleOperation.cs @@ -16,7 +16,7 @@ namespace YooAsset } // 下载参数 - protected readonly DefaultCacheFileSystem _fileSystem; + protected readonly CacheFileSystem _fileSystem; protected readonly DownloadFileOptions _options; private DownloadAndCacheFileOperation _downloadFileOp; @@ -26,7 +26,7 @@ namespace YooAsset private ESteps _steps = ESteps.None; - internal DownloadPackageBundleOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle) + internal DownloadPackageBundleOperation(CacheFileSystem fileSystem, DownloadFileOptions options) : base(options.Bundle) { _fileSystem = fileSystem; _options = options; @@ -62,7 +62,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Download file options is invalid !"; + Error = "Download file options is invalid."; Debug.Log(Error); return; } @@ -75,7 +75,7 @@ namespace YooAsset // 检测下载结果 if (_steps == ESteps.CheckRequest) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _downloadFileOp.WaitForAsyncComplete(); _downloadFileOp.UpdateOperation(); @@ -92,10 +92,10 @@ namespace YooAsset } else { - if (IsWaitForAsyncComplete == false && _failedTryAgain > 0) + if (IsWaitingForAsyncComplete == false && _failedTryAgain > 0) { _steps = ESteps.TryAgain; - YooLogger.Warning($"Failed download : {_downloadFileOp.URL} Try again !"); + YooLogger.Warning($"Failed download : {_downloadFileOp.URL} Try again."); } else { @@ -124,14 +124,7 @@ namespace YooAsset } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } internal override void InternalAbort() { diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs similarity index 86% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs index 0f860796..3c8ce0ee 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs @@ -12,7 +12,7 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly string _packageVersion; private readonly int _timeout; private IDownloadFileRequest _webFileRequestOp; @@ -20,7 +20,7 @@ namespace YooAsset private ESteps _steps = ESteps.None; - internal DownloadPackageHashOperation(DefaultCacheFileSystem fileSystem, string packageVersion, int timeout) + internal DownloadPackageHashOperation(CacheFileSystem fileSystem, string packageVersion, int timeout) { _fileSystem = fileSystem; _packageVersion = packageVersion; @@ -28,7 +28,7 @@ namespace YooAsset } internal override void InternalStart() { - _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(DownloadPackageHashOperation)); + _requestCount = DownloadFailureCounter.GetFailureCount(_fileSystem.PackageName, nameof(DownloadPackageHashOperation)); _steps = ESteps.CheckExist; } internal override void InternalUpdate() @@ -57,7 +57,7 @@ namespace YooAsset string savePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion); string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, _packageVersion); string webURL = GetWebRequestURL(fileName); - int watchdogTime = _fileSystem.DownloadWatchDogTime; + int watchdogTime = _fileSystem.DownloadWatchDogTimeout; var args = new DownloadFileRequestArgs(webURL, savePath, _timeout, watchdogTime); _webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args); _webFileRequestOp.SendRequest(); @@ -76,7 +76,7 @@ namespace YooAsset _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _webFileRequestOp.Error; - WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(DownloadPackageHashOperation)); + DownloadFailureCounter.RecordFailure(_fileSystem.PackageName, nameof(DownloadPackageHashOperation)); } } } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs similarity index 86% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs index 8ee423ec..1cf6e524 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs @@ -12,7 +12,7 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly string _packageVersion; private readonly int _timeout; private IDownloadFileRequest _webFileRequestOp; @@ -20,7 +20,7 @@ namespace YooAsset private ESteps _steps = ESteps.None; - internal DownloadPackageManifestOperation(DefaultCacheFileSystem fileSystem, string packageVersion, int timeout) + internal DownloadPackageManifestOperation(CacheFileSystem fileSystem, string packageVersion, int timeout) { _fileSystem = fileSystem; _packageVersion = packageVersion; @@ -28,7 +28,7 @@ namespace YooAsset } internal override void InternalStart() { - _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(DownloadPackageManifestOperation)); + _requestCount = DownloadFailureCounter.GetFailureCount(_fileSystem.PackageName, nameof(DownloadPackageManifestOperation)); _steps = ESteps.CheckExist; } internal override void InternalUpdate() @@ -57,7 +57,7 @@ namespace YooAsset string savePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion); string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion); string webURL = GetDownloadRequestURL(fileName); - int watchdogTime = _fileSystem.DownloadWatchDogTime; + int watchdogTime = _fileSystem.DownloadWatchDogTimeout; var args = new DownloadFileRequestArgs(webURL, savePath, _timeout, watchdogTime); _webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args); _webFileRequestOp.SendRequest(); @@ -76,7 +76,7 @@ namespace YooAsset _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _webFileRequestOp.Error; - WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(DownloadPackageManifestOperation)); + DownloadFailureCounter.RecordFailure(_fileSystem.PackageName, nameof(DownloadPackageManifestOperation)); } } } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs similarity index 90% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs index 5f937990..b36a4267 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs @@ -11,7 +11,7 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly string _packageVersion; private ESteps _steps = ESteps.None; @@ -21,7 +21,7 @@ namespace YooAsset public string PackageHash { private set; get; } - internal LoadCachePackageHashOperation(DefaultCacheFileSystem fileSystem, string packageVersion) + internal LoadCachePackageHashOperation(CacheFileSystem fileSystem, string packageVersion) { _fileSystem = fileSystem; _packageVersion = packageVersion; @@ -51,7 +51,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Cache package hash file content is empty !"; + Error = $"Cache package hash file content is empty."; } else { diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs similarity index 89% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs index 4f349184..dbae71e4 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs @@ -13,7 +13,7 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly string _packageVersion; private readonly string _packageHash; private DeserializeManifestOperation _deserializer; @@ -26,7 +26,7 @@ namespace YooAsset public PackageManifest Manifest { private set; get; } - internal LoadCachePackageManifestOperation(DefaultCacheFileSystem fileSystem, string packageVersion, string packageHash) + internal LoadCachePackageManifestOperation(CacheFileSystem fileSystem, string packageVersion, string packageHash) { _fileSystem = fileSystem; _packageVersion = packageVersion; @@ -59,7 +59,7 @@ namespace YooAsset if (_steps == ESteps.VerifyFileData) { - if (ManifestTools.VerifyManifestData(_fileData, _packageHash)) + if (PackageManifestTools.VerifyManifestData(_fileData, _packageHash)) { _steps = ESteps.LoadManifest; } @@ -67,7 +67,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Failed to verify cache package manifest file!"; + Error = "Failed to verify cache package manifest file."; } } @@ -75,7 +75,7 @@ namespace YooAsset { if (_deserializer == null) { - _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _fileData); + _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestRestoreServices, _fileData); _deserializer.StartOperation(); AddChildOperation(_deserializer); } @@ -99,7 +99,7 @@ namespace YooAsset } } } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { return $"PackageVersion : {_packageVersion} PackageHash : {_packageHash}"; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs similarity index 86% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs index 2dd49826..5a032bb1 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs @@ -10,7 +10,7 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly bool _appendTimeTicks; private readonly int _timeout; private IDownloadTextRequest _webTextRequestOp; @@ -23,7 +23,7 @@ namespace YooAsset internal string PackageVersion { set; get; } - internal RequestRemotePackageVersionOperation(DefaultCacheFileSystem fileSystem, bool appendTimeTicks, int timeout) + internal RequestRemotePackageVersionOperation(CacheFileSystem fileSystem, bool appendTimeTicks, int timeout) { _fileSystem = fileSystem; _appendTimeTicks = appendTimeTicks; @@ -31,7 +31,7 @@ namespace YooAsset } internal override void InternalStart() { - _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestRemotePackageVersionOperation)); + _requestCount = DownloadFailureCounter.GetFailureCount(_fileSystem.PackageName, nameof(RequestRemotePackageVersionOperation)); _steps = ESteps.RequestPackageVersion; } internal override void InternalUpdate() @@ -45,7 +45,7 @@ namespace YooAsset { string fileName = YooAssetSettingsData.GetPackageVersionFileName(_fileSystem.PackageName); string url = GetWebRequestURL(fileName); - int watchDogTime = _fileSystem.DownloadWatchDogTime; + int watchDogTime = _fileSystem.DownloadWatchDogTimeout; var args = new DownloadDataRequestArgs(url, _timeout, watchDogTime); _webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args); _webTextRequestOp.SendRequest(); @@ -62,7 +62,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Remote package version file content is empty !"; + Error = $"Remote package version file content is empty."; } else { @@ -75,7 +75,7 @@ namespace YooAsset _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _webTextRequestOp.Error; - WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(RequestRemotePackageVersionOperation)); + DownloadFailureCounter.RecordFailure(_fileSystem.PackageName, nameof(RequestRemotePackageVersionOperation)); } } } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheFileOperation.cs similarity index 94% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheFileOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheFileOperation.cs index 830915ca..6c9a4c9b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheFileOperation.cs @@ -27,7 +27,7 @@ namespace YooAsset { URL = url; } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { return $"RefCount : {RefCount}"; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs similarity index 88% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs index c8cbfed1..45552246 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs @@ -16,14 +16,14 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly PackageBundle _bundle; private readonly string _tempFilePath; private IDownloadRequest _request; private VerifyTempFileOperation _verifyOperation; private ESteps _steps = ESteps.None; - internal DownloadAndCacheLocalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url) : base(url) + internal DownloadAndCacheLocalFileOperation(CacheFileSystem fileSystem, PackageBundle bundle, string url) : base(url) { _fileSystem = fileSystem; _bundle = bundle; @@ -87,7 +87,7 @@ namespace YooAsset // 创建下载请求 if (_steps == ESteps.CreateRequest) { - int watchdogTime = _fileSystem.DownloadWatchDogTime; + int watchdogTime = _fileSystem.DownloadWatchDogTimeout; int timeout = 0; //注意:文件下载不做超时检测 var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime); _request = _fileSystem.DownloadBackend.CreateFileRequest(args); @@ -98,6 +98,10 @@ namespace YooAsset // 检测下载结果 if (_steps == ESteps.CheckRequest) { + //TODO 更新下载后台,防止无限挂起 + if (IsWaitingForAsyncComplete) + _fileSystem.DownloadBackend.Update(); + DownloadProgress = _request.DownloadProgress; DownloadedBytes = _request.DownloadedBytes; Progress = DownloadProgress; @@ -125,13 +129,13 @@ namespace YooAsset { if (_verifyOperation == null) { - var element = new TempFileElement(_tempFilePath, _bundle.FileCRC, _bundle.FileSize); + var element = new TempFileInfo(_tempFilePath, _bundle.FileCRC, _bundle.FileSize); _verifyOperation = new VerifyTempFileOperation(element); _verifyOperation.StartOperation(); AddChildOperation(_verifyOperation); } - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _verifyOperation.WaitForAsyncComplete(); _verifyOperation.UpdateOperation(); @@ -166,7 +170,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"{_fileSystem.GetType().FullName} failed to write file !"; + Error = $"{_fileSystem.GetType().FullName} failed to write file."; } // 注意:缓存完成后直接删除临时文件 @@ -177,23 +181,12 @@ namespace YooAsset internal override void InternalAbort() { if (_request != null) - _request.AbortRequest(); + _request.Dispose(); } internal override void InternalWaitForAsyncComplete() { - while (true) - { - //TODO 更新下载后台,防止无限挂起 - _fileSystem.DownloadBackend.Update(); - - //TODO 等待导入或解压本地文件完毕,该操作会挂起主线程! - InternalUpdate(); - if (IsDone) - break; - - //TODO 短暂休眠避免完全卡死 - System.Threading.Thread.Sleep(1); - } + //TODO 等待导入或解压本地文件完毕,该操作会挂起主线程! + RunUntilCompletion(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs similarity index 91% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs index 563c0578..de14d494 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs @@ -14,7 +14,7 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly PackageBundle _bundle; private readonly string _tempFilePath; private bool _enableResume = false; @@ -23,7 +23,7 @@ namespace YooAsset private VerifyTempFileOperation _verifyOperation; private ESteps _steps = ESteps.None; - internal DownloadAndCacheRemoteFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url) : base(url) + internal DownloadAndCacheRemoteFileOperation(CacheFileSystem fileSystem, PackageBundle bundle, string url) : base(url) { _fileSystem = fileSystem; _bundle = bundle; @@ -92,13 +92,13 @@ namespace YooAsset { if (_verifyOperation == null) { - var element = new TempFileElement(_tempFilePath, _bundle.FileCRC, _bundle.FileSize); + var element = new TempFileInfo(_tempFilePath, _bundle.FileCRC, _bundle.FileSize); _verifyOperation = new VerifyTempFileOperation(element); _verifyOperation.StartOperation(); AddChildOperation(_verifyOperation); } - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _verifyOperation.WaitForAsyncComplete(); _verifyOperation.UpdateOperation(); @@ -133,7 +133,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"{_fileSystem.GetType().FullName} failed to write file !"; + Error = $"{_fileSystem.GetType().FullName} failed to write file."; } // 注意:缓存完成后直接删除临时文件 @@ -144,14 +144,14 @@ namespace YooAsset internal override void InternalAbort() { if (_request != null) - _request.AbortRequest(); + _request.Dispose(); } internal override void InternalWaitForAsyncComplete() { if (_steps != ESteps.Done) { // 注意:不中断下载任务,保持后台继续下载 - YooLogger.Error($"Try load bundle {_bundle.BundleName} from remote : {URL} !"); + YooLogger.Error($"Try load bundle {_bundle.BundleName} from remote : {URL}"); } } @@ -171,12 +171,12 @@ namespace YooAsset } } - int watchdogTime = _fileSystem.DownloadWatchDogTime; + int watchdogTime = _fileSystem.DownloadWatchDogTimeout; int timeout = 0; //注意:文件下载不做超时检测 bool appendToFile = true; bool removeFileOnAbort = false; - long resumeFromBytes = _fileOriginLength; - var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime, appendToFile, removeFileOnAbort, resumeFromBytes); + long resumeOffset = _fileOriginLength; + var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime, appendToFile, removeFileOnAbort, resumeOffset); return _fileSystem.DownloadBackend.CreateFileRequest(args); } private IDownloadRequest CreateNormalRequest() @@ -185,7 +185,7 @@ namespace YooAsset if (File.Exists(_tempFilePath)) File.Delete(_tempFilePath); - int watchdogTime = _fileSystem.DownloadWatchDogTime; + int watchdogTime = _fileSystem.DownloadWatchDogTimeout; int timeout = 0; //注意:文件下载不做超时检测 var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime); return _fileSystem.DownloadBackend.CreateFileRequest(args); diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadSchedulerOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadSchedulerOperation.cs similarity index 91% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadSchedulerOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadSchedulerOperation.cs index 6f6ff833..ebb8f9ac 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadSchedulerOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadSchedulerOperation.cs @@ -11,7 +11,7 @@ namespace YooAsset /// internal class DownloadSchedulerOperation : AsyncOperationBase, IDisposable { - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly Dictionary _downloaders = new Dictionary(1000); private readonly List _removeList = new List(1000); @@ -40,7 +40,7 @@ namespace YooAsset /// /// 构造下载中心 /// - public DownloadSchedulerOperation(DefaultCacheFileSystem fileSystem) + public DownloadSchedulerOperation(CacheFileSystem fileSystem) { _fileSystem = fileSystem; } @@ -113,29 +113,22 @@ namespace YooAsset } } } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { return $"{_fileSystem.GetType().FullName}"; } /// - /// 中止所有下载任务 - /// - public void AbortAll() - { - foreach (var valuePair in _downloaders) - { - valuePair.Value.AbortOperation(); - } - _downloaders.Clear(); - } - - /// - /// 释放资源 + /// 释放下载资源 /// public void Dispose() { - AbortAll(); + foreach (var valuePair in _downloaders) + { + var operation = valuePair.Value; + operation.AbortOperation(); + } + _downloaders.Clear(); } /// @@ -155,7 +148,7 @@ namespace YooAsset // 创建新的下载器 DownloadAndCacheFileOperation newDownloader; - bool isRequestLocalFile = DownloadSystemHelper.IsRequestLocalFile(url); + bool isRequestLocalFile = DownloadSystemTools.IsLocalFileURL(url); if (isRequestLocalFile) { newDownloader = new DownloadAndCacheLocalFileOperation(_fileSystem, bundle, url); diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadSchedulerOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadSchedulerOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/Scheduler/DownloadSchedulerOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadSchedulerOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs similarity index 86% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs index a297e886..b11be146 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs @@ -15,25 +15,25 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private IEnumerator _filesEnumerator = null; - private float _verifyStartTime; + private double _verifyStartTime; private ESteps _steps = ESteps.None; /// /// 需要验证的元素 /// - public readonly List Result = new List(5000); + public readonly List Result = new List(5000); - internal SearchCacheFilesOperation(DefaultCacheFileSystem fileSystem) + internal SearchCacheFilesOperation(CacheFileSystem fileSystem) { _fileSystem = fileSystem; } internal override void InternalStart() { _steps = ESteps.Prepare; - _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; + _verifyStartTime = TimeUtility.RealtimeSinceStartup; } internal override void InternalUpdate() { @@ -58,7 +58,7 @@ namespace YooAsset _steps = ESteps.Done; Status = EOperationStatus.Succeed; - float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; + double costTime = TimeUtility.RealtimeSinceStartup - _verifyStartTime; YooLogger.Log($"Search cache files elapsed time {costTime:f1} seconds"); } } @@ -98,7 +98,7 @@ namespace YooAsset } } - var element = new VerifyFileElement(_fileSystem.PackageName, bundleGUID, fileRootPath, dataFilePath, infoFilePath); + var element = new VerifyFileInfo(_fileSystem.PackageName, bundleGUID, fileRootPath, dataFilePath, infoFilePath); Result.Add(element); } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs similarity index 83% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs index c6581091..97126e28 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs @@ -19,19 +19,19 @@ namespace YooAsset Done, } - private readonly DefaultCacheFileSystem _fileSystem; + private readonly CacheFileSystem _fileSystem; private readonly EFileVerifyLevel _fileVerifyLevel; - private List _waitingList; - private List _verifyingList; + private List _waitingList; + private List _verifyingList; private int _verifyMaxNum; private int _verifyTotalCount; - private float _verifyStartTime; + private double _verifyStartTime; private int _succeedCount; private int _failedCount; private ESteps _steps = ESteps.None; - internal VerifyCacheFilesOperation(DefaultCacheFileSystem fileSystem, List elements) + internal VerifyCacheFilesOperation(CacheFileSystem fileSystem, List elements) { _fileSystem = fileSystem; _waitingList = elements; @@ -40,7 +40,7 @@ namespace YooAsset internal override void InternalStart() { _steps = ESteps.InitVerify; - _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; + _verifyStartTime = TimeUtility.RealtimeSinceStartup; } internal override void InternalUpdate() { @@ -61,7 +61,7 @@ namespace YooAsset _verifyMaxNum = 1; YooLogger.Log($"Verify max concurrency : {_verifyMaxNum}"); - _verifyingList = new List(_verifyMaxNum); + _verifyingList = new List(_verifyMaxNum); _steps = ESteps.UpdateVerify; } @@ -84,7 +84,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Succeed; - float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; + double costTime = TimeUtility.RealtimeSinceStartup - _verifyStartTime; YooLogger.Log($"Verify cache files elapsed time {costTime:f1} seconds"); } @@ -120,16 +120,16 @@ namespace YooAsset } private void VerifyInThread(object obj) { - VerifyFileElement element = (VerifyFileElement)obj; + VerifyFileInfo element = (VerifyFileInfo)obj; int verifyResult = (int)VerifyingCacheFile(element, _fileVerifyLevel); element.Result = verifyResult; } - private void RecordVerifyFile(VerifyFileElement element) + private void RecordVerifyFile(VerifyFileInfo element) { if (element.Result == (int)EFileVerifyResult.Succeed) { _succeedCount++; - var recordFileElement = new RecordFileElement(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize); + var recordFileElement = new FileCacheEntry(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize); _fileSystem.RecordBundleFile(element.BundleGUID, recordFileElement); } else @@ -143,7 +143,7 @@ namespace YooAsset /// /// 验证缓存文件(子线程内操作) /// - private EFileVerifyResult VerifyingCacheFile(VerifyFileElement element, EFileVerifyLevel verifyLevel) + private EFileVerifyResult VerifyingCacheFile(VerifyFileInfo element, EFileVerifyLevel verifyLevel) { try { @@ -169,7 +169,7 @@ namespace YooAsset return EFileVerifyResult.Exception; } - return FileVerifyHelper.FileVerify(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel); + return FileVerifyTools.FileVerify(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/VerifyTempFileOperation.cs similarity index 73% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/VerifyTempFileOperation.cs index b88aa886..da18bd12 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/VerifyTempFileOperation.cs @@ -16,7 +16,7 @@ namespace YooAsset Done, } - private readonly TempFileElement _element; + private readonly TempFileInfo _element; private ESteps _steps = ESteps.None; /// @@ -25,7 +25,7 @@ namespace YooAsset public EFileVerifyResult VerifyResult { private set; get; } - internal VerifyTempFileOperation(TempFileElement element) + internal VerifyTempFileOperation(TempFileInfo element) { _element = element; } @@ -63,28 +63,20 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Failed to verify file : {_element.TempFilePath} ! ErrorCode : {VerifyResult}"; + Error = $"Failed to verify file : {_element.TempFilePath} ErrorCode : {VerifyResult}"; } } } internal override void InternalWaitForAsyncComplete() { - while (true) - { - //TODO 等待子线程验证文件完毕,该操作会挂起主线程! - InternalUpdate(); - if (IsDone) - break; - - //TODO 短暂休眠避免完全卡死 - System.Threading.Thread.Sleep(1); - } + //TODO 等待子线程验证文件完毕,该操作会挂起主线程! + RunUntilCompletion(); } private void VerifyInThread(object obj) { - TempFileElement element = (TempFileElement)obj; - int result = (int)FileVerifyHelper.FileVerify(element.TempFilePath, element.TempFileSize, element.TempFileCRC, EFileVerifyLevel.High); + TempFileInfo element = (TempFileInfo)obj; + int result = (int)FileVerifyTools.FileVerify(element.TempFilePath, element.TempFileSize, element.TempFileCRC, EFileVerifyLevel.High); element.Result = result; } } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/VerifyTempFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/VerifyTempFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/TempFileElement.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/TempFileInfo.cs similarity index 80% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/TempFileElement.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/TempFileInfo.cs index b3c69048..84ff3774 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/TempFileElement.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/TempFileInfo.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class TempFileElement + internal class TempFileInfo { public string TempFilePath { private set; get; } public uint TempFileCRC { private set; get; } @@ -12,7 +12,7 @@ namespace YooAsset /// public volatile int Result = 0; - public TempFileElement(string filePath, uint fileCRC, long fileSize) + public TempFileInfo(string filePath, uint fileCRC, long fileSize) { TempFilePath = filePath; TempFileCRC = fileCRC; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/TempFileElement.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/TempFileInfo.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/TempFileElement.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/TempFileInfo.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/VerifyFileElement.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/VerfiyFileInfo.cs similarity index 85% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/VerifyFileElement.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/VerfiyFileInfo.cs index de3c40f0..1f5adcda 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/VerifyFileElement.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/VerfiyFileInfo.cs @@ -2,7 +2,7 @@ namespace YooAsset { - internal class VerifyFileElement + internal class VerifyFileInfo { public string PackageName { private set; get; } public string BundleGUID { private set; get; } @@ -18,7 +18,7 @@ namespace YooAsset /// public volatile int Result = 0; - public VerifyFileElement(string packageName, string bundleGUID, string fileRootPath, string dataFilePath, string infoFilePath) + public VerifyFileInfo(string packageName, string bundleGUID, string fileRootPath, string dataFilePath, string infoFilePath) { PackageName = packageName; BundleGUID = bundleGUID; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/VerifyFileElement.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/VerfiyFileInfo.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Elements/VerifyFileElement.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/VerfiyFileInfo.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/EditorFileSystem.cs similarity index 77% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/EditorFileSystem.cs index 0412d547..7a8b686e 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/EditorFileSystem.cs @@ -6,7 +6,7 @@ namespace YooAsset /// /// 模拟文件系统 /// - internal class DefaultEditorFileSystem : IFileSystem + internal class EditorFileSystem : IFileSystem { protected readonly Dictionary _records = new Dictionary(10000); protected string _packageRoot; @@ -75,46 +75,47 @@ namespace YooAsset public int AsyncSimulateMaxFrame { private set; get; } = 1; #endregion - public DefaultEditorFileSystem() + public EditorFileSystem() { } - public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + public virtual FSInitializeOperation InitializeAsync() { - var operation = new DEFSInitializeOperation(this); + var operation = new EFSInitializeOperation(this); return operation; } - public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) + public virtual FSRequestVersionOperation RequestVersionAsync(RequestVersionOptions options) { - var operation = new DEFSLoadPackageManifestOperation(this, packageVersion); + var operation = new EFSRequestVersionOperation(this); return operation; } - public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout) + public virtual FSLoadManifestOperation LoadManifestAsync(LoadManifestOptions options) { - var operation = new DEFSRequestPackageVersionOperation(this); + var operation = new EFSLoadManifestOperation(this, options.PackageVersion); return operation; } - public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options) + public virtual FSClearCacheOperation ClearCacheAsync(ClearCacheOptions options) { - var operation = new FSClearCacheFilesCompleteOperation(); + var operation = new FSClearCacheCompleteOperation(); return operation; } - public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) + public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options) { - string mainURL = bundle.BundleName; + string mainURL = options.Bundle.BundleName; options.SetURL(mainURL, mainURL); - var downloader = new DownloadVirtualBundleOperation(this, bundle, options); + var downloader = new DownloadVirtualBundleOperation(this, options); return downloader; } - public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) { - if (bundle.BundleType == (int)EBuildBundleType.VirtualBundle) + PackageBundle bundle = options.Bundle; + if (bundle.BundleType == (int)EBundleType.VirtualBundle) { - var operation = new DEFSLoadBundleOperation(this, bundle); + var operation = new EFSLoadBundleOperation(this, bundle); return operation; } else { - string error = $"{nameof(DefaultEditorFileSystem)} not support load bundle type : {bundle.BundleType}"; + string error = $"{nameof(EditorFileSystem)} not support load bundle type : {bundle.BundleType}"; var operation = new FSLoadBundleCompleteOperation(error); return operation; } @@ -160,7 +161,7 @@ namespace YooAsset PackageName = packageName; if (string.IsNullOrEmpty(packageRoot)) - throw new YooFileSystemException($"{nameof(DefaultEditorFileSystem)} package root is null or empty !"); + throw new YooFileSystemException($"{nameof(EditorFileSystem)} package root is null or empty."); _packageRoot = packageRoot; @@ -207,7 +208,6 @@ namespace YooAsset { return false; } - public virtual string GetBundleFilePath(PackageBundle bundle) { if (bundle.IncludeMainAssets.Count == 0) @@ -216,22 +216,6 @@ namespace YooAsset var pacakgeAsset = bundle.IncludeMainAssets[0]; return pacakgeAsset.AssetPath; } - public virtual byte[] ReadBundleFileData(PackageBundle bundle) - { - if (bundle.IncludeMainAssets.Count == 0) - return null; - - var pacakgeAsset = bundle.IncludeMainAssets[0]; - return FileUtility.ReadAllBytes(pacakgeAsset.AssetPath); - } - public virtual string ReadBundleFileText(PackageBundle bundle) - { - if (bundle.IncludeMainAssets.Count == 0) - return null; - - var pacakgeAsset = bundle.IncludeMainAssets[0]; - return FileUtility.ReadAllText(pacakgeAsset.AssetPath); - } #region 内部方法 public void RecordDownloadFile(PackageBundle bundle) diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/EditorFileSystem.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/EditorFileSystem.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSInitializeOperation.cs similarity index 56% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSInitializeOperation.cs index b9de895d..b230e89b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSInitializeOperation.cs @@ -1,11 +1,11 @@  namespace YooAsset { - internal class DEFSInitializeOperation : FSInitializeFileSystemOperation + internal class EFSInitializeOperation : FSInitializeOperation { - private readonly DefaultEditorFileSystem _fileSytem; + private readonly EditorFileSystem _fileSytem; - internal DEFSInitializeOperation(DefaultEditorFileSystem fileSystem) + internal EFSInitializeOperation(EditorFileSystem fileSystem) { _fileSytem = fileSystem; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSInitializeOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSInitializeOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSLoadBundleOperation.cs similarity index 86% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSLoadBundleOperation.cs index 65685ce9..d958fd72 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSLoadBundleOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DEFSLoadBundleOperation : FSLoadBundleOperation + internal class EFSLoadBundleOperation : FSLoadBundleOperation { protected enum ESteps { @@ -14,13 +14,13 @@ namespace YooAsset Done, } - private readonly DefaultEditorFileSystem _fileSystem; + private readonly EditorFileSystem _fileSystem; private readonly PackageBundle _bundle; protected FSDownloadFileOperation _downloadFileOp; private int _asyncSimulateFrame; private ESteps _steps = ESteps.None; - internal DEFSLoadBundleOperation(DefaultEditorFileSystem fileSystem, PackageBundle bundle) + internal EFSLoadBundleOperation(EditorFileSystem fileSystem, PackageBundle bundle) { _fileSystem = fileSystem; _bundle = bundle; @@ -64,13 +64,13 @@ namespace YooAsset { if (_downloadFileOp == null) { - DownloadFileOptions options = new DownloadFileOptions(int.MaxValue); - _downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, options); + DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue); + _downloadFileOp = _fileSystem.DownloadFileAsync(options); _downloadFileOp.StartOperation(); AddChildOperation(_downloadFileOp); } - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _downloadFileOp.WaitForAsyncComplete(); _downloadFileOp.UpdateOperation(); @@ -95,7 +95,7 @@ namespace YooAsset { if (_downloadFileOp != null) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _downloadFileOp.WaitForAsyncComplete(); _downloadFileOp.UpdateOperation(); @@ -105,18 +105,18 @@ namespace YooAsset _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Abort download file !"; + Error = "Abort download file."; } if (_steps == ESteps.LoadAssetBundle) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { if (_fileSystem.VirtualWebGLMode) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Virtual WebGL Mode only support asyn load method !"; + Error = "Virtual WebGL Mode only support asyn load method."; YooLogger.Error(Error); } else @@ -142,14 +142,7 @@ namespace YooAsset } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSLoadBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSLoadBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSLoadManifestOperation.cs similarity index 92% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSLoadManifestOperation.cs index 02f838fd..204fea4f 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSLoadManifestOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DEFSLoadPackageManifestOperation : FSLoadPackageManifestOperation + internal class EFSLoadManifestOperation : FSLoadManifestOperation { private enum ESteps { @@ -11,14 +11,14 @@ namespace YooAsset Done, } - private readonly DefaultEditorFileSystem _fileSystem; + private readonly EditorFileSystem _fileSystem; private readonly string _packageVersion; private LoadEditorPackageHashOperation _loadEditorPackageHashOpe; private LoadEditorPackageManifestOperation _loadEditorPackageManifestOp; private ESteps _steps = ESteps.None; - internal DEFSLoadPackageManifestOperation(DefaultEditorFileSystem fileSystem, string packageVersion) + internal EFSLoadManifestOperation(EditorFileSystem fileSystem, string packageVersion) { _fileSystem = fileSystem; _packageVersion = packageVersion; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSLoadManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSLoadManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSRequestPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSRequestVersionOperation.cs similarity index 87% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSRequestPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSRequestVersionOperation.cs index ac34873a..48b15abf 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSRequestPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSRequestVersionOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DEFSRequestPackageVersionOperation : FSRequestPackageVersionOperation + internal class EFSRequestVersionOperation : FSRequestVersionOperation { private enum ESteps { @@ -10,12 +10,12 @@ namespace YooAsset Done, } - private readonly DefaultEditorFileSystem _fileSystem; + private readonly EditorFileSystem _fileSystem; private LoadEditorPackageVersionOperation _loadEditorPackageVersionOp; private ESteps _steps = ESteps.None; - internal DEFSRequestPackageVersionOperation(DefaultEditorFileSystem fileSystem) + internal EFSRequestVersionOperation(EditorFileSystem fileSystem) { _fileSystem = fileSystem; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSRequestVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSRequestPackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/EFSRequestVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/DownloadVirutalBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/DownloadVirutalBundleOperation.cs similarity index 91% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/DownloadVirutalBundleOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/DownloadVirutalBundleOperation.cs index ec6ac221..aea4874a 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/DownloadVirutalBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/DownloadVirutalBundleOperation.cs @@ -15,7 +15,7 @@ namespace YooAsset } // 下载参数 - protected readonly DefaultEditorFileSystem _fileSystem; + protected readonly EditorFileSystem _fileSystem; protected readonly DownloadFileOptions _options; protected IDownloadFileRequest _downloadFileOp; @@ -25,7 +25,7 @@ namespace YooAsset private ESteps _steps = ESteps.None; - internal DownloadVirtualBundleOperation(DefaultEditorFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle) + internal DownloadVirtualBundleOperation(EditorFileSystem fileSystem, DownloadFileOptions options) : base(options.Bundle) { _fileSystem = fileSystem; _options = options; @@ -61,7 +61,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Download file options is invalid !"; + Error = "Download file options is invalid."; Debug.Log(Error); return; } @@ -91,10 +91,10 @@ namespace YooAsset } else { - if (IsWaitForAsyncComplete == false && _failedTryAgain > 0) + if (IsWaitingForAsyncComplete == false && _failedTryAgain > 0) { _steps = ESteps.TryAgain; - YooLogger.Warning($"Failed download : {_downloadFileOp.URL} Try again !"); + YooLogger.Warning($"Failed download : {_downloadFileOp.URL} Try again."); } else { @@ -127,7 +127,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Try load bundle {Bundle.BundleName} from remote !"; + Error = $"Try load bundle {Bundle.BundleName} from remote."; YooLogger.Error(Error); } } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/DownloadVirutalBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/DownloadVirutalBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/DownloadVirutalBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/DownloadVirutalBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageHashOperation.cs similarity index 89% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageHashOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageHashOperation.cs index ecfcdc3f..d4ff4a65 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageHashOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageHashOperation.cs @@ -11,7 +11,7 @@ namespace YooAsset Done, } - private readonly DefaultEditorFileSystem _fileSystem; + private readonly EditorFileSystem _fileSystem; private readonly string _packageVersion; private ESteps _steps = ESteps.None; @@ -21,7 +21,7 @@ namespace YooAsset public string PackageHash { private set; get; } - internal LoadEditorPackageHashOperation(DefaultEditorFileSystem fileSystem, string packageVersion) + internal LoadEditorPackageHashOperation(EditorFileSystem fileSystem, string packageVersion) { _fileSystem = fileSystem; _packageVersion = packageVersion; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageHashOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageHashOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageHashOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs similarity index 90% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs index c6ebcc4b..1a29e270 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs @@ -13,7 +13,7 @@ namespace YooAsset Done, } - private readonly DefaultEditorFileSystem _fileSystem; + private readonly EditorFileSystem _fileSystem; private readonly string _packageVersion; private readonly string _packageHash; private DeserializeManifestOperation _deserializer; @@ -26,7 +26,7 @@ namespace YooAsset public PackageManifest Manifest { private set; get; } - internal LoadEditorPackageManifestOperation(DefaultEditorFileSystem fileSystem, string packageVersion, string packageHash) + internal LoadEditorPackageManifestOperation(EditorFileSystem fileSystem, string packageVersion, string packageHash) { _fileSystem = fileSystem; _packageVersion = packageVersion; @@ -59,7 +59,7 @@ namespace YooAsset if (_steps == ESteps.VerifyFileData) { - if (ManifestTools.VerifyManifestData(_fileData, _packageHash)) + if (PackageManifestTools.VerifyManifestData(_fileData, _packageHash)) { _steps = ESteps.LoadManifest; } @@ -67,7 +67,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Failed to verify simulation package manifest file !"; + Error = "Failed to verify simulation package manifest file."; } } @@ -99,7 +99,7 @@ namespace YooAsset } } } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { return $"PackageVersion : {_packageVersion} PackageHash : {_packageHash}"; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageVersionOperation.cs similarity index 90% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageVersionOperation.cs index 05a0d7f9..fa38568d 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageVersionOperation.cs @@ -11,7 +11,7 @@ namespace YooAsset Done, } - private readonly DefaultEditorFileSystem _fileSystem; + private readonly EditorFileSystem _fileSystem; private ESteps _steps = ESteps.None; /// @@ -20,7 +20,7 @@ namespace YooAsset public string PackageVersion { private set; get; } - internal LoadEditorPackageVersionOperation(DefaultEditorFileSystem fileSystem) + internal LoadEditorPackageVersionOperation(EditorFileSystem fileSystem) { _fileSystem = fileSystem; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/Operation/internal/LoadEditorPackageVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackFileSystem.cs similarity index 56% rename from Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackFileSystem.cs index 3b56ac3a..597e964b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackFileSystem.cs @@ -4,9 +4,9 @@ namespace YooAsset /// /// 解压文件系统 /// - internal class DefaultUnpackFileSystem : DefaultCacheFileSystem + internal class UnpackFileSystem : CacheFileSystem { - public DefaultUnpackFileSystem() + public UnpackFileSystem() { } public override void OnCreate(string packageName, string rootDirectory) @@ -14,9 +14,9 @@ namespace YooAsset base.OnCreate(packageName, rootDirectory); // 注意:重写保存根目录和临时目录 - _cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.SaveBundleFilesFolderName); - _cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.SaveManifestFilesFolderName); - _tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.TempFilesFolderName); + _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/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackFileSystem.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackFileSystem.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackFileSystemConstants.cs similarity index 91% rename from Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackFileSystemConstants.cs index fc3538a5..a23fda1a 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackFileSystemConstants.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DefaultUnpackFileSystemDefine + internal class UnpackFileSystemConstants { /// /// 保存的资源文件的文件夹名称 diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackFileSystemConstants.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackFileSystemConstants.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackRemoteServices.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackRemoteService.cs similarity index 81% rename from Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackRemoteServices.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackRemoteService.cs index 519db3ac..378bd197 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackRemoteServices.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackRemoteService.cs @@ -2,12 +2,12 @@ namespace YooAsset { - internal class DefaultUnpackRemoteServices : IRemoteServices + internal class UnpackRemoteService : IRemoteServices { private readonly string _buildinPackageRoot; protected readonly Dictionary _mapping = new Dictionary(10000); - public DefaultUnpackRemoteServices(string buildinPackRoot) + public UnpackRemoteService(string buildinPackRoot) { _buildinPackageRoot = buildinPackRoot; } @@ -25,7 +25,7 @@ namespace YooAsset if (_mapping.TryGetValue(fileName, out string url) == false) { string filePath = PathUtility.Combine(_buildinPackageRoot, fileName); - url = DownloadSystemHelper.ConvertToWWWPath(filePath); + url = DownloadSystemTools.ToLocalURL(filePath); _mapping.Add(fileName, url); } return url; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackRemoteServices.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackRemoteService.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackRemoteServices.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/UnpackFileSystem/UnpackRemoteService.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/WebGame.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/WebGame.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation.meta similarity index 77% rename from Assets/YooAsset/Runtime/FileSystem/WebGame/Operation.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation.meta index 24ba6337..737f941e 100644 --- a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation.meta +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 10a171d1f549765498fc478ac208cfe5 +guid: 2f9d85bd2fb05684fb1656d3dca59610 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebPackageManifestOperation.cs similarity index 91% rename from Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebPackageManifestOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebPackageManifestOperation.cs index 03014d54..b4427eb6 100644 --- a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebPackageManifestOperation.cs @@ -42,7 +42,7 @@ internal class LoadWebPackageManifestOperation : AsyncOperationBase } internal override void InternalStart() { - _requestCount = WebRequestCounter.GetRequestFailedCount(_packageName, nameof(LoadWebPackageManifestOperation)); + _requestCount = DownloadFailureCounter.GetFailureCount(_packageName, nameof(LoadWebPackageManifestOperation)); _steps = ESteps.RequestFileData; } internal override void InternalUpdate() @@ -74,13 +74,13 @@ internal class LoadWebPackageManifestOperation : AsyncOperationBase _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _webDataRequestOp.Error; - WebRequestCounter.RecordRequestFailed(_packageName, nameof(LoadWebPackageManifestOperation)); + DownloadFailureCounter.RecordFailure(_packageName, nameof(LoadWebPackageManifestOperation)); } } if (_steps == ESteps.VerifyFileData) { - if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash)) + if (PackageManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash)) { _steps = ESteps.LoadManifest; } @@ -88,7 +88,7 @@ internal class LoadWebPackageManifestOperation : AsyncOperationBase { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Failed to verify web package manifest file!"; + Error = "Failed to verify web package manifest file."; } } @@ -120,7 +120,7 @@ internal class LoadWebPackageManifestOperation : AsyncOperationBase } } } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { return $"PackageVersion : {_packageVersion} PackageHash : {_packageHash}"; } diff --git a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebPackageManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebPackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebPackageManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/RequestWebPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/RequestWebPackageHashOperation.cs similarity index 92% rename from Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/RequestWebPackageHashOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/RequestWebPackageHashOperation.cs index c7572317..c466c2c9 100644 --- a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/RequestWebPackageHashOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/RequestWebPackageHashOperation.cs @@ -34,7 +34,7 @@ internal class RequestWebPackageHashOperation : AsyncOperationBase } internal override void InternalStart() { - _requestCount = WebRequestCounter.GetRequestFailedCount(_packageName, nameof(RequestWebPackageHashOperation)); + _requestCount = DownloadFailureCounter.GetFailureCount(_packageName, nameof(RequestWebPackageHashOperation)); _steps = ESteps.RequestPackageHash; } internal override void InternalUpdate() @@ -64,7 +64,7 @@ internal class RequestWebPackageHashOperation : AsyncOperationBase { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Web package hash file content is empty !"; + Error = $"Web package hash file content is empty."; } else { @@ -77,7 +77,7 @@ internal class RequestWebPackageHashOperation : AsyncOperationBase _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _webTextRequestOp.Error; - WebRequestCounter.RecordRequestFailed(_packageName, nameof(RequestWebPackageHashOperation)); + DownloadFailureCounter.RecordFailure(_packageName, nameof(RequestWebPackageHashOperation)); } } } diff --git a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/RequestWebPackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/RequestWebPackageHashOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/RequestWebPackageHashOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/RequestWebPackageHashOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/RequestWebPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/RequestWebPackageVersionOperation.cs similarity index 92% rename from Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/RequestWebPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/RequestWebPackageVersionOperation.cs index 36e729ff..a21f4e99 100644 --- a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/RequestWebPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/RequestWebPackageVersionOperation.cs @@ -34,7 +34,7 @@ internal class RequestWebPackageVersionOperation : AsyncOperationBase } internal override void InternalStart() { - _requestCount = WebRequestCounter.GetRequestFailedCount(_packageName, nameof(RequestWebPackageVersionOperation)); + _requestCount = DownloadFailureCounter.GetFailureCount(_packageName, nameof(RequestWebPackageVersionOperation)); _steps = ESteps.RequestPackageVersion; } internal override void InternalUpdate() @@ -64,7 +64,7 @@ internal class RequestWebPackageVersionOperation : AsyncOperationBase { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Web package version file content is empty !"; + Error = $"Web package version file content is empty."; } else { @@ -77,7 +77,7 @@ internal class RequestWebPackageVersionOperation : AsyncOperationBase _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _webTextRequestOp.Error; - WebRequestCounter.RecordRequestFailed(_packageName, nameof(RequestWebPackageVersionOperation)); + DownloadFailureCounter.RecordFailure(_packageName, nameof(RequestWebPackageVersionOperation)); } } } diff --git a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/RequestWebPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/RequestWebPackageVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/RequestWebPackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/RequestWebPackageVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSInitializeOperation.cs similarity index 55% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSInitializeOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSInitializeOperation.cs index 05d790db..75f529fc 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSInitializeOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSInitializeOperation.cs @@ -1,11 +1,11 @@  namespace YooAsset { - internal class DWRFSInitializeOperation : FSInitializeFileSystemOperation + internal class WRFSInitializeOperation : FSInitializeOperation { - private readonly DefaultWebRemoteFileSystem _fileSystem; + private readonly WebRemoteFileSystem _fileSystem; - public DWRFSInitializeOperation(DefaultWebRemoteFileSystem fileSystem) + public WRFSInitializeOperation(WebRemoteFileSystem fileSystem) { _fileSystem = fileSystem; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSInitializeOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSInitializeOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSInitializeOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadBundleOperation.cs similarity index 57% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSLoadBundleOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadBundleOperation.cs index b16c1aad..f5ae804a 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadBundleOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DWRFSLoadAssetBundleOperation : FSLoadBundleOperation + internal class WRFSLoadAssetBundleOperation : FSLoadBundleOperation { private enum ESteps { @@ -10,13 +10,13 @@ namespace YooAsset Done, } - private readonly DefaultWebRemoteFileSystem _fileSystem; + private readonly WebRemoteFileSystem _fileSystem; private readonly PackageBundle _bundle; private LoadWebAssetBundleOperation _loadWebAssetBundleOp; private ESteps _steps = ESteps.None; - internal DWRFSLoadAssetBundleOperation(DefaultWebRemoteFileSystem fileSystem, PackageBundle bundle) + internal WRFSLoadAssetBundleOperation(WebRemoteFileSystem fileSystem, PackageBundle bundle) { _fileSystem = fileSystem; _bundle = bundle; @@ -34,23 +34,17 @@ namespace YooAsset { if (_loadWebAssetBundleOp == null) { - string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); - string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName); - DownloadFileOptions options = new DownloadFileOptions(int.MaxValue); - options.SetURL(mainURL, fallbackURL); - - if (_bundle.Encrypted) - { - _loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(_bundle, options, _fileSystem.DecryptionServices, _fileSystem.DownloadBackend); - _loadWebAssetBundleOp.StartOperation(); - AddChildOperation(_loadWebAssetBundleOp); - } - else - { - _loadWebAssetBundleOp = new LoadWebNormalAssetBundleOperation(_bundle, options, _fileSystem.DisableUnityWebCache, _fileSystem.DownloadBackend); - _loadWebAssetBundleOp.StartOperation(); - AddChildOperation(_loadWebAssetBundleOp); - } + 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); } _loadWebAssetBundleOp.UpdateOperation(); @@ -62,17 +56,16 @@ namespace YooAsset if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeed) { - var assetBundle = _loadWebAssetBundleOp.Result; - if (assetBundle == null) + if (_loadWebAssetBundleOp.Result == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"{nameof(DWRFSLoadAssetBundleOperation)} loaded asset bundle is null !"; + Error = $"Loaded asset bundle object is null."; } else { _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, assetBundle, null); + Result = new AssetBundleResult(_fileSystem, _bundle, _loadWebAssetBundleOp.Result, null); Status = EOperationStatus.Succeed; } } @@ -90,8 +83,8 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "WebGL platform not support sync load method !"; - UnityEngine.Debug.LogError(Error); + Error = "WebGL platform not support sync load method."; + YooLogger.Error(Error); } } } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSLoadBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadManifestOperation.cs similarity index 90% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSLoadPackageManifestOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadManifestOperation.cs index c0c68ba4..97d55ebf 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSLoadPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadManifestOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DWRFSLoadPackageManifestOperation : FSLoadPackageManifestOperation + internal class WRFSLoadManifestOperation : FSLoadManifestOperation { private enum ESteps { @@ -11,7 +11,7 @@ namespace YooAsset Done, } - private readonly DefaultWebRemoteFileSystem _fileSystem; + private readonly WebRemoteFileSystem _fileSystem; private readonly string _packageVersion; private readonly int _timeout; private RequestWebPackageHashOperation _requestWebPackageHashOp; @@ -19,7 +19,7 @@ namespace YooAsset private ESteps _steps = ESteps.None; - public DWRFSLoadPackageManifestOperation(DefaultWebRemoteFileSystem fileSystem, string packageVersion, int timeout) + public WRFSLoadManifestOperation(WebRemoteFileSystem fileSystem, string packageVersion, int timeout) { _fileSystem = fileSystem; _packageVersion = packageVersion; @@ -65,7 +65,7 @@ namespace YooAsset { string packageHash = _requestWebPackageHashOp.PackageHash; string packageName = _fileSystem.PackageName; - var manifestServices = _fileSystem.ManifestServices; + var manifestServices = _fileSystem.ManifestRestoreServices; var remoteServices = _fileSystem.RemoteServices; var downloadBackend = _fileSystem.DownloadBackend; _loadWebPackageManifestOp = new LoadWebPackageManifestOperation(manifestServices, remoteServices, downloadBackend, packageName, _packageVersion, packageHash, _timeout); diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSLoadPackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSRequestPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSRequestVersionOperation.cs similarity index 87% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSRequestPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSRequestVersionOperation.cs index 82042c38..06cbb26c 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSRequestPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSRequestVersionOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DWRFSRequestPackageVersionOperation : FSRequestPackageVersionOperation + internal class WRFSRequestVersionOperation : FSRequestVersionOperation { private enum ESteps { @@ -10,14 +10,14 @@ namespace YooAsset Done, } - private readonly DefaultWebRemoteFileSystem _fileSystem; + private readonly WebRemoteFileSystem _fileSystem; private readonly bool _appendTimeTicks; private readonly int _timeout; private RequestWebPackageVersionOperation _requestWebPackageVersionOp; private ESteps _steps = ESteps.None; - internal DWRFSRequestPackageVersionOperation(DefaultWebRemoteFileSystem fileSystem, bool appendTimeTicks, int timeout) + internal WRFSRequestVersionOperation(WebRemoteFileSystem fileSystem, bool appendTimeTicks, int timeout) { _fileSystem = fileSystem; _appendTimeTicks = appendTimeTicks; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSRequestVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/Operation/DWRFSRequestPackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSRequestVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/DefaultWebRemoteFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/WebRemoteFileSystem.cs similarity index 60% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/DefaultWebRemoteFileSystem.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/WebRemoteFileSystem.cs index cfa668b9..0d0b7d5a 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/DefaultWebRemoteFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/WebRemoteFileSystem.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Collections.Generic; using UnityEngine; @@ -8,7 +8,7 @@ namespace YooAsset /// /// Web文件系统 /// - internal class DefaultWebRemoteFileSystem : IFileSystem + internal class WebRemoteFileSystem : IFileSystem { /// /// 下载后台接口 @@ -53,60 +53,66 @@ namespace YooAsset /// public bool DisableUnityWebCache { private set; get; } = false; + /// + /// 自定义参数:下载任务的看门狗机制超时时间 + /// + public int DownloadWatchDogTimeout { private set; get; } = 0; + /// /// 自定义参数:远程服务接口的实例类(支持跨域下载) /// public IRemoteServices RemoteServices { private set; get; } /// - /// 自定义参数:解密服务接口的实例类 + /// 自定义参数:加载 AssetBundle 的工厂委托 /// - public IWebDecryptionServices DecryptionServices { private set; get; } + public LoadWebAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; } /// /// 自定义参数:资源清单服务类 /// - public IManifestRestoreServices ManifestServices { private set; get; } + public IManifestRestoreServices ManifestRestoreServices { private set; get; } #endregion - public DefaultWebRemoteFileSystem() + public WebRemoteFileSystem() { } - public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + public virtual FSInitializeOperation InitializeAsync() { - var operation = new DWRFSInitializeOperation(this); + var operation = new WRFSInitializeOperation(this); return operation; } - public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) + public virtual FSRequestVersionOperation RequestVersionAsync(RequestVersionOptions options) { - var operation = new DWRFSLoadPackageManifestOperation(this, packageVersion, timeout); + var operation = new WRFSRequestVersionOperation(this, options.AppendTimeTicks, options.Timeout); return operation; } - public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout) + public virtual FSLoadManifestOperation LoadManifestAsync(LoadManifestOptions options) { - var operation = new DWRFSRequestPackageVersionOperation(this, appendTimeTicks, timeout); + var operation = new WRFSLoadManifestOperation(this, options.PackageVersion, options.Timeout); return operation; } - public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options) + public virtual FSClearCacheOperation ClearCacheAsync(ClearCacheOptions options) { - var operation = new FSClearCacheFilesCompleteOperation(); + var operation = new FSClearCacheCompleteOperation(); return operation; } - public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) + public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options) { throw new System.NotImplementedException(); } - public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) { - if (bundle.BundleType == (int)EBuildBundleType.AssetBundle) + PackageBundle bundle = options.Bundle; + if (bundle.BundleType == (int)EBundleType.AssetBundle) { - var operation = new DWRFSLoadAssetBundleOperation(this, bundle); + var operation = new WRFSLoadAssetBundleOperation(this, bundle); return operation; } else { - string error = $"{nameof(DefaultWebRemoteFileSystem)} not support load bundle type : {bundle.BundleType}"; + string error = $"{nameof(WebRemoteFileSystem)} not support load bundle type : {bundle.BundleType}"; var operation = new FSLoadBundleCompleteOperation(error); return operation; } @@ -126,17 +132,22 @@ namespace YooAsset { DisableUnityWebCache = Convert.ToBoolean(value); } + else if (name == FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME) + { + int convertValue = Convert.ToInt32(value); + DownloadWatchDogTimeout = Mathf.Clamp(convertValue, 0, int.MaxValue); + } else if (name == FileSystemParametersDefine.REMOTE_SERVICES) { RemoteServices = (IRemoteServices)value; } - else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES) + else if (name == FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY) { - DecryptionServices = (IWebDecryptionServices)value; + LoadAssetBundleFactory = (LoadWebAssetBundleOperationFactory)value; } - else if (name == FileSystemParametersDefine.MANIFEST_SERVICES) + else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES) { - ManifestServices = (IManifestRestoreServices)value; + ManifestRestoreServices = (IManifestRestoreServices)value; } else { @@ -150,6 +161,10 @@ namespace YooAsset // 创建默认的下载后台接口 if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); + + // 创建默认的 AssetBundle 加载工厂 + if (LoadAssetBundleFactory == null) + LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory; } public virtual void OnDestroy() { @@ -180,21 +195,24 @@ namespace YooAsset { return false; } - public virtual string GetBundleFilePath(PackageBundle bundle) { throw new System.NotImplementedException(); } - public virtual byte[] ReadBundleFileData(PackageBundle bundle) - { - throw new System.NotImplementedException(); - } - public virtual string ReadBundleFileText(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/DefaultWebRemoteFileSystem/DefaultWebRemoteFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/WebRemoteFileSystem.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebRemoteFileSystem/DefaultWebRemoteFileSystem.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/WebRemoteFileSystem.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSInitializeOperation.cs similarity index 87% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSInitializeOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSInitializeOperation.cs index 8d44a15f..272f11ef 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSInitializeOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSInitializeOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DWSFSInitializeOperation : FSInitializeFileSystemOperation + internal class WSFSInitializeOperation : FSInitializeOperation { private enum ESteps { @@ -10,12 +10,12 @@ namespace YooAsset Done, } - private readonly DefaultWebServerFileSystem _fileSystem; + private readonly WebServerFileSystem _fileSystem; private LoadWebServerCatalogFileOperation _loadCatalogFileOp; private ESteps _steps = ESteps.None; - public DWSFSInitializeOperation(DefaultWebServerFileSystem fileSystem) + public WSFSInitializeOperation(WebServerFileSystem fileSystem) { _fileSystem = fileSystem; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSInitializeOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSInitializeOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSInitializeOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadBundleOperation.cs similarity index 59% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSLoadBundleOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadBundleOperation.cs index be4b003b..b6812dd3 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadBundleOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DWSFSLoadAssetBundleOperation : FSLoadBundleOperation + internal class WSFSLoadAssetBundleOperation : FSLoadBundleOperation { private enum ESteps { @@ -10,13 +10,13 @@ namespace YooAsset Done, } - private readonly DefaultWebServerFileSystem _fileSystem; + private readonly WebServerFileSystem _fileSystem; private readonly PackageBundle _bundle; private LoadWebAssetBundleOperation _loadWebAssetBundleOp; private ESteps _steps = ESteps.None; - internal DWSFSLoadAssetBundleOperation(DefaultWebServerFileSystem fileSystem, PackageBundle bundle) + internal WSFSLoadAssetBundleOperation(WebServerFileSystem fileSystem, PackageBundle bundle) { _fileSystem = fileSystem; _bundle = bundle; @@ -35,22 +35,19 @@ namespace YooAsset if (_loadWebAssetBundleOp == null) { string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle); - string mainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath); - DownloadFileOptions options = new DownloadFileOptions(int.MaxValue); - options.SetURL(mainURL, mainURL); + string mainURL = DownloadSystemTools.ToLocalURL(fileLoadPath); - if (_bundle.Encrypted) - { - _loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(_bundle, options, _fileSystem.DecryptionServices, _fileSystem.DownloadBackend); - _loadWebAssetBundleOp.StartOperation(); - AddChildOperation(_loadWebAssetBundleOp); - } - else - { - _loadWebAssetBundleOp = new LoadWebNormalAssetBundleOperation(_bundle, options, _fileSystem.DisableUnityWebCache, _fileSystem.DownloadBackend); - _loadWebAssetBundleOp.StartOperation(); - AddChildOperation(_loadWebAssetBundleOp); - } + 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); } _loadWebAssetBundleOp.UpdateOperation(); @@ -62,17 +59,16 @@ namespace YooAsset if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeed) { - var assetBundle = _loadWebAssetBundleOp.Result; - if (assetBundle == null) + if (_loadWebAssetBundleOp.Result == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"{nameof(DWSFSLoadAssetBundleOperation)} loaded asset bundle is null !"; + Error = $"Loaded asset bundle object is null."; } else { _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, assetBundle, null); + Result = new AssetBundleResult(_fileSystem, _bundle, _loadWebAssetBundleOp.Result, null); Status = EOperationStatus.Succeed; } } @@ -90,8 +86,8 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "WebGL platform not support sync load method !"; - UnityEngine.Debug.LogError(Error); + Error = "WebGL platform not support sync load method."; + YooLogger.Error(Error); } } } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSLoadBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadManifestOperation.cs similarity index 91% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSLoadPackageManifestOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadManifestOperation.cs index ee1f8645..544f5351 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSLoadPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadManifestOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DWSFSLoadPackageManifestOperation : FSLoadPackageManifestOperation + internal class WSFSLoadManifestOperation : FSLoadManifestOperation { private enum ESteps { @@ -11,7 +11,7 @@ namespace YooAsset Done, } - private readonly DefaultWebServerFileSystem _fileSystem; + private readonly WebServerFileSystem _fileSystem; private readonly string _packageVersion; private readonly int _timeout; private RequestWebServerPackageHashOperation _requestWebPackageHashOp; @@ -19,7 +19,7 @@ namespace YooAsset private ESteps _steps = ESteps.None; - public DWSFSLoadPackageManifestOperation(DefaultWebServerFileSystem fileSystem, string packageVersion, int timeout) + public WSFSLoadManifestOperation(WebServerFileSystem fileSystem, string packageVersion, int timeout) { _fileSystem = fileSystem; _packageVersion = packageVersion; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSLoadPackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSRequestPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSRequestVersionOperation.cs similarity index 87% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSRequestPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSRequestVersionOperation.cs index 349a3aa6..5c6e87af 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSRequestPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSRequestVersionOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal class DWSFSRequestPackageVersionOperation : FSRequestPackageVersionOperation + internal class WSFSRequestVersionOperation : FSRequestVersionOperation { private enum ESteps { @@ -10,13 +10,13 @@ namespace YooAsset Done, } - private readonly DefaultWebServerFileSystem _fileSystem; + private readonly WebServerFileSystem _fileSystem; private readonly int _timeout; private RequestWebServerPackageVersionOperation _requestWebPackageVersionOp; private ESteps _steps = ESteps.None; - internal DWSFSRequestPackageVersionOperation(DefaultWebServerFileSystem fileSystem, int timeout) + internal WSFSRequestVersionOperation(WebServerFileSystem fileSystem, int timeout) { _fileSystem = fileSystem; _timeout = timeout; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSRequestVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/DWSFSRequestPackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSRequestVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/LoadWebServerCatalogFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/LoadWebServerCatalogFileOperation.cs similarity index 86% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/LoadWebServerCatalogFileOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/LoadWebServerCatalogFileOperation.cs index 786c5a49..356ff945 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/LoadWebServerCatalogFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/LoadWebServerCatalogFileOperation.cs @@ -12,12 +12,12 @@ namespace YooAsset Done, } - private readonly DefaultWebServerFileSystem _fileSystem; + private readonly WebServerFileSystem _fileSystem; private readonly int _timeout; private IDownloadBytesRequest _webDataRequestOp; private ESteps _steps = ESteps.None; - internal LoadWebServerCatalogFileOperation(DefaultWebServerFileSystem fileSystem, int timeout) + internal LoadWebServerCatalogFileOperation(WebServerFileSystem fileSystem, int timeout) { _fileSystem = fileSystem; _timeout = timeout; @@ -36,7 +36,7 @@ namespace YooAsset if (_webDataRequestOp == null) { string filePath = _fileSystem.GetCatalogBinaryFileLoadPath(); - string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + string url = DownloadSystemTools.ToLocalURL(filePath); var args = new DownloadDataRequestArgs(url, _timeout, 0); _webDataRequestOp = _fileSystem.DownloadBackend.CreateBytesRequest(args); _webDataRequestOp.SendRequest(); @@ -61,7 +61,7 @@ namespace YooAsset { try { - var catalog = CatalogTools.DeserializeFromBinary(_webDataRequestOp.Result); + var catalog = CatalogFileTools.DeserializeFromBinary(_webDataRequestOp.Result); if (catalog.PackageName != _fileSystem.PackageName) { _steps = ESteps.Done; @@ -72,7 +72,7 @@ namespace YooAsset foreach (var wrapper in catalog.Wrappers) { - var fileWrapper = new DefaultWebServerFileSystem.FileWrapper(wrapper.FileName); + var fileWrapper = new WebServerFileSystem.FileWrapper(wrapper.FileName); _fileSystem.RecordCatalogFile(wrapper.BundleGUID, fileWrapper); } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/LoadWebServerCatalogFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/LoadWebServerCatalogFileOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/LoadWebServerCatalogFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/LoadWebServerCatalogFileOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/LoadWebServerPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/LoadWebServerPackageManifestOperation.cs similarity index 87% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/LoadWebServerPackageManifestOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/LoadWebServerPackageManifestOperation.cs index a0165137..96deffe9 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/LoadWebServerPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/LoadWebServerPackageManifestOperation.cs @@ -12,7 +12,7 @@ namespace YooAsset Done, } - private readonly DefaultWebServerFileSystem _fileSystem; + private readonly WebServerFileSystem _fileSystem; private readonly string _packageVersion; private readonly string _packageHash; private readonly int _timeout; @@ -26,7 +26,7 @@ namespace YooAsset public PackageManifest Manifest { private set; get; } - internal LoadWebServerPackageManifestOperation(DefaultWebServerFileSystem fileSystem, string packageVersion, string packageHash, int timeout) + internal LoadWebServerPackageManifestOperation(WebServerFileSystem fileSystem, string packageVersion, string packageHash, int timeout) { _fileSystem = fileSystem; _packageVersion = packageVersion; @@ -47,7 +47,7 @@ namespace YooAsset if (_webDataRequestOp == null) { string filePath = _fileSystem.GetWebPackageManifestFilePath(_packageVersion); - string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + string url = DownloadSystemTools.ToLocalURL(filePath); var args = new DownloadDataRequestArgs(url, _timeout, 0); _webDataRequestOp = _fileSystem.DownloadBackend.CreateBytesRequest(args); _webDataRequestOp.SendRequest(); @@ -70,7 +70,7 @@ namespace YooAsset if (_steps == ESteps.VerifyFileData) { - if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash)) + if (PackageManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash)) { _steps = ESteps.LoadManifest; } @@ -78,7 +78,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Failed to verify web server package manifest file!"; + Error = "Failed to verify web server package manifest file."; } } @@ -86,7 +86,7 @@ namespace YooAsset { if (_deserializer == null) { - _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _webDataRequestOp.Result); + _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestRestoreServices, _webDataRequestOp.Result); _deserializer.StartOperation(); AddChildOperation(_deserializer); } @@ -110,7 +110,7 @@ namespace YooAsset } } } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { return $"PackageVersion : {_packageVersion} PackageHash : {_packageHash}"; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/LoadWebServerPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/LoadWebServerPackageManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/LoadWebServerPackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/LoadWebServerPackageManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/RequestWebServerPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/RequestWebServerPackageHashOperation.cs similarity index 89% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/RequestWebServerPackageHashOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/RequestWebServerPackageHashOperation.cs index 4486fe41..a53f6cd6 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/RequestWebServerPackageHashOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/RequestWebServerPackageHashOperation.cs @@ -10,7 +10,7 @@ namespace YooAsset Done, } - private readonly DefaultWebServerFileSystem _fileSystem; + private readonly WebServerFileSystem _fileSystem; private readonly string _packageVersion; private readonly int _timeout; private IDownloadTextRequest _webTextRequestOp; @@ -22,7 +22,7 @@ namespace YooAsset public string PackageHash { private set; get; } - public RequestWebServerPackageHashOperation(DefaultWebServerFileSystem fileSystem, string packageVersion, int timeout) + public RequestWebServerPackageHashOperation(WebServerFileSystem fileSystem, string packageVersion, int timeout) { _fileSystem = fileSystem; _packageVersion = packageVersion; @@ -42,7 +42,7 @@ namespace YooAsset if (_webTextRequestOp == null) { string filePath = _fileSystem.GetWebPackageHashFilePath(_packageVersion); - string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + string url = DownloadSystemTools.ToLocalURL(filePath); var args = new DownloadDataRequestArgs(url, _timeout, 0); _webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args); _webTextRequestOp.SendRequest(); @@ -59,7 +59,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Web server package hash file content is empty !"; + Error = $"Web server package hash file content is empty."; } else { diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/RequestWebServerPackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/RequestWebServerPackageHashOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/RequestWebServerPackageHashOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/RequestWebServerPackageHashOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/RequestWebServerPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/RequestWebServerPackageVersionOperation.cs similarity index 89% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/RequestWebServerPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/RequestWebServerPackageVersionOperation.cs index b5b031e3..89d9a68d 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/RequestWebServerPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/RequestWebServerPackageVersionOperation.cs @@ -10,7 +10,7 @@ namespace YooAsset Done, } - private readonly DefaultWebServerFileSystem _fileSystem; + private readonly WebServerFileSystem _fileSystem; private readonly int _timeout; private IDownloadTextRequest _webTextRequestOp; private ESteps _steps = ESteps.None; @@ -21,7 +21,7 @@ namespace YooAsset public string PackageVersion { private set; get; } - internal RequestWebServerPackageVersionOperation(DefaultWebServerFileSystem fileSystem, int timeout) + internal RequestWebServerPackageVersionOperation(WebServerFileSystem fileSystem, int timeout) { _fileSystem = fileSystem; _timeout = timeout; @@ -40,7 +40,7 @@ namespace YooAsset if (_webTextRequestOp == null) { string filePath = _fileSystem.GetWebPackageVersionFilePath(); - string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + string url = DownloadSystemTools.ToLocalURL(filePath); var args = new DownloadDataRequestArgs(url, _timeout, 0); _webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args); _webTextRequestOp.SendRequest(); @@ -56,7 +56,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Web server package version file content is empty !"; + Error = $"Web server package version file content is empty."; } else { diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/RequestWebServerPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/RequestWebServerPackageVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/Operation/internal/RequestWebServerPackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/internal/RequestWebServerPackageVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/DefaultWebServerFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/WebServerFileSystem.cs similarity index 68% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/DefaultWebServerFileSystem.cs rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/WebServerFileSystem.cs index 8b0af887..50381076 100644 --- a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/DefaultWebServerFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/WebServerFileSystem.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Collections.Generic; using UnityEngine; @@ -8,7 +8,7 @@ namespace YooAsset /// /// Web文件系统 /// - internal class DefaultWebServerFileSystem : IFileSystem + internal class WebServerFileSystem : IFileSystem { public class FileWrapper { @@ -68,54 +68,60 @@ namespace YooAsset public bool DisableUnityWebCache { private set; get; } = false; /// - /// 自定义参数:解密服务接口的实例类 + /// 自定义参数:下载任务的看门狗机制超时时间 /// - public IWebDecryptionServices DecryptionServices { private set; get; } + public int DownloadWatchDogTimeout { private set; get; } = 0; + + /// + /// 自定义参数:加载 AssetBundle 的工厂委托 + /// + public LoadWebAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; } /// /// 自定义参数:资源清单服务类 /// - public IManifestRestoreServices ManifestServices { private set; get; } + public IManifestRestoreServices ManifestRestoreServices { private set; get; } #endregion - public DefaultWebServerFileSystem() + public WebServerFileSystem() { } - public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + public virtual FSInitializeOperation InitializeAsync() { - var operation = new DWSFSInitializeOperation(this); + var operation = new WSFSInitializeOperation(this); return operation; } - public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) + public virtual FSRequestVersionOperation RequestVersionAsync(RequestVersionOptions options) { - var operation = new DWSFSLoadPackageManifestOperation(this, packageVersion, timeout); + var operation = new WSFSRequestVersionOperation(this, options.Timeout); return operation; } - public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout) + public virtual FSLoadManifestOperation LoadManifestAsync(LoadManifestOptions options) { - var operation = new DWSFSRequestPackageVersionOperation(this, timeout); + var operation = new WSFSLoadManifestOperation(this, options.PackageVersion, options.Timeout); return operation; } - public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options) + public virtual FSClearCacheOperation ClearCacheAsync(ClearCacheOptions options) { - var operation = new FSClearCacheFilesCompleteOperation(); + var operation = new FSClearCacheCompleteOperation(); return operation; } - public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) + public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options) { throw new System.NotImplementedException(); } - public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options) { - if (bundle.BundleType == (int)EBuildBundleType.AssetBundle) + PackageBundle bundle = options.Bundle; + if (bundle.BundleType == (int)EBundleType.AssetBundle) { - var operation = new DWSFSLoadAssetBundleOperation(this, bundle); + var operation = new WSFSLoadAssetBundleOperation(this, bundle); return operation; } else { - string error = $"{nameof(DefaultWebServerFileSystem)} not support load bundle type : {bundle.BundleType}"; + string error = $"{nameof(WebServerFileSystem)} not support load bundle type : {bundle.BundleType}"; var operation = new FSLoadBundleCompleteOperation(error); return operation; } @@ -135,13 +141,18 @@ namespace YooAsset { DisableUnityWebCache = Convert.ToBoolean(value); } - else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES) + else if (name == FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME) { - DecryptionServices = (IWebDecryptionServices)value; + int convertValue = Convert.ToInt32(value); + DownloadWatchDogTimeout = Mathf.Clamp(convertValue, 0, int.MaxValue); } - else if (name == FileSystemParametersDefine.MANIFEST_SERVICES) + else if (name == FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY) { - ManifestServices = (IManifestRestoreServices)value; + LoadAssetBundleFactory = (LoadWebAssetBundleOperationFactory)value; + } + else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES) + { + ManifestRestoreServices = (IManifestRestoreServices)value; } else { @@ -160,6 +171,10 @@ namespace YooAsset // 创建默认的下载后台接口 if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); + + // 创建默认的 AssetBundle 加载工厂 + if (LoadAssetBundleFactory == null) + LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory; } public virtual void OnDestroy() { @@ -190,21 +205,24 @@ namespace YooAsset { return false; } - public virtual string GetBundleFilePath(PackageBundle bundle) { throw new System.NotImplementedException(); } - public virtual byte[] ReadBundleFileData(PackageBundle bundle) - { - throw new System.NotImplementedException(); - } - public virtual string ReadBundleFileText(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(); @@ -236,7 +254,7 @@ namespace YooAsset } public string GetCatalogBinaryFileLoadPath() { - return PathUtility.Combine(_webPackageRoot, DefaultBuildinFileSystemDefine.BuildinCatalogBinaryFileName); + return PathUtility.Combine(_webPackageRoot, BuiltinFileSystemConstants.BuiltinCatalogBinaryFileName); } /// @@ -246,7 +264,7 @@ namespace YooAsset { if (_wrappers.ContainsKey(bundleGUID)) { - YooLogger.Error($"{nameof(DefaultWebServerFileSystem)} has element : {bundleGUID}"); + YooLogger.Error($"{nameof(WebServerFileSystem)} has element : {bundleGUID}"); return false; } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/DefaultWebServerFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/WebServerFileSystem.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/DefaultWebServerFileSystem/DefaultWebServerFileSystem.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/WebServerFileSystem.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs index fb55c52c..bf5908b5 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs @@ -22,32 +22,32 @@ namespace YooAsset /// /// 初始化文件系统 /// - FSInitializeFileSystemOperation InitializeFileSystemAsync(); - - /// - /// 加载包裹清单 - /// - FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout); + FSInitializeOperation InitializeAsync(); /// /// 查询包裹版本 /// - FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout); + FSRequestVersionOperation RequestVersionAsync(RequestVersionOptions options); + + /// + /// 加载包裹清单 + /// + FSLoadManifestOperation LoadManifestAsync(LoadManifestOptions options); /// /// 清理缓存文件 /// - FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options); + FSClearCacheOperation ClearCacheAsync(ClearCacheOptions options); /// /// 下载Bundle文件 /// - FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options); - + FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options); + /// /// 加载Bundle文件 /// - FSLoadBundleOperation LoadBundleFile(PackageBundle bundle); + FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options); /// @@ -91,20 +91,9 @@ namespace YooAsset /// bool NeedImport(PackageBundle bundle); - /// - /// 获取Bundle文件路径 + /// 获取资源包本地路径 /// string GetBundleFilePath(PackageBundle bundle); - - /// - /// 读取Bundle文件的二进制数据 - /// - byte[] ReadBundleFileData(PackageBundle bundle); - - /// - /// 读取Bundle文件的文本数据 - /// - string ReadBundleFileText(PackageBundle bundle); } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSClearCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/FSClearCacheOperation.cs similarity index 51% rename from Assets/YooAsset/Runtime/FileSystem/Operation/FSClearCacheFilesOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Operation/FSClearCacheOperation.cs index d78f4e46..72d91f4b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Operation/FSClearCacheFilesOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/FSClearCacheOperation.cs @@ -1,32 +1,19 @@  namespace YooAsset { - internal class ClearCacheFilesOptions - { - /// - /// 清理模式 - /// - public string ClearMode; - - /// - /// 附加参数 - /// - public object ClearParam; - } - - internal abstract class FSClearCacheFilesOperation : AsyncOperationBase + internal abstract class FSClearCacheOperation : AsyncOperationBase { } - internal sealed class FSClearCacheFilesCompleteOperation : FSClearCacheFilesOperation + internal sealed class FSClearCacheCompleteOperation : FSClearCacheOperation { private readonly string _error; - internal FSClearCacheFilesCompleteOperation() + internal FSClearCacheCompleteOperation() { _error = null; } - internal FSClearCacheFilesCompleteOperation(string error) + internal FSClearCacheCompleteOperation(string error) { _error = error; } diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSClearCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/FSClearCacheOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operation/FSClearCacheFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Operation/FSClearCacheOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOperation.cs index 102fc9e5..f4f9693a 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOperation.cs @@ -1,54 +1,6 @@  namespace YooAsset { - internal class DownloadFileOptions - { - /// - /// 失败后重试次数 - /// - public readonly int FailedTryAgain; - - /// - /// 主资源地址 - /// - public string MainURL { private set; get; } - - /// - /// 备用资源地址 - /// - public string FallbackURL { private set; get; } - - /// - /// 拷贝的本地文件路径 - /// - public string ImportFilePath { set; get; } - - public DownloadFileOptions(int failedTryAgain) - { - FailedTryAgain = failedTryAgain; - } - - /// - /// 设置下载地址 - /// - public void SetURL(string mainURL, string fallbackURL) - { - MainURL = mainURL; - FallbackURL = fallbackURL; - } - - /// - /// 是否有效 - /// - public bool IsValid() - { - if (string.IsNullOrEmpty(MainURL) || string.IsNullOrEmpty(FallbackURL)) - return false; - - return true; - } - } - internal abstract class FSDownloadFileOperation : AsyncOperationBase { public PackageBundle Bundle { private set; get; } diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOptions.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOptions.cs new file mode 100644 index 00000000..af3e5658 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOptions.cs @@ -0,0 +1,60 @@ + +namespace YooAsset +{ + internal struct DownloadFileOptions + { + /// + /// 资源包 + /// + public readonly PackageBundle Bundle; + + /// + /// 失败后重试次数 + /// + public readonly int FailedTryAgain; + + /// + /// 主资源地址 + /// + public string MainURL { private set; get; } + + /// + /// 备用资源地址 + /// + public string FallbackURL { private set; get; } + + /// + /// 拷贝的本地文件路径 + /// + public string ImportFilePath { set; get; } + + public DownloadFileOptions(PackageBundle bundle, int failedTryAgain) + { + Bundle = bundle; + FailedTryAgain = failedTryAgain; + MainURL = null; + FallbackURL = null; + ImportFilePath = null; + } + + /// + /// 设置下载地址 + /// + public void SetURL(string mainURL, string fallbackURL) + { + MainURL = mainURL; + FallbackURL = fallbackURL; + } + + /// + /// 是否有效 + /// + public bool IsValid() + { + if (string.IsNullOrEmpty(MainURL) || string.IsNullOrEmpty(FallbackURL)) + return false; + + return true; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOptions.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOptions.cs.meta new file mode 100644 index 00000000..a9da4eeb --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae6a979ad693ddf488c7a0f387c6ea76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSInitializeFileSystemOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/FSInitializeFileSystemOperation.cs deleted file mode 100644 index d9a5666c..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/Operation/FSInitializeFileSystemOperation.cs +++ /dev/null @@ -1,7 +0,0 @@ - -namespace YooAsset -{ - internal abstract class FSInitializeFileSystemOperation : AsyncOperationBase - { - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/FSInitializeOperation.cs new file mode 100644 index 00000000..dadf17d2 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/FSInitializeOperation.cs @@ -0,0 +1,7 @@ + +namespace YooAsset +{ + internal abstract class FSInitializeOperation : AsyncOperationBase + { + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSInitializeFileSystemOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/FSInitializeOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operation/FSInitializeFileSystemOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Operation/FSInitializeOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOperation.cs index 19c6d3ce..da57ee96 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOperation.cs @@ -11,12 +11,12 @@ namespace YooAsset /// /// 下载进度 /// - public float DownloadProgress { protected set; get; } = 0; + public float DownloadProgress { protected set; get; } /// /// 下载大小 /// - public long DownloadedBytes { protected set; get; } = 0; + public long DownloadedBytes { protected set; get; } /// /// 终止下载文件 diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOptions.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOptions.cs new file mode 100644 index 00000000..ec3dcf0c --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOptions.cs @@ -0,0 +1,16 @@ + +namespace YooAsset +{ + internal struct LoadBundleOptions + { + /// + /// 资源包 + /// + public readonly PackageBundle Bundle; + + public LoadBundleOptions(PackageBundle bundle) + { + Bundle = bundle; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOptions.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOptions.cs.meta new file mode 100644 index 00000000..0b238221 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d4cf0ce3cf4c794fa2d40665d5f3147 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadManifestOperation.cs similarity index 67% rename from Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadPackageManifestOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadManifestOperation.cs index 72a99692..b69be2e4 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadManifestOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal abstract class FSLoadPackageManifestOperation : AsyncOperationBase + internal abstract class FSLoadManifestOperation : AsyncOperationBase { /// /// 资源清单 diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadPackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSRequestPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/FSRequestVersionOperation.cs similarity index 66% rename from Assets/YooAsset/Runtime/FileSystem/Operation/FSRequestPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/Operation/FSRequestVersionOperation.cs index a0cc5e40..0495532f 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Operation/FSRequestPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/FSRequestVersionOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - internal abstract class FSRequestPackageVersionOperation : AsyncOperationBase + internal abstract class FSRequestVersionOperation : AsyncOperationBase { /// /// 资源版本 diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/FSRequestVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/FileSystem/Operation/FSRequestPackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/Operation/FSRequestVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/README.md b/Assets/YooAsset/Runtime/FileSystem/README.md deleted file mode 100644 index 9cd92a73..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/README.md +++ /dev/null @@ -1,475 +0,0 @@ -# FileSystem 文件系统模块 - -## 模块概述 - -FileSystem 是 YooAsset 资源管理系统的**文件访问抽象层**,负责统一管理不同来源的资源文件访问。该模块采用策略模式设计,通过 `IFileSystem` 接口抽象不同的文件存储策略,支持编辑器模拟、内置资源、缓存资源、WebGL 等多种场景。 - -### 核心职责 - -- 统一的文件系统接口抽象 -- 资源包文件的加载和管理 -- 资源清单的请求和加载 -- 缓存文件的验证和清理 -- 资源下载的调度和管理 - ---- - -## 设计目标 - -| 目标 | 说明 | -|------|------| -| **统一抽象** | 通过 IFileSystem 接口统一不同来源的文件访问 | -| **策略模式** | 可插拔的文件系统实现,支持自定义扩展 | -| **多场景支持** | 编辑器、单机、联机、WebGL 等多种运行模式 | -| **灵活配置** | 通过参数系统支持丰富的自定义配置 | - ---- - -## 架构概念 - -### 系统架构 - -``` -┌─────────────────────────────────────────────────────────┐ -│ ResourcePackage │ -│ (资源包管理) │ -└─────────────────────────┬───────────────────────────────┘ - │ -┌─────────────────────────▼───────────────────────────────┐ -│ PlayModeImpl │ -│ (运行模式实现) │ -│ 管理多个 IFileSystem,按优先级查询 │ -└─────────────────────────┬───────────────────────────────┘ - │ -┌─────────────────────────▼───────────────────────────────┐ -│ IFileSystem │ -│ (文件系统接口) │ -├─────────────────────────────────────────────────────────┤ -│ DefaultEditorFileSystem │ 编辑器模拟文件系统 │ -│ DefaultBuildinFileSystem │ 内置资源文件系统 │ -│ DefaultCacheFileSystem │ 缓存资源文件系统 │ -│ DefaultUnpackFileSystem │ 解压资源文件系统 │ -│ DefaultWebServerFileSystem │ WebGL 服务器文件系统 │ -│ DefaultWebRemoteFileSystem │ WebGL 远程文件系统 │ -└─────────────────────────────────────────────────────────┘ - │ -┌─────────────────────────▼───────────────────────────────┐ -│ BundleResult │ -│ (资源包加载结果) │ -├─────────────────────────────────────────────────────────┤ -│ AssetBundleResult │ Unity AssetBundle 加载结果 │ -│ RawBundleResult │ 原生文件加载结果 │ -│ VirtualBundleResult│ 虚拟资源包结果(编辑器模拟) │ -└─────────────────────────────────────────────────────────┘ -``` - -### 核心组件 - -- **IFileSystem**: 文件系统核心接口,定义所有文件操作的契约 -- **FileSystemParameters**: 文件系统参数配置,支持自定义参数注入 -- **BundleResult**: 资源包加载结果抽象,封装不同类型的加载结果 -- **FSOperation**: 文件系统操作基类,定义异步操作的抽象 - ---- - -## 文件结构 - -``` -FileSystem/ -├── Interface/ # 接口定义 -│ └── IFileSystem.cs # 文件系统核心接口 -│ -├── Operation/ # 操作基类定义 -│ ├── FSInitializeFileSystemOperation.cs # 初始化操作 -│ ├── FSRequestPackageVersionOperation.cs # 请求版本操作 -│ ├── FSLoadPackageManifestOperation.cs # 加载清单操作 -│ ├── FSLoadBundleOperation.cs # 加载资源包操作 -│ ├── FSDownloadFileOperation.cs # 下载文件操作 -│ ├── FSClearCacheFilesOperation.cs # 清理缓存操作 -│ ├── FSLoadAssetOperation.cs # 加载资源操作 -│ ├── FSLoadAllAssetsOperation.cs # 加载所有资源操作 -│ ├── FSLoadSubAssetsOperation.cs # 加载子资源操作 -│ └── FSLoadSceneOperation.cs # 加载场景操作 -│ -├── BundleResult/ # 资源包加载结果 -│ ├── BundleResult.cs # 结果基类 -│ ├── AssetBundleResult/ # AssetBundle 结果实现 -│ ├── RawBundleResult/ # 原生文件结果实现 -│ └── VirtualBundleResult/ # 虚拟资源包结果实现 -│ -├── WebGame/ # WebGL 相关操作 -│ └── Operation/ # WebGL 专用操作类 -│ -├── FileSystemParameters.cs # 文件系统参数 -├── FileSystemParametersDefine.cs # 参数名称常量定义 -├── FileVerifyHelper.cs # 文件校验辅助类 -├── EFileVerifyLevel.cs # 文件校验等级枚举 -├── EFileVerifyResult.cs # 文件校验结果枚举 -└── EFileClearMode.cs # 文件清理模式枚举 -``` - ---- - -## 核心接口 - -### IFileSystem(文件系统接口) - -定义文件系统的核心契约,所有文件系统实现都必须实现此接口。 - -```csharp -internal interface IFileSystem -{ - // 基本属性 - string PackageName { get; } // 包裹名称 - string FileRoot { get; } // 文件根目录 - int FileCount { get; } // 文件数量 - - // 生命周期 - void OnCreate(string packageName, string packageRoot); - void OnDestroy(); - void SetParameter(string name, object value); - - // 异步操作 - FSInitializeFileSystemOperation InitializeFileSystemAsync(); - FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout); - FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout); - FSLoadBundleOperation LoadBundleFile(PackageBundle bundle); - FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options); - FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options); - - // 文件查询 - bool Belong(PackageBundle bundle); // 查询文件归属 - bool Exists(PackageBundle bundle); // 查询文件是否存在 - bool NeedDownload(PackageBundle bundle);// 是否需要下载 - bool NeedUnpack(PackageBundle bundle); // 是否需要解压 - bool NeedImport(PackageBundle bundle); // 是否需要导入 - - // 文件访问 - string GetBundleFilePath(PackageBundle bundle); - byte[] ReadBundleFileData(PackageBundle bundle); - string ReadBundleFileText(PackageBundle bundle); -} -``` - ---- - -## 操作类定义 - -### 文件系统操作基类 - -所有文件系统操作都继承自 `AsyncOperationBase`,提供异步执行能力。 - -| 操作类 | 说明 | 输出属性 | -|--------|------|----------| -| `FSInitializeFileSystemOperation` | 初始化文件系统 | - | -| `FSRequestPackageVersionOperation` | 请求包裹版本 | `PackageVersion` | -| `FSLoadPackageManifestOperation` | 加载资源清单 | `Manifest` | -| `FSLoadBundleOperation` | 加载资源包文件 | `Result`, `DownloadProgress`, `DownloadedBytes` | -| `FSDownloadFileOperation` | 下载文件 | `DownloadedBytes`, `DownloadProgress` | -| `FSClearCacheFilesOperation` | 清理缓存文件 | - | - -### 资源加载操作基类 - -| 操作类 | 说明 | 输出属性 | -|--------|------|----------| -| `FSLoadAssetOperation` | 加载单个资源 | `Result` (Object) | -| `FSLoadAllAssetsOperation` | 加载所有资源 | `Result` (Object[]) | -| `FSLoadSubAssetsOperation` | 加载子资源 | `Result` (Object[]) | -| `FSLoadSceneOperation` | 加载场景 | `Result` (Scene) | - ---- - -## BundleResult 资源包结果 - -### 基类定义 - -```csharp -internal abstract class BundleResult -{ - // 资源包管理 - public abstract void UnloadBundleFile(); - public abstract string GetBundleFilePath(); - public abstract byte[] ReadBundleFileData(); - public abstract string ReadBundleFileText(); - - // 资源加载 - public abstract FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo); - public abstract FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo); - public abstract FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo); - public abstract FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad); -} -``` - -### 实现类型 - -| 类型 | 说明 | 使用场景 | -|------|------|----------| -| `AssetBundleResult` | Unity AssetBundle 结果 | 正常构建的 AssetBundle 文件 | -| `RawBundleResult` | 原生文件结果 | 原生文件(非 AssetBundle) | -| `VirtualBundleResult` | 虚拟资源包结果 | 编辑器模拟模式 | - ---- - -## 枚举定义 - -### EFileVerifyLevel(文件校验等级) - -```csharp -public enum EFileVerifyLevel -{ - Low = 1, // 仅验证文件存在 - Middle = 2, // 验证文件大小 - High = 3 // 验证文件大小和 CRC -} -``` - -### EFileVerifyResult(文件校验结果) - -```csharp -internal enum EFileVerifyResult -{ - Exception = -7, // 验证异常 - CacheNotFound = -6, // 未找到缓存信息 - InfoFileNotExisted = -5, // 信息文件不存在 - DataFileNotExisted = -4, // 数据文件不存在 - FileNotComplete = -3, // 文件内容不足 - FileOverflow = -2, // 文件内容溢出 - FileCrcError = -1, // 文件 CRC 不匹配 - None = 0, // 默认状态 - Succeed = 1 // 验证成功 -} -``` - -### EFileClearMode(文件清理模式) - -```csharp -public enum EFileClearMode -{ - ClearAllBundleFiles, // 清理所有资源文件 - ClearUnusedBundleFiles, // 清理未使用的资源文件 - ClearBundleFilesByLocations,// 按地址清理资源文件 - ClearBundleFilesByTags, // 按标签清理资源文件 - ClearAllManifestFiles, // 清理所有清单文件 - ClearUnusedManifestFiles // 清理未使用的清单文件 -} -``` - ---- - -## 参数系统 - -### FileSystemParameters(文件系统参数) - -用于创建和配置文件系统实例。 - -```csharp -public class FileSystemParameters -{ - public string FileSystemClass { get; } // 文件系统类名 - public string PackageRoot { get; } // 包裹根目录 - - public void AddParameter(string name, object value); -} -``` - -### 参数名称常量 - -```csharp -public class FileSystemParametersDefine -{ - // 文件校验 - public const string FILE_VERIFY_LEVEL = "FILE_VERIFY_LEVEL"; - public const string FILE_VERIFY_MAX_CONCURRENCY = "FILE_VERIFY_MAX_CONCURRENCY"; - - // 下载配置 - public const string DOWNLOAD_MAX_CONCURRENCY = "DOWNLOAD_MAX_CONCURRENCY"; - public const string DOWNLOAD_MAX_REQUEST_PER_FRAME = "DOWNLOAD_MAX_REQUEST_PER_FRAME"; - public const string DOWNLOAD_WATCH_DOG_TIME = "DOWNLOAD_WATCH_DOG_TIME"; - public const string RESUME_DOWNLOAD_MINMUM_SIZE = "RESUME_DOWNLOAD_MINMUM_SIZE"; - public const string RESUME_DOWNLOAD_RESPONSE_CODES = "RESUME_DOWNLOAD_RESPONSE_CODES"; - - // 服务接口 - public const string REMOTE_SERVICES = "REMOTE_SERVICES"; - public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES"; - public const string MANIFEST_SERVICES = "MANIFEST_SERVICES"; - public const string COPY_LOCAL_FILE_SERVICES = "COPY_LOCAL_FILE_SERVICES"; - - // 功能开关 - public const string DISABLE_CATALOG_FILE = "DISABLE_CATALOG_FILE"; - public const string DISABLE_UNITY_WEB_CACHE = "DISABLE_UNITY_WEB_CACHE"; - public const string DISABLE_ONDEMAND_DOWNLOAD = "DISABLE_ONDEMAND_DOWNLOAD"; - public const string APPEND_FILE_EXTENSION = "APPEND_FILE_EXTENSION"; - - // 模拟模式 - public const string VIRTUAL_WEBGL_MODE = "VIRTUAL_WEBGL_MODE"; - public const string VIRTUAL_DOWNLOAD_MODE = "VIRTUAL_DOWNLOAD_MODE"; - public const string VIRTUAL_DOWNLOAD_SPEED = "VIRTUAL_DOWNLOAD_SPEED"; - public const string ASYNC_SIMULATE_MIN_FRAME = "ASYNC_SIMULATE_MIN_FRAME"; - public const string ASYNC_SIMULATE_MAX_FRAME = "ASYNC_SIMULATE_MAX_FRAME"; - - // 其他 - public const string INSTALL_CLEAR_MODE = "INSTALL_CLEAR_MODE"; - public const string COPY_BUILDIN_PACKAGE_MANIFEST = "COPY_BUILDIN_PACKAGE_MANIFEST"; - public const string UNPACK_FILE_SYSTEM_ROOT = "UNPACK_FILE_SYSTEM_ROOT"; -} -``` - ---- - -## 使用示例 - -### 创建文件系统参数 - -```csharp -// 编辑器文件系统 -var editorParams = FileSystemParameters.CreateDefaultEditorFileSystemParameters( - packageRoot: "Assets/GameRes/Bundles" -); - -// 内置文件系统 -var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters( - decryptionServices: new MyDecryptionServices() -); - -// 缓存文件系统 -var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters( - remoteServices: new MyRemoteServices(), - decryptionServices: new MyDecryptionServices() -); - -// WebGL 服务器文件系统 -var webServerParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters( - disableUnityWebCache: true -); - -// WebGL 远程文件系统 -var webRemoteParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters( - remoteServices: new MyRemoteServices(), - disableUnityWebCache: true -); -``` - -### 添加自定义参数 - -```csharp -var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices); - -// 设置 UnityWebRequest 创建委托(用于证书/代理/自定义 Header 等) -cacheParams.AddParameter(FileSystemParametersDefine.UNITY_WEB_REQUEST_CREATOR, (UnityWebRequestCreator)((url, method) => -{ - var request = new UnityEngine.Networking.UnityWebRequest(url, method); - // 自定义配置... - return request; -})); - -// 设置自定义下载后端(若设置则不再创建默认 UnityWebRequestBackend) -// cacheParams.AddParameter(FileSystemParametersDefine.DOWNLOAD_BACKEND, myDownloadBackend); - -// 设置文件校验级别 -cacheParams.AddParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, EFileVerifyLevel.High); - -// 设置下载并发数 -cacheParams.AddParameter(FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY, 16); - -// 设置看门狗时间 -cacheParams.AddParameter(FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME, 30); -``` - ---- - -## 文件系统实现 - -| 文件系统 | 说明 | 适用场景 | -|----------|------|----------| -| `DefaultEditorFileSystem` | 编辑器模拟文件系统 | 编辑器开发,快速迭代 | -| `DefaultBuildinFileSystem` | 内置资源文件系统 | StreamingAssets 内置资源 | -| `DefaultCacheFileSystem` | 缓存资源文件系统 | 下载并缓存的远程资源 | -| `DefaultUnpackFileSystem` | 解压资源文件系统 | 从内置解压到沙盒的资源 | -| `DefaultWebServerFileSystem` | WebGL 服务器文件系统 | WebGL 本地服务器资源 | -| `DefaultWebRemoteFileSystem` | WebGL 远程文件系统 | WebGL 远程 CDN 资源 | - ---- - -## 设计模式 - -### 策略模式 - -通过 `IFileSystem` 接口实现可插拔的文件系统: - -``` -IFileSystem (接口) - │ - ├── DefaultEditorFileSystem - ├── DefaultBuildinFileSystem - ├── DefaultCacheFileSystem - │ └── DefaultUnpackFileSystem (继承) - ├── DefaultWebServerFileSystem - └── DefaultWebRemoteFileSystem -``` - -### 工厂模式 - -`FileSystemParameters` 通过反射创建文件系统实例: - -```csharp -internal IFileSystem CreateFileSystem(string packageName) -{ - Type classType = Type.GetType(FileSystemClass); - var instance = (IFileSystem)Activator.CreateInstance(classType, true); - - foreach (var param in CreateParameters) - instance.SetParameter(param.Key, param.Value); - - instance.OnCreate(packageName, PackageRoot); - return instance; -} -``` - -### 模板方法模式 - -`BundleResult` 定义资源加载的算法骨架,子类实现具体加载逻辑: - -``` -BundleResult (抽象基类) - │ - ├── AssetBundleResult → AssetBundle.LoadAssetAsync - ├── RawBundleResult → 直接读取文件 - └── VirtualBundleResult → AssetDatabase.LoadAssetAtPath -``` - ---- - -## 类继承关系 - -``` -AsyncOperationBase - │ - ├── FSInitializeFileSystemOperation - ├── FSRequestPackageVersionOperation - ├── FSLoadPackageManifestOperation - ├── FSLoadBundleOperation - │ └── FSLoadBundleCompleteOperation - ├── FSDownloadFileOperation - ├── FSClearCacheFilesOperation - │ └── FSClearCacheFilesCompleteOperation - ├── FSLoadAssetOperation - ├── FSLoadAllAssetsOperation - ├── FSLoadSubAssetsOperation - └── FSLoadSceneOperation - -BundleResult - │ - ├── AssetBundleResult - ├── RawBundleResult - └── VirtualBundleResult -``` - ---- - -## 注意事项 - -1. **文件系统选择**:根据运行模式选择合适的文件系统组合 -2. **参数配置**:合理配置校验等级和并发数,平衡性能和安全性 -3. **自定义扩展**:可通过实现 `IFileSystem` 接口创建自定义文件系统 -4. **WebGL 限制**:WebGL 平台不支持持久化缓存,需使用专用文件系统 -5. **解密服务**:加密资源需要提供对应的解密服务实现 diff --git a/Assets/YooAsset/Runtime/FileSystem/README.md.meta b/Assets/YooAsset/Runtime/FileSystem/README.md.meta deleted file mode 100644 index e8b64503..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/README.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 3775825eb24ba6c46b557a3c96a09397 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebAssetBundleOperation.cs deleted file mode 100644 index 5662cc2b..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebAssetBundleOperation.cs +++ /dev/null @@ -1,22 +0,0 @@ -using UnityEngine; - -namespace YooAsset -{ - internal abstract class LoadWebAssetBundleOperation : AsyncOperationBase - { - /// - /// AssetBundle对象 - /// - public AssetBundle Result; - - /// - /// 下载进度 - /// - public float DownloadProgress { protected set; get; } = 0; - - /// - /// 下载大小 - /// - public long DownloadedBytes { protected set; get; } = 0; - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebEncryptAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebEncryptAssetBundleOperation.cs deleted file mode 100644 index 36cf9ef7..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebEncryptAssetBundleOperation.cs +++ /dev/null @@ -1,148 +0,0 @@ -using UnityEngine; - -namespace YooAsset -{ - internal class LoadWebEncryptAssetBundleOperation : LoadWebAssetBundleOperation - { - protected enum ESteps - { - None, - CreateRequest, - CheckRequest, - TryAgain, - Done, - } - - private readonly PackageBundle _bundle; - private readonly DownloadFileOptions _options; - private readonly IWebDecryptionServices _decryptionServices; - private readonly IDownloadBackend _downloadBackend; - private IDownloadBytesRequest _unityWebDataRequestOp; - - private int _requestCount = 0; - private float _tryAgainTimer = 0; - private int _failedTryAgain; - private ESteps _steps = ESteps.None; - - internal LoadWebEncryptAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options, IWebDecryptionServices decryptionServices, IDownloadBackend downloadBackend) - { - _bundle = bundle; - _options = options; - _failedTryAgain = options.FailedTryAgain; - _decryptionServices = decryptionServices; - _downloadBackend = downloadBackend; - } - internal override void InternalStart() - { - _steps = ESteps.CreateRequest; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - // 创建下载器 - if (_steps == ESteps.CreateRequest) - { - if (_decryptionServices == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"The {nameof(IWebDecryptionServices)} is null !"; - YooLogger.Error(Error); - return; - } - - string url = GetRequestURL(); - var args = new DownloadDataRequestArgs(url, 0, 0); - _unityWebDataRequestOp = _downloadBackend.CreateBytesRequest(args); - _unityWebDataRequestOp.SendRequest(); - _steps = ESteps.CheckRequest; - } - - // 检测下载结果 - if (_steps == ESteps.CheckRequest) - { - Progress = _unityWebDataRequestOp.DownloadProgress; - DownloadProgress = _unityWebDataRequestOp.DownloadProgress; - DownloadedBytes = _unityWebDataRequestOp.DownloadedBytes; - if (_unityWebDataRequestOp.IsDone == false) - return; - - // 检查网络错误 - if (_unityWebDataRequestOp.Status == EDownloadRequestStatus.Succeed) - { - AssetBundle assetBundle = LoadEncryptedAssetBundle(_unityWebDataRequestOp.Result); - if (assetBundle == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Failed load encrypted AssetBundle !"; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - Result = assetBundle; - } - } - else - { - if (_failedTryAgain > 0) - { - _steps = ESteps.TryAgain; - YooLogger.Warning($"Failed download : {_unityWebDataRequestOp.URL} Try again !"); - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _unityWebDataRequestOp.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; - } - } - } - - /// - /// 加载加密资源文件 - /// - private AssetBundle LoadEncryptedAssetBundle(byte[] fileData) - { - var fileInfo = new WebDecryptFileInfo(); - fileInfo.BundleName = _bundle.BundleName; - fileInfo.FileLoadCRC = _bundle.UnityCRC; - fileInfo.FileData = fileData; - var decryptResult = _decryptionServices.LoadAssetBundle(fileInfo); - return decryptResult.Result; - } - - /// - /// 获取网络请求地址 - /// - 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/WebGame/Operation/LoadWebNormalAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebNormalAssetBundleOperation.cs deleted file mode 100644 index e392c349..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/WebGame/Operation/LoadWebNormalAssetBundleOperation.cs +++ /dev/null @@ -1,116 +0,0 @@ -using UnityEngine; - -namespace YooAsset -{ - internal class LoadWebNormalAssetBundleOperation : LoadWebAssetBundleOperation - { - protected enum ESteps - { - None, - CreateRequest, - CheckRequest, - TryAgain, - Done, - } - - private readonly PackageBundle _bundle; - private readonly DownloadFileOptions _options; - private readonly bool _disableUnityWebCache; - private readonly IDownloadBackend _downloadBackend; - private IDownloadAssetBundleRequest _unityAssetBundleRequestOp; - - private int _requestCount = 0; - private float _tryAgainTimer = 0; - private int _failedTryAgain; - private ESteps _steps = ESteps.None; - - - internal LoadWebNormalAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options, bool disableUnityWebCache, IDownloadBackend downloadBackend) - { - _bundle = bundle; - _options = options; - _failedTryAgain = options.FailedTryAgain; - _disableUnityWebCache = disableUnityWebCache; - _downloadBackend = downloadBackend; - } - internal override void InternalStart() - { - _steps = ESteps.CreateRequest; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - // 创建下载器 - if (_steps == ESteps.CreateRequest) - { - string url = GetRequestURL(); - var args = new DownloadAssetBundleRequestArgs(url, 0, 0, _disableUnityWebCache, _bundle.FileHash, _bundle.UnityCRC); - _unityAssetBundleRequestOp = _downloadBackend.CreateAssetBundleRequest(args); - _unityAssetBundleRequestOp.SendRequest(); - _steps = ESteps.CheckRequest; - } - - // 检测下载结果 - if (_steps == ESteps.CheckRequest) - { - Progress = _unityAssetBundleRequestOp.DownloadProgress; - DownloadedBytes = _unityAssetBundleRequestOp.DownloadedBytes; - DownloadProgress = _unityAssetBundleRequestOp.DownloadProgress; - if (_unityAssetBundleRequestOp.IsDone == false) - return; - - if (_unityAssetBundleRequestOp.Status == EDownloadRequestStatus.Succeed) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - Result = _unityAssetBundleRequestOp.Result; - } - else - { - if (_failedTryAgain > 0) - { - _steps = ESteps.TryAgain; - YooLogger.Warning($"Failed download : {_unityAssetBundleRequestOp.URL} Try again !"); - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _unityAssetBundleRequestOp.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; - } - } - } - - /// - /// 获取网络请求地址 - /// - 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/OperationSystem/AsyncOperationBase.cs b/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs index 016eaa5b..f0fd58b4 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs +++ b/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Collections; using System.Collections.Generic; @@ -6,39 +6,61 @@ using System.Threading.Tasks; namespace YooAsset { + /// + /// 异步操作基类,所有异步操作的抽象基类 + /// 支持协程(IEnumerator)、Task(async/await)、回调等多种异步编程模式 + /// public abstract class AsyncOperationBase : IEnumerator, IComparable { - private List _childs; - private Action _callback; - private int _whileFrame = 1000; + private List _children; + private Action _completedCallbacks; + private uint _priority; /// - /// 等待异步执行完成 + /// 是否正处于同步等待状态 /// - internal bool IsWaitForAsyncComplete { private set; get; } = false; + internal bool IsWaitingForAsyncComplete { get; private set; } /// - /// 是否已经完成 + /// 标记脏(用于调度器检测并重排) /// - internal bool IsFinish { private set; get; } = false; + internal bool IsDirty { get; set; } /// - /// 异步系统是否繁忙 + /// 任务是否已结束(已触发回调和Task完成) + /// + internal bool IsFinished { get; private set; } + + /// + /// 当前帧时间切片是否已用完(同步等待时始终返回false) /// internal bool IsBusy { get { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) return false; return OperationSystem.IsBusy; } } /// - /// 任务优先级 + /// 任务优先级(值越大越优先执行) /// - public uint Priority { set; get; } = 0; + public uint Priority + { + set + { + if (_priority == value) + return; + _priority = value; + IsDirty = true; + } + get + { + return _priority; + } + } /// /// 任务状态 @@ -56,13 +78,13 @@ namespace YooAsset public float Progress { get; protected set; } /// - /// 是否已经完成 + /// 任务逻辑是否完成(Status为Succeed、Failed或Aborted) /// public bool IsDone { get { - return Status == EOperationStatus.Failed || Status == EOperationStatus.Succeed; + return Status == EOperationStatus.Succeed || Status == EOperationStatus.Failed || Status == EOperationStatus.Aborted; } } @@ -80,6 +102,7 @@ namespace YooAsset { try { + //注意:任务已完成,立即调用回调 value.Invoke(this); } catch (Exception ex) @@ -89,17 +112,17 @@ namespace YooAsset } else { - _callback += value; + _completedCallbacks += value; } } remove { - _callback -= value; + _completedCallbacks -= value; } } /// - /// 异步操作任务 + /// 用于 async/await 的 Task 对象 /// public Task Task { @@ -115,16 +138,37 @@ namespace YooAsset } } + + /// + /// 内部启动方法(子类必须实现) + /// internal abstract void InternalStart(); + + /// + /// 内部更新方法(子类必须实现) + /// internal abstract void InternalUpdate(); + + /// + /// 内部中止方法(子类可选实现) + /// internal virtual void InternalAbort() { } + + /// + /// 内部同步等待方法(子类可选实现) + /// 默认抛出异常,如果异步操作需要支持,子类应重写以支持同步等待 + /// internal virtual void InternalWaitForAsyncComplete() { - throw new System.NotImplementedException(this.GetType().Name); + throw new YooInternalException($"InternalWaitForAsyncComplete() not implemented : {this.GetType().Name}"); } - internal virtual string InternalGetDesc() + + /// + /// 获取操作的描述信息(子类可选实现) + /// + internal virtual string InternalGetDescription() { return string.Empty; } @@ -134,15 +178,25 @@ namespace YooAsset /// internal void AddChildOperation(AsyncOperationBase child) { - if (_childs == null) - _childs = new List(10); + if (_children == null) + _children = new List(10); -#if UNITY_EDITOR - if (_childs.Contains(child)) - throw new YooInternalException($"The child node {child.GetType().Name} already exists !"); +#if UNITY_EDITOR || DEBUG + if (child == null) + throw new YooInternalException("The child node is null."); + + if (ReferenceEquals(child, this)) + throw new YooInternalException("The child node cannot be itself."); + + if (_children.Contains(child)) + throw new YooInternalException($"The child node {child.GetType().Name} already exists."); + + // 禁止形成环依赖 + if (WouldCreateCycle(child)) + throw new YooInternalException($"AddChildOperation would create a cycle : {this.GetType().Name} -> {child.GetType().Name}"); #endif - _childs.Add(child); + _children.Add(child); } /// @@ -150,23 +204,26 @@ namespace YooAsset /// internal void RemoveChildOperation(AsyncOperationBase child) { - if (_childs == null) + if (_children == null) return; -#if UNITY_EDITOR - if (_childs.Contains(child) == false) - throw new YooInternalException($"The child node {child.GetType().Name} not exists !"); +#if UNITY_EDITOR || DEBUG + if (child == null) + throw new YooInternalException("The child node is null."); + + if (_children.Contains(child) == false) + throw new YooInternalException($"The child node {child.GetType().Name} not exists."); #endif - _childs.Remove(child); + _children.Remove(child); } /// /// 获取异步操作说明 /// - internal string GetOperationDesc() + internal string GetOperationDescription() { - return InternalGetDesc(); + return InternalGetDescription(); } /// @@ -182,7 +239,16 @@ namespace YooAsset DebugBeginRecording(); // 开始任务 - InternalStart(); + try + { + InternalStart(); + } + catch (Exception ex) + { + Status = EOperationStatus.Failed; + Error = ex.ToString(); + YooLogger.Error($"Exception in {this.GetType().Name}.InternalStart : {ex}"); + } } } @@ -197,23 +263,34 @@ namespace YooAsset DebugUpdateRecording(); // 更新任务 - InternalUpdate(); + // 注意:兜底隔离机制 + // 说明:检测的异常源包含:I/O(解压/读写权限/磁盘满),平台差异等 + try + { + InternalUpdate(); + } + catch (Exception ex) + { + Status = EOperationStatus.Failed; + Error = ex.ToString(); + YooLogger.Error($"Exception in {this.GetType().Name}.InternalUpdate : {ex}"); + } } - if (IsDone && IsFinish == false) + if (IsDone && IsFinished == false) { FinishOperation(); } } /// - /// 终止异步任务 + /// 终止异步任务(递归中止所有子任务) /// internal void AbortOperation() { - if (_childs != null) + if (_children != null) { - foreach (var child in _childs) + foreach (var child in _children) { child.AbortOperation(); } @@ -222,164 +299,264 @@ namespace YooAsset if (IsDone == false) { InternalAbort(); - Status = EOperationStatus.Failed; + Status = EOperationStatus.Aborted; Error = "user abort"; - YooLogger.Warning($"Async operation {this.GetType().Name} has been aborted !"); + YooLogger.Warning($"Async operation {this.GetType().Name} has been aborted."); } + + //注意:强制收尾,确保Task能完成 + FinishOperation(); } /// - /// 强制结束异步任务 + /// 完成异步任务(触发回调和Task完成) /// - internal void FinishOperation() + private void FinishOperation() { - if (IsFinish == false) + if (IsFinished == false) { - IsFinish = true; + IsFinished = true; Progress = 1f; // 结束记录 DebugEndRecording(); - try + if (_completedCallbacks != null) { - _callback?.Invoke(this); - } - catch (Exception ex) - { - YooLogger.Error($"Exception in completion callback: {ex}"); - } - finally - { - _callback = null; - if (_taskCompletionSource != null) - _taskCompletionSource.TrySetResult(null); + var invocationList = _completedCallbacks.GetInvocationList(); + foreach (var handler in invocationList) + { + try + { + ((Action)handler).Invoke(this); + } + catch (Exception ex) + { + YooLogger.Error($"Exception in completion callback: {ex}"); + } + } } + + _completedCallbacks = null; + if (_taskCompletionSource != null) + _taskCompletionSource.TrySetResult(null); } } /// - /// 执行While循环 + /// 执行一次更新逻辑 /// - protected bool ExecuteWhileDone() - { - if (IsDone == false) - { - // 执行更新逻辑 - InternalUpdate(); - - // 当执行次数用完时 - _whileFrame--; - if (_whileFrame <= 0) - { - Status = EOperationStatus.Failed; - Error = $"Operation {this.GetType().Name} failed to wait for async complete !"; - YooLogger.Error(Error); - } - } - return IsDone; - } - - /// - /// 等待异步执行完毕 - /// - public void WaitForAsyncComplete() + protected void RunOnceExecution() { if (IsDone) return; - //TODO 防止异步操作被挂起陷入无限死循环! - // 例如:文件解压任务或者文件导入任务! + UpdateOperation(); + } + + /// + /// 批量执行一定次数的更新逻辑 + /// + /// 最大执行次数,默认1000次 + /// + /// 用于需要快速完成但又不想完全阻塞主线程的场景。 + /// + protected void RunBatchExecution(int count = 1000) + { + if (IsDone) + return; + + int runCount = count; + while (true) + { + // 执行更新逻辑 + UpdateOperation(); + if (IsDone) + break; + + // 当执行次数用完时 + runCount--; + if (runCount <= 0) + break; + } + } + + /// + /// 无限次数的执行更新逻辑,直到任务完成 + /// 注意:该方法会阻塞主线程 + /// + /// 休眠时长 + protected void RunUntilCompletion(int sleepMS = 1) + { + if (IsDone) + return; + + while (true) + { + UpdateOperation(); + if (IsDone) + break; + + // 注意: 短暂休眠避免完全占用CPU资源 + System.Threading.Thread.Sleep(sleepMS); + } + } + + /// + /// 同步等待异步执行完毕(会阻塞当前线程) + /// + public void WaitForAsyncComplete() + { + //注意:防止异步操作被挂起陷入无限死循环! if (Status == EOperationStatus.None) { StartOperation(); } - if (IsWaitForAsyncComplete == false) + if (IsWaitingForAsyncComplete == false) { - IsWaitForAsyncComplete = true; - InternalWaitForAsyncComplete(); + IsWaitingForAsyncComplete = true; -#if UNITY_EDITOR if (IsDone == false) - throw new YooInternalException($"WaitForAsyncComplete() must complete operation: {this.GetType().Name}"); -#endif + InternalWaitForAsyncComplete(); + + if (IsDone == false) + { + Status = EOperationStatus.Failed; + Error = $"Operation {this.GetType().Name} failed to wait for async complete."; + YooLogger.Error(Error); + } + + //注意:强制收尾,确保Task能完成 + FinishOperation(); } } #region 调试信息 /// - /// 开始的时间 + /// 任务开始的时间(格式:HH:MM:SS,仅DEBUG模式有效) /// - public string BeginTime = string.Empty; + public string StartTime { get; protected set; } /// /// 处理耗时(单位:毫秒) /// - public long ProcessTime { protected set; get; } + public long ElapsedMS { get; protected set; } - // 加载耗时统计 - private Stopwatch _watch = null; + /// + /// 任务耗时计时器 + /// + private Stopwatch _stopwatch = null; [Conditional("DEBUG")] private void DebugBeginRecording() { - if (_watch == null) + if (_stopwatch == null) { - BeginTime = SpawnTimeToString(UnityEngine.Time.realtimeSinceStartup); - _watch = Stopwatch.StartNew(); + StartTime = FormatElapsedTime(TimeUtility.RealtimeSinceStartup); + _stopwatch = Stopwatch.StartNew(); } } [Conditional("DEBUG")] private void DebugUpdateRecording() { - if (_watch != null) + if (_stopwatch != null) { - ProcessTime = _watch.ElapsedMilliseconds; + ElapsedMS = _stopwatch.ElapsedMilliseconds; } } [Conditional("DEBUG")] private void DebugEndRecording() { - if (_watch != null) + if (_stopwatch != null) { - ProcessTime = _watch.ElapsedMilliseconds; - _watch = null; + ElapsedMS = _stopwatch.ElapsedMilliseconds; + _stopwatch = null; } } - private string SpawnTimeToString(float spawnTime) + /// + /// 将游戏运行时间格式化为 HH:MM:SS 格式 + /// + /// 运行时间(秒) + private string FormatElapsedTime(double time) { - float h = UnityEngine.Mathf.FloorToInt(spawnTime / 3600f); - float m = UnityEngine.Mathf.FloorToInt(spawnTime / 60f - h * 60f); - float s = UnityEngine.Mathf.FloorToInt(spawnTime - m * 60f - h * 3600f); + double h = System.Math.Floor(time / 3600); + double m = System.Math.Floor(time / 60 - h * 60); + double s = System.Math.Floor(time - m * 60 - h * 3600); return h.ToString("00") + ":" + m.ToString("00") + ":" + s.ToString("00"); } - internal DebugOperationInfo GetDebugOperationInfo() + /// + /// 检测添加子任务是否会形成循环依赖 + /// 使用深度优先搜索(DFS)遍历子任务图 + /// + private bool WouldCreateCycle(AsyncOperationBase child) { - var operationInfo = new DebugOperationInfo(); + const int MaxCycleCheckDepth = 4096; // 循环检测最大深度 + var stack = new Stack(); + var visited = new HashSet(); + stack.Push(child); + + while (stack.Count > 0) + { + var node = stack.Pop(); + if (node == null) + continue; + + // 防止重复访问 + if (visited.Add(node) == false) + continue; + + // 防止无限循环(图过大) + if (visited.Count > MaxCycleCheckDepth) + throw new YooInternalException("Child operation graph is too large, cycle check aborted."); + + // 检测循环:如果遍历到自己,说明形成循环 + if (ReferenceEquals(node, this)) + return true; + + if (node._children == null) + continue; + + // 将子节点加入栈 + for (int i = 0; i < node._children.Count; i++) + { + stack.Push(node._children[i]); + } + } + + return false; + } + + /// + /// 获取调试信息 + /// 注意:递归构建子树存在深度风险 + /// + internal DiagnosticOperationInfo GetDebugOperationInfo() + { + var operationInfo = new DiagnosticOperationInfo(); operationInfo.OperationName = this.GetType().Name; - operationInfo.OperationDesc = GetOperationDesc(); + operationInfo.OperationDesc = GetOperationDescription(); operationInfo.Priority = Priority; operationInfo.Progress = Progress; - operationInfo.BeginTime = BeginTime; - operationInfo.ProcessTime = ProcessTime; + operationInfo.StartTime = StartTime; + operationInfo.ElapsedMS = ElapsedMS; operationInfo.Status = Status.ToString(); - if (_childs == null) + if (_children == null) { - operationInfo.Childs = new List(); + operationInfo.Children = new List(); } else { - operationInfo.Childs = new List(_childs.Count); - foreach (var child in _childs) + operationInfo.Children = new List(_children.Count); + foreach (var child in _children) { var childInfo = child.GetDebugOperationInfo(); - operationInfo.Childs.Add(childInfo); + operationInfo.Children.Add(childInfo); } } @@ -395,6 +572,11 @@ namespace YooAsset #endregion #region 异步编程相关 + /// + /// 用于支持 async/await 的任务完成源 + /// + private TaskCompletionSource _taskCompletionSource; + bool IEnumerator.MoveNext() { return !IsDone; @@ -403,8 +585,6 @@ namespace YooAsset { } object IEnumerator.Current => null; - - private TaskCompletionSource _taskCompletionSource; #endregion } } diff --git a/Assets/YooAsset/Runtime/OperationSystem/EOperationStatus.cs b/Assets/YooAsset/Runtime/OperationSystem/EOperationStatus.cs index dddaa7d4..20c1b62e 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/EOperationStatus.cs +++ b/Assets/YooAsset/Runtime/OperationSystem/EOperationStatus.cs @@ -1,11 +1,34 @@  namespace YooAsset { + /// + /// 异步操作状态枚举 + /// public enum EOperationStatus { + /// + /// 未开始 + /// None, + + /// + /// 处理中 + /// Processing, + + /// + /// 已成功 + /// Succeed, - Failed + + /// + /// 已失败 + /// + Failed, + + /// + /// 已中止(用户主动取消) + /// + Aborted, } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/OperationSystem/GameAsyncOperation.cs b/Assets/YooAsset/Runtime/OperationSystem/GameAsyncOperation.cs deleted file mode 100644 index 806bbac9..00000000 --- a/Assets/YooAsset/Runtime/OperationSystem/GameAsyncOperation.cs +++ /dev/null @@ -1,25 +0,0 @@ - -namespace YooAsset -{ - public abstract class GameAsyncOperation : AsyncOperationBase - { - internal override void InternalStart() - { - OnStart(); - } - internal override void InternalUpdate() - { - OnUpdate(); - } - - /// - /// 异步操作开始 - /// - protected abstract void OnStart(); - - /// - /// 异步操作更新 - /// - protected abstract void OnUpdate(); - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/OperationSystem/OperationScheduler.cs b/Assets/YooAsset/Runtime/OperationSystem/OperationScheduler.cs index 51463577..f7464b25 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/OperationScheduler.cs +++ b/Assets/YooAsset/Runtime/OperationSystem/OperationScheduler.cs @@ -9,41 +9,58 @@ namespace YooAsset internal class OperationScheduler : IComparable { private readonly List _operations = new List(100); - private readonly List _newList = new List(100); + private readonly List _pendingOperations = new List(100); + private uint _priority; /// /// 所属包裹名称 /// - public string PackageName { private set; get; } + public string PackageName { get; private set; } /// /// 调度器优先级(值越大越优先) /// - public int Priority { private set; get; } + public uint Priority + { + get { return _priority; } + set + { + if (_priority != value) + { + _priority = value; + IsDirty = true; + } + } + } + + /// + /// 优先级是否已变更(需要重新排序) + /// + public bool IsDirty { get; set; } /// /// 创建顺序(用于同优先级稳定排序) /// - public int CreateIndex { private set; get; } + public int CreationOrder { get; private set; } - public OperationScheduler(string packageName, int priority, int createIndex) + public OperationScheduler(string packageName, int creationOrder) { PackageName = packageName; - Priority = priority; - CreateIndex = createIndex; + CreationOrder = creationOrder; } /// /// 开始处理异步操作 /// + /// + /// 操作会立即启动,但会先添加到待处理队列。 + /// 在下一次Update时才会合并到执行队列并参与调度更新 + /// public void StartOperation(AsyncOperationBase operation) { - _newList.Add(operation); + _pendingOperations.Add(operation); operation.StartOperation(); - - // 通知开始回调 - OperationSystem.InvokeStartCallback(PackageName, operation); } /// @@ -55,34 +72,32 @@ namespace YooAsset for (int i = _operations.Count - 1; i >= 0; i--) { var operation = _operations[i]; - if (operation.IsFinish) + if (operation.IsFinished) { _operations.RemoveAt(i); - - // 通知完成回调 - OperationSystem.InvokeFinishCallback(PackageName, operation); } } // 添加新增的异步操作 - if (_newList.Count > 0) + if (_pendingOperations.Count > 0) { - bool sorting = false; - foreach (var operation in _newList) + _operations.AddRange(_pendingOperations); + _pendingOperations.Clear(); + } + + // 检测是否需要执行排序 + bool isDirty = false; + foreach (var operation in _operations) + { + if (operation.IsDirty) { - if (operation.Priority > 0) - { - sorting = true; - break; - } + operation.IsDirty = false; + isDirty = true; } - - _operations.AddRange(_newList); - _newList.Clear(); - - // 重新排序优先级 - if (sorting) - _operations.Sort(); + } + if (isDirty) + { + _operations.Sort(); } // 更新进行中的异步操作 @@ -93,7 +108,7 @@ namespace YooAsset break; var operation = _operations[i]; - if (operation.IsFinish) + if (operation.IsFinished) continue; operation.UpdateOperation(); @@ -106,18 +121,16 @@ namespace YooAsset public void ClearAll() { // 终止临时队列里的任务 - foreach (var operation in _newList) + foreach (var operation in _pendingOperations) { operation.AbortOperation(); - operation.FinishOperation(); //注意:强制收尾,确保Task能完成 } - _newList.Clear(); + _pendingOperations.Clear(); // 终止正在进行的任务 foreach (var operation in _operations) { operation.AbortOperation(); - operation.FinishOperation(); //注意:强制收尾,确保Task能完成 } _operations.Clear(); } @@ -125,10 +138,10 @@ namespace YooAsset /// /// 获取调试信息 /// - public List GetDebugOperationInfos() + public List GetDebugOperationInfos() { - int totalCount = _operations.Count + _newList.Count; - List result = new List(totalCount); + int totalCount = _operations.Count + _pendingOperations.Count; + List result = new List(totalCount); // 包含正在执行的任务 foreach (var operation in _operations) @@ -138,7 +151,7 @@ namespace YooAsset } // 包含待处理的新任务 - foreach (var operation in _newList) + foreach (var operation in _pendingOperations) { var operationInfo = operation.GetDebugOperationInfo(); result.Add(operationInfo); @@ -155,7 +168,7 @@ namespace YooAsset if (result == 0) { // 优先级相同,按创建顺序 - result = this.CreateIndex.CompareTo(other.CreateIndex); + result = this.CreationOrder.CompareTo(other.CreationOrder); } return result; } diff --git a/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs b/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs index a5964487..f6252fc2 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs +++ b/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs @@ -5,7 +5,11 @@ using System.Diagnostics; namespace YooAsset { - internal class OperationSystem + /// + /// 异步操作系统(静态调度器) + /// 负责管理所有包裹的调度器,提供时间切片执行机制 + /// + internal static class OperationSystem { #if UNITY_EDITOR [UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)] @@ -15,25 +19,41 @@ namespace YooAsset } #endif - // 全局调度器名称 - public const string GLOBAL_SCHEDULER_NAME = ""; + public const string GlobalSchedulerName = "YOOASSET_GLOBAL_SCHEDULER"; // 全局调度器名称 + private const long MinTimeSlice = 10; // 最小时间片(毫秒) - private static readonly Dictionary _schedulerDic = new Dictionary(100); + private static readonly Dictionary _schedulerDict = new Dictionary(100); private static readonly List _schedulerList = new List(100); - private static bool _schedulerListDirty = false; - private static int _createIndex = 0; - - private static Action _startCallback = null; - private static Action _finishCallback = null; + private static bool _isInitialized; + private static int _nextCreationIndex; // 计时器相关 - private static Stopwatch _watch; + private static Stopwatch _systemStopwatch; private static long _frameTime; + private static long _maxTimeSlice = long.MaxValue; /// /// 异步操作系统的每帧最大执行预算(毫秒) /// - public static long MaxTimeSlice { set; get; } = long.MaxValue; + public static long MaxTimeSlice + { + get + { + return _maxTimeSlice; + } + set + { + if (value < MinTimeSlice) + { + _maxTimeSlice = MinTimeSlice; + YooLogger.Warning($"MaxTimeSlice minimum value is {MinTimeSlice} milliseconds."); + } + else + { + _maxTimeSlice = value; + } + } + } /// /// 异步操作系统是否繁忙 @@ -42,14 +62,14 @@ namespace YooAsset { get { - if (_watch == null) + if (_systemStopwatch == null) return false; - if (MaxTimeSlice == long.MaxValue) + if (_maxTimeSlice == long.MaxValue) return false; // 注意 : 单次调用开销约1微秒 - return _watch.ElapsedMilliseconds - _frameTime >= MaxTimeSlice; + return _systemStopwatch.ElapsedMilliseconds - _frameTime >= _maxTimeSlice; } } @@ -59,10 +79,17 @@ namespace YooAsset /// public static void Initialize() { - _watch = Stopwatch.StartNew(); + if (_isInitialized) + { + YooLogger.Warning("Operation system is already initialized."); + return; + } + + _isInitialized = true; + _systemStopwatch = Stopwatch.StartNew(); // 创建全局调度器 - CreatePackageScheduler(GLOBAL_SCHEDULER_NAME, 0); + CreatePackageScheduler(GlobalSchedulerName, uint.MaxValue); } /// @@ -70,15 +97,26 @@ namespace YooAsset /// public static void Update() { - // 重新排序调度器 - if (_schedulerListDirty) + if (_isInitialized == false) + return; + + // 检测是否需要执行排序 + bool isDirty = false; + foreach (var scheduler in _schedulerList) + { + if (scheduler.IsDirty) + { + scheduler.IsDirty = false; + isDirty = true; + } + } + if (isDirty) { - _schedulerListDirty = false; _schedulerList.Sort(); } // 更新帧时间 - _frameTime = _watch.ElapsedMilliseconds; + _frameTime = _systemStopwatch.ElapsedMilliseconds; // 更新调度器 for (int i = 0; i < _schedulerList.Count; i++) @@ -95,63 +133,69 @@ namespace YooAsset /// public static void DestroyAll() { + _isInitialized = false; + // 清空所有调度器 foreach (var scheduler in _schedulerList) { scheduler.ClearAll(); } - _schedulerDic.Clear(); + _schedulerDict.Clear(); _schedulerList.Clear(); - _schedulerListDirty = false; - _createIndex = 0; + _nextCreationIndex = 0; - _startCallback = null; - _finishCallback = null; - _watch = null; + _systemStopwatch = null; _frameTime = 0; - MaxTimeSlice = long.MaxValue; + _maxTimeSlice = long.MaxValue; } /// /// 创建包裹调度器 /// - internal static void CreatePackageScheduler(string packageName, int priority) + public static OperationScheduler CreatePackageScheduler(string packageName, uint priority) { - if (_schedulerDic.ContainsKey(packageName)) + DebugEnsureInitialized(packageName); + + if (_schedulerDict.ContainsKey(packageName)) { throw new YooInternalException($"Package scheduler already exists: {packageName}"); } - var scheduler = new OperationScheduler(packageName, priority, _createIndex++); - _schedulerDic.Add(packageName, scheduler); + var scheduler = new OperationScheduler(packageName, _nextCreationIndex++); + _schedulerDict.Add(packageName, scheduler); _schedulerList.Add(scheduler); - _schedulerListDirty = true; + scheduler.Priority = priority; + return scheduler; } /// /// 销毁包裹调度器 /// - internal static void DestroyPackageScheduler(string packageName) + public static void DestroyPackageScheduler(string packageName) { + DebugEnsureInitialized(packageName); + // 不允许销毁默认调度器 - if (packageName == GLOBAL_SCHEDULER_NAME) + if (packageName == GlobalSchedulerName) { - throw new YooInternalException("Cannot destroy the global package scheduler!"); + throw new YooInternalException("Cannot destroy the global package scheduler."); } - if (_schedulerDic.TryGetValue(packageName, out var scheduler)) + if (_schedulerDict.TryGetValue(packageName, out var scheduler)) { scheduler.ClearAll(); - _schedulerDic.Remove(packageName); + _schedulerDict.Remove(packageName); _schedulerList.Remove(scheduler); } } /// - /// 销毁包裹的所有任务 + /// 清空并中止包裹的所有任务 /// - public static void ClearPackageOperation(string packageName) + public static void ClearPackageOperations(string packageName) { + DebugEnsureInitialized(packageName); + var scheduler = GetScheduler(packageName); scheduler.ClearAll(); } @@ -161,40 +205,32 @@ namespace YooAsset /// public static void StartOperation(string packageName, AsyncOperationBase operation) { + DebugEnsureInitialized(packageName); + var scheduler = GetScheduler(packageName); scheduler.StartOperation(operation); } /// - /// 监听任务开始 + /// 设置调度器优先级 /// - public static void RegisterStartCallback(Action callback) + public static void SetSchedulerPriority(string packageName, uint priority) { - _startCallback = callback; + DebugEnsureInitialized(packageName); + + var scheduler = GetScheduler(packageName); + scheduler.Priority = priority; } /// - /// 监听任务结束 + /// 获取调度器优先级 /// - public static void RegisterFinishCallback(Action callback) + public static uint GetSchedulerPriority(string packageName) { - _finishCallback = callback; - } + DebugEnsureInitialized(packageName); - /// - /// 触发任务开始回调 - /// - internal static void InvokeStartCallback(string packageName, AsyncOperationBase operation) - { - _startCallback?.Invoke(packageName, operation); - } - - /// - /// 触发任务完成回调 - /// - internal static void InvokeFinishCallback(string packageName, AsyncOperationBase operation) - { - _finishCallback?.Invoke(packageName, operation); + var scheduler = GetScheduler(packageName); + return scheduler.Priority; } /// @@ -202,32 +238,34 @@ namespace YooAsset /// private static OperationScheduler GetScheduler(string packageName) { - // 空包名路由到默认调度器 - if (string.IsNullOrEmpty(packageName)) - packageName = GLOBAL_SCHEDULER_NAME; - - if (_schedulerDic.TryGetValue(packageName, out var scheduler)) + if (_schedulerDict.TryGetValue(packageName, out var scheduler)) { return scheduler; } // 严格模式:非默认包裹必须先创建调度器 - throw new YooInternalException($"Package scheduler not found: {packageName}. Please call YooAssets.CreatePackage() first!"); + throw new YooInternalException($"Operation scheduler not found: {packageName}."); } #region 调试信息 - internal static List GetDebugOperationInfos(string packageName) + internal static List GetDebugOperationInfos(string packageName) { - // 空包名路由到默认调度器 - if (string.IsNullOrEmpty(packageName)) - packageName = GLOBAL_SCHEDULER_NAME; + DebugEnsureInitialized(packageName); - if (_schedulerDic.TryGetValue(packageName, out var scheduler)) - { - return scheduler.GetDebugOperationInfos(); - } + var scheduler = GetScheduler(packageName); + return scheduler.GetDebugOperationInfos(); + } + #endregion - return new List(); + #region 调试方法 + [Conditional("DEBUG")] + private static void DebugEnsureInitialized(string packageName) + { + if (string.IsNullOrWhiteSpace(packageName)) + throw new YooInternalException("Package name is null or empty."); + + if (_isInitialized == false) + throw new YooInternalException($"{nameof(OperationSystem)} not initialized."); } #endregion } diff --git a/Assets/YooAsset/Runtime/OperationSystem/README.md b/Assets/YooAsset/Runtime/OperationSystem/README.md index 56ee82f5..eaf74a8f 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/README.md +++ b/Assets/YooAsset/Runtime/OperationSystem/README.md @@ -1,16 +1,30 @@ -# OperationSystem 异步操作系统 +# OperationSystem 异步操作模块 ## 模块概述 -OperationSystem 是 YooAsset 资源管理系统的**异步操作调度核心**,负责管理所有异步操作的生命周期、调度执行和状态追踪。该模块提供了统一的异步操作抽象,支持协程、async/await、回调等多种异步编程模式。 +OperationSystem 是 YooAsset 资源管理系统的**异步操作调度层**,负责管理和调度所有异步操作的生命周期。该模块提供了统一的异步操作抽象,支持协程、Task(async/await)、回调等多种异步编程模式,以及基于优先级的时间切片调度机制。 + +### 可见性说明 + +OperationSystem 属于 YooAsset Runtime 的内部基础模块,目录内 `OperationSystem`、`OperationScheduler` 等类型为 `internal`(仅供 YooAsset Runtime 内部程序集使用)。`AsyncOperationBase` 和 `EOperationStatus` 为 `public`,供上层和用户代码使用。 ### 核心职责 -- 异步操作的统一抽象和生命周期管理 -- 基于优先级的操作调度 +- 异步操作生命周期管理(启动、更新、完成、中止) +- 基于优先级的调度排序 - 时间切片执行(防止主线程阻塞) -- 多种异步编程模式支持 -- 操作状态追踪和调试信息收集 +- 多包裹独立调度 +- 父子任务依赖管理 + +--- + +## 边界与上层协作 + +OperationSystem 的职责是提供"统一异步操作抽象 + 优先级调度 + 时间切片执行"的基础能力: + +- **本模块不负责具体业务逻辑**:具体的资源加载、下载等逻辑由子类实现 +- **本模块不负责错误重试**:失败后的重试策略由上层或子类实现 +- **本模块不负责资源释放**:资源的引用计数和卸载由 ResourceManager 管理 --- @@ -18,47 +32,49 @@ OperationSystem 是 YooAsset 资源管理系统的**异步操作调度核心** | 目标 | 说明 | |------|------| -| **统一抽象** | 所有异步操作继承同一基类,接口一致 | -| **灵活调度** | 支持优先级排序、时间切片、帧预算控制 | -| **多模式支持** | 协程(IEnumerator)、Task(async/await)、回调 | -| **可调试性** | 完整的状态追踪、耗时统计、层级关系 | -| **线程安全** | 所有调度逻辑在主线程执行 | +| **统一抽象** | 所有异步操作继承 AsyncOperationBase,提供一致的 API | +| **多模式支持** | 支持协程(yield return)、Task(async/await)、回调三种异步模式 | +| **时间切片** | 可配置每帧最大执行时间,防止主线程卡顿 | +| **优先级调度** | 支持任务和调度器双层优先级,高优先级任务优先执行 | +| **多包裹隔离** | 每个资源包裹拥有独立调度器,互不干扰 | --- ## 架构概念 -### 系统架构 +### 分层架构 ``` ┌─────────────────────────────────────────────────────────┐ -│ 上层调用者 │ -│ (ResourceManager / FileSystem / 业务层) │ +│ 上层调用者 │ +│ (ResourcePackage / ResourceManager) │ └─────────────────────────┬───────────────────────────────┘ - │ StartOperation() + │ ┌─────────────────────────▼───────────────────────────────┐ -│ OperationSystem │ -│ (调度器) │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ 优先级队列 │ │ 时间切片 │ │ 回调通知 │ │ -│ └─────────────┘ └─────────────┘ └─────────────┘ │ +│ OperationSystem │ +│ (静态调度系统) │ +│ 管理所有调度器,提供时间切片机制 │ └─────────────────────────┬───────────────────────────────┘ - │ UpdateOperation() + │ ┌─────────────────────────▼───────────────────────────────┐ -│ AsyncOperationBase │ -│ (操作基类) │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ 状态机 │ │ 子任务管理 │ │ 异步模式 │ │ -│ └─────────────┘ └─────────────┘ └─────────────┘ │ +│ OperationScheduler │ +│ (包裹调度器) │ +│ 管理单个包裹的异步操作队列 │ +└─────────────────────────┬───────────────────────────────┘ + │ +┌─────────────────────────▼───────────────────────────────┐ +│ AsyncOperationBase │ +│ (异步操作基类) │ +│ 定义操作生命周期和状态机 │ └─────────────────────────────────────────────────────────┘ ``` ### 核心组件 -- **OperationSystem**: 静态调度器,管理所有操作的执行 -- **AsyncOperationBase**: 异步操作基类,定义生命周期和状态 -- **GameAsyncOperation**: 游戏层操作基类,提供更友好的 API -- **EOperationStatus**: 操作状态枚举 +- **OperationSystem**: 静态调度系统,管理所有包裹调度器,提供时间切片执行机制 +- **OperationScheduler**: 包裹调度器,管理单个包裹的异步操作队列和优先级排序 +- **AsyncOperationBase**: 异步操作抽象基类,定义操作生命周期和多种异步编程接口 +- **EOperationStatus**: 操作状态枚举,表示操作的当前状态 --- @@ -66,211 +82,143 @@ OperationSystem 是 YooAsset 资源管理系统的**异步操作调度核心** ``` OperationSystem/ -├── EOperationStatus.cs # 操作状态枚举 -├── AsyncOperationBase.cs # 异步操作基类 -├── OperationSystem.cs # 异步操作调度器 -└── GameAsyncOperation.cs # 游戏层操作基类 +├── AsyncOperationBase.cs # 异步操作抽象基类 +├── EOperationStatus.cs # 操作状态枚举 +├── OperationScheduler.cs # 包裹调度器 +├── OperationSystem.cs # 静态调度系统 +└── README.md # 本文档 ``` --- -## 枚举定义 +## 接口说明 -### EOperationStatus(操作状态) +### EOperationStatus(操作状态枚举) + +定义异步操作的生命周期状态。 ```csharp public enum EOperationStatus { - None, // 未开始 - Processing, // 处理中 - Succeed, // 已成功 - Failed // 已失败 + None, // 未开始 + Processing, // 处理中 + Succeed, // 已成功 + Failed, // 已失败 + Aborted // 已中止(用户主动取消) } ``` -**状态转换:** +### AsyncOperationBase(异步操作基类) +所有异步操作的抽象基类,实现 `IEnumerator`(协程支持)和 `IComparable`(优先级排序)。 + +```csharp +public abstract class AsyncOperationBase : IEnumerator, IComparable +{ + // 状态属性 + public EOperationStatus Status { get; } // 当前状态 + public bool IsDone { get; } // 是否完成(Succeed/Failed/Aborted) + public string Error { get; } // 错误信息 + public float Progress { get; } // 进度(0-1) + public uint Priority { get; set; } // 优先级(值越大越优先) + + // 异步编程支持 + public Task Task { get; } // 用于 async/await + public event Action Completed; // 完成回调 + + // 同步等待 + public void WaitForAsyncComplete(); // 同步等待完成(阻塞当前线程) + + // 调试信息(仅 DEBUG 模式有效) + public string StartTime { get; } // 开始时间(HH:MM:SS) + public long ElapsedMS { get; } // 耗时(毫秒) +} ``` - StartOperation() InternalUpdate() -None ─────────────────► Processing ─────────────────┬──► Succeed - │ - └──► Failed + +### 子类必须实现的方法 + +```csharp +// 启动时调用(必须实现) +internal abstract void InternalStart(); + +// 每帧更新(必须实现) +internal abstract void InternalUpdate(); + +// 中止时调用(可选实现) +internal virtual void InternalAbort() { } + +// 同步等待实现(可选实现,不实现则抛出异常) +internal virtual void InternalWaitForAsyncComplete(); + +// 获取操作描述(可选实现,用于调试) +internal virtual string InternalGetDescription(); ``` --- ## 核心类说明 -### AsyncOperationBase(异步操作基类) +### OperationSystem -所有异步操作的抽象基类,实现了 `IEnumerator` 和 `IComparable` 接口。 +静态调度系统,管理所有包裹的调度器,提供全局时间切片机制。 -#### 公共属性 - -| 属性 | 类型 | 说明 | -|------|------|------| -| `Priority` | `uint` | 任务优先级(值越大越优先) | -| `Status` | `EOperationStatus` | 当前状态 | -| `Error` | `string` | 错误信息(失败时) | -| `Progress` | `float` | 处理进度(0-1) | -| `PackageName` | `string` | 所属包裹名称 | -| `IsDone` | `bool` | 是否已完成(Succeed 或 Failed) | -| `Task` | `Task` | 用于 async/await | -| `BeginTime` | `string` | 开始时间(调试用) | -| `ProcessTime` | `long` | 处理耗时毫秒(调试用) | - -#### 公共事件 +**主要功能:** +- 管理多个包裹调度器的生命周期 +- 提供全局时间切片预算控制 +- 按优先级更新各调度器 ```csharp -/// -/// 完成事件(支持后注册立即触发) -/// -public event Action Completed; -``` - -#### 公共方法 - -```csharp -/// -/// 同步等待异步操作完成 -/// -public void WaitForAsyncComplete(); -``` - -#### 内部抽象方法(子类实现) - -| 方法 | 说明 | -|------|------| -| `InternalStart()` | 操作开始时调用 | -| `InternalUpdate()` | 每帧更新时调用 | -| `InternalAbort()` | 操作中止时调用(可选) | -| `InternalWaitForAsyncComplete()` | 同步等待时调用(可选) | -| `InternalGetDesc()` | 获取操作描述(可选) | - -#### 子任务管理 - -```csharp -// 子任务列表 -internal readonly List Childs; - -// 添加/移除子任务 -internal void AddChildOperation(AsyncOperationBase child); -internal void RemoveChildOperation(AsyncOperationBase child); -``` - ---- - -### OperationSystem(调度器) - -静态类,负责异步操作的调度和管理。 - -#### 配置属性 - -```csharp -/// -/// 每帧最大执行时间(毫秒) -/// 默认值:long.MaxValue(无限制) -/// -public static long MaxTimeSlice { set; get; } - -/// -/// 当前帧是否已超时 -/// -public static bool IsBusy { get; } -``` - -#### 核心方法 - -```csharp -/// -/// 初始化异步操作系统 -/// -public static void Initialize(); - -/// -/// 每帧更新(由 YooAssets 驱动) -/// -public static void Update(); - -/// -/// 销毁所有操作 -/// -public static void DestroyAll(); - -/// -/// 清理指定包裹的所有操作 -/// -public static void ClearPackageOperation(string packageName); - -/// -/// 启动异步操作 -/// -public static void StartOperation(string packageName, AsyncOperationBase operation); -``` - -#### 回调监听 - -```csharp -/// -/// 注册任务开始回调 -/// -public static void RegisterStartCallback(Action callback); - -/// -/// 注册任务结束回调 -/// -public static void RegisterFinishCallback(Action callback); -``` - ---- - -### GameAsyncOperation(游戏层基类) - -继承 `AsyncOperationBase`,为业务层提供更友好的 API。 - -```csharp -public abstract class GameAsyncOperation : AsyncOperationBase +internal static class OperationSystem { - /// - /// 异步操作开始 - /// - protected abstract void OnStart(); + // 时间切片配置 + public static long MaxTimeSlice { get; set; } // 每帧最大执行时间(毫秒) + public static bool IsBusy { get; } // 当前帧时间切片是否已用完 - /// - /// 异步操作更新 - /// - protected abstract void OnUpdate(); + // 生命周期 + public static void Initialize(); // 初始化系统 + public static void Update(); // 每帧更新 + public static void DestroyAll(); // 销毁系统 - /// - /// 异步操作终止 - /// - protected abstract void OnAbort(); + // 调度器管理 + public static OperationScheduler CreatePackageScheduler(string packageName, uint priority); + public static void DestroyPackageScheduler(string packageName); + public static void ClearPackageOperations(string packageName); - /// - /// 异步等待完成(可选重写) - /// - protected virtual void OnWaitForAsyncComplete(); + // 任务管理 + public static void StartOperation(string packageName, AsyncOperationBase operation); +} +``` - /// - /// 异步操作系统是否繁忙 - /// - protected bool IsBusy(); +### OperationScheduler - /// - /// 终止异步操作 - /// - protected void Abort(); +包裹调度器,管理单个包裹的异步操作队列。 + +**主要功能:** +- 管理操作队列(待处理队列 + 执行队列) +- 按优先级排序操作 +- 更新和完成操作 + +```csharp +internal class OperationScheduler : IComparable +{ + public string PackageName { get; } // 所属包裹名称 + public uint Priority { get; set; } // 调度器优先级 + public int CreationOrder { get; } // 创建顺序(同优先级稳定排序) + + public void StartOperation(AsyncOperationBase operation); // 启动操作 + public void Update(); // 更新调度 + public void ClearAll(); // 清空并中止所有任务 } ``` --- -## 异步编程模式 +## 使用示例 -### 1. 协程模式(IEnumerator) +### 协程方式 ```csharp -IEnumerator LoadAsset() +IEnumerator LoadAssetCoroutine() { var operation = package.LoadAssetAsync("Assets/Prefab.prefab"); yield return operation; @@ -278,14 +226,19 @@ IEnumerator LoadAsset() if (operation.Status == EOperationStatus.Succeed) { GameObject prefab = operation.AssetObject as GameObject; + Instantiate(prefab); + } + else + { + Debug.LogError($"加载失败: {operation.Error}"); } } ``` -### 2. Task 模式(async/await) +### async/await 方式 ```csharp -async Task LoadAssetAsync() +async void LoadAssetAsync() { var operation = package.LoadAssetAsync("Assets/Prefab.prefab"); await operation.Task; @@ -293,14 +246,19 @@ async Task LoadAssetAsync() if (operation.Status == EOperationStatus.Succeed) { GameObject prefab = operation.AssetObject as GameObject; + Instantiate(prefab); + } + else + { + Debug.LogError($"加载失败: {operation.Error}"); } } ``` -### 3. 回调模式(Completed 事件) +### 回调方式 ```csharp -void LoadAsset() +void LoadAssetWithCallback() { var operation = package.LoadAssetAsync("Assets/Prefab.prefab"); operation.Completed += OnLoadCompleted; @@ -312,246 +270,47 @@ void OnLoadCompleted(AsyncOperationBase op) if (operation.Status == EOperationStatus.Succeed) { GameObject prefab = operation.AssetObject as GameObject; + Instantiate(prefab); + } + else + { + Debug.LogError($"加载失败: {operation.Error}"); } } ``` -### 4. 同步等待模式 +### 同步等待方式 ```csharp void LoadAssetSync() { var operation = package.LoadAssetAsync("Assets/Prefab.prefab"); - operation.WaitForAsyncComplete(); // 阻塞等待完成 + operation.WaitForAsyncComplete(); // 注意:会阻塞当前线程 if (operation.Status == EOperationStatus.Succeed) { GameObject prefab = operation.AssetObject as GameObject; + Instantiate(prefab); } } ``` ---- - -## 调度机制 - -### 优先级调度 - -操作按 `Priority` 属性降序排列,优先级高的操作先执行。 +### 设置优先级 ```csharp -var operation = package.LoadAssetAsync(location); -operation.Priority = 100; // 设置高优先级 +// 高优先级任务优先执行 +var highPriorityOp = package.LoadAssetAsync("ImportantAsset"); +highPriorityOp.Priority = 100; + +var lowPriorityOp = package.LoadAssetAsync("BackgroundAsset"); +lowPriorityOp.Priority = 1; ``` -**排序规则:** -- 新操作添加时检查是否需要排序 -- 仅当存在非零优先级时触发排序 -- 使用 `List.Sort()` 进行原地排序 - -### 时间切片 - -通过 `MaxTimeSlice` 控制每帧最大执行时间,防止主线程阻塞。 +### 配置时间切片 ```csharp -// 设置每帧最多执行 8 毫秒 -OperationSystem.MaxTimeSlice = 8; -``` - -**执行流程:** - -``` -每帧 Update() - │ - ├── 记录帧开始时间 _frameTime - │ - └── 遍历操作队列 - │ - ├── 检查 IsBusy(是否超时) - │ │ - │ └── 超时则中断本帧 - │ - └── 执行 operation.UpdateOperation() -``` - -### 操作生命周期 - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ 操作生命周期 │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. 创建操作 │ -│ └── Status = None │ -│ │ -│ 2. StartOperation() │ -│ ├── Status = Processing │ -│ ├── DebugBeginRecording() │ -│ ├── InternalStart() │ -│ └── 添加到 _newList │ -│ │ -│ 3. Update() - 每帧调度 │ -│ ├── 移除已完成操作 │ -│ ├── 合并 _newList 到 _operations │ -│ ├── 按优先级排序(如需要) │ -│ └── 遍历执行 UpdateOperation() │ -│ │ -│ 4. UpdateOperation() │ -│ ├── DebugUpdateRecording() │ -│ ├── InternalUpdate() │ -│ └── 检查 IsDone │ -│ │ │ -│ └── 完成时: │ -│ ├── IsFinish = true │ -│ ├── Progress = 1f │ -│ ├── DebugEndRecording() │ -│ ├── 触发 Completed 回调 │ -│ └── 设置 TaskCompletionSource │ -│ │ -│ 5. 下一帧移除完成的操作 │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - ---- - -## 调试支持 - -### 调试信息结构 - -```csharp -internal struct DebugOperationInfo -{ - public string OperationName; // 操作类型名 - public string OperationDesc; // 操作描述 - public uint Priority; // 优先级 - public float Progress; // 进度 - public string BeginTime; // 开始时间 - public long ProcessTime; // 处理耗时(毫秒) - public string Status; // 状态 - public List Childs; // 子操作 -} -``` - -### 获取调试信息 - -```csharp -// 获取指定包裹的所有操作信息 -var infos = OperationSystem.GetDebugOperationInfos("DefaultPackage"); - -foreach (var info in infos) -{ - Debug.Log($"{info.OperationName}: {info.Status}, {info.ProcessTime}ms"); -} -``` - -### 耗时统计 - -在 DEBUG 模式下自动统计操作耗时: - -```csharp -// 操作完成后可获取耗时 -Debug.Log($"开始时间: {operation.BeginTime}"); -Debug.Log($"处理耗时: {operation.ProcessTime}ms"); -``` - ---- - -## 使用示例 - -### 自定义异步操作 - -```csharp -public class MyCustomOperation : GameAsyncOperation -{ - private int _step = 0; - - protected override void OnStart() - { - // 初始化操作 - _step = 0; - } - - protected override void OnUpdate() - { - // 检查系统是否繁忙(时间切片) - if (IsBusy()) - return; - - // 执行步骤 - switch (_step) - { - case 0: - // 第一步 - Progress = 0.3f; - _step = 1; - break; - case 1: - // 第二步 - Progress = 0.6f; - _step = 2; - break; - case 2: - // 完成 - Status = EOperationStatus.Succeed; - break; - } - } - - protected override void OnAbort() - { - // 清理资源 - } -} -``` - -### 启动自定义操作 - -```csharp -var operation = new MyCustomOperation(); -OperationSystem.StartOperation("DefaultPackage", operation); - -// 使用回调 -operation.Completed += (op) => -{ - if (op.Status == EOperationStatus.Succeed) - Debug.Log("操作成功"); -}; - -// 或使用 await -await operation.Task; -``` - -### 带子任务的操作 - -```csharp -public class ParentOperation : GameAsyncOperation -{ - private ChildOperation _child; - - protected override void OnStart() - { - _child = new ChildOperation(); - AddChildOperation(_child); // 添加子任务 - OperationSystem.StartOperation(PackageName, _child); - } - - protected override void OnUpdate() - { - if (_child.IsDone) - { - if (_child.Status == EOperationStatus.Succeed) - Status = EOperationStatus.Succeed; - else - Status = EOperationStatus.Failed; - } - } - - protected override void OnAbort() - { - // 子任务会自动中止 - } -} +// 设置每帧最大执行时间为 10 毫秒 +OperationSystem.MaxTimeSlice = 10; ``` --- @@ -560,43 +319,63 @@ public class ParentOperation : GameAsyncOperation ### 模板方法模式 -`AsyncOperationBase` 定义算法骨架,子类实现具体步骤: +`AsyncOperationBase` 定义操作的骨架流程,子类实现具体步骤: ``` -AsyncOperationBase +AsyncOperationBase (抽象类) │ - ├── StartOperation() ──► InternalStart() [子类实现] - ├── UpdateOperation() ──► InternalUpdate() [子类实现] - ├── AbortOperation() ──► InternalAbort() [子类实现] - └── WaitForAsyncComplete() ──► InternalWaitForAsyncComplete() [子类实现] + ├── StartOperation() ──► InternalStart() [子类实现] + ├── UpdateOperation() ──► InternalUpdate() [子类实现] + ├── AbortOperation() ──► InternalAbort() [子类可选实现] + └── WaitForAsyncComplete() ──► InternalWaitForAsyncComplete() [子类可选实现] ``` ### 状态机模式 -操作状态由 `EOperationStatus` 管理: +操作生命周期通过状态机管理: ``` -┌──────┐ StartOperation() ┌────────────┐ UpdateOperation() ┌─────────┐ -│ None │ ─────────────────► │ Processing │ ──────────────────► │ Succeed │ -└──────┘ └────────────┘ └─────────┘ - │ - │ UpdateOperation() / AbortOperation() - ▼ - ┌──────────┐ - │ Failed │ - └──────────┘ +┌──────┐ StartOperation() ┌────────────┐ +│ None │ ────────────────────► │ Processing │ +└──────┘ └─────┬──────┘ + │ UpdateOperation() + ┌───────────────┼───────────────┐ + ▼ ▼ ▼ + ┌─────────┐ ┌──────────┐ ┌─────────┐ + │ Succeed │ │ Failed │ │ Aborted │ + └─────────┘ └──────────┘ └─────────┘ ``` ### 组合模式 -通过 `Childs` 列表支持父子操作关系: +支持父子任务关系,父任务可以管理多个子任务: ``` ParentOperation + │ ├── ChildOperation1 ├── ChildOperation2 └── ChildOperation3 - └── GrandChildOperation +``` + +### 时间切片模式 + +防止主线程阻塞,每帧限制执行时间: + +``` +每帧 Update() + │ + ├── 记录帧开始时间 + │ + ├── 遍历调度器(按优先级) + │ │ + │ ├── 遍历操作(按优先级) + │ │ │ + │ │ └── 检查 IsBusy ──► 超时则跳出 + │ │ + │ └── 检查 IsBusy ──► 超时则跳出 + │ + └── 结束 ``` --- @@ -604,32 +383,60 @@ ParentOperation ## 类继承关系 ``` -IEnumerator + IComparable - │ - ▼ - AsyncOperationBase (抽象基类) - │ - ├── GameAsyncOperation (游戏层基类) - │ │ - │ └── [业务层自定义操作] - │ - └── [YooAsset 内部操作] - │ - ├── InitializationOperation - ├── LoadAssetOperation - ├── LoadSceneOperation - ├── DownloadOperation - └── ... +AsyncOperationBase (抽象基类) + │ + ├── InitializePackageOperation (包裹初始化) + ├── LoadManifestOperation (清单加载) + ├── DownloaderOperation (下载器操作) + ├── UnloadAllAssetsOperation (卸载所有资源) + ├── DestroyPackageOperation (销毁包裹) + │ + ├── ProviderOperation (资源提供者基类) + │ ├── AssetProvider (单个资源) + │ ├── SubAssetsProvider (子资源) + │ ├── AllAssetsProvider (全部资源) + │ └── SceneProvider (场景) + │ + └── ... (更多子类) + +OperationScheduler + └── 管理 List + +OperationSystem + └── 管理 Dictionary ``` --- +## 调试信息 + +### 调试属性 + +在 DEBUG 模式下,`AsyncOperationBase` 提供以下调试信息: + +| 属性 | 类型 | 说明 | +|------|------|------| +| `StartTime` | `string` | 操作开始时间(格式:HH:MM:SS) | +| `ElapsedMS` | `long` | 操作耗时(毫秒) | + +### DiagnosticOperationInfo + +通过 `GetDebugOperationInfo()` 获取操作的诊断信息结构体,包含: + +- 操作名称、描述 +- 优先级、进度、状态 +- 开始时间、耗时 +- 子操作列表(递归) + +--- + ## 注意事项 -1. **主线程执行**:所有操作的调度和更新都在 Unity 主线程执行 -2. **时间切片**:设置合理的 `MaxTimeSlice` 避免卡顿(建议 8-16ms) -3. **同步等待**:`WaitForAsyncComplete()` 会阻塞主线程,谨慎使用 -4. **子任务中止**:父操作中止时会自动中止所有子操作 -5. **回调异常**:`Completed` 回调中的异常会被捕获并记录,不会中断系统 -6. **编辑器重置**:编辑器中使用 `RuntimeInitializeOnLoadMethod` 自动重置状态 -7. **循环保护**:`WaitForAsyncComplete()` 有 1000 帧上限,防止无限循环 +1. **主线程调用**:所有操作的创建和更新应在 Unity 主线程进行 +2. **同步等待风险**:`WaitForAsyncComplete()` 会阻塞当前线程,可能导致死锁,谨慎使用 +3. **优先级变更**:修改 `Priority` 后,下一帧才会重新排序 +4. **时间切片粒度**:时间切片检测在每个操作更新后进行,单个操作内部不会被中断 +5. **子任务中止**:调用 `AbortOperation()` 会递归中止所有子任务 +6. **回调异常隔离**:完成回调中的异常会被捕获并记录,不会影响其他回调 +7. **状态不可逆**:一旦进入终态(Succeed/Failed/Aborted),状态不可更改 +8. **Progress 语义**:`Progress` 在操作完成时自动设置为 1.0f,子类应在处理过程中更新进度 diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeHelper.cs b/Assets/YooAsset/Runtime/PackageInvokeBuilder/EditorSimulateBuildInvoker.cs similarity index 79% rename from Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeHelper.cs rename to Assets/YooAsset/Runtime/PackageInvokeBuilder/EditorSimulateBuildInvoker.cs index 96e93389..d396ab48 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeHelper.cs +++ b/Assets/YooAsset/Runtime/PackageInvokeBuilder/EditorSimulateBuildInvoker.cs @@ -1,9 +1,9 @@  namespace YooAsset { - public class EditorSimulateModeHelper + public class EditorSimulateBuildInvoker { - public static PackageInvokeBuildResult SimulateBuild(string packageName) + public static PackageInvokeBuildResult Build(string packageName) { var buildParam = new PackageInvokeBuildParam(packageName); buildParam.BuildPipelineName = "EditorSimulateBuildPipeline"; diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeHelper.cs.meta b/Assets/YooAsset/Runtime/PackageInvokeBuilder/EditorSimulateBuildInvoker.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeHelper.cs.meta rename to Assets/YooAsset/Runtime/PackageInvokeBuilder/EditorSimulateBuildInvoker.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourceManager/DownloadStatus.cs b/Assets/YooAsset/Runtime/ResourceManager/DownloadStatus.cs index 038503c1..4443c838 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/DownloadStatus.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/DownloadStatus.cs @@ -6,22 +6,22 @@ namespace YooAsset /// /// 下载是否已经完成 /// - public bool IsDone; + public bool IsDone { get; set; } /// /// 下载进度(0-1f) /// - public float Progress; + public float Progress { get; set; } /// /// 下载文件的总大小 /// - public long TotalBytes; + public long TotalBytes { get; set; } /// /// 已经下载的文件大小 /// - public long DownloadedBytes; + public long DownloadedBytes { get; set; } public static DownloadStatus CreateDefaultStatus() { diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handle/AssetHandle.cs b/Assets/YooAsset/Runtime/ResourceManager/Handle/AssetHandle.cs index 5514d09a..c6f443a8 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handle/AssetHandle.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handle/AssetHandle.cs @@ -76,62 +76,48 @@ namespace YooAsset /// public GameObject InstantiateSync() { - return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, null, false); + var options = new InstantiateOptions(true); + return InstantiateSyncInternal(options); } - public GameObject InstantiateSync(Transform parent) + + /// + /// 同步初始化游戏对象 + /// + public GameObject InstantiateSync(InstantiateOptions options) { - return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, parent, false); - } - public GameObject InstantiateSync(Transform parent, bool worldPositionStays) - { - return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, parent, worldPositionStays); - } - public GameObject InstantiateSync(Vector3 position, Quaternion rotation) - { - return InstantiateSyncInternal(true, position, rotation, null, false); - } - public GameObject InstantiateSync(Vector3 position, Quaternion rotation, Transform parent) - { - return InstantiateSyncInternal(true, position, rotation, parent, false); + return InstantiateSyncInternal(options); } /// /// 异步初始化游戏对象 /// - public InstantiateOperation InstantiateAsync(bool actived = true) + public InstantiateOperation InstantiateAsync() { - return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, null, false, actived); - } - public InstantiateOperation InstantiateAsync(Transform parent, bool actived = true) - { - return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, parent, false, actived); - } - public InstantiateOperation InstantiateAsync(Transform parent, bool worldPositionStays, bool actived = true) - { - return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, parent, worldPositionStays, actived); - } - public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation, bool actived = true) - { - return InstantiateAsyncInternal(true, position, rotation, null, false, actived); - } - public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation, Transform parent, bool actived = true) - { - return InstantiateAsyncInternal(true, position, rotation, parent, false, actived); + var options = new InstantiateOptions(true); + return InstantiateAsyncInternal(options); } - private GameObject InstantiateSyncInternal(bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) + /// + /// 异步初始化游戏对象 + /// + public InstantiateOperation InstantiateAsync(InstantiateOptions options) + { + return InstantiateAsyncInternal(options); + } + + private GameObject InstantiateSyncInternal(InstantiateOptions options) { if (IsValidWithWarning == false) return null; if (Provider.AssetObject == null) return null; - return InstantiateOperation.InstantiateInternal(Provider.AssetObject, setPositionAndRotation, position, rotation, parent, worldPositionStays); + return InstantiateOperation.InstantiateInternal(Provider.AssetObject, options); } - private InstantiateOperation InstantiateAsyncInternal(bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays, bool actived) + private InstantiateOperation InstantiateAsyncInternal(InstantiateOptions options) { string packageName = GetAssetInfo().PackageName; - InstantiateOperation operation = new InstantiateOperation(this, setPositionAndRotation, position, rotation, parent, worldPositionStays, actived); + InstantiateOperation operation = new InstantiateOperation(this, options); OperationSystem.StartOperation(packageName, operation); return operation; } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handle/RawFileHandle.cs b/Assets/YooAsset/Runtime/ResourceManager/Handle/RawFileHandle.cs index ebf85eda..3936d174 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handle/RawFileHandle.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handle/RawFileHandle.cs @@ -45,27 +45,6 @@ namespace YooAsset Provider.WaitForAsyncComplete(); } - - /// - /// 获取原生文件的二进制数据 - /// - public byte[] GetRawFileData() - { - if (IsValidWithWarning == false) - return null; - return Provider.BundleResultObject.ReadBundleFileData(); - } - - /// - /// 获取原生文件的文本数据 - /// - public string GetRawFileText() - { - if (IsValidWithWarning == false) - return null; - return Provider.BundleResultObject.ReadBundleFileText(); - } - /// /// 获取原生文件的路径 /// @@ -73,7 +52,7 @@ namespace YooAsset { if (IsValidWithWarning == false) return string.Empty; - return Provider.BundleResultObject.GetBundleFilePath(); + return Provider.LoadedBundleResult.GetBundleFilePath(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs b/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs index 36f18904..593d004f 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs @@ -56,7 +56,7 @@ namespace YooAsset { if (IsValidWithWarning == false) return string.Empty; - return Provider.SceneName; + return Provider.LoadedSceneName; } } @@ -116,7 +116,7 @@ namespace YooAsset /// 异步卸载场景对象 /// 注意:场景卸载成功后,会自动释放该handle的引用计数! /// - public UnloadSceneOperation UnloadAsync() + public UnloadSceneOperation UnloadSceneAsync() { string packageName = GetAssetInfo().PackageName; diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs index ef4f32fc..14214c89 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs @@ -14,12 +14,7 @@ namespace YooAsset } private readonly AssetHandle _handle; - private readonly bool _setPositionAndRotation; - private readonly Vector3 _position; - private readonly Quaternion _rotation; - private readonly Transform _parent; - private readonly bool _worldPositionStays; - private readonly bool _actived; + private readonly InstantiateOptions _options; private ESteps _steps = ESteps.None; #if UNITY_2023_3_OR_NEWER @@ -32,16 +27,10 @@ namespace YooAsset public GameObject Result = null; - internal InstantiateOperation(AssetHandle handle, bool setPositionAndRotation, Vector3 position, Quaternion rotation, - Transform parent, bool worldPositionStays, bool actived) + internal InstantiateOperation(AssetHandle handle, InstantiateOptions options) { _handle = handle; - _setPositionAndRotation = setPositionAndRotation; - _position = position; - _rotation = rotation; - _parent = parent; - _worldPositionStays = worldPositionStays; - _actived = actived; + _options = options; } internal override void InternalStart() { @@ -62,6 +51,9 @@ namespace YooAsset return; } + if (IsWaitingForAsyncComplete) + _handle.WaitForAsyncComplete(); + if (_handle.IsDone == false) return; @@ -87,8 +79,8 @@ namespace YooAsset if (_steps == ESteps.CloneSync) { // 实例化游戏对象 - Result = InstantiateInternal(_handle.AssetObject, _setPositionAndRotation, _position, _rotation, _parent, _worldPositionStays); - if (_actived == false) + Result = InstantiateInternal(_handle.AssetObject, _options); + if (_options.Actived == false) Result.SetActive(false); _steps = ESteps.Done; @@ -100,10 +92,10 @@ namespace YooAsset { if (_instantiateAsync == null) { - _instantiateAsync = InstantiateAsyncInternal(_handle.AssetObject, _setPositionAndRotation, _position, _rotation, _parent, _worldPositionStays); + _instantiateAsync = InstantiateAsyncInternal(_handle.AssetObject, _options); } - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _instantiateAsync.WaitForCompletion(); if (_instantiateAsync.isDone == false) @@ -114,7 +106,7 @@ namespace YooAsset Result = _instantiateAsync.Result[0] as GameObject; if (Result != null) { - if (_actived == false) + if (_options.Actived == false) Result.SetActive(false); _steps = ESteps.Done; @@ -124,34 +116,23 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Instantiate game object is null !"; + Error = $"Instantiate game object is null."; } } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Instantiate async results is null !"; + Error = $"Instantiate async results is null."; } } #endif } internal override void InternalWaitForAsyncComplete() { - while (true) - { - // 等待句柄完成 - if (_handle != null) - _handle.WaitForAsyncComplete(); - - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { var assetInfo = _handle.GetAssetInfo(); return $"AssetPath : {assetInfo.AssetPath}"; @@ -173,22 +154,22 @@ namespace YooAsset /// /// 同步实例化 /// - internal static GameObject InstantiateInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) + internal static GameObject InstantiateInternal(UnityEngine.Object assetObject, InstantiateOptions options) { if (assetObject == null) return null; - if (setPositionAndRotation) + if (options.SetPositionAndRotation) { - if (parent != null) - return UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation, parent); + if (options.Parent != null) + return UnityEngine.Object.Instantiate(assetObject as GameObject, options.Position, options.Rotation, options.Parent); else - return UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation); + return UnityEngine.Object.Instantiate(assetObject as GameObject, options.Position, options.Rotation); } else { - if (parent != null) - return UnityEngine.Object.Instantiate(assetObject as GameObject, parent, worldPositionStays); + if (options.Parent != null) + return UnityEngine.Object.Instantiate(assetObject as GameObject, options.Parent, options.InWorldSpace); else return UnityEngine.Object.Instantiate(assetObject as GameObject); } @@ -200,19 +181,19 @@ namespace YooAsset /// 注意:Unity2022.3.20f1及以上版本生效 /// https://docs.unity3d.com/2022.3/Documentation/ScriptReference/Object.InstantiateAsync.html /// - internal static AsyncInstantiateOperation InstantiateAsyncInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) + internal static AsyncInstantiateOperation InstantiateAsyncInternal(UnityEngine.Object assetObject, InstantiateOptions options) { - if (setPositionAndRotation) + if (options.SetPositionAndRotation) { - if (parent != null) - return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, parent, position, rotation); + if (options.Parent != null) + return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, options.Parent, options.Position, options.Rotation); else - return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, position, rotation); + return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, options.Position, options.Rotation); } else { - if (parent != null) - return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, parent); + if (options.Parent != null) + return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, options.Parent); else return UnityEngine.Object.InstantiateAsync(assetObject as GameObject); } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOptions.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOptions.cs new file mode 100644 index 00000000..6cef708d --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOptions.cs @@ -0,0 +1,77 @@ +using UnityEngine; + +namespace YooAsset +{ + public struct InstantiateOptions + { + /// + /// 是否激活实例化对象 + /// + public bool Actived { private set; get; } + + /// + /// 将指定给新对象的父对象 + /// + public Transform Parent { private set; get; } + + /// + /// 分配父对象时, 定位新对象关系。 + /// true 在世界空间中定位新对象。 + /// false 相对于父对象来设置新对象。 + /// + public bool InWorldSpace { private set; get; } + + /// + /// 新对象的位置 + /// + public Vector3 Position { private set; get; } + + /// + /// 新对象的方向 + /// + public Quaternion Rotation { private set; get; } + + internal bool SetPositionAndRotation { private set; get; } + + public InstantiateOptions(bool actived) + { + Actived = actived; + Parent = null; + InWorldSpace = false; + + SetPositionAndRotation = false; + Position = Vector3.zero; + Rotation = Quaternion.identity; + } + public InstantiateOptions(bool actived, Transform parent, bool inWorldSpace) + { + Actived = actived; + Parent = parent; + InWorldSpace = inWorldSpace; + + SetPositionAndRotation = false; + Position = Vector3.zero; + Rotation = Quaternion.identity; + } + public InstantiateOptions(bool actived, Transform parent, Vector3 position, Quaternion rotation) + { + Actived = actived; + Parent = parent; + InWorldSpace = false; + + SetPositionAndRotation = true; + Position = position; + Rotation = rotation; + } + public InstantiateOptions(bool actived, Vector3 position, Quaternion rotation) + { + Actived = actived; + Parent = null; + InWorldSpace = false; + + SetPositionAndRotation = true; + Position = position; + Rotation = rotation; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOptions.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOptions.cs.meta new file mode 100644 index 00000000..7c74d45c --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7432581e3bde71648adef94499c7a398 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/Internal/LoadBundleFileOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/Internal/LoadBundleOperation.cs similarity index 90% rename from Assets/YooAsset/Runtime/ResourceManager/Operation/Internal/LoadBundleFileOperation.cs rename to Assets/YooAsset/Runtime/ResourceManager/Operation/Internal/LoadBundleOperation.cs index 4db2dd11..8224d31e 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/Internal/LoadBundleFileOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/Internal/LoadBundleOperation.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; namespace YooAsset { - internal class LoadBundleFileOperation : AsyncOperationBase + internal class LoadBundleOperation : AsyncOperationBase { private enum ESteps { @@ -51,7 +51,7 @@ namespace YooAsset public BundleResult Result { set; get; } - internal LoadBundleFileOperation(ResourceManager resourceManager, BundleInfo bundleInfo) + internal LoadBundleOperation(ResourceManager resourceManager, BundleInfo bundleInfo) { _resManager = resourceManager; LoadBundleInfo = bundleInfo; @@ -67,7 +67,7 @@ namespace YooAsset if (_steps == ESteps.CheckConcurrency) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { _steps = ESteps.LoadBundleFile; } @@ -84,13 +84,13 @@ namespace YooAsset if (_loadBundleOp == null) { // 统计计数增加 - _resManager.BundleLoadingCounter++; - _loadBundleOp = LoadBundleInfo.LoadBundleFile(); + _resManager.IncrementBundleLoadingCounter(); + _loadBundleOp = LoadBundleInfo.CreateBundleLoader(); _loadBundleOp.StartOperation(); AddChildOperation(_loadBundleOp); } - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _loadBundleOp.WaitForAsyncComplete(); _loadBundleOp.UpdateOperation(); @@ -105,7 +105,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"The bundle loader result is null ! {LoadBundleInfo.Bundle.BundleName}"; + Error = $"The bundle loader result is null. Bundle: {LoadBundleInfo.Bundle.BundleName}"; } else { @@ -122,21 +122,14 @@ namespace YooAsset } // 统计计数减少 - _resManager.BundleLoadingCounter--; + _resManager.DecrementBundleLoadingCounter(); } } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { return $"BundleName : {LoadBundleInfo.Bundle.BundleName}"; } @@ -178,7 +171,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Bundle loader destroyed !"; + Error = "Bundle loader destroyed."; } } @@ -275,7 +268,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Abort bundle loader !"; + Error = "Bundle loader aborted."; } if (_steps == ESteps.LoadBundleFile) diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/Internal/LoadBundleFileOperation.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Operation/Internal/LoadBundleOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourceManager/Operation/Internal/LoadBundleFileOperation.cs.meta rename to Assets/YooAsset/Runtime/ResourceManager/Operation/Internal/LoadBundleOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs index c5033d92..4d04f73a 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs @@ -3,19 +3,6 @@ using UnityEngine; namespace YooAsset { - public sealed class UnloadAllAssetsOptions - { - /// - /// 释放所有资源句柄,防止卸载过程中触发完成回调! - /// - public bool ReleaseAllHandles = false; - - /// - /// 卸载过程中锁定加载操作,防止新的任务请求! - /// - public bool LockLoadOperation = false; - } - public sealed class UnloadAllAssetsOperation : AsyncOperationBase { private enum ESteps @@ -49,14 +36,6 @@ namespace YooAsset if (_steps == ESteps.CheckOptions) { - if (_options == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"{nameof(UnloadAllAssetsOptions)} is null."; - return; - } - // 设置锁定状态 if (_options.LockLoadOperation) _resManager.LockLoadOperation = true; diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOptions.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOptions.cs new file mode 100644 index 00000000..23272d1b --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOptions.cs @@ -0,0 +1,22 @@ + +namespace YooAsset +{ + public struct UnloadAllAssetsOptions + { + /// + /// 释放所有资源句柄,防止卸载过程中触发完成回调! + /// + public bool ReleaseAllHandles { set; get; } + + /// + /// 卸载过程中锁定加载操作,防止新的任务请求! + /// + public bool LockLoadOperation { set; get; } + + public UnloadAllAssetsOptions(bool releaseAllHandles, bool lockLoadOperation) + { + ReleaseAllHandles = releaseAllHandles; + LockLoadOperation = lockLoadOperation; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOptions.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOptions.cs.meta new file mode 100644 index 00000000..f16bc5d0 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc733fff9ba8d5747b556fb6cdb2b9e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs index d82ec50f..fa982a8d 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs @@ -73,7 +73,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Scene is invalid !"; + Error = "Scene is invalid."; return; } @@ -81,7 +81,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Scene is not loaded !"; + Error = "Scene is not loaded."; return; } @@ -97,7 +97,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Unload scene failed, see the console logs !"; + Error = "Unload scene failed, see the console logs."; return; } } @@ -110,9 +110,9 @@ namespace YooAsset Status = EOperationStatus.Succeed; } } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { - return $"SceneName : {_provider.SceneName}"; + return $"SceneName : {_provider.LoadedSceneName}"; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs index 9aa01a4a..da990766 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs @@ -1,6 +1,5 @@ using System.Collections; using System.Collections.Generic; -using UnityEngine; namespace YooAsset { @@ -14,19 +13,19 @@ namespace YooAsset } private readonly ResourceManager _resManager; - private readonly int _loopCount; + private readonly UnloadUnusedAssetsOptions _options; private int _loopCounter = 0; private ESteps _steps = ESteps.None; - internal UnloadUnusedAssetsOperation(ResourceManager resourceManager, int loopCount) + internal UnloadUnusedAssetsOperation(ResourceManager resourceManager, UnloadUnusedAssetsOptions options) { _resManager = resourceManager; - _loopCount = loopCount; + _options = options; } internal override void InternalStart() { _steps = ESteps.UnloadUnused; - _loopCounter = _loopCount; + _loopCounter = _options.LoopCount; } internal override void InternalUpdate() { @@ -53,18 +52,11 @@ namespace YooAsset } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { - return $"LoopCount : {_loopCount}"; + return $"LoopCount : {_options.LoopCount}"; } /// @@ -72,7 +64,7 @@ namespace YooAsset /// private void LoopUnloadUnused() { - var removeList = new List(_resManager.LoaderDic.Count); + var removeList = new List(_resManager.LoaderDic.Count); // 注意:优先销毁资源提供者 foreach (var loader in _resManager.LoaderDic.Values) diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOptions.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOptions.cs new file mode 100644 index 00000000..4e2839c3 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOptions.cs @@ -0,0 +1,16 @@ + +namespace YooAsset +{ + public struct UnloadUnusedAssetsOptions + { + /// + /// 循环迭代次数 + /// + public int LoopCount { set; get; } + + public UnloadUnusedAssetsOptions(int loopCount) + { + LoopCount = loopCount; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOptions.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOptions.cs.meta new file mode 100644 index 00000000..4d7901b0 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 33a033398461486429728fc87b8b9840 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/AllAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/AllAssetsProvider.cs index d15aedad..2237d955 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/AllAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/AllAssetsProvider.cs @@ -12,7 +12,7 @@ namespace YooAsset { if (_loadAllAssetsOp == null) { - _loadAllAssetsOp = BundleResultObject.LoadAllAssetsAsync(MainAssetInfo); + _loadAllAssetsOp = LoadedBundleResult.LoadAllAssetsAsync(MainAssetInfo); _loadAllAssetsOp.StartOperation(); AddChildOperation(_loadAllAssetsOp); @@ -22,7 +22,7 @@ namespace YooAsset #endif } - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _loadAllAssetsOp.WaitForAsyncComplete(); _loadAllAssetsOp.UpdateOperation(); diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/AssetProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/AssetProvider.cs index 58391713..af1e21d4 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/AssetProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/AssetProvider.cs @@ -12,7 +12,7 @@ namespace YooAsset { if (_loadAssetOp == null) { - _loadAssetOp = BundleResultObject.LoadAssetAsync(MainAssetInfo); + _loadAssetOp = LoadedBundleResult.LoadAssetAsync(MainAssetInfo); _loadAssetOp.StartOperation(); AddChildOperation(_loadAssetOp); @@ -22,7 +22,7 @@ namespace YooAsset #endif } - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _loadAssetOp.WaitForAsyncComplete(); _loadAssetOp.UpdateOperation(); diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs index 719ea425..e7109ed8 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs @@ -48,14 +48,14 @@ namespace YooAsset public UnityEngine.SceneManagement.Scene SceneObject { protected set; get; } /// - /// 获取的资源包对象 + /// 加载的资源包结果 /// - public BundleResult BundleResultObject { protected set; get; } + public BundleResult LoadedBundleResult { protected set; get; } /// /// 加载的场景名称 /// - public string SceneName { protected set; get; } + public string LoadedSceneName { protected set; get; } /// /// 引用计数 @@ -80,8 +80,8 @@ namespace YooAsset private ESteps _steps = ESteps.None; protected readonly ResourceManager _resManager; - private readonly LoadBundleFileOperation _mainBundleLoader; - private readonly List _bundleLoaders = new List(10); + 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) @@ -137,7 +137,7 @@ namespace YooAsset if (_steps == ESteps.WaitBundleLoader) { - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) { foreach (var bundleLoader in _bundleLoaders) { @@ -165,10 +165,10 @@ namespace YooAsset } // 检测加载结果 - BundleResultObject = _mainBundleLoader.Result; - if (BundleResultObject == null) + LoadedBundleResult = _mainBundleLoader.Result; + if (LoadedBundleResult == null) { - string error = $"Loaded bundle result is null !"; + string error = $"Loaded bundle result is null."; InvokeCompletion(error, EOperationStatus.Failed); return; } @@ -183,16 +183,9 @@ namespace YooAsset } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { return $"AssetPath : {MainAssetInfo.AssetPath}"; } @@ -334,12 +327,12 @@ namespace YooAsset /// /// 出生的场景 /// - public string SpawnScene = string.Empty; + public string OriginScene = string.Empty; [Conditional("DEBUG")] public void InitProviderDebugInfo() { - SpawnScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; + OriginScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; } /// diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/SceneProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/SceneProvider.cs index 0950b233..bff838a2 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/SceneProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/SceneProvider.cs @@ -16,18 +16,18 @@ namespace YooAsset { _loadParams = loadParams; _suspendLoad = suspendLoad; - SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath); + LoadedSceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath); } protected override void ProcessBundleResult() { if (_loadSceneOp == null) { - _loadSceneOp = BundleResultObject.LoadSceneOperation(MainAssetInfo, _loadParams, _suspendLoad); + _loadSceneOp = LoadedBundleResult.LoadSceneOperation(MainAssetInfo, _loadParams, _suspendLoad); _loadSceneOp.StartOperation(); AddChildOperation(_loadSceneOp); } - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _loadSceneOp.WaitForAsyncComplete(); // 注意:场景加载中途可以取消挂起 diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/SubAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/SubAssetsProvider.cs index 4e2223c9..ccc7d6b7 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/SubAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/SubAssetsProvider.cs @@ -12,7 +12,7 @@ namespace YooAsset { if (_loadSubAssetsOp == null) { - _loadSubAssetsOp = BundleResultObject.LoadSubAssetsAsync(MainAssetInfo); + _loadSubAssetsOp = LoadedBundleResult.LoadSubAssetsAsync(MainAssetInfo); _loadSubAssetsOp.StartOperation(); AddChildOperation(_loadSubAssetsOp); @@ -22,7 +22,7 @@ namespace YooAsset #endif } - if (IsWaitForAsyncComplete) + if (IsWaitingForAsyncComplete) _loadSubAssetsOp.WaitForAsyncComplete(); _loadSubAssetsOp.UpdateOperation(); diff --git a/Assets/YooAsset/Runtime/ResourceManager/README.md b/Assets/YooAsset/Runtime/ResourceManager/README.md deleted file mode 100644 index 28fb9407..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/README.md +++ /dev/null @@ -1,1269 +0,0 @@ -# ResourceManager 资源管理器 - -## 模块概述 - -ResourceManager 是 YooAsset 资源管理系统的**核心执行层**,负责资源加载的实际执行和生命周期管理。该模块通过 Provider 模式实现资源加载抽象,通过 Handle 模式提供面向用户的类型安全访问接口。 - -### 核心特性 - -- **Provider 抽象**:统一的资源加载操作模式,支持复用机制 -- **Handle 封装**:类型安全的用户访问接口,支持协程和 async/await -- **引用计数**:精确的资源生命周期追踪,自动卸载未使用资源 -- **并发控制**:可配置的 Bundle 加载并发限制,避免系统过载 - -### 模块统计 - -| 子模块 | 职责 | -|--------|------| -| 核心 | ResourceManager + DownloadStatus | -| Handle 系统 | 面向用户的资源句柄 | -| Provider 系统 | 资源加载执行器 | -| Operation 系统 | 异步操作集合 | -| **总计** | 完整资源管理系统 | - ---- - -## 设计目标 - -| 目标 | 说明 | -|------|------| -| **统一加载接口** | 通过 Provider 模式抽象不同类型资源的加载逻辑 | -| **类型安全访问** | Handle 模式封装资源访问,提供编译时类型检查 | -| **资源生命周期** | 引用计数精确追踪,支持自动和手动卸载 | -| **并发流量控制** | 可配置的 Bundle 加载并发数,平衡性能与稳定性 | -| **Provider 复用** | 相同资源的多次加载共享同一个 Provider | - ---- - -## 文件结构 - -``` -ResourceManager/ -├── ResourceManager.cs # 主管理类 -├── DownloadStatus.cs # 下载状态结构体 -├── Handle/ # 句柄系统 -│ ├── HandleBase.cs # 句柄基类 -│ ├── HandleFactory.cs # 句柄工厂 -│ ├── AssetHandle.cs # 资源句柄 -│ ├── SceneHandle.cs # 场景句柄 -│ ├── SubAssetsHandle.cs # 子资源句柄 -│ ├── AllAssetsHandle.cs # 全部资源句柄 -│ └── RawFileHandle.cs # 原生文件句柄 -├── Provider/ # 提供者系统 -│ ├── ProviderOperation.cs # 提供者基类 -│ ├── AssetProvider.cs # 资源提供者 -│ ├── SceneProvider.cs # 场景提供者 -│ ├── SubAssetsProvider.cs # 子资源提供者 -│ ├── AllAssetsProvider.cs # 全部资源提供者 -│ ├── RawFileProvider.cs # 原生文件提供者 -│ └── CompletedProvider.cs # 完成提供者(错误快速返回) -└── Operation/ # 操作系统 - ├── Internal/ - │ └── LoadBundleFileOperation.cs # Bundle 加载操作 - ├── InstantiateOperation.cs # 实例化操作 - ├── UnloadSceneOperation.cs # 场景卸载操作 - ├── UnloadAllAssetsOperation.cs # 全部资源卸载操作 - └── UnloadUnusedAssetsOperation.cs # 未使用资源卸载操作 -``` - ---- - -## 核心类说明 - -### ResourceManager - -资源管理器主类,作为资源加载操作的中央枢纽。 - -```csharp -internal class ResourceManager -{ - // 核心数据结构 - internal readonly Dictionary ProviderDic; // 容量 5000 - internal readonly Dictionary LoaderDic; // 容量 5000 - internal readonly List SceneHandles; // 容量 100 - - // 配置属性 - public bool AutoUnloadBundleWhenUnused { get; } // 自动卸载未使用的 Bundle - public bool WebGLForceSyncLoadAsset { get; } // WebGL 强制同步加载 - public bool LockLoadOperation { get; set; } // 加载操作锁定 - public int BundleLoadingMaxConcurrency { get; } // Bundle 并发加载数量 (默认32,范围1-256) - public int BundleLoadingCounter { get; set; } // 正在加载的 Bundle 计数 -} -``` - -#### 初始化和销毁 - -```csharp -public void Initialize(InitializeParameters parameters, IBundleQuery bundleServices) -{ - _bundleLoadingMaxConcurrency = parameters.BundleLoadingMaxConcurrency; - AutoUnloadBundleWhenUnused = parameters.AutoUnloadBundleWhenUnused; - WebGLForceSyncLoadAsset = parameters.WebGLForceSyncLoadAsset; - _bundleQuery = bundleServices; - SceneManager.sceneUnloaded += OnSceneUnloaded; -} - -public void Destroy() -{ - SceneManager.sceneUnloaded -= OnSceneUnloaded; -} -``` - -#### 核心加载 API - -| 方法 | 返回类型 | 说明 | -|------|----------|------| -| `LoadAssetAsync()` | `AssetHandle` | 加载单个资源 | -| `LoadSceneAsync()` | `SceneHandle` | 加载场景 | -| `LoadSubAssetsAsync()` | `SubAssetsHandle` | 加载子资源 | -| `LoadAllAssetsAsync()` | `AllAssetsHandle` | 加载所有资源 | -| `LoadRawFileAsync()` | `RawFileHandle` | 加载原生文件 | - -#### Bundle 加载器管理 - -```csharp -// 创建主 Bundle 加载器 -internal LoadBundleFileOperation CreateMainBundleFileLoader(AssetInfo assetInfo) - -// 创建依赖 Bundle 加载器列表 -internal List CreateDependBundleFileLoaders(AssetInfo assetInfo) - -// 检查是否繁忙 -public bool BundleLoadingIsBusy() -{ - return BundleLoadingCounter >= _bundleLoadingMaxConcurrency; -} -``` - -### DownloadStatus - -下载状态结构体,用于追踪资源下载进度。 - -```csharp -public struct DownloadStatus -{ - public long DownloadedBytes; // 已下载字节数 - public long TotalBytes; // 总字节数 - public float Progress; // 下载进度 (0-1) - - public static DownloadStatus CreateDefaultStatus() - { - return new DownloadStatus - { - DownloadedBytes = 0, - TotalBytes = 0, - Progress = 1f - }; - } -} -``` - ---- - -## Provider 系统 - -Provider 系统负责资源加载的实际执行,每种资源类型都有对应的 Provider 实现。 - -### ProviderOperation(基类) - -所有资源提供者的抽象基类,继承自 `AsyncOperationBase`。 - -#### 状态机 - -``` -None → StartBundleLoader → WaitBundleLoader → ProcessBundleResult → Done -``` - -```csharp -protected enum ESteps -{ - None = 0, - StartBundleLoader, // 启动所有 Bundle 加载器 - WaitBundleLoader, // 等待 Bundle 加载完成 - ProcessBundleResult, // 处理 Bundle 结果(子类实现) - Done, // 完成 -} -``` - -#### 核心属性 - -```csharp -public abstract class ProviderOperation : AsyncOperationBase -{ - public string ProviderGUID { get; } // 唯一标识符 - public AssetInfo MainAssetInfo { get; } // 资源信息 - public UnityEngine.Object AssetObject { get; } // 单个资源对象 - public UnityEngine.Object[] AllAssetObjects { get; } // 全部资源对象数组 - public UnityEngine.Object[] SubAssetObjects { get; } // 子资源对象数组 - public Scene SceneObject { get; } // 场景对象 - public BundleResult BundleResultObject { get; } // Bundle 结果 - public int RefCount { get; } // 引用计数 - public bool IsDestroyed { get; } // 销毁标志 - public string SceneName { get; } // 场景名称 -} -``` - -#### 引用计数管理 - -```csharp -// 创建句柄(引用计数 +1) -public T CreateHandle() where T : HandleBase -{ - RefCount++; - HandleBase handle = HandleFactory.CreateHandle(this, typeof(T)); - _handles.Add(handle); - return handle as T; -} - -// 释放句柄(引用计数 -1) -public void ReleaseHandle(HandleBase handle) -{ - if (RefCount <= 0) - throw new YooInternalException(...); - - if (_handles.Remove(handle) == false) - throw new YooInternalException(...); - - RefCount--; -} - -// 检查是否可销毁 -public bool CanDestroyProvider() -{ - // 注意:正在加载中的任务不可以销毁 - if (IsLoading) return false; - return RefCount <= 0; -} -``` - -#### 核心执行流程 - -```csharp -internal override void InternalUpdate() -{ - if (_steps == ESteps.StartBundleLoader) - { - // 启动主 Bundle 加载器和所有依赖 Bundle 加载器 - foreach (var bundleLoader in _bundleLoaders) - { - bundleLoader.StartOperation(); - AddChildOperation(bundleLoader); - } - _steps = ESteps.WaitBundleLoader; - } - - if (_steps == ESteps.WaitBundleLoader) - { - // 等待所有 Bundle 加载完成并验证成功 - foreach (var bundleLoader in _bundleLoaders) - { - if (bundleLoader.IsDone == false) return; - if (bundleLoader.Status != EOperationStatus.Succeed) - { - InvokeCompletion(error, EOperationStatus.Failed); - return; - } - } - _steps = ESteps.ProcessBundleResult; - } - - if (_steps == ESteps.ProcessBundleResult) - { - // 子类实现的核心加载逻辑 - ProcessBundleResult(); - } -} -``` - -### Provider 子类 - -| 类型 | 职责 | 结果属性 | 说明 | -|------|------|----------|------| -| `AssetProvider` | 加载单个资源 | `AssetObject` | 最常用的加载方式 | -| `SceneProvider` | 加载场景 | `SceneObject` | 支持挂起加载 | -| `SubAssetsProvider` | 加载子资源 | `SubAssetObjects` | 用于图集、精灵等 | -| `AllAssetsProvider` | 加载所有资源 | `AllAssetObjects` | 加载 Bundle 内所有资源 | -| `RawFileProvider` | 加载原生文件 | `BundleResultObject` | 配置文件、二进制数据等 | -| `CompletedProvider` | 错误快速返回 | - | 用于无效请求的快速失败 | - -#### AssetProvider 示例 - -```csharp -internal class AssetProvider : ProviderOperation -{ - private FSLoadAssetOperation _loadAssetOp; - - protected override void ProcessBundleResult() - { - if (_loadAssetOp == null) - { - _loadAssetOp = BundleResultObject.LoadAssetAsync(MainAssetInfo); - _loadAssetOp.StartOperation(); - AddChildOperation(_loadAssetOp); - -#if UNITY_WEBGL - if (_resManager.WebGLForceSyncLoadAsset) - _loadAssetOp.WaitForAsyncComplete(); -#endif - } - - _loadAssetOp.UpdateOperation(); - Progress = _loadAssetOp.Progress; - - if (_loadAssetOp.IsDone == false) return; - - if (_loadAssetOp.Status != EOperationStatus.Succeed) - InvokeCompletion(_loadAssetOp.Error, EOperationStatus.Failed); - else - { - AssetObject = _loadAssetOp.Result; - InvokeCompletion(string.Empty, EOperationStatus.Succeed); - } - } -} -``` - -#### SceneProvider 示例 - -```csharp -internal class SceneProvider : ProviderOperation -{ - private LoadSceneParameters _loadParams; - private bool _suspendLoad; - - public SceneProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo, - LoadSceneParameters loadParams, bool suspendLoad) - : base(manager, providerGUID, assetInfo) - { - _loadParams = loadParams; - _suspendLoad = suspendLoad; - SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath); - } - - // 取消挂起加载 - public void UnSuspendLoad() - { - _suspendLoad = false; - } - - protected override void ProcessBundleResult() - { - if (_loadSceneOp == null) - { - _loadSceneOp = BundleResultObject.LoadSceneOperation( - MainAssetInfo, _loadParams, _suspendLoad); - _loadSceneOp.StartOperation(); - AddChildOperation(_loadSceneOp); - } - - // 支持中途取消挂起 - if (_suspendLoad == false) - _loadSceneOp.UnSuspendLoad(); - - // ... 进度更新和完成处理 - } -} -``` - ---- - -## Handle 系统 - -Handle 系统提供面向用户的资源访问接口,通过代理模式封装 Provider。 - -### HandleBase(基类) - -所有句柄的抽象基类,实现 `IEnumerator` 和 `IDisposable` 接口。 - -```csharp -public abstract class HandleBase : IEnumerator, IDisposable -{ - private readonly AssetInfo _assetInfo; - internal ProviderOperation Provider { get; private set; } - - // 有效性检查 - public bool IsValid - { - get { return Provider != null && Provider.IsDestroyed == false; } - } - - // 释放句柄 - public void Release() - { - if (IsValidWithWarning == false) return; - Provider.ReleaseHandle(this); - - // 主动卸载零引用的资源包 - if (Provider.RefCount == 0) - Provider.TryUnloadBundle(); - - Provider = null; - } - - // IDisposable 实现 - public void Dispose() - { - this.Release(); - } -} -``` - -#### 代理 Provider 属性 - -```csharp -public EOperationStatus Status -{ - get { return IsValidWithWarning ? Provider.Status : EOperationStatus.None; } -} - -public string LastError -{ - get { return IsValidWithWarning ? Provider.Error : string.Empty; } -} - -public float Progress -{ - get { return IsValidWithWarning ? Provider.Progress : 0; } -} - -public bool IsDone -{ - get { return IsValidWithWarning ? Provider.IsDone : true; } -} - -public Task Task -{ - get { return IsValidWithWarning ? Provider.Task : null; } -} -``` - -#### 协程支持 - -```csharp -bool IEnumerator.MoveNext() -{ - return !IsDone; // 返回 false 时循环结束 -} - -void IEnumerator.Reset() { } - -object IEnumerator.Current -{ - get { return Provider; } -} -``` - -### 具体 Handle 类型 - -#### AssetHandle - -资源句柄,用于访问加载的单个资源。 - -```csharp -public sealed class AssetHandle : HandleBase -{ - private System.Action _callback; - - // 完成事件 - public event System.Action Completed - { - add - { - if (IsValidWithWarning == false) - throw new YooHandleException(...); - if (Provider.IsDone) - value.Invoke(this); // 已完成则立即调用 - else - _callback += value; // 未完成则等待 - } - remove { _callback -= value; } - } - - // 资源对象访问 - public UnityEngine.Object AssetObject - { - get { return IsValidWithWarning ? Provider.AssetObject : null; } - } - - public TAsset GetAssetObject() where TAsset : UnityEngine.Object - { - return IsValidWithWarning ? Provider.AssetObject as TAsset : null; - } - - // 实例化支持 - public GameObject InstantiateSync(); - public GameObject InstantiateSync(Transform parent); - public GameObject InstantiateSync(Transform parent, bool worldPositionStays); - public GameObject InstantiateSync(Vector3 position, Quaternion rotation); - public GameObject InstantiateSync(Vector3 position, Quaternion rotation, Transform parent); - - public InstantiateOperation InstantiateAsync(); - public InstantiateOperation InstantiateAsync(Transform parent); - public InstantiateOperation InstantiateAsync(Transform parent, bool worldPositionStays); - public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation); - public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation, Transform parent); -} -``` - -#### SceneHandle - -场景句柄,用于管理加载的场景。 - -```csharp -public class SceneHandle : HandleBase -{ - internal string PackageName { get; set; } - - // 场景名称 - public string SceneName - { - get { return IsValidWithWarning ? Provider.SceneName : string.Empty; } - } - - // 场景对象 - public Scene SceneObject - { - get { return IsValidWithWarning ? Provider.SceneObject : new Scene(); } - } - - // 激活场景 - public bool ActivateScene() - { - if (IsValidWithWarning == false) return false; - if (SceneObject.IsValid() && SceneObject.isLoaded) - return SceneManager.SetActiveScene(SceneObject); - return false; - } - - // 取消挂起加载 - public bool UnSuspend() - { - if (IsValidWithWarning == false) return false; - if (Provider is SceneProvider provider) - provider.UnSuspendLoad(); - return true; - } - - // 卸载场景 - public UnloadSceneOperation UnloadAsync() - { - if (IsValidWithWarning == false) - { - var operation = new UnloadSceneOperation(error); - OperationSystem.StartOperation(packageName, operation); - return operation; - } - - var op = new UnloadSceneOperation(Provider); - OperationSystem.StartOperation(packageName, op); - return op; - } -} -``` - -#### SubAssetsHandle - -子资源句柄,用于访问 Bundle 内的子资源(如图集中的精灵)。 - -```csharp -public sealed class SubAssetsHandle : HandleBase -{ - // 所有子资源 - public IReadOnlyList SubAssetObjects - { - get { return IsValidWithWarning ? Provider.SubAssetObjects : null; } - } - - // 获取指定名称的子资源 - public TObject GetSubAssetObject(string assetName) - where TObject : UnityEngine.Object - { - if (IsValidWithWarning == false) return null; - - foreach (var assetObject in Provider.SubAssetObjects) - { - if (assetObject.name == assetName && assetObject is TObject) - return assetObject as TObject; - } - - YooLogger.Warning($"Not found sub asset object : {assetName}"); - return null; - } - - // 获取所有指定类型的子资源 - public TObject[] GetSubAssetObjects() - where TObject : UnityEngine.Object - { - if (IsValidWithWarning == false) return null; - - List result = new List(Provider.SubAssetObjects.Length); - foreach (var assetObject in Provider.SubAssetObjects) - { - var retObject = assetObject as TObject; - if (retObject != null) - result.Add(retObject); - } - return result.ToArray(); - } -} -``` - -#### AllAssetsHandle - -全部资源句柄,用于访问 Bundle 内的所有资源。 - -```csharp -public sealed class AllAssetsHandle : HandleBase -{ - public IReadOnlyList AllAssetObjects - { - get { return IsValidWithWarning ? Provider.AllAssetObjects : null; } - } -} -``` - -#### RawFileHandle - -原生文件句柄,用于访问未经 Unity 处理的原始文件。 - -```csharp -public class RawFileHandle : HandleBase -{ - // 读取二进制数据 - public byte[] GetRawFileData() - { - if (IsValidWithWarning == false) return null; - return Provider.BundleResultObject.ReadBundleFileData(); - } - - // 读取文本内容 - public string GetRawFileText() - { - if (IsValidWithWarning == false) return null; - return Provider.BundleResultObject.ReadBundleFileText(); - } - - // 获取文件路径 - public string GetRawFilePath() - { - if (IsValidWithWarning == false) return string.Empty; - return Provider.BundleResultObject.GetBundleFilePath(); - } -} -``` - -### HandleFactory - -句柄工厂,使用字典映射类型到构造函数。 - -```csharp -internal static class HandleFactory -{ - private static readonly Dictionary> - _handleFactory = new Dictionary>() - { - { typeof(AssetHandle), op => new AssetHandle(op) }, - { typeof(SceneHandle), op => new SceneHandle(op) }, - { typeof(SubAssetsHandle), op => new SubAssetsHandle(op) }, - { typeof(AllAssetsHandle), op => new AllAssetsHandle(op) }, - { typeof(RawFileHandle), op => new RawFileHandle(op) } - }; - - public static HandleBase CreateHandle(ProviderOperation operation, Type type) - { - if (_handleFactory.TryGetValue(type, out var factory) == false) - throw new NotImplementedException($"Handle type {type.FullName} is not supported."); - return factory(operation); - } -} -``` - ---- - -## Loader 系统 - -### LoadBundleFileOperation - -Bundle 文件加载操作,负责 Bundle 的实际加载和并发控制。 - -#### 状态机 - -``` -None → CheckConcurrency → LoadBundleFile → Done -``` - -```csharp -private enum ESteps -{ - None, - CheckConcurrency, // 检查并发限制 - LoadBundleFile, // 执行 Bundle 加载 - Done, -} -``` - -#### 核心属性 - -```csharp -internal class LoadBundleFileOperation : AsyncOperationBase -{ - public BundleInfo LoadBundleInfo { get; } // Bundle 信息 - public BundleResult Result { get; set; } // 加载结果 - public int RefCount { get; } // 引用计数 - public long DownloadedBytes { get; set; } // 已下载字节数 - public float DownloadProgress { get; set; } // 下载进度 - public bool IsDestroyed { get; } // 销毁标志 -} -``` - -#### 并发控制流程 - -```csharp -internal override void InternalUpdate() -{ - if (_steps == ESteps.CheckConcurrency) - { - // 检查是否超过最大并发加载数 - if (_resManager.BundleLoadingIsBusy()) - return; // 等待直到有空闲位置 - - _steps = ESteps.LoadBundleFile; - } - - if (_steps == ESteps.LoadBundleFile) - { - if (_loadBundleOp == null) - { - // 统计计数增加 - _resManager.BundleLoadingCounter++; - _loadBundleOp = LoadBundleInfo.LoadBundleFile(); - _loadBundleOp.StartOperation(); - AddChildOperation(_loadBundleOp); - } - - // ... 等待加载完成 ... - - // 统计计数减少 - _resManager.BundleLoadingCounter--; - } -} -``` - -#### 引用计数管理 - -```csharp -public void Reference() -{ - RefCount++; -} - -public void Release() -{ - RefCount--; -} - -public bool CanDestroyLoader() -{ - if (CanReleasableLoader() == false) - return false; - - // 检查引用链上的资源包是否已经全部销毁 - // 注意:互相引用的资源包无法卸载! - if (LoadBundleInfo.Bundle.ReferenceBundleIDs.Count > 0) - { - foreach (var bundleID in LoadBundleInfo.Bundle.ReferenceBundleIDs) - { -#if YOOASSET_EXPERIMENTAL - if (_resManager.CheckBundleReleasable(bundleID) == false) - return false; -#else - if (_resManager.CheckBundleDestroyed(bundleID) == false) - return false; -#endif - } - } - - return true; -} -``` - -#### Provider 管理 - -```csharp -private readonly List _providers = new List(100); - -public void AddProvider(ProviderOperation provider) -{ - if (_providers.Contains(provider) == false) - _providers.Add(provider); -} - -public void TryDestroyProviders() -{ - // 获取可销毁的 Provider 列表 - _removeList.Clear(); - foreach (var provider in _providers) - { - if (provider.CanDestroyProvider()) - _removeList.Add(provider); - } - - // 销毁 Provider - foreach (var provider in _removeList) - { - _providers.Remove(provider); - provider.DestroyProvider(); - } - - // 从 ResourceManager 中移除 - if (_removeList.Count > 0) - { - _resManager.RemoveBundleProviders(_removeList); - _removeList.Clear(); - } -} -``` - ---- - -## 操作类系统 - -### InstantiateOperation - -实例化操作,支持同步和异步实例化 GameObject。 - -```csharp -public class InstantiateOperation : AsyncOperationBase -{ - public GameObject Result { get; private set; } - - // 支持的实例化参数 - private Transform _parent; - private bool _worldPositionStays; - private Vector3 _position; - private Quaternion _rotation; - private bool _setPositionAndRotation; -} -``` - -### UnloadSceneOperation - -场景卸载操作。 - -```csharp -public class UnloadSceneOperation : AsyncOperationBase -{ - // 状态流程:UnloadScene → Done - private enum ESteps - { - None, - UnloadScene, - Done, - } -} -``` - -### UnloadAllAssetsOperation - -卸载包裹内所有资源操作。 - -```csharp -public class UnloadAllAssetsOperation : AsyncOperationBase -{ - // 状态流程:CheckInit → ClearProvider → ClearLoader → Done - private enum ESteps - { - None, - CheckInit, - ClearProvider, - ClearLoader, - Done, - } -} -``` - -### UnloadUnusedAssetsOperation - -卸载未使用资源操作,支持迭代清理。 - -```csharp -public class UnloadUnusedAssetsOperation : AsyncOperationBase -{ - private int _maxIterationCount; // 最大迭代次数 - - // 每次迭代清理一轮未使用的资源 - // 复杂的依赖链可能需要多次迭代 -} -``` - ---- - -## 关键工作流 - -### 资源加载流程 - -``` -用户请求 LoadAssetAsync(location) - ↓ -ResourcePackage 转换 → AssetInfo - ↓ -ResourceManager.LoadAssetAsync(assetInfo) - ├─ 构造 ProviderGUID (LoadAssetAsync + AssetInfo.GUID) - ├─ 查找已有 Provider (ProviderDic.TryGetValue) - ├─ 创建新 Provider (如不存在) - │ ├─ new AssetProvider(...) - │ ├─ 创建 LoadBundleFileOperation (主 Bundle) - │ └─ 创建 LoadBundleFileOperation[] (依赖 Bundle) - ├─ 注册到 ProviderDic - ├─ 启动 OperationSystem - └─ 返回 Handle (provider.CreateHandle()) - ↓ -ProviderOperation.InternalUpdate() - ├─ StartBundleLoader:启动所有 Bundle 加载器 - ├─ WaitBundleLoader:等待 Bundle 加载完成 - └─ ProcessBundleResult:调用 BundleResult.LoadAssetAsync() - ↓ -LoadBundleFileOperation.InternalUpdate() - ├─ CheckConcurrency:检查并发限制 - ├─ LoadBundleFile:调用 IFileSystem.LoadBundleFile() - └─ 返回 BundleResult - ↓ -用户获得 Handle - ├─ await handle.ToTask() - ├─ yield return handle - └─ handle.AssetObject -``` - -### 资源卸载流程 - -``` -用户释放 handle.Release() - ↓ -HandleBase.Release() - ├─ Provider.ReleaseHandle(this) - ├─ RefCount-- - └─ 如果 RefCount == 0:Provider.TryUnloadBundle() - ↓ -ProviderOperation.TryUnloadBundle() - └─ 如果 AutoUnloadBundleWhenUnused: - ResourceManager.TryUnloadUnusedAsset(assetInfo, loopCount) - ↓ -ResourceManager.TryUnloadUnusedAsset() - ├─ 循环处理依赖链 (loopCount 次) - ├─ 卸载主 Bundle - │ ├─ TryDestroyProviders() - │ ├─ CanDestroyLoader() 检查 - │ └─ DestroyLoader() - └─ 卸载依赖 Bundle - ├─ CanDestroyLoader() 检查 - └─ DestroyLoader() - ↓ -LoadBundleFileOperation.DestroyLoader() - └─ BundleResult.UnloadBundleFile() -``` - -### Provider 复用机制 - -``` -多次加载同一资源: - LoadAssetAsync("Player.prefab") → Provider A (新建) - LoadAssetAsync("Player.prefab") → Provider A (复用) - LoadAssetAsync("Player.prefab") → Provider A (复用) - -ProviderGUID 构造规则: - ProviderGUID = MethodName + AssetInfo.GUID - 例如:LoadAssetAsync + abc123def456 → "LoadAssetAsyncabc123def456" - -复用条件: - if (ProviderDic.TryGetValue(providerGUID, out provider)) - return provider.CreateHandle(); // 复用现有 Provider - -每次复用: - RefCount++ (通过 CreateHandle) -``` - ---- - -## 类继承关系图 - -``` -AsyncOperationBase -├── ProviderOperation (资源提供者基类) -│ ├── AssetProvider (加载单个资源) -│ ├── SceneProvider (加载场景) -│ ├── SubAssetsProvider (加载子资源) -│ ├── AllAssetsProvider (加载所有资源) -│ ├── RawFileProvider (加载原生文件) -│ └── CompletedProvider (错误快速返回) -├── LoadBundleFileOperation (Bundle 加载) -├── InstantiateOperation (实例化) -├── UnloadSceneOperation (场景卸载) -├── UnloadAllAssetsOperation (全部卸载) -└── UnloadUnusedAssetsOperation (未使用卸载) - -HandleBase (IEnumerator, IDisposable) -├── AssetHandle (资源句柄) -├── SceneHandle (场景句柄) -├── SubAssetsHandle (子资源句柄) -├── AllAssetsHandle (全部资源句柄) -└── RawFileHandle (原生文件句柄) -``` - ---- - -## 与其他模块的交互 - -``` -ResourcePackage - │ - ├─ 持有 → ResourceManager 实例 - │ ├─ LoadAssetAsync() - │ ├─ LoadSceneAsync() - │ ├─ LoadSubAssetsAsync() - │ ├─ LoadAllAssetsAsync() - │ └─ LoadRawFileAsync() - │ - └─ 实现 → IBundleQuery 接口 - ├─ GetMainBundleInfo(AssetInfo) → BundleInfo - ├─ GetDependBundleInfos(AssetInfo) → List - └─ GetMainBundleName(bundleID) → string - -ResourceManager - │ - ├─ 依赖 → IBundleQuery (Bundle 查询) - │ - ├─ 使用 → BundleInfo - │ └─ LoadBundleFile() → FSLoadBundleOperation - │ - └─ 间接使用 → IFileSystem - └─ 通过 BundleInfo 调用 - ├─ LoadBundleFile(Bundle) - └─ 返回 FSLoadBundleOperation -``` - -### 并发流量控制 - -``` -ResourceManager 维护的限制: -├─ BundleLoadingMaxConcurrency (默认 32,范围 1-256) -│ └─ 限制同时加载的 Bundle 文件数量 -├─ BundleLoadingCounter (当前计数) -│ └─ 由 LoadBundleFileOperation 增减 -└─ BundleLoadingIsBusy() 检查 - └─ 超过限制则阻塞新的 Bundle 加载 - -FileSystem (Cache) 维护的限制: -├─ FileVerifyMaxConcurrency (默认 32,范围 1-256) -│ └─ 限制同时验证的文件数量 -├─ DownloadMaxConcurrency (默认 10,范围 1-64) -│ └─ 限制同时下载的文件数量 -└─ DownloadMaxRequestPerFrame (默认 5,范围 1-20) - └─ 限制每帧发起的下载请求数 -``` - ---- - -## 使用示例 - -### 加载资源 - -```csharp -// 异步加载(async/await) -var handle = package.LoadAssetAsync("Assets/Prefabs/Player.prefab"); -await handle.ToTask(); -var prefab = handle.GetAssetObject(); - -// 使用资源 -var instance = GameObject.Instantiate(prefab); - -// 释放资源(必须!) -handle.Release(); -``` - -```csharp -// 异步加载(协程) -var handle = package.LoadAssetAsync("Assets/Prefabs/Player.prefab"); -yield return handle; -var prefab = handle.GetAssetObject(); - -// 使用资源 -var instance = GameObject.Instantiate(prefab); - -// 释放资源 -handle.Release(); -``` - -```csharp -// 异步加载(回调) -var handle = package.LoadAssetAsync("Assets/Prefabs/Player.prefab"); -handle.Completed += (h) => -{ - var prefab = h.GetAssetObject(); - var instance = GameObject.Instantiate(prefab); - - // 注意:回调中也需要释放 - h.Release(); -}; -``` - -### 加载场景 - -```csharp -// 加载场景(支持挂起) -var sceneHandle = package.LoadSceneAsync("Assets/Scenes/Main.unity", - LoadSceneMode.Additive, suspendLoad: true); - -// 在适当时机取消挂起 -sceneHandle.UnSuspend(); - -await sceneHandle.ToTask(); - -// 激活场景 -sceneHandle.ActivateScene(); - -// 卸载场景 -var unloadOp = sceneHandle.UnloadAsync(); -await unloadOp.ToTask(); -``` - -### 加载子资源 - -```csharp -// 加载图集 -var handle = package.LoadSubAssetsAsync("Assets/Atlas/UI.spriteatlas"); -await handle.ToTask(); - -// 获取特定精灵 -var homeIcon = handle.GetSubAssetObject("icon_home"); -var settingsIcon = handle.GetSubAssetObject("icon_settings"); - -// 获取所有精灵 -var allSprites = handle.GetSubAssetObjects(); - -// 释放资源 -handle.Release(); -``` - -### 加载原生文件 - -```csharp -// 加载 JSON 配置 -var handle = package.LoadRawFileAsync("Assets/Config/settings.json"); -await handle.ToTask(); - -// 读取文本 -string json = handle.GetRawFileText(); -var settings = JsonUtility.FromJson(json); - -// 释放资源 -handle.Release(); -``` - -```csharp -// 加载二进制文件 -var handle = package.LoadRawFileAsync("Assets/Data/binary.bytes"); -await handle.ToTask(); - -// 读取二进制数据 -byte[] data = handle.GetRawFileData(); - -// 或获取文件路径(用于第三方库) -string path = handle.GetRawFilePath(); - -handle.Release(); -``` - -### 实例化操作 - -```csharp -var handle = package.LoadAssetAsync("Assets/Prefabs/Player.prefab"); -await handle.ToTask(); - -// 同步实例化 -var go1 = handle.InstantiateSync(); -var go2 = handle.InstantiateSync(parentTransform); -var go3 = handle.InstantiateSync(parentTransform, worldPositionStays: false); -var go4 = handle.InstantiateSync(position, rotation); -var go5 = handle.InstantiateSync(position, rotation, parentTransform); - -// 异步实例化 -var instOp = handle.InstantiateAsync(parentTransform); -await instOp.ToTask(); -var go6 = instOp.Result; - -// 释放资源 -handle.Release(); -``` - -### 使用 using 语句自动释放 - -```csharp -// 利用 IDisposable 接口 -using (var handle = package.LoadAssetAsync("Assets/Prefabs/Player.prefab")) -{ - await handle.ToTask(); - var prefab = handle.GetAssetObject(); - var instance = GameObject.Instantiate(prefab); -} -// using 块结束时自动调用 handle.Dispose() → Release() -``` - ---- - -## 注意事项 - -1. **必须释放 Handle** - - 使用后必须调用 `handle.Release()` 避免内存泄漏 - - 可以使用 `using` 语句自动释放 - -2. **Provider 复用** - - 相同资源的多次加载会复用同一个 Provider - - 每次加载都会增加引用计数 - -3. **并发限制** - - Bundle 加载最大并发数为 256,默认 32 - - 超过限制的加载请求会排队等待 - -4. **引用计数** - - RefCount 为 0 且 `AutoUnloadBundleWhenUnused` 为 true 时自动卸载 - - 复杂依赖链可能需要多次迭代才能完全卸载 - -5. **WebGL 特殊处理** - - 可配置 `WebGLForceSyncLoadAsset` 强制同步加载 - - WebGL 平台不支持多线程 - -6. **循环依赖** - - 通过 `YOOASSET_EXPERIMENTAL` 宏处理循环 Bundle 依赖 - - 实验性功能,需谨慎使用 - -7. **线程安全** - - 所有资源管理逻辑在主线程执行 - - 多线程仅用于下载和文件验证 - -8. **场景加载** - - 场景不支持 Provider 复用 - - 每次加载都会创建新的 Provider(使用递增的 sceneCreateIndex) - ---- - -## 性能优化建议 - -1. **合理设置并发数** - - 根据设备性能调整 `BundleLoadingMaxConcurrency` - - 移动设备建议 16-32,PC 可设置更高 - -2. **预加载常用资源** - - 提前加载常用资源并持有 Handle - - 避免运行时频繁加载/卸载 - -3. **批量加载** - - 使用 `LoadAllAssetsAsync` 加载 Bundle 内所有资源 - - 减少多次加载请求的开销 - -4. **及时释放** - - 不再使用的资源及时调用 `Release()` - - 避免内存占用过高 - -5. **使用资源标签** - - 合理规划资源标签 - - 利用标签进行批量下载和加载 diff --git a/Assets/YooAsset/Runtime/ResourceManager/README.md.meta b/Assets/YooAsset/Runtime/ResourceManager/README.md.meta deleted file mode 100644 index f5e04ab6..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/README.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 23897062e5e2c98498f4bd00a407dda8 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs b/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs index dd49cc96..31524b28 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs @@ -7,18 +7,24 @@ using UnityEngine.SceneManagement; namespace YooAsset { + /// + /// 资源管理器 + /// 注意:此类不是线程安全的,所有方法必须在Unity主线程调用 + /// internal class ResourceManager { internal readonly Dictionary ProviderDic = new Dictionary(5000); - internal readonly Dictionary LoaderDic = new Dictionary(5000); + internal readonly Dictionary LoaderDic = new Dictionary(5000); internal readonly List SceneHandles = new List(100); - private long _sceneCreateIndex = 0; - private IBundleQuery _bundleQuery; + private readonly List _tempSceneHandles = new List(100); + private FileSystemHost _fileSystemHost; private int _bundleLoadingMaxConcurrency; + private int _bundleLoadingCounter; + private long _sceneCreateIndex; // 开发者配置选项 - public bool AutoUnloadBundleWhenUnused { private set; get; } - public bool WebGLForceSyncLoadAsset { private set; get; } + public bool AutoUnloadBundleWhenUnused { get; private set; } + public bool WebGLForceSyncLoadAsset { get; private set; } /// /// 所属包裹 @@ -30,12 +36,6 @@ namespace YooAsset /// public bool LockLoadOperation = false; - /// - /// 统计正在加载的Bundle文件数量 - /// - public int BundleLoadingCounter = 0; - - public ResourceManager(string packageName) { PackageName = packageName; @@ -44,12 +44,12 @@ namespace YooAsset /// /// 初始化 /// - public void Initialize(InitializeParameters parameters, IBundleQuery bundleServices) + public void Initialize(InitializePackageOptions options, FileSystemHost host) { - _bundleLoadingMaxConcurrency = parameters.BundleLoadingMaxConcurrency; - AutoUnloadBundleWhenUnused = parameters.AutoUnloadBundleWhenUnused; - WebGLForceSyncLoadAsset = parameters.WebGLForceSyncLoadAsset; - _bundleQuery = bundleServices; + _fileSystemHost = host; + _bundleLoadingMaxConcurrency = options.BundleLoadingMaxConcurrency; + AutoUnloadBundleWhenUnused = options.AutoUnloadBundleWhenUnused; + WebGLForceSyncLoadAsset = options.WebGLForceSyncLoadAsset; SceneManager.sceneUnloaded += OnSceneUnloaded; } @@ -68,21 +68,24 @@ namespace YooAsset { if (assetInfo == null) { - YooLogger.Error($"{nameof(AssetInfo)} is null !"); + YooLogger.Error($"{nameof(AssetInfo)} is null."); return; } if (assetInfo.IsInvalid) { - YooLogger.Error($"Failed to unload asset ! {assetInfo.Error}"); + YooLogger.Error($"Failed to unload asset. Error: {assetInfo.Error}"); return; } + // 多次循环尝试卸载,以处理复杂的依赖链 + // 例如:A依赖B,B依赖C,需要多次循环才能完全卸载 while (loopCount > 0) { loopCount--; + bool hasUnloaded = false; // 卸载主资源包加载器 - string mainBundleName = _bundleQuery.GetMainBundleName(assetInfo.Asset.BundleID); + string mainBundleName = _fileSystemHost.GetMainBundleName(assetInfo.Asset.BundleID); var mainLoader = TryGetBundleFileLoader(mainBundleName); if (mainLoader != null) { @@ -91,13 +94,14 @@ namespace YooAsset { mainLoader.DestroyLoader(); LoaderDic.Remove(mainBundleName); + hasUnloaded = true; } } // 卸载依赖资源包加载器 foreach (var dependID in assetInfo.Asset.DependBundleIDs) { - string dependBundleName = _bundleQuery.GetMainBundleName(dependID); + string dependBundleName = _fileSystemHost.GetMainBundleName(dependID); var dependLoader = TryGetBundleFileLoader(dependBundleName); if (dependLoader != null) { @@ -105,9 +109,14 @@ namespace YooAsset { dependLoader.DestroyLoader(); LoaderDic.Remove(dependBundleName); + hasUnloaded = true; } } } + + // 如果本次循环没有卸载任何资源,提前退出 + if (hasUnloaded == false) + break; } } @@ -120,7 +129,7 @@ namespace YooAsset { if (LockLoadOperation) { - string error = $"The load operation locked !"; + string error = $"The load operation locked."; YooLogger.Error(error); CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); completedProvider.SetCompletedWithError(error); @@ -129,7 +138,7 @@ namespace YooAsset if (assetInfo.IsInvalid) { - YooLogger.Error($"Failed to load scene ! {assetInfo.Error}"); + YooLogger.Error($"Failed to load scene. Error: {assetInfo.Error}"); CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); completedProvider.SetCompletedWithError(assetInfo.Error); return completedProvider.CreateHandle(); @@ -159,7 +168,7 @@ namespace YooAsset { if (LockLoadOperation) { - string error = $"The load operation locked !"; + string error = $"The load operation locked."; YooLogger.Error(error); CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); completedProvider.SetCompletedWithError(error); @@ -168,7 +177,7 @@ namespace YooAsset if (assetInfo.IsInvalid) { - YooLogger.Error($"Failed to load asset ! {assetInfo.Error}"); + YooLogger.Error($"Failed to load asset. Error: {assetInfo.Error}"); CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); completedProvider.SetCompletedWithError(assetInfo.Error); return completedProvider.CreateHandle(); @@ -195,7 +204,7 @@ namespace YooAsset { if (LockLoadOperation) { - string error = $"The load operation locked !"; + string error = $"The load operation locked."; YooLogger.Error(error); CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); completedProvider.SetCompletedWithError(error); @@ -204,7 +213,7 @@ namespace YooAsset if (assetInfo.IsInvalid) { - YooLogger.Error($"Failed to load sub assets ! {assetInfo.Error}"); + YooLogger.Error($"Failed to load sub assets. Error: {assetInfo.Error}"); CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); completedProvider.SetCompletedWithError(assetInfo.Error); return completedProvider.CreateHandle(); @@ -231,7 +240,7 @@ namespace YooAsset { if (LockLoadOperation) { - string error = $"The load operation locked !"; + string error = $"The load operation locked."; YooLogger.Error(error); CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); completedProvider.SetCompletedWithError(error); @@ -240,7 +249,7 @@ namespace YooAsset if (assetInfo.IsInvalid) { - YooLogger.Error($"Failed to load all assets ! {assetInfo.Error}"); + YooLogger.Error($"Failed to load all assets. Error: {assetInfo.Error}"); CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); completedProvider.SetCompletedWithError(assetInfo.Error); return completedProvider.CreateHandle(); @@ -267,7 +276,7 @@ namespace YooAsset { if (LockLoadOperation) { - string error = $"The load operation locked !"; + string error = $"The load operation locked."; YooLogger.Error(error); CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); completedProvider.SetCompletedWithError(error); @@ -276,7 +285,7 @@ namespace YooAsset if (assetInfo.IsInvalid) { - YooLogger.Error($"Failed to load raw file ! {assetInfo.Error}"); + YooLogger.Error($"Failed to load raw file. Error: {assetInfo.Error}"); CompletedProvider completedProvider = new CompletedProvider(this, assetInfo); completedProvider.SetCompletedWithError(assetInfo.Error); return completedProvider.CreateHandle(); @@ -296,15 +305,15 @@ namespace YooAsset return provider.CreateHandle(); } - internal LoadBundleFileOperation CreateMainBundleFileLoader(AssetInfo assetInfo) + internal LoadBundleOperation CreateMainBundleFileLoader(AssetInfo assetInfo) { - BundleInfo bundleInfo = _bundleQuery.GetMainBundleInfo(assetInfo); + BundleInfo bundleInfo = _fileSystemHost.GetMainBundleInfo(assetInfo); return CreateBundleFileLoaderInternal(bundleInfo); } - internal List CreateDependBundleFileLoaders(AssetInfo assetInfo) + internal List CreateDependBundleFileLoaders(AssetInfo assetInfo) { - List bundleInfos = _bundleQuery.GetDependBundleInfos(assetInfo); - List result = new List(bundleInfos.Count); + List bundleInfos = _fileSystemHost.GetDependBundleInfos(assetInfo); + List result = new List(bundleInfos.Count); foreach (var bundleInfo in bundleInfos) { var bundleLoader = CreateBundleFileLoaderInternal(bundleInfo); @@ -321,7 +330,7 @@ namespace YooAsset } internal bool CheckBundleDestroyed(int bundleID) { - string bundleName = _bundleQuery.GetMainBundleName(bundleID); + string bundleName = _fileSystemHost.GetMainBundleName(bundleID); var bundleFileLoader = TryGetBundleFileLoader(bundleName); if (bundleFileLoader == null) return true; @@ -329,7 +338,7 @@ namespace YooAsset } internal bool CheckBundleReleasable(int bundleID) { - string bundleName = _bundleQuery.GetMainBundleName(bundleID); + string bundleName = _fileSystemHost.GetMainBundleName(bundleID); var bundleFileLoader = TryGetBundleFileLoader(bundleName); if (bundleFileLoader == null) return true; @@ -339,27 +348,44 @@ namespace YooAsset { return LoaderDic.Count > 0; } + internal void IncrementBundleLoadingCounter() + { + _bundleLoadingCounter++; + } + internal void DecrementBundleLoadingCounter() + { + _bundleLoadingCounter--; + if (_bundleLoadingCounter < 0) + { + YooLogger.Error("BundleLoadingCounter is negative."); + _bundleLoadingCounter = 0; + } + } + internal int GetBundleLoadingCounter() + { + return _bundleLoadingCounter; + } internal bool BundleLoadingIsBusy() { - return BundleLoadingCounter >= _bundleLoadingMaxConcurrency; + return _bundleLoadingCounter >= _bundleLoadingMaxConcurrency; } - private LoadBundleFileOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo) + private LoadBundleOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo) { // 如果加载器已经存在 string bundleName = bundleInfo.Bundle.BundleName; - LoadBundleFileOperation loaderOperation = TryGetBundleFileLoader(bundleName); + LoadBundleOperation loaderOperation = TryGetBundleFileLoader(bundleName); if (loaderOperation != null) return loaderOperation; // 新增下载需求 - loaderOperation = new LoadBundleFileOperation(this, bundleInfo); + loaderOperation = new LoadBundleOperation(this, bundleInfo); LoaderDic.Add(bundleName, loaderOperation); return loaderOperation; } - private LoadBundleFileOperation TryGetBundleFileLoader(string bundleName) + private LoadBundleOperation TryGetBundleFileLoader(string bundleName) { - if (LoaderDic.TryGetValue(bundleName, out LoadBundleFileOperation value)) + if (LoaderDic.TryGetValue(bundleName, out LoadBundleOperation value)) return value; else return null; @@ -373,7 +399,7 @@ namespace YooAsset } private void OnSceneUnloaded(Scene scene) { - List removeList = new List(); + _tempSceneHandles.Clear(); //复用列表 foreach (var sceneHandle in SceneHandles) { if (sceneHandle.IsValid) @@ -381,45 +407,45 @@ namespace YooAsset if (sceneHandle.SceneObject == scene) { sceneHandle.Release(); - removeList.Add(sceneHandle); + _tempSceneHandles.Add(sceneHandle); } } } - foreach (var sceneHandle in removeList) + foreach (var sceneHandle in _tempSceneHandles) { SceneHandles.Remove(sceneHandle); } } #region 调试信息 - internal List GetDebugProviderInfos() + internal List GetDebugProviderInfos() { - List result = new List(ProviderDic.Count); + List result = new List(ProviderDic.Count); foreach (var provider in ProviderDic.Values) { - DebugProviderInfo providerInfo = new DebugProviderInfo(); + DiagnosticProviderInfo providerInfo = new DiagnosticProviderInfo(); providerInfo.AssetPath = provider.MainAssetInfo.AssetPath; - providerInfo.SpawnScene = provider.SpawnScene; - providerInfo.BeginTime = provider.BeginTime; - providerInfo.LoadingTime = provider.ProcessTime; - providerInfo.RefCount = provider.RefCount; + providerInfo.OriginScene = provider.OriginScene; + providerInfo.StartTime = provider.StartTime; + providerInfo.ElapsedMS = provider.ElapsedMS; + providerInfo.ReferenceCount = provider.RefCount; providerInfo.Status = provider.Status.ToString(); - providerInfo.DependBundles = provider.GetDebugDependBundles(); + providerInfo.DependentBundles = provider.GetDebugDependBundles(); result.Add(providerInfo); } return result; } - internal List GetDebugBundleInfos() + internal List GetDebugBundleInfos() { - List result = new List(LoaderDic.Values.Count); + List result = new List(LoaderDic.Values.Count); foreach (var bundleLoader in LoaderDic.Values) { var packageBundle = bundleLoader.LoadBundleInfo.Bundle; - var bundleInfo = new DebugBundleInfo(); + var bundleInfo = new DiagnosticBundleInfo(); bundleInfo.BundleName = packageBundle.BundleName; - bundleInfo.RefCount = bundleLoader.RefCount; + bundleInfo.ReferenceCount = bundleLoader.RefCount; bundleInfo.Status = bundleLoader.Status.ToString(); - bundleInfo.ReferenceBundles = FilterReferenceBundles(packageBundle); + bundleInfo.ReferencedByBundles = FilterReferenceBundles(packageBundle); result.Add(bundleInfo); } return result; diff --git a/Assets/YooAsset/Runtime/ResourcePackage/AssetInfo.cs b/Assets/YooAsset/Runtime/ResourcePackage/AssetInfo.cs index 2cbae43c..468c90bf 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/AssetInfo.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/AssetInfo.cs @@ -19,17 +19,17 @@ namespace YooAsset /// /// 所属包裹 /// - public string PackageName { private set; get; } + public string PackageName { get; private set; } /// /// 资源类型 /// - public System.Type AssetType { private set; get; } + public System.Type AssetType { get; private set; } /// /// 错误信息 /// - public string Error { private set; get; } + public string Error { get; private set; } /// /// 加载方法 diff --git a/Assets/YooAsset/Runtime/ResourcePackage/BundleInfo.cs b/Assets/YooAsset/Runtime/ResourcePackage/BundleInfo.cs index db6a158d..9d29ef58 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/BundleInfo.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/BundleInfo.cs @@ -26,21 +26,22 @@ namespace YooAsset } /// - /// 加载资源包 + /// 创建加载器 /// - public FSLoadBundleOperation LoadBundleFile() + public FSLoadBundleOperation CreateBundleLoader() { - return _fileSystem.LoadBundleFile(Bundle); + var options = new LoadBundleOptions(Bundle); + return _fileSystem.LoadBundleAsync(options); } /// /// 创建下载器 /// - public FSDownloadFileOperation CreateDownloader(int failedTryAgain) + public FSDownloadFileOperation CreateBundleDownloader(int failedTryAgain) { - DownloadFileOptions options = new DownloadFileOptions(failedTryAgain); + DownloadFileOptions options = new DownloadFileOptions(Bundle, failedTryAgain); options.ImportFilePath = _importFilePath; - return _fileSystem.DownloadFileAsync(Bundle, options); + return _fileSystem.DownloadFileAsync(options); } /// diff --git a/Assets/YooAsset/Runtime/ResourcePackage/EBuildBundleType.cs b/Assets/YooAsset/Runtime/ResourcePackage/EBundleType.cs similarity index 75% rename from Assets/YooAsset/Runtime/ResourcePackage/EBuildBundleType.cs rename to Assets/YooAsset/Runtime/ResourcePackage/EBundleType.cs index 99b658fe..e67e72dd 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/EBuildBundleType.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/EBundleType.cs @@ -1,7 +1,7 @@  namespace YooAsset { - public enum EBuildBundleType + public enum EBundleType { /// /// 未知类型 @@ -22,5 +22,10 @@ namespace YooAsset /// 原生文件 /// RawBundle = 3, + + /// + /// 团结资源包 + /// + InstantBundle = 4, } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/EBuildBundleType.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/EBundleType.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/EBuildBundleType.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/EBundleType.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/EPlayMode.cs b/Assets/YooAsset/Runtime/ResourcePackage/EPlayMode.cs new file mode 100644 index 00000000..df6dee54 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/EPlayMode.cs @@ -0,0 +1,34 @@ + +namespace YooAsset +{ + /// + /// 运行模式 + /// + public enum EPlayMode + { + /// + /// 编辑器下的模拟模式 + /// + EditorSimulateMode, + + /// + /// 离线运行模式 + /// + OfflinePlayMode, + + /// + /// 联机运行模式 + /// + HostPlayMode, + + /// + /// WebGL运行模式 + /// + WebPlayMode, + + /// + /// 自定义运行模式 + /// + CustomPlayMode, + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/EPlayMode.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/EPlayMode.cs.meta new file mode 100644 index 00000000..69838f36 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/EPlayMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c870af6a4c0efe444af84f4c3ba8c2c9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeImpl.cs b/Assets/YooAsset/Runtime/ResourcePackage/FileSystemHost.cs similarity index 56% rename from Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeImpl.cs rename to Assets/YooAsset/Runtime/ResourcePackage/FileSystemHost.cs index b15f0b51..9a65d316 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeImpl.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/FileSystemHost.cs @@ -4,22 +4,26 @@ using System.Collections.Generic; namespace YooAsset { - internal class PlayModeImpl : IPlayMode, IBundleQuery + internal class FileSystemHost { public readonly string PackageName; - public readonly EPlayMode PlayMode; public readonly List FileSystems = new List(10); - public PlayModeImpl(string packageName, EPlayMode playMode) + /// + /// 当前激活的清单 + /// + public PackageManifest ActiveManifest { get; private set; } + + + public FileSystemHost(string packageName) { PackageName = packageName; - PlayMode = playMode; } /// /// 异步初始化 /// - public InitializationOperation InitializeAsync(FileSystemParameters fileSystemParameter) + public InitializeFileSystemOperation InitializeAsync(FileSystemParameters fileSystemParameter) { var fileSystemParamList = new List(); if (fileSystemParameter != null) @@ -30,7 +34,7 @@ namespace YooAsset /// /// 异步初始化 /// - public InitializationOperation InitializeAsync(FileSystemParameters fileSystemParameterA, FileSystemParameters fileSystemParameterB) + public InitializeFileSystemOperation InitializeAsync(FileSystemParameters fileSystemParameterA, FileSystemParameters fileSystemParameterB) { var fileSystemParamList = new List(); if (fileSystemParameterA != null) @@ -43,22 +47,16 @@ namespace YooAsset /// /// 异步初始化 /// - public InitializationOperation InitializeAsync(List fileSystemParameterList) + public InitializeFileSystemOperation InitializeAsync(List fileSystemParameterList) { - var operation = new InitializationOperation(this, fileSystemParameterList); + var operation = new InitializeFileSystemOperation(this, fileSystemParameterList); return operation; } - #region IPlayMode接口 - /// - /// 当前激活的清单 - /// - public PackageManifest ActiveManifest { set; get; } - /// /// 销毁文件系统 /// - void IPlayMode.DestroyFileSystem() + public void Destroy() { foreach (var fileSystem in FileSystems) { @@ -68,91 +66,46 @@ namespace YooAsset } /// - /// 向网络端请求最新的资源版本 + /// 设置当前激活的资源清单 /// - RequestPackageVersionOperation IPlayMode.RequestPackageVersionAsync(bool appendTimeTicks, int timeout) + public void SetActiveManifest(PackageManifest manifest) { - var operation = new RequestPackageVersionImplOperation(this, appendTimeTicks, timeout); - return operation; + ActiveManifest = manifest; } /// - /// 向网络端请求并更新清单 + /// 获取主文件系统 /// - UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, int timeout) + /// + /// 文件系统列表里,最后一个属于主文件系统 + /// + public IFileSystem GetMainFileSystem() { - var operation = new UpdatePackageManifestOperation(this, packageVersion, timeout); - return operation; + int count = FileSystems.Count; + if (count == 0) + return null; + return FileSystems[count - 1]; } /// - /// 预下载指定版本的包裹内容 + /// 获取资源包所属文件系统 /// - PreDownloadContentOperation IPlayMode.PreDownloadContentAsync(string packageVersion, int timeout) + private IFileSystem GetBelongFileSystem(PackageBundle packageBundle) { - var operation = new PreDownloadContentOperation(this, packageVersion, timeout); - return operation; + for (int i = 0; i < FileSystems.Count; i++) + { + IFileSystem fileSystem = FileSystems[i]; + if (fileSystem.Belong(packageBundle)) + { + return fileSystem; + } + } + + YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}"); + return null; } - /// - /// 清理缓存文件 - /// - ClearCacheFilesOperation IPlayMode.ClearCacheFilesAsync(ClearCacheFilesOptions options) - { - var operation = new ClearCacheFilesOperation(this, options); - return operation; - } - - // 下载相关 - ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain) - { - List downloadList = GetDownloadListByAll(ActiveManifest); - var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain); - return operation; - } - ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain) - { - List downloadList = GetDownloadListByTags(ActiveManifest, tags); - var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain); - return operation; - } - ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain) - { - List downloadList = GetDownloadListByPaths(ActiveManifest, assetInfos, recursiveDownload); - var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain); - return operation; - } - - // 解压相关 - ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain) - { - List unpcakList = GetUnpackListByAll(ActiveManifest); - var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain); - return operation; - } - ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain) - { - List unpcakList = GetUnpackListByTags(ActiveManifest, tags); - var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain); - return operation; - } - - // 导入相关 - ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importingMaxNumber, int failedTryAgain) - { - List importerList = GetImporterListByFilePaths(ActiveManifest, filePaths); - var operation = new ResourceImporterOperation(PackageName, importerList, importingMaxNumber, failedTryAgain); - return operation; - } - ResourceImporterOperation IPlayMode.CreateResourceImporterByFileInfos(ImportFileInfo[] fileInfos, int importingMaxNumber, int failedTryAgain) - { - List importerList = GetImporterListByFileInfos(ActiveManifest, fileInfos); - var operation = new ResourceImporterOperation(PackageName, importerList, importingMaxNumber, failedTryAgain); - return operation; - } - #endregion - - #region IBundleQuery接口 + #region 资源包相关 private BundleInfo CreateBundleInfo(PackageBundle packageBundle) { if (packageBundle == null) @@ -161,22 +114,28 @@ namespace YooAsset var fileSystem = GetBelongFileSystem(packageBundle); if (fileSystem != null) { - BundleInfo bundleInfo = new BundleInfo(fileSystem, packageBundle); + var bundleInfo = new BundleInfo(fileSystem, packageBundle); return bundleInfo; } throw new YooFileSystemException($"Can not found belong file system : {packageBundle.BundleName}"); } - BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo) + public BundleInfo GetMainBundleInfo(AssetInfo assetInfo) { if (assetInfo == null || assetInfo.IsInvalid) throw new YooInternalException(); - // 注意:如果清单里未找到资源包会抛出异常! + // 注意:如果清单里未找到资源包会抛出异常 var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.Asset); return CreateBundleInfo(packageBundle); } - List IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo) + public string GetMainBundleName(int bundleID) + { + // 注意:如果清单里未找到资源包会抛出异常! + var packageBundle = ActiveManifest.GetMainPackageBundle(bundleID); + return packageBundle.BundleName; + } + public List GetDependBundleInfos(AssetInfo assetInfo) { if (assetInfo == null || assetInfo.IsInvalid) throw new YooInternalException(); @@ -201,57 +160,119 @@ namespace YooAsset } return result; } - string IBundleQuery.GetMainBundleName(int bundleID) - { - // 注意:如果清单里未找到资源包会抛出异常! - var packageBundle = ActiveManifest.GetMainPackageBundle(bundleID); - return packageBundle.BundleName; - } #endregion - /// - /// 获取主文件系统 - /// 说明:文件系统列表里,最后一个属于主文件系统 - /// - public IFileSystem GetMainFileSystem() - { - int count = FileSystems.Count; - if (count == 0) - return null; - return FileSystems[count - 1]; - } + #region 下载器相关 + private const int DefaultBundleInfoCapacity = 1000; - /// - /// 获取资源包所属文件系统 - /// - public IFileSystem GetBelongFileSystem(PackageBundle packageBundle) + public bool IsNeedDownloadFromRemoteInternal(AssetInfo assetInfo) { - for (int i = 0; i < FileSystems.Count; i++) + if (assetInfo.IsInvalid) { - IFileSystem fileSystem = FileSystems[i]; - if (fileSystem.Belong(packageBundle)) - { - return fileSystem; - } + YooLogger.Warning(assetInfo.Error); + return false; } - YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}"); - return null; + BundleInfo bundleInfo = GetMainBundleInfo(assetInfo); + if (bundleInfo.IsNeedDownloadFromRemote()) + return true; + + List depends = GetDependBundleInfos(assetInfo); + foreach (var depend in depends) + { + if (depend.IsNeedDownloadFromRemote()) + return true; + } + + return false; } - public List GetDownloadListByAll(PackageManifest manifest) + private delegate bool NeedPredicate(IFileSystem fileSystem, PackageBundle bundle); + private bool NeedDownload(IFileSystem fileSystem, PackageBundle bundle) + { + return fileSystem.NeedDownload(bundle); + } + private bool NeedUnpack(IFileSystem fileSystem, PackageBundle bundle) + { + return fileSystem.NeedUnpack(bundle); + } + private bool NeedImport(IFileSystem fileSystem, PackageBundle bundle) + { + 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); + else + downloadList = GetBundleInfoListByTags(manifest, options.Tags, NeedDownload); + + var operation = new ResourceDownloaderOperation(PackageName, downloadList, options.MaximumConcurrency, options.FailedTryAgain); + return operation; + } + + public ResourceDownloaderOperation CreateResourceDownloader(BundleDownloaderOptions options) + { + return CreateResourceDownloader(ActiveManifest, options); + } + public ResourceDownloaderOperation CreateResourceDownloader(PackageManifest manifest, BundleDownloaderOptions options) + { + List downloadList; + if (options.AssetInfos == null) + downloadList = GetBundleInfoListByAll(manifest, NeedDownload); + else + downloadList = GetBundleInfoListByAssetInfos(manifest, options.AssetInfos, options.DownloadBundleDependencies, NeedDownload); + + var operation = new ResourceDownloaderOperation(PackageName, downloadList, options.MaximumConcurrency, options.FailedTryAgain); + return operation; + } + + public ResourceUnpackerOperation CreateResourceUnpacker(ResourceUnpackerOptions options) + { + return CreateResourceUnpacker(ActiveManifest, options); + } + public ResourceUnpackerOperation CreateResourceUnpacker(PackageManifest manifest, ResourceUnpackerOptions options) + { + List unpackList; + if (options.Tags == null) + unpackList = GetBundleInfoListByAll(manifest, NeedUnpack); + else + unpackList = GetBundleInfoListByTags(manifest, options.Tags, NeedUnpack); + + var operation = new ResourceUnpackerOperation(PackageName, unpackList, options.MaximumConcurrency, options.FailedTryAgain); + 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); + return operation; + } + + private List GetBundleInfoListByAll(PackageManifest manifest, Func predicate) { if (manifest == null) return new List(); - List result = new List(1000); + List result = new List(DefaultBundleInfoCapacity); foreach (var packageBundle in manifest.BundleList) { var fileSystem = GetBelongFileSystem(packageBundle); if (fileSystem == null) continue; - if (fileSystem.NeedDownload(packageBundle)) + if (predicate(fileSystem, packageBundle)) { var bundleInfo = new BundleInfo(fileSystem, packageBundle); result.Add(bundleInfo); @@ -259,21 +280,21 @@ namespace YooAsset } return result; } - public List GetDownloadListByTags(PackageManifest manifest, string[] tags) + private List GetBundleInfoListByTags(PackageManifest manifest, string[] tags, Func predicate) { if (manifest == null) return new List(); - List result = new List(1000); + List result = new List(DefaultBundleInfoCapacity); foreach (var packageBundle in manifest.BundleList) { var fileSystem = GetBelongFileSystem(packageBundle); if (fileSystem == null) continue; - if (fileSystem.NeedDownload(packageBundle)) + if (predicate(fileSystem, packageBundle)) { - // 如果未带任何标记,则统一下载 + // 注意:如果未带任何标记,则统一处理 if (packageBundle.HasAnyTags() == false) { var bundleInfo = new BundleInfo(fileSystem, packageBundle); @@ -281,7 +302,6 @@ namespace YooAsset } else { - // 查询DLC资源 if (packageBundle.HasTag(tags)) { var bundleInfo = new BundleInfo(fileSystem, packageBundle); @@ -292,13 +312,14 @@ namespace YooAsset } return result; } - public List GetDownloadListByPaths(PackageManifest manifest, AssetInfo[] assetInfos, bool recursiveDownload) + private List GetBundleInfoListByAssetInfos(PackageManifest manifest, AssetInfo[] assetInfos, bool recursiveDepend, Func predicate) { if (manifest == null) return new List(); // 获取资源对象的资源包和所有依赖资源包 - List checkList = new List(); + HashSet checkSet = new HashSet(); + List checkList = new List(assetInfos.Length); foreach (var assetInfo in assetInfos) { if (assetInfo.IsInvalid) @@ -309,44 +330,56 @@ namespace YooAsset // 注意:如果清单里未找到资源包会抛出异常! PackageBundle mainBundle = manifest.GetMainPackageBundle(assetInfo.Asset); - if (checkList.Contains(mainBundle) == false) + if (checkSet.Contains(mainBundle.BundleGUID) == false) + { + checkSet.Add(mainBundle.BundleGUID); checkList.Add(mainBundle); + } // 注意:如果清单里未找到资源包会抛出异常! List mainDependBundles = manifest.GetAssetAllDependencies(assetInfo.Asset); foreach (var dependBundle in mainDependBundles) { - if (checkList.Contains(dependBundle) == false) + if (checkSet.Contains(dependBundle.BundleGUID) == false) + { + checkSet.Add(dependBundle.BundleGUID); checkList.Add(dependBundle); + } } // 下载主资源包内所有资源对象依赖的资源包 - if (recursiveDownload) + if (recursiveDepend) { foreach (var otherMainAsset in mainBundle.IncludeMainAssets) { var otherMainBundle = manifest.GetMainPackageBundle(otherMainAsset.BundleID); - if (checkList.Contains(otherMainBundle) == false) + if (checkSet.Contains(otherMainBundle.BundleGUID) == false) + { + checkSet.Add(otherMainBundle.BundleGUID); checkList.Add(otherMainBundle); + } List otherDependBundles = manifest.GetAssetAllDependencies(otherMainAsset); foreach (var dependBundle in otherDependBundles) { - if (checkList.Contains(dependBundle) == false) + if (checkSet.Contains(dependBundle.BundleGUID) == false) + { + checkSet.Add(dependBundle.BundleGUID); checkList.Add(dependBundle); + } } } } } - List result = new List(1000); + List result = new List(DefaultBundleInfoCapacity); foreach (var packageBundle in checkList) { var fileSystem = GetBelongFileSystem(packageBundle); if (fileSystem == null) continue; - if (fileSystem.NeedDownload(packageBundle)) + if (predicate(fileSystem, packageBundle)) { var bundleInfo = new BundleInfo(fileSystem, packageBundle); result.Add(bundleInfo); @@ -354,77 +387,19 @@ namespace YooAsset } return result; } - public List GetUnpackListByAll(PackageManifest manifest) + private List GetBundleInfoListByBundleInfos(PackageManifest manifest, ImportBundleInfo[] fileInfos, Func predicate) { if (manifest == null) return new List(); - List result = new List(1000); - foreach (var packageBundle in manifest.BundleList) - { - var fileSystem = GetBelongFileSystem(packageBundle); - if (fileSystem == null) - continue; - - if (fileSystem.NeedUnpack(packageBundle)) - { - var bundleInfo = new BundleInfo(fileSystem, packageBundle); - result.Add(bundleInfo); - } - } - return result; - } - public List GetUnpackListByTags(PackageManifest manifest, string[] tags) - { - if (manifest == null) - return new List(); - - List result = new List(1000); - foreach (var packageBundle in manifest.BundleList) - { - var fileSystem = GetBelongFileSystem(packageBundle); - if (fileSystem == null) - continue; - - if (fileSystem.NeedUnpack(packageBundle)) - { - if (packageBundle.HasTag(tags)) - { - var bundleInfo = new BundleInfo(fileSystem, packageBundle); - result.Add(bundleInfo); - } - } - } - return result; - } - public List GetImporterListByFilePaths(PackageManifest manifest, string[] filePaths) - { - if (manifest == null) - return new List(); - - ImportFileInfo[] fileInfos = new ImportFileInfo[filePaths.Length]; - for (int i = 0; i < filePaths.Length; i++) - { - ImportFileInfo fileInfo = new ImportFileInfo(); - fileInfo.FilePath = filePaths[i]; - fileInfos[i] = fileInfo; - } - - return GetImporterListByFileInfos(manifest, fileInfos); - } - public List GetImporterListByFileInfos(PackageManifest manifest, ImportFileInfo[] fileInfos) - { - if (manifest == null) - return new List(); - - List result = new List(); + List result = new List(DefaultBundleInfoCapacity); foreach (var fileInfo in fileInfos) { string filePath = fileInfo.FilePath; if (string.IsNullOrEmpty(filePath)) continue; - PackageBundle packageBundle = null; + PackageBundle packageBundle; if (string.IsNullOrEmpty(fileInfo.BundleName) == false) { if (manifest.TryGetPackageBundleByBundleName(fileInfo.BundleName, out packageBundle) == false) @@ -457,7 +432,7 @@ namespace YooAsset if (fileSystem == null) continue; - if (fileSystem.NeedImport(packageBundle)) + if (predicate(fileSystem, packageBundle)) { var bundleInfo = new BundleInfo(fileSystem, packageBundle, filePath); result.Add(bundleInfo); @@ -466,5 +441,6 @@ namespace YooAsset } return result; } + #endregion } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeImpl.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/FileSystemHost.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeImpl.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/FileSystemHost.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Interface/IBundleQuery.cs b/Assets/YooAsset/Runtime/ResourcePackage/Interface/IBundleQuery.cs deleted file mode 100644 index 2906c7f0..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Interface/IBundleQuery.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset -{ - internal interface IBundleQuery - { - /// - /// 获取主资源包信息 - /// - BundleInfo GetMainBundleInfo(AssetInfo assetInfo); - - /// - /// 获取依赖的资源包信息集合 - /// - List GetDependBundleInfos(AssetInfo assetPath); - - /// - /// 获取主资源包名称 - /// - string GetMainBundleName(int bundleID); - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Interface/IBundleQuery.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Interface/IBundleQuery.cs.meta deleted file mode 100644 index c0796aa2..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Interface/IBundleQuery.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 70420213c551a2b4b8cf014067699b07 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs b/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs deleted file mode 100644 index 2e7e9645..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs +++ /dev/null @@ -1,49 +0,0 @@ - -namespace YooAsset -{ - internal interface IPlayMode - { - /// - /// 当前激活的清单 - /// - PackageManifest ActiveManifest { set; get; } - - /// - /// 销毁文件系统 - /// - void DestroyFileSystem(); - - /// - /// 向网络端请求最新的资源版本 - /// - RequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout); - - /// - /// 向网络端请求并更新清单 - /// - UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, int timeout); - - /// - /// 预下载指定版本的包裹内容 - /// - PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout); - - /// - /// 清理缓存文件 - /// - ClearCacheFilesOperation ClearCacheFilesAsync(ClearCacheFilesOptions options); - - // 下载相关 - ResourceDownloaderOperation CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain); - ResourceDownloaderOperation CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain); - ResourceDownloaderOperation CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain); - - // 解压相关 - ResourceUnpackerOperation CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain); - ResourceUnpackerOperation CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain); - - // 导入相关 - ResourceImporterOperation CreateResourceImporterByFilePaths(string[] filePaths, int importingMaxNumber, int failedTryAgain); - ResourceImporterOperation CreateResourceImporterByFileInfos(ImportFileInfo[] fileInfos, int importingMaxNumber, int failedTryAgain); - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs.meta deleted file mode 100644 index 399ae723..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4629f36c31a96214b9057827c6a283cf -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheFilesOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheOperation.cs similarity index 76% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheFilesOperation.cs rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheOperation.cs index abcd0b9e..0174482d 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheFilesOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheOperation.cs @@ -3,7 +3,7 @@ using System.Linq; namespace YooAsset { - public sealed class ClearCacheFilesOperation : AsyncOperationBase + public sealed class ClearCacheOperation : AsyncOperationBase { private enum ESteps { @@ -14,15 +14,15 @@ namespace YooAsset Done, } - private readonly PlayModeImpl _impl; - private readonly ClearCacheFilesOptions _options; + private readonly FileSystemHost _host; + private readonly ClearCacheOptions _options; private List _cloneList; - private FSClearCacheFilesOperation _clearCacheFilesOp; + private FSClearCacheOperation _clearCacheFilesOp; private ESteps _steps = ESteps.None; - internal ClearCacheFilesOperation(PlayModeImpl impl, ClearCacheFilesOptions options) + internal ClearCacheOperation(FileSystemHost host, ClearCacheOptions options) { - _impl = impl; + _host = host; _options = options; } internal override void InternalStart() @@ -36,27 +36,27 @@ namespace YooAsset if (_steps == ESteps.Prepare) { - var fileSytems = _impl.FileSystems; - if (fileSytems == null || fileSytems.Count == 0) + var fileSystems = _host.FileSystems; + if (fileSystems == null || fileSystems.Count == 0) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "The file system is empty !"; + Error = "The file system is empty."; return; } - foreach (var fileSystem in fileSytems) + foreach (var fileSystem in fileSystems) { if (fileSystem == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "An empty object exists in the list!"; + Error = "An empty object exists in the list."; return; } } - _cloneList = fileSytems.ToList(); + _cloneList = fileSystems.ToList(); _steps = ESteps.ClearCacheFiles; } @@ -72,7 +72,7 @@ namespace YooAsset var fileSystem = _cloneList[0]; _cloneList.RemoveAt(0); - _clearCacheFilesOp = fileSystem.ClearCacheFilesAsync(_impl.ActiveManifest, _options); + _clearCacheFilesOp = fileSystem.ClearCacheAsync(_options); _clearCacheFilesOp.StartOperation(); AddChildOperation(_clearCacheFilesOp); _steps = ESteps.CheckClearResult; @@ -98,7 +98,7 @@ namespace YooAsset } } } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { return $"ClearMode : {_options.ClearMode}"; } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheOptions.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheOptions.cs new file mode 100644 index 00000000..3e0f4895 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheOptions.cs @@ -0,0 +1,40 @@ + +namespace YooAsset +{ + public struct ClearCacheOptions + { + /// + /// 清理模式 + /// + public string ClearMode { get; set; } + + /// + /// 附加参数 + /// + public object ClearParam { get; set; } + + /// + /// 资源清单 + /// + 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(string clearMode, object clearParam) + { + ClearMode = clearMode; + ClearParam = clearParam; + Manifest = null; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheOptions.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheOptions.cs.meta new file mode 100644 index 00000000..a40b9737 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearCacheOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4213bf1907101944b88f32ff19367b6f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyPackageOperation.cs similarity index 62% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyOperation.cs rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyPackageOperation.cs index f251a62e..f73f5def 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyPackageOperation.cs @@ -1,7 +1,7 @@ - + namespace YooAsset { - public class DestroyOperation : AsyncOperationBase + public class DestroyPackageOperation : AsyncOperationBase { private enum ESteps { @@ -18,7 +18,7 @@ namespace YooAsset private ESteps _steps = ESteps.None; - public DestroyOperation(ResourcePackage resourcePackage, UnloadAllAssetsOptions options) + public DestroyPackageOperation(ResourcePackage resourcePackage, UnloadAllAssetsOptions options) { _resourcePackage = resourcePackage; _options = options; @@ -35,30 +35,29 @@ namespace YooAsset if (_steps == ESteps.CheckInitStatus) { - if (_resourcePackage.InitializeStatus == EOperationStatus.None) + switch (_resourcePackage.InitializeStatus) { - _steps = ESteps.DestroyPackage; - } - else if (_resourcePackage.InitializeStatus == EOperationStatus.Processing) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "The Package is initializing ! Please try to destroy the package again later."; - } - else if (_resourcePackage.InitializeStatus == EOperationStatus.Failed) - { - _steps = ESteps.DestroyPackage; - } - else if (_resourcePackage.InitializeStatus == EOperationStatus.Succeed) - { - if (_resourcePackage.PackageValid) - _steps = ESteps.UnloadAllAssets; - else + case EOperationStatus.None: + case EOperationStatus.Failed: + case EOperationStatus.Aborted: _steps = ESteps.DestroyPackage; - } - else - { - throw new System.NotImplementedException(_resourcePackage.InitializeStatus.ToString()); + break; + + case EOperationStatus.Processing: + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "The Package is initializing. Please try to destroy the package again later."; + break; + + case EOperationStatus.Succeed: + if (_resourcePackage.PackageValid) + _steps = ESteps.UnloadAllAssets; + else + _steps = ESteps.DestroyPackage; + break; + + default: + throw new System.NotImplementedException(_resourcePackage.InitializeStatus.ToString()); } } @@ -90,17 +89,17 @@ namespace YooAsset if (_steps == ESteps.DestroyPackage) { // 销毁包裹 - _resourcePackage.DestroyPackage(); + _resourcePackage.InternalDestroy(); // 最后清理该包裹的异步任务 // 注意:对于有线程操作的异步任务,需要保证线程安全释放。 - OperationSystem.ClearPackageOperation(_resourcePackage.PackageName); + OperationSystem.ClearPackageOperations(_resourcePackage.PackageName); _steps = ESteps.Done; Status = EOperationStatus.Succeed; } } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { return $"PackageVersion : {_resourcePackage.GetPackageVersion()}"; } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyPackageOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyOperation.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyPackageOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderDefine.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderDefine.cs new file mode 100644 index 00000000..b040b785 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderDefine.cs @@ -0,0 +1,154 @@ + +namespace YooAsset +{ + /// + /// 下载完成事件参数 + /// + public struct DownloadFinishedEventArgs + { + /// + /// 所属包裹名称 + /// + public string PackageName { get; set; } + + /// + /// 是否成功 + /// + public bool IsSuccess { get; set; } + + /// + /// 如果下载失败,获取的错误信息。 + /// + public string ErrorInfo { get; set; } + + /// + /// 创建表示成功下载的事件参数 + /// + internal static DownloadFinishedEventArgs CreateSuccess(string packageName) + { + var args = new DownloadFinishedEventArgs(); + args.PackageName = packageName; + args.IsSuccess = true; + args.ErrorInfo = null; + return args; + } + + /// + /// 创建表示失败下载的事件参数 + /// + internal static DownloadFinishedEventArgs CreateFailure(string packageName, string errorInfo) + { + var args = new DownloadFinishedEventArgs(); + args.PackageName = packageName; + args.IsSuccess = false; + args.ErrorInfo = errorInfo; + return args; + } + } + + /// + /// 下载完成事件委托 + /// + public delegate void DownloadFinishedEventHandler(DownloadFinishedEventArgs args); + + + /// + /// 下载进度更新事件参数 + /// + public struct DownloadProgressChangedEventArgs + { + /// + /// 所属包裹名称 + /// + public string PackageName { get; set; } + + /// + /// 下载进度 (0-1f) + /// + public float Progress { get; set; } + + /// + /// 下载文件总数 + /// + public int TotalDownloadCount { get; set; } + + /// + /// 下载数据总大小(单位:字节) + /// + public long TotalDownloadBytes { get; set; } + + /// + /// 当前完成的下载文件数量 + /// + public int CurrentDownloadCount { get; set; } + + /// + /// 当前完成的下载数据大小(单位:字节) + /// + public long CurrentDownloadBytes { get; set; } + } + + /// + /// 下载进度更新事件委托 + /// + public delegate void DownloadProgressChangedEventHandler(DownloadProgressChangedEventArgs args); + + + /// + /// 下载错误事件参数 + /// + public struct DownloadErrorEventArgs + { + /// + /// 所属包裹名称 + /// + public string PackageName { get; set; } + + /// + /// 下载失败的文件名称 + /// + public string FileName { get; set; } + + /// + /// 错误信息 + /// + public string ErrorInfo { get; set; } + } + + /// + /// 下载错误事件委托 + /// + public delegate void DownloadErrorEventHandler(DownloadErrorEventArgs args); + + + /// + /// 开始下载单个文件事件参数 + /// + public struct DownloadFileStartedEventArgs + { + /// + /// 所属包裹名称 + /// + public string PackageName { get; set; } + + /// + /// 资源包名称 + /// + public string BundleName { get; set; } + + /// + /// 文件名称 + /// + public string FileName { get; set; } + + /// + /// 文件大小 + /// + public long FileSize { get; set; } + } + + /// + /// 开始下载单个文件事件委托 + /// + public delegate void DownloadFileStartedEventHandler(DownloadFileStartedEventArgs args); +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderDefine.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderDefine.cs.meta new file mode 100644 index 00000000..1a834b58 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderDefine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0a798eb87a00a284189bb69a767d2c02 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOperation.cs index de063aad..fc7f5105 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOperation.cs @@ -9,36 +9,14 @@ namespace YooAsset { None, Check, - Loading, + Downloading, + Finish, Done, } private const int MAX_LOADER_COUNT = 64; - - #region 委托定义 - /// - /// 下载器结束 - /// - public delegate void DownloaderFinish(DownloaderFinishData data); - - /// - /// 下载进度更新 - /// - public delegate void DownloadUpdate(DownloadUpdateData data); - - /// - /// 下载发生错误 - /// - public delegate void DownloadError(DownloadErrorData data); - - /// - /// 开始下载某个文件 - /// - public delegate void DownloadFileBegin(DownloadFileData data); - #endregion - private readonly string _packageName; - private readonly int _downloadingMaxNumber; + private readonly int _maximumConcurrency; private readonly int _failedTryAgain; private readonly List _bundleInfoList; private readonly List _downloaders = new List(MAX_LOADER_COUNT); @@ -57,12 +35,12 @@ namespace YooAsset /// /// 统计的下载文件总数量 /// - public int TotalDownloadCount { private set; get; } + public int TotalDownloadCount { get; private set; } /// /// 统计的下载文件的总大小 /// - public long TotalDownloadBytes { private set; get; } + public long TotalDownloadBytes { get; private set; } /// /// 当前已经完成的下载总数量 @@ -81,39 +59,39 @@ namespace YooAsset } /// - /// 当下载器结束(无论成功或失败) + /// 下载完成事件委托(无论成功或失败) /// - public DownloaderFinish DownloadFinishCallback { set; get; } + public DownloadFinishedEventHandler DownloadFinishedHandler { get; set; } /// - /// 当下载进度发生变化 + /// 下载进度更新事件委托 /// - public DownloadUpdate DownloadUpdateCallback { set; get; } + public DownloadProgressChangedEventHandler DownloadProgressChangedHandler { get; set; } /// - /// 当下载器发生错误 + /// 下载错误事件委托 /// - public DownloadError DownloadErrorCallback { set; get; } + public DownloadErrorEventHandler DownloadErrorHandler { get; set; } /// - /// 当开始下载某个文件 + /// 开始下载单个文件事件委托 /// - public DownloadFileBegin DownloadFileBeginCallback { set; get; } + public DownloadFileStartedEventHandler DownloadFileStartedHandler { get; set; } - internal DownloaderOperation(string packageName, List downloadList, int downloadingMaxNumber, int failedTryAgain) + internal DownloaderOperation(string packageName, List downloadList, int maximumConcurrency, int failedTryAgain) { _packageName = packageName; _bundleInfoList = downloadList; - _downloadingMaxNumber = UnityEngine.Mathf.Clamp(downloadingMaxNumber, 1, MAX_LOADER_COUNT); ; + _maximumConcurrency = UnityEngine.Mathf.Clamp(maximumConcurrency, 1, MAX_LOADER_COUNT); _failedTryAgain = failedTryAgain; // 统计下载信息 - CalculatDownloaderInfo(); + CalculateDownloaderInfo(); } internal override void InternalStart() { - YooLogger.Log($"Begine to download {TotalDownloadCount} files and {TotalDownloadBytes} bytes"); + YooLogger.Log($"Begin to download {TotalDownloadCount} files and {TotalDownloadBytes} bytes"); _steps = ESteps.Check; } internal override void InternalUpdate() @@ -127,15 +105,33 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Download list is null."; + Error = "Download bundle list is null."; + + if (DownloadFinishedHandler != null) + { + var args = DownloadFinishedEventArgs.CreateFailure(_packageName, Error); + DownloadFinishedHandler.Invoke(args); + } + } + else if (_bundleInfoList.Count == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + Progress = 1f; + + if (DownloadFinishedHandler != null) + { + var args = DownloadFinishedEventArgs.CreateSuccess(_packageName); + DownloadFinishedHandler.Invoke(args); + } } else { - _steps = ESteps.Loading; + _steps = ESteps.Downloading; } } - if (_steps == ESteps.Loading) + if (_steps == ESteps.Downloading) { // 检测下载器结果 _removeList.Clear(); @@ -172,18 +168,18 @@ namespace YooAsset { _lastDownloadBytes = downloadBytes; _lastDownloadCount = _cachedDownloadCount; - Progress = (float)_lastDownloadBytes / TotalDownloadBytes; + Progress = CalculateProgress(); - if (DownloadUpdateCallback != null) + if (DownloadProgressChangedHandler != null) { - var data = new DownloadUpdateData(); + var data = new DownloadProgressChangedEventArgs(); data.PackageName = _packageName; data.Progress = Progress; data.TotalDownloadCount = TotalDownloadCount; - data.CurrentDownloadCount = _lastDownloadCount; data.TotalDownloadBytes = TotalDownloadBytes; + data.CurrentDownloadCount = _lastDownloadCount; data.CurrentDownloadBytes = _lastDownloadBytes; - DownloadUpdateCallback.Invoke(data); + DownloadProgressChangedHandler.Invoke(data); } } @@ -194,74 +190,76 @@ namespace YooAsset if (_isPause) return; - if (_downloaders.Count < _downloadingMaxNumber) + if (_downloaders.Count < _maximumConcurrency) { int index = _bundleInfoList.Count - 1; var bundleInfo = _bundleInfoList[index]; - var downloader = bundleInfo.CreateDownloader(_failedTryAgain); + var downloader = bundleInfo.CreateBundleDownloader(_failedTryAgain); downloader.StartOperation(); this.AddChildOperation(downloader); _downloaders.Add(downloader); _bundleInfoList.RemoveAt(index); - if (DownloadFileBeginCallback != null) + if (DownloadFileStartedHandler != null) { - var data = new DownloadFileData(); + var data = new DownloadFileStartedEventArgs(); data.PackageName = _packageName; - data.FileName = bundleInfo.Bundle.BundleName; + data.BundleName = bundleInfo.Bundle.BundleName; + data.FileName = bundleInfo.Bundle.FileName; data.FileSize = bundleInfo.Bundle.FileSize; - DownloadFileBeginCallback.Invoke(data); + DownloadFileStartedHandler.Invoke(data); } } } - // 下载结算 + // 下载结束 if (_downloaders.Count == 0) { - if (_failedList.Count > 0) + _steps = ESteps.Finish; + } + } + + if (_steps == ESteps.Finish) + { + if (_failedList.Count > 0) + { + var failedDownloader = _failedList[0]; + string bundleName = failedDownloader.Bundle.BundleName; + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to download file : {bundleName}"; + + if (DownloadErrorHandler != null) { - var failedDownloader = _failedList[0]; - string bundleName = failedDownloader.Bundle.BundleName; - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Failed to download file : {bundleName}"; - - if (DownloadErrorCallback != null) - { - var data = new DownloadErrorData(); - data.PackageName = _packageName; - data.FileName = bundleName; - data.ErrorInfo = failedDownloader.Error; - DownloadErrorCallback.Invoke(data); - } - - if (DownloadFinishCallback != null) - { - var data = new DownloaderFinishData(); - data.PackageName = _packageName; - data.Succeed = false; - DownloadFinishCallback.Invoke(data); - } + var data = new DownloadErrorEventArgs(); + data.PackageName = _packageName; + data.FileName = bundleName; + data.ErrorInfo = failedDownloader.Error; + DownloadErrorHandler.Invoke(data); } - else - { - // 结算成功 - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - if (DownloadFinishCallback != null) - { - var data = new DownloaderFinishData(); - data.PackageName = _packageName; - data.Succeed = true; - DownloadFinishCallback.Invoke(data); - } + if (DownloadFinishedHandler != null) + { + var args = DownloadFinishedEventArgs.CreateFailure(_packageName, failedDownloader.Error); + DownloadFinishedHandler.Invoke(args); + } + } + else + { + // 结算成功 + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + + if (DownloadFinishedHandler != null) + { + var args = DownloadFinishedEventArgs.CreateSuccess(_packageName); + DownloadFinishedHandler.Invoke(args); } } } } - private void CalculatDownloaderInfo() + private void CalculateDownloaderInfo() { if (_bundleInfoList != null) { @@ -279,6 +277,14 @@ namespace YooAsset } } + private float CalculateProgress() + { + if (TotalDownloadBytes == 0) + return (float)_lastDownloadCount / TotalDownloadCount; + else + return (float)_lastDownloadBytes / TotalDownloadBytes; + } + /// /// 合并其它下载器 /// @@ -287,23 +293,23 @@ namespace YooAsset { if (_packageName != downloader._packageName) { - YooLogger.Error("The downloaders have different resource packages !"); + YooLogger.Error("The downloaders have different resource packages."); return; } if (Status != EOperationStatus.None) { - YooLogger.Error("The downloader is running, can not combine with other downloader !"); + YooLogger.Error("The downloader is running, can not combine with other downloader."); return; } - HashSet temper = new HashSet(); + HashSet combineGuidSet = new HashSet(); foreach (var bundleInfo in _bundleInfoList) { string combineGUID = bundleInfo.GetDownloadCombineGUID(); - if (temper.Contains(combineGUID) == false) + if (combineGuidSet.Contains(combineGUID) == false) { - temper.Add(combineGUID); + combineGuidSet.Add(combineGUID); } } @@ -311,14 +317,14 @@ namespace YooAsset foreach (var bundleInfo in downloader._bundleInfoList) { string combineGUID = bundleInfo.GetDownloadCombineGUID(); - if (temper.Contains(combineGUID) == false) + if (combineGuidSet.Contains(combineGUID) == false) { _bundleInfoList.Add(bundleInfo); } } // 重新统计下载信息 - CalculatDownloaderInfo(); + CalculateDownloaderInfo(); } /// @@ -369,52 +375,52 @@ namespace YooAsset public sealed class ResourceDownloaderOperation : DownloaderOperation { - internal ResourceDownloaderOperation(string packageName, List downloadList, int downloadingMaxNumber, int failedTryAgain) - : base(packageName, downloadList, downloadingMaxNumber, failedTryAgain) + internal ResourceDownloaderOperation(string packageName, List downloadList, int maximumConcurrency, int failedTryAgain) + : base(packageName, downloadList, maximumConcurrency, failedTryAgain) { } /// /// 创建空的下载器 /// - internal static ResourceDownloaderOperation CreateEmptyDownloader(string packageName, int downloadingMaxNumber, int failedTryAgain) + internal static ResourceDownloaderOperation CreateEmptyDownloader(string packageName) { List downloadList = new List(); - var operation = new ResourceDownloaderOperation(packageName, downloadList, downloadingMaxNumber, failedTryAgain); + var operation = new ResourceDownloaderOperation(packageName, downloadList, 1, 1); return operation; } } public sealed class ResourceUnpackerOperation : DownloaderOperation { - internal ResourceUnpackerOperation(string packageName, List downloadList, int downloadingMaxNumber, int failedTryAgain) - : base(packageName, downloadList, downloadingMaxNumber, failedTryAgain) + internal ResourceUnpackerOperation(string packageName, List downloadList, int maximumConcurrency, int failedTryAgain) + : base(packageName, downloadList, maximumConcurrency, failedTryAgain) { } /// /// 创建空的解压器 /// - internal static ResourceUnpackerOperation CreateEmptyUnpacker(string packageName, int upackingMaxNumber, int failedTryAgain) + internal static ResourceUnpackerOperation CreateEmptyUnpacker(string packageName) { List downloadList = new List(); - var operation = new ResourceUnpackerOperation(packageName, downloadList, upackingMaxNumber, failedTryAgain); + var operation = new ResourceUnpackerOperation(packageName, downloadList, 1, 1); return operation; } } public sealed class ResourceImporterOperation : DownloaderOperation { - internal ResourceImporterOperation(string packageName, List downloadList, int downloadingMaxNumber, int failedTryAgain) - : base(packageName, downloadList, downloadingMaxNumber, failedTryAgain) + internal ResourceImporterOperation(string packageName, List downloadList, int maximumConcurrency, int failedTryAgain) + : base(packageName, downloadList, maximumConcurrency, failedTryAgain) { } /// /// 创建空的导入器 /// - internal static ResourceImporterOperation CreateEmptyImporter(string packageName, int upackingMaxNumber, int failedTryAgain) + internal static ResourceImporterOperation CreateEmptyImporter(string packageName) { List downloadList = new List(); - var operation = new ResourceImporterOperation(packageName, downloadList, upackingMaxNumber, failedTryAgain); + var operation = new ResourceImporterOperation(packageName, downloadList, 1, 1); return operation; } } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOptions.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOptions.cs new file mode 100644 index 00000000..b5d09678 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOptions.cs @@ -0,0 +1,176 @@ + +namespace YooAsset +{ + /// + /// 资源下载选项 + /// + public struct BundleDownloaderOptions + { + /// + /// 最大并发数量 + /// + public int MaximumConcurrency { get; set; } + + /// + /// 失败后的重试次数 + /// + public int FailedTryAgain { get; set; } + + /// + /// 下载资源对象所属资源包内所有资源对象依赖的资源包 + /// + public bool DownloadBundleDependencies { get; set; } + + /// + /// 资源信息列表 + /// 说明:如果列表为NULL,则下载所有资产 + /// + public AssetInfo[] AssetInfos { get; set; } + + public BundleDownloaderOptions(AssetInfo assetInfo, bool downloadDependencies, int maximumConcurrency, int failedTryAgain) + { + AssetInfos = new AssetInfo[] { assetInfo }; + DownloadBundleDependencies = downloadDependencies; + MaximumConcurrency = maximumConcurrency; + FailedTryAgain = failedTryAgain; + } + public BundleDownloaderOptions(AssetInfo[] assetInfos, bool downloadDependencies, int maximumConcurrency, int failedTryAgain) + { + AssetInfos = assetInfos; + DownloadBundleDependencies = downloadDependencies; + MaximumConcurrency = maximumConcurrency; + FailedTryAgain = failedTryAgain; + } + } + + /// + /// 资源下载选项 + /// + public struct ResourceDownloaderOptions + { + /// + /// 最大并发数量 + /// + public int MaximumConcurrency { get; set; } + + /// + /// 失败后的重试次数 + /// + public int FailedTryAgain { get; set; } + + /// + /// 资源标签列表 + /// 说明:如果列表为NULL,则下载所有资产 + /// + public string[] Tags { get; set; } + + public ResourceDownloaderOptions(int maximumConcurrency, int failedTryAgain) + { + Tags = null; + MaximumConcurrency = maximumConcurrency; + FailedTryAgain = failedTryAgain; + } + public ResourceDownloaderOptions(string tag, int maximumConcurrency, int failedTryAgain) + { + Tags = new string[] { tag }; + MaximumConcurrency = maximumConcurrency; + FailedTryAgain = failedTryAgain; + } + public ResourceDownloaderOptions(string[] tags, int maximumConcurrency, int failedTryAgain) + { + Tags = tags; + MaximumConcurrency = maximumConcurrency; + FailedTryAgain = failedTryAgain; + } + } + + /// + /// 资源解压选项 + /// + public struct ResourceUnpackerOptions + { + /// + /// 最大并发数量 + /// + public int MaximumConcurrency { get; set; } + + /// + /// 失败后的重试次数 + /// + public int FailedTryAgain { get; set; } + + /// + /// 资源标签列表 + /// 说明:如果列表为NULL,则解压所有资产 + /// + public string[] Tags { get; set; } + + public ResourceUnpackerOptions(int maximumConcurrency, int failedTryAgain) + { + Tags = null; + MaximumConcurrency = maximumConcurrency; + FailedTryAgain = failedTryAgain; + } + public ResourceUnpackerOptions(string tag, int maximumConcurrency, int failedTryAgain) + { + Tags = new string[] { tag }; + MaximumConcurrency = maximumConcurrency; + FailedTryAgain = failedTryAgain; + } + public ResourceUnpackerOptions(string[] tags, int maximumConcurrency, int failedTryAgain) + { + Tags = tags; + MaximumConcurrency = maximumConcurrency; + FailedTryAgain = failedTryAgain; + } + } + + /// + /// 资源导入选项 + /// + public struct BundleImporterOptions + { + /// + /// 最大并发数量 + /// + public int MaximumConcurrency { get; set; } + + /// + /// 失败后的重试次数 + /// + public int FailedTryAgain { get; set; } + + /// + /// 资源包信息列表 + /// + public ImportBundleInfo[] BundleInfos { get; set; } + + public BundleImporterOptions(ImportBundleInfo[] bundleInfos, int maximumConcurrency, int failedTryAgain) + { + BundleInfos = bundleInfos; + MaximumConcurrency = maximumConcurrency; + FailedTryAgain = failedTryAgain; + } + } + + /// + /// 导入的资源包信息 + /// + public struct ImportBundleInfo + { + /// + /// 本地文件路径 + /// + public string FilePath; + + /// + /// 资源包名称 + /// + public string BundleName; + + /// + /// 资源包GUID + /// + public string BundleGUID; + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOptions.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOptions.cs.meta new file mode 100644 index 00000000..882bf6fc --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2567b73a071bdc14884214cb5e3b5cc0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializePackageOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializePackageOperation.cs new file mode 100644 index 00000000..c6d5cce5 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializePackageOperation.cs @@ -0,0 +1,189 @@ +using System; + +namespace YooAsset +{ + public class InitializePackageOperation : AsyncOperationBase + { + private enum ESteps + { + None, + SetPlayMode, + CheckOptions, + CheckPlatform, + CreateCore, + InitFileSystem, + Done, + } + + private readonly ResourcePackage _package; + private readonly InitializePackageOptions _options; + private FileSystemHost _fileSystemHost; + private InitializeFileSystemOperation _initializeFileSystemOp; + private EPlayMode _playMode; + private ESteps _steps = ESteps.None; + + internal InitializePackageOperation(ResourcePackage package, InitializePackageOptions options) + { + _package = package; + _options = options; + } + internal override void InternalStart() + { + _steps = ESteps.SetPlayMode; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.SetPlayMode) + { + if (_options is EditorSimulateModeOptions) + _playMode = EPlayMode.EditorSimulateMode; + else if (_options is OfflinePlayModeOptions) + _playMode = EPlayMode.OfflinePlayMode; + else if (_options is HostPlayModeOptions) + _playMode = EPlayMode.HostPlayMode; + else if (_options is WebPlayModeOptions) + _playMode = EPlayMode.WebPlayMode; + else if (_options is CustomPlayModeOptions) + _playMode = EPlayMode.CustomPlayMode; + else + throw new NotImplementedException($"{_options.GetType().Name}"); + + _steps = ESteps.CheckOptions; + } + + if (_steps == ESteps.CheckOptions) + { + // 检测初始化参数 + if (_options.BundleLoadingMaxConcurrency <= 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"{nameof(_options.BundleLoadingMaxConcurrency)} value must be greater than zero."; + YooLogger.Error(Error); + return; + } + + _steps = ESteps.CheckPlatform; + } + + if (_steps == ESteps.CheckPlatform) + { +#if !UNITY_EDITOR + if (_playMode == EPlayMode.EditorSimulateMode) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Editor simulate mode only support unity editor."; + YooLogger.Error(Error); + return; + } +#endif + +#if UNITY_WEBGL + if (_playMode != EPlayMode.EditorSimulateMode) + { + if (_playMode != EPlayMode.WebPlayMode) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"{_playMode} can not support WebGL plateform."; + YooLogger.Error(Error); + return; + } + } +#endif + +#if !UNITY_WEBGL + if (_playMode != EPlayMode.EditorSimulateMode) + { + if (_playMode == EPlayMode.WebPlayMode) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"{nameof(EPlayMode.WebPlayMode)} only support WebGL plateform."; + YooLogger.Error(Error); + return; + } + } +#endif + + _steps = ESteps.CreateCore; + } + + if (_steps == ESteps.CreateCore) + { + string packageName = _package.PackageName; + var resourceManager = new ResourceManager(packageName); + var fileSystemHost = new FileSystemHost(packageName); + resourceManager.Initialize(_options, fileSystemHost); + + _fileSystemHost = fileSystemHost; + _package.InternalInitialize(resourceManager, fileSystemHost); + _steps = ESteps.InitFileSystem; + } + + if (_steps == ESteps.InitFileSystem) + { + if (_initializeFileSystemOp == null) + { + if (_playMode == EPlayMode.EditorSimulateMode) + { + var initializeParameters = _options as EditorSimulateModeOptions; + _initializeFileSystemOp = _fileSystemHost.InitializeAsync(initializeParameters.EditorFileSystemParameters); + } + else if (_playMode == EPlayMode.OfflinePlayMode) + { + var initializeParameters = _options as OfflinePlayModeOptions; + _initializeFileSystemOp = _fileSystemHost.InitializeAsync(initializeParameters.BuildinFileSystemParameters); + } + else if (_playMode == EPlayMode.HostPlayMode) + { + var initializeParameters = _options as HostPlayModeOptions; + _initializeFileSystemOp = _fileSystemHost.InitializeAsync(initializeParameters.BuildinFileSystemParameters, initializeParameters.CacheFileSystemParameters); + } + else if (_playMode == EPlayMode.WebPlayMode) + { + var initializeParameters = _options as WebPlayModeOptions; + _initializeFileSystemOp = _fileSystemHost.InitializeAsync(initializeParameters.WebServerFileSystemParameters, initializeParameters.WebRemoteFileSystemParameters); + } + else if (_playMode == EPlayMode.CustomPlayMode) + { + var initializeParameters = _options as CustomPlayModeOptions; + _initializeFileSystemOp = _fileSystemHost.InitializeAsync(initializeParameters.FileSystemParameterList); + } + else + { + throw new NotImplementedException(_playMode.ToString()); + } + + _initializeFileSystemOp.StartOperation(); + AddChildOperation(_initializeFileSystemOp); + } + + _initializeFileSystemOp.UpdateOperation(); + if (_initializeFileSystemOp.IsDone == false) + return; + + if (_initializeFileSystemOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _initializeFileSystemOp.Error; + YooLogger.Error(Error); + } + } + } + internal override string InternalGetDescription() + { + return $"PlayMode : {_playMode}"; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializePackageOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializePackageOperation.cs.meta new file mode 100644 index 00000000..020ffd35 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializePackageOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ecb6fb1cbab9e0242849d2657f438478 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/InitializeParameters.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializePackageOptions.cs similarity index 64% rename from Assets/YooAsset/Runtime/InitializeParameters.cs rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializePackageOptions.cs index 387a6b62..b16ba623 100644 --- a/Assets/YooAsset/Runtime/InitializeParameters.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializePackageOptions.cs @@ -2,41 +2,10 @@ namespace YooAsset { - /// - /// 运行模式 - /// - public enum EPlayMode - { - /// - /// 编辑器下的模拟模式 - /// - EditorSimulateMode, - - /// - /// 离线运行模式 - /// - OfflinePlayMode, - - /// - /// 联机运行模式 - /// - HostPlayMode, - - /// - /// WebGL运行模式 - /// - WebPlayMode, - - /// - /// 自定义运行模式 - /// - CustomPlayMode, - } - /// /// 初始化参数 /// - public abstract class InitializeParameters + public abstract class InitializePackageOptions { /// /// 同时加载Bundle文件的最大并发数 @@ -57,7 +26,7 @@ namespace YooAsset /// /// 编辑器下模拟运行模式的初始化参数 /// - public class EditorSimulateModeParameters : InitializeParameters + public class EditorSimulateModeOptions : InitializePackageOptions { public FileSystemParameters EditorFileSystemParameters; } @@ -65,7 +34,7 @@ namespace YooAsset /// /// 离线运行模式的初始化参数 /// - public class OfflinePlayModeParameters : InitializeParameters + public class OfflinePlayModeOptions : InitializePackageOptions { public FileSystemParameters BuildinFileSystemParameters; } @@ -73,7 +42,7 @@ namespace YooAsset /// /// 联机运行模式的初始化参数 /// - public class HostPlayModeParameters : InitializeParameters + public class HostPlayModeOptions : InitializePackageOptions { public FileSystemParameters BuildinFileSystemParameters; public FileSystemParameters CacheFileSystemParameters; @@ -82,7 +51,7 @@ namespace YooAsset /// /// WebGL运行模式的初始化参数 /// - public class WebPlayModeParameters : InitializeParameters + public class WebPlayModeOptions : InitializePackageOptions { public FileSystemParameters WebServerFileSystemParameters; public FileSystemParameters WebRemoteFileSystemParameters; @@ -91,7 +60,7 @@ namespace YooAsset /// /// 自定义运行模式的初始化参数 /// - public class CustomPlayModeParameters : InitializeParameters + public class CustomPlayModeOptions : InitializePackageOptions { /// /// 文件系统初始化参数列表 diff --git a/Assets/YooAsset/Runtime/InitializeParameters.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializePackageOptions.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/InitializeParameters.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializePackageOptions.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DeserializeManifestOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DeserializeManifestOperation.cs index d354e63c..7da89566 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DeserializeManifestOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DeserializeManifestOperation.cs @@ -31,7 +31,7 @@ namespace YooAsset /// /// 解析的清单实例 /// - public PackageManifest Manifest { private set; get; } + public PackageManifest Manifest { get; private set; } public DeserializeManifestOperation(IManifestRestoreServices services, byte[] binaryData) { @@ -47,187 +47,170 @@ namespace YooAsset if (_steps == ESteps.None || _steps == ESteps.Done) return; - try + if (_steps == ESteps.RestoreFileData) { - if (_steps == ESteps.RestoreFileData) + if (_services != null) { - if (_services != null) - { - var resultData = _services.RestoreManifest(_sourceData); - if (resultData != null) - _sourceData = resultData; - } - - _buffer = new BufferReader(_sourceData); - _steps = ESteps.DeserializeFileHeader; + var resultData = _services.RestoreManifest(_sourceData); + if (resultData != null) + _sourceData = resultData; } - if (_steps == ESteps.DeserializeFileHeader) + _buffer = new BufferReader(_sourceData); + _steps = ESteps.DeserializeFileHeader; + } + + if (_steps == ESteps.DeserializeFileHeader) + { + if (_buffer.IsValid == false) { - if (_buffer.IsValid == false) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Buffer is invalid !"; - return; - } - - // 读取文件标记 - uint fileSign = _buffer.ReadUInt32(); - if (fileSign != ManifestDefine.FileSign) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "The manifest file format is invalid !"; - return; - } - - // 读取文件版本 - string fileVersion = _buffer.ReadUTF8(); - Version fileVer = new Version(fileVersion); - Version ver2025_8_28 = new Version(ManifestDefine.VERSION_2025_8_28); - Version ver2025_9_30 = new Version(ManifestDefine.VERSION_2025_9_30); - if (fileVer < ver2025_8_28) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"The manifest file version are not compatible : {fileVersion} != {ManifestDefine.FileVersion}"; - return; - } - - // 读取文件头信息 - Manifest = new PackageManifest(); - Manifest.FileVersion = fileVersion; - Manifest.EnableAddressable = _buffer.ReadBool(); - Manifest.SupportExtensionless = _buffer.ReadBool(); - Manifest.LocationToLower = _buffer.ReadBool(); - Manifest.IncludeAssetGUID = _buffer.ReadBool(); - if (fileVer >= ver2025_9_30) - Manifest.ReplaceAssetPathWithAddress = _buffer.ReadBool(); - else - Manifest.ReplaceAssetPathWithAddress = false; - Manifest.OutputNameStyle = _buffer.ReadInt32(); - Manifest.BuildBundleType = _buffer.ReadInt32(); - Manifest.BuildPipeline = _buffer.ReadUTF8(); - Manifest.PackageName = _buffer.ReadUTF8(); - Manifest.PackageVersion = _buffer.ReadUTF8(); - Manifest.PackageNote = _buffer.ReadUTF8(); - - // 检测配置 - if (Manifest.EnableAddressable && Manifest.LocationToLower) - throw new YooManifestException("Addressable not support location to lower !"); - if (Manifest.EnableAddressable == false && Manifest.ReplaceAssetPathWithAddress) - throw new YooManifestException("Replace asset path with address need enable Addressable !"); - - _steps = ESteps.PrepareAssetList; - } - - if (_steps == ESteps.PrepareAssetList) - { - _packageAssetCount = _buffer.ReadInt32(); - _progressTotalValue = _packageAssetCount; - CreateAssetCollection(Manifest, _packageAssetCount); - _steps = ESteps.DeserializeAssetList; - } - if (_steps == ESteps.DeserializeAssetList) - { - bool replaceAssetPath = false; - if (UnityEngine.Application.isPlaying) - { - if (Manifest.EnableAddressable && Manifest.ReplaceAssetPathWithAddress) - replaceAssetPath = true; - } - - while (_packageAssetCount > 0) - { - var packageAsset = new PackageAsset(); - packageAsset.Address = _buffer.ReadUTF8(); - if (replaceAssetPath) - { - packageAsset.AssetPath = packageAsset.Address; - _buffer.SkipUTF8(); //跳过解析AssetPath - } - else - { - packageAsset.AssetPath = _buffer.ReadUTF8(); - } - packageAsset.AssetGUID = _buffer.ReadUTF8(); - packageAsset.AssetTags = _buffer.ReadUTF8Array(); - packageAsset.BundleID = _buffer.ReadInt32(); - packageAsset.DependBundleIDs = _buffer.ReadInt32Array(); - FillAssetCollection(Manifest, packageAsset, replaceAssetPath); - - _packageAssetCount--; - Progress = 1f - _packageAssetCount / _progressTotalValue; - if (IsBusy) - break; - } - - if (_packageAssetCount <= 0) - { - _steps = ESteps.PrepareBundleList; - } - } - - if (_steps == ESteps.PrepareBundleList) - { - _packageBundleCount = _buffer.ReadInt32(); - _progressTotalValue = _packageBundleCount; - CreateBundleCollection(Manifest, _packageBundleCount); - _steps = ESteps.DeserializeBundleList; - } - if (_steps == ESteps.DeserializeBundleList) - { - while (_packageBundleCount > 0) - { - var packageBundle = new PackageBundle(); - packageBundle.BundleName = _buffer.ReadUTF8(); - packageBundle.UnityCRC = _buffer.ReadUInt32(); - packageBundle.FileHash = _buffer.ReadUTF8(); - packageBundle.FileCRC = _buffer.ReadUInt32(); - packageBundle.FileSize = _buffer.ReadInt64(); - packageBundle.Encrypted = _buffer.ReadBool(); - packageBundle.Tags = _buffer.ReadUTF8Array(); - packageBundle.DependBundleIDs = _buffer.ReadInt32Array(); - FillBundleCollection(Manifest, packageBundle); - - _packageBundleCount--; - Progress = 1f - _packageBundleCount / _progressTotalValue; - if (IsBusy) - break; - } - - if (_packageBundleCount <= 0) - { - _steps = ESteps.InitManifest; - } - } - - if (_steps == ESteps.InitManifest) - { - Manifest.Initialize(); _steps = ESteps.Done; - Status = EOperationStatus.Succeed; + Status = EOperationStatus.Failed; + Error = "Buffer is invalid."; + return; + } + + // 读取文件标记 + uint fileSign = _buffer.ReadUInt32(); + if (fileSign != PackageManifestDefine.FileSign) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "The manifest file format is invalid."; + return; + } + + // 读取文件版本 + string fileVersion = _buffer.ReadUTF8(); + Version fileVer = new Version(fileVersion); + Version ver2025_8_28 = new Version(PackageManifestDefine.VERSION_2025_8_28); + Version ver2025_9_30 = new Version(PackageManifestDefine.VERSION_2025_9_30); + if (fileVer < ver2025_8_28) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"The manifest version is lower than the minimum compatible version : {fileVer} < {ver2025_8_28}"; + return; + } + + // 读取文件头信息 + Manifest = new PackageManifest(); + Manifest.FileVersion = fileVersion; + Manifest.EnableAddressable = _buffer.ReadBool(); + Manifest.SupportExtensionless = _buffer.ReadBool(); + Manifest.LocationToLower = _buffer.ReadBool(); + Manifest.IncludeAssetGUID = _buffer.ReadBool(); + if (fileVer >= ver2025_9_30) + Manifest.ReplaceAssetPathWithAddress = _buffer.ReadBool(); + else + Manifest.ReplaceAssetPathWithAddress = false; + Manifest.OutputNameStyle = _buffer.ReadInt32(); + Manifest.BuildBundleType = _buffer.ReadInt32(); + Manifest.BuildPipeline = _buffer.ReadUTF8(); + Manifest.PackageName = _buffer.ReadUTF8(); + Manifest.PackageVersion = _buffer.ReadUTF8(); + Manifest.PackageNote = _buffer.ReadUTF8(); + + // 检测配置 + if (Manifest.EnableAddressable && Manifest.LocationToLower) + throw new YooManifestException("Addressable not support location to lower."); + if (Manifest.EnableAddressable == false && Manifest.ReplaceAssetPathWithAddress) + throw new YooManifestException("Replace asset path with address need enable Addressable."); + + _steps = ESteps.PrepareAssetList; + } + + if (_steps == ESteps.PrepareAssetList) + { + _packageAssetCount = _buffer.ReadInt32(); + _progressTotalValue = _packageAssetCount; + CreateAssetCollection(Manifest, _packageAssetCount); + _steps = ESteps.DeserializeAssetList; + } + if (_steps == ESteps.DeserializeAssetList) + { + bool replaceAssetPath = false; + if (UnityEngine.Application.isPlaying) + { + if (Manifest.EnableAddressable && Manifest.ReplaceAssetPathWithAddress) + replaceAssetPath = true; + } + + while (_packageAssetCount > 0) + { + var packageAsset = new PackageAsset(); + packageAsset.Address = _buffer.ReadUTF8(); + if (replaceAssetPath) + { + packageAsset.AssetPath = packageAsset.Address; + _buffer.SkipUTF8(); //跳过解析AssetPath + } + else + { + packageAsset.AssetPath = _buffer.ReadUTF8(); + } + packageAsset.AssetGUID = _buffer.ReadUTF8(); + packageAsset.AssetTags = _buffer.ReadUTF8Array(); + packageAsset.BundleID = _buffer.ReadInt32(); + packageAsset.DependBundleIDs = _buffer.ReadInt32Array(); + FillAssetCollection(Manifest, packageAsset, replaceAssetPath); + + _packageAssetCount--; + Progress = 1f - (_packageAssetCount / (float)_progressTotalValue); + if (IsBusy) + break; + } + + if (_packageAssetCount <= 0) + { + _steps = ESteps.PrepareBundleList; } } - catch (System.Exception ex) + + if (_steps == ESteps.PrepareBundleList) { - Manifest = null; + _packageBundleCount = _buffer.ReadInt32(); + _progressTotalValue = _packageBundleCount; + CreateBundleCollection(Manifest, _packageBundleCount); + _steps = ESteps.DeserializeBundleList; + } + if (_steps == ESteps.DeserializeBundleList) + { + while (_packageBundleCount > 0) + { + var packageBundle = new PackageBundle(); + packageBundle.BundleName = _buffer.ReadUTF8(); + packageBundle.UnityCRC = _buffer.ReadUInt32(); + packageBundle.FileHash = _buffer.ReadUTF8(); + packageBundle.FileCRC = _buffer.ReadUInt32(); + packageBundle.FileSize = _buffer.ReadInt64(); + packageBundle.Encrypted = _buffer.ReadBool(); + packageBundle.Tags = _buffer.ReadUTF8Array(); + packageBundle.DependBundleIDs = _buffer.ReadInt32Array(); + FillBundleCollection(Manifest, packageBundle); + + _packageBundleCount--; + Progress = 1f - (_packageBundleCount / (float)_progressTotalValue); + if (IsBusy) + break; + } + + if (_packageBundleCount <= 0) + { + _steps = ESteps.InitManifest; + } + } + + if (_steps == ESteps.InitManifest) + { + Manifest.Initialize(); _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = ex.Message; + Status = EOperationStatus.Succeed; } } internal override void InternalWaitForAsyncComplete() { - while (true) - { - if (ExecuteWhileDone()) - { - _steps = ESteps.Done; - break; - } - } + RunBatchExecution(); } private void CreateAssetCollection(PackageManifest manifest, int assetCount) diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializationOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/InitializeFileSystemOperation.cs similarity index 76% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializationOperation.cs rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/InitializeFileSystemOperation.cs index 3ba384ed..c331bb1e 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializationOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/InitializeFileSystemOperation.cs @@ -3,27 +3,26 @@ using System.Linq; namespace YooAsset { - public class InitializationOperation : AsyncOperationBase + public class InitializeFileSystemOperation : AsyncOperationBase { private enum ESteps { None, Prepare, - ClearOldFileSystem, InitFileSystem, CheckInitResult, Done, } - private readonly PlayModeImpl _impl; + private readonly FileSystemHost _host; private readonly List _parametersList; private List _cloneList; - private FSInitializeFileSystemOperation _initFileSystemOp; + private FSInitializeOperation _initFileSystemOp; private ESteps _steps = ESteps.None; - - internal InitializationOperation(PlayModeImpl impl, List parametersList) + + internal InitializeFileSystemOperation(FileSystemHost host, List parametersList) { - _impl = impl; + _host = host; _parametersList = parametersList; } internal override void InternalStart() @@ -41,7 +40,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "The file system parameters is empty !"; + Error = "The file system parameters is empty."; return; } @@ -51,24 +50,12 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "An empty object exists in the list!"; + Error = "An empty object exists in the list."; return; } } _cloneList = _parametersList.ToList(); - _steps = ESteps.ClearOldFileSystem; - } - - if (_steps == ESteps.ClearOldFileSystem) - { - // 注意:初始化失败后可能会残存一些旧的文件系统! - foreach (var fileSystem in _impl.FileSystems) - { - fileSystem.OnDestroy(); - } - - _impl.FileSystems.Clear(); _steps = ESteps.InitFileSystem; } @@ -84,17 +71,17 @@ namespace YooAsset var fileSystemParams = _cloneList[0]; _cloneList.RemoveAt(0); - IFileSystem fileSystemInstance = fileSystemParams.CreateFileSystem(_impl.PackageName); + IFileSystem fileSystemInstance = fileSystemParams.CreateFileSystem(_host.PackageName); if (fileSystemInstance == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Failed to create file system instance !"; + Error = "Failed to create file system instance."; return; } - _impl.FileSystems.Add(fileSystemInstance); - _initFileSystemOp = fileSystemInstance.InitializeFileSystemAsync(); + _host.FileSystems.Add(fileSystemInstance); + _initFileSystemOp = fileSystemInstance.InitializeAsync(); _initFileSystemOp.StartOperation(); AddChildOperation(_initFileSystemOp); _steps = ESteps.CheckInitResult; @@ -121,9 +108,5 @@ namespace YooAsset } } } - internal override string InternalGetDesc() - { - return $"PlayMode : {_impl.PlayMode}"; - } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializationOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/InitializeFileSystemOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializationOperation.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/InitializeFileSystemOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageManifestOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/LoadManifestOperation.cs similarity index 70% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageManifestOperation.cs rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/LoadManifestOperation.cs index 2bfe7770..75cd4532 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/LoadManifestOperation.cs @@ -1,7 +1,7 @@  namespace YooAsset { - public sealed class UpdatePackageManifestOperation : AsyncOperationBase + public sealed class LoadManifestOperation : AsyncOperationBase { private enum ESteps { @@ -12,17 +12,15 @@ namespace YooAsset Done, } - private readonly PlayModeImpl _impl; - private readonly string _packageVersion; - private readonly int _timeout; - private FSLoadPackageManifestOperation _loadPackageManifestOp; + private readonly FileSystemHost _host; + private readonly LoadManifestOptions _options; + private FSLoadManifestOperation _loadPackageManifestOp; private ESteps _steps = ESteps.None; - internal UpdatePackageManifestOperation(PlayModeImpl impl, string packageVersion, int timeout) + internal LoadManifestOperation(FileSystemHost host, LoadManifestOptions options) { - _impl = impl; - _packageVersion = packageVersion; - _timeout = timeout; + _host = host; + _options = options; } internal override void InternalStart() { @@ -35,7 +33,7 @@ namespace YooAsset if (_steps == ESteps.CheckParams) { - if (string.IsNullOrEmpty(_packageVersion)) + if (string.IsNullOrEmpty(_options.PackageVersion)) { _steps = ESteps.Done; Status = EOperationStatus.Failed; @@ -50,7 +48,7 @@ namespace YooAsset if (_steps == ESteps.CheckActiveManifest) { // 检测当前激活的清单对象 - if (_impl.ActiveManifest != null && _impl.ActiveManifest.PackageVersion == _packageVersion) + if (_host.ActiveManifest != null && _host.ActiveManifest.PackageVersion == _options.PackageVersion) { _steps = ESteps.Done; Status = EOperationStatus.Succeed; @@ -65,8 +63,8 @@ namespace YooAsset { if (_loadPackageManifestOp == null) { - var mainFileSystem = _impl.GetMainFileSystem(); - _loadPackageManifestOp = mainFileSystem.LoadPackageManifestAsync(_packageVersion, _timeout); + var mainFileSystem = _host.GetMainFileSystem(); + _loadPackageManifestOp = mainFileSystem.LoadManifestAsync(_options); _loadPackageManifestOp.StartOperation(); AddChildOperation(_loadPackageManifestOp); } @@ -78,7 +76,7 @@ namespace YooAsset if (_loadPackageManifestOp.Status == EOperationStatus.Succeed) { _steps = ESteps.Done; - _impl.ActiveManifest = _loadPackageManifestOp.Manifest; + _host.SetActiveManifest(_loadPackageManifestOp.Manifest); Status = EOperationStatus.Succeed; } else @@ -89,9 +87,9 @@ namespace YooAsset } } } - internal override string InternalGetDesc() + internal override string InternalGetDescription() { - return $"PackageVersion : {_packageVersion}"; + return $"PackageVersion : {_options.PackageVersion}"; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/LoadManifestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageManifestOperation.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/LoadManifestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/LoadManifestOptions.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/LoadManifestOptions.cs new file mode 100644 index 00000000..43e91ced --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/LoadManifestOptions.cs @@ -0,0 +1,22 @@ + +namespace YooAsset +{ + public struct LoadManifestOptions + { + /// + /// 包裹版本 + /// + public string PackageVersion { get; set; } + + /// + /// 超时时间 + /// + public int Timeout { get; set; } + + public LoadManifestOptions(string packageVersion, int timeout) + { + PackageVersion = packageVersion; + Timeout = timeout; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/LoadManifestOptions.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/LoadManifestOptions.cs.meta new file mode 100644 index 00000000..8b8efe21 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/LoadManifestOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02958c7c4e947ae4b95472741e166cb6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs deleted file mode 100644 index 5326a3f5..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs +++ /dev/null @@ -1,204 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset -{ - public sealed class PreDownloadContentOperation : AsyncOperationBase - { - private enum ESteps - { - None, - CheckParams, - CheckActiveManifest, - LoadPackageManifest, - Done, - } - - private readonly PlayModeImpl _impl; - private readonly string _packageVersion; - private readonly int _timeout; - private FSLoadPackageManifestOperation _loadPackageManifestOp; - private PackageManifest _manifest; - private ESteps _steps = ESteps.None; - - - internal PreDownloadContentOperation(PlayModeImpl impl, string packageVersion, int timeout) - { - _impl = impl; - _packageVersion = packageVersion; - _timeout = timeout; - } - internal override void InternalStart() - { - _steps = ESteps.CheckParams; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.CheckParams) - { - if (string.IsNullOrEmpty(_packageVersion)) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Package version is null or empty."; - return; - } - - _steps = ESteps.CheckActiveManifest; - } - - if (_steps == ESteps.CheckActiveManifest) - { - // 检测当前激活的清单对象 - if (_impl.ActiveManifest != null) - { - if (_impl.ActiveManifest.PackageVersion == _packageVersion) - { - _manifest = _impl.ActiveManifest; - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - return; - } - } - _steps = ESteps.LoadPackageManifest; - } - - if (_steps == ESteps.LoadPackageManifest) - { - if (_loadPackageManifestOp == null) - { - var mainFileSystem = _impl.GetMainFileSystem(); - _loadPackageManifestOp = mainFileSystem.LoadPackageManifestAsync(_packageVersion, _timeout); - _loadPackageManifestOp.StartOperation(); - AddChildOperation(_loadPackageManifestOp); - } - - _loadPackageManifestOp.UpdateOperation(); - if (_loadPackageManifestOp.IsDone == false) - return; - - if (_loadPackageManifestOp.Status == EOperationStatus.Succeed) - { - _manifest = _loadPackageManifestOp.Manifest; - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _loadPackageManifestOp.Error; - } - } - } - - /// - /// 创建资源下载器,用于下载当前资源版本所有的资源包文件 - /// - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain) - { - if (Status != EOperationStatus.Succeed) - { - YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain); - } - - List downloadList = _impl.GetDownloadListByAll(_manifest); - var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain); - return operation; - } - - /// - /// 创建资源下载器,用于下载指定的资源标签关联的资源包文件 - /// - /// 资源标签 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain) - { - if (Status != EOperationStatus.Succeed) - { - YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain); - } - - List downloadList = _impl.GetDownloadListByTags(_manifest, new string[] { tag }); - var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain); - return operation; - } - - /// - /// 创建资源下载器,用于下载指定的资源标签列表关联的资源包文件 - /// - /// 资源标签列表 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain) - { - if (Status != EOperationStatus.Succeed) - { - YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain); - } - - List downloadList = _impl.GetDownloadListByTags(_manifest, tags); - var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain); - return operation; - } - - /// - /// 创建资源下载器,用于下载指定的资源依赖的资源包文件 - /// - /// 资源定位地址 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public ResourceDownloaderOperation CreateBundleDownloader(string location, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain) - { - if (Status != EOperationStatus.Succeed) - { - YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain); - } - - List assetInfos = new List(); - var assetInfo = _manifest.ConvertLocationToAssetInfo(location, null); - assetInfos.Add(assetInfo); - - List downloadList = _impl.GetDownloadListByPaths(_manifest, assetInfos.ToArray(), recursiveDownload); - var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain); - return operation; - } - - /// - /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 - /// - /// 资源定位地址列表 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public ResourceDownloaderOperation CreateBundleDownloader(string[] locations, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain) - { - if (Status != EOperationStatus.Succeed) - { - YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain); - } - - List assetInfos = new List(locations.Length); - foreach (var location in locations) - { - var assetInfo = _manifest.ConvertLocationToAssetInfo(location, null); - assetInfos.Add(assetInfo); - } - - List downloadList = _impl.GetDownloadListByPaths(_manifest, assetInfos.ToArray(), recursiveDownload); - var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain); - return operation; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloaderOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloaderOperation.cs new file mode 100644 index 00000000..aab2a0e0 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloaderOperation.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace YooAsset +{ + public sealed class PreDownloaderOperation : AsyncOperationBase + { + private enum ESteps + { + None, + CheckParams, + CheckActiveManifest, + LoadPackageManifest, + Done, + } + + private readonly FileSystemHost _host; + private readonly PreDownloaderOptions _options; + private FSLoadManifestOperation _loadPackageManifestOp; + private PackageManifest _manifest; + private ESteps _steps = ESteps.None; + + + internal PreDownloaderOperation(FileSystemHost host, PreDownloaderOptions options) + { + _host = host; + _options = options; + } + internal override void InternalStart() + { + _steps = ESteps.CheckParams; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckParams) + { + if (string.IsNullOrEmpty(_options.PackageVersion)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Package version is null or empty."; + return; + } + + _steps = ESteps.CheckActiveManifest; + } + + if (_steps == ESteps.CheckActiveManifest) + { + // 检测当前激活的清单对象 + if (_host.ActiveManifest != null) + { + if (_host.ActiveManifest.PackageVersion == _options.PackageVersion) + { + _manifest = _host.ActiveManifest; + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + return; + } + } + _steps = ESteps.LoadPackageManifest; + } + + if (_steps == ESteps.LoadPackageManifest) + { + if (_loadPackageManifestOp == null) + { + var mainFileSystem = _host.GetMainFileSystem(); + var options = new LoadManifestOptions(_options.PackageVersion, _options.Timeout); + _loadPackageManifestOp = mainFileSystem.LoadManifestAsync(options); + _loadPackageManifestOp.StartOperation(); + AddChildOperation(_loadPackageManifestOp); + } + + _loadPackageManifestOp.UpdateOperation(); + if (_loadPackageManifestOp.IsDone == false) + return; + + if (_loadPackageManifestOp.Status == EOperationStatus.Succeed) + { + _manifest = _loadPackageManifestOp.Manifest; + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadPackageManifestOp.Error; + } + } + } + + /// + /// 创建资源下载器,用于下载指定的资源标签列表关联的资源包文件 + /// + public ResourceDownloaderOperation CreateResourceDownloader(ResourceDownloaderOptions options) + { + if (Status != EOperationStatus.Succeed) + { + YooLogger.Error($"{nameof(PreDownloaderOperation)} status is not succeed."); + return ResourceDownloaderOperation.CreateEmptyDownloader(_host.PackageName); + } + + return _host.CreateResourceDownloader(_manifest, options); + } + + /// + /// 创建资源下载器,用于下载指定的资源信息列表依赖的资源包文件 + /// + public ResourceDownloaderOperation CreateBundleDownloader(BundleDownloaderOptions options) + { + if (Status != EOperationStatus.Succeed) + { + YooLogger.Error($"{nameof(PreDownloaderOperation)} status is not succeed."); + return ResourceDownloaderOperation.CreateEmptyDownloader(_host.PackageName); + } + + return _host.CreateResourceDownloader(_manifest, options); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloaderOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloaderOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloaderOptions.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloaderOptions.cs new file mode 100644 index 00000000..9921df90 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloaderOptions.cs @@ -0,0 +1,22 @@ + +namespace YooAsset +{ + public struct PreDownloaderOptions + { + /// + /// 预下载的包裹版本 + /// + public string PackageVersion { get; set; } + + /// + /// 资源清单请求超时时间 + /// + public int Timeout { get; set; } + + public PreDownloaderOptions(string packageVersion, int timeout) + { + PackageVersion = packageVersion; + Timeout = timeout; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloaderOptions.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloaderOptions.cs.meta new file mode 100644 index 00000000..1fff0445 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloaderOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e6ccb056c8ca90c49a01cc15aa75a513 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestPackageVersionOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestVersionOperation.cs similarity index 67% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestVersionOperation.cs index adc3cfd3..ff1518ee 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestVersionOperation.cs @@ -1,14 +1,7 @@  namespace YooAsset { - public abstract class RequestPackageVersionOperation : AsyncOperationBase - { - /// - /// 当前最新的包裹版本 - /// - public string PackageVersion { protected set; get; } - } - internal sealed class RequestPackageVersionImplOperation : RequestPackageVersionOperation + public sealed class RequestVersionOperation : AsyncOperationBase { private enum ESteps { @@ -17,17 +10,21 @@ namespace YooAsset Done, } - private readonly PlayModeImpl _impl; - private readonly bool _appendTimeTicks; - private readonly int _timeout; - private FSRequestPackageVersionOperation _requestPackageVersionOp; + private readonly FileSystemHost _host; + private readonly RequestVersionOptions _options; + private FSRequestVersionOperation _requestPackageVersionOp; private ESteps _steps = ESteps.None; - internal RequestPackageVersionImplOperation(PlayModeImpl impl, bool appendTimeTicks, int timeout) + /// + /// 当前最新的包裹版本 + /// + public string PackageVersion { get; private set; } + + + internal RequestVersionOperation(FileSystemHost host, RequestVersionOptions options) { - _impl = impl; - _appendTimeTicks = appendTimeTicks; - _timeout = timeout; + _host = host; + _options = options; } internal override void InternalStart() { @@ -42,8 +39,8 @@ namespace YooAsset { if (_requestPackageVersionOp == null) { - var mainFileSystem = _impl.GetMainFileSystem(); - _requestPackageVersionOp = mainFileSystem.RequestPackageVersionAsync(_appendTimeTicks, _timeout); + var mainFileSystem = _host.GetMainFileSystem(); + _requestPackageVersionOp = mainFileSystem.RequestVersionAsync(_options); _requestPackageVersionOp.StartOperation(); AddChildOperation(_requestPackageVersionOp); } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestPackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestVersionOptions.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestVersionOptions.cs new file mode 100644 index 00000000..d5f21c45 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestVersionOptions.cs @@ -0,0 +1,22 @@ + +namespace YooAsset +{ + public struct RequestVersionOptions + { + /// + /// 在URL末尾添加时间戳 + /// + public bool AppendTimeTicks { get; set; } + + /// + /// 超时时间 + /// + public int Timeout { get; set; } + + public RequestVersionOptions(bool appendTimeTicks, int timeout) + { + AppendTimeTicks = appendTimeTicks; + Timeout = timeout; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestVersionOptions.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestVersionOptions.cs.meta new file mode 100644 index 00000000..a372a02b --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestVersionOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e89594016c3fa69499adf8d642490ed6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs index a8ebeaeb..a1c3a290 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs @@ -122,8 +122,8 @@ namespace YooAsset { _mainfest = manifest; _bundleType = manifest.BuildBundleType; - _fileExtension = ManifestTools.GetRemoteBundleFileExtension(BundleName); - _fileName = ManifestTools.GetRemoteBundleFileName(manifest.OutputNameStyle, BundleName, _fileExtension, FileHash); + _fileExtension = PackageManifestTools.GetRemoteBundleFileExtension(BundleName); + _fileName = PackageManifestTools.GetRemoteBundleFileName(manifest.OutputNameStyle, BundleName, _fileExtension, FileHash); } /// @@ -162,10 +162,7 @@ namespace YooAsset /// public bool HasAnyTags() { - if (Tags != null && Tags.Length > 0) - return true; - else - return false; + return Tags != null && Tags.Length > 0; } /// diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs index c46a41b3..d433d70b 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs @@ -335,7 +335,7 @@ namespace YooAsset { string error; if (string.IsNullOrEmpty(location)) - error = $"The location is null or empty !"; + error = $"The location is null or empty."; else error = $"The location is invalid : {location}"; AssetInfo assetInfo = new AssetInfo(PackageName, error); @@ -369,8 +369,8 @@ namespace YooAsset { if (IncludeAssetGUID == false) { - YooLogger.Warning("Package manifest not include asset guid ! Please check asset bundle collector settings."); - AssetInfo assetInfo = new AssetInfo(PackageName, "AssetGUID data is empty !"); + YooLogger.Warning("Package manifest not include asset guid. Please check asset bundle collector settings."); + AssetInfo assetInfo = new AssetInfo(PackageName, "AssetGUID data is empty."); return assetInfo; } @@ -384,7 +384,7 @@ namespace YooAsset { string error; if (string.IsNullOrEmpty(assetGUID)) - error = $"The assetGUID is null or empty !"; + error = $"The assetGUID is null or empty."; else error = $"The assetGUID is invalid : {assetGUID}"; AssetInfo assetInfo = new AssetInfo(PackageName, error); diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ManifestDefine.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestDefine.cs similarity index 77% rename from Assets/YooAsset/Runtime/ResourcePackage/ManifestDefine.cs rename to Assets/YooAsset/Runtime/ResourcePackage/PackageManifestDefine.cs index 91a9e93f..6914b1ca 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/ManifestDefine.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestDefine.cs @@ -1,7 +1,7 @@  namespace YooAsset { - public class ManifestDefine + internal class PackageManifestDefine { /// /// 文件极限大小(100MB) @@ -19,10 +19,5 @@ namespace YooAsset public const string FileVersion = "2025.9.30"; public const string VERSION_2025_8_28 = "2025.8.28"; public const string VERSION_2025_9_30 = "2025.9.30"; - - /// - /// 版本兼容 - /// - public const bool BackwardCompatible = true; } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ManifestDefine.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestDefine.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/ManifestDefine.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/PackageManifestDefine.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ManifestTools.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestHelper.cs similarity index 80% rename from Assets/YooAsset/Runtime/ResourcePackage/ManifestTools.cs rename to Assets/YooAsset/Runtime/ResourcePackage/PackageManifestHelper.cs index f27792e8..7531af11 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/ManifestTools.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestHelper.cs @@ -6,8 +6,10 @@ using UnityEngine; namespace YooAsset { - internal static class ManifestTools + internal static class PackageManifestTools { + private const int MD5HashLength = 32; //MD5的哈希值通常为32个字符 + /// /// 验证清单文件的二进制数据 /// @@ -18,18 +20,14 @@ namespace YooAsset if (string.IsNullOrEmpty(hashValue)) return false; - // 注意:兼容俩种验证方式 - // 注意:计算MD5的哈希值通常为32个字符 + // 注意:兼容两种验证方式 string fileHash; - if (hashValue.Length == 32) + if (hashValue.Length == MD5HashLength) fileHash = HashUtility.BytesMD5(fileData); else fileHash = HashUtility.BytesCRC32(fileData); - if (fileHash == hashValue) - return true; - else - return false; + return fileHash == hashValue; } /// @@ -49,10 +47,10 @@ namespace YooAsset using (FileStream fs = new FileStream(savePath, FileMode.Create)) { // 创建缓存器 - BufferWriter buffer = new BufferWriter(ManifestDefine.FileMaxSize); + BufferWriter buffer = new BufferWriter(PackageManifestDefine.FileMaxSize); // 写入文件标记 - buffer.WriteUInt32(ManifestDefine.FileSign); + buffer.WriteUInt32(PackageManifestDefine.FileSign); // 写入文件版本 buffer.WriteUTF8(manifest.FileVersion); @@ -159,29 +157,28 @@ namespace YooAsset /// public static string GetRemoteBundleFileName(int nameStyle, string bundleName, string fileExtension, string fileHash) { - if (nameStyle == (int)EFileNameStyle.HashName) + EFileNameStyle style = (EFileNameStyle)nameStyle; + switch (style) { - return StringUtility.Format("{0}{1}", fileHash, fileExtension); - } - else if (nameStyle == (int)EFileNameStyle.BundleName) - { - return bundleName; - } - else if (nameStyle == (int)EFileNameStyle.BundleName_HashName) - { - if (string.IsNullOrEmpty(fileExtension)) - { - return StringUtility.Format("{0}_{1}", bundleName, fileHash); - } - else - { - string fileName = bundleName.Remove(bundleName.LastIndexOf('.')); - return StringUtility.Format("{0}_{1}{2}", fileName, fileHash, fileExtension); - } - } - else - { - throw new NotImplementedException($"Invalid name style : {nameStyle}"); + case EFileNameStyle.HashName: + return StringUtility.Format("{0}{1}", fileHash, fileExtension); + + case EFileNameStyle.BundleName: + return bundleName; + + case EFileNameStyle.BundleName_HashName: + if (string.IsNullOrEmpty(fileExtension)) + { + return StringUtility.Format("{0}_{1}", bundleName, fileHash); + } + else + { + string fileName = bundleName.Remove(bundleName.LastIndexOf('.')); + return StringUtility.Format("{0}_{1}{2}", fileName, fileHash, fileExtension); + } + + default: + throw new NotImplementedException($"Invalid name style : {nameStyle}"); } } } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ManifestTools.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifestHelper.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/ManifestTools.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/PackageManifestHelper.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode.meta b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode.meta deleted file mode 100644 index 64d721b3..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: e9d6cb1ce5d510645866ad7c122abfab -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/README.md b/Assets/YooAsset/Runtime/ResourcePackage/README.md deleted file mode 100644 index 3cc7b297..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/README.md +++ /dev/null @@ -1,1192 +0,0 @@ -# ResourcePackage 资源包管理模块 - -## 模块概述 - -ResourcePackage 是 YooAsset 资源管理系统的**核心模块**,作为资源操作的统一入口,负责资源包的完整生命周期管理。该模块提供资源加载、清单管理、下载更新、缓存清理等核心功能。 - -### 核心特性 - -- **统一入口**:ResourcePackage 作为资源操作的门面,提供所有公开 API -- **多模式支持**:支持 Editor/Offline/Host/Web/Custom 五种运行模式 -- **高效查询**:字典缓存实现 O(1) 资源定位 -- **异步优先**:所有操作基于 AsyncOperationBase 异步框架 -- **灵活下载**:支持按标签、按路径、按资源的多种下载方式 - ---- - -## 设计目标 - -| 目标 | 说明 | -|------|------| -| **统一门面** | ResourcePackage 封装所有资源操作,简化使用复杂度 | -| **模式抽象** | 通过 IPlayMode 接口统一不同运行模式的行为 | -| **高效索引** | 清单初始化时构建多个字典,加速运行时查询 | -| **生命周期** | 完整管理包裹从创建到销毁的全过程 | - ---- - -## 文件结构 - -``` -ResourcePackage/ -├── ResourcePackage.cs # 包裹管理门面 -├── PackageManifest.cs # 资源清单 -├── PackageAsset.cs # 资源元数据 -├── PackageBundle.cs # 资源包元数据 -├── ManifestTools.cs # 清单序列化工具 -├── ManifestDefine.cs # 清单常量定义 -├── AssetInfo.cs # 资源信息(公开API) -├── BundleInfo.cs # 资源包信息(内部) -├── PackageDetail.cs # 包裹详情 -├── EBuildBundleType.cs # 资源包类型枚举 -├── EFileNameStyle.cs # 文件名风格枚举 -├── Interface/ # 接口定义 -│ ├── IPlayMode.cs # 播放模式接口 -│ └── IBundleQuery.cs # 资源包查询接口 -├── PlayMode/ # 播放模式实现 -│ ├── PlayModeImpl.cs # 播放模式核心实现 -│ └── EditorSimulateModeHelper.cs # 编辑器模拟辅助 -└── Operation/ # 操作类 - ├── InitializationOperation.cs # 初始化操作 - ├── DestroyOperation.cs # 销毁操作 - ├── RequestPackageVersionOperation.cs # 请求版本 - ├── UpdatePackageManifestOperation.cs # 更新清单 - ├── PreDownloadContentOperation.cs # 预下载 - ├── ClearCacheFilesOperation.cs # 清理缓存 - ├── DownloaderOperation.cs # 下载操作基类 - └── Internal/ - └── DeserializeManifestOperation.cs # 清单反序列化 -``` - ---- - -## 核心类说明 - -### ResourcePackage - -包裹管理门面类,提供所有资源操作的公开 API。 - -#### 核心属性 - -| 属性 | 类型 | 说明 | -|------|------|------| -| `PackageName` | `string` | 包裹唯一标识 | -| `InitializeStatus` | `EOperationStatus` | 初始化状态 | -| `PackageValid` | `bool` | 包裹是否有效(清单已加载) | - -#### 生命周期方法 - -```csharp -// 异步初始化包裹 -InitializationOperation InitializeAsync(InitializeParameters parameters); - -// 异步销毁包裹 -DestroyOperation DestroyAsync(); -``` - -#### 清单操作方法 - -```csharp -// 请求最新版本号 -RequestPackageVersionOperation RequestPackageVersionAsync( - bool appendTimeTicks = true, int timeout = 60); - -// 更新资源清单 -UpdatePackageManifestOperation UpdatePackageManifestAsync( - string packageVersion, int timeout = 60); - -// 预下载指定版本内容 -PreDownloadContentOperation PreDownloadContentAsync( - string packageVersion, int timeout = 60); - -// 获取包裹版本 -string GetPackageVersion(); - -// 获取包裹详细信息 -PackageDetails GetPackageDetails(); -``` - -#### 资源加载方法(5种模式) - -```csharp -// 1. 加载单个资源 -AssetHandle LoadAssetSync(string location); -AssetHandle LoadAssetAsync(string location); -AssetHandle LoadAssetAsync(AssetInfo assetInfo); - -// 2. 加载子资源 -SubAssetsHandle LoadSubAssetsSync(string location); -SubAssetsHandle LoadSubAssetsAsync(string location); - -// 3. 加载资源包内全部资源 -AllAssetsHandle LoadAllAssetsSync(string location); -AllAssetsHandle LoadAllAssetsAsync(string location); - -// 4. 加载场景 -SceneHandle LoadSceneSync(string location, LoadSceneMode sceneMode); -SceneHandle LoadSceneAsync(string location, LoadSceneMode sceneMode); - -// 5. 加载原生文件 -RawFileHandle LoadRawFileSync(string location); -RawFileHandle LoadRawFileAsync(string location); -``` - -#### 资源信息查询方法 - -```csharp -// 按定位地址获取资源信息 -AssetInfo GetAssetInfo(string location); - -// 按 GUID 获取资源信息 -AssetInfo GetAssetInfoByGUID(string assetGUID); - -// 按标签获取资源信息列表 -AssetInfo[] GetAssetInfos(string tag); -AssetInfo[] GetAssetInfos(string[] tags); - -// 获取全部资源信息 -AssetInfo[] GetAllAssetInfos(); - -// 验证定位地址有效性 -bool CheckLocationValid(string location); - -// 检查是否需要从远端下载 -bool IsNeedDownloadFromRemote(string location); -bool IsNeedDownloadFromRemote(AssetInfo assetInfo); -``` - -#### 下载器创建方法(4种模式) - -```csharp -// 下载全部需要下载的资源 -ResourceDownloaderOperation CreateResourceDownloader( - int downloadingMaxNumber, int failedTryAgain); - -// 按标签下载 -ResourceDownloaderOperation CreateResourceDownloader( - string tag, int downloadingMaxNumber, int failedTryAgain); -ResourceDownloaderOperation CreateResourceDownloader( - string[] tags, int downloadingMaxNumber, int failedTryAgain); - -// 按资源路径下载 -ResourceDownloaderOperation CreateBundleDownloader( - string location, int downloadingMaxNumber, int failedTryAgain); -ResourceDownloaderOperation CreateBundleDownloader( - string[] locations, int downloadingMaxNumber, int failedTryAgain); - -// 按 AssetInfo 下载 -ResourceDownloaderOperation CreateBundleDownloader( - AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain); -``` - -#### 解压器创建方法 - -```csharp -// 解压全部需要解压的资源 -ResourceUnpackerOperation CreateResourceUnpacker( - int unpackingMaxNumber, int failedTryAgain); - -// 按标签解压 -ResourceUnpackerOperation CreateResourceUnpacker( - string tag, int unpackingMaxNumber, int failedTryAgain); -ResourceUnpackerOperation CreateResourceUnpacker( - string[] tags, int unpackingMaxNumber, int failedTryAgain); -``` - -#### 导入器创建方法 - -```csharp -// 按文件路径导入 -ResourceImporterOperation CreateResourceImporter( - string[] filePaths, int importerMaxNumber, int failedTryAgain); - -// 按导入信息导入 -ResourceImporterOperation CreateResourceImporter( - ImportFileInfo[] fileInfos, int importerMaxNumber, int failedTryAgain); -``` - -#### 缓存清理方法 - -```csharp -// 清理缓存文件 -ClearCacheFilesOperation ClearCacheFilesAsync(EFileClearMode clearMode); -ClearCacheFilesOperation ClearCacheFilesAsync(string clearMode, object clearParam); -``` - -#### 资源卸载方法 - -```csharp -// 强制卸载全部资源 -UnloadAllAssetsOperation UnloadAllAssetsAsync(); - -// 卸载未使用的资源 -UnloadUnusedAssetsOperation UnloadUnusedAssetsAsync(int loopCount = 100); - -// 尝试卸载指定资源 -bool TryUnloadUnusedAsset(string location); -bool TryUnloadUnusedAsset(AssetInfo assetInfo); -``` - ---- - -## 清单系统 - -### PackageManifest - -资源清单文件,存储资源和资源包的元数据,是资源查询的数据库。 - -#### 配置信息 - -| 属性 | 类型 | 说明 | -|------|------|------| -| `FileVersion` | `string` | 清单文件格式版本 | -| `EnableAddressable` | `bool` | 启用可寻址定位 | -| `SupportExtensionless` | `bool` | 支持无扩展名寻址 | -| `LocationToLower` | `bool` | 定位地址大小写不敏感 | -| `IncludeAssetGUID` | `bool` | 包含资源 GUID | -| `ReplaceAssetPathWithAddress` | `bool` | 用 Address 替换 AssetPath | -| `OutputNameStyle` | `int` | 文件名样式 | -| `BuildBundleType` | `int` | 构建资源包类型 | -| `BuildPipeline` | `string` | 构建管线名称 | - -#### 包裹信息 - -| 属性 | 类型 | 说明 | -|------|------|------| -| `PackageName` | `string` | 包裹名称 | -| `PackageVersion` | `string` | 包裹版本 | -| `PackageNote` | `string` | 包裹备注 | - -#### 核心数据 - -| 属性 | 类型 | 说明 | -|------|------|------| -| `AssetList` | `List` | 主资源列表 | -| `BundleList` | `List` | 资源包列表 | - -#### 运行时字典(初始化时构建) - -| 字典 | 键 | 值 | 说明 | -|------|-----|-----|------| -| `AssetDic` | AssetPath | PackageAsset | 资源路径查询 | -| `AssetPathMapping1` | Location | AssetPath | 定位地址→资源路径 | -| `AssetPathMapping2` | AssetGUID | AssetPath | GUID→资源路径 | -| `BundleDic1` | BundleName | PackageBundle | 按名称查询 | -| `BundleDic2` | FileName | PackageBundle | 按文件名查询 | -| `BundleDic3` | BundleGUID | PackageBundle | 按 GUID 查询 | - -#### 查询方法 - -```csharp -// 定位地址转换 -bool TryMappingToAssetPath(string location, out string assetPath); - -// 资源查询 -bool TryGetPackageAsset(string assetPath, out PackageAsset result); - -// 资源包查询(3种方式) -bool TryGetPackageBundleByBundleName(string bundleName, out PackageBundle result); -bool TryGetPackageBundleByFileName(string fileName, out PackageBundle result); -bool TryGetPackageBundleByBundleGUID(string bundleGUID, out PackageBundle result); - -// 获取资源主包 -PackageBundle GetMainPackageBundle(AssetInfo assetInfo); - -// 获取资源依赖包 -PackageBundle[] GetAssetAllDependencies(PackageAsset asset); - -// 获取资源包依赖 -PackageBundle[] GetBundleAllDependencies(PackageBundle bundle); - -// 定位地址转 AssetInfo -AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType); - -// GUID 转 AssetInfo -AssetInfo ConvertAssetGUIDToAssetInfo(string assetGUID, System.Type assetType); - -// 按标签获取资源 -AssetInfo[] GetAssetInfosByTags(string[] tags); - -// 检查资源包是否在清单中 -bool IsIncludeBundleFile(string bundleGUID); -``` - -### PackageAsset - -单个资源的元数据(可序列化)。 - -```csharp -public class PackageAsset -{ - public string Address; // 可寻址地址 - public string AssetPath; // 资源路径 (Assets/...) - public string AssetGUID; // 资源 GUID - public string[] AssetTags; // 分类标签 - public int BundleID; // 所属资源包 ID(索引) - public int[] DependBundleIDs; // 依赖资源包 ID 数组 - - // 检查是否包含指定标签 - public bool HasTag(string[] tags); -} -``` - -### PackageBundle - -资源包的元数据(可序列化)。 - -```csharp -public class PackageBundle -{ - // 基础信息 - public string BundleName; // 资源包名称 - public string BundleGUID { get; } // GUID(= FileHash) - public uint UnityCRC; // Unity 生成的 CRC - public string FileHash; // 文件哈希值 - public uint FileCRC; // 文件 CRC 校验码 - public long FileSize; // 文件大小(字节) - public bool Encrypted; // 是否加密 - - // 分类和依赖 - public string[] Tags; // 资源包分类标签 - public int[] DependBundleIDs; // 依赖资源包 ID(引擎层) - - // 运行时属性 - public int BundleType { get; } // 资源包类型 - public string FileName { get; } // 远端文件名 - public string FileExtension { get; } // 文件扩展名 - - // 运行时列表 - public List IncludeMainAssets; // 包含的主资源 - public List ReferenceBundleIDs; // 引用此包的 ID 列表 - - // 检查是否包含标签 - public bool HasTag(string[] tags); - public bool HasAnyTags(); - - // 对比相等性(基于 FileHash) - public bool Equals(PackageBundle otherBundle); -} -``` - -### ManifestTools - -清单序列化工具类。 - -```csharp -// 验证清单数据完整性 -static bool VerifyManifestData(byte[] fileData, string hashValue); - -// 序列化 -static string SerializeToJson(PackageManifest manifest); -static byte[] SerializeToBinary(PackageManifest manifest); - -// 反序列化 -static PackageManifest DeserializeFromJson(string jsonContent); -static PackageManifest DeserializeFromBinary(byte[] binaryData); - -// 文件命名 -static string GetRemoteBundleFileExtension(string bundleName); -static string GetRemoteBundleFileName(OutputNameStyle style, ...); -``` - -### ManifestDefine - -清单常量定义。 - -```csharp -public class ManifestDefine -{ - public const int FileMaxSize = 104857600; // 100MB - public const uint FileSign = 0x594F4F; // "YOO" 标记 - public const string FileVersion = "2025.9.30"; // 当前版本 - public const string VERSION_2025_8_28 = "2025.8.28"; - public const string VERSION_2025_9_30 = "2025.9.30"; - public const bool BackwardCompatible = true; // 向后兼容 -} -``` - ---- - -## 运行模式系统 - -### IPlayMode 接口 - -定义不同运行模式的统一接口。 - -```csharp -public interface IPlayMode -{ - // 当前活跃的清单 - PackageManifest ActiveManifest { set; get; } - - // 销毁文件系统 - void DestroyFileSystem(); - - // 版本和清单操作 - RequestPackageVersionOperation RequestPackageVersionAsync(...); - UpdatePackageManifestOperation UpdatePackageManifestAsync(...); - PreDownloadContentOperation PreDownloadContentAsync(...); - ClearCacheFilesOperation ClearCacheFilesAsync(...); - - // 下载器创建 - ResourceDownloaderOperation CreateResourceDownloaderByAll(...); - ResourceDownloaderOperation CreateResourceDownloaderByTags(...); - ResourceDownloaderOperation CreateResourceDownloaderByPaths(...); - - // 解压器创建 - ResourceUnpackerOperation CreateResourceUnpackerByAll(...); - ResourceUnpackerOperation CreateResourceUnpackerByTags(...); - - // 导入器创建 - ResourceImporterOperation CreateResourceImporterByFilePaths(...); - ResourceImporterOperation CreateResourceImporterByFileInfos(...); -} -``` - -### PlayModeImpl - -播放模式核心实现,同时实现 `IPlayMode` 和 `IBundleQuery` 接口。 - -#### 核心属性 - -```csharp -public class PlayModeImpl : IPlayMode, IBundleQuery -{ - public readonly string PackageName; - public readonly EPlayMode PlayMode; - public readonly List FileSystems = new List(10); - public PackageManifest ActiveManifest { set; get; } -} -``` - -#### 文件系统管理 - -```csharp -// 获取主文件系统(列表最后一个) -public IFileSystem GetMainFileSystem(); - -// 获取资源包所属的文件系统 -public IFileSystem GetBelongFileSystem(PackageBundle bundle); -``` - -#### IBundleQuery 实现 - -```csharp -// 获取主资源包信息 -BundleInfo GetMainBundleInfo(AssetInfo assetInfo); - -// 获取依赖资源包信息 -BundleInfo[] GetDependBundleInfos(AssetInfo assetInfo); - -// 获取资源包名称 -string GetMainBundleName(int bundleID); -``` - -#### 下载/解压/导入列表生成 - -```csharp -// 生成全部下载列表 -List GetDownloadListByAll(PackageManifest manifest); - -// 按标签筛选下载列表 -List GetDownloadListByTags(PackageManifest manifest, string[] tags); - -// 按资源路径筛选下载列表 -List GetDownloadListByPaths(PackageManifest manifest, string[] locations); - -// 解压列表 -List GetUnpackListByAll(PackageManifest manifest); -List GetUnpackListByTags(PackageManifest manifest, string[] tags); - -// 导入列表 -List GetImporterListByFilePaths(...); -List GetImporterListByFileInfos(...); -``` - -### 五种运行模式 - -| 模式 | 说明 | 文件系统 | -|------|------|----------| -| `EditorSimulateMode` | 编辑器模拟模式 | DefaultEditorFileSystem | -| `OfflinePlayMode` | 单机运行模式 | DefaultBuildinFileSystem | -| `HostPlayMode` | 联机运行模式 | Buildin + Cache | -| `WebPlayMode` | WebGL 运行模式 | WebServer + WebRemote | -| `CustomPlayMode` | 自定义模式 | 用户自定义 | - -#### 文件系统优先级 - -``` -FileSystems[0] → FileSystems[1] → ... → FileSystems[N] (主文件系统) - ↓ ↓ - 编辑器或内置资源 远端或缓存资源 -``` - ---- - -## 操作类系统 - -### InitializationOperation - -初始化操作,管理包裹的初始化流程。 - -``` -状态流程: -Prepare - ↓ -ClearOldFileSystem - └── 清理旧的文件系统(如果存在) - ↓ -InitFileSystem - └── 逐个初始化 FileSystems - ├── FileSystem[0].InitializeFileSystemAsync() - ├── FileSystem[1].InitializeFileSystemAsync() - └── ... - ↓ -CheckInitResult - └── 检查所有文件系统初始化结果 - ├── 任一失败 → Status = Failed - └── 全部成功 → Status = Succeed - ↓ -Done -``` - -### DestroyOperation - -销毁操作,管理包裹的销毁流程。 - -``` -状态流程: -CheckInitStatus - ├── 初始化中 → Status = Failed(不允许销毁) - └── 其他状态 → 继续 - ↓ -UnloadAllAssets - └── 如果初始化成功,卸载所有资源 - ↓ -DestroyPackage - ├── 销毁包裹 - └── OperationSystem.ClearPackageOperation() - ↓ -Done → Status = Succeed -``` - -### RequestPackageVersionOperation - -请求版本操作,获取远端最新版本号。 - -``` -状态流程: -RequestPackageVersion - └── 委托给主文件系统 - └── FileSystem.RequestPackageVersionAsync() - ├── 成功 → PackageVersion = 版本号 - └── 失败 → Error - ↓ -Done -``` - -### UpdatePackageManifestOperation - -更新清单操作,加载指定版本的清单。 - -``` -状态流程: -CheckParams - └── 验证参数有效性 - ↓ -CheckActiveManifest - └── 检查当前清单版本 - ├── 版本匹配 → 直接成功(复用) - └── 版本不匹配 → 继续加载 - ↓ -LoadPackageManifest - └── 主文件系统加载清单 - └── FileSystem.LoadPackageManifestAsync() - ├── 成功 → Manifest = 新清单 - └── 失败 → Error - ↓ -Done -``` - -### PreDownloadContentOperation - -预下载操作,预加载指定版本的清单并支持创建下载器。 - -``` -状态流程: -CheckParams - └── 验证参数有效性 - ↓ -CheckActiveManifest - └── 检查是否已有相同版本清单 - ├── 有 → 复用清单 - └── 无 → 继续加载 - ↓ -LoadPackageManifest - └── 加载指定版本清单 - ├── 成功 → 可创建下载器 - └── 失败 → Error - ↓ -Done -``` - -#### 预下载后创建下载器 - -```csharp -// 下载全部 -CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain); - -// 按标签下载 -CreateResourceDownloader(string tag, ...); -CreateResourceDownloader(string[] tags, ...); - -// 按资源路径下载 -CreateResourceDownloader(string[] locations, ...); -``` - -### ClearCacheFilesOperation - -缓存清理操作,清理指定的缓存文件。 - -``` -状态流程: -Prepare - └── 准备清理任务 - ↓ -ClearCacheFiles - └── 逐个文件系统清理 - └── FileSystem.ClearCacheFilesAsync(options) - ↓ -CheckClearResult - └── 检查清理结果 - ├── 任一失败 → Status = Failed - └── 全部成功 → Status = Succeed - ↓ -Done -``` - -### DownloaderOperation - -下载操作基类,管理并发下载任务。 - -#### 核心属性 - -```csharp -public abstract class DownloaderOperation : AsyncOperationBase -{ - // 下载统计 - public int TotalDownloadCount { get; } // 总下载数 - public long TotalDownloadBytes { get; } // 总大小(字节) - public int CurrentDownloadCount { get; } // 已完成数 - public long CurrentDownloadBytes { get; } // 已完成大小 - public float Progress { get; } // 进度 0.0~1.0 - - // 并发控制 - protected const int MAX_LOADER_COUNT = 64; // 最大同时下载数 -} -``` - -#### 回调委托 - -```csharp -// 下载完成回调 -public DownloadFinishDelegate DownloadFinishCallback; - -// 进度更新回调 -public DownloadUpdateDelegate DownloadUpdateCallback; - -// 下载错误回调 -public DownloadErrorDelegate DownloadErrorCallback; - -// 开始下载文件回调 -public DownloadFileBeginDelegate DownloadFileBeginCallback; -``` - -#### 状态流程 - -``` -Check - └── 检查下载列表是否为空 - ├── 为空 → 直接成功 - └── 不为空 → 开始下载 - ↓ -Loading - ├── 检测已完成的下载器 - ├── 移除完成的下载器 - ├── 更新进度回调 - ├── 创建新下载器(≤ MAX_LOADER_COUNT) - └── 处理失败重试 - ↓ -Done -``` - -#### 子类 - -| 类 | 说明 | -|-----|------| -| `ResourceDownloaderOperation` | 资源下载器 | -| `ResourceUnpackerOperation` | 资源解压器 | -| `ResourceImporterOperation` | 资源导入器 | - -### DeserializeManifestOperation - -清单反序列化操作,从二进制数据反序列化清单。 - -``` -状态流程: -RestoreFileData - └── 调用插件还原数据(如果有) - ↓ -DeserializeFileHeader - └── 读取文件头 - ├── 验证 FileSign (0x594F4F) - └── 检查 FileVersion 兼容性 - ↓ -PrepareAssetList - └── 读取资源数量 - ↓ -DeserializeAssetList(时间切片) - └── 逐个反序列化资源 - ↓ -PrepareBundleList - └── 读取资源包数量 - ↓ -DeserializeBundleList(时间切片) - └── 逐个反序列化资源包 - ↓ -InitManifest - └── 初始化清单(构建字典) - ↓ -Done → Manifest -``` - ---- - -## 辅助类说明 - -### AssetInfo - -资源信息包装类(公开 API)。 - -```csharp -public class AssetInfo -{ - // 公开属性 - public string PackageName { get; } // 所属包裹 - public System.Type AssetType { get; } // 资源类型 - public string Error { get; } // 错误信息 - public bool IsInvalid { get; } // 身份是否无效 - public string Address { get; } // 可寻址地址 - public string AssetPath { get; } // 资源路径 - - // 内部属性 - internal ELoadMethod LoadMethod; // 加载方法 - internal string GUID { get; } // 唯一标识符 - internal PackageAsset Asset { get; } // 内部对象 -} -``` - -### BundleInfo - -资源包信息(内部使用)。 - -```csharp -public class BundleInfo -{ - private readonly IFileSystem _fileSystem; - public readonly PackageBundle Bundle; - - // 加载资源包 - public FSLoadBundleOperation LoadBundleFile(); - - // 创建下载器 - public FSDownloadFileOperation CreateDownloader(int failedTryAgain); - - // 检查是否需要下载 - public bool IsNeedDownloadFromRemote(); - - // 生成唯一标识(用于去重) - public string GetDownloadCombineGUID(); -} -``` - -### PackageDetails - -包裹详细信息(公开 API)。 - -```csharp -public class PackageDetails -{ - public string FileVersion; - public bool EnableAddressable; - public bool SupportExtensionless; - public bool LocationToLower; - public bool IncludeAssetGUID; - public bool ReplaceAssetPathWithAddress; - public int OutputNameStyle; - public int BuildBundleType; - public string BuildPipeline; - public string PackageName; - public string PackageVersion; - public string PackageNote; - public int AssetTotalCount; // 主资源总数 - public int BundleTotalCount; // 资源包总数 -} -``` - ---- - -## 枚举定义 - -### EBuildBundleType - -资源包类型枚举。 - -```csharp -public enum EBuildBundleType -{ - Unknown = 0, // 未知(默认) - VirtualBundle = 1, // 虚拟包(编辑器模拟) - AssetBundle = 2, // Unity AssetBundle - RawBundle = 3, // 原生文件(未压缩) - InstantBundle = 4, // Unity China InstantBundle -} -``` - -### EFileNameStyle - -文件名命名风格枚举。 - -```csharp -public enum EFileNameStyle -{ - HashName = 0, // "abc123def456.bundle" - BundleName = 1, // "assets_ui.bundle" - BundleName_HashName = 2, // "assets_ui_abc123def456.bundle" -} -``` - -### ELoadMethod - -资源加载方法枚举(内部)。 - -```csharp -internal enum ELoadMethod -{ - None = 0, - LoadAsset, // 加载单个资源 - LoadSubAssets, // 加载子资源 - LoadAllAssets, // 加载资源包内全部 - LoadScene, // 加载场景 - LoadRawFile, // 加载原生文件 -} -``` - ---- - -## 关键工作流 - -### 初始化流程 - -``` -1. YooAssets.CreatePackage(packageName) - └── new ResourcePackage(packageName) - -2. package.InitializeAsync(parameters) - ├── CheckInitializeParameters() - ├── new ResourceManager() - ├── new PlayModeImpl() - ├── new InitializationOperation() - └── OperationSystem.StartOperation() - -3. InitializationOperation 逐个初始化 FileSystem - ├── DefaultEditorFileSystem(编辑器模拟) - ├── DefaultBuildinFileSystem(StreamingAssets) - ├── DefaultCacheFileSystem(已缓存资源) - └── DefaultWebServerFileSystem(WebGL) - -4. PlayModeImpl.ActiveManifest = fileSystem.LoadPackageManifest() - └── 清单反序列化并初始化 -``` - -### 资源加载流程 - -``` -package.LoadAssetAsync(location) - │ - ├── ConvertLocationToAssetInfo(location) - │ └── PlayModeImpl.ActiveManifest.ConvertLocationToAssetInfo() - │ └── AssetPathMapping1[location] → AssetPath - │ └── AssetDic[assetPath] → PackageAsset - │ - ├── ResourceManager.LoadAssetAsync(assetInfo) - │ ├── ProviderDic 查询或创建 Provider - │ ├── Provider.StartBundleLoader() - │ │ ├── GetMainBundleInfo() → BundleInfo - │ │ └── GetDependBundleInfos() → List - │ │ - │ └── 并发加载 AssetBundle - │ ├── PlayModeImpl.GetBelongFileSystem() - │ └── IFileSystem.LoadBundleFile() - │ - └── return AssetHandle -``` - -### 清单更新流程 - -``` -package.RequestPackageVersionAsync() - └── PlayModeImpl.GetMainFileSystem().RequestPackageVersionAsync() - │ - ▼ -package.UpdatePackageManifestAsync(version) - ├── 检查 ActiveManifest 版本是否已匹配 - └── PlayModeImpl.GetMainFileSystem().LoadPackageManifestAsync(version) - └── ManifestTools.DeserializeFromBinary() - └── DeserializeManifestOperation(逐个反序列化资源包) -``` - -### 下载流程 - -``` -downloader = package.CreateResourceDownloader(...) - └── PlayModeImpl.GetDownloadListByXXX() - ├── 遍历清单的 BundleList - ├── GetBelongFileSystem(bundle) - └── fileSystem.NeedDownload(bundle) - │ - ▼ -downloader.BeginDownload() - └── DownloaderOperation.InternalUpdate() - ├── 创建 ≤ MAX_LOADER_COUNT 个 FSDownloadFileOperation - ├── fileSystem.DownloadFileAsync(bundle, options) - ├── 更新进度和回调 - └── 失败文件进入重试列表 -``` - ---- - -## 类继承关系 - -``` -AsyncOperationBase -├── InitializationOperation -├── DestroyOperation -├── RequestPackageVersionOperation -│ └── RequestPackageVersionImplOperation -├── UpdatePackageManifestOperation -├── PreDownloadContentOperation -├── ClearCacheFilesOperation -├── DownloaderOperation (abstract) -│ ├── ResourceDownloaderOperation -│ ├── ResourceUnpackerOperation -│ └── ResourceImporterOperation -└── DeserializeManifestOperation - -IPlayMode -└── PlayModeImpl (also implements IBundleQuery) - -PackageManifest -├── List AssetList -└── List BundleList -``` - ---- - -## 使用示例 - -### 初始化包裹(联机模式) - -```csharp -// 创建包裹 -var package = YooAssets.CreatePackage("DefaultPackage"); - -// 创建内置文件系统参数 -var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(); - -// 创建缓存文件系统参数 -var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters( - remoteServices: new GameRemoteServices() -); - -// 创建联机模式初始化参数 -var initParams = new HostPlayModeParameters(); -initParams.BuildinFileSystemParameters = buildinParams; -initParams.CacheFileSystemParameters = cacheParams; - -// 异步初始化 -var initOp = package.InitializeAsync(initParams); -await initOp.ToTask(); - -if (initOp.Status == EOperationStatus.Succeed) -{ - Debug.Log("包裹初始化成功!"); -} -``` - -### 更新清单 - -```csharp -// 请求最新版本 -var versionOp = package.RequestPackageVersionAsync(); -await versionOp.ToTask(); - -if (versionOp.Status != EOperationStatus.Succeed) -{ - Debug.LogError($"请求版本失败:{versionOp.Error}"); - return; -} - -string packageVersion = versionOp.PackageVersion; -Debug.Log($"最新版本:{packageVersion}"); - -// 更新清单 -var updateOp = package.UpdatePackageManifestAsync(packageVersion); -await updateOp.ToTask(); - -if (updateOp.Status == EOperationStatus.Succeed) -{ - Debug.Log("清单更新成功!"); -} -``` - -### 下载资源 - -```csharp -// 创建下载器(最多10个并发,失败重试3次) -var downloader = package.CreateResourceDownloader(10, 3); - -if (downloader.TotalDownloadCount == 0) -{ - Debug.Log("没有需要下载的资源"); - return; -} - -Debug.Log($"需要下载 {downloader.TotalDownloadCount} 个文件," + - $"总大小 {downloader.TotalDownloadBytes / 1024 / 1024}MB"); - -// 注册回调 -downloader.DownloadUpdateCallback = (info) => -{ - Debug.Log($"下载进度:{info.Progress * 100:F1}%"); -}; - -downloader.DownloadErrorCallback = (info) => -{ - Debug.LogError($"下载错误:{info.FileName} - {info.Error}"); -}; - -// 开始下载 -downloader.BeginDownload(); -await downloader.ToTask(); - -if (downloader.Status == EOperationStatus.Succeed) -{ - Debug.Log("下载完成!"); -} -``` - -### 按标签下载 - -```csharp -// 按单个标签下载 -var downloader = package.CreateResourceDownloader("level1", 10, 3); - -// 按多个标签下载 -var downloader = package.CreateResourceDownloader( - new string[] { "level1", "level2" }, 10, 3); - -downloader.BeginDownload(); -await downloader.ToTask(); -``` - -### 加载资源 - -```csharp -// 异步加载预制体 -var handle = package.LoadAssetAsync("Assets/Prefabs/Player.prefab"); -await handle.ToTask(); - -if (handle.Status == EOperationStatus.Succeed) -{ - var prefab = handle.AssetObject as GameObject; - var player = GameObject.Instantiate(prefab); - - // 使用完毕后释放 - // handle.Release(); -} -else -{ - Debug.LogError($"加载失败:{handle.LastError}"); -} -``` - -### 加载场景 - -```csharp -// 异步加载场景(叠加模式) -var handle = package.LoadSceneAsync("Assets/Scenes/GameScene.unity", LoadSceneMode.Additive); -await handle.ToTask(); - -if (handle.Status == EOperationStatus.Succeed) -{ - Debug.Log("场景加载成功!"); -} -``` - -### 预下载指定版本 - -```csharp -// 预下载特定版本 -var predownloadOp = package.PreDownloadContentAsync("1.0.5"); -await predownloadOp.ToTask(); - -if (predownloadOp.Status == EOperationStatus.Succeed) -{ - // 创建下载器 - var downloader = predownloadOp.CreateResourceDownloader(10, 3); - downloader.BeginDownload(); - await downloader.ToTask(); -} -``` - -### 清理缓存 - -```csharp -// 清理所有缓存 -var clearOp = package.ClearCacheFilesAsync(EFileClearMode.ClearAllBundleFiles); -await clearOp.ToTask(); - -// 清理未使用的缓存 -var clearOp = package.ClearCacheFilesAsync(EFileClearMode.ClearUnusedBundleFiles); -await clearOp.ToTask(); - -// 按标签清理 -var clearOp = package.ClearCacheFilesAsync( - EFileClearMode.ClearBundleFilesByTags.ToString(), "dlc_old"); -await clearOp.ToTask(); -``` - -### 卸载资源 - -```csharp -// 卸载未使用的资源 -var unloadOp = package.UnloadUnusedAssetsAsync(); -await unloadOp.ToTask(); - -// 强制卸载全部资源 -var unloadOp = package.UnloadAllAssetsAsync(); -await unloadOp.ToTask(); -``` - ---- - -## 注意事项 - -1. **初始化顺序**:必须先初始化包裹才能进行其他操作 -2. **清单更新**:建议在更新清单前调用 `UnloadAllAssetsAsync()` 释放已加载资源 -3. **资源释放**:使用后必须调用 `Handle.Release()` 避免内存泄漏 -4. **并发限制**:下载器最大并发数为 64,建议根据网络环境合理设置 -5. **版本兼容**:清单文件版本需 >= 2025.8.28 -6. **异常处理**:操作失败时检查 `Status` 和 `Error` 属性 -7. **线程安全**:所有核心逻辑在 Unity 主线程执行,无需额外同步 diff --git a/Assets/YooAsset/Runtime/ResourcePackage/README.md.meta b/Assets/YooAsset/Runtime/ResourcePackage/README.md.meta deleted file mode 100644 index 6f584ed2..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/README.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 0ee8a6b68676976428b1886c273eaeb6 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs index c1343355..067098a5 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Collections; using System.Collections.Generic; @@ -8,15 +8,9 @@ namespace YooAsset { public class ResourcePackage { - private bool _isInitialize = false; - private string _initializeError = string.Empty; - private EOperationStatus _initializeStatus = EOperationStatus.None; - private EPlayMode _playMode; - - // 管理器 + private InitializePackageOperation _initializeOp; private ResourceManager _resourceManager; - private IBundleQuery _bundleQuery; - private IPlayMode _playModeImpl; + private FileSystemHost _fileSystemHost; /// /// 包裹名 @@ -28,7 +22,12 @@ namespace YooAsset /// public EOperationStatus InitializeStatus { - get { return _initializeStatus; } + get + { + if (_initializeOp == null) + return EOperationStatus.None; + return _initializeOp.Status; + } } /// @@ -38,55 +37,34 @@ namespace YooAsset { get { - if (_playModeImpl == null) + if (_fileSystemHost == null) return false; - return _playModeImpl.ActiveManifest != null; + return _fileSystemHost.ActiveManifest != null; } } + /// + /// 包裹优先级(值越大越优先更新) + /// + public uint PackagePriority + { + get { return OperationSystem.GetSchedulerPriority(PackageName); } + set { OperationSystem.SetSchedulerPriority(PackageName, value); } + } + internal ResourcePackage(string packageName) { PackageName = packageName; } - - /// - /// 销毁资源包裹 - /// - internal void DestroyPackage() + internal void InternalInitialize(ResourceManager manager, FileSystemHost host) { - if (_isInitialize) - { - _isInitialize = false; - _initializeError = string.Empty; - _initializeStatus = EOperationStatus.None; - - // 销毁资源管理器 - if (_resourceManager != null) - { - _resourceManager.Destroy(); - _resourceManager = null; - } - - // 销毁文件系统 - if (_playModeImpl != null) - _playModeImpl.DestroyFileSystem(); - - _bundleQuery = null; - _playModeImpl = null; - } + _resourceManager = manager; + _fileSystemHost = host; } - - /// - /// 异步初始化 - /// - public InitializationOperation InitializeAsync(InitializeParameters parameters) + internal void InternalDestroy() { - // 注意:联机平台因为网络原因可能会初始化失败! - ResetInitializeAfterFailed(); - - // 检测初始化参数合法性 - CheckInitializeParameters(parameters); + _initializeOp = null; // 销毁资源管理器 if (_resourceManager != null) @@ -95,157 +73,86 @@ namespace YooAsset _resourceManager = null; } - // 创建资源管理器 - _resourceManager = new ResourceManager(PackageName); - var playModeImpl = new PlayModeImpl(PackageName, _playMode); - _bundleQuery = playModeImpl; - _playModeImpl = playModeImpl; - _resourceManager.Initialize(parameters, _bundleQuery); - - // 初始化资源系统 - InitializationOperation initializeOperation; - if (_playMode == EPlayMode.EditorSimulateMode) + // 销毁文件系统中枢 + if (_fileSystemHost != null) { - var initializeParameters = parameters as EditorSimulateModeParameters; - initializeOperation = playModeImpl.InitializeAsync(initializeParameters.EditorFileSystemParameters); + _fileSystemHost.Destroy(); + _fileSystemHost = null; } - else if (_playMode == EPlayMode.OfflinePlayMode) - { - var initializeParameters = parameters as OfflinePlayModeParameters; - initializeOperation = playModeImpl.InitializeAsync(initializeParameters.BuildinFileSystemParameters); - } - else if (_playMode == EPlayMode.HostPlayMode) - { - var initializeParameters = parameters as HostPlayModeParameters; - initializeOperation = playModeImpl.InitializeAsync(initializeParameters.BuildinFileSystemParameters, initializeParameters.CacheFileSystemParameters); - } - else if (_playMode == EPlayMode.WebPlayMode) - { - var initializeParameters = parameters as WebPlayModeParameters; - initializeOperation = playModeImpl.InitializeAsync(initializeParameters.WebServerFileSystemParameters, initializeParameters.WebRemoteFileSystemParameters); - } - else if (_playMode == EPlayMode.CustomPlayMode) - { - var initializeParameters = parameters as CustomPlayModeParameters; - initializeOperation = playModeImpl.InitializeAsync(initializeParameters.FileSystemParameterList); - } - else - { - throw new NotImplementedException(); - } - - // 监听初始化结果 - _isInitialize = true; - OperationSystem.StartOperation(PackageName, initializeOperation); - initializeOperation.Completed += InitializeOperation_Completed; - return initializeOperation; - } - private void ResetInitializeAfterFailed() - { - if (_isInitialize && _initializeStatus == EOperationStatus.Failed) - { - _isInitialize = false; - _initializeStatus = EOperationStatus.None; - _initializeError = string.Empty; - } - } - private void CheckInitializeParameters(InitializeParameters parameters) - { - if (_isInitialize) - throw new YooPackageException(PackageName, $"Package '{PackageName}' is already initialized !"); - - if (parameters == null) - throw new YooPackageException(PackageName, $"Initialize parameters cannot be null."); - -#if !UNITY_EDITOR - if (parameters is EditorSimulateModeParameters) - throw new YooPlatformNotSupportedException($"Editor simulate mode only support unity editor."); -#endif - - // 检测初始化参数 - if (parameters.BundleLoadingMaxConcurrency <= 0) - throw new YooPackageException(PackageName, $"{nameof(parameters.BundleLoadingMaxConcurrency)} value must be greater than zero."); - - // 鉴定运行模式 - if (parameters is EditorSimulateModeParameters) - _playMode = EPlayMode.EditorSimulateMode; - else if (parameters is OfflinePlayModeParameters) - _playMode = EPlayMode.OfflinePlayMode; - else if (parameters is HostPlayModeParameters) - _playMode = EPlayMode.HostPlayMode; - else if (parameters is WebPlayModeParameters) - _playMode = EPlayMode.WebPlayMode; - else if (parameters is CustomPlayModeParameters) - _playMode = EPlayMode.CustomPlayMode; - else - throw new NotImplementedException(); - - // 检测运行时平台 - if (_playMode != EPlayMode.EditorSimulateMode) - { -#if UNITY_WEBGL - if (_playMode != EPlayMode.WebPlayMode) - { - throw new YooPlatformNotSupportedException($"{_playMode} can not support WebGL plateform !"); - } -#else - if (_playMode == EPlayMode.WebPlayMode) - { - throw new YooPlatformNotSupportedException($"{nameof(EPlayMode.WebPlayMode)} only support WebGL plateform !"); - } -#endif - } - } - private void InitializeOperation_Completed(AsyncOperationBase op) - { - _initializeStatus = op.Status; - _initializeError = op.Error; - if (_initializeStatus != EOperationStatus.Succeed) - YooLogger.Error(_initializeError); } /// - /// 异步销毁 + /// 异步初始化包裹 /// - public DestroyOperation DestroyAsync() + public InitializePackageOperation InitializePackageAsync(InitializePackageOptions options) { - var options = new UnloadAllAssetsOptions(); - options.ReleaseAllHandles = true; - options.LockLoadOperation = true; - var operation = new DestroyOperation(this, options); - OperationSystem.StartOperation(null, operation); + // 注意:联机平台因为网络原因可能会初始化失败! + ResetInitializeAfterFailed(); + + // 检测重复初始化 + if (_initializeOp != null) + throw new YooPackageException(PackageName, $"Resource package '{PackageName}' is already initialized."); + + // 开始初始化操作 + _initializeOp = new InitializePackageOperation(this, options); + OperationSystem.StartOperation(PackageName, _initializeOp); + return _initializeOp; + } + private void ResetInitializeAfterFailed() + { + if (InitializeStatus == EOperationStatus.Failed) + { + InternalDestroy(); + } + } + + /// + /// 异步销毁包裹 + /// + public DestroyPackageOperation DestroyPackageAsync() + { + var options = new UnloadAllAssetsOptions(true, true); + var operation = new DestroyPackageOperation(this, options); + OperationSystem.StartOperation(OperationSystem.GlobalSchedulerName, operation); return operation; } /// /// 请求最新的资源版本 + /// 说明:超时时间默认60秒 /// - /// 在URL末尾添加时间戳 - /// 超时时间(默认值:60秒) - public RequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks = true, int timeout = 60) + public RequestVersionOperation RequestVersionAsync() { - DebugCheckInitialize(false); - var operation = _playModeImpl.RequestPackageVersionAsync(appendTimeTicks, timeout); + int defaultTimeout = 60; + var options = new RequestVersionOptions(true, defaultTimeout); + return RequestVersionAsync(options); + } + + /// + /// 请求最新的资源版本 + /// + public RequestVersionOperation RequestVersionAsync(RequestVersionOptions options) + { + EnsureInitialized(false); + var operation = new RequestVersionOperation(_fileSystemHost, options); OperationSystem.StartOperation(PackageName, operation); return operation; } /// - /// 更新并加载指定版本的资源清单 + /// 加载指定版本的资源清单 /// - /// 包裹版本 - /// 超时时间(默认值:60秒) - public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, int timeout = 60) + public LoadManifestOperation LoadManifestAsync(LoadManifestOptions options) { - DebugCheckInitialize(false); + EnsureInitialized(false); // 注意:强烈建议在更新之前保持加载器为空! 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 bundle before update manifest. Recommended to call the {nameof(UnloadAllAssetsAsync)} method to release loaded bundle."); } - var operation = _playModeImpl.UpdatePackageManifestAsync(packageVersion, timeout); + var operation = new LoadManifestOperation(_fileSystemHost, options); OperationSystem.StartOperation(PackageName, operation); return operation; } @@ -253,44 +160,22 @@ namespace YooAsset /// /// 预下载指定版本的包裹资源 /// - /// 包裹版本 - /// 资源清单下载的超时时间(默认值:60秒) - public PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout = 60) + public PreDownloaderOperation PreDownloaderAsync(PreDownloaderOptions options) { - DebugCheckInitialize(false); - var operation = _playModeImpl.PreDownloadContentAsync(packageVersion, timeout); + EnsureInitialized(false); + var operation = new PreDownloaderOperation(_fileSystemHost, options); OperationSystem.StartOperation(PackageName, operation); return operation; } - + /// /// 清理缓存文件 /// - /// 清理方式 - /// 执行参数 - public ClearCacheFilesOperation ClearCacheFilesAsync(EFileClearMode clearMode, object clearParam = null) + public ClearCacheOperation ClearCacheAsync(ClearCacheOptions options) { - DebugCheckInitialize(false); - ClearCacheFilesOptions options = new ClearCacheFilesOptions(); - options.ClearMode = clearMode.ToString(); - options.ClearParam = clearParam; - var operation = _playModeImpl.ClearCacheFilesAsync(options); - OperationSystem.StartOperation(PackageName, operation); - return operation; - } - - /// - /// 清理缓存文件 - /// - /// 清理方式 - /// 执行参数 - public ClearCacheFilesOperation ClearCacheFilesAsync(string clearMode, object clearParam = null) - { - DebugCheckInitialize(false); - ClearCacheFilesOptions options = new ClearCacheFilesOptions(); - options.ClearMode = clearMode; - options.ClearParam = clearParam; - var operation = _playModeImpl.ClearCacheFilesAsync(options); + EnsureInitialized(false); + options.Manifest = _fileSystemHost.ActiveManifest; + var operation = new ClearCacheOperation(_fileSystemHost, options); OperationSystem.StartOperation(PackageName, operation); return operation; } @@ -302,8 +187,8 @@ namespace YooAsset /// public string GetPackageVersion() { - DebugCheckInitialize(); - return _playModeImpl.ActiveManifest.PackageVersion; + EnsureInitialized(); + return _fileSystemHost.ActiveManifest.PackageVersion; } /// @@ -311,8 +196,8 @@ namespace YooAsset /// public string GetPackageNote() { - DebugCheckInitialize(); - return _playModeImpl.ActiveManifest.PackageNote; + EnsureInitialized(); + return _fileSystemHost.ActiveManifest.PackageNote; } /// @@ -320,8 +205,8 @@ namespace YooAsset /// public PackageDetails GetPackageDetails() { - DebugCheckInitialize(); - return _playModeImpl.ActiveManifest.GetPackageDetails(); + EnsureInitialized(); + return _fileSystemHost.ActiveManifest.GetPackageDetails(); } #endregion @@ -331,7 +216,7 @@ namespace YooAsset /// public UnloadAllAssetsOperation UnloadAllAssetsAsync() { - var options = new UnloadAllAssetsOptions(); + var options = new UnloadAllAssetsOptions(true, true); return UnloadAllAssetsAsync(options); } @@ -341,7 +226,7 @@ namespace YooAsset /// 卸载选项 public UnloadAllAssetsOperation UnloadAllAssetsAsync(UnloadAllAssetsOptions options) { - DebugCheckInitialize(); + EnsureInitialized(); var operation = new UnloadAllAssetsOperation(_resourceManager, options); OperationSystem.StartOperation(PackageName, operation); return operation; @@ -350,12 +235,23 @@ namespace YooAsset /// /// 回收不再使用的资源 /// 说明:卸载引用计数为零的资源 + /// 说明:默认循环10次 /// - /// 循环迭代次数 - public UnloadUnusedAssetsOperation UnloadUnusedAssetsAsync(int loopCount = 10) + public UnloadUnusedAssetsOperation UnloadUnusedAssetsAsync() { - DebugCheckInitialize(); - var operation = new UnloadUnusedAssetsOperation(_resourceManager, loopCount); + int defaultLoopCount = 10; + var options = new UnloadUnusedAssetsOptions(defaultLoopCount); + return UnloadUnusedAssetsAsync(options); + } + + /// + /// 回收不再使用的资源 + /// 说明:卸载引用计数为零的资源 + /// + public UnloadUnusedAssetsOperation UnloadUnusedAssetsAsync(UnloadUnusedAssetsOptions options) + { + EnsureInitialized(); + var operation = new UnloadUnusedAssetsOperation(_resourceManager, options); OperationSystem.StartOperation(PackageName, operation); return operation; } @@ -366,7 +262,7 @@ namespace YooAsset /// public void TryUnloadUnusedAsset(string location, int loopCount = 10) { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null); _resourceManager.TryUnloadUnusedAsset(assetInfo, loopCount); } @@ -377,7 +273,7 @@ namespace YooAsset /// public void TryUnloadUnusedAsset(AssetInfo assetInfo, int loopCount = 10) { - DebugCheckInitialize(); + EnsureInitialized(); _resourceManager.TryUnloadUnusedAsset(assetInfo, loopCount); } #endregion @@ -389,9 +285,9 @@ namespace YooAsset /// 资源的定位地址 public bool IsNeedDownloadFromRemote(string location) { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null); - return IsNeedDownloadFromRemoteInternal(assetInfo); + return _fileSystemHost.IsNeedDownloadFromRemoteInternal(assetInfo); } /// @@ -400,8 +296,8 @@ namespace YooAsset /// 资源的定位地址 public bool IsNeedDownloadFromRemote(AssetInfo assetInfo) { - DebugCheckInitialize(); - return IsNeedDownloadFromRemoteInternal(assetInfo); + EnsureInitialized(); + return _fileSystemHost.IsNeedDownloadFromRemoteInternal(assetInfo); } /// @@ -409,8 +305,8 @@ namespace YooAsset /// public AssetInfo[] GetAllAssetInfos() { - DebugCheckInitialize(); - return _playModeImpl.ActiveManifest.GetAllAssetInfos(); + EnsureInitialized(); + return _fileSystemHost.ActiveManifest.GetAllAssetInfos(); } /// @@ -419,9 +315,9 @@ namespace YooAsset /// 资源标签 public AssetInfo[] GetAssetInfos(string tag) { - DebugCheckInitialize(); + EnsureInitialized(); string[] tags = new string[] { tag }; - return _playModeImpl.ActiveManifest.GetAssetInfosByTags(tags); + return _fileSystemHost.ActiveManifest.GetAssetInfosByTags(tags); } /// @@ -430,8 +326,8 @@ namespace YooAsset /// 资源标签列表 public AssetInfo[] GetAssetInfos(string[] tags) { - DebugCheckInitialize(); - return _playModeImpl.ActiveManifest.GetAssetInfosByTags(tags); + EnsureInitialized(); + return _fileSystemHost.ActiveManifest.GetAssetInfosByTags(tags); } /// @@ -440,7 +336,7 @@ namespace YooAsset /// 资源的定位地址 public AssetInfo GetAssetInfo(string location) { - DebugCheckInitialize(); + EnsureInitialized(); return ConvertLocationToAssetInfo(location, null); } @@ -451,7 +347,7 @@ namespace YooAsset /// 资源类型 public AssetInfo GetAssetInfo(string location, System.Type type) { - DebugCheckInitialize(); + EnsureInitialized(); return ConvertLocationToAssetInfo(location, type); } @@ -461,7 +357,7 @@ namespace YooAsset /// 资源GUID public AssetInfo GetAssetInfoByGUID(string assetGUID) { - DebugCheckInitialize(); + EnsureInitialized(); return ConvertAssetGUIDToAssetInfo(assetGUID, null); } @@ -472,7 +368,7 @@ namespace YooAsset /// 资源类型 public AssetInfo GetAssetInfoByGUID(string assetGUID, System.Type type) { - DebugCheckInitialize(); + EnsureInitialized(); return ConvertAssetGUIDToAssetInfo(assetGUID, type); } @@ -482,32 +378,10 @@ namespace YooAsset /// 资源的定位地址 public bool CheckLocationValid(string location) { - DebugCheckInitialize(); - string assetPath = _playModeImpl.ActiveManifest.TryMappingToAssetPath(location); + EnsureInitialized(); + string assetPath = _fileSystemHost.ActiveManifest.TryMappingToAssetPath(location); return string.IsNullOrEmpty(assetPath) == false; } - - private bool IsNeedDownloadFromRemoteInternal(AssetInfo assetInfo) - { - if (assetInfo.IsInvalid) - { - YooLogger.Warning(assetInfo.Error); - return false; - } - - BundleInfo bundleInfo = _bundleQuery.GetMainBundleInfo(assetInfo); - if (bundleInfo.IsNeedDownloadFromRemote()) - return true; - - List depends = _bundleQuery.GetDependBundleInfos(assetInfo); - foreach (var depend in depends) - { - if (depend.IsNeedDownloadFromRemote()) - return true; - } - - return false; - } #endregion #region 原生文件 @@ -517,7 +391,7 @@ namespace YooAsset /// 资源信息 public RawFileHandle LoadRawFileSync(AssetInfo assetInfo) { - DebugCheckInitialize(); + EnsureInitialized(); return LoadRawFileInternal(assetInfo, true, 0); } @@ -527,7 +401,7 @@ namespace YooAsset /// 资源的定位地址 public RawFileHandle LoadRawFileSync(string location) { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null); return LoadRawFileInternal(assetInfo, true, 0); } @@ -539,7 +413,7 @@ namespace YooAsset /// 加载的优先级 public RawFileHandle LoadRawFileAsync(AssetInfo assetInfo, uint priority = 0) { - DebugCheckInitialize(); + EnsureInitialized(); return LoadRawFileInternal(assetInfo, false, priority); } @@ -550,7 +424,7 @@ namespace YooAsset /// 加载的优先级 public RawFileHandle LoadRawFileAsync(string location, uint priority = 0) { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null); return LoadRawFileInternal(assetInfo, false, priority); } @@ -575,7 +449,7 @@ namespace YooAsset /// 场景物理模式 public SceneHandle LoadSceneSync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, LocalPhysicsMode physicsMode = LocalPhysicsMode.None) { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null); return LoadSceneInternal(assetInfo, true, sceneMode, physicsMode, false, 0); } @@ -588,7 +462,7 @@ namespace YooAsset /// 场景物理模式 public SceneHandle LoadSceneSync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, LocalPhysicsMode physicsMode = LocalPhysicsMode.None) { - DebugCheckInitialize(); + EnsureInitialized(); return LoadSceneInternal(assetInfo, true, sceneMode, physicsMode, false, 0); } @@ -602,7 +476,7 @@ namespace YooAsset /// 加载的优先级 public SceneHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, LocalPhysicsMode physicsMode = LocalPhysicsMode.None, bool suspendLoad = false, uint priority = 0) { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null); return LoadSceneInternal(assetInfo, false, sceneMode, physicsMode, suspendLoad, priority); } @@ -617,13 +491,13 @@ namespace YooAsset /// 加载的优先级 public SceneHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, LocalPhysicsMode physicsMode = LocalPhysicsMode.None, bool suspendLoad = false, uint priority = 0) { - DebugCheckInitialize(); + EnsureInitialized(); return LoadSceneInternal(assetInfo, false, sceneMode, physicsMode, suspendLoad, priority); } private SceneHandle LoadSceneInternal(AssetInfo assetInfo, bool waitForAsyncComplete, LoadSceneMode sceneMode, LocalPhysicsMode physicsMode, bool suspendLoad, uint priority) { - DebugCheckAssetLoadType(assetInfo.AssetType); + DebugEnsureAssetType(assetInfo.AssetType); assetInfo.LoadMethod = AssetInfo.ELoadMethod.LoadScene; var loadSceneParams = new LoadSceneParameters(sceneMode, physicsMode); var handle = _resourceManager.LoadSceneAsync(assetInfo, loadSceneParams, suspendLoad, priority); @@ -633,14 +507,14 @@ namespace YooAsset } #endregion - #region 资源加载 + #region 资源加载 [主资源] /// /// 同步加载资源对象 /// /// 资源信息 public AssetHandle LoadAssetSync(AssetInfo assetInfo) { - DebugCheckInitialize(); + EnsureInitialized(); return LoadAssetInternal(assetInfo, true, 0); } @@ -651,7 +525,7 @@ namespace YooAsset /// 资源的定位地址 public AssetHandle LoadAssetSync(string location) where TObject : UnityEngine.Object { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject)); return LoadAssetInternal(assetInfo, true, 0); } @@ -663,7 +537,7 @@ namespace YooAsset /// 资源类型 public AssetHandle LoadAssetSync(string location, System.Type type) { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type); return LoadAssetInternal(assetInfo, true, 0); } @@ -674,9 +548,8 @@ namespace YooAsset /// 资源的定位地址 public AssetHandle LoadAssetSync(string location) { - DebugCheckInitialize(); - Type type = typeof(UnityEngine.Object); - AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type); + EnsureInitialized(); + AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(UnityEngine.Object)); return LoadAssetInternal(assetInfo, true, 0); } @@ -688,7 +561,7 @@ namespace YooAsset /// 加载的优先级 public AssetHandle LoadAssetAsync(AssetInfo assetInfo, uint priority = 0) { - DebugCheckInitialize(); + EnsureInitialized(); return LoadAssetInternal(assetInfo, false, priority); } @@ -700,7 +573,7 @@ namespace YooAsset /// 加载的优先级 public AssetHandle LoadAssetAsync(string location, uint priority = 0) where TObject : UnityEngine.Object { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject)); return LoadAssetInternal(assetInfo, false, priority); } @@ -713,7 +586,7 @@ namespace YooAsset /// 加载的优先级 public AssetHandle LoadAssetAsync(string location, System.Type type, uint priority = 0) { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type); return LoadAssetInternal(assetInfo, false, priority); } @@ -725,16 +598,15 @@ namespace YooAsset /// 加载的优先级 public AssetHandle LoadAssetAsync(string location, uint priority = 0) { - DebugCheckInitialize(); - Type type = typeof(UnityEngine.Object); - AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type); + EnsureInitialized(); + AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(UnityEngine.Object)); return LoadAssetInternal(assetInfo, false, priority); } private AssetHandle LoadAssetInternal(AssetInfo assetInfo, bool waitForAsyncComplete, uint priority) { - DebugCheckAssetLoadType(assetInfo.AssetType); + DebugEnsureAssetType(assetInfo.AssetType); assetInfo.LoadMethod = AssetInfo.ELoadMethod.LoadAsset; var handle = _resourceManager.LoadAssetAsync(assetInfo, priority); if (waitForAsyncComplete) @@ -743,14 +615,14 @@ namespace YooAsset } #endregion - #region 资源加载 + #region 资源加载 [子资源] /// /// 同步加载子资源对象 /// /// 资源信息 public SubAssetsHandle LoadSubAssetsSync(AssetInfo assetInfo) { - DebugCheckInitialize(); + EnsureInitialized(); return LoadSubAssetsInternal(assetInfo, true, 0); } @@ -761,7 +633,7 @@ namespace YooAsset /// 资源的定位地址 public SubAssetsHandle LoadSubAssetsSync(string location) where TObject : UnityEngine.Object { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject)); return LoadSubAssetsInternal(assetInfo, true, 0); } @@ -773,7 +645,7 @@ namespace YooAsset /// 子对象类型 public SubAssetsHandle LoadSubAssetsSync(string location, System.Type type) { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type); return LoadSubAssetsInternal(assetInfo, true, 0); } @@ -784,9 +656,8 @@ namespace YooAsset /// 资源的定位地址 public SubAssetsHandle LoadSubAssetsSync(string location) { - DebugCheckInitialize(); - Type type = typeof(UnityEngine.Object); - AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type); + EnsureInitialized(); + AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(UnityEngine.Object)); return LoadSubAssetsInternal(assetInfo, true, 0); } @@ -798,7 +669,7 @@ namespace YooAsset /// 加载的优先级 public SubAssetsHandle LoadSubAssetsAsync(AssetInfo assetInfo, uint priority = 0) { - DebugCheckInitialize(); + EnsureInitialized(); return LoadSubAssetsInternal(assetInfo, false, priority); } @@ -810,7 +681,7 @@ namespace YooAsset /// 加载的优先级 public SubAssetsHandle LoadSubAssetsAsync(string location, uint priority = 0) where TObject : UnityEngine.Object { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject)); return LoadSubAssetsInternal(assetInfo, false, priority); } @@ -823,7 +694,7 @@ namespace YooAsset /// 加载的优先级 public SubAssetsHandle LoadSubAssetsAsync(string location, System.Type type, uint priority = 0) { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type); return LoadSubAssetsInternal(assetInfo, false, priority); } @@ -835,16 +706,15 @@ namespace YooAsset /// 加载的优先级 public SubAssetsHandle LoadSubAssetsAsync(string location, uint priority = 0) { - DebugCheckInitialize(); - Type type = typeof(UnityEngine.Object); - AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type); + EnsureInitialized(); + AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(UnityEngine.Object)); return LoadSubAssetsInternal(assetInfo, false, priority); } private SubAssetsHandle LoadSubAssetsInternal(AssetInfo assetInfo, bool waitForAsyncComplete, uint priority) { - DebugCheckAssetLoadType(assetInfo.AssetType); + DebugEnsureAssetType(assetInfo.AssetType); assetInfo.LoadMethod = AssetInfo.ELoadMethod.LoadSubAssets; var handle = _resourceManager.LoadSubAssetsAsync(assetInfo, priority); if (waitForAsyncComplete) @@ -853,14 +723,14 @@ namespace YooAsset } #endregion - #region 资源加载 + #region 资源加载 [全资源] /// /// 同步加载资源包内所有资源对象 /// /// 资源信息 public AllAssetsHandle LoadAllAssetsSync(AssetInfo assetInfo) { - DebugCheckInitialize(); + EnsureInitialized(); return LoadAllAssetsInternal(assetInfo, true, 0); } @@ -871,7 +741,7 @@ namespace YooAsset /// 资源的定位地址 public AllAssetsHandle LoadAllAssetsSync(string location) where TObject : UnityEngine.Object { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject)); return LoadAllAssetsInternal(assetInfo, true, 0); } @@ -883,7 +753,7 @@ namespace YooAsset /// 子对象类型 public AllAssetsHandle LoadAllAssetsSync(string location, System.Type type) { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type); return LoadAllAssetsInternal(assetInfo, true, 0); } @@ -894,9 +764,8 @@ namespace YooAsset /// 资源的定位地址 public AllAssetsHandle LoadAllAssetsSync(string location) { - DebugCheckInitialize(); - Type type = typeof(UnityEngine.Object); - AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type); + EnsureInitialized(); + AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(UnityEngine.Object)); return LoadAllAssetsInternal(assetInfo, true, 0); } @@ -908,7 +777,7 @@ namespace YooAsset /// 加载的优先级 public AllAssetsHandle LoadAllAssetsAsync(AssetInfo assetInfo, uint priority = 0) { - DebugCheckInitialize(); + EnsureInitialized(); return LoadAllAssetsInternal(assetInfo, false, priority); } @@ -920,7 +789,7 @@ namespace YooAsset /// 加载的优先级 public AllAssetsHandle LoadAllAssetsAsync(string location, uint priority = 0) where TObject : UnityEngine.Object { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject)); return LoadAllAssetsInternal(assetInfo, false, priority); } @@ -933,7 +802,7 @@ namespace YooAsset /// 加载的优先级 public AllAssetsHandle LoadAllAssetsAsync(string location, System.Type type, uint priority = 0) { - DebugCheckInitialize(); + EnsureInitialized(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type); return LoadAllAssetsInternal(assetInfo, false, priority); } @@ -945,16 +814,15 @@ namespace YooAsset /// 加载的优先级 public AllAssetsHandle LoadAllAssetsAsync(string location, uint priority = 0) { - DebugCheckInitialize(); - Type type = typeof(UnityEngine.Object); - AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type); + EnsureInitialized(); + AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(UnityEngine.Object)); return LoadAllAssetsInternal(assetInfo, false, priority); } private AllAssetsHandle LoadAllAssetsInternal(AssetInfo assetInfo, bool waitForAsyncComplete, uint priority) { - DebugCheckAssetLoadType(assetInfo.AssetType); + DebugEnsureAssetType(assetInfo.AssetType); assetInfo.LoadMethod = AssetInfo.ELoadMethod.LoadAllAssets; var handle = _resourceManager.LoadAllAssetsAsync(assetInfo, priority); if (waitForAsyncComplete) @@ -964,233 +832,105 @@ namespace YooAsset #endregion #region 资源下载 - /// - /// 创建资源下载器,用于下载当前资源版本所有的资源包文件 - /// - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain) - { - DebugCheckInitialize(); - return _playModeImpl.CreateResourceDownloaderByAll(downloadingMaxNumber, failedTryAgain); - } - - /// - /// 创建资源下载器,用于下载指定的资源标签关联的资源包文件 - /// - /// 资源标签 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain) - { - DebugCheckInitialize(); - return _playModeImpl.CreateResourceDownloaderByTags(new string[] { tag }, downloadingMaxNumber, failedTryAgain); - } - /// /// 创建资源下载器,用于下载指定的资源标签列表关联的资源包文件 /// - /// 资源标签列表 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain) + public ResourceDownloaderOperation CreateResourceDownloader(ResourceDownloaderOptions options) { - DebugCheckInitialize(); - return _playModeImpl.CreateResourceDownloaderByTags(tags, downloadingMaxNumber, failedTryAgain); + EnsureInitialized(); + return _fileSystemHost.CreateResourceDownloader(options); } /// - /// 创建资源下载器,用于下载指定的资源依赖的资源包文件 + /// 创建资源下载器,用于下载指定的资源信息列表依赖的资源包文件 /// - /// 资源的定位地址 - /// 下载资源对象所属资源包内所有资源对象依赖的资源包 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public ResourceDownloaderOperation CreateBundleDownloader(string location, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain) + public ResourceDownloaderOperation CreateResourceDownloader(BundleDownloaderOptions options) { - DebugCheckInitialize(); - var assetInfo = ConvertLocationToAssetInfo(location, null); - AssetInfo[] assetInfos = new AssetInfo[] { assetInfo }; - return _playModeImpl.CreateResourceDownloaderByPaths(assetInfos, recursiveDownload, downloadingMaxNumber, failedTryAgain); - } - public ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain) - { - return CreateBundleDownloader(location, false, downloadingMaxNumber, failedTryAgain); - } - - /// - /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 - /// - /// 资源的定位地址列表 - /// 下载资源对象所属资源包内所有资源对象依赖的资源包 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public ResourceDownloaderOperation CreateBundleDownloader(string[] locations, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain) - { - DebugCheckInitialize(); - List assetInfos = new List(locations.Length); - foreach (var location in locations) - { - var assetInfo = ConvertLocationToAssetInfo(location, null); - assetInfos.Add(assetInfo); - } - return _playModeImpl.CreateResourceDownloaderByPaths(assetInfos.ToArray(), recursiveDownload, downloadingMaxNumber, failedTryAgain); - } - public ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain) - { - return CreateBundleDownloader(locations, false, downloadingMaxNumber, failedTryAgain); - } - - /// - /// 创建资源下载器,用于下载指定的资源依赖的资源包文件 - /// - /// 资源信息 - /// 下载资源对象所属资源包内所有资源对象依赖的资源包 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo assetInfo, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain) - { - DebugCheckInitialize(); - AssetInfo[] assetInfos = new AssetInfo[] { assetInfo }; - return _playModeImpl.CreateResourceDownloaderByPaths(assetInfos, recursiveDownload, downloadingMaxNumber, failedTryAgain); - } - public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo assetInfo, int downloadingMaxNumber, int failedTryAgain) - { - return CreateBundleDownloader(assetInfo, false, downloadingMaxNumber, failedTryAgain); - } - - /// - /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 - /// - /// 资源信息列表 - /// 下载资源对象所属资源包内所有资源对象依赖的资源包 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain) - { - DebugCheckInitialize(); - return _playModeImpl.CreateResourceDownloaderByPaths(assetInfos, recursiveDownload, downloadingMaxNumber, failedTryAgain); - } - public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain) - { - return CreateBundleDownloader(assetInfos, false, downloadingMaxNumber, failedTryAgain); + EnsureInitialized(); + return _fileSystemHost.CreateResourceDownloader(options); } #endregion #region 资源解压 - /// - /// 创建内置资源解压器,用于解压当前资源版本所有的资源包文件 - /// - /// 同时解压的最大文件数 - /// 解压失败的重试次数 - public ResourceUnpackerOperation CreateResourceUnpacker(int unpackingMaxNumber, int failedTryAgain) - { - DebugCheckInitialize(); - return _playModeImpl.CreateResourceUnpackerByAll(unpackingMaxNumber, failedTryAgain); - } - - /// - /// 创建内置资源解压器,用于解压指定的资源标签关联的资源包文件 - /// - /// 资源标签 - /// 同时解压的最大文件数 - /// 解压失败的重试次数 - public ResourceUnpackerOperation CreateResourceUnpacker(string tag, int unpackingMaxNumber, int failedTryAgain) - { - DebugCheckInitialize(); - return _playModeImpl.CreateResourceUnpackerByTags(new string[] { tag }, unpackingMaxNumber, failedTryAgain); - } - /// /// 创建内置资源解压器,用于解压指定的资源标签列表关联的资源包文件 /// - /// 资源标签列表 - /// 同时解压的最大文件数 - /// 解压失败的重试次数 - public ResourceUnpackerOperation CreateResourceUnpacker(string[] tags, int unpackingMaxNumber, int failedTryAgain) + public ResourceUnpackerOperation CreateResourceUnpacker(ResourceUnpackerOptions options) { - DebugCheckInitialize(); - return _playModeImpl.CreateResourceUnpackerByTags(tags, unpackingMaxNumber, failedTryAgain); + EnsureInitialized(); + return _fileSystemHost.CreateResourceUnpacker(options); } #endregion #region 资源导入 /// /// 创建资源导入器 - /// 注意:资源文件名称必须和资源服务器部署的文件名称一致! /// - /// 资源路径列表 - /// 同时导入的最大文件数 - /// 导入失败的重试次数 - public ResourceImporterOperation CreateResourceImporter(string[] filePaths, int importerMaxNumber, int failedTryAgain) + public ResourceImporterOperation CreateResourceImporter(BundleImporterOptions options) { - DebugCheckInitialize(); - return _playModeImpl.CreateResourceImporterByFilePaths(filePaths, importerMaxNumber, failedTryAgain); - } - - /// - /// 创建资源导入器 - /// 注意:资源信息里需要指定BundleName或BundleGUID! - /// - /// 资源信息列表 - /// 同时导入的最大文件数 - /// 导入失败的重试次数 - public ResourceImporterOperation CreateResourceImporter(ImportFileInfo[] fileInfos, int importerMaxNumber, int failedTryAgain) - { - DebugCheckInitialize(); - return _playModeImpl.CreateResourceImporterByFileInfos(fileInfos, importerMaxNumber, failedTryAgain); + EnsureInitialized(); + return _fileSystemHost.CreateResourceImporter(options); } #endregion #region 内部方法 - private AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType) + internal AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType) { - return _playModeImpl.ActiveManifest.ConvertLocationToAssetInfo(location, assetType); + return _fileSystemHost.ActiveManifest.ConvertLocationToAssetInfo(location, assetType); } - private AssetInfo ConvertAssetGUIDToAssetInfo(string assetGUID, System.Type assetType) + internal AssetInfo ConvertAssetGUIDToAssetInfo(string assetGUID, System.Type assetType) { - return _playModeImpl.ActiveManifest.ConvertAssetGUIDToAssetInfo(assetGUID, assetType); + return _fileSystemHost.ActiveManifest.ConvertAssetGUIDToAssetInfo(assetGUID, assetType); } #endregion #region 调试方法 - [Conditional("DEBUG")] - private void DebugCheckInitialize(bool checkActiveManifest = true) + private void EnsureInitialized(bool checkActiveManifest = true) { - if (_initializeStatus == EOperationStatus.None) - throw new YooPackageException(PackageName, "Package initialize not completed !"); - else if (_initializeStatus == EOperationStatus.Failed) - throw new YooPackageException(PackageName, $"Package initialize failed ! {_initializeError}"); + if (InitializeStatus != EOperationStatus.Succeed) + { + switch (InitializeStatus) + { + case EOperationStatus.None: + throw new YooPackageException(PackageName, "Resource package not initialized."); + + case EOperationStatus.Processing: + throw new YooPackageException(PackageName, "Resource package initialization not completed."); + + case EOperationStatus.Failed: + string error = _initializeOp == null ? string.Empty : _initializeOp.Error; + throw new YooPackageException(PackageName, $"Resource package initialization failed. Error: {error}"); + + case EOperationStatus.Aborted: + throw new YooPackageException(PackageName, "Resource package initialization was aborted."); + } + } if (checkActiveManifest) { - if (_playModeImpl.ActiveManifest == null) - throw new YooPackageException(PackageName, "Can not found active package manifest !"); + if (_fileSystemHost.ActiveManifest == null) + throw new YooPackageException(PackageName, "Cannot found active package manifest."); } } [Conditional("DEBUG")] - private void DebugCheckAssetLoadType(System.Type type) + private void DebugEnsureAssetType(System.Type type) { if (type == null) return; if (typeof(UnityEngine.Behaviour).IsAssignableFrom(type)) - { - throw new YooLoadException($"Load asset type is invalid : {type.FullName} !"); - } + throw new YooLoadException($"Load asset type is invalid : {type.FullName}"); if (typeof(UnityEngine.Object).IsAssignableFrom(type) == false) - { - throw new YooLoadException($"Load asset type is invalid : {type.FullName} !"); - } + throw new YooLoadException($"Load asset type is invalid : {type.FullName}"); } #endregion #region 调试信息 - internal DebugPackageData GetDebugPackageData() + internal DiagnosticPackageData GetDebugPackageData() { - DebugPackageData data = new DebugPackageData(); + DiagnosticPackageData data = new DiagnosticPackageData(); data.PackageName = PackageName; data.ProviderInfos = _resourceManager.GetDebugProviderInfos(); data.BundleInfos = _resourceManager.GetDebugBundleInfos(); diff --git a/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs b/Assets/YooAsset/Runtime/Services/IBundleEncryptionServices.cs similarity index 70% rename from Assets/YooAsset/Runtime/Services/IEncryptionServices.cs rename to Assets/YooAsset/Runtime/Services/IBundleEncryptionServices.cs index 6facc4dd..c7d705ac 100644 --- a/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs +++ b/Assets/YooAsset/Runtime/Services/IBundleEncryptionServices.cs @@ -1,7 +1,7 @@  namespace YooAsset { - public struct EncryptFileInfo + public struct BundleEncryptionContext { /// /// 资源包名称 @@ -13,7 +13,7 @@ namespace YooAsset /// public string FileLoadPath; } - public struct EncryptResult + public struct BundleEncryptionResult { /// /// 文件是否加密 @@ -25,9 +25,8 @@ namespace YooAsset /// public byte[] EncryptedData; } - - public interface IEncryptionServices + public interface IBundleEncryptionServices { - EncryptResult Encrypt(EncryptFileInfo fileInfo); + BundleEncryptionResult Encrypt(BundleEncryptionContext bundleInfo); } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs.meta b/Assets/YooAsset/Runtime/Services/IBundleEncryptionServices.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/Services/IEncryptionServices.cs.meta rename to Assets/YooAsset/Runtime/Services/IBundleEncryptionServices.cs.meta diff --git a/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs b/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs deleted file mode 100644 index a5587dc3..00000000 --- a/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.IO; -using UnityEngine; - -namespace YooAsset -{ - public struct DecryptFileInfo - { - /// - /// 资源包名称 - /// - public string BundleName; - - /// - /// 文件加载路径 - /// - public string FileLoadPath; - - /// - /// Unity引擎用于内容校验的CRC - /// - public uint FileLoadCRC; - } - public struct DecryptResult - { - /// - /// 资源包对象 - /// - public AssetBundle Result; - - /// - /// 异步请求句柄 - /// - public AssetBundleCreateRequest CreateRequest; - - /// - /// 托管流对象 - /// 注意:流对象在资源包对象释放的时候会自动释放 - /// - public Stream ManagedStream; - } - - public interface IDecryptionServices - { - /// - /// 同步方式获取解密的资源包 - /// - DecryptResult LoadAssetBundle(DecryptFileInfo fileInfo); - - /// - /// 异步方式获取解密的资源包 - /// - DecryptResult LoadAssetBundleAsync(DecryptFileInfo fileInfo); - - /// - /// 后备方式获取解密的资源包 - /// 注意:当正常解密方法失败后,会触发后备加载! - /// 说明:建议通过LoadFromMemory()方法加载资源包作为保底机制。 - /// issues : https://github.com/tuyoogame/YooAsset/issues/562 - /// - DecryptResult LoadAssetBundleFallback(DecryptFileInfo fileInfo); - - /// - /// 获取解密的字节数据 - /// - byte[] ReadFileData(DecryptFileInfo fileInfo); - - /// - /// 获取解密的文本数据 - /// - string ReadFileText(DecryptFileInfo fileInfo); - } -} diff --git a/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs.meta b/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs.meta deleted file mode 100644 index ea5b4e0d..00000000 --- a/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3444518ef1b082a46a9855fef4f69c86 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/Services/ICopyLocalFileServices.cs b/Assets/YooAsset/Runtime/Services/ILocalFileCopyServices.cs similarity index 93% rename from Assets/YooAsset/Runtime/Services/ICopyLocalFileServices.cs rename to Assets/YooAsset/Runtime/Services/ILocalFileCopyServices.cs index 6124649d..79af5a35 100644 --- a/Assets/YooAsset/Runtime/Services/ICopyLocalFileServices.cs +++ b/Assets/YooAsset/Runtime/Services/ILocalFileCopyServices.cs @@ -23,7 +23,7 @@ namespace YooAsset /// 本地文件拷贝服务类 /// 备注:包体内文件拷贝,沙盒内文件导入都会触发该服务! /// - public interface ICopyLocalFileServices + public interface ILocalFileCopyServices { void CopyFile(LocalFileInfo sourceFileInfo, string destFilePath); } diff --git a/Assets/YooAsset/Runtime/Services/ICopyLocalFileServices.cs.meta b/Assets/YooAsset/Runtime/Services/ILocalFileCopyServices.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/Services/ICopyLocalFileServices.cs.meta rename to Assets/YooAsset/Runtime/Services/ILocalFileCopyServices.cs.meta diff --git a/Assets/YooAsset/Runtime/Services/IWebDecryptionServices.cs b/Assets/YooAsset/Runtime/Services/IWebDecryptionServices.cs deleted file mode 100644 index 99e7cd63..00000000 Binary files a/Assets/YooAsset/Runtime/Services/IWebDecryptionServices.cs and /dev/null differ diff --git a/Assets/YooAsset/Runtime/Services/IWebDecryptionServices.cs.meta b/Assets/YooAsset/Runtime/Services/IWebDecryptionServices.cs.meta deleted file mode 100644 index 5616d69f..00000000 --- a/Assets/YooAsset/Runtime/Services/IWebDecryptionServices.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9143514bc9d4f3e4aa9a50a7cfb08d21 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/Utility/BufferWriter.cs b/Assets/YooAsset/Runtime/Utility/BufferWriter.cs index f1acec27..c002f5e9 100644 --- a/Assets/YooAsset/Runtime/Utility/BufferWriter.cs +++ b/Assets/YooAsset/Runtime/Utility/BufferWriter.cs @@ -121,7 +121,7 @@ namespace YooAsset byte[] bytes = Encoding.UTF8.GetBytes(value); int count = bytes.Length; if (count > ushort.MaxValue) - throw new FormatException($"Write string length cannot be greater than {ushort.MaxValue} !"); + throw new FormatException($"Write string length cannot be greater than {ushort.MaxValue}"); WriteUInt16(Convert.ToUInt16(count)); WriteBytes(bytes); @@ -137,7 +137,7 @@ namespace YooAsset { int count = values.Length; if (count > ushort.MaxValue) - throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue} !"); + throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue}"); WriteUInt16(Convert.ToUInt16(count)); for (int i = 0; i < count; i++) @@ -156,7 +156,7 @@ namespace YooAsset { int count = values.Length; if (count > ushort.MaxValue) - throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue} !"); + throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue}"); WriteUInt16(Convert.ToUInt16(count)); for (int i = 0; i < count; i++) @@ -175,7 +175,7 @@ namespace YooAsset { int count = values.Length; if (count > ushort.MaxValue) - throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue} !"); + throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue}"); WriteUInt16(Convert.ToUInt16(count)); for (int i = 0; i < count; i++) diff --git a/Assets/YooAsset/Runtime/Utility/YooUtility.cs b/Assets/YooAsset/Runtime/Utility/YooUtility.cs index 85e4af84..64c09062 100644 --- a/Assets/YooAsset/Runtime/Utility/YooUtility.cs +++ b/Assets/YooAsset/Runtime/Utility/YooUtility.cs @@ -5,6 +5,27 @@ 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 + } + } + } + /// /// 路径工具类 /// diff --git a/Assets/YooAsset/Runtime/YooAssets.cs b/Assets/YooAsset/Runtime/YooAssets.cs index 635b1822..fd716017 100644 --- a/Assets/YooAsset/Runtime/YooAssets.cs +++ b/Assets/YooAsset/Runtime/YooAssets.cs @@ -13,22 +13,21 @@ namespace YooAsset [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void OnRuntimeInitialize() { - _isInitialize = false; + _isInitialized = false; _packages.Clear(); - _defaultPackage = null; } #endif - private static bool _isInitialize = false; - private static GameObject _driver = null; - private static readonly List _packages = new List(); + private static bool _isInitialized; + private static GameObject _driver; + private static readonly Dictionary _packages = new Dictionary(10); /// /// 是否已经初始化 /// public static bool Initialized { - get { return _isInitialize; } + get { return _isInitialized; } } /// @@ -37,30 +36,27 @@ namespace YooAsset /// 自定义日志处理 public static void Initialize(ILogger logger = null) { - if (_isInitialize) + if (_isInitialized) { - UnityEngine.Debug.LogWarning($"{nameof(YooAssets)} is initialized !"); + YooLogger.Warning("YooAssets is already initialized."); return; } - if (_isInitialize == false) - { - YooLogger.Logger = logger; + YooLogger.Logger = logger; - // 创建驱动器 - _isInitialize = true; - _driver = new UnityEngine.GameObject($"[{nameof(YooAssets)}]"); - _driver.AddComponent(); - UnityEngine.Object.DontDestroyOnLoad(_driver); - YooLogger.Log($"{nameof(YooAssets)} initialize !"); + // 创建驱动器 + _isInitialized = true; + _driver = new UnityEngine.GameObject($"[{nameof(YooAssets)}]"); + _driver.AddComponent(); + UnityEngine.Object.DontDestroyOnLoad(_driver); #if DEBUG - // 添加远程调试脚本 - _driver.AddComponent(); + // 添加远程调试脚本 + _driver.AddComponent(); #endif - OperationSystem.Initialize(); - } + // 初始化异步操作系统 + OperationSystem.Initialize(); } /// @@ -68,15 +64,15 @@ namespace YooAsset /// public static void Destroy() { - if (_isInitialize) + if (_isInitialized) { - _isInitialize = false; + _isInitialized = false; if (_driver != null) GameObject.Destroy(_driver); - // 终止并清空所有包裹的异步操作 - ClearAllPackageOperation(); + // 销毁异步操作系统 + OperationSystem.DestroyAll(); // 卸载所有AssetBundle AssetBundle.UnloadAllAssetBundles(true); @@ -91,47 +87,25 @@ namespace YooAsset /// internal static void Update() { - if (_isInitialize) + if (_isInitialized) { OperationSystem.Update(); } } - /// - /// 终止并清空所有包裹的异步操作 - /// - internal static void ClearAllPackageOperation() - { - foreach (var package in _packages) - { - OperationSystem.ClearPackageOperation(package.PackageName); - } - OperationSystem.DestroyAll(); - } - - /// - /// 创建资源包裹 - /// - /// 包裹名称 - public static ResourcePackage CreatePackage(string packageName) - { - return CreatePackage(packageName, 0); - } - /// /// 创建资源包裹 /// /// 包裹名称 /// 包裹优先级(值越大越优先更新) - public static ResourcePackage CreatePackage(string packageName, int packagePriority) + public static ResourcePackage CreatePackage(string packageName, uint packagePriority = 0) { - CheckException(packageName); + EnsureInitialized(packageName); if (ContainsPackage(packageName)) - throw new YooPackageException(packageName, $"Package {packageName} already existed ! Cannot create duplicate packages."); + throw new YooPackageException(packageName, $"Resource package {packageName} already existed. Cannot create duplicate packages."); - YooLogger.Log($"Create resource package : {packageName}"); ResourcePackage package = new ResourcePackage(packageName); - _packages.Add(package); + _packages.Add(packageName, package); // 注册包裹调度器 OperationSystem.CreatePackageScheduler(packageName, packagePriority); @@ -145,7 +119,7 @@ namespace YooAsset /// 包裹名称 public static ResourcePackage GetPackage(string packageName) { - CheckException(packageName); + EnsureInitialized(packageName); var package = GetPackageInternal(packageName); if (package == null) YooLogger.Error($"Can not found resource package : {packageName}"); @@ -158,16 +132,16 @@ namespace YooAsset /// 包裹名称 public static ResourcePackage TryGetPackage(string packageName) { - CheckException(packageName); + EnsureInitialized(packageName); return GetPackageInternal(packageName); } /// /// 获取所有资源包裹 /// - public static List GetAllPackages() + public static IReadOnlyList GetAllPackages() { - return _packages.ToList(); + return _packages.Values.ToList(); } /// @@ -176,35 +150,24 @@ namespace YooAsset /// 包裹名称 public static bool RemovePackage(string packageName) { - CheckException(packageName); + EnsureInitialized(packageName); ResourcePackage package = GetPackageInternal(packageName); if (package == null) - return false; - - return RemovePackage(package); - } - - /// - /// 移除资源包裹 - /// - /// 包裹实例对象 - public static bool RemovePackage(ResourcePackage package) - { - CheckException(package); - string packageName = package.PackageName; - if (package.InitializeStatus != EOperationStatus.None) { - YooLogger.Error($"The resource package {packageName} has not been destroyed, please call the method {nameof(ResourcePackage.DestroyAsync)} to destroy!"); + YooLogger.Error($"Can not found resource package : {packageName}"); return false; } - YooLogger.Log($"Remove resource package : {packageName}"); + if (package.InitializeStatus != EOperationStatus.None) + { + YooLogger.Error($"The resource package {packageName} has not been destroyed, please call the method {nameof(ResourcePackage.DestroyPackageAsync)} to destroy."); + return false; + } // 先销毁调度器,再移除包裹 OperationSystem.DestroyPackageScheduler(packageName); - _packages.Remove(package); - return true; + return _packages.Remove(packageName); } /// @@ -213,82 +176,45 @@ namespace YooAsset /// 包裹名称 public static bool ContainsPackage(string packageName) { - CheckException(packageName); + EnsureInitialized(packageName); var package = GetPackageInternal(packageName); return package != null; } - /// - /// 开启一个异步操作 - /// - /// 异步操作对象 - public static void StartOperation(GameAsyncOperation operation) - { - // 注意:游戏业务逻辑的包裹填写为空 - OperationSystem.StartOperation(string.Empty, operation); - } - - private static ResourcePackage GetPackageInternal(string packageName) { - foreach (var package in _packages) - { - if (package.PackageName == packageName) - return package; - } - return null; + _packages.TryGetValue(packageName, out var package); + return package; } - private static void CheckException(string packageName) + private static void EnsureInitialized(string packageName) { - if (_isInitialize == false) - throw new YooInitializeException($"{nameof(YooAssets)} not initialized ! Please call {nameof(YooAssets.Initialize)} first."); + if (_isInitialized == false) + throw new YooInitializeException($"YooAssets not initialized. Please call {nameof(YooAssets.Initialize)} first."); if (string.IsNullOrEmpty(packageName)) - throw new YooInitializeException("Package name cannot be null or empty !"); - } - private static void CheckException(ResourcePackage package) - { - if (_isInitialize == false) - throw new YooInitializeException($"{nameof(YooAssets)} not initialized ! Please call {nameof(YooAssets.Initialize)} first."); - - if (package == null) - throw new YooInitializeException("Package instance cannot be null !"); + throw new YooInitializeException("Package name cannot be null or empty."); } #region 系统参数 - /// - /// 设置下载系统参数,自定义下载请求 - /// - [Obsolete("This method is deprecated. Please use FileSystemParametersDefine.UNITY_WEB_REQUEST_CREATOR instead.", true)] - public static void SetDownloadSystemUnityWebRequest(UnityWebRequestCreator createDelegate) - { - throw new NotImplementedException(); - } - /// /// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒) /// public static void SetOperationSystemMaxTimeSlice(long milliseconds) { - if (milliseconds < 10) - { - milliseconds = 10; - YooLogger.Warning($"MaxTimeSlice minimum value is 10 milliseconds."); - } OperationSystem.MaxTimeSlice = milliseconds; } #endregion #region 调试信息 - internal static DebugReport GetDebugReport() + internal static DiagnosticReport GetDebugReport() { - DebugReport report = new DebugReport(); + DiagnosticReport report = new DiagnosticReport(); report.FrameCount = Time.frameCount; - foreach (var package in _packages) + foreach (var kv in _packages) { - var packageData = package.GetDebugPackageData(); - report.PackageDatas.Add(packageData); + var packageData = kv.Value.GetDebugPackageData(); + report.PackageDataList.Add(packageData); } return report; } diff --git a/Assets/YooAsset/Runtime/YooAssetsDriver.cs b/Assets/YooAsset/Runtime/YooAssetsDriver.cs index 4adb4e40..0bf75f39 100644 --- a/Assets/YooAsset/Runtime/YooAssetsDriver.cs +++ b/Assets/YooAsset/Runtime/YooAssetsDriver.cs @@ -24,8 +24,8 @@ namespace YooAsset #if UNITY_EDITOR void OnApplicationQuit() { - // 说明:在编辑器下确保播放被停止时IO类操作被终止。 - YooAssets.ClearAllPackageOperation(); + //注意:在编辑器下确保播放被停止时IO类操作被终止。 + YooAssets.Destroy(); } #endif diff --git a/Assets/YooAsset/Runtime/YooAssetsExtension.cs b/Assets/YooAsset/Runtime/YooAssetsExtension.cs deleted file mode 100644 index 504bc429..00000000 --- a/Assets/YooAsset/Runtime/YooAssetsExtension.cs +++ /dev/null @@ -1,619 +0,0 @@ -using System; -using System.Diagnostics; -using System.Collections; -using System.Collections.Generic; -using UnityEngine.SceneManagement; - -namespace YooAsset -{ - public static partial class YooAssets - { - private static ResourcePackage _defaultPackage; - - /// - /// 设置默认的资源包 - /// - public static void SetDefaultPackage(ResourcePackage package) - { - _defaultPackage = package; - } - - #region 资源信息 - /// - /// 是否需要从远端更新下载 - /// - /// 资源的定位地址 - public static bool IsNeedDownloadFromRemote(string location) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.IsNeedDownloadFromRemote(location); - } - - /// - /// 是否需要从远端更新下载 - /// - /// 资源的定位地址 - public static bool IsNeedDownloadFromRemote(AssetInfo assetInfo) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.IsNeedDownloadFromRemote(assetInfo); - } - - /// - /// 获取资源信息列表 - /// - /// 资源标签 - public static AssetInfo[] GetAssetInfos(string tag) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.GetAssetInfos(tag); - } - - /// - /// 获取资源信息列表 - /// - /// 资源标签列表 - public static AssetInfo[] GetAssetInfos(string[] tags) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.GetAssetInfos(tags); - } - - /// - /// 获取资源信息 - /// - /// 资源的定位地址 - public static AssetInfo GetAssetInfo(string location) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.GetAssetInfo(location); - } - - /// - /// 获取资源信息 - /// - /// 资源的定位地址 - /// 资源类型 - public static AssetInfo GetAssetInfo(string location, System.Type type) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.GetAssetInfo(location, type); - } - - /// - /// 获取资源信息 - /// - /// 资源GUID - public static AssetInfo GetAssetInfoByGUID(string assetGUID) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.GetAssetInfoByGUID(assetGUID); - } - - /// - /// 获取资源信息 - /// - /// 资源GUID - /// 资源类型 - public static AssetInfo GetAssetInfoByGUID(string assetGUID, System.Type type) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.GetAssetInfoByGUID(assetGUID, type); - } - - /// - /// 检查资源定位地址是否有效 - /// - /// 资源的定位地址 - public static bool CheckLocationValid(string location) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.CheckLocationValid(location); - } - #endregion - - #region 原生文件 - /// - /// 同步加载原生文件 - /// - /// 资源信息 - public static RawFileHandle LoadRawFileSync(AssetInfo assetInfo) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadRawFileSync(assetInfo); - } - - /// - /// 同步加载原生文件 - /// - /// 资源的定位地址 - public static RawFileHandle LoadRawFileSync(string location) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadRawFileSync(location); - } - - - /// - /// 异步加载原生文件 - /// - /// 资源信息 - public static RawFileHandle LoadRawFileAsync(AssetInfo assetInfo, uint priority = 0) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadRawFileAsync(assetInfo, priority); - } - - /// - /// 异步加载原生文件 - /// - /// 资源的定位地址 - public static RawFileHandle LoadRawFileAsync(string location, uint priority = 0) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadRawFileAsync(location, priority); - } - #endregion - - #region 场景加载 - /// - /// 同步加载场景 - /// - /// 场景的定位地址 - /// 场景加载模式 - /// 场景物理模式 - public static SceneHandle LoadSceneSync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, LocalPhysicsMode physicsMode = LocalPhysicsMode.None) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadSceneSync(location, sceneMode, physicsMode); - } - - /// - /// 同步加载场景 - /// - /// 场景的资源信息 - /// 场景加载模式 - /// 场景物理模式 - public static SceneHandle LoadSceneSync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, LocalPhysicsMode physicsMode = LocalPhysicsMode.None) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadSceneSync(assetInfo, sceneMode, physicsMode); - } - - /// - /// 异步加载场景 - /// - /// 场景的定位地址 - /// 场景加载模式 - /// 场景物理模式 - /// 场景加载到90%自动挂起 - /// 优先级 - public static SceneHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, LocalPhysicsMode physicsMode = LocalPhysicsMode.None, bool suspendLoad = false, uint priority = 100) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadSceneAsync(location, sceneMode, physicsMode, suspendLoad, priority); - } - - /// - /// 异步加载场景 - /// - /// 场景的资源信息 - /// 场景加载模式 - /// 场景物理模式 - /// 场景加载到90%自动挂起 - /// 优先级 - public static SceneHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, LocalPhysicsMode physicsMode = LocalPhysicsMode.None, bool suspendLoad = false, uint priority = 100) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadSceneAsync(assetInfo, sceneMode, physicsMode, suspendLoad, priority); - } - #endregion - - #region 资源加载 - /// - /// 同步加载资源对象 - /// - /// 资源信息 - public static AssetHandle LoadAssetSync(AssetInfo assetInfo) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAssetSync(assetInfo); - } - - /// - /// 同步加载资源对象 - /// - /// 资源类型 - /// 资源的定位地址 - public static AssetHandle LoadAssetSync(string location) where TObject : UnityEngine.Object - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAssetSync(location); - } - - /// - /// 同步加载资源对象 - /// - /// 资源的定位地址 - /// 资源类型 - public static AssetHandle LoadAssetSync(string location, System.Type type) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAssetSync(location, type); - } - - /// - /// 同步加载资源对象 - /// - /// 资源的定位地址 - public static AssetHandle LoadAssetSync(string location) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAssetSync(location); - } - - - /// - /// 异步加载资源对象 - /// - /// 资源信息 - public static AssetHandle LoadAssetAsync(AssetInfo assetInfo, uint priority = 0) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAssetAsync(assetInfo, priority); - } - - /// - /// 异步加载资源对象 - /// - /// 资源类型 - /// 资源的定位地址 - public static AssetHandle LoadAssetAsync(string location, uint priority = 0) where TObject : UnityEngine.Object - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAssetAsync(location, priority); - } - - /// - /// 异步加载资源对象 - /// - /// 资源的定位地址 - /// 资源类型 - public static AssetHandle LoadAssetAsync(string location, System.Type type, uint priority = 0) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAssetAsync(location, type, priority); - } - - /// - /// 异步加载资源对象 - /// - /// 资源的定位地址 - public static AssetHandle LoadAssetAsync(string location, uint priority = 0) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAssetAsync(location, priority); - } - #endregion - - #region 资源加载 - /// - /// 同步加载子资源对象 - /// - /// 资源信息 - public static SubAssetsHandle LoadSubAssetsSync(AssetInfo assetInfo) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadSubAssetsSync(assetInfo); - } - - /// - /// 同步加载子资源对象 - /// - /// 资源类型 - /// 资源的定位地址 - public static SubAssetsHandle LoadSubAssetsSync(string location) where TObject : UnityEngine.Object - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadSubAssetsSync(location); - } - - /// - /// 同步加载子资源对象 - /// - /// 资源的定位地址 - /// 子对象类型 - public static SubAssetsHandle LoadSubAssetsSync(string location, System.Type type) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadSubAssetsSync(location, type); - } - - /// - /// 同步加载子资源对象 - /// - /// 资源的定位地址 - public static SubAssetsHandle LoadSubAssetsSync(string location) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadSubAssetsSync(location); - } - - - /// - /// 异步加载子资源对象 - /// - /// 资源信息 - public static SubAssetsHandle LoadSubAssetsAsync(AssetInfo assetInfo, uint priority = 0) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadSubAssetsAsync(assetInfo, priority); - } - - /// - /// 异步加载子资源对象 - /// - /// 资源类型 - /// 资源的定位地址 - public static SubAssetsHandle LoadSubAssetsAsync(string location, uint priority = 0) where TObject : UnityEngine.Object - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadSubAssetsAsync(location, priority); - } - - /// - /// 异步加载子资源对象 - /// - /// 资源的定位地址 - /// 子对象类型 - public static SubAssetsHandle LoadSubAssetsAsync(string location, System.Type type, uint priority = 0) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadSubAssetsAsync(location, type, priority); - } - - /// - /// 异步加载子资源对象 - /// - /// 资源的定位地址 - public static SubAssetsHandle LoadSubAssetsAsync(string location, uint priority = 0) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadSubAssetsAsync(location, priority); - } - #endregion - - #region 资源加载 - /// - /// 同步加载资源包内所有资源对象 - /// - /// 资源信息 - public static AllAssetsHandle LoadAllAssetsSync(AssetInfo assetInfo) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAllAssetsSync(assetInfo); - } - - /// - /// 同步加载资源包内所有资源对象 - /// - /// 资源类型 - /// 资源的定位地址 - public static AllAssetsHandle LoadAllAssetsSync(string location) where TObject : UnityEngine.Object - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAllAssetsSync(location); - } - - /// - /// 同步加载资源包内所有资源对象 - /// - /// 资源的定位地址 - /// 子对象类型 - public static AllAssetsHandle LoadAllAssetsSync(string location, System.Type type) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAllAssetsSync(location, type); - } - - /// - /// 同步加载资源包内所有资源对象 - /// - /// 资源的定位地址 - public static AllAssetsHandle LoadAllAssetsSync(string location) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAllAssetsSync(location); - } - - - /// - /// 异步加载资源包内所有资源对象 - /// - /// 资源信息 - public static AllAssetsHandle LoadAllAssetsAsync(AssetInfo assetInfo, uint priority = 0) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAllAssetsAsync(assetInfo, priority); - } - - /// - /// 异步加载资源包内所有资源对象 - /// - /// 资源类型 - /// 资源的定位地址 - public static AllAssetsHandle LoadAllAssetsAsync(string location, uint priority = 0) where TObject : UnityEngine.Object - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAllAssetsAsync(location, priority); - } - - /// - /// 异步加载资源包内所有资源对象 - /// - /// 资源的定位地址 - /// 子对象类型 - public static AllAssetsHandle LoadAllAssetsAsync(string location, System.Type type, uint priority = 0) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAllAssetsAsync(location, type, priority); - } - - /// - /// 异步加载资源包内所有资源对象 - /// - /// 资源的定位地址 - public static AllAssetsHandle LoadAllAssetsAsync(string location, uint priority = 0) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.LoadAllAssetsAsync(location, priority); - } - #endregion - - #region 资源下载 - /// - /// 创建资源下载器,用于下载当前资源版本所有的资源包文件 - /// - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public static ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.CreateResourceDownloader(downloadingMaxNumber, failedTryAgain); - } - - /// - /// 创建资源下载器,用于下载指定的资源标签关联的资源包文件 - /// - /// 资源标签 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public static ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.CreateResourceDownloader(new string[] { tag }, downloadingMaxNumber, failedTryAgain); - } - - /// - /// 创建资源下载器,用于下载指定的资源标签列表关联的资源包文件 - /// - /// 资源标签列表 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public static ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.CreateResourceDownloader(tags, downloadingMaxNumber, failedTryAgain); - } - - /// - /// 创建资源下载器,用于下载指定的资源依赖的资源包文件 - /// - /// 资源定位地址 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public static ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.CreateBundleDownloader(location, downloadingMaxNumber, failedTryAgain); - } - - /// - /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 - /// - /// 资源定位地址列表 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public static ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.CreateBundleDownloader(locations, downloadingMaxNumber, failedTryAgain); - } - - /// - /// 创建资源下载器,用于下载指定的资源依赖的资源包文件 - /// - /// 资源信息 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public static ResourceDownloaderOperation CreateBundleDownloader(AssetInfo assetInfo, int downloadingMaxNumber, int failedTryAgain) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.CreateBundleDownloader(assetInfo, downloadingMaxNumber, failedTryAgain); - } - - /// - /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 - /// - /// 资源信息列表 - /// 同时下载的最大文件数 - /// 下载失败的重试次数 - public static ResourceDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.CreateBundleDownloader(assetInfos, downloadingMaxNumber, failedTryAgain); - } - #endregion - - #region 资源解压 - /// - /// 创建内置资源解压器,用于解压当前资源版本所有的资源包文件 - /// - /// 同时解压的最大文件数 - /// 解压失败的重试次数 - public static ResourceUnpackerOperation CreateResourceUnpacker(int unpackingMaxNumber, int failedTryAgain) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.CreateResourceUnpacker(unpackingMaxNumber, failedTryAgain); - } - - /// - /// 创建内置资源解压器,用于解压指定的资源标签关联的资源包文件 - /// - /// 资源标签 - /// 同时解压的最大文件数 - /// 解压失败的重试次数 - public static ResourceUnpackerOperation CreateResourceUnpacker(string tag, int unpackingMaxNumber, int failedTryAgain) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.CreateResourceUnpacker(tag, unpackingMaxNumber, failedTryAgain); - } - - /// - /// 创建内置资源解压器,用于解压指定的资源标签列表关联的资源包文件 - /// - /// 资源标签列表 - /// 同时解压的最大文件数 - /// 解压失败的重试次数 - public static ResourceUnpackerOperation CreateResourceUnpacker(string[] tags, int unpackingMaxNumber, int failedTryAgain) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.CreateResourceUnpacker(tags, unpackingMaxNumber, failedTryAgain); - } - #endregion - - #region 资源导入 - /// - /// 创建资源导入器 - /// 注意:资源文件名称必须和资源服务器部署的文件名称一致! - /// - /// 资源路径列表 - /// 同时导入的最大文件数 - /// 导入失败的重试次数 - public static ResourceImporterOperation CreateResourceImporter(string[] filePaths, int importerMaxNumber, int failedTryAgain) - { - DebugCheckDefaultPackageValid(); - return _defaultPackage.CreateResourceImporter(filePaths, importerMaxNumber, failedTryAgain); - } - #endregion - - #region 调试方法 - [Conditional("DEBUG")] - private static void DebugCheckDefaultPackageValid() - { - if (_defaultPackage == null) - throw new YooInitializeException($"Default package is null. Please use {nameof(YooAssets.SetDefaultPackage)} !"); - } - #endregion - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/YooAssetsExtension.cs.meta b/Assets/YooAsset/Runtime/YooAssetsExtension.cs.meta deleted file mode 100644 index 68145ca3..00000000 --- a/Assets/YooAsset/Runtime/YooAssetsExtension.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2db868c2aaaee8e42a7f035117e747c4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Editor/CreateBuildinCatalog/CreateBuildinCatalogWindow.cs b/Assets/YooAsset/Samples~/Extension Sample/Editor/CreateBuildinCatalog/CreateBuildinCatalogWindow.cs index b8c03bda..6b52a644 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 = CatalogTools.CreateCatalogFile(null, packageName, packageRoot); //TODO 自行处理解密 + bool result = CatalogFileTools.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 ea244849..6cd2e902 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 = CatalogTools.CreateEmptyCatalogFile(_packageName, string.Empty, outputPath); + bool result = CatalogFileTools.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 6af12fa5..e0d28f00 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 = ManifestTools.DeserializeFromBinary(bytesData1, null); //TODO 自行处理解密 + PackageManifest manifest1 = PackageManifestTools.DeserializeFromBinary(bytesData1, null); //TODO 自行处理解密 // 加载补丁清单1 byte[] bytesData2 = FileUtility.ReadAllBytes(_manifestPath2); - PackageManifest manifest2 = ManifestTools.DeserializeFromBinary(bytesData2, null); //TODO 自行处理解密 + PackageManifest manifest2 = PackageManifestTools.DeserializeFromBinary(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 ac3ac2e6..7a1ba040 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 = ManifestTools.DeserializeFromBinary(bytesData, null); //TODO 自行处理解密 + PackageManifest manifest = PackageManifestTools.DeserializeFromBinary(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 339fc58d..e569c12c 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 = CatalogTools.CreateCatalogFile(null, packageName, pacakgeDirectory); //TODO 自行处理解密 + bool result = CatalogFileTools.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/CompatibleOldVersion.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/CompatibleOldVersion.cs new file mode 100644 index 00000000..eb53ca3b --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/CompatibleOldVersion.cs @@ -0,0 +1,506 @@ +using System.Collections.Generic; +using UnityEngine; +using YooAsset; + +#region InitializeParameters +/// +/// 初始化参数 +/// +public abstract class InitializeParameters +{ + /// + /// 同时加载Bundle文件的最大并发数 + /// + public int BundleLoadingMaxConcurrency = int.MaxValue; + + /// + /// 当资源引用计数为零的时候自动释放资源包 + /// + public bool AutoUnloadBundleWhenUnused = false; + + /// + /// WebGL平台强制同步加载资源对象 + /// + public bool WebGLForceSyncLoadAsset = false; +} + +/// +/// 编辑器下模拟运行模式的初始化参数 +/// +public class EditorSimulateModeParameters : InitializeParameters +{ + public FileSystemParameters EditorFileSystemParameters; +} + +/// +/// 离线运行模式的初始化参数 +/// +public class OfflinePlayModeParameters : InitializeParameters +{ + public FileSystemParameters BuildinFileSystemParameters; +} + +/// +/// 联机运行模式的初始化参数 +/// +public class HostPlayModeParameters : InitializeParameters +{ + public FileSystemParameters BuildinFileSystemParameters; + public FileSystemParameters CacheFileSystemParameters; +} + +/// +/// WebGL运行模式的初始化参数 +/// +public class WebPlayModeParameters : InitializeParameters +{ + public FileSystemParameters WebServerFileSystemParameters; + public FileSystemParameters WebRemoteFileSystemParameters; +} +#endregion + +#region InitializationOperation +public class InitializationOperation : AsyncOperationBase +{ + private bool _isDone = false; + private readonly InitializePackageOperation _operation; + + internal InitializationOperation(InitializePackageOperation op) + { + _operation = op; + } + internal override void InternalStart() + { + } + internal override void InternalUpdate() + { + if (_isDone) + return; + + _operation.UpdateOperation(); + if (_operation.IsDone == false) + return; + + _isDone = true; + Status = _operation.Status; + Error = _operation.Error; + } +} +#endregion + +#region DestroyOperation +public class DestroyOperation : AsyncOperationBase +{ + private bool _isDone = false; + private readonly DestroyPackageOperation _operation; + + internal DestroyOperation(DestroyPackageOperation op) + { + _operation = op; + } + internal override void InternalStart() + { + } + internal override void InternalUpdate() + { + if (_isDone) + return; + + _operation.UpdateOperation(); + if (_operation.IsDone == false) + return; + + _isDone = true; + Status = _operation.Status; + Error = _operation.Error; + } +} +#endregion + +#region UpdatePackageManifestOperation +public class UpdatePackageManifestOperation : AsyncOperationBase +{ + private bool _isDone = false; + private readonly LoadManifestOperation _operation; + + internal UpdatePackageManifestOperation(LoadManifestOperation op) + { + _operation = op; + } + internal override void InternalStart() + { + } + internal override void InternalUpdate() + { + if (_isDone) + return; + + _operation.UpdateOperation(); + if (_operation.IsDone == false) + return; + + _isDone = true; + Status = _operation.Status; + Error = _operation.Error; + } +} +#endregion + +#region ImportFileInfo +public struct ImportFileInfo +{ + /// + /// 本地文件路径 + /// + public string FilePath; + + /// + /// 资源包名称 + /// + public string BundleName; + + /// + /// 资源包GUID + /// + public string BundleGUID; +} +#endregion + +public static class CompatibleResourcePackage +{ + /// + /// 兼容Yoo2版本 + /// + public static InitializationOperation InitializeAsync(this ResourcePackage package, InitializeParameters parameters) + { + if (parameters is EditorSimulateModeParameters) + { + var initializeParameters = parameters as EditorSimulateModeParameters; + var options = new EditorSimulateModeOptions(); + options.BundleLoadingMaxConcurrency = initializeParameters.BundleLoadingMaxConcurrency; + options.AutoUnloadBundleWhenUnused = initializeParameters.AutoUnloadBundleWhenUnused; + options.WebGLForceSyncLoadAsset = initializeParameters.WebGLForceSyncLoadAsset; + options.EditorFileSystemParameters = initializeParameters.EditorFileSystemParameters; + var operation = package.InitializePackageAsync(options); + var wrapper = new InitializationOperation(operation); + OperationSystem.StartOperation(package.PackageName, wrapper); + return wrapper; + } + else if (parameters is OfflinePlayModeParameters) + { + var initializeParameters = parameters as OfflinePlayModeParameters; + var options = new OfflinePlayModeOptions(); + options.BundleLoadingMaxConcurrency = initializeParameters.BundleLoadingMaxConcurrency; + options.AutoUnloadBundleWhenUnused = initializeParameters.AutoUnloadBundleWhenUnused; + options.WebGLForceSyncLoadAsset = initializeParameters.WebGLForceSyncLoadAsset; + options.BuildinFileSystemParameters = initializeParameters.BuildinFileSystemParameters; + var operation = package.InitializePackageAsync(options); + var wrapper = new InitializationOperation(operation); + OperationSystem.StartOperation(package.PackageName, wrapper); + return wrapper; + } + else if (parameters is HostPlayModeParameters) + { + var initializeParameters = parameters as HostPlayModeParameters; + var options = new HostPlayModeOptions(); + options.BundleLoadingMaxConcurrency = initializeParameters.BundleLoadingMaxConcurrency; + options.AutoUnloadBundleWhenUnused = initializeParameters.AutoUnloadBundleWhenUnused; + options.WebGLForceSyncLoadAsset = initializeParameters.WebGLForceSyncLoadAsset; + options.BuildinFileSystemParameters = initializeParameters.BuildinFileSystemParameters; + options.CacheFileSystemParameters = initializeParameters.CacheFileSystemParameters; + var operation = package.InitializePackageAsync(options); + var wrapper = new InitializationOperation(operation); + OperationSystem.StartOperation(package.PackageName, wrapper); + return wrapper; + } + else if (parameters is WebPlayModeParameters) + { + var initializeParameters = parameters as WebPlayModeParameters; + var options = new WebPlayModeOptions(); + options.BundleLoadingMaxConcurrency = initializeParameters.BundleLoadingMaxConcurrency; + options.AutoUnloadBundleWhenUnused = initializeParameters.AutoUnloadBundleWhenUnused; + options.WebGLForceSyncLoadAsset = initializeParameters.WebGLForceSyncLoadAsset; + options.WebServerFileSystemParameters = initializeParameters.WebServerFileSystemParameters; + options.WebRemoteFileSystemParameters = initializeParameters.WebRemoteFileSystemParameters; + var operation = package.InitializePackageAsync(options); + var wrapper = new InitializationOperation(operation); + OperationSystem.StartOperation(package.PackageName, wrapper); + return wrapper; + } + else + { + throw new System.NotImplementedException(); + } + } + + /// + /// 兼容Yoo2版本 + /// + public static DestroyOperation DestroyAsync(this ResourcePackage package) + { + var operation = package.DestroyPackageAsync(); + var wrapper = new DestroyOperation(operation); + OperationSystem.StartOperation(package.PackageName, wrapper); + return wrapper; + } + + /// + /// 兼容Yoo2版本 + /// + public static RequestVersionOperation RequestPackageVersionAsync(this ResourcePackage package, bool appendTimeTicks = true, int timeout = 60) + { + var options = new RequestVersionOptions(appendTimeTicks, timeout); + return package.RequestVersionAsync(options); + } + + /// + /// 兼容Yoo2版本 + /// + public static UpdatePackageManifestOperation UpdatePackageManifestAsync(this ResourcePackage package, string packageVersion, int timeout = 60) + { + var options = new LoadManifestOptions(packageVersion, timeout); + var operation = package.LoadManifestAsync(options); + var wrapper = new UpdatePackageManifestOperation(operation); + OperationSystem.StartOperation(package.PackageName, wrapper); + return wrapper; + } + + /// + /// 兼容Yoo2版本 + /// + public static PreDownloaderOperation PreDownloadContentAsync(this ResourcePackage package, string packageVersion, int timeout = 60) + { + var options = new PreDownloaderOptions(packageVersion, timeout); + return package.PreDownloaderAsync(options); + } + + /// + /// 兼容Yoo2版本 + /// + public static ClearCacheOperation ClearCacheFilesAsync(this ResourcePackage package, EFileClearMode fileClearMode, object clearParam = null) + { + var options = new ClearCacheOptions(fileClearMode, clearParam); + return package.ClearCacheAsync(options); + } + + /// + /// 兼容Yoo2版本 + /// + public static ClearCacheOperation ClearCacheFilesAsync(this ResourcePackage package, string fileClearMode, object clearParam = null) + { + var options = new ClearCacheOptions(fileClearMode, clearParam); + return package.ClearCacheAsync(options); + } + + /// + /// 兼容Yoo2版本 + /// + public static UnloadUnusedAssetsOperation UnloadUnusedAssetsAsync(this ResourcePackage package, int loopCount) + { + var options = new UnloadUnusedAssetsOptions(loopCount); + return package.UnloadUnusedAssetsAsync(options); + } + + #region 资源下载 + /// + /// 兼容Yoo2版本 + /// + public static ResourceDownloaderOperation CreateResourceDownloader(this ResourcePackage package, int downloadingMaxNumber, int failedTryAgain) + { + var options = new ResourceDownloaderOptions(downloadingMaxNumber, failedTryAgain); + return package.CreateResourceDownloader(options); + } + + /// + /// 兼容Yoo2版本 + /// + public static ResourceDownloaderOperation CreateResourceDownloader(this ResourcePackage package, string tag, int downloadingMaxNumber, int failedTryAgain) + { + string[] tags = new string[] { tag }; + var options = new ResourceDownloaderOptions(tags, downloadingMaxNumber, failedTryAgain); + return package.CreateResourceDownloader(options); + } + + /// + /// 兼容Yoo2版本 + /// + public static ResourceDownloaderOperation CreateResourceDownloader(this ResourcePackage package, string[] tags, int downloadingMaxNumber, int failedTryAgain) + { + var options = new ResourceDownloaderOptions(tags, downloadingMaxNumber, failedTryAgain); + return package.CreateResourceDownloader(options); + } + + /// + /// 兼容Yoo2版本 + /// + public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, string location, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain) + { + var assetInfo = package.ConvertLocationToAssetInfo(location, null); + var options = new BundleDownloaderOptions(assetInfo, recursiveDownload, downloadingMaxNumber, failedTryAgain); + return package.CreateResourceDownloader(options); + } + public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, string location, int downloadingMaxNumber, int failedTryAgain) + { + return package.CreateBundleDownloader(location, false, downloadingMaxNumber, failedTryAgain); + } + + /// + /// 兼容Yoo2版本 + /// + public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, string[] locations, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain) + { + List assetInfos = new List(locations.Length); + foreach (var location in locations) + { + var assetInfo = package.ConvertLocationToAssetInfo(location, null); + assetInfos.Add(assetInfo); + } + + var options = new BundleDownloaderOptions(assetInfos.ToArray(), recursiveDownload, downloadingMaxNumber, failedTryAgain); + return package.CreateResourceDownloader(options); + } + public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, string[] locations, int downloadingMaxNumber, int failedTryAgain) + { + return package.CreateBundleDownloader(locations, false, downloadingMaxNumber, failedTryAgain); + } + + /// + /// 兼容Yoo2版本 + /// + public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, AssetInfo assetInfo, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain) + { + AssetInfo[] assetInfos = new AssetInfo[] { assetInfo }; + var options = new BundleDownloaderOptions(assetInfos, recursiveDownload, downloadingMaxNumber, failedTryAgain); + return package.CreateResourceDownloader(options); + } + public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, AssetInfo assetInfo, int downloadingMaxNumber, int failedTryAgain) + { + return package.CreateBundleDownloader(assetInfo, false, downloadingMaxNumber, failedTryAgain); + } + + /// + /// 兼容Yoo2版本 + /// + public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain) + { + var options = new BundleDownloaderOptions(assetInfos, recursiveDownload, downloadingMaxNumber, failedTryAgain); + return package.CreateResourceDownloader(options); + } + public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain) + { + return package.CreateBundleDownloader(assetInfos, false, downloadingMaxNumber, failedTryAgain); + } + #endregion + + #region 资源解压 + /// + /// 兼容Yoo2版本 + /// + public static ResourceUnpackerOperation CreateResourceUnpacker(this ResourcePackage package, int unpackingMaxNumber, int failedTryAgain) + { + var options = new ResourceUnpackerOptions(unpackingMaxNumber, failedTryAgain); + return package.CreateResourceUnpacker(options); + } + + /// + /// 兼容Yoo2版本 + /// + public static ResourceUnpackerOperation CreateResourceUnpacker(this ResourcePackage package, string tag, int unpackingMaxNumber, int failedTryAgain) + { + string[] tags = new string[] { tag }; + var options = new ResourceUnpackerOptions(tags, unpackingMaxNumber, failedTryAgain); + return package.CreateResourceUnpacker(options); + } + + /// + /// 兼容Yoo2版本 + /// + public static ResourceUnpackerOperation CreateResourceUnpacker(this ResourcePackage package, string[] tags, int unpackingMaxNumber, int failedTryAgain) + { + var options = new ResourceUnpackerOptions(tags, unpackingMaxNumber, failedTryAgain); + return package.CreateResourceUnpacker(options); + } + #endregion + + #region 资源导入 + /// + /// 兼容Yoo2版本 + /// + public static ResourceImporterOperation CreateResourceImporter(this ResourcePackage package, string[] filePaths, int importerMaxNumber, int failedTryAgain) + { + ImportFileInfo[] fileInfos = new ImportFileInfo[filePaths.Length]; + for (int i = 0; i < filePaths.Length; i++) + { + ImportFileInfo fileInfo = new ImportFileInfo(); + fileInfo.FilePath = filePaths[i]; + fileInfos[i] = fileInfo; + } + + return package.CreateResourceImporter(fileInfos, importerMaxNumber, failedTryAgain); + } + + /// + /// 兼容Yoo2版本 + /// + public static ResourceImporterOperation CreateResourceImporter(this ResourcePackage package, ImportFileInfo[] fileInfos, int importerMaxNumber, int failedTryAgain) + { + ImportBundleInfo[] bundleInfos = new ImportBundleInfo[fileInfos.Length]; + for (int i = 0; i < fileInfos.Length; i++) + { + ImportBundleInfo bundleInfo = new ImportBundleInfo(); + bundleInfo.FilePath = fileInfos[i].FilePath; + bundleInfo.BundleName = fileInfos[i].BundleName; + bundleInfo.BundleGUID = fileInfos[i].BundleGUID; + bundleInfos[i] = bundleInfo; + } + + var options = new BundleImporterOptions(bundleInfos, importerMaxNumber, failedTryAgain); + return package.CreateResourceImporter(options); + } + #endregion +} + +public static class CompatibleAssetHandle +{ + public static GameObject InstantiateSync(this AssetHandle handle, Transform parent) + { + var options = new InstantiateOptions(true, parent, false); + return handle.InstantiateSync(options); + } + public static GameObject InstantiateSync(this AssetHandle handle, Transform parent, bool worldPositionStays) + { + var options = new InstantiateOptions(true, parent, worldPositionStays); + return handle.InstantiateSync(options); + } + public static GameObject InstantiateSync(this AssetHandle handle, Vector3 position, Quaternion rotation) + { + var options = new InstantiateOptions(true, position, rotation); + return handle.InstantiateSync(options); + } + public static GameObject InstantiateSync(this AssetHandle handle, Vector3 position, Quaternion rotation, Transform parent) + { + var options = new InstantiateOptions(true, parent, position, rotation); + return handle.InstantiateSync(options); + } + + public static InstantiateOperation InstantiateAsync(this AssetHandle handle, Transform parent, bool actived = true) + { + var options = new InstantiateOptions(actived, parent, false); + return handle.InstantiateAsync(options); + } + public static InstantiateOperation InstantiateAsync(this AssetHandle handle, Transform parent, bool worldPositionStays, bool actived = true) + { + var options = new InstantiateOptions(actived, parent, worldPositionStays); + return handle.InstantiateAsync(options); + } + public static InstantiateOperation InstantiateAsync(this AssetHandle handle, Vector3 position, Quaternion rotation, bool actived = true) + { + var options = new InstantiateOptions(actived, position, rotation); + return handle.InstantiateAsync(options); + } + public static InstantiateOperation InstantiateAsync(this AssetHandle handle, Vector3 position, Quaternion rotation, Transform parent, bool actived = true) + { + var options = new InstantiateOptions(actived, parent, position, rotation); + return handle.InstantiateAsync(options); + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/CompatibleOldVersion.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/CompatibleOldVersion.cs.meta new file mode 100644 index 00000000..466e4d35 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/CompatibleOldVersion.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b974d3d744622f3499d026f99074cd72 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/CopyBuildinManifestOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/CopyBuildinManifestOperation.cs index 4ad500a0..fc87ad14 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/CopyBuildinManifestOperation.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/CopyBuildinManifestOperation.cs @@ -7,7 +7,7 @@ using YooAsset; /// /// 拷贝内置清单文件到沙盒目录 /// -public class CopyBuildinManifestOperation : GameAsyncOperation +public class CopyBuildinManifestOperation : AsyncOperationBase { private enum ESteps { @@ -32,11 +32,11 @@ public class CopyBuildinManifestOperation : GameAsyncOperation _packageVersion = packageVersion; _backend = new UnityWebRequestBackend(); } - protected override void OnStart() + internal override void InternalStart() { _steps = ESteps.CheckHashFile; } - protected override void OnUpdate() + internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; @@ -59,7 +59,7 @@ public class CopyBuildinManifestOperation : GameAsyncOperation { string sourcePath = GetBuildinHashFilePath(); string destPath = GetCacheHashFilePath(); - string url = DownloadSystemHelper.ConvertToWWWPath(sourcePath); + string url = DownloadSystemTools.ToLocalURL(sourcePath); var args = new DownloadFileRequestArgs(url, destPath, 60, 0); _hashFileRequestOp = _backend.CreateFileRequest(args); _hashFileRequestOp.SendRequest(); @@ -99,7 +99,7 @@ public class CopyBuildinManifestOperation : GameAsyncOperation { string sourcePath = GetBuildinManifestFilePath(); string destPath = GetCacheManifestFilePath(); - string url = DownloadSystemHelper.ConvertToWWWPath(sourcePath); + string url = DownloadSystemTools.ToLocalURL(sourcePath); var args = new DownloadFileRequestArgs(url, destPath, 60, 0); _manifestFileRequestOp = _backend.CreateFileRequest(args); _manifestFileRequestOp.SendRequest(); @@ -121,9 +121,6 @@ public class CopyBuildinManifestOperation : GameAsyncOperation } } } - protected override void OnAbort() - { - } private string GetBuildinYooRoot() { diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/GetBuildinPackageVersionOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/GetBuildinPackageVersionOperation.cs index 6217dca9..b2eac7a8 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/GetBuildinPackageVersionOperation.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/GetBuildinPackageVersionOperation.cs @@ -7,7 +7,7 @@ using YooAsset; /// /// 获取包体里的内置资源清单版本 /// -public class GetBuildinPackageVersionOperation : GameAsyncOperation +public class GetBuildinPackageVersionOperation : AsyncOperationBase { private enum ESteps { @@ -31,11 +31,11 @@ public class GetBuildinPackageVersionOperation : GameAsyncOperation _packageName = packageName; _backend = new UnityWebRequestBackend(); } - protected override void OnStart() + internal override void InternalStart() { _steps = ESteps.GetPackageVersion; } - protected override void OnUpdate() + internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; @@ -45,7 +45,7 @@ public class GetBuildinPackageVersionOperation : GameAsyncOperation if (_versionFileRequestOp == null) { string filePath = GetBuildinPackageVersionFilePath(); - string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + string url = DownloadSystemTools.ToLocalURL(filePath); var args = new DownloadDataRequestArgs(url, 60, 0); _versionFileRequestOp = _backend.CreateTextRequest(args); _versionFileRequestOp.SendRequest(); @@ -68,9 +68,6 @@ public class GetBuildinPackageVersionOperation : GameAsyncOperation } } } - protected override void OnAbort() - { - } private string GetBuildinYooRoot() { diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/GetCacheBundleSizeOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/GetCacheBundleSizeOperation.cs index 6eb9b501..5459a32a 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/GetCacheBundleSizeOperation.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/GetCacheBundleSizeOperation.cs @@ -7,7 +7,7 @@ using YooAsset; /// /// 获取沙盒目录里缓存文件大小 /// -public class GetCacheBundleSizeOperation : GameAsyncOperation +public class GetCacheBundleSizeOperation : AsyncOperationBase { private enum ESteps { @@ -29,11 +29,11 @@ public class GetCacheBundleSizeOperation : GameAsyncOperation { _packageName = packageName; } - protected override void OnStart() + internal override void InternalStart() { _steps = ESteps.GetCacheFiles; } - protected override void OnUpdate() + internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; @@ -57,9 +57,6 @@ public class GetCacheBundleSizeOperation : GameAsyncOperation Status = EOperationStatus.Succeed; } } - protected override void OnAbort() - { - } private string GetCacheDirectoryRoot() { diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadAssetsByTagOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadAssetsByTagOperation.cs index 2e275c08..82fe34fa 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadAssetsByTagOperation.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadAssetsByTagOperation.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using UnityEngine; using YooAsset; -public class LoadAssetsByTagOperation : GameAsyncOperation where TObject : UnityEngine.Object +public class LoadAssetsByTagOperation : AsyncOperationBase where TObject : UnityEngine.Object { private enum ESteps { @@ -14,6 +14,7 @@ public class LoadAssetsByTagOperation : GameAsyncOperation where TObjec Done, } + private readonly string _packageName; private readonly string _tag; private ESteps _steps = ESteps.None; private List _handles; @@ -24,26 +25,28 @@ public class LoadAssetsByTagOperation : GameAsyncOperation where TObjec public List AssetObjects { private set; get; } - public LoadAssetsByTagOperation(string tag) + public LoadAssetsByTagOperation(string packageName, string tag) { + _packageName = packageName; _tag = tag; } - protected override void OnStart() + internal override void InternalStart() { _steps = ESteps.LoadAssets; } - protected override void OnUpdate() + internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; if (_steps == ESteps.LoadAssets) { - AssetInfo[] assetInfos = YooAssets.GetAssetInfos(_tag); + var package = YooAssets.GetPackage(_packageName); + AssetInfo[] assetInfos = package.GetAssetInfos(_tag); _handles = new List(assetInfos.Length); foreach (var assetInfo in assetInfos) { - var handle = YooAssets.LoadAssetAsync(assetInfo); + var handle = package.LoadAssetAsync(assetInfo); _handles.Add(handle); } _steps = ESteps.CheckResult; @@ -53,7 +56,7 @@ public class LoadAssetsByTagOperation : GameAsyncOperation where TObjec { int index = 0; foreach (var handle in _handles) - { + { if (handle.IsDone == false) { Progress = (float)index / _handles.Count; @@ -77,7 +80,7 @@ public class LoadAssetsByTagOperation : GameAsyncOperation where TObjec string error = $"资源类型转换失败:{handle.AssetObject.name}"; Debug.LogError($"{error}"); AssetObjects.Clear(); - SetFinish(false, error); + SetFailed(error); return; } } @@ -85,21 +88,23 @@ public class LoadAssetsByTagOperation : GameAsyncOperation where TObjec { Debug.LogError($"{handle.LastError}"); AssetObjects.Clear(); - SetFinish(false, handle.LastError); + SetFailed(handle.LastError); return; } } - SetFinish(true); + SetSucceed(); } } - protected override void OnAbort() + private void SetSucceed() { + Status = EOperationStatus.Succeed; + _steps = ESteps.Done; } - private void SetFinish(bool succeed, string error = "") + private void SetFailed(string error) { Error = error; - Status = succeed ? EOperationStatus.Succeed : EOperationStatus.Failed; + Status = EOperationStatus.Failed; _steps = ESteps.Done; } diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadGameObjectOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadGameObjectOperation.cs index fa4ef821..e1984113 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadGameObjectOperation.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/LoadGameObjectOperation.cs @@ -6,15 +6,15 @@ using YooAsset; public static class YooAssetsExtension { - public static LoadGameObjectOperation LoadGameObjectAsync(this ResourcePackage resourcePackage, string location, Vector3 position, Quaternion rotation, Transform parent, bool destroyGoOnRelease = false) + public static LoadGameObjectOperation LoadGameObjectAsync(this ResourcePackage package, string location, Vector3 position, Quaternion rotation, Transform parent, bool destroyGoOnRelease = false) { - var operation = new LoadGameObjectOperation(location, position, rotation, parent, destroyGoOnRelease); - YooAssets.StartOperation(operation); + var operation = new LoadGameObjectOperation(package.PackageName, location, position, rotation, parent, destroyGoOnRelease); + OperationSystem.StartOperation(OperationSystem.GlobalSchedulerName, operation); return operation; } } -public class LoadGameObjectOperation : GameAsyncOperation +public class LoadGameObjectOperation : AsyncOperationBase { private enum ESteps { @@ -23,6 +23,7 @@ public class LoadGameObjectOperation : GameAsyncOperation Done, } + private readonly string _packageName; private readonly string _location; private readonly Vector3 _positon; private readonly Quaternion _rotation; @@ -37,19 +38,20 @@ public class LoadGameObjectOperation : GameAsyncOperation public GameObject Go { private set; get; } - public LoadGameObjectOperation(string location, Vector3 position, Quaternion rotation, Transform parent, bool destroyGoOnRelease = false) + public LoadGameObjectOperation(string packageName, string location, Vector3 position, Quaternion rotation, Transform parent, bool destroyGoOnRelease = false) { + _packageName = packageName; _location = location; _positon = position; _rotation = rotation; _parent = parent; _destroyGoOnRelease = destroyGoOnRelease; } - protected override void OnStart() + internal override void InternalStart() { _steps = ESteps.LoadAsset; } - protected override void OnUpdate() + internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; @@ -58,7 +60,8 @@ public class LoadGameObjectOperation : GameAsyncOperation { if (_handle == null) { - _handle = YooAssets.LoadAssetAsync(_location); + var package = YooAssets.GetPackage(_packageName); + _handle = package.LoadAssetAsync(_location); } Progress = _handle.Progress; @@ -79,9 +82,6 @@ public class LoadGameObjectOperation : GameAsyncOperation } } } - protected override void OnAbort() - { - } /// /// 释放资源句柄 diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/OperationHelper.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/OperationHelper.cs new file mode 100644 index 00000000..d5bacbf2 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/OperationHelper.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using YooAsset; + +public class OperationHelper +{ + /// + /// 开始一个业务实现的自定义异步任务 + /// + public static void StartOperation(AsyncOperationBase operation) + { + OperationSystem.StartOperation(OperationSystem.GlobalSchedulerName, operation); + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/OperationHelper.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/OperationHelper.cs.meta new file mode 100644 index 00000000..98379f7f --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ExtensionOperation/OperationHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fd52bc7cb896369498d42a12081816ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/OperationMonitor/OperationMonitor.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/OperationMonitor/OperationMonitor.cs index bda79d71..049ebd70 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/OperationMonitor/OperationMonitor.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/OperationMonitor/OperationMonitor.cs @@ -6,8 +6,6 @@ public static class OperationMonitor { public static void RegisterOperationCallback() { - OperationSystem.RegisterStartCallback(OperationStartCallback); - OperationSystem.RegisterFinishCallback(OperationFinishCallback); } private static void OperationStartCallback(string packageName, AsyncOperationBase operation) diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/MiniGameTest/FileSystemTester.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/MiniGameTest/FileSystemTester.cs index 80084a63..a5737cc6 100644 --- a/Assets/YooAsset/Samples~/Mini Game/Runtime/MiniGameTest/FileSystemTester.cs +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/MiniGameTest/FileSystemTester.cs @@ -11,7 +11,7 @@ namespace YooAsset // 初始化小游戏文件系统 Debug.Log("初始化小游戏文件系统!"); - var initializeFileSystemOp = fileSystem.InitializeFileSystemAsync(); + var initializeFileSystemOp = fileSystem.InitializeAsync(); OperationSystem.StartOperation(packageName, initializeFileSystemOp); yield return initializeFileSystemOp; if (initializeFileSystemOp.Status != EOperationStatus.Succeed) @@ -22,7 +22,8 @@ namespace YooAsset // 请求资源版本 Debug.Log("请求资源版本信息!"); - var requestPackageVersionOp = fileSystem.RequestPackageVersionAsync(true, 60); + var requestPackageVersionOptions = new RequestVersionOptions(true, 60); + var requestPackageVersionOp = fileSystem.RequestVersionAsync(requestPackageVersionOptions); OperationSystem.StartOperation(packageName, requestPackageVersionOp); yield return requestPackageVersionOp; if (requestPackageVersionOp.Status != EOperationStatus.Succeed) @@ -34,7 +35,8 @@ namespace YooAsset // 请求资源清单 string packageVersion = requestPackageVersionOp.PackageVersion; Debug.Log($"加载资源清单文件!{packageVersion}"); - var loadPackageManifestOp = fileSystem.LoadPackageManifestAsync(packageVersion, 60); + var loadPackageManifestOptions = new LoadManifestOptions(packageVersion, 60); + var loadPackageManifestOp = fileSystem.LoadManifestAsync(loadPackageManifestOptions); OperationSystem.StartOperation(packageName, loadPackageManifestOp); yield return loadPackageManifestOp; if (loadPackageManifestOp.Status != EOperationStatus.Succeed) @@ -48,8 +50,8 @@ namespace YooAsset { var manifest = loadPackageManifestOp.Manifest; var packageBundle = GetPackageBundle(manifest, testLocation); - var options = new DownloadFileOptions(1); - var downloadFileOp = fileSystem.DownloadFileAsync(packageBundle, options); + var options = new DownloadFileOptions(packageBundle, 1); + var downloadFileOp = fileSystem.DownloadFileAsync(options); OperationSystem.StartOperation(packageName, downloadFileOp); yield return downloadFileOp; if (downloadFileOp.Status != EOperationStatus.Succeed) @@ -68,7 +70,8 @@ namespace YooAsset { var manifest = loadPackageManifestOp.Manifest; var packageBundle = GetPackageBundle(manifest, testLocation); - var loadBundleFileOp = fileSystem.LoadBundleFile(packageBundle); + var loadBundleFileOptions = new LoadBundleOptions(packageBundle); + var loadBundleFileOp = fileSystem.LoadBundleAsync(loadBundleFileOptions); OperationSystem.StartOperation(packageName, loadBundleFileOp); yield return loadBundleFileOp; if (loadBundleFileOp.Status != EOperationStatus.Succeed) diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/BattleRoom.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/BattleRoom.cs index a5313d00..abe7e3f8 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/BattleRoom.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/BattleLogic/BattleRoom.cs @@ -100,7 +100,7 @@ public class BattleRoom if (_startWaitTimer.Update(Time.deltaTime)) { // 生成实体 - var assetHandle = YooAssets.LoadAssetAsync("player_ship"); + var assetHandle = GameManager.Instance.GamePakcage.LoadAssetAsync("player_ship"); assetHandle.Completed += (AssetHandle handle) => { handle.InstantiateSync(_roomRoot.transform); @@ -117,7 +117,7 @@ public class BattleRoom Quaternion spawnRotation = Quaternion.identity; // 生成实体 - var assetHandle = YooAssets.LoadAssetAsync(enemyLocation); + var assetHandle = GameManager.Instance.GamePakcage.LoadAssetAsync(enemyLocation); assetHandle.Completed += (AssetHandle handle) => { handle.InstantiateSync(spawnPosition, spawnRotation, _roomRoot.transform); @@ -166,7 +166,7 @@ public class BattleRoom var msg = message as BattleEventDefine.PlayerDead; // 创建爆炸效果 - var assetHandle = YooAssets.LoadAssetAsync("explosion_player"); + var assetHandle = GameManager.Instance.GamePakcage.LoadAssetAsync("explosion_player"); assetHandle.Completed += (AssetHandle handle) => { handle.InstantiateSync(msg.Position, msg.Rotation, _roomRoot.transform); @@ -181,7 +181,7 @@ public class BattleRoom var msg = message as BattleEventDefine.EnemyDead; // 创建爆炸效果 - var assetHandle = YooAssets.LoadAssetAsync("explosion_enemy"); + var assetHandle = GameManager.Instance.GamePakcage.LoadAssetAsync("explosion_enemy"); assetHandle.Completed += (AssetHandle handle) => { handle.InstantiateSync(msg.Position, msg.Rotation, _roomRoot.transform); @@ -196,7 +196,7 @@ public class BattleRoom var msg = message as BattleEventDefine.AsteroidExplosion; // 创建爆炸效果 - var assetHandle = YooAssets.LoadAssetAsync("explosion_asteroid"); + var assetHandle = GameManager.Instance.GamePakcage.LoadAssetAsync("explosion_asteroid"); assetHandle.Completed += (AssetHandle handle) => { handle.InstantiateSync(msg.Position, msg.Rotation, _roomRoot.transform); @@ -211,7 +211,7 @@ public class BattleRoom var msg = message as BattleEventDefine.PlayerFireBullet; // 创建子弹实体 - var assetHandle = YooAssets.LoadAssetAsync("player_bullet"); + var assetHandle = GameManager.Instance.GamePakcage.LoadAssetAsync("player_bullet"); assetHandle.Completed += (AssetHandle handle) => { handle.InstantiateSync(msg.Position, msg.Rotation, _roomRoot.transform); @@ -223,7 +223,7 @@ public class BattleRoom var msg = message as BattleEventDefine.EnemyFireBullet; // 创建子弹实体 - var assetHandle = YooAssets.LoadAssetAsync("enemy_bullet"); + var assetHandle = GameManager.Instance.GamePakcage.LoadAssetAsync("enemy_bullet"); assetHandle.Completed += (AssetHandle handle) => { handle.InstantiateSync(msg.Position, msg.Rotation, _roomRoot.transform); diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/Boot.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/Boot.cs index 953255b3..cb8f3f6c 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/Boot.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/Boot.cs @@ -19,7 +19,7 @@ public class Boot : MonoBehaviour Application.runInBackground = true; DontDestroyOnLoad(this.gameObject); } - IEnumerator Start() + void Start() { // 游戏管理器 GameManager.Instance.Behaviour = this; @@ -34,16 +34,12 @@ public class Boot : MonoBehaviour var go = Resources.Load("PatchWindow"); GameObject.Instantiate(go); - // 开始补丁更新流程 - var operation = new PatchOperation("DefaultPackage", PlayMode); - YooAssets.StartOperation(operation); - yield return operation; - - // 设置默认的资源包 - var gamePackage = YooAssets.GetPackage("DefaultPackage"); - YooAssets.SetDefaultPackage(gamePackage); - - // 切换到主页面场景 - SceneEventDefine.ChangeToHomeScene.SendEventMessage(); + // 补丁更新流程 + PatchManager.Create("DefaultPackage", PlayMode); + PatchManager.Start(); + } + private void Update() + { + PatchManager.Update(); } } \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/EventDefine/PatchEventDefine.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/EventDefine/PatchEventDefine.cs index e2c1cfb5..cdbb4dbd 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/EventDefine/PatchEventDefine.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/EventDefine/PatchEventDefine.cs @@ -57,7 +57,7 @@ public class PatchEventDefine public long TotalDownloadSizeBytes; public long CurrentDownloadSizeBytes; - public static void SendEventMessage(DownloadUpdateData updateData) + public static void SendEventMessage(DownloadProgressChangedEventArgs updateData) { var msg = new DownloadUpdate(); msg.TotalDownloadCount = updateData.TotalDownloadCount; @@ -100,7 +100,7 @@ public class PatchEventDefine public string FileName; public string Error; - public static void SendEventMessage(DownloadErrorData errorData) + public static void SendEventMessage(DownloadErrorEventArgs errorData) { var msg = new WebFileDownloadFailed(); msg.FileName = errorData.FileName; diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/GameManager.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/GameManager.cs index 3fe1b261..be2ec095 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/GameManager.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/GameManager.cs @@ -19,6 +19,11 @@ public class GameManager private readonly EventGroup _eventGroup = new EventGroup(); + /// + /// 游戏包裹 + /// + public ResourcePackage GamePakcage; + /// /// 协程启动器 /// @@ -47,11 +52,11 @@ public class GameManager { if (message is SceneEventDefine.ChangeToHomeScene) { - YooAssets.LoadSceneAsync("scene_home"); + GamePakcage.LoadSceneAsync("scene_home"); } else if (message is SceneEventDefine.ChangeToBattleScene) { - YooAssets.LoadSceneAsync("scene_battle"); + GamePakcage.LoadSceneAsync("scene_battle"); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/SceneBattle.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/SceneBattle.cs index b2312de8..78292f4e 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/SceneBattle.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/SceneBattle.cs @@ -14,12 +14,12 @@ internal class SceneBattle : MonoBehaviour private IEnumerator Start() { // 加载战斗页面 - _windowHandle = YooAssets.LoadAssetAsync("UIBattle"); + _windowHandle = GameManager.Instance.GamePakcage.LoadAssetAsync("UIBattle"); yield return _windowHandle; _windowHandle.InstantiateSync(CanvasDesktop.transform); // 加载背景音乐 - _musicHandle = YooAssets.LoadAssetAsync("music_background"); + _musicHandle = GameManager.Instance.GamePakcage.LoadAssetAsync("music_background"); yield return _musicHandle; // 播放背景音乐 diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/SceneHome.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/SceneHome.cs index c6756e86..7df2f530 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/SceneHome.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/GameLogic/SceneHome.cs @@ -11,7 +11,7 @@ public class SceneHome : MonoBehaviour private IEnumerator Start() { // 加载主页面 - _windowHandle = YooAssets.LoadAssetAsync("UIHome"); + _windowHandle = GameManager.Instance.GamePakcage.LoadAssetAsync("UIHome"); yield return _windowHandle; _windowHandle.InstantiateSync(CanvasDesktop.transform); diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmDownloadPackageFiles.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmDownloadPackageFiles.cs index ea5d6bd8..efe21631 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmDownloadPackageFiles.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmDownloadPackageFiles.cs @@ -26,8 +26,8 @@ public class FsmDownloadPackageFiles : IStateNode private IEnumerator BeginDownload() { var downloader = (ResourceDownloaderOperation)_machine.GetBlackboardValue("Downloader"); - downloader.DownloadErrorCallback = PatchEventDefine.WebFileDownloadFailed.SendEventMessage; - downloader.DownloadUpdateCallback = PatchEventDefine.DownloadUpdate.SendEventMessage; + downloader.DownloadErrorHandler = PatchEventDefine.WebFileDownloadFailed.SendEventMessage; + downloader.DownloadProgressChangedHandler = PatchEventDefine.DownloadUpdate.SendEventMessage; downloader.BeginDownload(); yield return downloader; diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmInitializePackage.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmInitializePackage.cs index 7e586444..3cb33732 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmInitializePackage.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmInitializePackage.cs @@ -40,10 +40,13 @@ internal class FsmInitializePackage : IStateNode InitializationOperation initializationOperation = null; if (playMode == EPlayMode.EditorSimulateMode) { - var buildResult = EditorSimulateModeHelper.SimulateBuild(packageName); + var buildResult = EditorSimulateBuildInvoker.Build(packageName); var packageRoot = buildResult.PackageRootDirectory; var createParameters = new EditorSimulateModeParameters(); createParameters.EditorFileSystemParameters = FileSystemParameters.CreateDefaultEditorFileSystemParameters(packageRoot); + createParameters.EditorFileSystemParameters.AddParameter(FileSystemParametersDefine.VIRTUAL_WEBGL_MODE, true); + createParameters.EditorFileSystemParameters.AddParameter(FileSystemParametersDefine.VIRTUAL_DOWNLOAD_MODE, true); + createParameters.EditorFileSystemParameters.AddParameter(FileSystemParametersDefine.VIRTUAL_DOWNLOAD_SPEED, 1024 * 1000); initializationOperation = package.InitializeAsync(createParameters); } @@ -63,7 +66,11 @@ internal class FsmInitializePackage : IStateNode IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer); var createParameters = new HostPlayModeParameters(); createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(); + createParameters.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST, true); createParameters.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices); + createParameters.CacheFileSystemParameters.AddParameter(FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY, 5); + createParameters.CacheFileSystemParameters.AddParameter(FileSystemParametersDefine.DOWNLOAD_MAX_REQUEST_PER_FRAME, 1); + createParameters.CacheFileSystemParameters.AddParameter(FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME, 10); initializationOperation = package.InitializeAsync(createParameters); } diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmRequestPackageVersion.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmRequestPackageVersion.cs index e0a8aaa8..09268032 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmRequestPackageVersion.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmRequestPackageVersion.cs @@ -28,7 +28,7 @@ internal class FsmRequestPackageVersion : IStateNode { var packageName = (string)_machine.GetBlackboardValue("PackageName"); var package = YooAssets.GetPackage(packageName); - var operation = package.RequestPackageVersionAsync(); + var operation = package.RequestVersionAsync(); yield return operation; if (operation.Status != EOperationStatus.Succeed) diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmStartGame.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmStartGame.cs index ce156ebe..e21249fc 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmStartGame.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/FsmNode/FsmStartGame.cs @@ -2,19 +2,22 @@ using System.Collections.Generic; using UnityEngine; using UniFramework.Machine; +using YooAsset; internal class FsmStartGame : IStateNode { - private PatchOperation _owner; - void IStateNode.OnCreate(StateMachine machine) { - _owner = machine.Owner as PatchOperation; } void IStateNode.OnEnter() { PatchEventDefine.PatchStepsChange.SendEventMessage("开始游戏!"); - _owner.SetFinish(); + + // 设置默认的资源包 + GameManager.Instance.GamePakcage = YooAssets.GetPackage("DefaultPackage"); + + // 切换到主页面场景 + SceneEventDefine.ChangeToHomeScene.SendEventMessage(); } void IStateNode.OnUpdate() { diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchOperation.cs b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchManager.cs similarity index 67% rename from Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchOperation.cs rename to Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchManager.cs index f03fa8ff..a3ace715 100644 --- a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchOperation.cs +++ b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchManager.cs @@ -3,24 +3,13 @@ using UniFramework.Machine; using UniFramework.Event; using YooAsset; -public class PatchOperation : GameAsyncOperation +public static class PatchManager { - private enum ESteps + private static readonly EventGroup _eventGroup = new EventGroup(); + private static StateMachine _machine; + + public static void Create(string packageName, EPlayMode playMode) { - None, - Update, - Done, - } - - private readonly EventGroup _eventGroup = new EventGroup(); - private readonly StateMachine _machine; - private readonly string _packageName; - private ESteps _steps = ESteps.None; - - public PatchOperation(string packageName, EPlayMode playMode) - { - _packageName = packageName; - // 注册监听事件 _eventGroup.AddListener(OnHandleEventMessage); _eventGroup.AddListener(OnHandleEventMessage); @@ -29,7 +18,7 @@ public class PatchOperation : GameAsyncOperation _eventGroup.AddListener(OnHandleEventMessage); // 创建状态机 - _machine = new StateMachine(this); + _machine = new StateMachine(null); _machine.AddNode(); _machine.AddNode(); _machine.AddNode(); @@ -42,37 +31,19 @@ public class PatchOperation : GameAsyncOperation _machine.SetBlackboardValue("PackageName", packageName); _machine.SetBlackboardValue("PlayMode", playMode); } - protected override void OnStart() + public static void Start() { - _steps = ESteps.Update; _machine.Run(); } - protected override void OnUpdate() + public static void Update() { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.Update) - { - _machine.Update(); - } - } - protected override void OnAbort() - { - } - - public void SetFinish() - { - _steps = ESteps.Done; - _eventGroup.RemoveAllListener(); - Status = EOperationStatus.Succeed; - Debug.Log($"Package {_packageName} patch done !"); + _machine.Update(); } /// /// 接收事件 /// - private void OnHandleEventMessage(IEventMessage message) + private static void OnHandleEventMessage(IEventMessage message) { if (message is UserEventDefine.UserTryInitialize) { diff --git a/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchOperation.cs.meta b/Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchManager.cs.meta similarity index 100% rename from Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchOperation.cs.meta rename to Assets/YooAsset/Samples~/Space Shooter/GameScript/Runtime/PatchLogic/PatchManager.cs.meta diff --git a/Assets/YooAsset/Samples~/Test Sample/Editor/TestPackageBuilder.cs b/Assets/YooAsset/Samples~/Test Sample/Editor/TestPackageBuilder.cs index 676ed303..8fedc1db 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Editor/TestPackageBuilder.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Editor/TestPackageBuilder.cs @@ -22,7 +22,7 @@ public static class TestPackageBuilder buildParameters.BuildOutputRoot = outputRoot; buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildPipeline = EBuildPipeline.EditorSimulateBuildPipeline.ToString(); - buildParameters.BuildBundleType = (int)EBuildBundleType.VirtualBundle; + buildParameters.BuildBundleType = (int)EBundleType.VirtualBundle; buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget; buildParameters.PackageName = packageName; buildParameters.PackageVersion = "TestVersion"; @@ -58,7 +58,7 @@ public static class TestPackageBuilder buildParameters.BuildOutputRoot = outputRoot; buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildPipeline = EBuildPipeline.ScriptableBuildPipeline.ToString(); - buildParameters.BuildBundleType = (int)EBuildBundleType.AssetBundle; + buildParameters.BuildBundleType = (int)EBundleType.AssetBundle; buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget; buildParameters.PackageName = packageName; buildParameters.PackageVersion = "TestVersion"; @@ -98,7 +98,7 @@ public static class TestPackageBuilder buildParameters.BuildOutputRoot = outputRoot; buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildPipeline = EBuildPipeline.ScriptableBuildPipeline.ToString(); - buildParameters.BuildBundleType = (int)EBuildBundleType.AssetBundle; + buildParameters.BuildBundleType = (int)EBundleType.AssetBundle; buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget; buildParameters.PackageName = packageName; buildParameters.PackageVersion = "TestVersion"; @@ -137,7 +137,7 @@ public static class TestPackageBuilder buildParameters.BuildOutputRoot = outputRoot; buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(); buildParameters.BuildPipeline = EBuildPipeline.RawFileBuildPipeline.ToString(); - buildParameters.BuildBundleType = (int)EBuildBundleType.RawBundle; + buildParameters.BuildBundleType = (int)EBundleType.RawBundle; buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget; buildParameters.PackageName = packageName; buildParameters.PackageVersion = "TestVersion"; diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileEncryption.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileEncryption.cs new file mode 100644 index 00000000..eb6eb891 --- /dev/null +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileEncryption.cs @@ -0,0 +1,136 @@ +using System; +using System.IO; +using YooAsset; + +public class BundleStream : FileStream +{ + public const byte KEY = 64; + + public BundleStream(string path, FileMode mode, FileAccess access, FileShare share) : base(path, mode, access, share) + { + } + public BundleStream(string path, FileMode mode) : base(path, mode) + { + } + public override int Read(byte[] array, int offset, int count) + { + var index = base.Read(array, offset, count); + for (int i = 0; i < array.Length; i++) + { + array[i] ^= KEY; + } + return index; + } +} +public class TestFileStreamEncryption : IBundleEncryptionServices +{ + public BundleEncryptionResult Encrypt(BundleEncryptionContext fileInfo) + { + // 说明:对TestRes3资源目录进行加密 + if (fileInfo.BundleName.Contains("_testres3_")) + { + var fileData = File.ReadAllBytes(fileInfo.FileLoadPath); + for (int i = 0; i < fileData.Length; i++) + { + fileData[i] ^= BundleStream.KEY; + } + + BundleEncryptionResult result = new BundleEncryptionResult(); + result.Encrypted = true; + result.EncryptedData = fileData; + return result; + } + else + { + BundleEncryptionResult result = new BundleEncryptionResult(); + result.Encrypted = false; + return result; + } + } +} +public class TestFileOffsetEncryption : IBundleEncryptionServices +{ + public BundleEncryptionResult Encrypt(BundleEncryptionContext fileInfo) + { + // 说明:对TestRes3资源目录进行加密 + if (fileInfo.BundleName.Contains("_testres3_")) + { + int offset = 32; + byte[] fileData = File.ReadAllBytes(fileInfo.FileLoadPath); + var encryptedData = new byte[fileData.Length + offset]; + Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length); + + BundleEncryptionResult result = new BundleEncryptionResult(); + result.Encrypted = true; + result.EncryptedData = encryptedData; + return result; + } + else + { + BundleEncryptionResult result = new BundleEncryptionResult(); + result.Encrypted = false; + return result; + } + } +} + +public class TestLoadAssetBundleFromOffsetOperation : DefaultLoadAssetBundleFromOffsetOperation +{ + private const uint FILE_OFFSET = 32; + + public TestLoadAssetBundleFromOffsetOperation(LoadAssetBundleOptions options) : base(options) { } + + protected override uint GetFileOffset() + { + return FILE_OFFSET; + } +} +public class TestLoadAssetBundleFromMemoryOperation : DefaultLoadAssetBundleFromMemoryOperation +{ + public TestLoadAssetBundleFromMemoryOperation(LoadAssetBundleOptions options) : base(options) { } + + protected override byte[] DecryptData(byte[] data) + { + for (int i = 0; i < data.Length; i++) + { + data[i] ^= BundleStream.KEY; + } + return data; + } +} +public class TestLoadAssetBundleFromStreamOperation : DefaultLoadAssetBundleFromStreamOperation +{ + public TestLoadAssetBundleFromStreamOperation(LoadAssetBundleOptions options) : base(options) { } + + protected override FileStream CreateManagedFileStream() + { + var fileStream = new BundleStream(_options.FileLoadPath, FileMode.Open, FileAccess.Read, FileShare.Read); + return fileStream; + } + protected override uint GetManagedReadBufferSize() + { + return 1024; + } + protected override byte[] DecryptData(byte[] data) + { + for (int i = 0; i < data.Length; i++) + { + data[i] ^= BundleStream.KEY; + } + return data; + } +} +public class TestWebAssetBundleFromMemoryDecryption : DefaultLoadWebAssetBundleFromMemoryOperation +{ + public TestWebAssetBundleFromMemoryDecryption(LoadWebAssetBundleOptions opionts) : base(opionts) { } + + protected override byte[] Decryption(byte[] data) + { + for (int i = 0; i < data.Length; i++) + { + data[i] ^= BundleStream.KEY; + } + + return data; + } +} diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileStreamEncryption.cs.meta b/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileEncryption.cs.meta similarity index 100% rename from Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileStreamEncryption.cs.meta rename to Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileEncryption.cs.meta diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileOffsetEncryption.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileOffsetEncryption.cs deleted file mode 100644 index 483a5788..00000000 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileOffsetEncryption.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.IO; -using System.Text; -using System.Collections; -using UnityEngine; -using YooAsset; - -/// -/// 文件偏移加密方式 -/// -public class TestFileOffsetEncryption : IEncryptionServices -{ - public EncryptResult Encrypt(EncryptFileInfo fileInfo) - { - // 说明:对TestRes3资源目录进行加密 - if (fileInfo.BundleName.Contains("_testres3_")) - { - int offset = 32; - byte[] fileData = File.ReadAllBytes(fileInfo.FileLoadPath); - var encryptedData = new byte[fileData.Length + offset]; - Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length); - - EncryptResult result = new EncryptResult(); - result.Encrypted = true; - result.EncryptedData = encryptedData; - return result; - } - else - { - EncryptResult result = new EncryptResult(); - result.Encrypted = false; - return result; - } - } -} - -/// -/// 资源文件偏移解密类 -/// -public class TestFileOffsetDecryption : IDecryptionServices -{ - /// - /// 同步方式获取解密的资源包对象 - /// 注意:加载流对象在资源包对象释放的时候会自动释放 - /// - DecryptResult IDecryptionServices.LoadAssetBundle(DecryptFileInfo fileInfo) - { - DecryptResult decryptResult = new DecryptResult(); - decryptResult.ManagedStream = null; - decryptResult.Result = AssetBundle.LoadFromFile(fileInfo.FileLoadPath, fileInfo.FileLoadCRC, GetFileOffset()); - return decryptResult; - } - - /// - /// 异步方式获取解密的资源包对象 - /// 注意:加载流对象在资源包对象释放的时候会自动释放 - /// - DecryptResult IDecryptionServices.LoadAssetBundleAsync(DecryptFileInfo fileInfo) - { - DecryptResult decryptResult = new DecryptResult(); - decryptResult.ManagedStream = null; - decryptResult.CreateRequest = AssetBundle.LoadFromFileAsync(fileInfo.FileLoadPath, fileInfo.FileLoadCRC, GetFileOffset()); - return decryptResult; - } - - /// - /// 后备方式获取解密的资源包对象 - /// - DecryptResult IDecryptionServices.LoadAssetBundleFallback(DecryptFileInfo fileInfo) - { - return new DecryptResult(); - } - - /// - /// 获取解密的字节数据 - /// - byte[] IDecryptionServices.ReadFileData(DecryptFileInfo fileInfo) - { - throw new System.NotImplementedException(); - } - - /// - /// 获取解密的文本数据 - /// - string IDecryptionServices.ReadFileText(DecryptFileInfo fileInfo) - { - throw new System.NotImplementedException(); - } - - private static ulong GetFileOffset() - { - return 32; - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileOffsetEncryption.cs.meta b/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileOffsetEncryption.cs.meta deleted file mode 100644 index 5f30658f..00000000 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileOffsetEncryption.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 174e56f3a30d7fd4e80bde43ba267631 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileStreamEncryption.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileStreamEncryption.cs deleted file mode 100644 index 40881058..00000000 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileStreamEncryption.cs +++ /dev/null @@ -1,159 +0,0 @@ -using System; -using System.IO; -using System.Text; -using System.Collections; -using UnityEngine; -using YooAsset; - -/// -/// 资源文件解密流 -/// -public class BundleStream : FileStream -{ - public const byte KEY = 64; - - public BundleStream(string path, FileMode mode, FileAccess access, FileShare share) : base(path, mode, access, share) - { - } - public BundleStream(string path, FileMode mode) : base(path, mode) - { - } - - public override int Read(byte[] array, int offset, int count) - { - var index = base.Read(array, offset, count); - for (int i = 0; i < array.Length; i++) - { - array[i] ^= KEY; - } - return index; - } -} - -/// -/// 文件流加密方式 -/// -public class TestFileStreamEncryption : IEncryptionServices -{ - public EncryptResult Encrypt(EncryptFileInfo fileInfo) - { - // 说明:对TestRes3资源目录进行加密 - if (fileInfo.BundleName.Contains("_testres3_")) - { - var fileData = File.ReadAllBytes(fileInfo.FileLoadPath); - for (int i = 0; i < fileData.Length; i++) - { - fileData[i] ^= BundleStream.KEY; - } - - EncryptResult result = new EncryptResult(); - result.Encrypted = true; - result.EncryptedData = fileData; - return result; - } - else - { - EncryptResult result = new EncryptResult(); - result.Encrypted = false; - return result; - } - } -} - -/// -/// 资源文件流解密类 -/// -public class TestFileStreamDecryption : IDecryptionServices -{ - /// - /// 同步方式获取解密的资源包对象 - /// - DecryptResult IDecryptionServices.LoadAssetBundle(DecryptFileInfo fileInfo) - { - BundleStream bundleStream = new BundleStream(fileInfo.FileLoadPath, FileMode.Open, FileAccess.Read, FileShare.Read); - DecryptResult decryptResult = new DecryptResult(); - decryptResult.ManagedStream = bundleStream; - decryptResult.Result = AssetBundle.LoadFromStream(bundleStream, fileInfo.FileLoadCRC, GetManagedReadBufferSize()); - return decryptResult; - } - - /// - /// 异步方式获取解密的资源包对象 - /// - DecryptResult IDecryptionServices.LoadAssetBundleAsync(DecryptFileInfo fileInfo) - { - BundleStream bundleStream = new BundleStream(fileInfo.FileLoadPath, FileMode.Open, FileAccess.Read, FileShare.Read); - DecryptResult decryptResult = new DecryptResult(); - decryptResult.ManagedStream = bundleStream; - decryptResult.CreateRequest = AssetBundle.LoadFromStreamAsync(bundleStream, fileInfo.FileLoadCRC, GetManagedReadBufferSize()); - return decryptResult; - } - - /// - /// 后备方式获取解密的资源包 - /// 注意:当正常解密方法失败后,会触发后备加载! - /// 说明:建议通过LoadFromMemory()方法加载资源包作为保底机制。 - /// - DecryptResult IDecryptionServices.LoadAssetBundleFallback(DecryptFileInfo fileInfo) - { - byte[] fileData = File.ReadAllBytes(fileInfo.FileLoadPath); - var assetBundle = AssetBundle.LoadFromMemory(fileData); - DecryptResult decryptResult = new DecryptResult(); - decryptResult.Result = assetBundle; - return decryptResult; - } - - /// - /// 获取解密的字节数据 - /// - byte[] IDecryptionServices.ReadFileData(DecryptFileInfo fileInfo) - { - throw new System.NotImplementedException(); - } - - /// - /// 获取解密的文本数据 - /// - string IDecryptionServices.ReadFileText(DecryptFileInfo fileInfo) - { - throw new System.NotImplementedException(); - } - - private static uint GetManagedReadBufferSize() - { - return 1024; - } -} - -/// -/// WebGL平台解密类 -/// 注意:WebGL平台支持内存解密 -/// -public class TestWebFileMemoryDecryption : IWebDecryptionServices -{ - public WebDecryptResult LoadAssetBundle(WebDecryptFileInfo fileInfo) - { - /* - byte[] copyData = new byte[fileInfo.FileData.Length]; - Buffer.BlockCopy(fileInfo.FileData, 0, copyData, 0, fileInfo.FileData.Length); - - for (int i = 0; i < copyData.Length; i++) - { - copyData[i] ^= BundleStream.KEY; - } - - WebDecryptResult decryptResult = new WebDecryptResult(); - decryptResult.Result = AssetBundle.LoadFromMemory(copyData); - return decryptResult; - */ - - for (int i = 0; i < fileInfo.FileData.Length; i++) - { - fileInfo.FileData[i] ^= BundleStream.KEY; - } - - WebDecryptResult decryptResult = new WebDecryptResult(); - decryptResult.Result = AssetBundle.LoadFromMemory(fileInfo.FileData); - return decryptResult; - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/T1_TestEditorFileSystem/T1_TestEditorFileSystem.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/T1_TestEditorFileSystem/T1_TestEditorFileSystem.cs index 17d6ac08..d3966619 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/T1_TestEditorFileSystem/T1_TestEditorFileSystem.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/T1_TestEditorFileSystem/T1_TestEditorFileSystem.cs @@ -59,27 +59,28 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup var package = YooAssets.CreatePackage(TestDefine.AssetBundlePackageName); // 初始化资源包 - var initParams = new EditorSimulateModeParameters(); + var initParams = new EditorSimulateModeOptions(); initParams.EditorFileSystemParameters = FileSystemParameters.CreateDefaultEditorFileSystemParameters(packageRoot); - var initializeOp = package.InitializeAsync(initParams); + var initializeOp = package.InitializePackageAsync(initParams); yield return initializeOp; if (initializeOp.Status != EOperationStatus.Succeed) Debug.LogError(initializeOp.Error); Assert.AreEqual(EOperationStatus.Succeed, initializeOp.Status); // 请求资源版本 - var requetVersionOp = package.RequestPackageVersionAsync(); + var requetVersionOp = package.RequestVersionAsync(); yield return requetVersionOp; if (requetVersionOp.Status != EOperationStatus.Succeed) Debug.LogError(requetVersionOp.Error); Assert.AreEqual(EOperationStatus.Succeed, requetVersionOp.Status); // 更新资源清单 - var updateManifestOp = package.UpdatePackageManifestAsync(requetVersionOp.PackageVersion); - yield return updateManifestOp; - if (updateManifestOp.Status != EOperationStatus.Succeed) - Debug.LogError(updateManifestOp.Error); - Assert.AreEqual(EOperationStatus.Succeed, updateManifestOp.Status); + var loadPackageManifestOptions = new LoadManifestOptions(requetVersionOp.PackageVersion, 60); + var loadPackageManifestOp = package.LoadManifestAsync(loadPackageManifestOptions); + yield return loadPackageManifestOp; + if (loadPackageManifestOp.Status != EOperationStatus.Succeed) + Debug.LogError(loadPackageManifestOp.Error); + Assert.AreEqual(EOperationStatus.Succeed, loadPackageManifestOp.Status); } // 初始化资源包 RAW_BUNDLE @@ -94,27 +95,28 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup var package = YooAssets.CreatePackage(TestDefine.RawBundlePackageName); // 初始化资源包 - var initParams = new EditorSimulateModeParameters(); + var initParams = new EditorSimulateModeOptions(); initParams.EditorFileSystemParameters = FileSystemParameters.CreateDefaultEditorFileSystemParameters(packageRoot); - var initializeOp = package.InitializeAsync(initParams); + var initializeOp = package.InitializePackageAsync(initParams); yield return initializeOp; if (initializeOp.Status != EOperationStatus.Succeed) Debug.LogError(initializeOp.Error); Assert.AreEqual(EOperationStatus.Succeed, initializeOp.Status); // 请求资源版本 - var requetVersionOp = package.RequestPackageVersionAsync(); + var requetVersionOp = package.RequestVersionAsync(); yield return requetVersionOp; if (requetVersionOp.Status != EOperationStatus.Succeed) Debug.LogError(requetVersionOp.Error); Assert.AreEqual(EOperationStatus.Succeed, requetVersionOp.Status); // 更新资源清单 - var updateManifestOp = package.UpdatePackageManifestAsync(requetVersionOp.PackageVersion); - yield return updateManifestOp; - if (updateManifestOp.Status != EOperationStatus.Succeed) - Debug.LogError(updateManifestOp.Error); - Assert.AreEqual(EOperationStatus.Succeed, updateManifestOp.Status); + var loadPackageManifestOptions = new LoadManifestOptions(requetVersionOp.PackageVersion, 60); + var loadPackageManifestOp = package.LoadManifestAsync(loadPackageManifestOptions); + yield return loadPackageManifestOp; + if (loadPackageManifestOp.Status != EOperationStatus.Succeed) + Debug.LogError(loadPackageManifestOp.Error); + Assert.AreEqual(EOperationStatus.Succeed, loadPackageManifestOp.Status); } } 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 fb0545bd..0ed2c895 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 @@ -59,31 +59,31 @@ public class T2_TestBuldinFileSystem : IPrebuildSetup, IPostBuildCleanup var package = YooAssets.CreatePackage(TestDefine.AssetBundlePackageName); // 初始化资源包 - var initParams = new OfflinePlayModeParameters(); - var fileDecryption = new TestFileStreamDecryption(); + var initParams = new OfflinePlayModeOptions(); var manifestServices = new TestRestoreManifest(); - initParams.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(fileDecryption, packageRoot); + initParams.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(packageRoot); initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.DISABLE_CATALOG_FILE, true); - initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.MANIFEST_SERVICES, manifestServices); - var initializeOp = package.InitializeAsync(initParams); + initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES, manifestServices); + var initializeOp = package.InitializePackageAsync(initParams); yield return initializeOp; if (initializeOp.Status != EOperationStatus.Succeed) Debug.LogError(initializeOp.Error); Assert.AreEqual(EOperationStatus.Succeed, initializeOp.Status); // 请求资源版本 - var requetVersionOp = package.RequestPackageVersionAsync(); + var requetVersionOp = package.RequestVersionAsync(); yield return requetVersionOp; if (requetVersionOp.Status != EOperationStatus.Succeed) Debug.LogError(requetVersionOp.Error); Assert.AreEqual(EOperationStatus.Succeed, requetVersionOp.Status); // 更新资源清单 - var updateManifestOp = package.UpdatePackageManifestAsync(requetVersionOp.PackageVersion); - yield return updateManifestOp; - if (updateManifestOp.Status != EOperationStatus.Succeed) - Debug.LogError(updateManifestOp.Error); - Assert.AreEqual(EOperationStatus.Succeed, updateManifestOp.Status); + var loadPackageManifestOptions = new LoadManifestOptions(requetVersionOp.PackageVersion, 60); + var loadPackageManifestOp = package.LoadManifestAsync(loadPackageManifestOptions); + yield return loadPackageManifestOp; + if (loadPackageManifestOp.Status != EOperationStatus.Succeed) + Debug.LogError(loadPackageManifestOp.Error); + Assert.AreEqual(EOperationStatus.Succeed, loadPackageManifestOp.Status); } // 初始化资源包 RAW_BUNDLE @@ -98,29 +98,30 @@ public class T2_TestBuldinFileSystem : IPrebuildSetup, IPostBuildCleanup var package = YooAssets.CreatePackage(TestDefine.RawBundlePackageName); // 初始化资源包 - var initParams = new OfflinePlayModeParameters(); - initParams.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(null, packageRoot); + 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.InitializeAsync(initParams); + var initializeOp = package.InitializePackageAsync(initParams); yield return initializeOp; if (initializeOp.Status != EOperationStatus.Succeed) Debug.LogError(initializeOp.Error); Assert.AreEqual(EOperationStatus.Succeed, initializeOp.Status); // 请求资源版本 - var requetVersionOp = package.RequestPackageVersionAsync(); + var requetVersionOp = package.RequestVersionAsync(); yield return requetVersionOp; if (requetVersionOp.Status != EOperationStatus.Succeed) Debug.LogError(requetVersionOp.Error); Assert.AreEqual(EOperationStatus.Succeed, requetVersionOp.Status); // 更新资源清单 - var updateManifestOp = package.UpdatePackageManifestAsync(requetVersionOp.PackageVersion); - yield return updateManifestOp; - if (updateManifestOp.Status != EOperationStatus.Succeed) - Debug.LogError(updateManifestOp.Error); - Assert.AreEqual(EOperationStatus.Succeed, updateManifestOp.Status); + var loadPackageManifestOptions = new LoadManifestOptions(requetVersionOp.PackageVersion, 60); + var loadPackageManifestOp = package.LoadManifestAsync(loadPackageManifestOptions); + yield return loadPackageManifestOp; + if (loadPackageManifestOp.Status != EOperationStatus.Succeed) + Debug.LogError(loadPackageManifestOp.Error); + Assert.AreEqual(EOperationStatus.Succeed, loadPackageManifestOp.Status); } } diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleEncryption.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleEncryption.cs index 08a9d543..7925e36b 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleEncryption.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleEncryption.cs @@ -23,7 +23,8 @@ public class TestBundleEncryption yield return assetHandle; Assert.AreEqual(EOperationStatus.Succeed, assetHandle.Status); - var go = assetHandle.InstantiateSync(Vector3.zero, Quaternion.identity); + var options = new InstantiateOptions(true, Vector3.zero, Quaternion.identity); + var go = assetHandle.InstantiateSync(options); Assert.IsNotNull(go); } @@ -33,7 +34,8 @@ public class TestBundleEncryption var assetHandle = package.LoadAssetSync("prefab_encryptB"); Assert.AreEqual(EOperationStatus.Succeed, assetHandle.Status); - var go = assetHandle.InstantiateSync(Vector3.zero, Quaternion.identity); + var options = new InstantiateOptions(true, Vector3.zero, Quaternion.identity); + var go = assetHandle.InstantiateSync(options); Assert.IsNotNull(go); } } diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleReference.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleReference.cs index f9a8f404..5bd84a7a 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleReference.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleReference.cs @@ -23,7 +23,8 @@ public class TestBundleReference Assert.AreEqual(EOperationStatus.Succeed, assetHandle.Status); var pos = new Vector3(-1, -1, 0); - var go = assetHandle.InstantiateSync(pos, Quaternion.identity); + var options = new InstantiateOptions(true, pos, Quaternion.identity); + var go = assetHandle.InstantiateSync(options); Assert.IsNotNull(go); } @@ -36,7 +37,8 @@ public class TestBundleReference Assert.AreEqual(EOperationStatus.Succeed, heroHandle.Status); var pos = new Vector3(1, -1, 0); - heroObject = heroHandle.InstantiateSync(pos, Quaternion.identity); + var options = new InstantiateOptions(true, pos, Quaternion.identity); + heroObject = heroHandle.InstantiateSync(options); Assert.IsNotNull(heroObject); } @@ -61,7 +63,8 @@ public class TestBundleReference Assert.AreEqual(EOperationStatus.Succeed, heroHandle.Status); var pos = new Vector3(1, -1, 0); - heroObject = heroHandle.InstantiateSync(pos, Quaternion.identity); + var options = new InstantiateOptions(true, pos, Quaternion.identity); + heroObject = heroHandle.InstantiateSync(options); Assert.IsNotNull(heroObject); // 检测材质球关联的纹理是否为空 diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleUnload.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleUnload.cs index db5c29dc..c0e69509 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleUnload.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleUnload.cs @@ -26,7 +26,7 @@ public class TestBundleUnload yield return assetHandle; Assert.AreEqual(EOperationStatus.Succeed, assetHandle.Status); - DebugPackageData debugData = package.GetDebugPackageData(); + DiagnosticPackageData debugData = package.GetDebugPackageData(); var findItem = debugData.BundleInfos.Where(x => x.BundleName == targetBundleName); Assert.AreEqual(findItem.Count(), 1); } @@ -36,7 +36,7 @@ public class TestBundleUnload assetHandle.Release(); package.TryUnloadUnusedAsset("enemy"); - DebugPackageData debugData = package.GetDebugPackageData(); + DiagnosticPackageData debugData = package.GetDebugPackageData(); var findItem = debugData.BundleInfos.Where(x => x.BundleName == targetBundleName); Assert.AreEqual(findItem.Count(), 0); } diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleUnpacker.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleUnpacker.cs index 0c41a5f3..917559e7 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleUnpacker.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/TestBundleUnpacker.cs @@ -16,7 +16,8 @@ public class TestBundleUnpacker ResourcePackage package = YooAssets.GetPackage(TestDefine.AssetBundlePackageName); Assert.IsNotNull(package); - var resourceUnpacker = package.CreateResourceUnpacker("unpack", 10, 1); + var options = new ResourceUnpackerOptions("unpack", 10, 1); + var resourceUnpacker = package.CreateResourceUnpacker(options); Assert.AreEqual(resourceUnpacker.TotalDownloadCount, 2); resourceUnpacker.BeginDownload(); diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/T3_TestCacheFileSystem.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/T3_TestCacheFileSystem.cs index 1b2bcd9c..8ce4d6d7 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/T3_TestCacheFileSystem.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/T3_TestCacheFileSystem.cs @@ -44,34 +44,34 @@ public class T3_TestCacheFileSystem : IPrebuildSetup, IPostBuildCleanup var package = YooAssets.CreatePackage(TestDefine.AssetBundlePackageName); // 初始化资源包 - var initParams = new HostPlayModeParameters(); - var fileDecryption = new TestFileStreamDecryption(); + var initParams = new HostPlayModeOptions(); var manifestServices = new TestRestoreManifest(); string hostServerIP = "http://127.0.0.1/CDN/Android/Test/"; var remoteServices = new TestRemoteServices(hostServerIP); initParams.BuildinFileSystemParameters = null; - initParams.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices, fileDecryption); - initParams.CacheFileSystemParameters.AddParameter(FileSystemParametersDefine.MANIFEST_SERVICES, manifestServices); - var initializeOp = package.InitializeAsync(initParams); + initParams.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices); + initParams.CacheFileSystemParameters.AddParameter(FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES, manifestServices); + var initializeOp = package.InitializePackageAsync(initParams); yield return initializeOp; if (initializeOp.Status != EOperationStatus.Succeed) Debug.LogError(initializeOp.Error); Assert.AreEqual(EOperationStatus.Succeed, initializeOp.Status); // 请求资源版本 - var requetVersionOp = package.RequestPackageVersionAsync(); + var requetVersionOp = package.RequestVersionAsync(); yield return requetVersionOp; if (requetVersionOp.Status != EOperationStatus.Succeed) Debug.LogError(requetVersionOp.Error); Assert.AreEqual(EOperationStatus.Succeed, requetVersionOp.Status); // 更新资源清单 - var updateManifestOp = package.UpdatePackageManifestAsync(requetVersionOp.PackageVersion); - yield return updateManifestOp; - if (updateManifestOp.Status != EOperationStatus.Succeed) - Debug.LogError(updateManifestOp.Error); - Assert.AreEqual(EOperationStatus.Succeed, updateManifestOp.Status); + var loadPackageManifestOptions = new LoadManifestOptions(requetVersionOp.PackageVersion, 60); + var loadPackageManifestOp = package.LoadManifestAsync(loadPackageManifestOptions); + yield return loadPackageManifestOp; + if (loadPackageManifestOp.Status != EOperationStatus.Succeed) + Debug.LogError(loadPackageManifestOp.Error); + Assert.AreEqual(EOperationStatus.Succeed, loadPackageManifestOp.Status); } } private class TestRemoteServices : IRemoteServices diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/TestBundleDownloader.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/TestBundleDownloader.cs index 35ed2b3d..7270f538 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/TestBundleDownloader.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/TestBundleDownloader.cs @@ -16,7 +16,8 @@ public class TestBundleDownloader ResourcePackage package = YooAssets.GetPackage(TestDefine.AssetBundlePackageName); Assert.IsNotNull(package); - var downloader = package.CreateResourceDownloader(10, 1); + var options = new ResourceDownloaderOptions(10, 1); + var downloader = package.CreateResourceDownloader(options); Assert.AreNotEqual(downloader.TotalDownloadCount, 0); downloader.BeginDownload(); diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/TestBundleImporter.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/TestBundleImporter.cs index 42aa535f..4fb1347f 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/TestBundleImporter.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/TestBundleImporter.cs @@ -20,16 +20,17 @@ public class TestBundleImporter DirectoryInfo packageDir = new DirectoryInfo(packageRoot); string fileRoot = $"{packageDir.Parent.FullName}/OutputCache"; - ImportFileInfo fileInfoA = new ImportFileInfo(); + ImportBundleInfo fileInfoA = new ImportBundleInfo(); fileInfoA.FilePath = $"{fileRoot}/assets_samples_test_sample_testres3_import_prefab_importa.bundle.encrypt"; fileInfoA.BundleName = "assets_samples_test_sample_testres3_import_prefab_importa.bundle"; - ImportFileInfo fileInfoB = new ImportFileInfo(); + ImportBundleInfo fileInfoB = new ImportBundleInfo(); fileInfoB.FilePath = $"{fileRoot}/assets_samples_test_sample_testres3_import_prefab_importb.bundle.encrypt"; fileInfoB.BundleName = "assets_samples_test_sample_testres3_import_prefab_importb.bundle"; - ImportFileInfo[] importInfos = { fileInfoA, fileInfoB }; - var unpacker = package.CreateResourceImporter(importInfos, 10, 1); + ImportBundleInfo[] importInfos = { fileInfoA, fileInfoB }; + var options = new BundleImporterOptions(importInfos, 10, 1); + var unpacker = package.CreateResourceImporter(options); Assert.AreEqual(unpacker.TotalDownloadCount, 2); unpacker.BeginDownload(); diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/TestBundlePlaying.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/TestBundlePlaying.cs index ad60f7e8..6c95c79d 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/TestBundlePlaying.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/TestBundlePlaying.cs @@ -36,9 +36,9 @@ public class TestBundlePlaying { // 验证失败结果 UnityEngine.TestTools.LogAssert.ignoreFailingMessages = true; - var assetsHandle = package.LoadAssetSync("prefab_encryptB"); - Assert.AreEqual(EOperationStatus.Failed, assetsHandle.Status); + var assetsHandle = package.LoadAssetSync("prefab_encryptB"); UnityEngine.TestTools.LogAssert.ignoreFailingMessages = false; + Assert.AreEqual(EOperationStatus.Failed, assetsHandle.Status); // 清理加载器 assetsHandle.Release(); @@ -47,7 +47,9 @@ public class TestBundlePlaying // 验证成功结果 // 说明:同步加载也会触发远端下载任务! yield return new WaitForSeconds(1f); + UnityEngine.TestTools.LogAssert.ignoreFailingMessages = true; assetsHandle = package.LoadAssetSync("prefab_encryptB"); + UnityEngine.TestTools.LogAssert.ignoreFailingMessages = false; Assert.AreEqual(EOperationStatus.Succeed, assetsHandle.Status); } } diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestDestroyPackage.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestDestroyPackage.cs index a2e21bba..d849d8eb 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestDestroyPackage.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestDestroyPackage.cs @@ -16,7 +16,7 @@ public class TestDestroyPackage // 销毁旧资源包 ASSET_BUNDLE { var package = YooAssets.GetPackage(TestDefine.AssetBundlePackageName); - var destroyOp = package.DestroyAsync(); + var destroyOp = package.DestroyPackageAsync(); yield return destroyOp; if (destroyOp.Status != EOperationStatus.Succeed) Debug.LogError(destroyOp.Error); @@ -30,7 +30,7 @@ public class TestDestroyPackage if (destroyRawPackage) { var package = YooAssets.GetPackage(TestDefine.RawBundlePackageName); - var destroyOp = package.DestroyAsync(); + var destroyOp = package.DestroyPackageAsync(); yield return destroyOp; if (destroyOp.Status != EOperationStatus.Succeed) Debug.LogError(destroyOp.Error); diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadAsset.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadAsset.cs index 3c3ce900..1da6e867 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadAsset.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadAsset.cs @@ -38,7 +38,13 @@ public class TestLoadAsset // 同步加载音效 { + int loadFrame = Time.frameCount; var assetHandle = package.LoadAssetSync("sound_b"); + assetHandle.Completed += (AssetHandle handle) => + { + Assert.AreEqual(loadFrame, Time.frameCount); + }; + Assert.AreEqual(true, assetHandle.Provider.IsFinished); Assert.AreEqual(EOperationStatus.Succeed, assetHandle.Status); var audioClip = assetHandle.AssetObject as AudioClip; diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadRawFile.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadRawFile.cs index 721194cc..ae99e6ca 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadRawFile.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadRawFile.cs @@ -24,13 +24,6 @@ public class TestLoadRawFile var filePath = rawFileHandle.GetRawFilePath(); Assert.IsNotNull(filePath); - - var fileText = rawFileHandle.GetRawFileText(); - TestLogger.Log(this, fileText); - Assert.IsNotNull(fileText); - - var fileData = rawFileHandle.GetRawFileData(); - Assert.IsNotNull(fileData); } // 测试同步加载 @@ -40,13 +33,6 @@ public class TestLoadRawFile var filePath = rawFileHandle.GetRawFilePath(); Assert.IsNotNull(filePath); - - var fileText = rawFileHandle.GetRawFileText(); - TestLogger.Log(this, fileText); - Assert.IsNotNull(fileText); - - var fileData = rawFileHandle.GetRawFileData(); - Assert.IsNotNull(fileData); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadScene.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadScene.cs index 3969185a..94626891 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadScene.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadScene.cs @@ -52,7 +52,7 @@ public class TestLoadScene // 异步销毁附加场景 yield return new WaitForSeconds(0.2f); { - var unloadSceneOp = cachedHandle.UnloadAsync(); + var unloadSceneOp = cachedHandle.UnloadSceneAsync(); yield return unloadSceneOp; Assert.AreEqual(EOperationStatus.Succeed, unloadSceneOp.Status); }