using System.IO; namespace YooAsset { internal class RawBundleFileLoader : BundleLoaderBase { private enum ESteps { None, Download, CheckDownload, Unpack, CheckUnpack, CheckFile, Done, } private ESteps _steps = ESteps.None; private DownloaderBase _unpacker; private DownloaderBase _downloader; public RawBundleFileLoader(AssetSystemImpl impl, BundleInfo bundleInfo) : base(impl, bundleInfo) { } /// /// 轮询更新 /// public override void Update() { if (_steps == ESteps.Done) return; if (_steps == ESteps.None) { if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote) { _steps = ESteps.Download; FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming) { #if UNITY_ANDROID _steps = ESteps.Unpack; FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; #else _steps = ESteps.CheckFile; FileLoadPath = MainBundleInfo.Bundle.StreamingFilePath; #endif } else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) { _steps = ESteps.CheckFile; FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else { throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString()); } } // 1. 下载远端文件 if (_steps == ESteps.Download) { int failedTryAgain = Impl.DownloadFailedTryAgain; _downloader = DownloadSystem.BeginDownload(MainBundleInfo, failedTryAgain); _steps = ESteps.CheckDownload; } // 2. 检测下载结果 if (_steps == ESteps.CheckDownload) { DownloadProgress = _downloader.DownloadProgress; DownloadedBytes = _downloader.DownloadedBytes; if (_downloader.IsDone() == false) return; if (_downloader.HasError()) { _steps = ESteps.Done; Status = EStatus.Failed; LastError = _downloader.GetLastError(); } else { _steps = ESteps.CheckFile; } } // 3. 解压内置文件 if (_steps == ESteps.Unpack) { int failedTryAgain = Impl.DownloadFailedTryAgain; var bundleInfo = ManifestTools.GetUnpackInfo(MainBundleInfo.Bundle); _unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain); _steps = ESteps.CheckUnpack; } // 4. 检测解压结果 if (_steps == ESteps.CheckUnpack) { DownloadProgress = _unpacker.DownloadProgress; DownloadedBytes = _unpacker.DownloadedBytes; if (_unpacker.IsDone() == false) return; if (_unpacker.HasError()) { _steps = ESteps.Done; Status = EStatus.Failed; LastError = _unpacker.GetLastError(); } else { _steps = ESteps.CheckFile; } } // 5. 检测结果 if (_steps == ESteps.CheckFile) { // 设置下载进度 DownloadProgress = 1f; DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize; if (File.Exists(FileLoadPath)) { _steps = ESteps.Done; Status = EStatus.Succeed; } else { _steps = ESteps.Done; Status = EStatus.Failed; LastError = $"Raw file not found : {FileLoadPath}"; } } } /// /// 主线程等待异步操作完毕 /// public override void WaitForAsyncComplete() { int frame = 1000; while (true) { // 文件解压 if (_unpacker != null) { if (_unpacker.IsDone() == false) { _unpacker.WaitForAsyncComplete = true; _unpacker.Update(); continue; } } // 保险机制 // 注意:如果需要从远端下载资源,可能会触发保险机制! frame--; if (frame == 0) { if (IsDone() == false) { Status = EStatus.Failed; LastError = $"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !"; YooLogger.Error(LastError); } break; } // 驱动流程 Update(); // 完成后退出 if (IsDone()) break; } } } }