diff --git a/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs b/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs index 06822afe..e232ea7a 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs +++ b/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs @@ -36,6 +36,9 @@ namespace YooAsset { get { + if (_watch == null) + return false; + // NOTE : 单次调用开销约1微秒 return _watch.ElapsedMilliseconds - _frameTime >= MaxTimeSlice; } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ManifestTools.cs b/Assets/YooAsset/Runtime/ResourcePackage/ManifestTools.cs index 47334575..b388d95d 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/ManifestTools.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/ManifestTools.cs @@ -119,86 +119,13 @@ namespace YooAsset /// public static PackageManifest DeserializeFromJson(string jsonContent) { - return JsonUtility.FromJson(jsonContent); - } + var manifest = JsonUtility.FromJson(jsonContent); - /// - /// 反序列化(二进制文件) - /// - public static PackageManifest DeserializeFromBinary(byte[] binaryData, IManifestRestoreServices services) - { - // 创建缓存器 - BufferReader buffer; - if (services != null) + // 初始化资源包 + for (int i = 0; i < manifest.BundleList.Count; i++) { - var resultBytes = services.RestoreManifest(binaryData); - buffer = new BufferReader(resultBytes); - } - else - { - buffer = new BufferReader(binaryData); - } - - // 读取文件标记 - uint fileSign = buffer.ReadUInt32(); - if (fileSign != ManifestDefine.FileSign) - throw new Exception("Invalid manifest file !"); - - // 读取文件版本 - string fileVersion = buffer.ReadUTF8(); - if (fileVersion != ManifestDefine.FileVersion) - throw new Exception($"The manifest file version are not compatible : {fileVersion} != {ManifestDefine.FileVersion}"); - - PackageManifest manifest = new PackageManifest(); - { - // 读取文件头信息 - manifest.FileVersion = fileVersion; - manifest.EnableAddressable = buffer.ReadBool(); - manifest.SupportExtensionless = buffer.ReadBool(); - manifest.LocationToLower = buffer.ReadBool(); - manifest.IncludeAssetGUID = buffer.ReadBool(); - 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 Exception("Addressable not support location to lower !"); - - // 读取资源列表 - int packageAssetCount = buffer.ReadInt32(); - CreateAssetCollection(manifest, packageAssetCount); - for (int i = 0; i < packageAssetCount; i++) - { - var packageAsset = new PackageAsset(); - packageAsset.Address = buffer.ReadUTF8(); - packageAsset.AssetPath = buffer.ReadUTF8(); - packageAsset.AssetGUID = buffer.ReadUTF8(); - packageAsset.AssetTags = buffer.ReadUTF8Array(); - packageAsset.BundleID = buffer.ReadInt32(); - packageAsset.DependBundleIDs = buffer.ReadInt32Array(); - FillAssetCollection(manifest, packageAsset); - } - - // 读取资源包列表 - int packageBundleCount = buffer.ReadInt32(); - CreateBundleCollection(manifest, packageBundleCount); - for (int i = 0; i < packageBundleCount; i++) - { - 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); - } + var packageBundle = manifest.BundleList[i]; + packageBundle.InitBundle(manifest); } // 初始化资源清单 @@ -206,8 +133,20 @@ namespace YooAsset return manifest; } + /// + /// 反序列化(二进制文件) + /// + public static PackageManifest DeserializeFromBinary(byte[] binaryData, IManifestRestoreServices services) + { + DeserializeManifestOperation operation = new DeserializeManifestOperation(services, binaryData); + operation.StartOperation(); + operation.WaitForAsyncComplete(); + return operation.Manifest; + } - #region 解析资源清单辅助方法 + /// + /// 初始化资源清单 + /// public static void InitManifest(PackageManifest manifest) { // 填充资源包内包含的主资源列表 @@ -237,108 +176,6 @@ namespace YooAsset } } - public static void CreateAssetCollection(PackageManifest manifest, int assetCount) - { - manifest.AssetList = new List(assetCount); - manifest.AssetDic = new Dictionary(assetCount); - - if (manifest.EnableAddressable) - { - manifest.AssetPathMapping1 = new Dictionary(assetCount * 3); - } - else - { - if (manifest.LocationToLower) - manifest.AssetPathMapping1 = new Dictionary(assetCount * 2, StringComparer.OrdinalIgnoreCase); - else - manifest.AssetPathMapping1 = new Dictionary(assetCount * 2); - } - - if (manifest.IncludeAssetGUID) - manifest.AssetPathMapping2 = new Dictionary(assetCount); - else - manifest.AssetPathMapping2 = new Dictionary(); - } - public static void FillAssetCollection(PackageManifest manifest, PackageAsset packageAsset) - { - // 添加到列表集合 - manifest.AssetList.Add(packageAsset); - - // 注意:我们不允许原始路径存在重名 - string assetPath = packageAsset.AssetPath; - if (manifest.AssetDic.ContainsKey(assetPath)) - throw new System.Exception($"AssetPath have existed : {assetPath}"); - else - manifest.AssetDic.Add(assetPath, packageAsset); - - // 填充AssetPathMapping1 - { - string location = packageAsset.AssetPath; - - // 添加原生路径的映射 - if (manifest.AssetPathMapping1.ContainsKey(location)) - throw new System.Exception($"Location have existed : {location}"); - else - manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath); - - // 添加无后缀名路径的映射 - if (manifest.SupportExtensionless) - { - string locationWithoutExtension = Path.ChangeExtension(location, null); - if (ReferenceEquals(location, locationWithoutExtension) == false) - { - if (manifest.AssetPathMapping1.ContainsKey(locationWithoutExtension)) - YooLogger.Warning($"Location have existed : {locationWithoutExtension}"); - else - manifest.AssetPathMapping1.Add(locationWithoutExtension, packageAsset.AssetPath); - } - } - } - - // 添加可寻址地址 - if (manifest.EnableAddressable) - { - string location = packageAsset.Address; - if (string.IsNullOrEmpty(location) == false) - { - if (manifest.AssetPathMapping1.ContainsKey(location)) - throw new System.Exception($"Location have existed : {location}"); - else - manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath); - } - } - - // 填充AssetPathMapping2 - if (manifest.IncludeAssetGUID) - { - if (manifest.AssetPathMapping2.ContainsKey(packageAsset.AssetGUID)) - throw new System.Exception($"AssetGUID have existed : {packageAsset.AssetGUID}"); - else - manifest.AssetPathMapping2.Add(packageAsset.AssetGUID, packageAsset.AssetPath); - } - } - - public static void CreateBundleCollection(PackageManifest manifest, int bundleCount) - { - manifest.BundleList = new List(bundleCount); - manifest.BundleDic1 = new Dictionary(bundleCount); - manifest.BundleDic2 = new Dictionary(bundleCount); - manifest.BundleDic3 = new Dictionary(bundleCount); - } - public static void FillBundleCollection(PackageManifest manifest, PackageBundle packageBundle) - { - // 初始化资源包 - packageBundle.InitBundle(manifest); - - // 添加到列表集合 - manifest.BundleList.Add(packageBundle); - - manifest.BundleDic1.Add(packageBundle.BundleName, packageBundle); - manifest.BundleDic2.Add(packageBundle.FileName, packageBundle); - manifest.BundleDic3.Add(packageBundle.BundleGUID, packageBundle); - } - #endregion - /// /// 获取资源文件的后缀名 /// diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DeserializeManifestOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DeserializeManifestOperation.cs index 1d39374f..66ac23a6 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DeserializeManifestOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DeserializeManifestOperation.cs @@ -117,7 +117,7 @@ namespace YooAsset { _packageAssetCount = _buffer.ReadInt32(); _progressTotalValue = _packageAssetCount; - ManifestTools.CreateAssetCollection(Manifest, _packageAssetCount); + CreateAssetCollection(Manifest, _packageAssetCount); _steps = ESteps.DeserializeAssetList; } if (_steps == ESteps.DeserializeAssetList) @@ -131,7 +131,7 @@ namespace YooAsset packageAsset.AssetTags = _buffer.ReadUTF8Array(); packageAsset.BundleID = _buffer.ReadInt32(); packageAsset.DependBundleIDs = _buffer.ReadInt32Array(); - ManifestTools.FillAssetCollection(Manifest, packageAsset); + FillAssetCollection(Manifest, packageAsset); _packageAssetCount--; Progress = 1f - _packageAssetCount / _progressTotalValue; @@ -149,7 +149,7 @@ namespace YooAsset { _packageBundleCount = _buffer.ReadInt32(); _progressTotalValue = _packageBundleCount; - ManifestTools.CreateBundleCollection(Manifest, _packageBundleCount); + CreateBundleCollection(Manifest, _packageBundleCount); _steps = ESteps.DeserializeBundleList; } if (_steps == ESteps.DeserializeBundleList) @@ -165,7 +165,7 @@ namespace YooAsset packageBundle.Encrypted = _buffer.ReadBool(); packageBundle.Tags = _buffer.ReadUTF8Array(); packageBundle.DependBundleIDs = _buffer.ReadInt32Array(); - ManifestTools.FillBundleCollection(Manifest, packageBundle); + FillBundleCollection(Manifest, packageBundle); _packageBundleCount--; Progress = 1f - _packageBundleCount / _progressTotalValue; @@ -194,5 +194,117 @@ namespace YooAsset Error = e.Message; } } + internal override void InternalWaitForAsyncComplete() + { + while (true) + { + if (ExecuteWhileDone()) + { + _steps = ESteps.Done; + break; + } + } + } + + private void CreateAssetCollection(PackageManifest manifest, int assetCount) + { + manifest.AssetList = new List(assetCount); + manifest.AssetDic = new Dictionary(assetCount); + + if (manifest.EnableAddressable) + { + manifest.AssetPathMapping1 = new Dictionary(assetCount * 3); + } + else + { + if (manifest.LocationToLower) + manifest.AssetPathMapping1 = new Dictionary(assetCount * 2, StringComparer.OrdinalIgnoreCase); + else + manifest.AssetPathMapping1 = new Dictionary(assetCount * 2); + } + + if (manifest.IncludeAssetGUID) + manifest.AssetPathMapping2 = new Dictionary(assetCount); + else + manifest.AssetPathMapping2 = new Dictionary(); + } + private void FillAssetCollection(PackageManifest manifest, PackageAsset packageAsset) + { + // 添加到列表集合 + manifest.AssetList.Add(packageAsset); + + // 注意:我们不允许原始路径存在重名 + string assetPath = packageAsset.AssetPath; + if (manifest.AssetDic.ContainsKey(assetPath)) + throw new System.Exception($"AssetPath have existed : {assetPath}"); + else + manifest.AssetDic.Add(assetPath, packageAsset); + + // 填充AssetPathMapping1 + { + string location = packageAsset.AssetPath; + + // 添加原生路径的映射 + if (manifest.AssetPathMapping1.ContainsKey(location)) + throw new System.Exception($"Location have existed : {location}"); + else + manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath); + + // 添加无后缀名路径的映射 + if (manifest.SupportExtensionless) + { + string locationWithoutExtension = Path.ChangeExtension(location, null); + if (ReferenceEquals(location, locationWithoutExtension) == false) + { + if (manifest.AssetPathMapping1.ContainsKey(locationWithoutExtension)) + YooLogger.Warning($"Location have existed : {locationWithoutExtension}"); + else + manifest.AssetPathMapping1.Add(locationWithoutExtension, packageAsset.AssetPath); + } + } + } + + // 填充AssetPathMapping2 + if (manifest.IncludeAssetGUID) + { + if (manifest.AssetPathMapping2.ContainsKey(packageAsset.AssetGUID)) + throw new System.Exception($"AssetGUID have existed : {packageAsset.AssetGUID}"); + else + manifest.AssetPathMapping2.Add(packageAsset.AssetGUID, packageAsset.AssetPath); + } + + // 添加可寻址地址 + if (manifest.EnableAddressable) + { + string location = packageAsset.Address; + if (string.IsNullOrEmpty(location) == false) + { + if (manifest.AssetPathMapping1.ContainsKey(location)) + throw new System.Exception($"Location have existed : {location}"); + else + manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath); + } + } + } + + private void CreateBundleCollection(PackageManifest manifest, int bundleCount) + { + manifest.BundleList = new List(bundleCount); + manifest.BundleDic1 = new Dictionary(bundleCount); + manifest.BundleDic2 = new Dictionary(bundleCount); + manifest.BundleDic3 = new Dictionary(bundleCount); + } + private void FillBundleCollection(PackageManifest manifest, PackageBundle packageBundle) + { + // 初始化资源包 + packageBundle.InitBundle(manifest); + + // 添加到列表集合 + manifest.BundleList.Add(packageBundle); + + manifest.BundleDic1.Add(packageBundle.BundleName, packageBundle); + manifest.BundleDic2.Add(packageBundle.FileName, packageBundle); + manifest.BundleDic3.Add(packageBundle.BundleGUID, packageBundle); + } } } \ No newline at end of file