Compare commits

...

8 Commits

Author SHA1 Message Date
何冠峰
f05f794461 Update CHANGELOG.md 2026-05-19 16:32:45 +08:00
何冠峰
a5ec8e8eb9 Update package.json 2026-05-19 16:21:32 +08:00
何冠峰
c0c3bb406d feat: add bundle type dropdown for editor simulate pipeline 2026-05-19 16:00:33 +08:00
何冠峰
656b8f18e2 feat: complete compatibility layer 2026-05-19 15:30:38 +08:00
何冠峰
429a7395ca update test sample 2026-05-19 14:26:25 +08:00
何冠峰
f8f2dd8faf feat : add editor bundle cache markers 2026-05-19 14:16:23 +08:00
何冠峰
45ecd8baff feat: add EnsureBundleFileAsync operation 2026-05-15 18:37:01 +08:00
何冠峰
322c4a9847 refactor: rename LoadRawFile API to LoadBundleFile with BundleFileHandle 2026-05-13 17:42:07 +08:00
107 changed files with 1721 additions and 512 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,7 +7,7 @@ namespace YooAsset
internal interface ICacheEntry
{
/// <summary>
/// Bundle 唯一标识
/// 资源包唯一标识
/// </summary>
string BundleGuid { get; }
}

View File

@@ -74,7 +74,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
SetResult();
BundleHandle = new ArchiveBundleHandle(_options.FilePath, _options.Bundle, _archiveBundle);
BundleHandle = new ArchiveBundleHandle(_options.Bundle, _archiveBundle);
}
}
}

View File

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

View File

@@ -100,7 +100,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
SetResult();
BundleHandle = new RawBundleHandle(_options.FilePath, _options.Bundle, _rawBundle);
BundleHandle = new RawBundleHandle(_options.Bundle, _rawBundle);
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f11e7e5e45702bb459771f57e1b84fdc
guid: dc5ebd7b9a6b77145b004dadfe7ed587
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

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

View File

@@ -46,7 +46,6 @@ namespace YooAsset
{
var cacheEntries = _fileCache.GetAllEntries();
EvictionResult clearResult = _policy.SelectEvictionTargets(cacheEntries, _options);
if (clearResult.Succeeded == false)
{
_steps = ESteps.Done;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 2c5756c583ed1474c9abb56419b488d6
guid: dc7b3752dfb973447bdae44ea8722995
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

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

View File

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

View File

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

View File

@@ -170,7 +170,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
SetResult();
BundleHandle = new AssetBundleHandle(_cacheEntry.DataFilePath, _bundle, assetBundle, null);
BundleHandle = new AssetBundleHandle(_bundle, assetBundle, null);
}
}
}

View File

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

View File

@@ -40,5 +40,10 @@ namespace YooAsset
/// 信息文件预期大小(字节)
/// </summary>
public const int InfoFileExpectedSize = 36;
/// <summary>
/// 哈希分片目录前缀长度
/// </summary>
public const int HashFolderNameLength = 2;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,11 +7,6 @@ namespace YooAsset
/// </summary>
internal interface IBundleHandle
{
/// <summary>
/// 资源包文件的本地路径
/// </summary>
string BundleFilePath { get; }
/// <summary>
/// 卸载资源包
/// </summary>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,19 @@
namespace YooAsset
{
/// <summary>
/// 确保资源包已就绪的操作选项
/// </summary>
internal readonly struct FSEnsurePackageBundleOptions
{
/// <summary>
/// 资源包描述
/// </summary>
public PackageBundle Bundle { get; }
public FSEnsurePackageBundleOptions(PackageBundle bundle)
{
Bundle = bundle;
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,14 @@
namespace YooAsset
{
/// <summary>
/// 编辑器文件系统常量定义
/// </summary>
internal static class EditorFileSystemConsts
{
/// <summary>
/// 编辑器缓存文件的文件夹名称
/// </summary>
public const string CacheFolderName = "SimulateCache";
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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.");

View File

@@ -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.");

View File

@@ -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.");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -32,9 +32,9 @@ namespace YooAsset
LoadScene,
/// <summary>
/// 加载原生文件
/// 加载资源包文件
/// </summary>
LoadRawFile,
LoadBundleFile,
}
/// <summary>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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>
/// 创建资源下载器,用于下载指定的资源标签关联的资源包文件。

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1 @@
this is archive file a !

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a84d58cf1f5f6d24aa165fe859227a5a
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1 @@
this is archive file b !

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: cbf8014e6b7abb942a31ff5b316c5344
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1 @@
this is archive file c !

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