Update CacheSystem

优化缓存系统代码结构
This commit is contained in:
hevinci
2022-08-15 11:55:13 +08:00
parent aba68f859f
commit fbbf762e70
26 changed files with 306 additions and 446 deletions
@@ -273,7 +273,7 @@ namespace YooAsset
private static AssetBundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo)
{
// 如果加载器已经存在
AssetBundleLoaderBase loader = TryGetAssetBundleLoader(bundleInfo.BundleName);
AssetBundleLoaderBase loader = TryGetAssetBundleLoader(bundleInfo.Bundle.BundleName);
if (loader != null)
return loader;
@@ -293,7 +293,7 @@ namespace YooAsset
for (int i = 0; i < _loaders.Count; i++)
{
AssetBundleLoaderBase temp = _loaders[i];
if (temp.MainBundleInfo.BundleName.Equals(bundleName))
if (temp.MainBundleInfo.Bundle.BundleName.Equals(bundleName))
{
loader = temp;
break;
@@ -40,29 +40,20 @@ namespace YooAsset
if (_steps == ESteps.None)
{
if (MainBundleInfo.IsInvalid)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"The bundle info is invalid : {MainBundleInfo.BundleName}";
YooLogger.Error(LastError);
return;
}
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.Download;
_fileLoadPath = MainBundleInfo.GetCacheLoadPath();
_fileLoadPath = MainBundleInfo.Bundle.CachedFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
_steps = ESteps.LoadFile;
_fileLoadPath = MainBundleInfo.GetStreamingLoadPath();
_fileLoadPath = MainBundleInfo.Bundle.StreamingFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
_steps = ESteps.LoadFile;
_fileLoadPath = MainBundleInfo.GetCacheLoadPath();
_fileLoadPath = MainBundleInfo.Bundle.CachedFilePath;
}
else
{
@@ -112,15 +103,14 @@ namespace YooAsset
#endif
// Load assetBundle file
if (MainBundleInfo.IsEncrypted)
if (MainBundleInfo.Bundle.IsEncrypted)
{
if (AssetSystem.DecryptionServices == null)
throw new Exception($"{nameof(AssetBundleFileLoader)} need {nameof(IDecryptionServices)} : {MainBundleInfo.BundleName}");
throw new Exception($"{nameof(AssetBundleFileLoader)} need {nameof(IDecryptionServices)} : {MainBundleInfo.Bundle.BundleName}");
DecryptionFileInfo fileInfo = new DecryptionFileInfo();
fileInfo.BundleName = MainBundleInfo.BundleName;
fileInfo.FileHash = MainBundleInfo.FileHash;
fileInfo.FileCRC = MainBundleInfo.FileCRC;
fileInfo.BundleName = MainBundleInfo.Bundle.BundleName;
fileInfo.FileHash = MainBundleInfo.Bundle.FileHash;
ulong offset = AssetSystem.DecryptionServices.GetFileOffset(fileInfo);
if (_isWaitForAsyncComplete)
CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath, 0, offset);
@@ -161,15 +151,15 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"Failed to load assetBundle : {MainBundleInfo.BundleName}";
LastError = $"Failed to load assetBundle : {MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
// 注意:当缓存文件的校验等级为Low的时候,并不能保证缓存文件的完整性。
// 在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性!
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
string cacheLoadPath = MainBundleInfo.GetCacheLoadPath();
if (CacheSystem.CheckContentIntegrity(EVerifyLevel.High, cacheLoadPath, MainBundleInfo.FileSize, MainBundleInfo.FileCRC) == false)
string cacheLoadPath = MainBundleInfo.Bundle.CachedFilePath;
if (CacheSystem.VerifyBundle(MainBundleInfo.Bundle, EVerifyLevel.High) == false)
{
if (File.Exists(cacheLoadPath))
{
@@ -205,7 +195,7 @@ namespace YooAsset
if (_isShowWaitForAsyncError == false)
{
_isShowWaitForAsyncError = true;
YooLogger.Error($"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.BundleName} from remote with sync load method !");
YooLogger.Error($"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !");
}
break;
}
@@ -91,9 +91,9 @@ namespace YooAsset
if (forceDestroy == false)
{
if (RefCount > 0)
throw new Exception($"Bundle file loader ref is not zero : {MainBundleInfo.BundleName}");
throw new Exception($"Bundle file loader ref is not zero : {MainBundleInfo.Bundle.BundleName}");
if (IsDone() == false)
throw new Exception($"Bundle file loader is not done : {MainBundleInfo.BundleName}");
throw new Exception($"Bundle file loader is not done : {MainBundleInfo.Bundle.BundleName}");
}
if (CacheBundle != null)
@@ -38,19 +38,10 @@ namespace YooAsset
if (_steps == ESteps.None)
{
if (MainBundleInfo.IsInvalid)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"The bundle info is invalid : {MainBundleInfo.BundleName}";
YooLogger.Error(LastError);
return;
}
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
_steps = ESteps.LoadFile;
_webURL = MainBundleInfo.GetStreamingLoadPath();
_webURL = MainBundleInfo.Bundle.StreamingFilePath;
}
else
{
@@ -61,7 +52,7 @@ namespace YooAsset
// 1. 从服务器或缓存中获取AssetBundle文件
if (_steps == ESteps.LoadFile)
{
_webRequest = UnityWebRequestAssetBundle.GetAssetBundle(_webURL, Hash128.Parse(MainBundleInfo.FileHash));
_webRequest = UnityWebRequestAssetBundle.GetAssetBundle(_webURL, Hash128.Parse(MainBundleInfo.Bundle.FileHash));
_webRequest.SendWebRequest();
_steps = ESteps.CheckFile;
}
@@ -89,7 +80,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"AssetBundle file is invalid : {MainBundleInfo.BundleName}";
LastError = $"AssetBundle file is invalid : {MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
}
else
@@ -102,7 +102,7 @@ namespace YooAsset
foreach (var loader in _dependBundles)
{
var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = loader.MainBundleInfo.BundleName;
bundleInfo.BundleName = loader.MainBundleInfo.Bundle.BundleName;
bundleInfo.RefCount = loader.RefCount;
bundleInfo.Status = (int)loader.Status;
output.Add(bundleInfo);
@@ -171,14 +171,14 @@ namespace YooAsset
{
None,
Prepare,
DownloadFromApk,
CheckDownloadFromApk,
DownloadBuildinFile,
CheckDownload,
CheckAndCopyFile,
Done,
}
private ESteps _steps = ESteps.None;
private UnityWebFileRequester _fileRequester;
private DownloaderBase _downloader;
public OfflinePlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
{
@@ -199,14 +199,15 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Bundle info is invalid : {_bundleInfo.BundleName}";
Error = $"Bundle info is invalid : {_bundleInfo.Bundle.BundleName}";
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
if (CacheSystem.ContainsVerifyFile(_bundleInfo.LoadBundle))
_steps = ESteps.CheckAndCopyFile;
else
_steps = ESteps.DownloadFromApk;
_steps = ESteps.DownloadBuildinFile;
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
_steps = ESteps.CheckAndCopyFile;
}
else
{
@@ -214,43 +215,32 @@ namespace YooAsset
}
}
// 2. 从APK拷贝文件
if (_steps == ESteps.DownloadFromApk)
// 2. 下载文件
if (_steps == ESteps.DownloadBuildinFile)
{
string downloadURL = PathHelper.ConvertToWWWPath(_bundleInfo.GetStreamingLoadPath());
_fileRequester = new UnityWebFileRequester();
_fileRequester.SendRequest(downloadURL, GetCachePath());
_steps = ESteps.CheckDownloadFromApk;
int failedTryAgain = int.MaxValue;
var bundleInfo = PatchHelper.ConvertToUnpackInfo(_bundleInfo.Bundle);
_downloader = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
_steps = ESteps.CheckDownload;
}
// 3. 检测APK拷贝文件结果
if (_steps == ESteps.CheckDownloadFromApk)
// 3. 检测下载结果
if (_steps == ESteps.CheckDownload)
{
Progress = _fileRequester.Progress();
if (_fileRequester.IsDone() == false)
Progress = _downloader.DownloadProgress;
if (_downloader.IsDone() == false)
return;
if (_fileRequester.HasError())
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _fileRequester.GetError();
Error = _downloader.GetLastError();
}
else
{
if (CacheSystem.CheckContentIntegrity(GetCachePath(), _bundleInfo.FileSize, _bundleInfo.FileCRC))
{
CacheSystem.CacheVerifyFile(_bundleInfo.LoadBundle);
_steps = ESteps.CheckAndCopyFile;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "File content verify failed !";
}
_steps = ESteps.CheckAndCopyFile;
}
_fileRequester.Dispose();
}
// 4. 检测并拷贝原生文件
@@ -267,7 +257,7 @@ namespace YooAsset
// 如果原生文件已经存在,则验证其完整性
if (File.Exists(CopyPath))
{
bool result = CacheSystem.CheckContentIntegrity(CopyPath, _bundleInfo.FileSize, _bundleInfo.FileCRC);
bool result = CacheSystem.VerifyContentInternal(CopyPath, _bundleInfo.Bundle.FileSize, _bundleInfo.Bundle.FileCRC, EVerifyLevel.High);
if (result)
{
_steps = ESteps.Done;
@@ -303,7 +293,7 @@ namespace YooAsset
{
if (_bundleInfo == null)
return string.Empty;
return _bundleInfo.GetCacheLoadPath();
return _bundleInfo.Bundle.CachedFilePath;
}
}
@@ -316,17 +306,15 @@ namespace YooAsset
{
None,
Prepare,
DownloadFromWeb,
CheckDownloadFromWeb,
DownloadFromApk,
CheckDownloadFromApk,
DownloadWebFile,
DownloadBuildinFile,
CheckDownload,
CheckAndCopyFile,
Done,
}
private ESteps _steps = ESteps.None;
private DownloaderBase _downloader;
private UnityWebFileRequester _fileRequester;
internal HostPlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
{
@@ -347,18 +335,15 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Bundle info is invalid : {_bundleInfo.BundleName}";
Error = $"Bundle info is invalid : {_bundleInfo.Bundle.BundleName}";
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.DownloadFromWeb;
_steps = ESteps.DownloadWebFile;
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
if (CacheSystem.ContainsVerifyFile(_bundleInfo.LoadBundle))
_steps = ESteps.CheckAndCopyFile;
else
_steps = ESteps.DownloadFromApk;
_steps = ESteps.DownloadBuildinFile;
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
@@ -370,16 +355,25 @@ namespace YooAsset
}
}
// 2. 从服务器下载
if (_steps == ESteps.DownloadFromWeb)
// 2. 下载远端文件
if (_steps == ESteps.DownloadWebFile)
{
int failedTryAgain = int.MaxValue;
_downloader = DownloadSystem.BeginDownload(_bundleInfo, failedTryAgain);
_steps = ESteps.CheckDownloadFromWeb;
_steps = ESteps.CheckDownload;
}
// 3. 检测服务器下载结果
if (_steps == ESteps.CheckDownloadFromWeb)
// 3. 下载内置文件
if (_steps == ESteps.DownloadBuildinFile)
{
int failedTryAgain = int.MaxValue;
var bundleInfo = PatchHelper.ConvertToUnpackInfo(_bundleInfo.Bundle);
_downloader = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
_steps = ESteps.CheckDownload;
}
// 4. 检测下载结果
if (_steps == ESteps.CheckDownload)
{
Progress = _downloader.DownloadProgress;
if (_downloader.IsDone() == false)
@@ -397,46 +391,7 @@ namespace YooAsset
}
}
// 4. 从APK拷贝文件
if (_steps == ESteps.DownloadFromApk)
{
string downloadURL = PathHelper.ConvertToWWWPath(_bundleInfo.GetStreamingLoadPath());
_fileRequester = new UnityWebFileRequester();
_fileRequester.SendRequest(downloadURL, GetCachePath());
_steps = ESteps.CheckDownloadFromApk;
}
// 5. 检测APK拷贝文件结果
if (_steps == ESteps.CheckDownloadFromApk)
{
Progress = _fileRequester.Progress();
if (_fileRequester.IsDone() == false)
return;
if (_fileRequester.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _fileRequester.GetError();
}
else
{
if (CacheSystem.CheckContentIntegrity(GetCachePath(), _bundleInfo.FileSize, _bundleInfo.FileCRC))
{
CacheSystem.CacheVerifyFile(_bundleInfo.LoadBundle);
_steps = ESteps.CheckAndCopyFile;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "File content verify failed !";
}
}
_fileRequester.Dispose();
}
// 6. 检测并拷贝原生文件
// 5. 检测并拷贝原生文件
if (_steps == ESteps.CheckAndCopyFile)
{
// 如果不需要保存文件
@@ -450,7 +405,7 @@ namespace YooAsset
// 如果原生文件已经存在,则验证其完整性
if (File.Exists(CopyPath))
{
bool result = CacheSystem.CheckContentIntegrity(CopyPath, _bundleInfo.FileSize, _bundleInfo.FileCRC);
bool result = CacheSystem.VerifyContentInternal(CopyPath, _bundleInfo.Bundle.FileSize, _bundleInfo.Bundle.FileCRC, EVerifyLevel.High);
if (result)
{
_steps = ESteps.Done;
@@ -486,7 +441,7 @@ namespace YooAsset
{
if (_bundleInfo == null)
return string.Empty;
return _bundleInfo.GetCacheLoadPath();
return _bundleInfo.Bundle.CachedFilePath;
}
}
}
@@ -65,7 +65,7 @@ namespace YooAsset
if (OwnerBundle.IsDestroyed)
throw new System.Exception("Should never get here !");
Status = EStatus.Fail;
LastError = $"The bundle {OwnerBundle.MainBundleInfo.BundleName} has been destroyed by unity bugs !";
LastError = $"The bundle {OwnerBundle.MainBundleInfo.Bundle.BundleName} has been destroyed by unity bugs !";
InvokeCompletion();
return;
}
@@ -116,9 +116,9 @@ namespace YooAsset
if (Status == EStatus.Fail)
{
if (MainAssetInfo.AssetType == null)
LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.BundleName}";
LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
else
LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.BundleName}";
LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
}
InvokeCompletion();
@@ -41,7 +41,7 @@ namespace YooAsset
internal void GetBundleDebugInfos(List<DebugBundleInfo> output)
{
var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = OwnerBundle.MainBundleInfo.BundleName;
bundleInfo.BundleName = OwnerBundle.MainBundleInfo.Bundle.BundleName;
bundleInfo.RefCount = OwnerBundle.RefCount;
bundleInfo.Status = (int)OwnerBundle.Status;
output.Add(bundleInfo);
@@ -106,9 +106,9 @@ namespace YooAsset
if (Status == EStatus.Fail)
{
if (MainAssetInfo.AssetType == null)
LastError = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.BundleName}";
LastError = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
else
LastError = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.BundleName}";
LastError = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
}
InvokeCompletion();