using System;
using System.IO;
namespace YooAsset
{
///
/// 编辑器文件缓存写入操作
///
internal sealed class EBCWriteCacheOperation : BCWriteCacheOperation
{
private enum ESteps
{
None,
CheckCache,
CacheFile,
Done,
}
private readonly EditorBundleCache _fileCache;
private readonly BCWriteCacheOptions _options;
private ESteps _steps = ESteps.None;
///
/// 创建编辑器写入缓存操作实例
///
/// 编辑器文件缓存系统
/// 写入缓存选项
public EBCWriteCacheOperation(EditorBundleCache fileCache, BCWriteCacheOptions options)
{
_fileCache = fileCache;
_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 (_fileCache.IsCached(_options.Bundle.BundleGuid))
{
_steps = ESteps.Done;
SetError("Bundle is already cached.");
}
else
{
_steps = ESteps.CacheFile;
}
}
if (_steps == ESteps.CacheFile)
{
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();
}
}
protected override void InternalWaitForCompletion()
{
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}.");
}
}
}
}