mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-19 14:50:10 +00:00
Compare commits
8 Commits
6b23927f71
...
3.0.1-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f05f794461 | ||
|
|
a5ec8e8eb9 | ||
|
|
c0c3bb406d | ||
|
|
656b8f18e2 | ||
|
|
429a7395ca | ||
|
|
f8f2dd8faf | ||
|
|
45ecd8baff | ||
|
|
322c4a9847 |
@@ -2,6 +2,57 @@
|
||||
|
||||
All notable changes to this package will be documented in this file.
|
||||
|
||||
## [3.0.1-beta] - 2026-05-19
|
||||
|
||||
### Added
|
||||
|
||||
- 新增归档文件构建管线 `ArchiveFileBuildPipeline`
|
||||
|
||||
支持将同一资源包内的多个原始文件合并为 `ArchiveBundle`,并提供构建参数、构建任务、编辑器构建界面和运行时加载支持。
|
||||
|
||||
- 新增 `EnsureBundleFileOperation` 操作
|
||||
|
||||
用于确保资源包文件已就绪,并通过 `EnsureBundleFileOperation.Detail` 获取资源包名称、本地文件路径、资源包类型和加密状态。
|
||||
|
||||
**代码示例**
|
||||
|
||||
```csharp
|
||||
var package = YooAssets.GetPackage("DefaultPackage");
|
||||
|
||||
// 确保资源所在的资源包文件已经就绪。
|
||||
// 如果资源包未缓存,会自动触发下载或解压流程。
|
||||
var operation = package.EnsureBundleFileAsync(new EnsureBundleFileOptions("asset_location"));
|
||||
yield return operation;
|
||||
|
||||
if (operation.Status == EOperationStatus.Succeeded)
|
||||
{
|
||||
var detail = operation.Detail;
|
||||
string bundleName = detail.BundleName;
|
||||
string bundleFilePath = detail.BundleFilePath;
|
||||
int bundleType = detail.BundleType;
|
||||
bool isEncrypted = detail.IsEncrypted;
|
||||
|
||||
UnityEngine.Debug.Log($"BundleName: {bundleName}");
|
||||
UnityEngine.Debug.Log($"BundleFilePath: {bundleFilePath}");
|
||||
UnityEngine.Debug.Log($"BundleType: {bundleType}");
|
||||
UnityEngine.Debug.Log($"IsEncrypted: {isEncrypted}");
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.LogError(operation.Error);
|
||||
}
|
||||
```
|
||||
|
||||
- 新增编辑器模拟模式下的 Bundle Cache 标记文件机制
|
||||
|
||||
通过记录缓存状态,提升虚拟下载模式下缓存扫描、恢复和清理的可靠性。
|
||||
|
||||
### Changed
|
||||
|
||||
- `LoadRawFile` API 重命名为 `LoadBundleFile`
|
||||
|
||||
对应句柄由 `RawFileHandle` 重命名为 `BundleFileHandle`,语义从“原生文件”调整为“资源包文件”。
|
||||
|
||||
## [3.0.0-beta] - 2026-05-09
|
||||
|
||||
beta released.
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace YooAsset.Editor
|
||||
/// <summary>
|
||||
/// 构建资源包类型下拉框
|
||||
/// </summary>
|
||||
protected DropdownField _buildBundleTypeField;
|
||||
protected PopupField<string> _buildBundleTypeField;
|
||||
|
||||
|
||||
public override void CreateView(VisualElement parent)
|
||||
@@ -56,8 +56,8 @@ namespace YooAsset.Editor
|
||||
SetBuildVersionField(_buildVersionField);
|
||||
|
||||
// 构建资源包类型
|
||||
_buildBundleTypeField = Root.Q<DropdownField>("BuildBundleType");
|
||||
SetBuildBundleTypeField(_buildBundleTypeField);
|
||||
var buildBundleTypeContainer = Root.Q<VisualElement>("BuildBundleType");
|
||||
_buildBundleTypeField = CreateBuildBundleTypeField(buildBundleTypeContainer);
|
||||
|
||||
// 构建按钮
|
||||
var buildButton = Root.Q<Button>("Build");
|
||||
@@ -104,7 +104,7 @@ namespace YooAsset.Editor
|
||||
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
|
||||
}
|
||||
|
||||
private void SetBuildBundleTypeField(DropdownField dropdownField)
|
||||
private PopupField<string> CreateBuildBundleTypeField(VisualElement container)
|
||||
{
|
||||
var bundleTypes = Enum.GetValues(typeof(EBundleType))
|
||||
.Cast<EBundleType>()
|
||||
@@ -112,10 +112,17 @@ namespace YooAsset.Editor
|
||||
.Select(type => type.ToString())
|
||||
.ToList();
|
||||
|
||||
dropdownField.choices = bundleTypes;
|
||||
dropdownField.SetValueWithoutNotify(EBundleType.VirtualAssetBundle.ToString());
|
||||
dropdownField.style.width = StyleWidth;
|
||||
UIElementsTools.SetElementLabelMinWidth(dropdownField, LabelMinWidth);
|
||||
int defaultIndex = bundleTypes.IndexOf(EBundleType.VirtualAssetBundle.ToString());
|
||||
if (defaultIndex < 0)
|
||||
defaultIndex = 0;
|
||||
|
||||
var popupField = new PopupField<string>(bundleTypes, defaultIndex);
|
||||
popupField.label = "Build Bundle Type";
|
||||
popupField.style.width = StyleWidth;
|
||||
|
||||
container.Add(popupField);
|
||||
UIElementsTools.SetElementLabelMinWidth(popupField, LabelMinWidth);
|
||||
return popupField;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
<ui:VisualElement name="BuildContainer">
|
||||
<ui:TextField picking-mode="Ignore" label="Build Output" name="BuildOutput" />
|
||||
<ui:TextField picking-mode="Ignore" label="Build Version" name="BuildVersion" />
|
||||
<ui:DropdownField label="Build Bundle Type" name="BuildBundleType" />
|
||||
<ui:VisualElement name="BuildBundleType" />
|
||||
<ui:VisualElement name="ExtensionContainer" />
|
||||
<ui:Button text="Click Build" display-tooltip-when-elided="true" name="Build" style="height: 50px; background-color: rgb(40, 106, 42); margin-top: 10px;" />
|
||||
</ui:VisualElement>
|
||||
|
||||
@@ -73,5 +73,12 @@ namespace YooAsset
|
||||
/// <param name="bundleGuid">资源包的唯一标识符</param>
|
||||
/// <returns>如果缓存中存在该资源包则返回 true,否则返回 false。</returns>
|
||||
bool IsCached(string bundleGuid);
|
||||
|
||||
/// <summary>
|
||||
/// 获取已缓存的资源包文件路径
|
||||
/// </summary>
|
||||
/// <param name="bundleGuid">资源包的唯一标识符</param>
|
||||
/// <returns>返回已缓存的资源包文件路径,如果不存在则返回 null。</returns>
|
||||
string GetCacheFilePath(string bundleGuid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace YooAsset
|
||||
internal interface ICacheEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// Bundle 唯一标识
|
||||
/// 资源包唯一标识
|
||||
/// </summary>
|
||||
string BundleGuid { get; }
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace YooAsset
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
BundleHandle = new ArchiveBundleHandle(_options.FilePath, _options.Bundle, _archiveBundle);
|
||||
BundleHandle = new ArchiveBundleHandle(_options.Bundle, _archiveBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace YooAsset
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
BundleHandle = new AssetBundleHandle(_options.FilePath, _options.Bundle, _assetBundle, _loadStream);
|
||||
BundleHandle = new AssetBundleHandle(_options.Bundle, _assetBundle, _loadStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace YooAsset
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
BundleHandle = new RawBundleHandle(_options.FilePath, _options.Bundle, _rawBundle);
|
||||
BundleHandle = new RawBundleHandle(_options.Bundle, _rawBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace YooAsset
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
BundleHandle = new AssetBundleHandle(_downloadAssetBundleRequest.Url, _options.Bundle, assetBundle, null);
|
||||
BundleHandle = new AssetBundleHandle(_options.Bundle, assetBundle, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -290,7 +290,7 @@ namespace YooAsset
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
BundleHandle = new AssetBundleHandle(_downloadBytesRequest.Url, _options.Bundle, assetBundle, null);
|
||||
BundleHandle = new AssetBundleHandle(_options.Bundle, assetBundle, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -135,6 +135,17 @@ namespace YooAsset
|
||||
{
|
||||
return _cacheEntries.ContainsKey(bundleGuid);
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public string GetCacheFilePath(string bundleGuid)
|
||||
{
|
||||
if (_cacheEntries.TryGetValue(bundleGuid, out BuiltinBundleCacheEntry entry))
|
||||
{
|
||||
return entry.FilePath;
|
||||
}
|
||||
|
||||
YooLogger.LogWarning($"Cache file path not found. Bundle GUID: '{bundleGuid}'.");
|
||||
return null;
|
||||
}
|
||||
|
||||
#region 内部方法
|
||||
/// <summary>
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace YooAsset
|
||||
PackageName = packageName;
|
||||
RootPath = rootPath;
|
||||
Config = config;
|
||||
IsReadOnly = true;
|
||||
IsReadOnly = config.VirtualDownloadMode == false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -142,10 +142,16 @@ namespace YooAsset
|
||||
/// <inheritdoc />
|
||||
public bool IsCached(string bundleGuid)
|
||||
{
|
||||
if (Config.VirtualDownloadMode)
|
||||
return _cacheEntries.ContainsKey(bundleGuid);
|
||||
else
|
||||
if (Config.VirtualDownloadMode == false)
|
||||
return true;
|
||||
|
||||
return _cacheEntries.ContainsKey(bundleGuid);
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public string GetCacheFilePath(string bundleGuid)
|
||||
{
|
||||
YooLogger.LogWarning($"{nameof(EditorBundleCache)} does not support local cache file path.");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -202,8 +208,43 @@ namespace YooAsset
|
||||
if (_cacheEntries.TryGetValue(bundleGuid, out EditorBundleCacheEntry entry))
|
||||
{
|
||||
_cacheEntries.Remove(bundleGuid);
|
||||
entry.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 marker 文件路径
|
||||
/// </summary>
|
||||
/// <param name="bundle">资源包描述</param>
|
||||
/// <returns>marker 文件的完整路径</returns>
|
||||
internal string GetMarkerFilePath(PackageBundle bundle)
|
||||
{
|
||||
string bundleGuid = bundle.BundleGuid;
|
||||
string hashFolder = GetHashFolderName(bundleGuid);
|
||||
return PathUtility.Combine(RootPath, hashFolder, bundleGuid, EditorBundleCacheConsts.MarkerFileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 marker 临时文件路径
|
||||
/// </summary>
|
||||
/// <param name="bundle">资源包描述</param>
|
||||
/// <returns>marker 临时文件的完整路径</returns>
|
||||
internal string GetMarkerTempFilePath(PackageBundle bundle)
|
||||
{
|
||||
string bundleGuid = bundle.BundleGuid;
|
||||
string hashFolder = GetHashFolderName(bundleGuid);
|
||||
return PathUtility.Combine(RootPath, hashFolder, bundleGuid, EditorBundleCacheConsts.MarkerTempFileName);
|
||||
}
|
||||
|
||||
private string GetHashFolderName(string bundleGuid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(bundleGuid))
|
||||
throw new YooInternalException("Bundle GUID is null or empty.");
|
||||
|
||||
if (bundleGuid.Length <= EditorBundleCacheConsts.HashFolderNameLength)
|
||||
return bundleGuid;
|
||||
return bundleGuid.Substring(0, EditorBundleCacheConsts.HashFolderNameLength);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 编辑器文件缓存常量定义
|
||||
/// </summary>
|
||||
internal static class EditorBundleCacheConsts
|
||||
{
|
||||
/// <summary>
|
||||
/// 标记文件名称
|
||||
/// </summary>
|
||||
public const string MarkerFileName = "__marker";
|
||||
|
||||
/// <summary>
|
||||
/// 标记临时文件名称
|
||||
/// </summary>
|
||||
public const string MarkerTempFileName = "__marker.tmp";
|
||||
|
||||
/// <summary>
|
||||
/// 哈希分片目录前缀长度
|
||||
/// </summary>
|
||||
public const int HashFolderNameLength = 2;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f11e7e5e45702bb459771f57e1b84fdc
|
||||
guid: dc5ebd7b9a6b77145b004dadfe7ed587
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
@@ -12,19 +14,46 @@ namespace YooAsset
|
||||
public string BundleGuid { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 资源包文件路径
|
||||
/// 标记文件路径
|
||||
/// </summary>
|
||||
public string FilePath { get; private set; }
|
||||
public string MarkerFilePath { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建编辑器文件缓存条目实例
|
||||
/// </summary>
|
||||
/// <param name="bundleGuid">资源包唯一标识</param>
|
||||
/// <param name="filePath">资源包文件路径</param>
|
||||
public EditorBundleCacheEntry(string bundleGuid, string filePath)
|
||||
/// <param name="markerFilePath">标记文件路径</param>
|
||||
public EditorBundleCacheEntry(string bundleGuid, string markerFilePath)
|
||||
{
|
||||
BundleGuid = bundleGuid;
|
||||
FilePath = filePath;
|
||||
MarkerFilePath = markerFilePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除缓存文件夹及其所有内容
|
||||
/// </summary>
|
||||
/// <returns>删除是否成功</returns>
|
||||
public bool Delete()
|
||||
{
|
||||
try
|
||||
{
|
||||
string directory = Path.GetDirectoryName(MarkerFilePath);
|
||||
var directoryInfo = new DirectoryInfo(directory);
|
||||
if (directoryInfo.Exists)
|
||||
{
|
||||
directoryInfo.Delete(true);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
YooLogger.LogError($"Failed to delete editor cache file: {ex.Message}.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ namespace YooAsset
|
||||
{
|
||||
var cacheEntries = _fileCache.GetAllEntries();
|
||||
EvictionResult clearResult = _policy.SelectEvictionTargets(cacheEntries, _options);
|
||||
|
||||
if (clearResult.Succeeded == false)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
@@ -6,7 +5,17 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
internal sealed class EBCInitializeOperation : BCInitializeOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
ScanMarkerFiles,
|
||||
AddCacheEntries,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly EditorBundleCache _fileCache;
|
||||
private ScanMarkerFilesOperation _scanMarkerFilesOp;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
public EBCInitializeOperation(EditorBundleCache cache)
|
||||
{
|
||||
@@ -14,10 +23,58 @@ namespace YooAsset
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
SetResult();
|
||||
if (_fileCache.Config.VirtualDownloadMode == false)
|
||||
{
|
||||
SetResult();
|
||||
return;
|
||||
}
|
||||
|
||||
_steps = ESteps.ScanMarkerFiles;
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.ScanMarkerFiles)
|
||||
{
|
||||
if (_scanMarkerFilesOp == null)
|
||||
{
|
||||
_scanMarkerFilesOp = new ScanMarkerFilesOperation(_fileCache);
|
||||
_scanMarkerFilesOp.StartOperation();
|
||||
AddChildOperation(_scanMarkerFilesOp);
|
||||
}
|
||||
|
||||
_scanMarkerFilesOp.UpdateOperation();
|
||||
Progress = _scanMarkerFilesOp.Progress;
|
||||
if (_scanMarkerFilesOp.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_scanMarkerFilesOp.Status == EOperationStatus.Succeeded)
|
||||
{
|
||||
_steps = ESteps.AddCacheEntries;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError(_scanMarkerFilesOp.Error);
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.AddCacheEntries)
|
||||
{
|
||||
foreach (var fileInfo in _scanMarkerFilesOp.Result)
|
||||
{
|
||||
if (_fileCache.IsCached(fileInfo.BundleGuid) == false)
|
||||
{
|
||||
var cacheEntry = new EditorBundleCacheEntry(fileInfo.BundleGuid, fileInfo.MarkerFilePath);
|
||||
_fileCache.AddEntry(fileInfo.BundleGuid, cacheEntry);
|
||||
}
|
||||
}
|
||||
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
@@ -13,15 +11,8 @@ namespace YooAsset
|
||||
|
||||
protected override void CreateBundleHandle()
|
||||
{
|
||||
string editorFilePath = EditorFileSystemHelper.GetEditorFilePath(_bundle);
|
||||
if (string.IsNullOrEmpty(editorFilePath))
|
||||
{
|
||||
SetError($"Editor file path is null. Bundle: '{_bundle.BundleName}'.");
|
||||
return;
|
||||
}
|
||||
|
||||
SetResult();
|
||||
BundleHandle = new VirtualAssetBundleHandle(editorFilePath, _bundle);
|
||||
BundleHandle = new VirtualAssetBundleHandle(_bundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace YooAsset
|
||||
var rawBundle = new RawBundle(data);
|
||||
|
||||
SetResult();
|
||||
BundleHandle = new VirtualRawBundleHandle(editorFilePath, _bundle, rawBundle);
|
||||
BundleHandle = new VirtualRawBundleHandle(_bundle, rawBundle);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
@@ -52,7 +54,38 @@ namespace YooAsset
|
||||
|
||||
if (_steps == ESteps.CacheFile)
|
||||
{
|
||||
var cacheEntry = new EditorBundleCacheEntry(_options.Bundle.BundleGuid, _options.FilePath);
|
||||
string markerFilePath = _fileCache.GetMarkerFilePath(_options.Bundle);
|
||||
string markerTempPath = _fileCache.GetMarkerTempFilePath(_options.Bundle);
|
||||
|
||||
try
|
||||
{
|
||||
// 阶段A:准备目标目录,清理可能存在的残留临时文件
|
||||
FileUtility.EnsureParentDirectoryExists(markerFilePath);
|
||||
DeleteFileSafely(markerTempPath);
|
||||
|
||||
// 阶段B:写入临时文件,内容仅用于人工调试
|
||||
string debugContent = $"BundleName={_options.Bundle.BundleName}\n"
|
||||
+ $"BundleGuid={_options.Bundle.BundleGuid}\n";
|
||||
File.WriteAllText(markerTempPath, debugContent);
|
||||
|
||||
// 阶段C:原子提交
|
||||
if (File.Exists(markerFilePath))
|
||||
File.Delete(markerFilePath);
|
||||
File.Move(markerTempPath, markerFilePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError($"Failed to write marker file: {ex.Message}.");
|
||||
YooLogger.LogError(Error);
|
||||
|
||||
// 回滚:清理临时文件,正式文件不受影响
|
||||
DeleteFileSafely(markerTempPath);
|
||||
return;
|
||||
}
|
||||
|
||||
// 阶段D:注册内存缓存条目
|
||||
var cacheEntry = new EditorBundleCacheEntry(_options.Bundle.BundleGuid, markerFilePath);
|
||||
_fileCache.AddEntry(_options.Bundle.BundleGuid, cacheEntry);
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
@@ -62,5 +95,18 @@ namespace YooAsset
|
||||
{
|
||||
ExecuteBatch();
|
||||
}
|
||||
|
||||
private static void DeleteFileSafely(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(filePath))
|
||||
File.Delete(filePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
YooLogger.LogWarning($"Failed to delete file '{filePath}': {ex.Message}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e9a70495d8ca514caa7647851844101
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,114 @@
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 扫描标记文件操作
|
||||
/// </summary>
|
||||
internal sealed class ScanMarkerFilesOperation : AsyncOperationBase
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Prepare,
|
||||
ScanFiles,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly EditorBundleCache _fileCache;
|
||||
private IEnumerator<string> _shardEnumerator = null;
|
||||
private double _scanStartTime;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
/// <summary>
|
||||
/// 扫描到的标记件信息
|
||||
/// </summary>
|
||||
public readonly List<ScanFileInfo> Result = new List<ScanFileInfo>(5000);
|
||||
|
||||
/// <summary>
|
||||
/// 创建操作实例
|
||||
/// </summary>
|
||||
/// <param name="fileCache">编辑器文件缓存系统</param>
|
||||
internal ScanMarkerFilesOperation(EditorBundleCache fileCache)
|
||||
{
|
||||
_fileCache = fileCache;
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.Prepare;
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.Prepare)
|
||||
{
|
||||
if (Directory.Exists(_fileCache.RootPath))
|
||||
{
|
||||
var directories = Directory.EnumerateDirectories(_fileCache.RootPath);
|
||||
_shardEnumerator = directories.GetEnumerator();
|
||||
_scanStartTime = TimeUtility.RealtimeSinceStartup;
|
||||
_steps = ESteps.ScanFiles;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.ScanFiles)
|
||||
{
|
||||
if (ScanFiles())
|
||||
return;
|
||||
|
||||
_shardEnumerator.Dispose();
|
||||
_shardEnumerator = null;
|
||||
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
double costTime = TimeUtility.RealtimeSinceStartup - _scanStartTime;
|
||||
YooLogger.Log($"Marker file scan completed in {costTime:f1} seconds. Found {Result.Count} marker files.");
|
||||
}
|
||||
}
|
||||
protected override void InternalDispose()
|
||||
{
|
||||
if (_shardEnumerator != null)
|
||||
{
|
||||
_shardEnumerator.Dispose();
|
||||
_shardEnumerator = null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool ScanFiles()
|
||||
{
|
||||
bool hasMore;
|
||||
while (true)
|
||||
{
|
||||
hasMore = _shardEnumerator.MoveNext();
|
||||
if (hasMore == false)
|
||||
break;
|
||||
|
||||
string shardFolder = _shardEnumerator.Current;
|
||||
var childDirectories = Directory.EnumerateDirectories(shardFolder);
|
||||
foreach (string childDirectory in childDirectories)
|
||||
{
|
||||
string bundleGuid = Path.GetFileName(childDirectory);
|
||||
string markerFilePath = PathUtility.Combine(childDirectory, EditorBundleCacheConsts.MarkerFileName);
|
||||
if (File.Exists(markerFilePath))
|
||||
{
|
||||
var fileInfo = new ScanFileInfo(bundleGuid, markerFilePath);
|
||||
Result.Add(fileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsBusy)
|
||||
break;
|
||||
}
|
||||
|
||||
return hasMore;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c5756c583ed1474c9abb56419b488d6
|
||||
guid: dc7b3752dfb973447bdae44ea8722995
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 扫描到的标记文件信息
|
||||
/// </summary>
|
||||
internal class ScanFileInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源包唯一标识
|
||||
/// </summary>
|
||||
public string BundleGuid { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标记文件路径
|
||||
/// </summary>
|
||||
public string MarkerFilePath { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建扫描文件信息实例
|
||||
/// </summary>
|
||||
/// <param name="bundleGuid">资源包唯一标识</param>
|
||||
/// <param name="markerFilePath">标记文件路径</param>
|
||||
public ScanFileInfo(string bundleGuid, string markerFilePath)
|
||||
{
|
||||
BundleGuid = bundleGuid;
|
||||
MarkerFilePath = markerFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4a3717e25e79a14485f85e83794dd6a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -19,7 +19,7 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
private readonly SandboxBundleCache _fileCache;
|
||||
private IEnumerator<string> _filesEnumerator = null;
|
||||
private IEnumerator<string> _shardEnumerator = null;
|
||||
private double _verifyStartTime;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace YooAsset
|
||||
if (Directory.Exists(_fileCache.RootPath))
|
||||
{
|
||||
var directories = Directory.EnumerateDirectories(_fileCache.RootPath);
|
||||
_filesEnumerator = directories.GetEnumerator();
|
||||
_shardEnumerator = directories.GetEnumerator();
|
||||
_verifyStartTime = TimeUtility.RealtimeSinceStartup;
|
||||
_steps = ESteps.SearchFiles;
|
||||
}
|
||||
@@ -66,35 +66,35 @@ namespace YooAsset
|
||||
if (SearchFiles())
|
||||
return;
|
||||
|
||||
_filesEnumerator.Dispose();
|
||||
_filesEnumerator = null;
|
||||
_shardEnumerator.Dispose();
|
||||
_shardEnumerator = null;
|
||||
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
double costTime = TimeUtility.RealtimeSinceStartup - _verifyStartTime;
|
||||
YooLogger.Log($"Cache file search completed in {costTime:f1} seconds.");
|
||||
YooLogger.Log($"Cache file search completed in {costTime:f1} seconds. Found {Result.Count} cache files.");
|
||||
}
|
||||
}
|
||||
protected override void InternalDispose()
|
||||
{
|
||||
if (_filesEnumerator != null)
|
||||
if (_shardEnumerator != null)
|
||||
{
|
||||
_filesEnumerator.Dispose();
|
||||
_filesEnumerator = null;
|
||||
_shardEnumerator.Dispose();
|
||||
_shardEnumerator = null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool SearchFiles()
|
||||
{
|
||||
bool isFindItem;
|
||||
bool hasMore;
|
||||
while (true)
|
||||
{
|
||||
isFindItem = _filesEnumerator.MoveNext();
|
||||
if (isFindItem == false)
|
||||
hasMore = _shardEnumerator.MoveNext();
|
||||
if (hasMore == false)
|
||||
break;
|
||||
|
||||
var rootFolder = _filesEnumerator.Current;
|
||||
var childDirectories = Directory.EnumerateDirectories(rootFolder);
|
||||
var shardFolder = _shardEnumerator.Current;
|
||||
var childDirectories = Directory.EnumerateDirectories(shardFolder);
|
||||
foreach (var childDirectory in childDirectories)
|
||||
{
|
||||
string bundleGuid = Path.GetFileName(childDirectory);
|
||||
@@ -113,7 +113,7 @@ namespace YooAsset
|
||||
break;
|
||||
}
|
||||
|
||||
return isFindItem;
|
||||
return hasMore;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace YooAsset
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
BundleHandle = new AssetBundleHandle(_cacheEntry.DataFilePath, _bundle, assetBundle, null);
|
||||
BundleHandle = new AssetBundleHandle(_bundle, assetBundle, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
private const int HashFolderNameLength = 2;
|
||||
private readonly Dictionary<string, SandboxBundleCacheEntry> _cacheEntries = new Dictionary<string, SandboxBundleCacheEntry>(10000);
|
||||
private readonly Dictionary<string, string> _dataFilePathMapping = new Dictionary<string, string>(10000);
|
||||
private readonly Dictionary<string, string> _infoFilePathMapping = new Dictionary<string, string>(10000);
|
||||
@@ -154,6 +153,17 @@ namespace YooAsset
|
||||
{
|
||||
return _cacheEntries.ContainsKey(bundleGuid);
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public string GetCacheFilePath(string bundleGuid)
|
||||
{
|
||||
if (_cacheEntries.TryGetValue(bundleGuid, out SandboxBundleCacheEntry entry))
|
||||
{
|
||||
return entry.DataFilePath;
|
||||
}
|
||||
|
||||
YooLogger.LogWarning($"Cache file path not found. Bundle GUID: '{bundleGuid}'.");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据 ClearMethod 创建对应的淘汰策略实例
|
||||
@@ -185,11 +195,12 @@ namespace YooAsset
|
||||
/// <returns>数据文件的完整路径</returns>
|
||||
internal string GetDataFilePath(PackageBundle bundle)
|
||||
{
|
||||
if (_dataFilePathMapping.TryGetValue(bundle.BundleGuid, out string filePath) == false)
|
||||
string bundleGuid = bundle.BundleGuid;
|
||||
if (_dataFilePathMapping.TryGetValue(bundleGuid, out string filePath) == false)
|
||||
{
|
||||
string folderName = GetHashFolderName(bundle.FileHash);
|
||||
filePath = PathUtility.Combine(RootPath, folderName, bundle.BundleGuid, SandboxBundleCacheConsts.BundleDataFileName);
|
||||
_dataFilePathMapping.Add(bundle.BundleGuid, filePath);
|
||||
string folderName = GetHashFolderName(bundleGuid);
|
||||
filePath = PathUtility.Combine(RootPath, folderName, bundleGuid, SandboxBundleCacheConsts.BundleDataFileName);
|
||||
_dataFilePathMapping.Add(bundleGuid, filePath);
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
@@ -201,11 +212,12 @@ namespace YooAsset
|
||||
/// <returns>信息文件的完整路径</returns>
|
||||
internal string GetInfoFilePath(PackageBundle bundle)
|
||||
{
|
||||
if (_infoFilePathMapping.TryGetValue(bundle.BundleGuid, out string filePath) == false)
|
||||
string bundleGuid = bundle.BundleGuid;
|
||||
if (_infoFilePathMapping.TryGetValue(bundleGuid, out string filePath) == false)
|
||||
{
|
||||
string folderName = GetHashFolderName(bundle.FileHash);
|
||||
filePath = PathUtility.Combine(RootPath, folderName, bundle.BundleGuid, SandboxBundleCacheConsts.BundleInfoFileName);
|
||||
_infoFilePathMapping.Add(bundle.BundleGuid, filePath);
|
||||
string folderName = GetHashFolderName(bundleGuid);
|
||||
filePath = PathUtility.Combine(RootPath, folderName, bundleGuid, SandboxBundleCacheConsts.BundleInfoFileName);
|
||||
_infoFilePathMapping.Add(bundleGuid, filePath);
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
@@ -217,8 +229,9 @@ namespace YooAsset
|
||||
/// <returns>数据临时文件的完整路径</returns>
|
||||
internal string GetDataTempFilePath(PackageBundle bundle)
|
||||
{
|
||||
string folderName = GetHashFolderName(bundle.FileHash);
|
||||
return PathUtility.Combine(RootPath, folderName, bundle.BundleGuid, SandboxBundleCacheConsts.BundleDataTempFileName);
|
||||
string bundleGuid = bundle.BundleGuid;
|
||||
string folderName = GetHashFolderName(bundleGuid);
|
||||
return PathUtility.Combine(RootPath, folderName, bundleGuid, SandboxBundleCacheConsts.BundleDataTempFileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -228,8 +241,9 @@ namespace YooAsset
|
||||
/// <returns>信息临时文件的完整路径</returns>
|
||||
internal string GetInfoTempFilePath(PackageBundle bundle)
|
||||
{
|
||||
string folderName = GetHashFolderName(bundle.FileHash);
|
||||
return PathUtility.Combine(RootPath, folderName, bundle.BundleGuid, SandboxBundleCacheConsts.BundleInfoTempFileName);
|
||||
string bundleGuid = bundle.BundleGuid;
|
||||
string folderName = GetHashFolderName(bundleGuid);
|
||||
return PathUtility.Combine(RootPath, folderName, bundleGuid, SandboxBundleCacheConsts.BundleInfoTempFileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -286,14 +300,14 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
private string GetHashFolderName(string fileHash)
|
||||
private string GetHashFolderName(string bundleGuid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fileHash))
|
||||
throw new YooInternalException("File hash is null or empty.");
|
||||
if (string.IsNullOrEmpty(bundleGuid))
|
||||
throw new YooInternalException("Bundle GUID is null or empty.");
|
||||
|
||||
if (fileHash.Length <= HashFolderNameLength)
|
||||
return fileHash;
|
||||
return fileHash.Substring(0, HashFolderNameLength);
|
||||
if (bundleGuid.Length <= SandboxBundleCacheConsts.HashFolderNameLength)
|
||||
return bundleGuid;
|
||||
return bundleGuid.Substring(0, SandboxBundleCacheConsts.HashFolderNameLength);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -40,5 +40,10 @@ namespace YooAsset
|
||||
/// 信息文件预期大小(字节)
|
||||
/// </summary>
|
||||
public const int InfoFileExpectedSize = 36;
|
||||
|
||||
/// <summary>
|
||||
/// 哈希分片目录前缀长度
|
||||
/// </summary>
|
||||
public const int HashFolderNameLength = 2;
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ namespace YooAsset
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
BundleHandle = new WebGameAssetBundleHandle(_options.CacheFilePath, _options.Bundle, assetBundle, _options.GamePlatform);
|
||||
BundleHandle = new WebGameAssetBundleHandle(_options.Bundle, assetBundle, _options.GamePlatform);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -22,11 +22,6 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public IWebGamePlatform GamePlatform { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 平台侧缓存文件路径
|
||||
/// </summary>
|
||||
public string CacheFilePath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 看门狗超时时间
|
||||
/// </summary>
|
||||
@@ -43,13 +38,12 @@ namespace YooAsset
|
||||
public IDownloadUrlPolicy DownloadUrlPolicy { get; }
|
||||
|
||||
public LoadWebGameAssetBundleOptions(PackageBundle bundle, IReadOnlyList<string> candidateUrls,
|
||||
IWebGamePlatform gamePlatform, string cacheFilePath, int watchdogTimeout,
|
||||
IWebGamePlatform gamePlatform, int watchdogTimeout,
|
||||
IDownloadRetryPolicy downloadRetryPolicy, IDownloadUrlPolicy downloadUrlPolicy)
|
||||
{
|
||||
Bundle = bundle;
|
||||
CandidateUrls = candidateUrls;
|
||||
GamePlatform = gamePlatform;
|
||||
CacheFilePath = cacheFilePath;
|
||||
WatchdogTimeout = watchdogTimeout;
|
||||
DownloadRetryPolicy = downloadRetryPolicy;
|
||||
DownloadUrlPolicy = downloadUrlPolicy;
|
||||
|
||||
@@ -8,7 +8,6 @@ namespace YooAsset
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
GetEntry,
|
||||
LoadBundle,
|
||||
Done,
|
||||
}
|
||||
@@ -16,7 +15,6 @@ namespace YooAsset
|
||||
private readonly WebGameBundleCache _fileCache;
|
||||
private readonly BCLoadBundleOptions _options;
|
||||
private BCLoadBundleOperation _loadBundleOp;
|
||||
private WebGameBundleCacheEntry _cacheEntry;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal WGBCLoadAssetBundleOperation(WebGameBundleCache fileCache, BCLoadBundleOptions options)
|
||||
@@ -26,37 +24,24 @@ namespace YooAsset
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.GetEntry;
|
||||
_steps = ESteps.LoadBundle;
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.GetEntry)
|
||||
{
|
||||
_cacheEntry = _fileCache.GetEntry(_options.Bundle);
|
||||
if (_cacheEntry == null)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError($"File cache entry not found: '{_options.Bundle.BundleGuid}'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.LoadBundle;
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.LoadBundle)
|
||||
{
|
||||
if (_loadBundleOp == null)
|
||||
{
|
||||
var urls = _fileCache.Config.RemoteService.GetRemoteUrls(_options.Bundle.GetFileName());
|
||||
if (_options.Bundle.IsEncrypted)
|
||||
{
|
||||
var options = new LoadWebAssetBundleOptions(
|
||||
cacheName: _fileCache.GetType().Name,
|
||||
bundle: _options.Bundle,
|
||||
candidateUrls: _cacheEntry.Urls,
|
||||
candidateUrls: urls,
|
||||
assetBundleDecryptor: _fileCache.Config.AssetBundleDecryptor,
|
||||
downloadBackend: _fileCache.Config.DownloadBackend,
|
||||
downloadVerifyLevel: _fileCache.Config.DownloadVerifyLevel,
|
||||
@@ -70,9 +55,8 @@ namespace YooAsset
|
||||
{
|
||||
var webGameOptions = new LoadWebGameAssetBundleOptions(
|
||||
bundle: _options.Bundle,
|
||||
candidateUrls: _cacheEntry.Urls,
|
||||
candidateUrls: urls,
|
||||
gamePlatform: _fileCache.Config.GamePlatform,
|
||||
cacheFilePath: _cacheEntry.CacheFilePath,
|
||||
watchdogTimeout: _fileCache.Config.WatchdogTimeout,
|
||||
downloadRetryPolicy: _fileCache.Config.DownloadRetryPolicy,
|
||||
downloadUrlPolicy: _fileCache.Config.DownloadUrlPolicy);
|
||||
|
||||
@@ -71,8 +71,6 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, WebGameBundleCacheEntry> _cacheEntries = new Dictionary<string, WebGameBundleCacheEntry>(10000);
|
||||
|
||||
/// <summary>
|
||||
/// 缓存配置
|
||||
/// </summary>
|
||||
@@ -89,10 +87,10 @@ namespace YooAsset
|
||||
public bool IsReadOnly { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int FileCount => _cacheEntries.Count;
|
||||
public int FileCount { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public long SpaceOccupied => 0;
|
||||
public long SpaceOccupied { get; }
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -155,28 +153,13 @@ namespace YooAsset
|
||||
/// <inheritdoc/>
|
||||
public bool IsCached(string bundleGuid)
|
||||
{
|
||||
if (_cacheEntries.TryGetValue(bundleGuid, out var entry))
|
||||
return Config.GamePlatform.IsCached(entry.CacheFilePath);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#region 内部方法
|
||||
/// <summary>
|
||||
/// 获取或创建指定资源包的缓存条目
|
||||
/// </summary>
|
||||
/// <param name="bundle">资源包描述</param>
|
||||
/// <returns>已存在则返回对应条目;否则创建并登记后返回新条目。</returns>
|
||||
internal WebGameBundleCacheEntry GetEntry(PackageBundle bundle)
|
||||
/// <inheritdoc/>
|
||||
public string GetCacheFilePath(string bundleGuid)
|
||||
{
|
||||
if (_cacheEntries.TryGetValue(bundle.BundleGuid, out var entry))
|
||||
return entry;
|
||||
|
||||
var urls = Config.RemoteService.GetRemoteUrls(bundle.GetFileName());
|
||||
var filePath = Config.GamePlatform.GetCacheFilePath(RootPath, bundle);
|
||||
var newEntry = new WebGameBundleCacheEntry(bundle.BundleGuid, urls, filePath);
|
||||
_cacheEntries.Add(bundle.BundleGuid, newEntry);
|
||||
return newEntry;
|
||||
YooLogger.LogWarning($"{nameof(WebGameBundleCache)} does not support local cache file path.");
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// WebGL 游戏平台缓存条目
|
||||
/// </summary>
|
||||
internal class WebGameBundleCacheEntry : ICacheEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源包唯一标识
|
||||
/// </summary>
|
||||
public string BundleGuid { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 候选下载地址列表
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> Urls { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 平台侧缓存文件路径
|
||||
/// </summary>
|
||||
public string CacheFilePath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建 WebGL 游戏平台缓存条目实例
|
||||
/// </summary>
|
||||
/// <param name="bundleGuid">资源包唯一标识</param>
|
||||
/// <param name="urls">候选下载地址列表</param>
|
||||
/// <param name="cacheFilePath">平台侧缓存文件路径</param>
|
||||
public WebGameBundleCacheEntry(string bundleGuid, IReadOnlyList<string> urls, string cacheFilePath)
|
||||
{
|
||||
BundleGuid = bundleGuid;
|
||||
Urls = urls;
|
||||
CacheFilePath = cacheFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ namespace YooAsset
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
GetEntry,
|
||||
LoadBundle,
|
||||
Done,
|
||||
}
|
||||
@@ -17,7 +16,6 @@ namespace YooAsset
|
||||
private readonly WebRemoteBundleCache _fileCache;
|
||||
private readonly BCLoadBundleOptions _options;
|
||||
private BCLoadBundleOperation _loadBundleOp;
|
||||
private WebRemoteBundleCacheEntry _cacheEntry;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
/// <summary>
|
||||
@@ -32,35 +30,22 @@ namespace YooAsset
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.GetEntry;
|
||||
_steps = ESteps.LoadBundle;
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.GetEntry)
|
||||
{
|
||||
_cacheEntry = _fileCache.GetEntry(_options.Bundle);
|
||||
if (_cacheEntry == null)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError($"File cache entry not found: '{_options.Bundle.BundleGuid}'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.LoadBundle;
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.LoadBundle)
|
||||
{
|
||||
if (_loadBundleOp == null)
|
||||
{
|
||||
var urls = _fileCache.Config.RemoteService.GetRemoteUrls(_options.Bundle.GetFileName());
|
||||
var options = new LoadWebAssetBundleOptions(
|
||||
cacheName: _fileCache.GetType().Name,
|
||||
bundle: _options.Bundle,
|
||||
candidateUrls: _cacheEntry.Urls,
|
||||
candidateUrls: urls,
|
||||
assetBundleDecryptor: _fileCache.Config.AssetBundleDecryptor,
|
||||
downloadBackend: _fileCache.Config.DownloadBackend,
|
||||
downloadVerifyLevel: _fileCache.Config.DownloadVerifyLevel,
|
||||
|
||||
@@ -65,8 +65,6 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, WebRemoteBundleCacheEntry> _cacheEntries = new Dictionary<string, WebRemoteBundleCacheEntry>(10000);
|
||||
|
||||
/// <summary>
|
||||
/// 缓存配置
|
||||
/// </summary>
|
||||
@@ -83,16 +81,10 @@ namespace YooAsset
|
||||
public bool IsReadOnly { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int FileCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _cacheEntries.Count;
|
||||
}
|
||||
}
|
||||
public int FileCount { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public long SpaceOccupied { get; private set; }
|
||||
public long SpaceOccupied { get; }
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -157,23 +149,11 @@ namespace YooAsset
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#region 内部方法
|
||||
/// <summary>
|
||||
/// 获取或创建指定资源包的缓存条目
|
||||
/// </summary>
|
||||
/// <param name="bundle">资源包描述</param>
|
||||
/// <returns>已存在则返回对应条目;否则创建并登记后返回新条目。</returns>
|
||||
internal WebRemoteBundleCacheEntry GetEntry(PackageBundle bundle)
|
||||
/// <inheritdoc />
|
||||
public string GetCacheFilePath(string bundleGuid)
|
||||
{
|
||||
if (_cacheEntries.TryGetValue(bundle.BundleGuid, out WebRemoteBundleCacheEntry entry))
|
||||
return entry;
|
||||
|
||||
var urls = Config.RemoteService.GetRemoteUrls(bundle.GetFileName());
|
||||
var newEntry = new WebRemoteBundleCacheEntry(bundle.BundleGuid, urls);
|
||||
_cacheEntries.Add(bundle.BundleGuid, newEntry);
|
||||
return newEntry;
|
||||
YooLogger.LogWarning($"{nameof(WebRemoteBundleCache)} does not support local cache file path.");
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// Web远端文件缓存条目
|
||||
/// </summary>
|
||||
internal class WebRemoteBundleCacheEntry : ICacheEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源包唯一标识
|
||||
/// </summary>
|
||||
public string BundleGuid { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 候选下载地址列表
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> Urls { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建 Web 远端文件缓存条目实例
|
||||
/// </summary>
|
||||
/// <param name="bundleGuid">资源包唯一标识</param>
|
||||
/// <param name="urls">候选下载地址列表</param>
|
||||
public WebRemoteBundleCacheEntry(string bundleGuid, IReadOnlyList<string> urls)
|
||||
{
|
||||
BundleGuid = bundleGuid;
|
||||
Urls = urls;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public long SpaceOccupied { get; private set; }
|
||||
public long SpaceOccupied { get; }
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -151,6 +151,12 @@ namespace YooAsset
|
||||
{
|
||||
return _cacheEntries.ContainsKey(bundleGuid);
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public string GetCacheFilePath(string bundleGuid)
|
||||
{
|
||||
YooLogger.LogWarning($"{nameof(WebServerBundleCache)} does not support local cache file path.");
|
||||
return null;
|
||||
}
|
||||
|
||||
#region 内部方法
|
||||
/// <summary>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
@@ -46,5 +47,10 @@ namespace YooAsset
|
||||
/// 虚拟归档文件资源包(编辑器模拟 ArchiveBundle)
|
||||
/// </summary>
|
||||
VirtualArchiveBundle = 14,
|
||||
|
||||
#if YOOASSET_LEGACY_API
|
||||
[Obsolete("Use VirtualAssetBundle instead.")]
|
||||
VirtualBundle = VirtualAssetBundle,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,6 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
internal interface IBundleHandle
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源包文件的本地路径
|
||||
/// </summary>
|
||||
string BundleFilePath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 卸载资源包
|
||||
/// </summary>
|
||||
|
||||
@@ -7,25 +7,16 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
internal sealed class ArchiveBundleHandle : IBundleHandle
|
||||
{
|
||||
private readonly string _bundleFilePath;
|
||||
private readonly PackageBundle _packageBundle;
|
||||
private readonly ArchiveBundle _archiveBundle;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string BundleFilePath
|
||||
{
|
||||
get { return _bundleFilePath; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建 ArchiveBundleHandle 实例
|
||||
/// </summary>
|
||||
/// <param name="bundleFilePath">资源包文件的本地路径</param>
|
||||
/// <param name="packageBundle">资源包描述</param>
|
||||
/// <param name="archiveBundle">已解析的归档资源包数据对象</param>
|
||||
public ArchiveBundleHandle(string bundleFilePath, PackageBundle packageBundle, ArchiveBundle archiveBundle)
|
||||
public ArchiveBundleHandle(PackageBundle packageBundle, ArchiveBundle archiveBundle)
|
||||
{
|
||||
_bundleFilePath = bundleFilePath;
|
||||
_packageBundle = packageBundle;
|
||||
_archiveBundle = archiveBundle;
|
||||
}
|
||||
|
||||
@@ -9,27 +9,18 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
internal sealed class AssetBundleHandle : IBundleHandle
|
||||
{
|
||||
private readonly string _bundleFilePath;
|
||||
private readonly PackageBundle _packageBundle;
|
||||
private readonly AssetBundle _assetBundle;
|
||||
private readonly Stream _bundleStream;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string BundleFilePath
|
||||
{
|
||||
get { return _bundleFilePath; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建 AssetBundleHandle 实例
|
||||
/// </summary>
|
||||
/// <param name="bundleFilePath">资源包文件的本地路径</param>
|
||||
/// <param name="packageBundle">资源包描述</param>
|
||||
/// <param name="assetBundle">已加载的 AssetBundle 对象</param>
|
||||
/// <param name="bundleStream">加载 AssetBundle 时使用的文件流</param>
|
||||
public AssetBundleHandle(string bundleFilePath, PackageBundle packageBundle, AssetBundle assetBundle, Stream bundleStream)
|
||||
public AssetBundleHandle(PackageBundle packageBundle, AssetBundle assetBundle, Stream bundleStream)
|
||||
{
|
||||
_bundleFilePath = bundleFilePath;
|
||||
_packageBundle = packageBundle;
|
||||
_assetBundle = assetBundle;
|
||||
_bundleStream = bundleStream;
|
||||
|
||||
@@ -7,25 +7,16 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
internal sealed class RawBundleHandle : IBundleHandle
|
||||
{
|
||||
private readonly string _bundleFilePath;
|
||||
private readonly PackageBundle _packageBundle;
|
||||
private readonly RawBundle _rawBundle;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string BundleFilePath
|
||||
{
|
||||
get { return _bundleFilePath; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建 RawBundleHandle 实例
|
||||
/// </summary>
|
||||
/// <param name="bundleFilePath">资源包文件的本地路径</param>
|
||||
/// <param name="packageBundle">资源包描述</param>
|
||||
/// <param name="rawBundle">已加载的原生资源包数据对象</param>
|
||||
public RawBundleHandle(string bundleFilePath, PackageBundle packageBundle, RawBundle rawBundle)
|
||||
public RawBundleHandle(PackageBundle packageBundle, RawBundle rawBundle)
|
||||
{
|
||||
_bundleFilePath = bundleFilePath;
|
||||
_packageBundle = packageBundle;
|
||||
_rawBundle = rawBundle;
|
||||
}
|
||||
|
||||
@@ -4,23 +4,14 @@ namespace YooAsset
|
||||
{
|
||||
internal sealed class VirtualAssetBundleHandle : IBundleHandle
|
||||
{
|
||||
private readonly string _bundleFilePath;
|
||||
private readonly PackageBundle _packageBundle;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string BundleFilePath
|
||||
{
|
||||
get { return _bundleFilePath; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建 VirtualAssetBundleHandle 实例
|
||||
/// </summary>
|
||||
/// <param name="bundleFilePath">资源包文件的本地路径</param>
|
||||
/// <param name="packageBundle">资源包描述</param>
|
||||
public VirtualAssetBundleHandle(string bundleFilePath, PackageBundle packageBundle)
|
||||
public VirtualAssetBundleHandle(PackageBundle packageBundle)
|
||||
{
|
||||
_bundleFilePath = bundleFilePath;
|
||||
_packageBundle = packageBundle;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,25 +4,16 @@ namespace YooAsset
|
||||
{
|
||||
internal sealed class VirtualRawBundleHandle : IBundleHandle
|
||||
{
|
||||
private readonly string _bundleFilePath;
|
||||
private readonly PackageBundle _packageBundle;
|
||||
private readonly RawBundle _rawBundle;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string BundleFilePath
|
||||
{
|
||||
get { return _bundleFilePath; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建 VirtualRawBundleHandle 实例
|
||||
/// </summary>
|
||||
/// <param name="bundleFilePath">资源包文件的本地路径</param>
|
||||
/// <param name="packageBundle">资源包描述</param>
|
||||
/// <param name="rawBundle">已加载的原生资源包数据对象</param>
|
||||
public VirtualRawBundleHandle(string bundleFilePath, PackageBundle packageBundle, RawBundle rawBundle)
|
||||
public VirtualRawBundleHandle(PackageBundle packageBundle, RawBundle rawBundle)
|
||||
{
|
||||
_bundleFilePath = bundleFilePath;
|
||||
_packageBundle = packageBundle;
|
||||
_rawBundle = rawBundle;
|
||||
}
|
||||
|
||||
@@ -8,27 +8,18 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
internal sealed class WebGameAssetBundleHandle : IBundleHandle
|
||||
{
|
||||
private readonly string _bundleFilePath;
|
||||
private readonly PackageBundle _packageBundle;
|
||||
private readonly AssetBundle _assetBundle;
|
||||
private readonly IWebGamePlatform _platform;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string BundleFilePath
|
||||
{
|
||||
get { return _bundleFilePath; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建 WebGameAssetBundleHandle 实例
|
||||
/// </summary>
|
||||
/// <param name="bundleFilePath">资源包文件的本地路径</param>
|
||||
/// <param name="packageBundle">资源包描述</param>
|
||||
/// <param name="assetBundle">已加载的 AssetBundle 对象</param>
|
||||
/// <param name="platform">平台实现</param>
|
||||
public WebGameAssetBundleHandle(string bundleFilePath, PackageBundle packageBundle, AssetBundle assetBundle, IWebGamePlatform platform)
|
||||
public WebGameAssetBundleHandle(PackageBundle packageBundle, AssetBundle assetBundle, IWebGamePlatform platform)
|
||||
{
|
||||
_bundleFilePath = bundleFilePath;
|
||||
_packageBundle = packageBundle;
|
||||
_assetBundle = assetBundle;
|
||||
_platform = platform;
|
||||
|
||||
@@ -94,27 +94,34 @@ namespace YooAsset
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RawFileHandle -- GetRawFileData / GetRawFileText
|
||||
public sealed partial class RawFileHandle
|
||||
#region BundleFileHandle -- GetBundleFilePath / GetRawFileData / GetRawFileText
|
||||
public sealed partial class BundleFileHandle
|
||||
{
|
||||
/// <summary>
|
||||
/// v2.3: rawFileHandle.GetRawFilePath()
|
||||
/// </summary>
|
||||
[Obsolete("Use EnsureBundleFileAsync() to get bundle file path via EnsureBundleFileOperation.Detail.BundleFilePath.")]
|
||||
public string GetBundleFilePath()
|
||||
{
|
||||
throw new NotSupportedException("GetBundleFilePath() is no longer available. Use EnsureBundleFileAsync() to get bundle file path via EnsureBundleFileOperation.Detail.BundleFilePath.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: rawFileHandle.GetRawFileData()
|
||||
/// </summary>
|
||||
[Obsolete("Read file manually via GetRawFilePath().")]
|
||||
[Obsolete("Use LoadAssetAsync<RawFileObject>() to read binary data via RawFileObject.GetBytes().")]
|
||||
public byte[] GetRawFileData()
|
||||
{
|
||||
if (CheckValidWithWarning() == false) return null;
|
||||
return System.IO.File.ReadAllBytes(GetRawFilePath());
|
||||
throw new NotSupportedException("GetRawFileData() is no longer available. Use LoadAssetAsync<RawFileObject>() to read binary data via RawFileObject.GetBytes().");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: rawFileHandle.GetRawFileText()
|
||||
/// </summary>
|
||||
[Obsolete("Read file manually via GetRawFilePath().")]
|
||||
[Obsolete("Use LoadAssetAsync<RawFileObject>() to read text data via RawFileObject.GetText().")]
|
||||
public string GetRawFileText()
|
||||
{
|
||||
if (CheckValidWithWarning() == false) return null;
|
||||
return System.IO.File.ReadAllText(GetRawFilePath());
|
||||
throw new NotSupportedException("GetRawFileText() is no longer available. Use LoadAssetAsync<RawFileObject>() to read text data via RawFileObject.GetText().");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#if YOOASSET_LEGACY_API
|
||||
using System;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
[Obsolete("Use EditorSimulateBuildInvoker.Build(packageName, (int)EBundleType.VirtualAssetBundle) instead.")]
|
||||
public static class EditorSimulateModeHelper
|
||||
{
|
||||
public static PackageBuildResult SimulateBuild(string packageName)
|
||||
{
|
||||
return EditorSimulateBuildInvoker.Build(packageName, (int)EBundleType.VirtualAssetBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89a5eac0288b2c04dba6f26e6bbdeb0f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -329,6 +329,32 @@ namespace YooAsset
|
||||
return CreateResourceImporter(options);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 资源包文件加载
|
||||
[Obsolete("Use LoadBundleFileSync(AssetInfo) instead.")]
|
||||
public BundleFileHandle LoadRawFileSync(AssetInfo assetInfo)
|
||||
{
|
||||
return LoadBundleFileSync(assetInfo);
|
||||
}
|
||||
|
||||
[Obsolete("Use LoadBundleFileSync(string) instead.")]
|
||||
public BundleFileHandle LoadRawFileSync(string location)
|
||||
{
|
||||
return LoadBundleFileSync(location);
|
||||
}
|
||||
|
||||
[Obsolete("Use LoadBundleFileAsync(AssetInfo, uint) instead.")]
|
||||
public BundleFileHandle LoadRawFileAsync(AssetInfo assetInfo, uint priority = 0)
|
||||
{
|
||||
return LoadBundleFileAsync(assetInfo, priority);
|
||||
}
|
||||
|
||||
[Obsolete("Use LoadBundleFileAsync(string, uint) instead.")]
|
||||
public BundleFileHandle LoadRawFileAsync(string location, uint priority = 0)
|
||||
{
|
||||
return LoadBundleFileAsync(location, priority);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -38,6 +38,13 @@ namespace YooAsset
|
||||
/// <returns>加载资源包操作句柄</returns>
|
||||
FSLoadPackageBundleOperation LoadPackageBundleAsync(FSLoadPackageBundleOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// 确保资源包文件已就绪
|
||||
/// </summary>
|
||||
/// <param name="options">确保资源包已就绪的选项参数</param>
|
||||
/// <returns>确保资源包已就绪的操作句柄</returns>
|
||||
FSEnsurePackageBundleOperation EnsurePackageBundleAsync(FSEnsurePackageBundleOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// 下载资源包
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 确保资源包已就绪的操作基类
|
||||
/// </summary>
|
||||
internal abstract class FSEnsurePackageBundleOperation : AsyncOperationBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源包文件的本地路径
|
||||
/// </summary>
|
||||
public string BundleFilePath { get; protected set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 确保资源包已就绪的失败实现
|
||||
/// </summary>
|
||||
internal sealed class FSEnsurePackageBundleFailureOperation : FSEnsurePackageBundleOperation
|
||||
{
|
||||
private readonly string _error;
|
||||
|
||||
internal FSEnsurePackageBundleFailureOperation(string error)
|
||||
{
|
||||
_error = error;
|
||||
}
|
||||
|
||||
protected override void InternalStart()
|
||||
{
|
||||
SetError(_error);
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 104d90c1b2424984d86d037cc4672f41
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 确保资源包已就绪的操作选项
|
||||
/// </summary>
|
||||
internal readonly struct FSEnsurePackageBundleOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源包描述
|
||||
/// </summary>
|
||||
public PackageBundle Bundle { get; }
|
||||
|
||||
public FSEnsurePackageBundleOptions(PackageBundle bundle)
|
||||
{
|
||||
Bundle = bundle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27f8e387050567642b3ee6da777f3189
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -175,6 +175,12 @@ namespace YooAsset
|
||||
return operation;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FSEnsurePackageBundleOperation EnsurePackageBundleAsync(FSEnsurePackageBundleOptions options)
|
||||
{
|
||||
var operation = new BFSEnsurePackageBundleOperation(this, options);
|
||||
return operation;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FSDownloadBundleOperation DownloadBundleAsync(FSDownloadBundleOptions options)
|
||||
{
|
||||
var operation = new BFSDownloadBundleOperation(this, options);
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal sealed class BFSEnsurePackageBundleOperation : FSEnsurePackageBundleOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
CheckUnpack,
|
||||
UnpackFile,
|
||||
CheckFilePath,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly BuiltinFileSystem _fileSystem;
|
||||
private readonly FSEnsurePackageBundleOptions _options;
|
||||
private FSDownloadBundleOperation _unpackFileOp;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal BFSEnsurePackageBundleOperation(BuiltinFileSystem fileSystem, FSEnsurePackageBundleOptions options)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_options = options;
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CheckUnpack;
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.CheckUnpack)
|
||||
{
|
||||
if (_fileSystem.IsUnpackBundleFile(_options.Bundle))
|
||||
{
|
||||
if (_fileSystem.UnpackBundleCache.IsCached(_options.Bundle.BundleGuid))
|
||||
{
|
||||
_steps = ESteps.CheckFilePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.UnpackFile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BundleFilePath = _fileSystem.GetBuiltinBundleFilePath(_options.Bundle);
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.UnpackFile)
|
||||
{
|
||||
if (_unpackFileOp == null)
|
||||
{
|
||||
var options = new FSDownloadBundleOptions(_options.Bundle, 0);
|
||||
_unpackFileOp = _fileSystem.DownloadBundleAsync(options);
|
||||
_unpackFileOp.StartOperation();
|
||||
AddChildOperation(_unpackFileOp);
|
||||
}
|
||||
|
||||
if (IsWaitForCompletion)
|
||||
_unpackFileOp.WaitForCompletion();
|
||||
|
||||
_unpackFileOp.UpdateOperation();
|
||||
Progress = _unpackFileOp.Progress;
|
||||
if (_unpackFileOp.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_unpackFileOp.Status == EOperationStatus.Succeeded)
|
||||
{
|
||||
_steps = ESteps.CheckFilePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError(_unpackFileOp.Error);
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.CheckFilePath)
|
||||
{
|
||||
string filePath = _fileSystem.UnpackBundleCache.GetCacheFilePath(_options.Bundle.BundleGuid);
|
||||
if (string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError($"Bundle '{_options.Bundle.BundleName}' cache file path not found.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
BundleFilePath = filePath;
|
||||
SetResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
protected override void InternalWaitForCompletion()
|
||||
{
|
||||
ExecuteBatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ea859176a8a53342a78b5dbb0909da0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -121,6 +121,12 @@ namespace YooAsset
|
||||
return operation;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FSEnsurePackageBundleOperation EnsurePackageBundleAsync(FSEnsurePackageBundleOptions options)
|
||||
{
|
||||
var operation = new EFSEnsurePackageBundleOperation(this, options);
|
||||
return operation;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FSDownloadBundleOperation DownloadBundleAsync(FSDownloadBundleOptions options)
|
||||
{
|
||||
var downloader = new EFSDownloadBundleOperation(this, options);
|
||||
@@ -227,7 +233,8 @@ namespace YooAsset
|
||||
virtualWebGLMode: VirtualWebGLMode,
|
||||
asyncSimulateMinFrame: AsyncSimulateMinFrame,
|
||||
asyncSimulateMaxFrame: AsyncSimulateMaxFrame);
|
||||
BundleCache = new EditorBundleCache(packageName, _packageRoot, cacheConfig);
|
||||
string cacheRoot = GetEditorBundleCacheRoot();
|
||||
BundleCache = new EditorBundleCache(packageName, cacheRoot, cacheConfig);
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public void OnDestroy()
|
||||
@@ -273,6 +280,15 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
#region 内部方法
|
||||
/// <summary>
|
||||
/// 获取编辑器缓存根目录路径
|
||||
/// </summary>
|
||||
private string GetEditorBundleCacheRoot()
|
||||
{
|
||||
string root = YooAssetConfiguration.GetEditorCacheRoot();
|
||||
return PathUtility.Combine(root, PackageName, EditorFileSystemConsts.CacheFolderName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取编辑器包裹版本文件路径
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 编辑器文件系统常量定义
|
||||
/// </summary>
|
||||
internal static class EditorFileSystemConsts
|
||||
{
|
||||
/// <summary>
|
||||
/// 编辑器缓存文件的文件夹名称
|
||||
/// </summary>
|
||||
public const string CacheFolderName = "SimulateCache";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 983d63c1d4cc2a24bb2d048e6c2feb2b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,96 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal sealed class EFSEnsurePackageBundleOperation : FSEnsurePackageBundleOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
CheckCache,
|
||||
DownloadFile,
|
||||
CheckFilePath,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly EditorFileSystem _fileSystem;
|
||||
private readonly FSEnsurePackageBundleOptions _options;
|
||||
private FSDownloadBundleOperation _downloadFileOp;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal EFSEnsurePackageBundleOperation(EditorFileSystem fileSystem, FSEnsurePackageBundleOptions options)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_options = options;
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CheckCache;
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.CheckCache)
|
||||
{
|
||||
if (_fileSystem.BundleCache.IsCached(_options.Bundle.BundleGuid))
|
||||
{
|
||||
_steps = ESteps.CheckFilePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.DownloadFile;
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.DownloadFile)
|
||||
{
|
||||
if (_downloadFileOp == null)
|
||||
{
|
||||
var options = new FSDownloadBundleOptions(_options.Bundle, 0);
|
||||
_downloadFileOp = _fileSystem.DownloadBundleAsync(options);
|
||||
_downloadFileOp.StartOperation();
|
||||
AddChildOperation(_downloadFileOp);
|
||||
}
|
||||
|
||||
if (IsWaitForCompletion)
|
||||
_downloadFileOp.WaitForCompletion();
|
||||
|
||||
_downloadFileOp.UpdateOperation();
|
||||
Progress = _downloadFileOp.Progress;
|
||||
if (_downloadFileOp.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_downloadFileOp.Status == EOperationStatus.Succeeded)
|
||||
{
|
||||
_steps = ESteps.CheckFilePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError(_downloadFileOp.Error);
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.CheckFilePath)
|
||||
{
|
||||
string filePath = EditorFileSystemHelper.GetEditorFilePath(_options.Bundle);
|
||||
if (string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError($"Editor file path is empty for bundle '{_options.Bundle.BundleName}'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
BundleFilePath = filePath;
|
||||
SetResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
protected override void InternalWaitForCompletion()
|
||||
{
|
||||
ExecuteBatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44426c6bae3a47e43be1a57e455bf520
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,96 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal sealed class SFSEnsurePackageBundleOperation : FSEnsurePackageBundleOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
CheckCache,
|
||||
DownloadFile,
|
||||
CheckFilePath,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly SandboxFileSystem _fileSystem;
|
||||
private readonly FSEnsurePackageBundleOptions _options;
|
||||
private FSDownloadBundleOperation _downloadFileOp;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal SFSEnsurePackageBundleOperation(SandboxFileSystem fileSystem, FSEnsurePackageBundleOptions options)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_options = options;
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CheckCache;
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.CheckCache)
|
||||
{
|
||||
if (_fileSystem.BundleCache.IsCached(_options.Bundle.BundleGuid))
|
||||
{
|
||||
_steps = ESteps.CheckFilePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.DownloadFile;
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.DownloadFile)
|
||||
{
|
||||
if (_downloadFileOp == null)
|
||||
{
|
||||
var options = new FSDownloadBundleOptions(_options.Bundle, int.MaxValue);
|
||||
_downloadFileOp = _fileSystem.DownloadBundleAsync(options);
|
||||
_downloadFileOp.StartOperation();
|
||||
AddChildOperation(_downloadFileOp);
|
||||
}
|
||||
|
||||
if (IsWaitForCompletion)
|
||||
_downloadFileOp.WaitForCompletion();
|
||||
|
||||
_downloadFileOp.UpdateOperation();
|
||||
Progress = _downloadFileOp.Progress;
|
||||
if (_downloadFileOp.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_downloadFileOp.Status == EOperationStatus.Succeeded)
|
||||
{
|
||||
_steps = ESteps.CheckFilePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError(_downloadFileOp.Error);
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.CheckFilePath)
|
||||
{
|
||||
string filePath = _fileSystem.BundleCache.GetCacheFilePath(_options.Bundle.BundleGuid);
|
||||
if (string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError($"Bundle '{_options.Bundle.BundleName}' cache file path not found.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
BundleFilePath = filePath;
|
||||
SetResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
protected override void InternalWaitForCompletion()
|
||||
{
|
||||
ExecuteBatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3df0f518860ad9042aefab0cc18bc630
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -177,6 +177,12 @@ namespace YooAsset
|
||||
return operation;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FSEnsurePackageBundleOperation EnsurePackageBundleAsync(FSEnsurePackageBundleOptions options)
|
||||
{
|
||||
var operation = new SFSEnsurePackageBundleOperation(this, options);
|
||||
return operation;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FSDownloadBundleOperation DownloadBundleAsync(FSDownloadBundleOptions options)
|
||||
{
|
||||
var downloader = new SFSDownloadBundleOperation(this, options);
|
||||
|
||||
@@ -96,6 +96,12 @@ namespace YooAsset
|
||||
return operation;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public virtual FSEnsurePackageBundleOperation EnsurePackageBundleAsync(FSEnsurePackageBundleOptions options)
|
||||
{
|
||||
var operation = new FSEnsurePackageBundleFailureOperation($"{nameof(WebGameFileSystem)} does not support ensure bundle file operation.");
|
||||
return operation;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public virtual FSDownloadBundleOperation DownloadBundleAsync(FSDownloadBundleOptions options)
|
||||
{
|
||||
var operation = new FSDownloadBundleCompleteOperation($"{nameof(WebGameFileSystem)} does not support download operation.");
|
||||
|
||||
@@ -102,6 +102,12 @@ namespace YooAsset
|
||||
return operation;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FSEnsurePackageBundleOperation EnsurePackageBundleAsync(FSEnsurePackageBundleOptions options)
|
||||
{
|
||||
var operation = new FSEnsurePackageBundleFailureOperation($"{nameof(WebRemoteFileSystem)} does not support ensure bundle file operation.");
|
||||
return operation;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FSDownloadBundleOperation DownloadBundleAsync(FSDownloadBundleOptions options)
|
||||
{
|
||||
var operation = new FSDownloadBundleCompleteOperation($"{nameof(WebRemoteFileSystem)} does not support download operation.");
|
||||
|
||||
@@ -108,6 +108,12 @@ namespace YooAsset
|
||||
return operation;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FSEnsurePackageBundleOperation EnsurePackageBundleAsync(FSEnsurePackageBundleOptions options)
|
||||
{
|
||||
var operation = new FSEnsurePackageBundleFailureOperation($"{nameof(WebServerFileSystem)} does not support ensure bundle file operation.");
|
||||
return operation;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FSDownloadBundleOperation DownloadBundleAsync(FSDownloadBundleOptions options)
|
||||
{
|
||||
var operation = new FSDownloadBundleCompleteOperation($"{nameof(WebServerFileSystem)} does not support download operation.");
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 原生文件句柄,用于访问未经 Unity 处理的原始文件。
|
||||
/// 资源包文件句柄,用于持有已加载的资源包引用。
|
||||
/// </summary>
|
||||
public sealed partial class RawFileHandle : HandleBase
|
||||
public sealed partial class BundleFileHandle : HandleBase
|
||||
{
|
||||
private System.Action<RawFileHandle> _callback;
|
||||
private System.Action<BundleFileHandle> _callback;
|
||||
|
||||
internal RawFileHandle(ProviderBase provider) : base(provider)
|
||||
internal BundleFileHandle(ProviderBase provider) : base(provider)
|
||||
{
|
||||
}
|
||||
internal override void InvokeCallback()
|
||||
@@ -19,12 +19,12 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 当加载完成时触发
|
||||
/// </summary>
|
||||
public event System.Action<RawFileHandle> Completed
|
||||
public event System.Action<BundleFileHandle> Completed
|
||||
{
|
||||
add
|
||||
{
|
||||
if (CheckValidWithWarning() == false)
|
||||
throw new YooHandleInvalidException($"{nameof(RawFileHandle)} is invalid. It may have been released or the provider was destroyed.");
|
||||
throw new YooHandleInvalidException($"{nameof(BundleFileHandle)} is invalid. It may have been released or the provider was destroyed.");
|
||||
if (Provider.IsDone)
|
||||
value.Invoke(this);
|
||||
else
|
||||
@@ -33,7 +33,7 @@ namespace YooAsset
|
||||
remove
|
||||
{
|
||||
if (CheckValidWithWarning() == false)
|
||||
throw new YooHandleInvalidException($"{nameof(RawFileHandle)} is invalid. It may have been released or the provider was destroyed.");
|
||||
throw new YooHandleInvalidException($"{nameof(BundleFileHandle)} is invalid. It may have been released or the provider was destroyed.");
|
||||
_callback -= value;
|
||||
}
|
||||
}
|
||||
@@ -47,16 +47,5 @@ namespace YooAsset
|
||||
return;
|
||||
Provider.WaitForCompletion();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取原生文件的路径
|
||||
/// </summary>
|
||||
/// <returns>原生文件的磁盘路径</returns>
|
||||
public string GetRawFilePath()
|
||||
{
|
||||
if (CheckValidWithWarning() == false)
|
||||
return string.Empty;
|
||||
return Provider.LoadedBundleHandle.BundleFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ namespace YooAsset
|
||||
{ typeof(SceneHandle), op => new SceneHandle(op) },
|
||||
{ typeof(SubAssetsHandle), op => new SubAssetsHandle(op) },
|
||||
{ typeof(AllAssetsHandle), op => new AllAssetsHandle(op) },
|
||||
{ typeof(RawFileHandle), op => new RawFileHandle(op) }
|
||||
{ typeof(BundleFileHandle), op => new BundleFileHandle(op) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源包文件提供者,负责加载资源包文件。
|
||||
/// </summary>
|
||||
internal sealed class BundleFileProvider : ProviderBase
|
||||
{
|
||||
public BundleFileProvider(ResourceManager manager, string providerKey, AssetInfo assetInfo) : base(manager, providerKey, assetInfo)
|
||||
{
|
||||
}
|
||||
protected override void InternalProcessBundleHandle()
|
||||
{
|
||||
SetSuccess();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 原生文件提供者,负责加载原始文件资源。
|
||||
/// </summary>
|
||||
internal sealed class RawFileProvider : ProviderBase
|
||||
{
|
||||
public RawFileProvider(ResourceManager manager, string providerKey, AssetInfo assetInfo) : base(manager, providerKey, assetInfo)
|
||||
{
|
||||
}
|
||||
protected override void InternalProcessBundleHandle()
|
||||
{
|
||||
SetSuccess();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,12 +305,12 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载原生文件
|
||||
/// 加载资源包文件
|
||||
/// </summary>
|
||||
/// <param name="assetInfo">资源信息</param>
|
||||
/// <param name="priority">加载优先级</param>
|
||||
/// <returns>原生文件句柄</returns>
|
||||
public RawFileHandle LoadRawFileAsync(AssetInfo assetInfo, uint priority)
|
||||
/// <returns>资源包文件句柄</returns>
|
||||
public BundleFileHandle LoadBundleFileAsync(AssetInfo assetInfo, uint priority)
|
||||
{
|
||||
if (IsLoadingLocked)
|
||||
{
|
||||
@@ -318,29 +318,29 @@ namespace YooAsset
|
||||
YooLogger.LogError(error);
|
||||
ErrorProvider errorProvider = new ErrorProvider(this, assetInfo);
|
||||
errorProvider.SetCompletedWithError(error);
|
||||
return errorProvider.CreateHandle<RawFileHandle>();
|
||||
return errorProvider.CreateHandle<BundleFileHandle>();
|
||||
}
|
||||
|
||||
if (assetInfo.IsValid == false)
|
||||
{
|
||||
YooLogger.LogError($"Failed to load raw file. Error: {assetInfo.Error}");
|
||||
YooLogger.LogError($"Failed to load bundle file. Error: {assetInfo.Error}");
|
||||
ErrorProvider errorProvider = new ErrorProvider(this, assetInfo);
|
||||
errorProvider.SetCompletedWithError(assetInfo.Error);
|
||||
return errorProvider.CreateHandle<RawFileHandle>();
|
||||
return errorProvider.CreateHandle<BundleFileHandle>();
|
||||
}
|
||||
|
||||
string providerKey = nameof(LoadRawFileAsync) + assetInfo.AssetKey;
|
||||
string providerKey = nameof(LoadBundleFileAsync) + assetInfo.AssetKey;
|
||||
ProviderBase provider = GetAssetProvider(providerKey);
|
||||
if (provider == null)
|
||||
{
|
||||
provider = new RawFileProvider(this, providerKey, assetInfo);
|
||||
provider = new BundleFileProvider(this, providerKey, assetInfo);
|
||||
provider.InitProviderDebugInfo();
|
||||
_providerDict.Add(providerKey, provider);
|
||||
AsyncOperationSystem.StartOperation(PackageName, provider);
|
||||
}
|
||||
|
||||
provider.Priority = priority;
|
||||
return provider.CreateHandle<RawFileHandle>();
|
||||
return provider.CreateHandle<BundleFileHandle>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -32,9 +32,9 @@ namespace YooAsset
|
||||
LoadScene,
|
||||
|
||||
/// <summary>
|
||||
/// 加载原生文件
|
||||
/// 加载资源包文件
|
||||
/// </summary>
|
||||
LoadRawFile,
|
||||
LoadBundleFile,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -50,6 +50,16 @@ namespace YooAsset
|
||||
return _fileSystem.LoadPackageBundleAsync(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建资源包文件确保器
|
||||
/// </summary>
|
||||
/// <returns>返回确保资源包文件就绪的操作对象</returns>
|
||||
public FSEnsurePackageBundleOperation CreateBundleEnsurer()
|
||||
{
|
||||
var options = new FSEnsurePackageBundleOptions(Bundle);
|
||||
return _fileSystem.EnsurePackageBundleAsync(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建资源包下载器
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 确保资源包已就绪的异步操作
|
||||
/// </summary>
|
||||
public sealed class EnsureBundleFileOperation : AsyncOperationBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源包文件详情
|
||||
/// </summary>
|
||||
public readonly struct BundleDetail
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源包名称
|
||||
/// </summary>
|
||||
public readonly string BundleName;
|
||||
|
||||
/// <summary>
|
||||
/// 资源包文件的本地路径
|
||||
/// </summary>
|
||||
public readonly string BundleFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// 资源包类型
|
||||
/// </summary>
|
||||
public readonly int BundleType;
|
||||
|
||||
/// <summary>
|
||||
/// 文件是否加密
|
||||
/// </summary>
|
||||
public readonly bool IsEncrypted;
|
||||
|
||||
internal BundleDetail(string bundleName, string bundleFilePath, int bundleType, bool isEncrypted)
|
||||
{
|
||||
BundleName = bundleName;
|
||||
BundleFilePath = bundleFilePath;
|
||||
BundleType = bundleType;
|
||||
IsEncrypted = isEncrypted;
|
||||
}
|
||||
}
|
||||
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Validate,
|
||||
EnsureFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly FileSystemHost _host;
|
||||
private readonly EnsureBundleFileOptions _options;
|
||||
private FSEnsurePackageBundleOperation _ensurePackageBundleOp;
|
||||
private BundleInfo _bundleInfo;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
/// <summary>
|
||||
/// 资源包文件详情
|
||||
/// </summary>
|
||||
public BundleDetail Detail { get; private set; }
|
||||
|
||||
|
||||
internal EnsureBundleFileOperation(FileSystemHost host, EnsureBundleFileOptions options)
|
||||
{
|
||||
_host = host;
|
||||
_options = options;
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.Validate;
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.Validate)
|
||||
{
|
||||
AssetInfo assetInfo = _options.AssetInfo;
|
||||
if (assetInfo == null)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError("Failed to ensure bundle file. Error: AssetInfo is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (assetInfo.IsValid == false)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError($"Failed to ensure bundle file. Error: {assetInfo.Error}");
|
||||
return;
|
||||
}
|
||||
|
||||
_steps = ESteps.EnsureFile;
|
||||
}
|
||||
|
||||
if (_steps == ESteps.EnsureFile)
|
||||
{
|
||||
if (_ensurePackageBundleOp == null)
|
||||
{
|
||||
_bundleInfo = _host.GetMainBundleInfo(_options.AssetInfo);
|
||||
_ensurePackageBundleOp = _bundleInfo.CreateBundleEnsurer();
|
||||
_ensurePackageBundleOp.StartOperation();
|
||||
AddChildOperation(_ensurePackageBundleOp);
|
||||
}
|
||||
|
||||
_ensurePackageBundleOp.UpdateOperation();
|
||||
Progress = _ensurePackageBundleOp.Progress;
|
||||
if (_ensurePackageBundleOp.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_ensurePackageBundleOp.Status == EOperationStatus.Succeeded)
|
||||
{
|
||||
var bundle = _bundleInfo.Bundle;
|
||||
Detail = new BundleDetail(
|
||||
bundleName: bundle.BundleName,
|
||||
bundleFilePath: _ensurePackageBundleOp.BundleFilePath,
|
||||
bundleType: bundle.GetBundleType(),
|
||||
isEncrypted: bundle.IsEncrypted);
|
||||
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError(_ensurePackageBundleOp.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f96dcb07877ab7d4eaff7d2f9f171ecd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 确保资源包文件已就绪的选项
|
||||
/// </summary>
|
||||
public readonly struct EnsureBundleFileOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源定位地址
|
||||
/// </summary>
|
||||
public string Location { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 资源信息
|
||||
/// </summary>
|
||||
public AssetInfo AssetInfo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建确保资源包文件已就绪的选项实例
|
||||
/// </summary>
|
||||
/// <param name="location">资源定位地址</param>
|
||||
public EnsureBundleFileOptions(string location)
|
||||
{
|
||||
Location = location;
|
||||
AssetInfo = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建确保资源包文件已就绪的选项实例
|
||||
/// </summary>
|
||||
/// <param name="assetInfo">资源信息</param>
|
||||
public EnsureBundleFileOptions(AssetInfo assetInfo)
|
||||
{
|
||||
Location = null;
|
||||
AssetInfo = assetInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a62e7d7a33c4d34a9c3b4d59a3b0a2f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -419,66 +419,6 @@ namespace YooAsset
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 原生文件
|
||||
/// <summary>
|
||||
/// 同步加载原生文件
|
||||
/// </summary>
|
||||
/// <param name="assetInfo">资源信息</param>
|
||||
/// <returns>返回原生文件操作句柄</returns>
|
||||
public RawFileHandle LoadRawFileSync(AssetInfo assetInfo)
|
||||
{
|
||||
CheckInitialized();
|
||||
return LoadRawFileInternal(assetInfo, true, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步加载原生文件
|
||||
/// </summary>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
/// <returns>返回原生文件操作句柄</returns>
|
||||
public RawFileHandle LoadRawFileSync(string location)
|
||||
{
|
||||
CheckInitialized();
|
||||
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
|
||||
return LoadRawFileInternal(assetInfo, true, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载原生文件
|
||||
/// </summary>
|
||||
/// <param name="assetInfo">资源信息</param>
|
||||
/// <param name="priority">加载的优先级</param>
|
||||
/// <returns>返回原生文件操作句柄</returns>
|
||||
public RawFileHandle LoadRawFileAsync(AssetInfo assetInfo, uint priority = 0)
|
||||
{
|
||||
CheckInitialized();
|
||||
return LoadRawFileInternal(assetInfo, false, priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载原生文件
|
||||
/// </summary>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
/// <param name="priority">加载的优先级</param>
|
||||
/// <returns>返回原生文件操作句柄</returns>
|
||||
public RawFileHandle LoadRawFileAsync(string location, uint priority = 0)
|
||||
{
|
||||
CheckInitialized();
|
||||
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
|
||||
return LoadRawFileInternal(assetInfo, false, priority);
|
||||
}
|
||||
|
||||
|
||||
private RawFileHandle LoadRawFileInternal(AssetInfo assetInfo, bool waitForAsyncComplete, uint priority)
|
||||
{
|
||||
assetInfo.LoadMethod = ELoadMethod.LoadRawFile;
|
||||
var handle = _resourceManager.LoadRawFileAsync(assetInfo, priority);
|
||||
if (waitForAsyncComplete)
|
||||
handle.WaitForAsyncComplete();
|
||||
return handle;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 场景加载
|
||||
/// <summary>
|
||||
/// 同步加载场景
|
||||
@@ -898,6 +838,84 @@ namespace YooAsset
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 资源包文件
|
||||
/// <summary>
|
||||
/// 确保资源包文件已就绪
|
||||
/// </summary>
|
||||
/// <param name="options">确保资源包文件已就绪的选项</param>
|
||||
/// <returns>返回确保资源包文件就绪的操作对象</returns>
|
||||
public EnsureBundleFileOperation EnsureBundleFileAsync(EnsureBundleFileOptions options)
|
||||
{
|
||||
CheckInitialized();
|
||||
if (options.AssetInfo == null)
|
||||
{
|
||||
AssetInfo assetInfo = ConvertLocationToAssetInfo(options.Location, null);
|
||||
options = new EnsureBundleFileOptions(assetInfo);
|
||||
}
|
||||
|
||||
var operation = new EnsureBundleFileOperation(_fileSystemHost, options);
|
||||
AsyncOperationSystem.StartOperation(PackageName, operation);
|
||||
return operation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步加载资源包文件
|
||||
/// </summary>
|
||||
/// <param name="assetInfo">资源信息</param>
|
||||
/// <returns>返回资源包文件操作句柄</returns>
|
||||
public BundleFileHandle LoadBundleFileSync(AssetInfo assetInfo)
|
||||
{
|
||||
CheckInitialized();
|
||||
return LoadBundleFileInternal(assetInfo, true, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步加载资源包文件
|
||||
/// </summary>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
/// <returns>返回资源包文件操作句柄</returns>
|
||||
public BundleFileHandle LoadBundleFileSync(string location)
|
||||
{
|
||||
CheckInitialized();
|
||||
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
|
||||
return LoadBundleFileInternal(assetInfo, true, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载资源包文件
|
||||
/// </summary>
|
||||
/// <param name="assetInfo">资源信息</param>
|
||||
/// <param name="priority">加载的优先级</param>
|
||||
/// <returns>返回资源包文件操作句柄</returns>
|
||||
public BundleFileHandle LoadBundleFileAsync(AssetInfo assetInfo, uint priority = 0)
|
||||
{
|
||||
CheckInitialized();
|
||||
return LoadBundleFileInternal(assetInfo, false, priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载资源包文件
|
||||
/// </summary>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
/// <param name="priority">加载的优先级</param>
|
||||
/// <returns>返回资源包文件操作句柄</returns>
|
||||
public BundleFileHandle LoadBundleFileAsync(string location, uint priority = 0)
|
||||
{
|
||||
CheckInitialized();
|
||||
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
|
||||
return LoadBundleFileInternal(assetInfo, false, priority);
|
||||
}
|
||||
|
||||
private BundleFileHandle LoadBundleFileInternal(AssetInfo assetInfo, bool waitForAsyncComplete, uint priority)
|
||||
{
|
||||
assetInfo.LoadMethod = ELoadMethod.LoadBundleFile;
|
||||
var handle = _resourceManager.LoadBundleFileAsync(assetInfo, priority);
|
||||
if (waitForAsyncComplete)
|
||||
handle.WaitForAsyncComplete();
|
||||
return handle;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 资源下载
|
||||
/// <summary>
|
||||
/// 创建资源下载器,用于下载指定的资源标签关联的资源包文件。
|
||||
|
||||
@@ -6,29 +6,29 @@ using NUnit.Framework;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 测试原生文件句柄释放与重新加载
|
||||
/// 测试 Bundle 文件句柄释放与重新加载
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 覆盖 API: LoadRawFileAsync / RawFileHandle.Release / UnloadUnusedAssetsAsync
|
||||
/// 覆盖 API: LoadBundleFileAsync / BundleFileHandle.Release / UnloadUnusedAssetsAsync
|
||||
/// 测试内容:
|
||||
/// 1. 异步加载原生文件,验证加载成功
|
||||
/// 2. 释放 RawFileHandle 引用,等待一帧
|
||||
/// 1. 异步加载 Bundle 文件,验证加载成功
|
||||
/// 2. 释放 BundleFileHandle 引用,等待一帧
|
||||
/// 3. 调用 UnloadUnusedAssetsAsync 清理未使用资源
|
||||
/// 4. 再次加载同一原生文件,验证加载成功且文件路径有效
|
||||
/// 4. 再次加载同一 Bundle 文件,验证加载成功
|
||||
/// </remarks>
|
||||
public class TestRawFileRelease
|
||||
public class TestBundleFileRelease
|
||||
{
|
||||
public IEnumerator RuntimeTester()
|
||||
{
|
||||
ResourcePackage package = YooAssets.GetPackage(TestConsts.RawBundlePackageName);
|
||||
Assert.IsNotNull(package);
|
||||
|
||||
var rawFileHandle = package.LoadRawFileAsync("raw_file_e");
|
||||
yield return rawFileHandle;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, rawFileHandle.Status);
|
||||
var bundleFileHandle = package.LoadBundleFileAsync("raw_file_e");
|
||||
yield return bundleFileHandle;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, bundleFileHandle.Status);
|
||||
|
||||
// 释放
|
||||
rawFileHandle.Release();
|
||||
bundleFileHandle.Release();
|
||||
yield return new WaitForEndOfFrame();
|
||||
|
||||
var unloadOp = package.UnloadUnusedAssetsAsync();
|
||||
@@ -36,10 +36,9 @@ public class TestRawFileRelease
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, unloadOp.Status);
|
||||
|
||||
// 再次加载
|
||||
var reloadHandle = package.LoadRawFileAsync("raw_file_e");
|
||||
var reloadHandle = package.LoadBundleFileAsync("raw_file_e");
|
||||
yield return reloadHandle;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, reloadHandle.Status);
|
||||
Assert.IsTrue(File.Exists(reloadHandle.GetRawFilePath()));
|
||||
reloadHandle.Release();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 测试确保资源包已就绪
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 覆盖 API: EnsureBundleFileAsync
|
||||
/// 测试内容:
|
||||
/// 1. RawBundle 包裹:异步确保资源包已就绪,验证文件路径有效(raw_file_a)
|
||||
/// 2. AssetBundle 包裹:异步确保资源包已就绪,验证文件路径有效(prefab_a)
|
||||
/// 3. ArchiveBundle 包裹:异步确保资源包已就绪,验证文件路径有效(archive_file_a)
|
||||
/// </remarks>
|
||||
public class TestEnsureBundleFile
|
||||
{
|
||||
public IEnumerator RuntimeTester_RawBundle()
|
||||
{
|
||||
ResourcePackage package = YooAssets.GetPackage(TestConsts.RawBundlePackageName);
|
||||
Assert.IsNotNull(package);
|
||||
|
||||
{
|
||||
var ensureOp = package.EnsureBundleFileAsync(new EnsureBundleFileOptions("raw_file_a"));
|
||||
yield return ensureOp;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, ensureOp.Status);
|
||||
|
||||
var detail = ensureOp.Detail;
|
||||
Assert.IsNotNull(detail.BundleFilePath);
|
||||
Assert.IsNotEmpty(detail.BundleFilePath);
|
||||
Assert.IsTrue(File.Exists(detail.BundleFilePath), $"Bundle file does not exist: {detail.BundleFilePath}");
|
||||
Assert.IsNotNull(detail.BundleName);
|
||||
Assert.IsNotEmpty(detail.BundleName);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator RuntimeTester_AssetBundle()
|
||||
{
|
||||
ResourcePackage package = YooAssets.GetPackage(TestConsts.AssetBundlePackageName);
|
||||
Assert.IsNotNull(package);
|
||||
|
||||
{
|
||||
var ensureOp = package.EnsureBundleFileAsync(new EnsureBundleFileOptions("prefab_a"));
|
||||
yield return ensureOp;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, ensureOp.Status);
|
||||
|
||||
var detail = ensureOp.Detail;
|
||||
Assert.IsNotNull(detail.BundleFilePath);
|
||||
Assert.IsNotEmpty(detail.BundleFilePath);
|
||||
Assert.IsTrue(File.Exists(detail.BundleFilePath), $"Bundle file does not exist: {detail.BundleFilePath}");
|
||||
Assert.IsNotNull(detail.BundleName);
|
||||
Assert.IsNotEmpty(detail.BundleName);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator RuntimeTester_ArchiveBundle()
|
||||
{
|
||||
ResourcePackage package = YooAssets.GetPackage(TestConsts.ArchiveBundlePackageName);
|
||||
Assert.IsNotNull(package);
|
||||
|
||||
{
|
||||
var ensureOp = package.EnsureBundleFileAsync(new EnsureBundleFileOptions("archive_file_a"));
|
||||
yield return ensureOp;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, ensureOp.Status);
|
||||
|
||||
var detail = ensureOp.Detail;
|
||||
Assert.IsNotNull(detail.BundleFilePath);
|
||||
Assert.IsNotEmpty(detail.BundleFilePath);
|
||||
Assert.IsTrue(File.Exists(detail.BundleFilePath), $"Bundle file does not exist: {detail.BundleFilePath}");
|
||||
Assert.IsNotNull(detail.BundleName);
|
||||
Assert.IsNotEmpty(detail.BundleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c4cd191337037a4da1cc228d1d871fc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -10,10 +10,10 @@ using YooAsset;
|
||||
/// <remarks>
|
||||
/// 覆盖 API: LoadAssetAsync(RawFileObject) / LoadAssetSync(RawFileObject) / UnloadUnusedAssetsAsync
|
||||
/// 测试内容:
|
||||
/// 1. 异步加载归档子文件,验证 GetBytes() 和 GetText() 均返回有效数据(raw_file_a)
|
||||
/// 2. 同步加载归档子文件,验证 GetBytes() 和 GetText() 均返回有效数据(raw_file_b)
|
||||
/// 3. 重复加载同一归档子文件,验证缓存命中不会失败(raw_file_c)
|
||||
/// 4. 释放句柄并卸载后重新加载,验证卸载保护和重载链路正常(raw_file_e)
|
||||
/// 1. 异步加载归档子文件,验证 GetBytes() 和 GetText() 均返回有效数据(archive_file_a)
|
||||
/// 2. 同步加载归档子文件,验证 GetBytes() 和 GetText() 均返回有效数据(archive_file_b)
|
||||
/// 3. 重复加载同一归档子文件,验证缓存命中不会失败(archive_file_c)
|
||||
/// 4. 释放句柄并卸载后重新加载,验证卸载保护和重载链路正常(archive_file_e)
|
||||
/// </remarks>
|
||||
public class TestLoadArchiveBundle
|
||||
{
|
||||
@@ -24,7 +24,7 @@ public class TestLoadArchiveBundle
|
||||
|
||||
// 异步加载归档子文件
|
||||
{
|
||||
var assetHandle = package.LoadAssetAsync<RawFileObject>("raw_file_a");
|
||||
var assetHandle = package.LoadAssetAsync<RawFileObject>("archive_file_a");
|
||||
yield return assetHandle;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, assetHandle.Status);
|
||||
|
||||
@@ -43,7 +43,7 @@ public class TestLoadArchiveBundle
|
||||
|
||||
// 同步加载归档子文件
|
||||
{
|
||||
var assetHandle = package.LoadAssetSync<RawFileObject>("raw_file_b");
|
||||
var assetHandle = package.LoadAssetSync<RawFileObject>("archive_file_b");
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, assetHandle.Status);
|
||||
|
||||
var rawFileObject = assetHandle.GetAssetObject<RawFileObject>();
|
||||
@@ -61,11 +61,11 @@ public class TestLoadArchiveBundle
|
||||
|
||||
// 重复加载同一归档子文件,验证缓存命中
|
||||
{
|
||||
var handle1 = package.LoadAssetAsync<RawFileObject>("raw_file_c");
|
||||
var handle1 = package.LoadAssetAsync<RawFileObject>("archive_file_c");
|
||||
yield return handle1;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, handle1.Status);
|
||||
|
||||
var handle2 = package.LoadAssetAsync<RawFileObject>("raw_file_c");
|
||||
var handle2 = package.LoadAssetAsync<RawFileObject>("archive_file_c");
|
||||
yield return handle2;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, handle2.Status);
|
||||
|
||||
@@ -80,7 +80,7 @@ public class TestLoadArchiveBundle
|
||||
|
||||
// 释放后卸载再重新加载,验证新旧对象不是同一实例
|
||||
{
|
||||
var assetHandle = package.LoadAssetAsync<RawFileObject>("raw_file_e");
|
||||
var assetHandle = package.LoadAssetAsync<RawFileObject>("archive_file_e");
|
||||
yield return assetHandle;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, assetHandle.Status);
|
||||
|
||||
@@ -93,7 +93,7 @@ public class TestLoadArchiveBundle
|
||||
yield return unloadOp;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, unloadOp.Status);
|
||||
|
||||
var reloadHandle = package.LoadAssetAsync<RawFileObject>("raw_file_e");
|
||||
var reloadHandle = package.LoadAssetAsync<RawFileObject>("archive_file_e");
|
||||
yield return reloadHandle;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, reloadHandle.Status);
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Collections;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 测试 Bundle 文件加载
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 覆盖 API: LoadBundleFileAsync / LoadBundleFileSync
|
||||
/// 测试内容:
|
||||
/// 1. 异步加载 Bundle 文件(raw_file_a)
|
||||
/// 2. 同步加载 Bundle 文件(raw_file_b)
|
||||
/// </remarks>
|
||||
public class TestLoadBundleFile
|
||||
{
|
||||
public IEnumerator RuntimeTester()
|
||||
{
|
||||
ResourcePackage package = YooAssets.GetPackage(TestConsts.RawBundlePackageName);
|
||||
Assert.IsNotNull(package);
|
||||
|
||||
// 测试异步加载
|
||||
{
|
||||
var bundleFileHandle = package.LoadBundleFileAsync("raw_file_a");
|
||||
yield return bundleFileHandle;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, bundleFileHandle.Status);
|
||||
bundleFileHandle.Release();
|
||||
}
|
||||
|
||||
// 测试同步加载
|
||||
{
|
||||
var bundleFileHandle = package.LoadBundleFileSync("raw_file_b");
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, bundleFileHandle.Status);
|
||||
bundleFileHandle.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +1,24 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 测试原生文件加载
|
||||
/// 测试 RawFileObject 加载
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 覆盖 API: LoadRawFileAsync / LoadRawFileSync / LoadAssetAsync(RawFileObject) / LoadAssetSync(RawFileObject)
|
||||
/// 覆盖 API: LoadAssetAsync(RawFileObject) / LoadAssetSync(RawFileObject)
|
||||
/// 测试内容:
|
||||
/// 1. 异步加载原生文件,获取文件路径,验证文件存在且二进制数据非空(raw_file_a)
|
||||
/// 2. 同步加载原生文件,获取文件路径,验证文件存在且二进制数据非空(raw_file_b)
|
||||
/// 3. 异步通过 RawFileObject 加载,验证 GetBytes() 和 GetText() 均返回有效数据(raw_file_c)
|
||||
/// 4. 同步通过 RawFileObject 加载,验证 GetBytes() 和 GetText() 均返回有效数据(raw_file_d)
|
||||
/// 1. 异步通过 RawFileObject 加载,验证 GetBytes() 和 GetText() 均返回有效数据(raw_file_c)
|
||||
/// 2. 同步通过 RawFileObject 加载,验证 GetBytes() 和 GetText() 均返回有效数据(raw_file_d)
|
||||
/// </remarks>
|
||||
public class TestLoadRawFile
|
||||
public class TestLoadRawFileObject
|
||||
{
|
||||
public IEnumerator RuntimeTester()
|
||||
{
|
||||
ResourcePackage package = YooAssets.GetPackage(TestConsts.RawBundlePackageName);
|
||||
Assert.IsNotNull(package);
|
||||
|
||||
// 测试异步加载
|
||||
{
|
||||
var rawFileHandle = package.LoadRawFileAsync("raw_file_a");
|
||||
yield return rawFileHandle;
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, rawFileHandle.Status);
|
||||
|
||||
var filePath = rawFileHandle.GetRawFilePath();
|
||||
Assert.IsNotNull(filePath);
|
||||
Assert.IsTrue(File.Exists(filePath));
|
||||
|
||||
byte[] fileBytes = File.ReadAllBytes(filePath);
|
||||
Assert.IsNotNull(fileBytes);
|
||||
Assert.Greater(fileBytes.Length, 0);
|
||||
rawFileHandle.Release();
|
||||
}
|
||||
|
||||
// 测试同步加载
|
||||
{
|
||||
var rawFileHandle = package.LoadRawFileSync("raw_file_b");
|
||||
Assert.AreEqual(EOperationStatus.Succeeded, rawFileHandle.Status);
|
||||
|
||||
var filePath = rawFileHandle.GetRawFilePath();
|
||||
Assert.IsNotNull(filePath);
|
||||
Assert.IsTrue(File.Exists(filePath));
|
||||
|
||||
byte[] fileBytes = File.ReadAllBytes(filePath);
|
||||
Assert.IsNotNull(fileBytes);
|
||||
Assert.Greater(fileBytes.Length, 0);
|
||||
rawFileHandle.Release();
|
||||
}
|
||||
|
||||
// 测试异步加载:通过 RawFileObject 获取二进制数据和文本数据
|
||||
{
|
||||
var assetHandle = package.LoadAssetAsync<RawFileObject>("raw_file_c");
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d03e8f2341d4c74886f1e7aef83d0c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -247,7 +247,7 @@ public class T0_InitYooAssets : IPrebuildSetup, IPostBuildCleanup
|
||||
{
|
||||
var collector1 = new YooAsset.Editor.BundleCollector();
|
||||
collector1.CollectPath = "";
|
||||
collector1.CollectorGUID = "fddaaf9430e24344196cc82ac3d006b4"; //TestRes/RawFiles目录
|
||||
collector1.CollectorGUID = "c0444018376a7cd4ead6a671035617d6"; //TestRes/ArchiveFiles目录
|
||||
collector1.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
|
||||
collector1.PackRuleName = nameof(YooAsset.Editor.PackCollector);
|
||||
YooAsset.Editor.BundleCollectorSettingData.CreateCollector(archiveFileGroup, collector1);
|
||||
|
||||
@@ -239,23 +239,51 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup
|
||||
var tester = new TestLoadScene();
|
||||
yield return tester.RuntimeTester();
|
||||
}
|
||||
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B10_TestLoadRawFile()
|
||||
public IEnumerator B10_TestLoadBundleFile()
|
||||
{
|
||||
var tester = new TestLoadRawFile();
|
||||
var tester = new TestLoadBundleFile();
|
||||
yield return tester.RuntimeTester();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B11_TestLoadArchiveBundle()
|
||||
public IEnumerator B11_TestLoadRawFileObject()
|
||||
{
|
||||
var tester = new TestLoadRawFileObject();
|
||||
yield return tester.RuntimeTester();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B12_TestLoadArchiveBundle()
|
||||
{
|
||||
var tester = new TestLoadArchiveBundle();
|
||||
yield return tester.RuntimeTester();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B12_TestUniTask()
|
||||
public IEnumerator B13_TestEnsureBundleFile_RawBundle()
|
||||
{
|
||||
var tester = new TestEnsureBundleFile();
|
||||
yield return tester.RuntimeTester_RawBundle();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B14_TestEnsureBundleFile_AssetBundle()
|
||||
{
|
||||
var tester = new TestEnsureBundleFile();
|
||||
yield return tester.RuntimeTester_AssetBundle();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B15_TestEnsureBundleFile_ArchiveBundle()
|
||||
{
|
||||
var tester = new TestEnsureBundleFile();
|
||||
yield return tester.RuntimeTester_ArchiveBundle();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B16_TestUniTask()
|
||||
{
|
||||
var tester = new TestUniTask();
|
||||
yield return tester.RuntimeTester();
|
||||
@@ -304,9 +332,9 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator C07_TestRawFileRelease()
|
||||
public IEnumerator C07_TestBundleFileRelease()
|
||||
{
|
||||
var tester = new TestRawFileRelease();
|
||||
var tester = new TestBundleFileRelease();
|
||||
yield return tester.RuntimeTester();
|
||||
}
|
||||
|
||||
|
||||
@@ -239,23 +239,51 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
|
||||
var tester = new TestLoadScene();
|
||||
yield return tester.RuntimeTester();
|
||||
}
|
||||
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B10_TestLoadRawFile()
|
||||
public IEnumerator B10_TestLoadBundleFile()
|
||||
{
|
||||
var tester = new TestLoadRawFile();
|
||||
var tester = new TestLoadBundleFile();
|
||||
yield return tester.RuntimeTester();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B11_TestLoadArchiveBundle()
|
||||
public IEnumerator B11_TestLoadRawFileObject()
|
||||
{
|
||||
var tester = new TestLoadRawFileObject();
|
||||
yield return tester.RuntimeTester();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B12_TestLoadArchiveBundle()
|
||||
{
|
||||
var tester = new TestLoadArchiveBundle();
|
||||
yield return tester.RuntimeTester();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B12_TestUniTask()
|
||||
public IEnumerator B13_TestEnsureBundleFile_RawBundle()
|
||||
{
|
||||
var tester = new TestEnsureBundleFile();
|
||||
yield return tester.RuntimeTester_RawBundle();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B14_TestEnsureBundleFile_AssetBundle()
|
||||
{
|
||||
var tester = new TestEnsureBundleFile();
|
||||
yield return tester.RuntimeTester_AssetBundle();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B15_TestEnsureBundleFile_ArchiveBundle()
|
||||
{
|
||||
var tester = new TestEnsureBundleFile();
|
||||
yield return tester.RuntimeTester_ArchiveBundle();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator B16_TestUniTask()
|
||||
{
|
||||
var tester = new TestUniTask();
|
||||
yield return tester.RuntimeTester();
|
||||
@@ -331,11 +359,11 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
|
||||
var tester = new TestHandleRelease();
|
||||
yield return tester.RuntimeTester();
|
||||
}
|
||||
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator D07_TestRawFileRelease()
|
||||
public IEnumerator D07_TestBundleFileRelease()
|
||||
{
|
||||
var tester = new TestRawFileRelease();
|
||||
var tester = new TestBundleFileRelease();
|
||||
yield return tester.RuntimeTester();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0444018376a7cd4ead6a671035617d6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1 @@
|
||||
this is archive file a !
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a84d58cf1f5f6d24aa165fe859227a5a
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1 @@
|
||||
this is archive file b !
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cbf8014e6b7abb942a31ff5b316c5344
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1 @@
|
||||
this is archive file c !
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user