mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-26 10:40:14 +00:00
feat : add editor bundle cache markers
This commit is contained in:
@@ -80,7 +80,7 @@ namespace YooAsset
|
|||||||
PackageName = packageName;
|
PackageName = packageName;
|
||||||
RootPath = rootPath;
|
RootPath = rootPath;
|
||||||
Config = config;
|
Config = config;
|
||||||
IsReadOnly = true;
|
IsReadOnly = config.VirtualDownloadMode == false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -208,8 +208,43 @@ namespace YooAsset
|
|||||||
if (_cacheEntries.TryGetValue(bundleGuid, out EditorBundleCacheEntry entry))
|
if (_cacheEntries.TryGetValue(bundleGuid, out EditorBundleCacheEntry entry))
|
||||||
{
|
{
|
||||||
_cacheEntries.Remove(bundleGuid);
|
_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
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dc5ebd7b9a6b77145b004dadfe7ed587
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace YooAsset
|
namespace YooAsset
|
||||||
{
|
{
|
||||||
@@ -11,13 +13,47 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string BundleGuid { get; private set; }
|
public string BundleGuid { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 标记文件路径
|
||||||
|
/// </summary>
|
||||||
|
public string MarkerFilePath { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建编辑器文件缓存条目实例
|
/// 创建编辑器文件缓存条目实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bundleGuid">资源包唯一标识</param>
|
/// <param name="bundleGuid">资源包唯一标识</param>
|
||||||
public EditorBundleCacheEntry(string bundleGuid)
|
/// <param name="markerFilePath">标记文件路径</param>
|
||||||
|
public EditorBundleCacheEntry(string bundleGuid, string markerFilePath)
|
||||||
{
|
{
|
||||||
BundleGuid = bundleGuid;
|
BundleGuid = bundleGuid;
|
||||||
|
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();
|
var cacheEntries = _fileCache.GetAllEntries();
|
||||||
EvictionResult clearResult = _policy.SelectEvictionTargets(cacheEntries, _options);
|
EvictionResult clearResult = _policy.SelectEvictionTargets(cacheEntries, _options);
|
||||||
|
|
||||||
if (clearResult.Succeeded == false)
|
if (clearResult.Succeeded == false)
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
namespace YooAsset
|
namespace YooAsset
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -6,7 +5,17 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal sealed class EBCInitializeOperation : BCInitializeOperation
|
internal sealed class EBCInitializeOperation : BCInitializeOperation
|
||||||
{
|
{
|
||||||
|
private enum ESteps
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
ScanMarkerFiles,
|
||||||
|
AddCacheEntries,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
private readonly EditorBundleCache _fileCache;
|
private readonly EditorBundleCache _fileCache;
|
||||||
|
private ScanMarkerFilesOperation _scanMarkerFilesOp;
|
||||||
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
public EBCInitializeOperation(EditorBundleCache cache)
|
public EBCInitializeOperation(EditorBundleCache cache)
|
||||||
{
|
{
|
||||||
@@ -14,10 +23,58 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
protected override void InternalStart()
|
protected override void InternalStart()
|
||||||
{
|
{
|
||||||
SetResult();
|
if (_fileCache.Config.VirtualDownloadMode == false)
|
||||||
|
{
|
||||||
|
SetResult();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_steps = ESteps.ScanMarkerFiles;
|
||||||
}
|
}
|
||||||
protected override void InternalUpdate()
|
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,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace YooAsset
|
namespace YooAsset
|
||||||
{
|
{
|
||||||
@@ -52,7 +54,38 @@ namespace YooAsset
|
|||||||
|
|
||||||
if (_steps == ESteps.CacheFile)
|
if (_steps == ESteps.CacheFile)
|
||||||
{
|
{
|
||||||
var cacheEntry = new EditorBundleCacheEntry(_options.Bundle.BundleGuid);
|
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);
|
_fileCache.AddEntry(_options.Bundle.BundleGuid, cacheEntry);
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
SetResult();
|
SetResult();
|
||||||
@@ -62,5 +95,18 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
ExecuteBatch();
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dc7b3752dfb973447bdae44ea8722995
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -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 readonly SandboxBundleCache _fileCache;
|
||||||
private IEnumerator<string> _filesEnumerator = null;
|
private IEnumerator<string> _shardEnumerator = null;
|
||||||
private double _verifyStartTime;
|
private double _verifyStartTime;
|
||||||
private ESteps _steps = ESteps.None;
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ namespace YooAsset
|
|||||||
if (Directory.Exists(_fileCache.RootPath))
|
if (Directory.Exists(_fileCache.RootPath))
|
||||||
{
|
{
|
||||||
var directories = Directory.EnumerateDirectories(_fileCache.RootPath);
|
var directories = Directory.EnumerateDirectories(_fileCache.RootPath);
|
||||||
_filesEnumerator = directories.GetEnumerator();
|
_shardEnumerator = directories.GetEnumerator();
|
||||||
_verifyStartTime = TimeUtility.RealtimeSinceStartup;
|
_verifyStartTime = TimeUtility.RealtimeSinceStartup;
|
||||||
_steps = ESteps.SearchFiles;
|
_steps = ESteps.SearchFiles;
|
||||||
}
|
}
|
||||||
@@ -66,35 +66,35 @@ namespace YooAsset
|
|||||||
if (SearchFiles())
|
if (SearchFiles())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_filesEnumerator.Dispose();
|
_shardEnumerator.Dispose();
|
||||||
_filesEnumerator = null;
|
_shardEnumerator = null;
|
||||||
|
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
SetResult();
|
SetResult();
|
||||||
double costTime = TimeUtility.RealtimeSinceStartup - _verifyStartTime;
|
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()
|
protected override void InternalDispose()
|
||||||
{
|
{
|
||||||
if (_filesEnumerator != null)
|
if (_shardEnumerator != null)
|
||||||
{
|
{
|
||||||
_filesEnumerator.Dispose();
|
_shardEnumerator.Dispose();
|
||||||
_filesEnumerator = null;
|
_shardEnumerator = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SearchFiles()
|
private bool SearchFiles()
|
||||||
{
|
{
|
||||||
bool isFindItem;
|
bool hasMore;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
isFindItem = _filesEnumerator.MoveNext();
|
hasMore = _shardEnumerator.MoveNext();
|
||||||
if (isFindItem == false)
|
if (hasMore == false)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
var rootFolder = _filesEnumerator.Current;
|
var shardFolder = _shardEnumerator.Current;
|
||||||
var childDirectories = Directory.EnumerateDirectories(rootFolder);
|
var childDirectories = Directory.EnumerateDirectories(shardFolder);
|
||||||
foreach (var childDirectory in childDirectories)
|
foreach (var childDirectory in childDirectories)
|
||||||
{
|
{
|
||||||
string bundleGuid = Path.GetFileName(childDirectory);
|
string bundleGuid = Path.GetFileName(childDirectory);
|
||||||
@@ -113,7 +113,7 @@ namespace YooAsset
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isFindItem;
|
return hasMore;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, SandboxBundleCacheEntry> _cacheEntries = new Dictionary<string, SandboxBundleCacheEntry>(10000);
|
||||||
private readonly Dictionary<string, string> _dataFilePathMapping = new Dictionary<string, string>(10000);
|
private readonly Dictionary<string, string> _dataFilePathMapping = new Dictionary<string, string>(10000);
|
||||||
private readonly Dictionary<string, string> _infoFilePathMapping = new Dictionary<string, string>(10000);
|
private readonly Dictionary<string, string> _infoFilePathMapping = new Dictionary<string, string>(10000);
|
||||||
@@ -196,11 +195,12 @@ namespace YooAsset
|
|||||||
/// <returns>数据文件的完整路径</returns>
|
/// <returns>数据文件的完整路径</returns>
|
||||||
internal string GetDataFilePath(PackageBundle bundle)
|
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);
|
string folderName = GetHashFolderName(bundleGuid);
|
||||||
filePath = PathUtility.Combine(RootPath, folderName, bundle.BundleGuid, SandboxBundleCacheConsts.BundleDataFileName);
|
filePath = PathUtility.Combine(RootPath, folderName, bundleGuid, SandboxBundleCacheConsts.BundleDataFileName);
|
||||||
_dataFilePathMapping.Add(bundle.BundleGuid, filePath);
|
_dataFilePathMapping.Add(bundleGuid, filePath);
|
||||||
}
|
}
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
@@ -212,11 +212,12 @@ namespace YooAsset
|
|||||||
/// <returns>信息文件的完整路径</returns>
|
/// <returns>信息文件的完整路径</returns>
|
||||||
internal string GetInfoFilePath(PackageBundle bundle)
|
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);
|
string folderName = GetHashFolderName(bundleGuid);
|
||||||
filePath = PathUtility.Combine(RootPath, folderName, bundle.BundleGuid, SandboxBundleCacheConsts.BundleInfoFileName);
|
filePath = PathUtility.Combine(RootPath, folderName, bundleGuid, SandboxBundleCacheConsts.BundleInfoFileName);
|
||||||
_infoFilePathMapping.Add(bundle.BundleGuid, filePath);
|
_infoFilePathMapping.Add(bundleGuid, filePath);
|
||||||
}
|
}
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
@@ -228,8 +229,9 @@ namespace YooAsset
|
|||||||
/// <returns>数据临时文件的完整路径</returns>
|
/// <returns>数据临时文件的完整路径</returns>
|
||||||
internal string GetDataTempFilePath(PackageBundle bundle)
|
internal string GetDataTempFilePath(PackageBundle bundle)
|
||||||
{
|
{
|
||||||
string folderName = GetHashFolderName(bundle.FileHash);
|
string bundleGuid = bundle.BundleGuid;
|
||||||
return PathUtility.Combine(RootPath, folderName, bundle.BundleGuid, SandboxBundleCacheConsts.BundleDataTempFileName);
|
string folderName = GetHashFolderName(bundleGuid);
|
||||||
|
return PathUtility.Combine(RootPath, folderName, bundleGuid, SandboxBundleCacheConsts.BundleDataTempFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -239,8 +241,9 @@ namespace YooAsset
|
|||||||
/// <returns>信息临时文件的完整路径</returns>
|
/// <returns>信息临时文件的完整路径</returns>
|
||||||
internal string GetInfoTempFilePath(PackageBundle bundle)
|
internal string GetInfoTempFilePath(PackageBundle bundle)
|
||||||
{
|
{
|
||||||
string folderName = GetHashFolderName(bundle.FileHash);
|
string bundleGuid = bundle.BundleGuid;
|
||||||
return PathUtility.Combine(RootPath, folderName, bundle.BundleGuid, SandboxBundleCacheConsts.BundleInfoTempFileName);
|
string folderName = GetHashFolderName(bundleGuid);
|
||||||
|
return PathUtility.Combine(RootPath, folderName, bundleGuid, SandboxBundleCacheConsts.BundleInfoTempFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -297,14 +300,14 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetHashFolderName(string fileHash)
|
private string GetHashFolderName(string bundleGuid)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(fileHash))
|
if (string.IsNullOrEmpty(bundleGuid))
|
||||||
throw new YooInternalException("File hash is null or empty.");
|
throw new YooInternalException("Bundle GUID is null or empty.");
|
||||||
|
|
||||||
if (fileHash.Length <= HashFolderNameLength)
|
if (bundleGuid.Length <= SandboxBundleCacheConsts.HashFolderNameLength)
|
||||||
return fileHash;
|
return bundleGuid;
|
||||||
return fileHash.Substring(0, HashFolderNameLength);
|
return bundleGuid.Substring(0, SandboxBundleCacheConsts.HashFolderNameLength);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,5 +40,10 @@ namespace YooAsset
|
|||||||
/// 信息文件预期大小(字节)
|
/// 信息文件预期大小(字节)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int InfoFileExpectedSize = 36;
|
public const int InfoFileExpectedSize = 36;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 哈希分片目录前缀长度
|
||||||
|
/// </summary>
|
||||||
|
public const int HashFolderNameLength = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,7 +233,8 @@ namespace YooAsset
|
|||||||
virtualWebGLMode: VirtualWebGLMode,
|
virtualWebGLMode: VirtualWebGLMode,
|
||||||
asyncSimulateMinFrame: AsyncSimulateMinFrame,
|
asyncSimulateMinFrame: AsyncSimulateMinFrame,
|
||||||
asyncSimulateMaxFrame: AsyncSimulateMaxFrame);
|
asyncSimulateMaxFrame: AsyncSimulateMaxFrame);
|
||||||
BundleCache = new EditorBundleCache(packageName, _packageRoot, cacheConfig);
|
string cacheRoot = GetEditorBundleCacheRoot();
|
||||||
|
BundleCache = new EditorBundleCache(packageName, cacheRoot, cacheConfig);
|
||||||
}
|
}
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void OnDestroy()
|
public void OnDestroy()
|
||||||
@@ -279,6 +280,15 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region 内部方法
|
#region 内部方法
|
||||||
|
/// <summary>
|
||||||
|
/// 获取编辑器缓存根目录路径
|
||||||
|
/// </summary>
|
||||||
|
private string GetEditorBundleCacheRoot()
|
||||||
|
{
|
||||||
|
string root = YooAssetConfiguration.GetEditorCacheRoot();
|
||||||
|
return PathUtility.Combine(root, PackageName, EditorFileSystemConsts.CacheFolderName);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取编辑器包裹版本文件路径
|
/// 获取编辑器包裹版本文件路径
|
||||||
/// </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:
|
||||||
Reference in New Issue
Block a user