diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskEncryption.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskEncryption.cs index d430ae1c..7e9369d7 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskEncryption.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskEncryption.cs @@ -26,7 +26,7 @@ namespace YooAsset.Editor { EncryptFileInfo fileInfo = new EncryptFileInfo(); fileInfo.BundleName = bundleInfo.BundleName; - fileInfo.FilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; + fileInfo.FileLoadPath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; var encryptResult = encryptionServices.Encrypt(fileInfo); if (encryptResult.Encrypted) { diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs index 089bec7d..70cd9770 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs @@ -189,7 +189,7 @@ namespace YooAsset.Editor // Status StyleColor textColor; - if (bundleInfo.Status == BundleLoaderBase.EStatus.Failed.ToString()) + if (bundleInfo.Status == BundleFileLoader.EStatus.Failed.ToString()) textColor = new StyleColor(Color.yellow); else textColor = label1.style.color; diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs b/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs deleted file mode 100644 index 0830053d..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs +++ /dev/null @@ -1,19 +0,0 @@ - -namespace YooAsset -{ - public class CacheFileInfo - { - public string RemoteFileName { private set; get; } - public string FilePath { private set; get; } - public string FileCRC { private set; get; } - public long FileSize { private set; get; } - - public CacheFileInfo(string remoteFileName, string filePath, string fileCRC, long fileSize) - { - RemoteFileName = remoteFileName; - FilePath = filePath; - FileCRC = fileCRC; - FileSize = fileSize; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheHelper.cs b/Assets/YooAsset/Runtime/CacheSystem/CacheHelper.cs deleted file mode 100644 index f99cb6e5..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/CacheHelper.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.IO; - -namespace YooAsset -{ - internal static class CacheHelper - { - /// - /// 禁用Unity缓存系统在WebGL平台 - /// - public static bool DisableUnityCacheOnWebGL = false; - - #region 资源信息文件相关 - private static readonly BufferWriter SharedBuffer = new BufferWriter(1024); - - /// - /// 写入资源包信息 - /// - public static void WriteInfoToFile(string filePath, string dataFileCRC, long dataFileSize) - { - using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read)) - { - SharedBuffer.Clear(); - SharedBuffer.WriteUTF8(dataFileCRC); - SharedBuffer.WriteInt64(dataFileSize); - SharedBuffer.WriteToStream(fs); - fs.Flush(); - } - } - - /// - /// 读取资源包信息 - /// - public static void ReadInfoFromFile(string filePath, out string dataFileCRC, out long dataFileSize) - { - byte[] binaryData = FileUtility.ReadAllBytes(filePath); - BufferReader buffer = new BufferReader(binaryData); - dataFileCRC = buffer.ReadUTF8(); - dataFileSize = buffer.ReadInt64(); - } - #endregion - - #region 资源文件验证相关 - /// - /// 验证缓存文件(子线程内操作) - /// - public static EVerifyResult VerifyingCacheFile(VerifyCacheFileElement element, EVerifyLevel verifyLevel) - { - try - { - if (verifyLevel == EVerifyLevel.Low) - { - if (File.Exists(element.InfoFilePath) == false) - return EVerifyResult.InfoFileNotExisted; - if (File.Exists(element.DataFilePath) == false) - return EVerifyResult.DataFileNotExisted; - return EVerifyResult.Succeed; - } - else - { - if (File.Exists(element.InfoFilePath) == false) - return EVerifyResult.InfoFileNotExisted; - - // 解析信息文件获取验证数据 - CacheHelper.ReadInfoFromFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize); - } - } - catch (Exception) - { - return EVerifyResult.Exception; - } - - return VerifyingInternal(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel); - } - - /// - /// 验证下载文件(子线程内操作) - /// - public static EVerifyResult VerifyingTempFile(VerifyTempFileElement element) - { - return VerifyingInternal(element.TempDataFilePath, element.FileSize, element.FileCRC, EVerifyLevel.High); - } - - /// - /// 验证记录文件(主线程内操作) - /// - public static EVerifyResult VerifyingRecordFile(CacheManager cache, string cacheGUID) - { - var wrapper = cache.TryGetWrapper(cacheGUID); - if (wrapper == null) - return EVerifyResult.CacheNotFound; - - EVerifyResult result = VerifyingInternal(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EVerifyLevel.High); - return result; - } - - private static EVerifyResult VerifyingInternal(string filePath, long fileSize, string fileCRC, EVerifyLevel verifyLevel) - { - try - { - if (File.Exists(filePath) == false) - return EVerifyResult.DataFileNotExisted; - - // 先验证文件大小 - long size = FileUtility.GetFileSize(filePath); - if (size < fileSize) - return EVerifyResult.FileNotComplete; - else if (size > fileSize) - return EVerifyResult.FileOverflow; - - // 再验证文件CRC - if (verifyLevel == EVerifyLevel.High) - { - string crc = HashUtility.FileCRC32Safely(filePath); - if (crc == fileCRC) - return EVerifyResult.Succeed; - else - return EVerifyResult.FileCrcError; - } - else - { - return EVerifyResult.Succeed; - } - } - catch (Exception) - { - return EVerifyResult.Exception; - } - } - #endregion - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheManager.cs b/Assets/YooAsset/Runtime/CacheSystem/CacheManager.cs deleted file mode 100644 index 9b94fc28..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/CacheManager.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset -{ - internal class CacheManager - { - internal class RecordWrapper - { - public string InfoFilePath { private set; get; } - public string DataFilePath { private set; get; } - public string DataFileCRC { private set; get; } - public long DataFileSize { private set; get; } - - public RecordWrapper(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize) - { - InfoFilePath = infoFilePath; - DataFilePath = dataFilePath; - DataFileCRC = dataFileCRC; - DataFileSize = dataFileSize; - } - } - - private readonly Dictionary _wrappers = new Dictionary(); - - /// - /// 所属包裹 - /// - public readonly string PackageName; - - /// - /// 验证级别 - /// - public readonly EVerifyLevel BootVerifyLevel; - - - public CacheManager(string packageName, EVerifyLevel bootVerifyLevel) - { - PackageName = packageName; - BootVerifyLevel = bootVerifyLevel; - } - - /// - /// 清空所有数据 - /// - public void ClearAll() - { - _wrappers.Clear(); - } - - /// - /// 查询缓存记录 - /// - public bool IsCached(string cacheGUID) - { - return _wrappers.ContainsKey(cacheGUID); - } - - /// - /// 记录验证结果 - /// - public void Record(string cacheGUID, RecordWrapper wrapper) - { - if (_wrappers.ContainsKey(cacheGUID) == false) - { - _wrappers.Add(cacheGUID, wrapper); - } - else - { - throw new Exception("Should never get here !"); - } - } - - /// - /// 丢弃验证结果并删除缓存文件 - /// - public void Discard(string cacheGUID) - { - var wrapper = TryGetWrapper(cacheGUID); - if (wrapper != null) - { - try - { - string dataFilePath = wrapper.DataFilePath; - FileInfo fileInfo = new FileInfo(dataFilePath); - if (fileInfo.Exists) - fileInfo.Directory.Delete(true); - } - catch (Exception e) - { - YooLogger.Error($"Failed to delete cache file ! {e.Message}"); - } - } - - if (_wrappers.ContainsKey(cacheGUID)) - { - _wrappers.Remove(cacheGUID); - } - } - - /// - /// 获取记录对象 - /// - public RecordWrapper TryGetWrapper(string cacheGUID) - { - if (_wrappers.TryGetValue(cacheGUID, out RecordWrapper value)) - return value; - else - return null; - } - - /// - /// 获取缓存文件总数 - /// - public int GetAllCachedFilesCount() - { - return _wrappers.Count; - } - - /// - /// 获取缓存GUID集合 - /// - public List GetAllCachedGUIDs() - { - List keys = new List(_wrappers.Keys.Count); - var keyCollection = _wrappers.Keys; - foreach (var key in keyCollection) - { - keys.Add(key); - } - return keys; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs.meta deleted file mode 100644 index 4060acc1..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 65584a0568d40b14582a3c4aaf947b98 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearAllCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearAllCacheFilesOperation.cs.meta deleted file mode 100644 index a16ec019..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearAllCacheFilesOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4eb0b0eafee709d478ab6d81faacb304 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearUnusedCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearUnusedCacheFilesOperation.cs.meta deleted file mode 100644 index 41bfef3b..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearUnusedCacheFilesOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5d188c50fd00bf941b2eeebb374dc0d1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/GetAllCacheFileInfosOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operation/GetAllCacheFileInfosOperation.cs deleted file mode 100644 index b256812b..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/GetAllCacheFileInfosOperation.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset -{ - public class GetAllCacheFileInfosOperation : AsyncOperationBase - { - private enum ESteps - { - None, - TryLoadCacheManifest, - GetCacheFileInfos, - Done, - } - - private readonly PersistentManager _persistent; - private readonly CacheManager _cache; - private readonly string _packageVersion; - private LoadCacheManifestOperation _tryLoadCacheManifestOp; - private PackageManifest _manifest; - private ESteps _steps = ESteps.None; - - private List _cacheFileInfos; - - /// - /// 搜索结果 - /// - public List Result - { - get { return _cacheFileInfos; } - } - - - internal GetAllCacheFileInfosOperation(PersistentManager persistent, CacheManager cache, string packageVersion) - { - _persistent = persistent; - _cache = cache; - _packageVersion = packageVersion; - } - internal override void InternalOnStart() - { - _steps = ESteps.TryLoadCacheManifest; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.TryLoadCacheManifest) - { - if (_tryLoadCacheManifestOp == null) - { - _tryLoadCacheManifestOp = new LoadCacheManifestOperation(_persistent, _packageVersion); - OperationSystem.StartOperation(_cache.PackageName, _tryLoadCacheManifestOp); - } - - if (_tryLoadCacheManifestOp.IsDone == false) - return; - - if (_tryLoadCacheManifestOp.Status == EOperationStatus.Succeed) - { - _manifest = _tryLoadCacheManifestOp.Manifest; - _steps = ESteps.GetCacheFileInfos; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _tryLoadCacheManifestOp.Error; - } - } - - if (_steps == ESteps.GetCacheFileInfos) - { - var allCachedGUIDs = _cache.GetAllCachedGUIDs(); - _cacheFileInfos = new List(allCachedGUIDs.Count); - for (int i = 0; i < allCachedGUIDs.Count; i++) - { - var cachedGUID = allCachedGUIDs[i]; - var wrapper = _cache.TryGetWrapper(cachedGUID); - if (wrapper != null) - { - if (_manifest.TryGetPackageBundleByCacheGUID(cachedGUID, out var packageBundle)) - { - var cacheFileInfo = new CacheFileInfo(packageBundle.FileName, wrapper.DataFilePath, wrapper.DataFileCRC, wrapper.DataFileSize); - _cacheFileInfos.Add(cacheFileInfo); - } - } - } - - // 注意:总是返回成功 - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/GetAllCacheFileInfosOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operation/GetAllCacheFileInfosOperation.cs.meta deleted file mode 100644 index d029471d..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/GetAllCacheFileInfosOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d37e37f5d78ddf8468adcf2dff1edfbb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/FindCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/FindCacheFilesOperation.cs.meta deleted file mode 100644 index 66a2d13a..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/FindCacheFilesOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 00ec004354d75ac499606d6959192f9b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyCacheFilesOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyCacheFilesOperation.cs deleted file mode 100644 index ef46764f..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyCacheFilesOperation.cs +++ /dev/null @@ -1,254 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Threading; - -namespace YooAsset -{ - internal abstract class VerifyCacheFilesOperation : AsyncOperationBase - { - public static VerifyCacheFilesOperation CreateOperation(CacheManager cache, List elements) - { -#if UNITY_WEBGL - var operation = new VerifyCacheFilesWithoutThreadOperation(cache, elements); -#else - var operation = new VerifyCacheFilesWithThreadOperation(cache, elements); -#endif - return operation; - } - } - - /// - /// 本地缓存文件验证(线程版) - /// - internal class VerifyCacheFilesWithThreadOperation : VerifyCacheFilesOperation - { - private enum ESteps - { - None, - InitVerify, - UpdateVerify, - Done, - } - - private readonly ThreadSyncContext _syncContext = new ThreadSyncContext(); - private readonly CacheManager _cache; - private List _waitingList; - private List _verifyingList; - private int _verifyMaxNum; - private int _verifyTotalCount; - private float _verifyStartTime; - private int _succeedCount; - private int _failedCount; - private ESteps _steps = ESteps.None; - - public VerifyCacheFilesWithThreadOperation(CacheManager cache, List elements) - { - _cache = cache; - _waitingList = elements; - } - internal override void InternalOnStart() - { - _steps = ESteps.InitVerify; - _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.InitVerify) - { - int fileCount = _waitingList.Count; - - // 设置同时验证的最大数 - ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads); - YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}"); - _verifyMaxNum = Math.Min(workerThreads, ioThreads); - _verifyTotalCount = fileCount; - if (_verifyMaxNum < 1) - _verifyMaxNum = 1; - - _verifyingList = new List(_verifyMaxNum); - _steps = ESteps.UpdateVerify; - } - - if (_steps == ESteps.UpdateVerify) - { - _syncContext.Update(); - - Progress = GetProgress(); - if (_waitingList.Count == 0 && _verifyingList.Count == 0) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; - YooLogger.Log($"Verify cache files elapsed time {costTime:f1} seconds"); - } - - for (int i = _waitingList.Count - 1; i >= 0; i--) - { - if (OperationSystem.IsBusy) - break; - - if (_verifyingList.Count >= _verifyMaxNum) - break; - - var element = _waitingList[i]; - if (BeginVerifyFileWithThread(element)) - { - _waitingList.RemoveAt(i); - _verifyingList.Add(element); - } - else - { - YooLogger.Warning("The thread pool is failed queued."); - break; - } - } - } - } - - private float GetProgress() - { - if (_verifyTotalCount == 0) - return 1f; - return (float)(_succeedCount + _failedCount) / _verifyTotalCount; - } - private bool BeginVerifyFileWithThread(VerifyCacheFileElement element) - { - return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element); - } - private void VerifyInThread(object obj) - { - VerifyCacheFileElement element = (VerifyCacheFileElement)obj; - element.Result = CacheHelper.VerifyingCacheFile(element, _cache.BootVerifyLevel); - _syncContext.Post(VerifyCallback, element); - } - private void VerifyCallback(object obj) - { - VerifyCacheFileElement element = (VerifyCacheFileElement)obj; - _verifyingList.Remove(element); - - if (element.Result == EVerifyResult.Succeed) - { - _succeedCount++; - var wrapper = new CacheManager.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize); - _cache.Record(element.CacheGUID, wrapper); - } - else - { - _failedCount++; - - YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}"); - element.DeleteFiles(); - } - } - } - - /// - /// 本地缓存文件验证(非线程版) - /// - internal class VerifyCacheFilesWithoutThreadOperation : VerifyCacheFilesOperation - { - private enum ESteps - { - None, - InitVerify, - UpdateVerify, - Done, - } - - private readonly CacheManager _cache; - private List _waitingList; - private List _verifyingList; - private int _verifyMaxNum; - private int _verifyTotalCount; - private float _verifyStartTime; - private int _succeedCount; - private int _failedCount; - private ESteps _steps = ESteps.None; - - public VerifyCacheFilesWithoutThreadOperation(CacheManager cache, List elements) - { - _cache = cache; - _waitingList = elements; - } - internal override void InternalOnStart() - { - _steps = ESteps.InitVerify; - _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.InitVerify) - { - int fileCount = _waitingList.Count; - - // 设置同时验证的最大数 - _verifyMaxNum = fileCount; - _verifyTotalCount = fileCount; - - _verifyingList = new List(_verifyMaxNum); - _steps = ESteps.UpdateVerify; - } - - if (_steps == ESteps.UpdateVerify) - { - Progress = GetProgress(); - if (_waitingList.Count == 0 && _verifyingList.Count == 0) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; - YooLogger.Log($"Package verify elapsed time {costTime:f1} seconds"); - } - - for (int i = _waitingList.Count - 1; i >= 0; i--) - { - if (OperationSystem.IsBusy) - break; - - if (_verifyingList.Count >= _verifyMaxNum) - break; - - var element = _waitingList[i]; - BeginVerifyFileWithoutThread(element); - _waitingList.RemoveAt(i); - _verifyingList.Add(element); - } - - // 主线程内验证,可以清空列表 - _verifyingList.Clear(); - } - } - - private float GetProgress() - { - if (_verifyTotalCount == 0) - return 1f; - return (float)(_succeedCount + _failedCount) / _verifyTotalCount; - } - private void BeginVerifyFileWithoutThread(VerifyCacheFileElement element) - { - element.Result = CacheHelper.VerifyingCacheFile(element, _cache.BootVerifyLevel); - if (element.Result == EVerifyResult.Succeed) - { - _succeedCount++; - var wrapper = new CacheManager.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize); - _cache.Record(element.CacheGUID, wrapper); - } - else - { - _failedCount++; - - YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}"); - element.DeleteFiles(); - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyTempFileOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyTempFileOperation.cs deleted file mode 100644 index 89ee8df9..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyTempFileOperation.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Threading; - -namespace YooAsset -{ - internal abstract class VerifyTempFileOperation : AsyncOperationBase - { - public EVerifyResult VerifyResult { protected set; get; } - - public static VerifyTempFileOperation CreateOperation(VerifyTempFileElement element) - { -#if UNITY_WEBGL - var operation = new VerifyTempFileWithoutThreadOperation(element); -#else - var operation = new VerifyTempFileWithThreadOperation(element); -#endif - return operation; - } - } - - /// - /// 下载文件验证(线程版) - /// - internal class VerifyTempFileWithThreadOperation : VerifyTempFileOperation - { - private enum ESteps - { - None, - VerifyFile, - Waiting, - Done, - } - - private readonly VerifyTempFileElement _element; - private ESteps _steps = ESteps.None; - - public VerifyTempFileWithThreadOperation(VerifyTempFileElement element) - { - _element = element; - } - internal override void InternalOnStart() - { - _steps = ESteps.VerifyFile; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.VerifyFile) - { - if (BeginVerifyFileWithThread(_element)) - { - _steps = ESteps.Waiting; - } - } - - if (_steps == ESteps.Waiting) - { - int result = _element.Result; - if (result == 0) - return; - - VerifyResult = (EVerifyResult)result; - if (VerifyResult == EVerifyResult.Succeed) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Failed verify file : {_element.TempDataFilePath} ! ErrorCode : {VerifyResult}"; - } - } - } - - private bool BeginVerifyFileWithThread(VerifyTempFileElement element) - { - return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element); - } - private void VerifyInThread(object obj) - { - VerifyTempFileElement element = (VerifyTempFileElement)obj; - int result = (int)CacheHelper.VerifyingTempFile(element); - element.Result = result; - } - } - - /// - /// 下载文件验证(非线程版) - /// - internal class VerifyTempFileWithoutThreadOperation : VerifyTempFileOperation - { - private enum ESteps - { - None, - VerifyFile, - Done, - } - - private readonly VerifyTempFileElement _element; - private ESteps _steps = ESteps.None; - - public VerifyTempFileWithoutThreadOperation(VerifyTempFileElement element) - { - _element = element; - } - internal override void InternalOnStart() - { - _steps = ESteps.VerifyFile; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.VerifyFile) - { - _element.Result = (int)CacheHelper.VerifyingTempFile(_element); - - VerifyResult = (EVerifyResult)_element.Result; - if (VerifyResult == EVerifyResult.Succeed) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Failed verify file : {_element.TempDataFilePath} ! ErrorCode : {VerifyResult}"; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/PackageCachingOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operation/PackageCachingOperation.cs deleted file mode 100644 index c8611bf5..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/PackageCachingOperation.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset -{ - internal class PackageCachingOperation : AsyncOperationBase - { - private enum ESteps - { - None, - FindCacheFiles, - VerifyCacheFiles, - Done, - } - - private readonly PersistentManager _persistent; - private readonly CacheManager _cache; - private FindCacheFilesOperation _findCacheFilesOp; - private VerifyCacheFilesOperation _verifyCacheFilesOp; - private ESteps _steps = ESteps.None; - - public PackageCachingOperation(PersistentManager persistent, CacheManager cache) - { - _persistent = persistent; - _cache = cache; - } - internal override void InternalOnStart() - { - _steps = ESteps.FindCacheFiles; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.FindCacheFiles) - { - if (_findCacheFilesOp == null) - { - _findCacheFilesOp = new FindCacheFilesOperation(_persistent, _cache); - OperationSystem.StartOperation(_cache.PackageName, _findCacheFilesOp); - } - - Progress = _findCacheFilesOp.Progress; - if (_findCacheFilesOp.IsDone == false) - return; - - _steps = ESteps.VerifyCacheFiles; - } - - if (_steps == ESteps.VerifyCacheFiles) - { - if (_verifyCacheFilesOp == null) - { - _verifyCacheFilesOp = VerifyCacheFilesOperation.CreateOperation(_cache, _findCacheFilesOp.VerifyElements); - OperationSystem.StartOperation(_cache.PackageName, _verifyCacheFilesOp); - } - - Progress = _verifyCacheFilesOp.Progress; - if (_verifyCacheFilesOp.IsDone == false) - return; - - // 注意:总是返回成功 - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - - int totalCount = _cache.GetAllCachedFilesCount(); - YooLogger.Log($"Package '{_cache.PackageName}' cached files count : {totalCount}"); - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/PackageCachingOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operation/PackageCachingOperation.cs.meta deleted file mode 100644 index e7c542e6..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/PackageCachingOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4ff95e7516dbfa148b4fe16eaab783fb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/PersistentHelper.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/PersistentHelper.cs.meta deleted file mode 100644 index fe3433d2..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/PersistentHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9581e7c53fe081749ab849ec6e2be3d6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/PersistentManager.cs b/Assets/YooAsset/Runtime/CacheSystem/PersistentManager.cs deleted file mode 100644 index fc5f5eb0..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/PersistentManager.cs +++ /dev/null @@ -1,217 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Collections.Generic; - -namespace YooAsset -{ - internal class PersistentManager - { - private readonly Dictionary _cachedDataFilePaths = new Dictionary(10000); - private readonly Dictionary _cachedInfoFilePaths = new Dictionary(10000); - private readonly Dictionary _tempDataFilePaths = new Dictionary(10000); - private readonly Dictionary _buildinFilePaths = new Dictionary(10000); - - /// - /// 所属包裹 - /// - public readonly string PackageName; - - public string BuildinRoot { private set; get; } - public string BuildinPackageRoot { private set; get; } - - public string SandboxRoot { private set; get; } - public string SandboxPackageRoot { private set; get; } - public string SandboxCacheFilesRoot { private set; get; } - public string SandboxManifestFilesRoot { private set; get; } - public string SandboxAppFootPrintFilePath { private set; get; } - - public bool AppendFileExtension { private set; get; } - - - public PersistentManager(string packageName) - { - PackageName = packageName; - } - - /// - /// 初始化 - /// - public void Initialize(string buildinRoot, string sandboxRoot, bool appendFileExtension) - { - if (string.IsNullOrEmpty(buildinRoot)) - BuildinRoot = CreateDefaultBuildinRoot(); - else - BuildinRoot = buildinRoot; - - if (string.IsNullOrEmpty(sandboxRoot)) - SandboxRoot = CreateDefaultSandboxRoot(); - else - SandboxRoot = sandboxRoot; - - BuildinPackageRoot = PathUtility.Combine(BuildinRoot, PackageName); - SandboxPackageRoot = PathUtility.Combine(SandboxRoot, PackageName); - SandboxCacheFilesRoot = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.CacheFilesFolderName); - SandboxManifestFilesRoot = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.ManifestFolderName); - SandboxAppFootPrintFilePath = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.AppFootPrintFileName); - AppendFileExtension = appendFileExtension; - } - private static string CreateDefaultBuildinRoot() - { - string path = PathUtility.Combine(UnityEngine.Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName); -#if UNITY_OPENHARMONY - return $"file://{path}"; -#else - return path; -#endif - } - private static string CreateDefaultSandboxRoot() - { -#if UNITY_EDITOR - // 注意:为了方便调试查看,编辑器下把存储目录放到项目里。 - string projectPath = Path.GetDirectoryName(UnityEngine.Application.dataPath); - projectPath = PathUtility.RegularPath(projectPath); - return PathUtility.Combine(projectPath, YooAssetSettingsData.Setting.DefaultYooFolderName); -#elif UNITY_STANDALONE - return PathUtility.Combine(UnityEngine.Application.dataPath, YooAssetSettingsData.Setting.DefaultYooFolderName); -#else - return PathUtility.Combine(UnityEngine.Application.persistentDataPath, YooAssetSettingsData.Setting.DefaultYooFolderName); -#endif - } - - public string GetCachedDataFilePath(PackageBundle bundle) - { - if (_cachedDataFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false) - { - string folderName = bundle.FileHash.Substring(0, 2); - filePath = PathUtility.Combine(SandboxCacheFilesRoot, folderName, bundle.CacheGUID, YooAssetSettings.CacheBundleDataFileName); - if (AppendFileExtension) - filePath += bundle.FileExtension; - _cachedDataFilePaths.Add(bundle.CacheGUID, filePath); - } - return filePath; - } - public string GetCachedInfoFilePath(PackageBundle bundle) - { - if (_cachedInfoFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false) - { - string folderName = bundle.FileHash.Substring(0, 2); - filePath = PathUtility.Combine(SandboxCacheFilesRoot, folderName, bundle.CacheGUID, YooAssetSettings.CacheBundleInfoFileName); - _cachedInfoFilePaths.Add(bundle.CacheGUID, filePath); - } - return filePath; - } - public string GetTempDataFilePath(PackageBundle bundle) - { - if (_tempDataFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false) - { - string cachedDataFilePath = GetCachedDataFilePath(bundle); - filePath = $"{cachedDataFilePath}.temp"; - _tempDataFilePaths.Add(bundle.CacheGUID, filePath); - } - return filePath; - } - public string GetBuildinFilePath(PackageBundle bundle) - { - if (_buildinFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false) - { - filePath = PathUtility.Combine(BuildinPackageRoot, bundle.FileName); - _buildinFilePaths.Add(bundle.CacheGUID, filePath); - } - return filePath; - } - - /// - /// 删除沙盒里的包裹目录 - /// - public void DeleteSandboxPackageFolder() - { - if (Directory.Exists(SandboxPackageRoot)) - Directory.Delete(SandboxPackageRoot, true); - } - - /// - /// 删除沙盒内的缓存文件夹 - /// - public void DeleteSandboxCacheFilesFolder() - { - if (Directory.Exists(SandboxCacheFilesRoot)) - Directory.Delete(SandboxCacheFilesRoot, true); - } - - /// - /// 删除沙盒内的清单文件夹 - /// - public void DeleteSandboxManifestFilesFolder() - { - if (Directory.Exists(SandboxManifestFilesRoot)) - Directory.Delete(SandboxManifestFilesRoot, true); - } - - - /// - /// 获取沙盒内包裹的清单文件的路径 - /// - public string GetSandboxPackageManifestFilePath(string packageVersion) - { - string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion); - return PathUtility.Combine(SandboxManifestFilesRoot, fileName); - } - - /// - /// 获取沙盒内包裹的哈希文件的路径 - /// - public string GetSandboxPackageHashFilePath(string packageVersion) - { - string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion); - return PathUtility.Combine(SandboxManifestFilesRoot, fileName); - } - - /// - /// 获取沙盒内包裹的版本文件的路径 - /// - public string GetSandboxPackageVersionFilePath() - { - string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName); - return PathUtility.Combine(SandboxManifestFilesRoot, fileName); - } - - /// - /// 保存沙盒内默认的包裹版本 - /// - public void SaveSandboxPackageVersionFile(string version) - { - YooLogger.Log($"Save package version : {version}"); - string filePath = GetSandboxPackageVersionFilePath(); - FileUtility.WriteAllText(filePath, version); - } - - - /// - /// 获取APP内包裹的清单文件的路径 - /// - public string GetBuildinPackageManifestFilePath(string packageVersion) - { - string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion); - return PathUtility.Combine(BuildinPackageRoot, fileName); - } - - /// - /// 获取APP内包裹的哈希文件的路径 - /// - public string GetBuildinPackageHashFilePath(string packageVersion) - { - string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion); - return PathUtility.Combine(BuildinPackageRoot, fileName); - } - - /// - /// 获取APP内包裹的版本文件的路径 - /// - public string GetBuildinPackageVersionFilePath() - { - string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName); - return PathUtility.Combine(BuildinPackageRoot, fileName); - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/PersistentManager.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/PersistentManager.cs.meta deleted file mode 100644 index 0ba0c6d8..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/PersistentManager.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 62ee5fd2821fe85488efff3f8242b703 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs b/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs deleted file mode 100644 index c8cbb461..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System.IO; - -namespace YooAsset -{ - /// - /// 缓存文件验证元素 - /// - internal class VerifyCacheFileElement - { - public string PackageName { private set; get; } - public string CacheGUID { private set; get; } - public string FileRootPath { private set; get; } - public string DataFilePath { private set; get; } - public string InfoFilePath { private set; get; } - - public EVerifyResult Result; - public string DataFileCRC; - public long DataFileSize; - - public VerifyCacheFileElement(string packageName, string cacheGUID, string fileRootPath, string dataFilePath, string infoFilePath) - { - PackageName = packageName; - CacheGUID = cacheGUID; - FileRootPath = fileRootPath; - DataFilePath = dataFilePath; - InfoFilePath = infoFilePath; - } - - public void DeleteFiles() - { - try - { - Directory.Delete(FileRootPath, true); - } - catch (System.Exception e) - { - YooLogger.Warning($"Failed delete cache bundle folder : {e}"); - } - } - } - - /// - /// 下载文件验证元素 - /// - internal class VerifyTempFileElement - { - public string TempDataFilePath { private set; get; } - public string FileCRC { private set; get; } - public long FileSize { private set; get; } - - public int Result = 0; // 注意:原子操作对象 - - public VerifyTempFileElement(string tempDataFilePath, string fileCRC, long fileSize) - { - TempDataFilePath = tempDataFilePath; - FileCRC = fileCRC; - FileSize = fileSize; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta deleted file mode 100644 index 8cb15ad2..00000000 --- a/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5a4b96484bd701f4289b2f74c38abaa8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadHelper.cs b/Assets/YooAsset/Runtime/DownloadSystem/DownloadHelper.cs deleted file mode 100644 index 458529f1..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadHelper.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Collections.Generic; -using System.Threading; -using UnityEngine.Networking; - -namespace YooAsset -{ - /// - /// 自定义下载器的请求委托 - /// - public delegate UnityWebRequest DownloadRequestDelegate(string url); - - - internal static class DownloadHelper - { - /// - /// 下载失败后清理文件的HTTP错误码 - /// - public static List ClearFileResponseCodes { set; get; } - - /// - /// 自定义下载器的请求委托 - /// - public static DownloadRequestDelegate RequestDelegate = null; - - /// - /// 创建一个新的网络请求 - /// - public static UnityWebRequest NewRequest(string requestURL) - { - UnityWebRequest webRequest; - if (RequestDelegate != null) - webRequest = RequestDelegate.Invoke(requestURL); - else - webRequest = new UnityWebRequest(requestURL, UnityWebRequest.kHttpVerbGET); - return webRequest; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadHelper.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/DownloadHelper.cs.meta deleted file mode 100644 index 8b9112e2..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d19eae1f43ecf6347925a06730a6c846 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadManager.cs b/Assets/YooAsset/Runtime/DownloadSystem/DownloadManager.cs deleted file mode 100644 index 84993376..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadManager.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Collections.Generic; -using UnityEngine.Networking; - -namespace YooAsset -{ - /// - /// 1. 保证每一时刻资源文件只存在一个下载器 - /// 2. 保证下载器下载完成后立刻验证并缓存 - /// 3. 保证资源文件不会被重复下载 - /// - internal class DownloadManager - { - private readonly Dictionary _downloaders = new Dictionary(1000); - private readonly List _removeList = new List(1000); - - private uint _breakpointResumeFileSize; - - /// - /// 所属包裹 - /// - public readonly string PackageName; - - - public DownloadManager(string packageName) - { - PackageName = packageName; - } - - /// - /// 初始化 - /// - public void Initialize(uint breakpointResumeFileSize) - { - _breakpointResumeFileSize = breakpointResumeFileSize; - } - - /// - /// 更新下载器 - /// - public void Update() - { - // 更新下载器 - _removeList.Clear(); - foreach (var valuePair in _downloaders) - { - var downloader = valuePair.Value; - downloader.Update(); - if (downloader.IsDone()) - { - _removeList.Add(valuePair.Key); - } - } - - // 移除下载器 - foreach (var key in _removeList) - { - _downloaders.Remove(key); - } - } - - /// - /// 销毁所有下载器 - /// - public void DestroyAll() - { - foreach (var valuePair in _downloaders) - { - var downloader = valuePair.Value; - downloader.Abort(); - } - - _downloaders.Clear(); - _removeList.Clear(); - } - - /// - /// 创建下载器 - /// 注意:只有第一次请求的参数才有效 - /// - public DownloaderBase CreateDownload(BundleInfo bundleInfo, int failedTryAgain, int timeout = 60) - { - // 查询存在的下载器 - if (_downloaders.TryGetValue(bundleInfo.CachedDataFilePath, out var downloader)) - { - downloader.Reference(); - return downloader; - } - - // 如果资源已经缓存 - if (bundleInfo.IsCached()) - { - var completedDownloader = new CompletedDownloader(bundleInfo); - return completedDownloader; - } - - // 创建新的下载器 - DownloaderBase newDownloader = null; - YooLogger.Log($"Beginning to download bundle : {bundleInfo.Bundle.BundleName} URL : {bundleInfo.RemoteMainURL}"); -#if UNITY_WEBGL - if (bundleInfo.Bundle.Buildpipeline == EDefaultBuildPipeline.RawFileBuildPipeline.ToString()) - { - FileUtility.CreateFileDirectory(bundleInfo.CachedDataFilePath); - System.Type requesterType = typeof(FileGeneralRequest); - newDownloader = new FileDownloader(bundleInfo, requesterType, failedTryAgain, timeout); - } - else - { - System.Type requesterType = typeof(AssetBundleWebRequest); - newDownloader = new WebDownloader(bundleInfo, requesterType, failedTryAgain, timeout); - } -#else - FileUtility.CreateFileDirectory(bundleInfo.CachedDataFilePath); - bool resumeDownload = bundleInfo.Bundle.FileSize >= _breakpointResumeFileSize; - if (resumeDownload) - { - System.Type requesterType = typeof(FileResumeRequest); - newDownloader = new FileDownloader(bundleInfo, requesterType, failedTryAgain, timeout); - } - else - { - System.Type requesterType = typeof(FileGeneralRequest); - newDownloader = new FileDownloader(bundleInfo, requesterType, failedTryAgain, timeout); - } -#endif - - // 返回新创建的下载器 - _downloaders.Add(bundleInfo.CachedDataFilePath, newDownloader); - newDownloader.Reference(); - return newDownloader; - } - - /// - /// 停止不再使用的下载器 - /// - public void AbortUnusedDownloader() - { - foreach (var valuePair in _downloaders) - { - var downloader = valuePair.Value; - if (downloader.RefCount <= 0) - { - downloader.Abort(); - } - } - } - } -} diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadManager.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/DownloadManager.cs.meta deleted file mode 100644 index dceffc05..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadManager.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6fbbbfe01e018b241bf33469f870a4b8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/PersistentHelper.cs b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs similarity index 54% rename from Assets/YooAsset/Runtime/CacheSystem/PersistentHelper.cs rename to Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs index dd757a4f..736ec55c 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/PersistentHelper.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs @@ -1,8 +1,25 @@ - +using UnityEngine.Networking; + namespace YooAsset { - internal static class PersistentHelper + /// + /// 自定义下载器的请求委托 + /// + public delegate UnityWebRequest UnityWebRequestDelegate(string url); + + internal class DownloadSystemHelper { + public static UnityWebRequestDelegate UnityWebRequestCreater = null; + public static UnityWebRequest NewUnityWebRequestGet(string requestURL) + { + UnityWebRequest webRequest; + if (UnityWebRequestCreater != null) + webRequest = UnityWebRequestCreater.Invoke(requestURL); + else + webRequest = new UnityWebRequest(requestURL, UnityWebRequest.kHttpVerbGET); + return webRequest; + } + /// /// 获取WWW加载本地资源的路径 /// diff --git a/Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs.meta index 26f29bbc..03e266c3 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs.meta +++ b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 02ad351eb8539da47a0c789e2f8c468f +guid: 5bacfa8c42e283a45a2d21cbb93d6e5d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/CompletedDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/CompletedDownloader.cs deleted file mode 100644 index 44954096..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/CompletedDownloader.cs +++ /dev/null @@ -1,28 +0,0 @@ -using UnityEngine; - -namespace YooAsset -{ - internal sealed class CompletedDownloader : DownloaderBase - { - public CompletedDownloader(BundleInfo bundleInfo) : base(bundleInfo, null, 0, 0) - { - DownloadProgress = 1f; - DownloadedBytes = (ulong)bundleInfo.Bundle.FileSize; - _status = EStatus.Succeed; - } - - public override void SendRequest(params object[] param) - { - } - public override void Update() - { - } - public override void Abort() - { - } - public override AssetBundle GetAssetBundle() - { - throw new System.NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/CompletedDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/CompletedDownloader.cs.meta deleted file mode 100644 index a225b15f..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/CompletedDownloader.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3c7907ead85e2f94786308b28c37a8aa -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs deleted file mode 100644 index df531d5b..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs +++ /dev/null @@ -1,182 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.Networking; - -namespace YooAsset -{ - internal abstract class DownloaderBase - { - public enum EStatus - { - None = 0, - Succeed, - Failed - } - - protected readonly BundleInfo _bundleInfo; - protected readonly System.Type _requesterType; - protected readonly int _timeout; - protected int _failedTryAgain; - - protected IWebRequester _requester; - protected EStatus _status = EStatus.None; - protected string _lastestNetError = string.Empty; - protected long _lastestHttpCode = 0; - - // 请求次数 - protected int _requestCount = 0; - protected string _requestURL; - - // 超时相关 - protected bool _isAbort = false; - protected ulong _latestDownloadBytes; - protected float _latestDownloadRealtime; - protected float _tryAgainTimer; - - /// - /// 是否等待异步结束 - /// 警告:只能用于解压APP内部资源 - /// - public bool WaitForAsyncComplete = false; - - /// - /// 下载进度(0f~1f) - /// - public float DownloadProgress { protected set; get; } - - /// - /// 已经下载的总字节数 - /// - public ulong DownloadedBytes { protected set; get; } - - /// - /// 引用计数 - /// - public int RefCount { private set; get; } - - - public DownloaderBase(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout) - { - _bundleInfo = bundleInfo; - _requesterType = requesterType; - _failedTryAgain = failedTryAgain; - _timeout = timeout; - } - public abstract void SendRequest(params object[] args); - public abstract void Update(); - public abstract void Abort(); - public abstract AssetBundle GetAssetBundle(); - - /// - /// 引用(引用计数递加) - /// - public void Reference() - { - RefCount++; - } - - /// - /// 释放(引用计数递减) - /// - public void Release() - { - RefCount--; - } - - /// - /// 检测下载器是否已经完成(无论成功或失败) - /// - public bool IsDone() - { - return _status == EStatus.Succeed || _status == EStatus.Failed; - } - - /// - /// 下载过程是否发生错误 - /// - public bool HasError() - { - return _status == EStatus.Failed; - } - - /// - /// 按照错误级别打印错误 - /// - public void ReportError() - { - YooLogger.Error(GetLastError()); - } - - /// - /// 按照警告级别打印错误 - /// - public void ReportWarning() - { - YooLogger.Warning(GetLastError()); - } - - /// - /// 获取最近发生的错误信息 - /// - public string GetLastError() - { - return $"Failed to download : {_requestURL} Error : {_lastestNetError} Code : {_lastestHttpCode}"; - } - - /// - /// 获取下载文件的大小 - /// - /// - public long GetDownloadFileSize() - { - return _bundleInfo.Bundle.FileSize; - } - - /// - /// 获取下载的资源包名称 - /// - public string GetDownloadBundleName() - { - return _bundleInfo.Bundle.BundleName; - } - - - /// - /// 获取网络请求地址 - /// - protected string GetRequestURL() - { - // 轮流返回请求地址 - _requestCount++; - if (_requestCount % 2 == 0) - return _bundleInfo.RemoteFallbackURL; - else - return _bundleInfo.RemoteMainURL; - } - - /// - /// 超时判定方法 - /// - protected void CheckTimeout() - { - // 注意:在连续时间段内无新增下载数据及判定为超时 - if (_isAbort == false) - { - if (_latestDownloadBytes != DownloadedBytes) - { - _latestDownloadBytes = DownloadedBytes; - _latestDownloadRealtime = Time.realtimeSinceStartup; - } - - float offset = Time.realtimeSinceStartup - _latestDownloadRealtime; - if (offset > _timeout) - { - YooLogger.Warning($"Web file request timeout : {_requestURL}"); - if (_requester != null) - _requester.Abort(); - _isAbort = true; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs.meta deleted file mode 100644 index 0a530878..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dda4d1eafa2c9f34fade509f8dae9c04 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs deleted file mode 100644 index c84f2653..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs +++ /dev/null @@ -1,216 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using UnityEngine; - -namespace YooAsset -{ - /// - /// 文件下载器 - /// - internal sealed class FileDownloader : DownloaderBase - { - private enum ESteps - { - None, - PrepareDownload, - CreateDownloader, - CheckDownload, - VerifyTempFile, - WaitingVerifyTempFile, - CachingFile, - TryAgain, - Done, - } - - private VerifyTempFileOperation _verifyFileOp = null; - private ESteps _steps = ESteps.None; - - public FileDownloader(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout) : base(bundleInfo, requesterType, failedTryAgain, timeout) - { - } - public override void SendRequest(params object[] args) - { - if (_steps == ESteps.None) - { - _steps = ESteps.PrepareDownload; - } - } - public override void Update() - { - if (_steps == ESteps.None) - return; - if (IsDone()) - return; - - // 准备下载 - if (_steps == ESteps.PrepareDownload) - { - // 获取请求地址 - _requestURL = GetRequestURL(); - - // 重置变量 - DownloadProgress = 0f; - DownloadedBytes = 0; - - // 重置变量 - _isAbort = false; - _latestDownloadBytes = 0; - _latestDownloadRealtime = Time.realtimeSinceStartup; - - // 重置计时器 - if (_tryAgainTimer > 0f) - YooLogger.Warning($"Try again download : {_requestURL}"); - _tryAgainTimer = 0f; - - _steps = ESteps.CreateDownloader; - } - - // 创建下载器 - if (_steps == ESteps.CreateDownloader) - { - _requester = (IWebRequester)Activator.CreateInstance(_requesterType); - _requester.Create(_requestURL, _bundleInfo); - _steps = ESteps.CheckDownload; - } - - // 检测下载结果 - if (_steps == ESteps.CheckDownload) - { - _requester.Update(); - DownloadedBytes = _requester.DownloadedBytes; - DownloadProgress = _requester.DownloadProgress; - if (_requester.IsDone() == false) - { - CheckTimeout(); - return; - } - - _lastestNetError = _requester.RequestNetError; - _lastestHttpCode = _requester.RequestHttpCode; - if (_requester.Status != ERequestStatus.Success) - { - _steps = ESteps.TryAgain; - } - else - { - _steps = ESteps.VerifyTempFile; - } - } - - // 验证下载文件 - if (_steps == ESteps.VerifyTempFile) - { - VerifyTempFileElement element = new VerifyTempFileElement(_bundleInfo.TempDataFilePath, _bundleInfo.Bundle.FileCRC, _bundleInfo.Bundle.FileSize); - _verifyFileOp = VerifyTempFileOperation.CreateOperation(element); - OperationSystem.StartOperation(_bundleInfo.Bundle.PackageName, _verifyFileOp); - _steps = ESteps.WaitingVerifyTempFile; - } - - // 等待验证完成 - if (_steps == ESteps.WaitingVerifyTempFile) - { - if (WaitForAsyncComplete) - _verifyFileOp.InternalOnUpdate(); - - if (_verifyFileOp.IsDone == false) - return; - - if (_verifyFileOp.Status == EOperationStatus.Succeed) - { - _steps = ESteps.CachingFile; - } - else - { - string tempFilePath = _bundleInfo.TempDataFilePath; - if (File.Exists(tempFilePath)) - File.Delete(tempFilePath); - - _lastestNetError = _verifyFileOp.Error; - _steps = ESteps.TryAgain; - } - } - - // 缓存下载文件 - if (_steps == ESteps.CachingFile) - { - try - { - CachingFile(); - _status = EStatus.Succeed; - _steps = ESteps.Done; - } - catch (Exception e) - { - _lastestNetError = e.Message; - _steps = ESteps.TryAgain; - } - } - - // 重新尝试下载 - if (_steps == ESteps.TryAgain) - { - if (_failedTryAgain <= 0) - { - ReportError(); - _status = EStatus.Failed; - _steps = ESteps.Done; - return; - } - - _tryAgainTimer += Time.unscaledDeltaTime; - if (_tryAgainTimer > 1f) - { - _failedTryAgain--; - _steps = ESteps.PrepareDownload; - ReportWarning(); - } - } - } - public override void Abort() - { - if (_requester != null) - _requester.Abort(); - - if (IsDone() == false) - { - _status = EStatus.Failed; - _steps = ESteps.Done; - _lastestNetError = "user abort"; - _lastestHttpCode = 0; - } - } - public override AssetBundle GetAssetBundle() - { - throw new NotImplementedException(); - } - - /// - /// 缓存下载文件 - /// - private void CachingFile() - { - string tempFilePath = _bundleInfo.TempDataFilePath; - string infoFilePath = _bundleInfo.CachedInfoFilePath; - string dataFilePath = _bundleInfo.CachedDataFilePath; - string dataFileCRC = _bundleInfo.Bundle.FileCRC; - long dataFileSize = _bundleInfo.Bundle.FileSize; - - if (File.Exists(infoFilePath)) - File.Delete(infoFilePath); - if (File.Exists(dataFilePath)) - File.Delete(dataFilePath); - - // 移动临时文件路径 - FileInfo fileInfo = new FileInfo(tempFilePath); - fileInfo.MoveTo(dataFilePath); - - // 写入信息文件记录验证数据 - CacheHelper.WriteInfoToFile(infoFilePath, dataFileCRC, dataFileSize); - - // 记录缓存文件 - _bundleInfo.CacheRecord(); - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs.meta deleted file mode 100644 index 54386037..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4c6e1a8bc8d5e664395395daa772ddd7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/WebDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/WebDownloader.cs deleted file mode 100644 index 83ac7e5d..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/WebDownloader.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using UnityEngine; - -namespace YooAsset -{ - internal sealed class WebDownloader : DownloaderBase - { - private enum ESteps - { - None, - PrepareDownload, - CreateDownloader, - CheckDownload, - TryAgain, - Done, - } - - private ESteps _steps = ESteps.None; - private bool _getAssetBundle = false; - - public WebDownloader(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout) : base(bundleInfo, requesterType, failedTryAgain, timeout) - { - } - public override void SendRequest(params object[] args) - { - if (_steps == ESteps.None) - { - if (args.Length > 0) - { - _getAssetBundle = (bool)args[0]; - } - _steps = ESteps.PrepareDownload; - } - } - public override void Update() - { - if (_steps == ESteps.None) - return; - if (IsDone()) - return; - - // 创建下载器 - if (_steps == ESteps.PrepareDownload) - { - // 获取请求地址 - _requestURL = GetRequestURL(); - - // 重置变量 - DownloadProgress = 0f; - DownloadedBytes = 0; - - // 重置变量 - _isAbort = false; - _latestDownloadBytes = 0; - _latestDownloadRealtime = Time.realtimeSinceStartup; - - // 重置计时器 - if (_tryAgainTimer > 0f) - YooLogger.Warning($"Try again download : {_requestURL}"); - _tryAgainTimer = 0f; - - _steps = ESteps.CreateDownloader; - } - - // 创建下载器 - if (_steps == ESteps.CreateDownloader) - { - _requester = (IWebRequester)Activator.CreateInstance(_requesterType); - _requester.Create(_requestURL, _bundleInfo, _getAssetBundle); - _steps = ESteps.CheckDownload; - } - - // 检测下载结果 - if (_steps == ESteps.CheckDownload) - { - _requester.Update(); - DownloadedBytes = _requester.DownloadedBytes; - DownloadProgress = _requester.DownloadProgress; - if (_requester.IsDone() == false) - { - CheckTimeout(); - return; - } - - _lastestNetError = _requester.RequestNetError; - _lastestHttpCode = _requester.RequestHttpCode; - if (_requester.Status != ERequestStatus.Success) - { - _steps = ESteps.TryAgain; - } - else - { - _status = EStatus.Succeed; - _steps = ESteps.Done; - } - } - - // 重新尝试下载 - if (_steps == ESteps.TryAgain) - { - if (_failedTryAgain <= 0) - { - ReportError(); - _status = EStatus.Failed; - _steps = ESteps.Done; - return; - } - - _tryAgainTimer += Time.unscaledDeltaTime; - if (_tryAgainTimer > 1f) - { - _failedTryAgain--; - _steps = ESteps.PrepareDownload; - ReportWarning(); - YooLogger.Warning($"Try again download : {_requestURL}"); - } - } - } - public override void Abort() - { - if (_requester != null) - _requester.Abort(); - - if (IsDone() == false) - { - _status = EStatus.Failed; - _steps = ESteps.Done; - _lastestNetError = "user abort"; - _lastestHttpCode = 0; - } - } - public override AssetBundle GetAssetBundle() - { - return (AssetBundle)_requester.GetRequestObject(); - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/WebDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/WebDownloader.cs.meta deleted file mode 100644 index 690ea8f1..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/WebDownloader.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 41bc4bc56f59ddb4b8925f9536bbbfbc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operation.meta similarity index 77% rename from Assets/YooAsset/Runtime/CacheSystem/Operation.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Operation.meta index 9b6ba5bf..0587d2ca 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation.meta +++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d29a9623b2b346e439b7a7e37fafa781 +guid: a8f060786f8775b4a82cc3f55d9135e2 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal.meta similarity index 77% rename from Assets/YooAsset/Runtime/CacheSystem/Operation/Internal.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal.meta index 81927ef8..159e6467 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal.meta +++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a93a516506b2b5c4492fdefe26eb1175 +guid: 4630dac2050606043bb146325fdce6ad folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebDataRequestOperation.cs b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebDataRequestOperation.cs new file mode 100644 index 00000000..3a26ffc2 --- /dev/null +++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebDataRequestOperation.cs @@ -0,0 +1,77 @@ +using UnityEngine.Networking; +using UnityEngine; + +namespace YooAsset +{ + internal class UnityWebDataRequestOperation : UnityWebRequestOperation + { + private UnityWebRequestAsyncOperation _requestOperation; + + /// + /// 请求结果 + /// + public byte[] Result { private set; get; } + + + internal UnityWebDataRequestOperation(string url, int timeout = 60) : base(url, timeout) + { + } + internal override void InternalOnStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CreateRequest) + { + _latestDownloadBytes = 0; + _latestDownloadRealtime = Time.realtimeSinceStartup; + + CreateWebRequest(); + _steps = ESteps.Download; + } + + if (_steps == ESteps.Download) + { + Progress = _requestOperation.progress; + if (_requestOperation.isDone == false) + { + CheckRequestTimeout(); + return; + } + + if (CheckRequestResult()) + { + _steps = ESteps.Done; + Result = _webRequest.downloadHandler.data; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + } + + // 注意:最终释放请求器 + DisposeRequest(); + } + } + internal override void InternalOnAbort() + { + _steps = ESteps.Done; + DisposeRequest(); + } + + private void CreateWebRequest() + { + _webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL); + DownloadHandlerBuffer handler = new DownloadHandlerBuffer(); + _webRequest.downloadHandler = handler; + _webRequest.disposeDownloadHandlerOnDispose = true; + _requestOperation = _webRequest.SendWebRequest(); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebDataRequestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebDataRequestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebFileRequestOperation.cs b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebFileRequestOperation.cs new file mode 100644 index 00000000..28936bdf --- /dev/null +++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebFileRequestOperation.cs @@ -0,0 +1,73 @@ +using UnityEngine.Networking; +using UnityEngine; + +namespace YooAsset +{ + internal class UnityWebFileRequestOperation : UnityWebRequestOperation + { + private UnityWebRequestAsyncOperation _requestOperation; + private readonly string _fileSavePath; + + internal UnityWebFileRequestOperation(string url, string fileSavePath, int timeout = 60) : base(url, timeout) + { + _fileSavePath = fileSavePath; + } + internal override void InternalOnStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CreateRequest) + { + _latestDownloadBytes = 0; + _latestDownloadRealtime = Time.realtimeSinceStartup; + + CreateWebRequest(); + _steps = ESteps.Download; + } + + if (_steps == ESteps.Download) + { + Progress = _requestOperation.progress; + if (_requestOperation.isDone == false) + { + CheckRequestTimeout(); + return; + } + + if (CheckRequestResult()) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + } + + // 注意:最终释放请求器 + DisposeRequest(); + } + } + internal override void InternalOnAbort() + { + _steps = ESteps.Done; + DisposeRequest(); + } + + private void CreateWebRequest() + { + _webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL); + DownloadHandlerFile handler = new DownloadHandlerFile(_fileSavePath); + handler.removeFileOnAbort = true; + _webRequest.downloadHandler = handler; + _webRequest.disposeDownloadHandlerOnDispose = true; + _requestOperation = _webRequest.SendWebRequest(); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebFileRequestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebFileRequestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequesterBase.cs b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebRequestOperation.cs similarity index 53% rename from Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequesterBase.cs rename to Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebRequestOperation.cs index 0fb6d6ce..26bd625f 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequesterBase.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebRequestOperation.cs @@ -6,94 +6,53 @@ using UnityEngine; namespace YooAsset { - internal abstract class UnityWebRequesterBase + internal abstract class UnityWebRequestOperation : AsyncOperationBase { + protected enum ESteps + { + None, + CreateRequest, + Download, + Done, + } + protected UnityWebRequest _webRequest; - protected UnityWebRequestAsyncOperation _operationHandle; + protected readonly string _requestURL; + protected ESteps _steps = ESteps.None; // 超时相关 - private float _timeout; + protected readonly float _timeout; + protected ulong _latestDownloadBytes; + protected float _latestDownloadRealtime; private bool _isAbort = false; - private ulong _latestDownloadBytes; - private float _latestDownloadRealtime; - /// - /// 请求URL地址 - /// - public string URL { protected set; get; } - - - protected void ResetTimeout(float timeout) + public string URL { + get { return _requestURL; } + } + + internal UnityWebRequestOperation(string url, int timeout) + { + _requestURL = url; _timeout = timeout; - _latestDownloadBytes = 0; - _latestDownloadRealtime = Time.realtimeSinceStartup; } /// /// 释放下载器 /// - public void Dispose() + protected void DisposeRequest() { if (_webRequest != null) { _webRequest.Dispose(); _webRequest = null; - _operationHandle = null; } } - /// - /// 是否完毕(无论成功失败) - /// - public bool IsDone() - { - if (_operationHandle == null) - return false; - return _operationHandle.isDone; - } - - /// - /// 下载进度 - /// - public float Progress() - { - if (_operationHandle == null) - return 0; - return _operationHandle.progress; - } - - /// - /// 下载是否发生错误 - /// - public bool HasError() - { -#if UNITY_2020_3_OR_NEWER - return _webRequest.result != UnityWebRequest.Result.Success; -#else - if (_webRequest.isNetworkError || _webRequest.isHttpError) - return true; - else - return false; -#endif - } - - /// - /// 获取错误信息 - /// - public string GetError() - { - if (_webRequest != null) - { - return $"URL : {URL} Error : {_webRequest.error}"; - } - return string.Empty; - } - /// /// 检测超时 /// - public void CheckTimeout() + protected void CheckRequestTimeout() { // 注意:在连续时间段内无新增下载数据及判定为超时 if (_isAbort == false) @@ -112,5 +71,33 @@ namespace YooAsset } } } + + /// + /// 检测请求结果 + /// + protected bool CheckRequestResult() + { +#if UNITY_2020_3_OR_NEWER + if (_webRequest.result != UnityWebRequest.Result.Success) + { + Error = $"URL : {_requestURL} Error : {_webRequest.error}"; + return false; + } + else + { + return true; + } +#else + if (_webRequest.isNetworkError || _webRequest.isHttpError) + { + Error = $"URL : {_requestURL} Error : {_webRequest.error}"; + return false; + } + else + { + return true; + } +#endif + } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequesterBase.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebRequestOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequesterBase.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebRequestOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebTextRequestOperation.cs b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebTextRequestOperation.cs new file mode 100644 index 00000000..ee1ae32c --- /dev/null +++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebTextRequestOperation.cs @@ -0,0 +1,77 @@ +using UnityEngine.Networking; +using UnityEngine; + +namespace YooAsset +{ + internal class UnityWebTextRequestOperation : UnityWebRequestOperation + { + private UnityWebRequestAsyncOperation _requestOperation; + + /// + /// 请求结果 + /// + public string Result { private set; get; } + + + internal UnityWebTextRequestOperation(string url, int timeout = 60) : base(url, timeout) + { + } + internal override void InternalOnStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CreateRequest) + { + _latestDownloadBytes = 0; + _latestDownloadRealtime = Time.realtimeSinceStartup; + + CreateWebRequest(); + _steps = ESteps.Download; + } + + if (_steps == ESteps.Download) + { + Progress = _requestOperation.progress; + if (_requestOperation.isDone == false) + { + CheckRequestTimeout(); + return; + } + + if (CheckRequestResult()) + { + _steps = ESteps.Done; + Result = _webRequest.downloadHandler.text; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + } + + // 注意:最终释放请求器 + DisposeRequest(); + } + } + internal override void InternalOnAbort() + { + _steps = ESteps.Done; + DisposeRequest(); + } + + private void CreateWebRequest() + { + _webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL); + DownloadHandlerBuffer handler = new DownloadHandlerBuffer(); + _webRequest.downloadHandler = handler; + _webRequest.disposeDownloadHandlerOnDispose = true; + _requestOperation = _webRequest.SendWebRequest(); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheHelper.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebTextRequestOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/CacheSystem/CacheHelper.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebTextRequestOperation.cs.meta index 5fbd5e69..14653aeb 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/CacheHelper.cs.meta +++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebTextRequestOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 8616c7550a7890141af598898a12df1b +guid: a488de5dcd6f4c448a47c4b574d5c9bc MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester.meta b/Assets/YooAsset/Runtime/DownloadSystem/Requester.meta deleted file mode 100644 index 451d6c03..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Requester.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 8a97534752300584a9b8c60c04c6a6a8 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/AssetBundleWebRequest.cs b/Assets/YooAsset/Runtime/DownloadSystem/Requester/AssetBundleWebRequest.cs deleted file mode 100644 index 20b4ab3f..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/AssetBundleWebRequest.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System.IO; -using UnityEngine; -using UnityEngine.Networking; - -namespace YooAsset -{ - internal class AssetBundleWebRequest : IWebRequester - { - private UnityWebRequest _webRequest; - private DownloadHandlerAssetBundle _downloadhandler; - private AssetBundle _cacheAssetBundle; - private bool _getAssetBundle = false; - - public ERequestStatus Status { private set; get; } = ERequestStatus.None; - public float DownloadProgress { private set; get; } - public ulong DownloadedBytes { private set; get; } - public string RequestNetError { private set; get; } - public long RequestHttpCode { private set; get; } - - public AssetBundleWebRequest() { } - public void Create(string requestURL, BundleInfo bundleInfo, params object[] args) - { - if (Status != ERequestStatus.None) - throw new System.Exception("Should never get here !"); - - if (args.Length == 0) - throw new System.Exception("Not found param value"); - - // 解析附加参数 - _getAssetBundle = (bool)args[0]; - - // 创建下载器 - _webRequest = DownloadHelper.NewRequest(requestURL); - if (CacheHelper.DisableUnityCacheOnWebGL) - { - uint crc = bundleInfo.Bundle.UnityCRC; - _downloadhandler = new DownloadHandlerAssetBundle(requestURL, crc); - } - else - { - uint crc = bundleInfo.Bundle.UnityCRC; - var hash = Hash128.Parse(bundleInfo.Bundle.FileHash); - _downloadhandler = new DownloadHandlerAssetBundle(requestURL, hash, crc); - } -#if UNITY_2020_3_OR_NEWER - _downloadhandler.autoLoadAssetBundle = false; -#endif - _webRequest.downloadHandler = _downloadhandler; - _webRequest.disposeDownloadHandlerOnDispose = true; - _webRequest.SendWebRequest(); - Status = ERequestStatus.InProgress; - } - public void Update() - { - if (Status == ERequestStatus.None) - return; - if (IsDone()) - return; - - DownloadProgress = _webRequest.downloadProgress; - DownloadedBytes = _webRequest.downloadedBytes; - if (_webRequest.isDone == false) - return; - - // 检查网络错误 -#if UNITY_2020_3_OR_NEWER - RequestHttpCode = _webRequest.responseCode; - if (_webRequest.result != UnityWebRequest.Result.Success) - { - RequestNetError = _webRequest.error; - Status = ERequestStatus.Error; - } - else - { - Status = ERequestStatus.Success; - } -#else - RequestHttpCode = _webRequest.responseCode; - if (_webRequest.isNetworkError || _webRequest.isHttpError) - { - RequestNetError = _webRequest.error; - Status = ERequestStatus.Error; - } - else - { - Status = ERequestStatus.Success; - } -#endif - - // 缓存加载的AssetBundle对象 - if (Status == ERequestStatus.Success) - { - if (_getAssetBundle) - { - _cacheAssetBundle = _downloadhandler.assetBundle; - if (_cacheAssetBundle == null) - { - RequestNetError = "assetBundle is null"; - Status = ERequestStatus.Error; - } - } - } - - // 最终释放下载器 - DisposeWebRequest(); - } - public void Abort() - { - // 如果下载任务还未开始 - if (Status == ERequestStatus.None) - { - RequestNetError = "user cancel"; - Status = ERequestStatus.Error; - } - else - { - // 注意:为了防止同一个文件强制停止之后立马创建新的请求,应该让进行中的请求自然终止。 - if (_webRequest != null) - { - if (_webRequest.isDone == false) - _webRequest.Abort(); // If in progress, halts the UnityWebRequest as soon as possible. - } - } - } - public bool IsDone() - { - if (Status == ERequestStatus.Success || Status == ERequestStatus.Error) - return true; - else - return false; - } - public object GetRequestObject() - { - return _cacheAssetBundle; - } - private void DisposeWebRequest() - { - if (_webRequest != null) - { - _webRequest.Dispose(); - _webRequest = null; - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/AssetBundleWebRequest.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Requester/AssetBundleWebRequest.cs.meta deleted file mode 100644 index 2c61d444..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/AssetBundleWebRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 34efa85440da15247b570a98b0971282 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileGeneralRequest.cs b/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileGeneralRequest.cs deleted file mode 100644 index 11d49f93..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileGeneralRequest.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System.IO; -using UnityEngine.Networking; - -namespace YooAsset -{ - internal class FileGeneralRequest : IWebRequester - { - private UnityWebRequest _webRequest; - - public ERequestStatus Status { private set; get; } = ERequestStatus.None; - public float DownloadProgress { private set; get; } - public ulong DownloadedBytes { private set; get; } - public string RequestNetError { private set; get; } - public long RequestHttpCode { private set; get; } - - public FileGeneralRequest() { } - public void Create(string requestURL, BundleInfo bundleInfo, params object[] args) - { - if (Status != ERequestStatus.None) - throw new System.Exception("Should never get here !"); - - string tempFilePath = bundleInfo.TempDataFilePath; - - // 删除临时文件 - if (File.Exists(tempFilePath)) - File.Delete(tempFilePath); - - // 创建下载器 - _webRequest = DownloadHelper.NewRequest(requestURL); - DownloadHandlerFile handler = new DownloadHandlerFile(tempFilePath); - handler.removeFileOnAbort = true; - _webRequest.downloadHandler = handler; - _webRequest.disposeDownloadHandlerOnDispose = true; - _webRequest.SendWebRequest(); - Status = ERequestStatus.InProgress; - } - public void Update() - { - if (Status == ERequestStatus.None) - return; - if (IsDone()) - return; - - DownloadProgress = _webRequest.downloadProgress; - DownloadedBytes = _webRequest.downloadedBytes; - if (_webRequest.isDone == false) - return; - - // 检查网络错误 -#if UNITY_2020_3_OR_NEWER - RequestHttpCode = _webRequest.responseCode; - if (_webRequest.result != UnityWebRequest.Result.Success) - { - RequestNetError = _webRequest.error; - Status = ERequestStatus.Error; - } - else - { - Status = ERequestStatus.Success; - } -#else - RequestHttpCode = _webRequest.responseCode; - if (_webRequest.isNetworkError || _webRequest.isHttpError) - { - RequestNetError = _webRequest.error; - Status = ERequestStatus.Error; - } - else - { - Status = ERequestStatus.Success; - } -#endif - - // 最终释放下载器 - DisposeWebRequest(); - } - public void Abort() - { - DisposeWebRequest(); - if (IsDone() == false) - { - RequestNetError = "user abort"; - RequestHttpCode = 0; - Status = ERequestStatus.Error; - } - } - public bool IsDone() - { - if (Status == ERequestStatus.Success || Status == ERequestStatus.Error) - return true; - else - return false; - } - public object GetRequestObject() - { - throw new System.NotImplementedException(); - } - private void DisposeWebRequest() - { - if (_webRequest != null) - { - //注意:引擎底层会自动调用Abort方法 - _webRequest.Dispose(); - _webRequest = null; - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileGeneralRequest.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileGeneralRequest.cs.meta deleted file mode 100644 index 10255323..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileGeneralRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b2f339136a4269343a3b5ab80450b889 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileResumeRequest.cs b/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileResumeRequest.cs deleted file mode 100644 index 0936a466..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileResumeRequest.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System.IO; -using UnityEngine.Networking; - -namespace YooAsset -{ - internal class FileResumeRequest : IWebRequester - { - private string _tempFilePath; - private UnityWebRequest _webRequest; - private DownloadHandlerFileRange _downloadHandle; - private ulong _fileOriginLength = 0; - - public ERequestStatus Status { private set; get; } = ERequestStatus.None; - public float DownloadProgress { private set; get; } - public ulong DownloadedBytes { private set; get; } - public string RequestNetError { private set; get; } - public long RequestHttpCode { private set; get; } - - public FileResumeRequest() { } - public void Create(string requestURL, BundleInfo bundleInfo, params object[] args) - { - if (Status != ERequestStatus.None) - throw new System.Exception("Should never get here !"); - - _tempFilePath = bundleInfo.TempDataFilePath; - long fileBytes = bundleInfo.Bundle.FileSize; - - // 获取下载的起始位置 - long fileLength = -1; - if (File.Exists(_tempFilePath)) - { - FileInfo fileInfo = new FileInfo(_tempFilePath); - fileLength = fileInfo.Length; - _fileOriginLength = (ulong)fileLength; - DownloadedBytes = _fileOriginLength; - } - - // 检测下载起始位置是否有效 - if (fileLength >= fileBytes) - { - if (File.Exists(_tempFilePath)) - File.Delete(_tempFilePath); - } - - // 创建下载器 - _webRequest = DownloadHelper.NewRequest(requestURL); -#if UNITY_2019_4_OR_NEWER - var handler = new DownloadHandlerFile(_tempFilePath, true); - handler.removeFileOnAbort = false; -#else - var handler = new DownloadHandlerFileRange(tempFilePath, _bundleInfo.Bundle.FileSize, _webRequest); - _downloadHandle = handler; -#endif - _webRequest.downloadHandler = handler; - _webRequest.disposeDownloadHandlerOnDispose = true; - if (fileLength > 0) - _webRequest.SetRequestHeader("Range", $"bytes={fileLength}-"); - _webRequest.SendWebRequest(); - Status = ERequestStatus.InProgress; - } - public void Update() - { - if (Status == ERequestStatus.None) - return; - if (IsDone()) - return; - - DownloadProgress = _webRequest.downloadProgress; - DownloadedBytes = _fileOriginLength + _webRequest.downloadedBytes; - if (_webRequest.isDone == false) - return; - - // 检查网络错误 -#if UNITY_2020_3_OR_NEWER - RequestHttpCode = _webRequest.responseCode; - if (_webRequest.result != UnityWebRequest.Result.Success) - { - RequestNetError = _webRequest.error; - Status = ERequestStatus.Error; - } - else - { - Status = ERequestStatus.Success; - } -#else - RequestHttpCode = _webRequest.responseCode; - if (_webRequest.isNetworkError || _webRequest.isHttpError) - { - RequestNetError = _webRequest.error; - Status = ERequestStatus.Error; - } - else - { - Status = ERequestStatus.Success; - } -#endif - - // 注意:下载断点续传文件发生特殊错误码之后删除文件 - if (Status == ERequestStatus.Error) - { - if (DownloadHelper.ClearFileResponseCodes != null) - { - if (DownloadHelper.ClearFileResponseCodes.Contains(RequestHttpCode)) - { - if (File.Exists(_tempFilePath)) - File.Delete(_tempFilePath); - } - } - } - - // 最终释放下载器 - DisposeWebRequest(); - } - public void Abort() - { - DisposeWebRequest(); - if (IsDone() == false) - { - RequestNetError = "user abort"; - RequestHttpCode = 0; - Status = ERequestStatus.Error; - } - } - public bool IsDone() - { - if (Status == ERequestStatus.Success || Status == ERequestStatus.Error) - return true; - else - return false; - } - public object GetRequestObject() - { - throw new System.NotImplementedException(); - } - private void DisposeWebRequest() - { - if (_downloadHandle != null) - { - _downloadHandle.Cleanup(); - _downloadHandle = null; - } - - if (_webRequest != null) - { - //注意:引擎底层会自动调用Abort方法 - _webRequest.Dispose(); - _webRequest = null; - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileResumeRequest.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileResumeRequest.cs.meta deleted file mode 100644 index df15a3be..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileResumeRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 816bf5396d7570e4ab28f1af407bc10f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/IWebRequester.cs b/Assets/YooAsset/Runtime/DownloadSystem/Requester/IWebRequester.cs deleted file mode 100644 index 1feeee4a..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/IWebRequester.cs +++ /dev/null @@ -1,65 +0,0 @@ - -namespace YooAsset -{ - internal enum ERequestStatus - { - None, - InProgress, - Error, - Success, - } - - internal interface IWebRequester - { - /// - /// 任务状态 - /// - ERequestStatus Status { get; } - - /// - /// 下载进度(0f~1f) - /// - float DownloadProgress { get; } - - /// - /// 已经下载的总字节数 - /// - ulong DownloadedBytes { get; } - - /// - /// 返回的网络错误 - /// - string RequestNetError { get; } - - /// - /// 返回的HTTP CODE - /// - long RequestHttpCode { get; } - - - /// - /// 创建任务 - /// - void Create(string url, BundleInfo bundleInfo, params object[] args); - - /// - /// 更新任务 - /// - void Update(); - - /// - /// 终止任务 - /// - void Abort(); - - /// - /// 是否已经完成(无论成功或失败) - /// - bool IsDone(); - - /// - /// 获取请求的对象 - /// - object GetRequestObject(); - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/IWebRequester.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Requester/IWebRequester.cs.meta deleted file mode 100644 index fffe1950..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/IWebRequester.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4d80b965d56870b43af1bf6943015914 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs deleted file mode 100644 index fb109dcf..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine.Networking; -using UnityEngine; - -namespace YooAsset -{ - internal class UnityWebDataRequester : UnityWebRequesterBase - { - /// - /// 发送GET请求 - /// - public void SendRequest(string url, int timeout = 60) - { - if (_webRequest == null) - { - URL = url; - ResetTimeout(timeout); - - _webRequest = DownloadHelper.NewRequest(URL); - DownloadHandlerBuffer handler = new DownloadHandlerBuffer(); - _webRequest.downloadHandler = handler; - _webRequest.disposeDownloadHandlerOnDispose = true; - _operationHandle = _webRequest.SendWebRequest(); - } - } - - /// - /// 获取下载的字节数据 - /// - public byte[] GetData() - { - if (_webRequest != null && IsDone()) - return _webRequest.downloadHandler.data; - else - return null; - } - - /// - /// 获取下载的文本数据 - /// - public string GetText() - { - if (_webRequest != null && IsDone()) - return _webRequest.downloadHandler.text; - else - return null; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs deleted file mode 100644 index 09e17459..00000000 --- a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine.Networking; -using UnityEngine; - -namespace YooAsset -{ - internal class UnityWebFileRequester : UnityWebRequesterBase - { - /// - /// 发送GET请求 - /// - public void SendRequest(string url, string fileSavePath, int timeout = 60) - { - if (_webRequest == null) - { - URL = url; - ResetTimeout(timeout); - - _webRequest = DownloadHelper.NewRequest(URL); - DownloadHandlerFile handler = new DownloadHandlerFile(fileSavePath); - handler.removeFileOnAbort = true; - _webRequest.downloadHandler = handler; - _webRequest.disposeDownloadHandlerOnDispose = true; - _operationHandle = _webRequest.SendWebRequest(); - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/RequestHelper.cs b/Assets/YooAsset/Runtime/DownloadSystem/WebRequestCounter.cs similarity index 96% rename from Assets/YooAsset/Runtime/DownloadSystem/RequestHelper.cs rename to Assets/YooAsset/Runtime/DownloadSystem/WebRequestCounter.cs index 3f99b6fc..0c962d91 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/RequestHelper.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/WebRequestCounter.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; namespace YooAsset { - public class RequestHelper + internal class WebRequestCounter { /// /// 记录网络请求失败事件的次数 diff --git a/Assets/YooAsset/Runtime/DownloadSystem/RequestHelper.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/WebRequestCounter.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/RequestHelper.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/WebRequestCounter.cs.meta diff --git a/Assets/YooAsset/Runtime/CacheSystem.meta b/Assets/YooAsset/Runtime/FileSystem.meta similarity index 77% rename from Assets/YooAsset/Runtime/CacheSystem.meta rename to Assets/YooAsset/Runtime/FileSystem.meta index 8a548d3b..95647683 100644 --- a/Assets/YooAsset/Runtime/CacheSystem.meta +++ b/Assets/YooAsset/Runtime/FileSystem.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 96a75a20111d6124696665e7aac3564c +guid: d7ac605758b151748980942c6d563fed folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem.meta similarity index 77% rename from Assets/YooAsset/Runtime/DownloadSystem/Downloader.meta rename to Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem.meta index 1b00904c..a1243696 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader.meta +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a82eeb6a47cd02c4cb38e851c8ed8784 +guid: 6f2f046660639e54cb2c40610189a91c folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs new file mode 100644 index 00000000..bc991a86 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace YooAsset +{ + /// + /// 内置资源清单目录 + /// + internal class DefaultBuildinFileCatalog : ScriptableObject + { + [Serializable] + public class FileWrapper + { + public string BundleGUID; + public string FileName; + + public FileWrapper(string bundleGUID, string fileName) + { + BundleGUID = bundleGUID; + FileName = fileName; + } + } + + /// + /// 包裹名称 + /// + public string PackageName; + + /// + /// 包裹版本 + /// + public string PackageVersion; + + /// + /// 文件列表 + /// + public List Wrappers = new List(); + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs.meta index 8d035ba8..36204b3a 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e4a97c06e069c1146a881fcb359f9b4b +guid: b05c83971e3dca94f9fa460d396385e5 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs new file mode 100644 index 00000000..84b7b4c9 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs @@ -0,0 +1,335 @@ +using System; +using System.IO; +using System.Collections.Generic; +using UnityEngine; + +namespace YooAsset +{ + /// + /// 内置文件系统 + /// + internal class DefaultBuildinFileSystem : IFileSystem + { + public class FileWrapper + { + public string FileName { private set; get; } + + public FileWrapper(string fileName) + { + FileName = fileName; + } + } + + protected readonly Dictionary _wrappers = new Dictionary(10000); + protected readonly Dictionary _loadedStream = new Dictionary(10000); + protected readonly Dictionary _buildinFilePaths = new Dictionary(10000); + protected string _packageRoot; + + /// + /// 解压文件系统 + /// + public IFileSystem UnpackFileSystem { private set; get; } + + + /// + /// 包裹名称 + /// + public string PackageName { private set; get; } + + /// + /// 文件访问权限 + /// + public EFileAccess FileSystemAccess + { + get + { + return EFileAccess.Read; + } + } + + /// + /// 文件根目录 + /// + public string FileRoot + { + get + { + return _packageRoot; + } + } + + /// + /// 文件数量 + /// + public int FileCount + { + get + { + return _wrappers.Count; + } + } + + #region 自定义参数 + /// + /// 自定义参数:初始化的时候缓存文件校验级别 + /// + public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle; + + /// + /// 自定义参数:数据文件追加文件格式 + /// + public bool AppendFileExtension { private set; get; } = false; + + /// + /// 自定义参数:原生文件构建管线 + /// + public bool RawFileBuildPipeline { private set; get; } = false; + #endregion + + + public DefaultBuildinFileSystem() + { + } + public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + { +#if UNITY_EDITOR + var operation = new DBFSInitializeInEditorPlayModeOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; +#else + var operation = new DBFSInitializeOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; +#endif + } + public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(params object[] args) + { + var operation = new DBFSLoadPackageManifestOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(params object[] args) + { + throw new System.NotImplementedException(); + } + public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync(params object[] args) + { + var operation = new DBFSClearAllBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(params object[] args) + { + PackageManifest manifest = args[0] as PackageManifest; + var operation = new DBFSClearUnusedBundleFilesOperation(this, manifest); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSDownloadFileOperation DownloadFileAsync(params object[] args) + { + PackageBundle bundle = args[0] as PackageBundle; + int failedTryAgain = (int)args[2]; + int timeout = (int)args[3]; + + string buidlinFilePath = GetBuildinFileLoadPath(bundle); + return UnpackFileSystem.DownloadFileAsync(bundle, buidlinFilePath, failedTryAgain, timeout); + } + + public virtual void SetParameter(string name, object value) + { + if (name == "FILE_VERIFY_LEVEL") + { + FileVerifyLevel = (EFileVerifyLevel)value; + } + else if (name == "APPEND_FILE_EXTENSION") + { + AppendFileExtension = (bool)value; + } + else if (name == "RAW_FILE_BUILD_PIPELINE") + { + RawFileBuildPipeline = (bool)value; + } + else + { + YooLogger.Warning($"Invalid parameter : {name}"); + } + } + public virtual void OnCreate(string packageName, string rootDirectory) + { + PackageName = packageName; + + if (string.IsNullOrEmpty(rootDirectory)) + rootDirectory = GetDefaultRoot(); + + _packageRoot = PathUtility.Combine(rootDirectory, packageName); + + // 创建解压文件系统 + UnpackFileSystem = new DefaultUnpackFileSystem(); + UnpackFileSystem.SetParameter("FILE_VERIFY_LEVEL", FileVerifyLevel); + UnpackFileSystem.SetParameter("APPEND_FILE_EXTENSION", AppendFileExtension); + UnpackFileSystem.SetParameter("RAW_FILE_BUILD_PIPELINE", RawFileBuildPipeline); + UnpackFileSystem.OnCreate(packageName, null); + } + public virtual void OnUpdate() + { + } + + public virtual bool Belong(PackageBundle bundle) + { + return _wrappers.ContainsKey(bundle.BundleGUID); + } + public virtual bool Belong(string bundleGUID) + { + return _wrappers.ContainsKey(bundleGUID); + } + public virtual bool Exists(PackageBundle bundle) + { + return _wrappers.ContainsKey(bundle.BundleGUID); + } + public virtual bool Exists(string bundleGUID) + { + return _wrappers.ContainsKey(bundleGUID); + } + + public virtual bool CheckNeedDownload(PackageBundle bundle) + { + return false; + } + public virtual bool CheckNeedUnpack(PackageBundle bundle) + { + if (Belong(bundle) == false) + return false; + +#if UNITY_ANDROID + return RawFileBuildPipeline || bundle.Encrypted; +#else + return false; +#endif + } + public virtual bool CheckNeedImport(PackageBundle bundle) + { + return false; + } + + public virtual bool WriteFile(PackageBundle bundle, string copyPath) + { + return UnpackFileSystem.WriteFile(bundle, copyPath); + } + public virtual bool DeleteFile(PackageBundle bundle) + { + return UnpackFileSystem.DeleteFile(bundle); + } + public virtual bool DeleteFile(string bundleGUID) + { + return UnpackFileSystem.DeleteFile(bundleGUID); + } + public virtual EFileVerifyResult VerifyFile(PackageBundle bundle) + { + return UnpackFileSystem.VerifyFile(bundle); + } + + public virtual byte[] ReadFileBytes(PackageBundle bundle) + { + return UnpackFileSystem.ReadFileBytes(bundle); + } + public virtual string ReadFileText(PackageBundle bundle) + { + return UnpackFileSystem.ReadFileText(bundle); + } + + public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + { + if (RawFileBuildPipeline) + { + var operation = new DBFSLoadRawBundleOperation(this, bundle); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + else + { + var operation = new DBFSLoadAssetBundleOperation(this, bundle); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + } + public virtual void UnloadBundleFile(PackageBundle bundle, object result) + { + AssetBundle assetBundle = result as AssetBundle; + if (assetBundle == null) + return; + + if (UnpackFileSystem.Exists(bundle)) + { + UnpackFileSystem.UnloadBundleFile(bundle, assetBundle); + } + else + { + if (assetBundle != null) + assetBundle.Unload(true); + + if (_loadedStream.TryGetValue(bundle.BundleGUID, out Stream managedStream)) + { + managedStream.Close(); + managedStream.Dispose(); + _loadedStream.Remove(bundle.BundleGUID); + } + } + } + + #region 内部方法 + protected string GetDefaultRoot() + { + string path = PathUtility.Combine(UnityEngine.Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName); +#if UNITY_OPENHARMONY + return $"file://{path}"; +#else + return path; +#endif + } + public string GetBuildinFileLoadPath(PackageBundle bundle) + { + if (_buildinFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false) + { + filePath = PathUtility.Combine(_packageRoot, bundle.FileName); + _buildinFilePaths.Add(bundle.BundleGUID, filePath); + } + return filePath; + } + public string GetBuildinCatalogFileLoadPath() + { + string fileName = Path.GetFileNameWithoutExtension(DefaultBuildinFileSystemDefine.BuildinCatalogFileName); + return PathUtility.Combine(YooAssetSettingsData.Setting.DefaultYooFolderName, PackageName, fileName); + } + public string GetBuildinPackageVersionFilePath() + { + string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName); + return PathUtility.Combine(FileRoot, fileName); + } + public string GetBuildinPackageHashFilePath(string packageVersion) + { + string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion); + return PathUtility.Combine(FileRoot, fileName); + } + public string GetBuildinPackageManifestFilePath(string packageVersion) + { + string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion); + return PathUtility.Combine(FileRoot, fileName); + } + + /// + /// 记录缓存信息 + /// + public bool Record(string bundleGUID, FileWrapper wrapper) + { + if (_wrappers.ContainsKey(bundleGUID)) + { + YooLogger.Error($"{nameof(DefaultBuildinFileSystem)} has element : {bundleGUID}"); + return false; + } + + _wrappers.Add(bundleGUID, wrapper); + return true; + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheManager.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/CacheSystem/CacheManager.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs.meta index 54c9bad7..cfdf8446 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/CacheManager.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 08f3e92fdbd5d56459d8882be1f54f60 +guid: 98465b987635afc479022ec358477491 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemBuild.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemBuild.cs new file mode 100644 index 00000000..720983df --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemBuild.cs @@ -0,0 +1,114 @@ +#if UNITY_EDITOR +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +namespace YooAsset +{ + internal class DefaultBuildinFileSystemBuild : UnityEditor.Build.IPreprocessBuildWithReport + { + public int callbackOrder { get { return 0; } } + + /// + /// 在构建应用程序前自动生成内置资源清单。 + /// 原理:搜索StreamingAssets目录下的所有资源文件,然后将这些文件信息写入内置资源清单,并存储在Resources目录下。 + /// + public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report) + { + string savePath = $"Assets/Resources/{YooAssetSettingsData.Setting.DefaultYooFolderName}"; + DirectoryInfo saveDirectory = new DirectoryInfo(savePath); + if (saveDirectory.Exists) + saveDirectory.Delete(true); + + string rootPath = $"{Application.dataPath}/StreamingAssets/{YooAssetSettingsData.Setting.DefaultYooFolderName}"; + DirectoryInfo rootDirectory = new DirectoryInfo(rootPath); + if (rootDirectory.Exists == false) + { + Debug.LogWarning($"Not found buildin root folder : {rootPath}"); + return; + } + + // 搜索所有Package目录 + DirectoryInfo[] subDirectories = rootDirectory.GetDirectories(); + foreach (var subDirectory in subDirectories) + { + CreateBuildinManifest(subDirectory.Name, subDirectory.FullName); + } + } + private void CreateBuildinManifest(string packageName, string pacakgeDirectory) + { + // 获取资源清单版本 + string packageVersion; + { + string versionFileName = YooAssetSettingsData.GetPackageVersionFileName(packageName); + string versionFilePath = $"{pacakgeDirectory}/{versionFileName}"; + if (File.Exists(versionFilePath) == false) + { + Debug.LogWarning($"Not found package version file : {versionFilePath}"); + return; + } + + packageVersion = FileUtility.ReadAllText(versionFilePath); + } + + // 加载资源清单文件 + PackageManifest packageManifest; + { + string manifestFileName = YooAssetSettingsData.GetManifestBinaryFileName(packageName, packageVersion); + string manifestFilePath = $"{pacakgeDirectory}/{manifestFileName}"; + if (File.Exists(manifestFilePath) == false) + { + Debug.LogWarning($"Not found package manifest file : {manifestFilePath}"); + return; + } + + var binaryData = FileUtility.ReadAllBytes(manifestFilePath); + packageManifest = ManifestTools.DeserializeFromBinary(binaryData); + } + + // 获取文件名映射关系 + Dictionary fileMapping = new Dictionary(); + { + foreach (var packageBundle in packageManifest.BundleList) + { + fileMapping.Add(packageBundle.FileName, packageBundle.BundleGUID); + } + } + + // 创建内置清单实例 + var buildinFileCatalog = ScriptableObject.CreateInstance(); + buildinFileCatalog.PackageName = packageName; + buildinFileCatalog.PackageVersion = packageVersion; + + // 记录所有内置资源文件 + DirectoryInfo rootDirectory = new DirectoryInfo(pacakgeDirectory); + FileInfo[] fileInfos = rootDirectory.GetFiles(); + foreach (var fileInfo in fileInfos) + { + if (fileInfo.Extension == ".meta" || fileInfo.Extension == ".version" || + fileInfo.Extension == ".hash" || fileInfo.Extension == ".bytes") + continue; + + string fileName = fileInfo.Name; + if (fileMapping.TryGetValue(fileName, out string bundleGUID)) + { + var wrapper = new DefaultBuildinFileCatalog.FileWrapper(bundleGUID, fileName); + buildinFileCatalog.Wrappers.Add(wrapper); + } + else + { + Debug.LogWarning($"Failed mapping file : {fileName}"); + } + } + + string saveFilePath = $"Assets/Resources/{YooAssetSettingsData.Setting.DefaultYooFolderName}/{packageName}/{DefaultBuildinFileSystemDefine.BuildinCatalogFileName}"; + FileUtility.CreateFileDirectory(saveFilePath); + + UnityEditor.AssetDatabase.CreateAsset(buildinFileCatalog, saveFilePath); + UnityEditor.AssetDatabase.SaveAssets(); + UnityEditor.AssetDatabase.Refresh(); + Debug.Log($"一共记录{buildinFileCatalog.Wrappers.Count}个内置资源文件,内置资源目录文件保存成功 : {saveFilePath}"); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemBuild.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemBuild.cs.meta new file mode 100644 index 00000000..5400d792 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemBuild.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6b5abe115ebfe1344b674db78b2edf6c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs new file mode 100644 index 00000000..876e01d2 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs @@ -0,0 +1,11 @@ + +namespace YooAsset +{ + internal class DefaultBuildinFileSystemDefine + { + /// + /// 内置清单文件名称 + /// + public const string BuildinCatalogFileName = "BuildinCatalog.asset"; + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs.meta new file mode 100644 index 00000000..a0860a97 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4aa038f71ffd2394abc5daee917fbc66 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation.meta new file mode 100644 index 00000000..cb776399 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 06f6a75331ed07a4a9e5e8f46dcf157e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearAllBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearAllBundleFilesOperation.cs new file mode 100644 index 00000000..b6ad4b3d --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearAllBundleFilesOperation.cs @@ -0,0 +1,45 @@ + +namespace YooAsset +{ + internal sealed class DBFSClearAllBundleFilesOperation : FSClearAllBundleFilesOperation + { + private enum ESteps + { + None, + ClearUnpackFileSystem, + Done, + } + + private readonly DefaultBuildinFileSystem _fileSystem; + private FSClearAllBundleFilesOperation _unpackClearAllBundleFilesOp; + private ESteps _steps = ESteps.None; + + internal DBFSClearAllBundleFilesOperation(DefaultBuildinFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + _steps = ESteps.ClearUnpackFileSystem; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearUnpackFileSystem) + { + if (_unpackClearAllBundleFilesOp == null) + _unpackClearAllBundleFilesOp = _fileSystem.UnpackFileSystem.ClearAllBundleFilesAsync(); + + Progress = _unpackClearAllBundleFilesOp.Progress; + if (_unpackClearAllBundleFilesOp.IsDone == false) + return; + + _steps = ESteps.Done; + Status = _unpackClearAllBundleFilesOp.Status; + Error = _unpackClearAllBundleFilesOp.Error; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearAllBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearAllBundleFilesOperation.cs.meta new file mode 100644 index 00000000..8c0b9743 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearAllBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 624ca0ff2f0c7da4bb9c1a1d58e732b1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearUnusedBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearUnusedBundleFilesOperation.cs new file mode 100644 index 00000000..13263b0d --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearUnusedBundleFilesOperation.cs @@ -0,0 +1,47 @@ + +namespace YooAsset +{ + internal sealed class DBFSClearUnusedBundleFilesOperation : FSClearUnusedBundleFilesOperation + { + private enum ESteps + { + None, + ClearUnpackFileSystem, + Done, + } + + private readonly DefaultBuildinFileSystem _fileSystem; + private readonly PackageManifest _manifest; + private FSClearUnusedBundleFilesOperation _unpackClearUnusedBundleFilesOp; + private ESteps _steps = ESteps.None; + + internal DBFSClearUnusedBundleFilesOperation(DefaultBuildinFileSystem fileSystem, PackageManifest manifest) + { + _fileSystem = fileSystem; + _manifest = manifest; + } + internal override void InternalOnStart() + { + _steps = ESteps.ClearUnpackFileSystem; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearUnpackFileSystem) + { + if (_unpackClearUnusedBundleFilesOp == null) + _unpackClearUnusedBundleFilesOp = _fileSystem.UnpackFileSystem.ClearUnusedBundleFilesAsync(_manifest); + + Progress = _unpackClearUnusedBundleFilesOp.Progress; + if (_unpackClearUnusedBundleFilesOp.IsDone == false) + return; + + _steps = ESteps.Done; + Status = _unpackClearUnusedBundleFilesOp.Status; + Error = _unpackClearUnusedBundleFilesOp.Error; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearUnusedBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearUnusedBundleFilesOperation.cs.meta new file mode 100644 index 00000000..07c57ba4 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearUnusedBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e0e1c080b28b3c45b401da4ac06f687 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs new file mode 100644 index 00000000..2e6f3926 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs @@ -0,0 +1,186 @@ +using System; +using System.IO; + +namespace YooAsset +{ + internal class DBFSInitializeOperation : FSInitializeFileSystemOperation + { + private enum ESteps + { + None, + InitUnpackFileSystem, + LoadCatalogFile, + Done, + } + + private readonly DefaultBuildinFileSystem _fileSystem; + private FSInitializeFileSystemOperation _initUnpackFIleSystemOp; + private LoadBuildinCatalogFileOperation _loadCatalogFileOp; + private ESteps _steps = ESteps.None; + + internal DBFSInitializeOperation(DefaultBuildinFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + _steps = ESteps.InitUnpackFileSystem; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.InitUnpackFileSystem) + { + if (_initUnpackFIleSystemOp == null) + _initUnpackFIleSystemOp = _fileSystem.UnpackFileSystem.InitializeFileSystemAsync(); + + Progress = _initUnpackFIleSystemOp.Progress; + if (_initUnpackFIleSystemOp.IsDone == false) + return; + + if (_initUnpackFIleSystemOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadCatalogFile; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _initUnpackFIleSystemOp.Error; + } + } + + if (_steps == ESteps.LoadCatalogFile) + { + if (_loadCatalogFileOp == null) + { + _loadCatalogFileOp = new LoadBuildinCatalogFileOperation(_fileSystem); + OperationSystem.StartOperation(_fileSystem.PackageName, _loadCatalogFileOp); + } + + if (_loadCatalogFileOp.IsDone == false) + return; + + if (_loadCatalogFileOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadCatalogFileOp.Error; + } + } + } + } + + /// + /// 在编辑器下离线模式的兼容性初始化 + /// + internal sealed class DBFSInitializeInEditorPlayModeOperation : FSInitializeFileSystemOperation + { + private enum ESteps + { + None, + InitUnpackFileSystem, + LoadPackageManifest, + RecordFiles, + Done, + } + + private readonly DefaultBuildinFileSystem _fileSystem; + private FSInitializeFileSystemOperation _initUnpackFIleSystemOp; + private DBFSLoadPackageManifestOperation _loadPackageManifestOp; + private ESteps _steps = ESteps.None; + + internal DBFSInitializeInEditorPlayModeOperation(DefaultBuildinFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + _steps = ESteps.InitUnpackFileSystem; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.InitUnpackFileSystem) + { + if (_initUnpackFIleSystemOp == null) + _initUnpackFIleSystemOp = _fileSystem.UnpackFileSystem.InitializeFileSystemAsync(); + + Progress = _initUnpackFIleSystemOp.Progress; + if (_initUnpackFIleSystemOp.IsDone == false) + return; + + if (_initUnpackFIleSystemOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadPackageManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _initUnpackFIleSystemOp.Error; + } + } + + if (_steps == ESteps.LoadPackageManifest) + { + if (_loadPackageManifestOp == null) + { + _loadPackageManifestOp = new DBFSLoadPackageManifestOperation(_fileSystem); + OperationSystem.StartOperation(_fileSystem.PackageName, _loadPackageManifestOp); + } + + if (_loadPackageManifestOp.IsDone == false) + return; + + if (_loadPackageManifestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.RecordFiles; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadPackageManifestOp.Error; + } + } + + if (_steps == ESteps.RecordFiles) + { + PackageManifest manifest = _loadPackageManifestOp.Result; + string pacakgeDirectory = _fileSystem.FileRoot; + DirectoryInfo rootDirectory = new DirectoryInfo(pacakgeDirectory); + FileInfo[] fileInfos = rootDirectory.GetFiles(); + foreach (var fileInfo in fileInfos) + { + if (fileInfo.Extension == ".meta" || fileInfo.Extension == ".version" || + fileInfo.Extension == ".hash" || fileInfo.Extension == ".bytes") + continue; + + string fileName = fileInfo.Name; + if (manifest.TryGetPackageBundleByFileName(fileName, out PackageBundle value)) + { + var fileWrapper = new DefaultBuildinFileSystem.FileWrapper(fileName); + _fileSystem.Record(value.BundleGUID, fileWrapper); + } + else + { + YooLogger.Warning($"Failed mapping file : {fileName}"); + } + } + + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs.meta new file mode 100644 index 00000000..082f0edd --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a15804d2ba6172a4b91f6c17245495a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs new file mode 100644 index 00000000..75e50424 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs @@ -0,0 +1,334 @@ +using System.IO; +using UnityEngine; + +namespace YooAsset +{ + internal class DBFSLoadAssetBundleOperation : FSLoadBundleOperation + { + private enum ESteps + { + None, + UnpackAssetBundleFile, + LoadUnpackAssetBundle, + LoadBuidlinAssetBundle, + CheckLoadBuildinResult, + Done, + } + + private readonly DefaultBuildinFileSystem _fileSystem; + private readonly PackageBundle _bundle; + private FSLoadBundleOperation _loadUnpackBundleOp; + private FSDownloadFileOperation _unpackBundleOp; + private AssetBundleCreateRequest _createRequest; + private bool _isWaitForAsyncComplete = false; + private ESteps _steps = ESteps.None; + + + internal DBFSLoadAssetBundleOperation(DefaultBuildinFileSystem fileSystem, PackageBundle bundle) + { + _fileSystem = fileSystem; + _bundle = bundle; + } + internal override void InternalOnStart() + { + DownloadProgress = 1f; + DownloadedBytes = _bundle.FileSize; + + if (_fileSystem.CheckNeedUnpack(_bundle)) + { + _steps = ESteps.UnpackAssetBundleFile; + } + else + { + _steps = ESteps.LoadBuidlinAssetBundle; + } + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.UnpackAssetBundleFile) + { + if (_unpackBundleOp == null) + { + int failedTryAgain = 0; + int timeout = int.MaxValue; + _unpackBundleOp = _fileSystem.DownloadFileAsync(_bundle, null, failedTryAgain, timeout); + } + + if (_unpackBundleOp.IsDone == false) + return; + + if (_unpackBundleOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadUnpackAssetBundle; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _unpackBundleOp.Error; + } + } + + if (_steps == ESteps.LoadUnpackAssetBundle) + { + if (_loadUnpackBundleOp == null) + _loadUnpackBundleOp = _fileSystem.UnpackFileSystem.LoadBundleFile(_bundle); + + if (_loadUnpackBundleOp.IsDone == false) + return; + + if (_loadUnpackBundleOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Result = _loadUnpackBundleOp.Result; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadUnpackBundleOp.Error; + } + } + + if (_steps == ESteps.LoadBuidlinAssetBundle) + { + string filePath = _fileSystem.GetBuildinFileLoadPath(_bundle); + if (_isWaitForAsyncComplete) + { + Result = AssetBundle.LoadFromFile(filePath); + } + else + { + _createRequest = AssetBundle.LoadFromFileAsync(filePath); + } + _steps = ESteps.CheckLoadBuildinResult; + } + + if (_steps == ESteps.CheckLoadBuildinResult) + { + if (_createRequest != null) + { + if (_isWaitForAsyncComplete) + { + // 强制挂起主线程(注意:该操作会很耗时) + YooLogger.Warning("Suspend the main thread to load unity bundle."); + Result = _createRequest.assetBundle; + } + else + { + if (_createRequest.isDone == false) + return; + Result = _createRequest.assetBundle; + } + } + + if (Result != null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load buildin asset bundle file : {_bundle.BundleName}"; + } + } + } + + public override void WaitForAsyncComplete() + { + _isWaitForAsyncComplete = true; + + while (true) + { + if (_unpackBundleOp != null) + { + if (_unpackBundleOp.IsDone == false) + _unpackBundleOp.WaitForAsyncComplete(); + } + + if (_loadUnpackBundleOp != null) + { + if (_loadUnpackBundleOp.IsDone == false) + _loadUnpackBundleOp.WaitForAsyncComplete(); + } + + // 驱动流程 + InternalOnUpdate(); + + // 完成后退出 + if (IsDone) + break; + } + } + public override void AbortDownloadOperation() + { + if (_steps == ESteps.UnpackAssetBundleFile) + { + if (_unpackBundleOp != null) + _unpackBundleOp.SetAbort(); + } + } + } + + internal class DBFSLoadRawBundleOperation : FSLoadBundleOperation + { + private enum ESteps + { + None, + UnpackRawBundleFile, + LoadUnpackRawBundle, + LoadBuildinRawBundle, + CheckLoadBuildinResult, + Done, + } + + private readonly DefaultBuildinFileSystem _fileSystem; + private readonly PackageBundle _bundle; + private FSLoadBundleOperation _loadUnpackBundleOp; + private FSDownloadFileOperation _unpackBundleOp; + private ESteps _steps = ESteps.None; + + + internal DBFSLoadRawBundleOperation(DefaultBuildinFileSystem fileSystem, PackageBundle bundle) + { + _fileSystem = fileSystem; + _bundle = bundle; + } + internal override void InternalOnStart() + { + DownloadProgress = 1f; + DownloadedBytes = _bundle.FileSize; + + if (_fileSystem.CheckNeedUnpack(_bundle)) + { + _steps = ESteps.UnpackRawBundleFile; + } + else + { + _steps = ESteps.LoadBuildinRawBundle; + } + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.UnpackRawBundleFile) + { + if (_unpackBundleOp == null) + { + int failedTryAgain = 0; + int timeout = int.MaxValue; + _unpackBundleOp = _fileSystem.DownloadFileAsync(_bundle, null, failedTryAgain, timeout); + } + + if (_unpackBundleOp.IsDone == false) + return; + + if (_unpackBundleOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadUnpackRawBundle; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _unpackBundleOp.Error; + } + } + + if (_steps == ESteps.LoadUnpackRawBundle) + { + if (_loadUnpackBundleOp == null) + _loadUnpackBundleOp = _fileSystem.UnpackFileSystem.LoadBundleFile(_bundle); + + if (_loadUnpackBundleOp.IsDone == false) + return; + + if (_loadUnpackBundleOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Result = _loadUnpackBundleOp.Result; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadUnpackBundleOp.Error; + } + } + + if (_steps == ESteps.LoadBuildinRawBundle) + { + string filePath = _fileSystem.GetBuildinFileLoadPath(_bundle); + Result = filePath; + _steps = ESteps.CheckLoadBuildinResult; + } + + if (_steps == ESteps.CheckLoadBuildinResult) + { + if (Result != null) + { + string filePath = Result as string; + if (File.Exists(filePath)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Can not found buildin raw bundle file : {filePath}"; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load buildin raw bundle file : {_bundle.BundleName}"; + } + } + } + + public override void WaitForAsyncComplete() + { + while (true) + { + if (_unpackBundleOp != null) + { + if (_unpackBundleOp.IsDone == false) + _unpackBundleOp.WaitForAsyncComplete(); + } + + if (_loadUnpackBundleOp != null) + { + if (_loadUnpackBundleOp.IsDone == false) + _loadUnpackBundleOp.WaitForAsyncComplete(); + } + + // 驱动流程 + InternalOnUpdate(); + + // 完成后退出 + if (IsDone) + break; + } + } + public override void AbortDownloadOperation() + { + if (_steps == ESteps.UnpackRawBundleFile) + { + if (_unpackBundleOp != null) + _unpackBundleOp.SetAbort(); + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs.meta new file mode 100644 index 00000000..e1546aa9 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 99fc95c784d960c45ba9373f31fbc7fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs new file mode 100644 index 00000000..37772c68 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs @@ -0,0 +1,110 @@ + +namespace YooAsset +{ + internal class DBFSLoadPackageManifestOperation : FSLoadPackageManifestOperation + { + private enum ESteps + { + None, + RequestBuildinPackageVersion, + RequestBuildinPackageHash, + LoadBuildinPackageManifest, + Done, + } + + private readonly DefaultBuildinFileSystem _fileSystem; + private RequestBuildinPackageVersionOperation _requestBuildinPackageVersionOp; + private RequestBuildinPackageHashOperation _requestBuildinPackageHashOp; + private LoadBuildinPackageManifestOperation _loadBuildinPackageManifestOp; + private ESteps _steps = ESteps.None; + + + public DBFSLoadPackageManifestOperation(DefaultBuildinFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + _steps = ESteps.RequestBuildinPackageVersion; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestBuildinPackageVersion) + { + if (_requestBuildinPackageVersionOp == null) + { + _requestBuildinPackageVersionOp = new RequestBuildinPackageVersionOperation(_fileSystem); + OperationSystem.StartOperation(_fileSystem.PackageName, _requestBuildinPackageVersionOp); + } + + if (_requestBuildinPackageVersionOp.IsDone == false) + return; + + if (_requestBuildinPackageVersionOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.RequestBuildinPackageHash; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _requestBuildinPackageVersionOp.Error; + } + } + + if (_steps == ESteps.RequestBuildinPackageHash) + { + if (_requestBuildinPackageHashOp == null) + { + string packageVersion = _requestBuildinPackageVersionOp.PackageVersion; + _requestBuildinPackageHashOp = new RequestBuildinPackageHashOperation(_fileSystem, packageVersion); + OperationSystem.StartOperation(_fileSystem.PackageName, _requestBuildinPackageHashOp); + } + + if (_requestBuildinPackageHashOp.IsDone == false) + return; + + if (_requestBuildinPackageHashOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadBuildinPackageManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _requestBuildinPackageHashOp.Error; + } + } + + if (_steps == ESteps.LoadBuildinPackageManifest) + { + if (_loadBuildinPackageManifestOp == null) + { + string packageVersion = _requestBuildinPackageVersionOp.PackageVersion; + string packageHash = _requestBuildinPackageHashOp.PackageHash; + _loadBuildinPackageManifestOp = new LoadBuildinPackageManifestOperation(_fileSystem, packageVersion, packageHash); + OperationSystem.StartOperation(_fileSystem.PackageName, _loadBuildinPackageManifestOp); + } + + if (_loadBuildinPackageManifestOp.IsDone == false) + return; + + if (_loadBuildinPackageManifestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Result = _loadBuildinPackageManifestOp.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadBuildinPackageManifestOp.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs.meta new file mode 100644 index 00000000..f5b0c30b --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b55b3624add2db6489954d999b13a9ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal.meta new file mode 100644 index 00000000..cf359da8 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: be1c19353672bb34ca3e4ddcb462402f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs new file mode 100644 index 00000000..92247a38 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs @@ -0,0 +1,63 @@ +using UnityEngine; + +namespace YooAsset +{ + internal sealed class LoadBuildinCatalogFileOperation : AsyncOperationBase + { + private enum ESteps + { + None, + LoadCatalog, + Done, + } + + private readonly DefaultBuildinFileSystem _fileSystem; + private ESteps _steps = ESteps.None; + + + internal LoadBuildinCatalogFileOperation(DefaultBuildinFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + _steps = ESteps.LoadCatalog; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadCatalog) + { + string catalogFilePath = _fileSystem.GetBuildinCatalogFileLoadPath(); + var catalog = Resources.Load(catalogFilePath); + if (catalog == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load catalog file : {catalogFilePath}"; + return; + } + + if (catalog.PackageName != _fileSystem.PackageName) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"The catalog file package name {catalog.PackageName} cannot match the file system package name {_fileSystem.PackageName}"; + return; + } + + foreach (var wrapper in catalog.Wrappers) + { + var fileWrapper = new DefaultBuildinFileSystem.FileWrapper(wrapper.FileName); + _fileSystem.Record(wrapper.BundleGUID, fileWrapper); + } + + YooLogger.Log($"Package '{_fileSystem.PackageName}' catalog files count : {catalog.Wrappers.Count}"); + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs.meta new file mode 100644 index 00000000..365df095 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a4113df346bbd1b4ead918b52ac46f55 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs new file mode 100644 index 00000000..555c6948 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs @@ -0,0 +1,110 @@ + +namespace YooAsset +{ + internal class LoadBuildinPackageManifestOperation : AsyncOperationBase + { + private enum ESteps + { + None, + RequestFileData, + VerifyFileData, + LoadManifest, + Done, + } + + private readonly DefaultBuildinFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly string _packageHash; + private UnityWebDataRequestOperation _webDataRequestOp; + private DeserializeManifestOperation _deserializer; + private ESteps _steps = ESteps.None; + + /// + /// 加载的清单实例 + /// + public PackageManifest Manifest { private set; get; } + + + internal LoadBuildinPackageManifestOperation(DefaultBuildinFileSystem fileSystem, string packageVersion, string packageHash) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _packageHash = packageHash; + } + internal override void InternalOnStart() + { + _steps = ESteps.RequestFileData; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestFileData) + { + if (_webDataRequestOp == null) + { + string filePath = _fileSystem.GetBuildinPackageManifestFilePath(_packageVersion); + string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + _webDataRequestOp = new UnityWebDataRequestOperation(url); + OperationSystem.StartOperation(_fileSystem.PackageName, _webDataRequestOp); + } + + if (_webDataRequestOp.IsDone == false) + return; + + if (_webDataRequestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.VerifyFileData; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webDataRequestOp.Error; + } + } + + if (_steps == ESteps.VerifyFileData) + { + string fileHash = HashUtility.BytesMD5(_webDataRequestOp.Result); + if (fileHash == _packageHash) + { + _steps = ESteps.LoadManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Failed to verify buildin package manifest file!"; + } + } + + if (_steps == ESteps.LoadManifest) + { + if (_deserializer == null) + { + _deserializer = new DeserializeManifestOperation(_webDataRequestOp.Result); + OperationSystem.StartOperation(_fileSystem.PackageName, _deserializer); + } + + Progress = _deserializer.Progress; + if (_deserializer.IsDone == false) + return; + + if (_deserializer.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Manifest = _deserializer.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _deserializer.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs.meta new file mode 100644 index 00000000..750e80dc --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8af9b72837c6a01428ee627011f4341b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs new file mode 100644 index 00000000..661f118d --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs @@ -0,0 +1,75 @@ + +namespace YooAsset +{ + internal class RequestBuildinPackageHashOperation : AsyncOperationBase + { + private enum ESteps + { + None, + RequestPackageHash, + Done, + } + + private readonly DefaultBuildinFileSystem _fileSystem; + private readonly string _packageVersion; + private UnityWebTextRequestOperation _webTextRequestOp; + private ESteps _steps = ESteps.None; + + /// + /// 包裹哈希值 + /// + public string PackageHash { private set; get; } + + + internal RequestBuildinPackageHashOperation(DefaultBuildinFileSystem fileSystem, string packageVersion) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + } + internal override void InternalOnStart() + { + _steps = ESteps.RequestPackageHash; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestPackageHash) + { + if (_webTextRequestOp == null) + { + string filePath = _fileSystem.GetBuildinPackageHashFilePath(_packageVersion); + string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + _webTextRequestOp = new UnityWebTextRequestOperation(url); + OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp); + } + + if (_webTextRequestOp.IsDone == false) + return; + + if (_webTextRequestOp.Status == EOperationStatus.Succeed) + { + PackageHash = _webTextRequestOp.Result; + if (string.IsNullOrEmpty(PackageHash)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Buildin package hash file content is empty !"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webTextRequestOp.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs.meta new file mode 100644 index 00000000..36f56cbc --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2084625d8253164aa71ef934e0690fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryBuildinPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs similarity index 54% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryBuildinPackageVersionOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs index b072b0cf..3b8b582f 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryBuildinPackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs @@ -1,17 +1,17 @@  namespace YooAsset { - internal class QueryBuildinPackageVersionOperation : AsyncOperationBase + internal class RequestBuildinPackageVersionOperation : AsyncOperationBase { private enum ESteps { None, - LoadBuildinPackageVersionFile, + RequestPackageVersion, Done, } - private readonly PersistentManager _persistent; - private UnityWebDataRequester _downloader; + private readonly DefaultBuildinFileSystem _fileSystem; + private UnityWebTextRequestOperation _webTextRequestOp; private ESteps _steps = ESteps.None; /// @@ -20,41 +20,35 @@ namespace YooAsset public string PackageVersion { private set; get; } - public QueryBuildinPackageVersionOperation(PersistentManager persistent) + internal RequestBuildinPackageVersionOperation(DefaultBuildinFileSystem fileSystem) { - _persistent = persistent; + _fileSystem = fileSystem; } internal override void InternalOnStart() { - _steps = ESteps.LoadBuildinPackageVersionFile; + _steps = ESteps.RequestPackageVersion; } internal override void InternalOnUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.LoadBuildinPackageVersionFile) + if (_steps == ESteps.RequestPackageVersion) { - if (_downloader == null) + if (_webTextRequestOp == null) { - string filePath = _persistent.GetBuildinPackageVersionFilePath(); - string url = PersistentHelper.ConvertToWWWPath(filePath); - _downloader = new UnityWebDataRequester(); - _downloader.SendRequest(url); + string filePath = _fileSystem.GetBuildinPackageVersionFilePath(); + string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + _webTextRequestOp = new UnityWebTextRequestOperation(url); + OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp); } - if (_downloader.IsDone() == false) + if (_webTextRequestOp.IsDone == false) return; - if (_downloader.HasError()) + if (_webTextRequestOp.Status == EOperationStatus.Succeed) { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloader.GetError(); - } - else - { - PackageVersion = _downloader.GetText(); + PackageVersion = _webTextRequestOp.Result; if (string.IsNullOrEmpty(PackageVersion)) { _steps = ESteps.Done; @@ -67,8 +61,12 @@ namespace YooAsset Status = EOperationStatus.Succeed; } } - - _downloader.Dispose(); + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webTextRequestOp.Error; + } } } } diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs.meta new file mode 100644 index 00000000..b7939834 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6bddb076e377b66488ec28c9dbdd18cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem.meta new file mode 100644 index 00000000..896191a1 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b03f54c14ce3f6041870eaa9317d2e64 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs new file mode 100644 index 00000000..e1c2a0ae --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs @@ -0,0 +1,537 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace YooAsset +{ + /// + /// 缓存文件系统 + /// 说明:正在进行的下载器会在ResourcePackage销毁的时候执行Abort操作! + /// + internal class DefaultCacheFileSystem : IFileSystem + { + public class FileWrapper + { + public string InfoFilePath { private set; get; } + public string DataFilePath { private set; get; } + public string DataFileCRC { private set; get; } + public long DataFileSize { private set; get; } + + public FileWrapper(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize) + { + InfoFilePath = infoFilePath; + DataFilePath = dataFilePath; + DataFileCRC = dataFileCRC; + DataFileSize = dataFileSize; + } + } + + protected readonly Dictionary _downloaders = new Dictionary(1000); + protected readonly Dictionary _wrappers = new Dictionary(10000); + protected readonly Dictionary _loadedStream = new Dictionary(10000); + protected readonly Dictionary _dataFilePaths = new Dictionary(10000); + protected readonly Dictionary _infoFilePaths = new Dictionary(10000); + protected readonly Dictionary _tempFilePaths = new Dictionary(10000); + protected readonly List _removeList = new List(1000); + protected string _packageRoot; + protected string _saveFileRoot; + protected string _tempFileRoot; + protected string _manifestFileRoot; + + + /// + /// 包裹名称 + /// + public string PackageName { private set; get; } + + /// + /// 文件访问权限 + /// + public EFileAccess FileSystemAccess + { + get + { + return EFileAccess.ReadWrite; + } + } + + /// + /// 文件根目录 + /// + public string FileRoot + { + get + { + return _packageRoot; + } + } + + /// + /// 文件数量 + /// + public int FileCount + { + get + { + return _wrappers.Count; + } + } + + #region 自定义参数 + /// + /// 自定义参数:远程服务接口 + /// + public IRemoteServices RemoteServices { private set; get; } = null; + + /// + /// 自定义参数:初始化的时候缓存文件校验级别 + /// + public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle; + + /// + /// 自定义参数:数据文件追加文件格式 + /// + public bool AppendFileExtension { private set; get; } = false; + + /// + /// 自定义参数:原生文件构建管线 + /// + public bool RawFileBuildPipeline { private set; get; } = false; + + /// + /// 自定义参数:启用断点续传的最小尺寸 + /// + public long ResumeDownloadMinimumSize { private set; get; } = long.MaxValue; + + /// + /// 自定义参数:断点续传下载器关注的错误码 + /// + public List ResumeDownloadResponseCodes { private set; get; } = null; + #endregion + + + public DefaultCacheFileSystem() + { + } + public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + { + var operation = new DCFSInitializeOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(params object[] args) + { + string packageVersion = args[0] as string; + int timeout = (int)args[1]; + var operation = new DCFSLoadPackageManifestOperation(this, packageVersion, timeout); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(params object[] args) + { + bool appendTimeTicks = (bool)args[0]; + int timeout = (int)args[1]; + var operation = new DCFSRequestPackageVersionOperation(this, appendTimeTicks, timeout); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync(params object[] args) + { + var operation = new DCFSClearAllBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(params object[] args) + { + PackageManifest manifest = args[0] as PackageManifest; + var operation = new DCFSClearUnusedBundleFilesOperation(this, manifest); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSDownloadFileOperation DownloadFileAsync(params object[] args) + { + PackageBundle bundle = args[0] as PackageBundle; + string localCopyFilePath = (string)args[1]; + int failedTryAgain = (int)args[2]; + int timeout = (int)args[3]; + + // 查询旧的下载器 + if (_downloaders.TryGetValue(bundle.BundleGUID, out var oldDownloader)) + { + oldDownloader.Reference(); + return oldDownloader; + } + + // 创建新的下载器 + { + string mainURL; + string fallbackURL; + if (string.IsNullOrEmpty(localCopyFilePath)) + { + mainURL = RemoteServices.GetRemoteMainURL(bundle.FileName); + fallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName); + } + else + { + // 注意:把本地文件路径指定为远端下载地址 + mainURL = DownloadSystemHelper.ConvertToWWWPath(localCopyFilePath); + fallbackURL = mainURL; + } + + if (bundle.FileSize >= ResumeDownloadMinimumSize) + { + var newDownloader = new DCFSDownloadResumeFileOperation(this, bundle, mainURL, fallbackURL, failedTryAgain, timeout); + newDownloader.Reference(); + _downloaders.Add(bundle.BundleGUID, newDownloader); + OperationSystem.StartOperation(PackageName, newDownloader); + return newDownloader; + } + else + { + var newDownloader = new DCFSDownloadNormalFileOperation(this, bundle, mainURL, fallbackURL, failedTryAgain, timeout); + newDownloader.Reference(); + _downloaders.Add(bundle.BundleGUID, newDownloader); + OperationSystem.StartOperation(PackageName, newDownloader); + return newDownloader; + } + } + } + + public virtual void SetParameter(string name, object value) + { + if (name == "REMOTE_SERVICES") + { + RemoteServices = (IRemoteServices)value; + } + else if (name == "FILE_VERIFY_LEVEL") + { + FileVerifyLevel = (EFileVerifyLevel)value; + } + else if (name == "APPEND_FILE_EXTENSION") + { + AppendFileExtension = (bool)value; + } + else if (name == "RAW_FILE_BUILD_PIPELINE") + { + RawFileBuildPipeline = (bool)value; + } + else if (name == "RESUME_DOWNLOAD_MINMUM_SIZE") + { + ResumeDownloadMinimumSize = (long)value; + } + else if (name == "RESUME_DOWNLOAD_RESPONSE_CODES") + { + ResumeDownloadResponseCodes = (List)value; + } + else + { + YooLogger.Warning($"Invalid parameter : {name}"); + } + } + public virtual void OnCreate(string packageName, string rootDirectory) + { + PackageName = packageName; + + if (string.IsNullOrEmpty(rootDirectory)) + rootDirectory = GetDefaultRoot(); + + _packageRoot = PathUtility.Combine(rootDirectory, packageName); + _saveFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.SaveFilesFolderName); + _tempFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName); + _manifestFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.ManifestFilesFolderName); + } + public virtual void OnUpdate() + { + _removeList.Clear(); + + foreach (var valuePair in _downloaders) + { + var downloader = valuePair.Value; + + // 注意:主动终止引用计数为零的下载任务 + if (downloader.RefCount <= 0) + { + _removeList.Add(valuePair.Key); + downloader.SetAbort(); + continue; + } + + if (downloader.IsDone) + _removeList.Add(valuePair.Key); + } + + foreach (var key in _removeList) + { + _downloaders.Remove(key); + } + } + + public virtual bool Belong(PackageBundle bundle) + { + // 注意:缓存文件系统保底加载! + return true; + } + public virtual bool Belong(string bundleGUID) + { + // 注意:缓存文件系统保底加载! + return true; + } + public virtual bool Exists(PackageBundle packageBundle) + { + return _wrappers.ContainsKey(packageBundle.BundleGUID); + } + public virtual bool Exists(string bundleGUID) + { + return _wrappers.ContainsKey(bundleGUID); + } + + public virtual bool CheckNeedDownload(PackageBundle bundle) + { + if (Belong(bundle) == false) + return false; + + return Exists(bundle) == false; + } + public virtual bool CheckNeedUnpack(PackageBundle bundle) + { + return false; + } + public virtual bool CheckNeedImport(PackageBundle bundle) + { + if (Belong(bundle) == false) + return false; + + return Exists(bundle) == false; + } + + public virtual bool WriteFile(PackageBundle bundle, string copyPath) + { + if (_wrappers.ContainsKey(bundle.BundleGUID)) + { + throw new Exception("Should never get here !"); + } + + string infoFilePath = GetInfoFilePath(bundle); + string dataFilePath = GetDataFilePath(bundle); + + try + { + if (File.Exists(infoFilePath)) + File.Delete(infoFilePath); + if (File.Exists(dataFilePath)) + File.Delete(dataFilePath); + + FileUtility.CreateFileDirectory(dataFilePath); + + // 拷贝数据文件 + FileInfo fileInfo = new FileInfo(copyPath); + fileInfo.CopyTo(dataFilePath); + + // 写入文件信息 + WriteInfoFile(infoFilePath, bundle.FileCRC, bundle.FileSize); + } + catch (Exception e) + { + YooLogger.Error($"Failed to write cache file ! {e.Message}"); + return false; + } + + FileWrapper wrapper = new FileWrapper(infoFilePath, dataFilePath, bundle.FileCRC, bundle.FileSize); + return Record(bundle.BundleGUID, wrapper); + } + public virtual bool DeleteFile(PackageBundle bundle) + { + return DeleteFile(bundle.BundleGUID); + } + public virtual bool DeleteFile(string bundleGUID) + { + if (_wrappers.TryGetValue(bundleGUID, out FileWrapper wrapper)) + { + try + { + string dataFilePath = wrapper.DataFilePath; + FileInfo fileInfo = new FileInfo(dataFilePath); + if (fileInfo.Exists) + fileInfo.Directory.Delete(true); + _wrappers.Remove(bundleGUID); + return true; + } + catch (Exception e) + { + YooLogger.Error($"Failed to delete cache file ! {e.Message}"); + return false; + } + } + else + { + return false; + } + } + public virtual EFileVerifyResult VerifyFile(PackageBundle bundle) + { + if (_wrappers.TryGetValue(bundle.BundleGUID, out FileWrapper wrapper) == false) + return EFileVerifyResult.CacheNotFound; + + EFileVerifyResult result = FileSystemHelper.FileVerify(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EFileVerifyLevel.High); + return result; + } + + public virtual byte[] ReadFileBytes(PackageBundle bundle) + { + throw new System.NotImplementedException(); + } + public virtual string ReadFileText(PackageBundle bundle) + { + throw new System.NotImplementedException(); + } + + public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + { + if (RawFileBuildPipeline) + { + var operation = new DCFSLoadRawBundleOperation(this, bundle); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + else + { + var operation = new DCFSLoadAssetBundleOperation(this, bundle); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + } + public virtual void UnloadBundleFile(PackageBundle bundle, object result) + { + AssetBundle assetBundle = result as AssetBundle; + if (assetBundle == null) + return; + + if (assetBundle != null) + assetBundle.Unload(true); + + if (_loadedStream.TryGetValue(bundle.BundleGUID, out Stream managedStream)) + { + managedStream.Close(); + managedStream.Dispose(); + _loadedStream.Remove(bundle.BundleGUID); + } + } + + #region 内部方法 + private readonly BufferWriter _sharedBuffer = new BufferWriter(1024); + public void WriteInfoFile(string filePath, string dataFileCRC, long dataFileSize) + { + using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read)) + { + _sharedBuffer.Clear(); + _sharedBuffer.WriteUTF8(dataFileCRC); + _sharedBuffer.WriteInt64(dataFileSize); + _sharedBuffer.WriteToStream(fs); + fs.Flush(); + } + } + public void ReadInfoFile(string filePath, out string dataFileCRC, out long dataFileSize) + { + byte[] binaryData = FileUtility.ReadAllBytes(filePath); + BufferReader buffer = new BufferReader(binaryData); + dataFileCRC = buffer.ReadUTF8(); + dataFileSize = buffer.ReadInt64(); + } + + protected string GetDefaultRoot() + { +#if UNITY_EDITOR + // 注意:为了方便调试查看,编辑器下把存储目录放到项目里。 + string projectPath = Path.GetDirectoryName(UnityEngine.Application.dataPath); + projectPath = PathUtility.RegularPath(projectPath); + return PathUtility.Combine(projectPath, YooAssetSettingsData.Setting.DefaultYooFolderName); +#elif UNITY_STANDALONE + return PathUtility.Combine(UnityEngine.Application.dataPath, YooAssetSettingsData.Setting.DefaultYooFolderName); +#else + return PathUtility.Combine(UnityEngine.Application.persistentDataPath, YooAssetSettingsData.Setting.DefaultYooFolderName); +#endif + } + protected string GetDataFilePath(PackageBundle bundle) + { + if (_dataFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false) + { + string folderName = bundle.FileHash.Substring(0, 2); + filePath = PathUtility.Combine(_saveFileRoot, folderName, bundle.BundleGUID, DefaultCacheFileSystemDefine.SaveBundleDataFileName); + if (AppendFileExtension) + filePath += bundle.FileExtension; + _dataFilePaths.Add(bundle.BundleGUID, filePath); + } + return filePath; + } + protected string GetInfoFilePath(PackageBundle bundle) + { + if (_infoFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false) + { + string folderName = bundle.FileHash.Substring(0, 2); + filePath = PathUtility.Combine(_saveFileRoot, folderName, bundle.BundleGUID, DefaultCacheFileSystemDefine.SaveBundleInfoFileName); + _infoFilePaths.Add(bundle.BundleGUID, filePath); + } + return filePath; + } + public string GetTempFilePath(PackageBundle bundle) + { + if (_tempFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false) + { + filePath = PathUtility.Combine(_tempFileRoot, bundle.BundleGUID); + _tempFilePaths.Add(bundle.BundleGUID, filePath); + } + return filePath; + } + public string GetFileLoadPath(PackageBundle bundle) + { + return GetDataFilePath(bundle); + } + public string GetCacheFilesRoot() + { + return _saveFileRoot; + } + public string GetCachePackageHashFilePath(string packageVersion) + { + string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion); + return PathUtility.Combine(_manifestFileRoot, fileName); + } + public string GetCachePackageManifestFilePath(string packageVersion) + { + string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion); + return PathUtility.Combine(_manifestFileRoot, fileName); + } + public string GetSandboxAppFootPrintFilePath() + { + return PathUtility.Combine(_manifestFileRoot, DefaultCacheFileSystemDefine.AppFootPrintFileName); + } + public void DeleteAllManifestFiles() + { + if (Directory.Exists(_manifestFileRoot)) + { + Directory.Delete(_manifestFileRoot, true); + } + } + public List GetAllCachedBundleGUIDs() + { + return _wrappers.Keys.ToList(); + } + + /// + /// 记录缓存信息 + /// + public bool Record(string bundleGUID, FileWrapper wrapper) + { + if (Exists(bundleGUID)) + { + YooLogger.Error($"{nameof(DefaultCacheFileSystem)} has element : {bundleGUID}"); + return false; + } + + _wrappers.Add(bundleGUID, wrapper); + return true; + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs.meta new file mode 100644 index 00000000..8e1ebce8 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4989ddcb6c99102429eeefffc3675ae5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs new file mode 100644 index 00000000..c607cdb6 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs @@ -0,0 +1,36 @@ + +namespace YooAsset +{ + internal class DefaultCacheFileSystemDefine + { + /// + /// 保存的数据文件名称 + /// + public const string SaveBundleDataFileName = "__data"; + + /// + /// 保存的信息文件名称 + /// + public const string SaveBundleInfoFileName = "__info"; + + /// + /// 保存的资源文件的文件夹名称 + /// + public const string SaveFilesFolderName = "CacheFiles"; + + /// + /// 下载的临时文件的文件夹名称 + /// + public const string TempFilesFolderName = "CacheTempFiles"; + + /// + /// 保存的清单文件的文件夹名称 + /// + public const string ManifestFilesFolderName = "ManifestFiles"; + + /// + /// 记录应用程序版本的文件名称 + /// + public const string AppFootPrintFileName = "ApplicationFootPrint.bytes"; + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs.meta new file mode 100644 index 00000000..940178db --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 610912866fe58794a904b43c2e24d84d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation.meta new file mode 100644 index 00000000..3110b708 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 09e4cebb2073ab945ac09e9099b327ad +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearAllCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearAllBundleFilesOperation.cs similarity index 60% rename from Assets/YooAsset/Runtime/CacheSystem/Operation/ClearAllCacheFilesOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearAllBundleFilesOperation.cs index deb1ac84..351524fb 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearAllCacheFilesOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearAllBundleFilesOperation.cs @@ -1,13 +1,9 @@ using System.Collections; using System.Collections.Generic; -using System.IO; namespace YooAsset { - /// - /// 清理本地包裹所有的缓存文件 - /// - public sealed class ClearAllCacheFilesOperation : AsyncOperationBase + internal sealed class DCFSClearAllBundleFilesOperation : FSClearAllBundleFilesOperation { private enum ESteps { @@ -17,14 +13,15 @@ namespace YooAsset Done, } - private readonly CacheManager _cache; - private List _allCacheGUIDs; + private readonly DefaultCacheFileSystem _fileSystem; + private List _allBundleGUIDs; private int _fileTotalCount = 0; private ESteps _steps = ESteps.None; - internal ClearAllCacheFilesOperation(CacheManager cache) + + internal DCFSClearAllBundleFilesOperation(DefaultCacheFileSystem fileSystem) { - _cache = cache; + _fileSystem = fileSystem; } internal override void InternalOnStart() { @@ -37,20 +34,19 @@ namespace YooAsset if (_steps == ESteps.GetAllCacheFiles) { - _allCacheGUIDs = _cache.GetAllCachedGUIDs(); - _fileTotalCount = _allCacheGUIDs.Count; + _allBundleGUIDs = _fileSystem.GetAllCachedBundleGUIDs(); + _fileTotalCount = _allBundleGUIDs.Count; YooLogger.Log($"Found all cache file count : {_fileTotalCount}"); _steps = ESteps.ClearAllCacheFiles; } if (_steps == ESteps.ClearAllCacheFiles) { - for (int i = _allCacheGUIDs.Count - 1; i >= 0; i--) + for (int i = _allBundleGUIDs.Count - 1; i >= 0; i--) { - string cacheGUID = _allCacheGUIDs[i]; - _cache.Discard(cacheGUID); - _allCacheGUIDs.RemoveAt(i); - + string bundleGUID = _allBundleGUIDs[i]; + _fileSystem.DeleteFile(bundleGUID); + _allBundleGUIDs.RemoveAt(i); if (OperationSystem.IsBusy) break; } @@ -58,9 +54,9 @@ namespace YooAsset if (_fileTotalCount == 0) Progress = 1.0f; else - Progress = 1.0f - (_allCacheGUIDs.Count / _fileTotalCount); + Progress = 1.0f - (_allBundleGUIDs.Count / _fileTotalCount); - if (_allCacheGUIDs.Count == 0) + if (_allBundleGUIDs.Count == 0) { _steps = ESteps.Done; Status = EOperationStatus.Succeed; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearAllBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearAllBundleFilesOperation.cs.meta new file mode 100644 index 00000000..fc104aac --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearAllBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: daed187502431d347bf11bddcf8d77de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearUnusedCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearUnusedBundleFilesOperation.cs similarity index 51% rename from Assets/YooAsset/Runtime/CacheSystem/Operation/ClearUnusedCacheFilesOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearUnusedBundleFilesOperation.cs index 2db369fc..1dcb7218 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearUnusedCacheFilesOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearUnusedBundleFilesOperation.cs @@ -1,13 +1,9 @@ using System.Collections; using System.Collections.Generic; -using System.IO; namespace YooAsset { - /// - /// 清理本地包裹未使用的缓存文件 - /// - public sealed class ClearUnusedCacheFilesOperation : AsyncOperationBase + internal sealed class DCFSClearUnusedBundleFilesOperation : FSClearUnusedBundleFilesOperation { private enum ESteps { @@ -17,16 +13,17 @@ namespace YooAsset Done, } - private readonly ResourcePackage _package; - private readonly CacheManager _cache; - private List _unusedCacheGUIDs; + private readonly DefaultCacheFileSystem _fileSystem; + private readonly PackageManifest _manifest; + private List _unusedBundleGUIDs; private int _unusedFileTotalCount = 0; private ESteps _steps = ESteps.None; - internal ClearUnusedCacheFilesOperation(ResourcePackage package, CacheManager cache) + + internal DCFSClearUnusedBundleFilesOperation(DefaultCacheFileSystem fileSystem, PackageManifest manifest) { - _package = package; - _cache = cache; + _fileSystem = fileSystem; + _manifest = manifest; } internal override void InternalOnStart() { @@ -39,20 +36,19 @@ namespace YooAsset if (_steps == ESteps.GetUnusedCacheFiles) { - _unusedCacheGUIDs = GetUnusedCacheGUIDs(); - _unusedFileTotalCount = _unusedCacheGUIDs.Count; - YooLogger.Log($"Found unused cache file count : {_unusedFileTotalCount}"); _steps = ESteps.ClearUnusedCacheFiles; + _unusedBundleGUIDs = GetUnusedBundleGUIDs(); + _unusedFileTotalCount = _unusedBundleGUIDs.Count; + YooLogger.Log($"Found unused cache file count : {_unusedFileTotalCount}"); } if (_steps == ESteps.ClearUnusedCacheFiles) { - for (int i = _unusedCacheGUIDs.Count - 1; i >= 0; i--) + for (int i = _unusedBundleGUIDs.Count - 1; i >= 0; i--) { - string cacheGUID = _unusedCacheGUIDs[i]; - _cache.Discard(cacheGUID); - _unusedCacheGUIDs.RemoveAt(i); - + string bundleGUID = _unusedBundleGUIDs[i]; + _fileSystem.DeleteFile(bundleGUID); + _unusedBundleGUIDs.RemoveAt(i); if (OperationSystem.IsBusy) break; } @@ -60,9 +56,9 @@ namespace YooAsset if (_unusedFileTotalCount == 0) Progress = 1.0f; else - Progress = 1.0f - (_unusedCacheGUIDs.Count / _unusedFileTotalCount); + Progress = 1.0f - (_unusedBundleGUIDs.Count / _unusedFileTotalCount); - if (_unusedCacheGUIDs.Count == 0) + if (_unusedBundleGUIDs.Count == 0) { _steps = ESteps.Done; Status = EOperationStatus.Succeed; @@ -70,15 +66,15 @@ namespace YooAsset } } - private List GetUnusedCacheGUIDs() + private List GetUnusedBundleGUIDs() { - var allCacheGUIDs = _cache.GetAllCachedGUIDs(); - List result = new List(allCacheGUIDs.Count); - foreach (var cacheGUID in allCacheGUIDs) + var allBundleGUIDs = _fileSystem.GetAllCachedBundleGUIDs(); + List result = new List(allBundleGUIDs.Count); + foreach (var bundleGUID in allBundleGUIDs) { - if (_package.IsIncludeBundleFile(cacheGUID) == false) + if (_manifest.IsIncludeBundleFile(bundleGUID) == false) { - result.Add(cacheGUID); + result.Add(bundleGUID); } } return result; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearUnusedBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearUnusedBundleFilesOperation.cs.meta new file mode 100644 index 00000000..b0863b70 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearUnusedBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be7b242f10abf524fa59e9ca0d12b052 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSDownloadFileOperation.cs new file mode 100644 index 00000000..fd2bc7bd --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSDownloadFileOperation.cs @@ -0,0 +1,432 @@ +using System.IO; +using UnityEngine; +using UnityEngine.Networking; + +namespace YooAsset +{ + internal sealed class DCFSDownloadNormalFileOperation : DefaultDownloadFileOperation + { + private readonly DefaultCacheFileSystem _fileSystem; + private VerifyTempFileOperation _verifyOperation; + private string _fileSavePath; + private ESteps _steps = ESteps.None; + + internal DCFSDownloadNormalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string mainURL, string fallbackURL, int failedTryAgain, int timeout) + : base(bundle, mainURL, fallbackURL, failedTryAgain, timeout) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + _fileSavePath = _fileSystem.GetTempFilePath(Bundle); + + // 注意:检测文件是否存在 + if (_fileSystem.Exists(Bundle)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.CreateRequest; + } + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 创建下载器 + if (_steps == ESteps.CreateRequest) + { + FileUtility.CreateFileDirectory(_fileSavePath); + + // 获取请求地址 + _requestURL = GetRequestURL(); + + // 重置变量 + _isAbort = false; + _latestDownloadBytes = 0; + _latestDownloadRealtime = Time.realtimeSinceStartup; + DownloadProgress = 0f; + DownloadedBytes = 0; + + // 重置计时器 + if (_tryAgainTimer > 0f) + YooLogger.Warning($"Try again download : {_requestURL}"); + _tryAgainTimer = 0f; + + // 删除临时文件 + if (File.Exists(_fileSavePath)) + File.Delete(_fileSavePath); + + // 创建下载器 + CreateWebRequest(); + + _steps = ESteps.CheckRequest; + } + + // 检测下载结果 + if (_steps == ESteps.CheckRequest) + { + DownloadProgress = _webRequest.downloadProgress; + DownloadedBytes = (long)_webRequest.downloadedBytes; + Progress = DownloadProgress; + if (_webRequest.isDone == false) + { + CheckRequestTimeout(); + return; + } + + // 检查网络错误 + if (CheckRequestResult()) + _steps = ESteps.VerifyTempFile; + else + _steps = ESteps.TryAgain; + + // 注意:最终释放请求器 + DisposeWebRequest(); + } + + // 验证下载文件 + if (_steps == ESteps.VerifyTempFile) + { + var element = new TempFileElement(_fileSavePath, Bundle.FileCRC, Bundle.FileSize); + _verifyOperation = new VerifyTempFileOperation(element); + OperationSystem.StartOperation(_fileSystem.PackageName, _verifyOperation); + _steps = ESteps.CheckVerifyTempFile; + } + + // 等待验证完成 + if (_steps == ESteps.CheckVerifyTempFile) + { + // 注意:同步解压文件更新 + _verifyOperation.InternalOnUpdate(); + if (_verifyOperation.IsDone == false) + return; + + if (_verifyOperation.Status == EOperationStatus.Succeed) + { + if (_fileSystem.WriteFile(Bundle, _fileSavePath)) + { + Status = EOperationStatus.Succeed; + _steps = ESteps.Done; + } + else + { + Error = $"{_fileSystem.GetType().FullName} write file failed !"; + Status = EOperationStatus.Failed; + _steps = ESteps.Done; + YooLogger.Error(Error); + } + } + else + { + Error = _verifyOperation.Error; + _steps = ESteps.TryAgain; + } + + // 注意:验证完成后直接删除文件 + if (File.Exists(_fileSavePath)) + File.Delete(_fileSavePath); + } + + // 重新尝试下载 + if (_steps == ESteps.TryAgain) + { + if (FailedTryAgain <= 0) + { + Status = EOperationStatus.Failed; + _steps = ESteps.Done; + YooLogger.Error(Error); + return; + } + + _tryAgainTimer += Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + FailedTryAgain--; + _steps = ESteps.CreateRequest; + YooLogger.Warning(Error); + } + } + } + internal override void InternalOnAbort() + { + _steps = ESteps.Done; + DisposeWebRequest(); + } + public override void WaitForAsyncComplete() + { + while (true) + { + // 文件验证 + if (_verifyOperation != null) + { + if (_verifyOperation.IsDone == false) + _verifyOperation.WaitForAsyncComplete(); + } + + // 驱动流程 + InternalOnUpdate(); + + // 完成后退出 + if (IsDone) + break; + } + } + + private void CreateWebRequest() + { + _webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL); + DownloadHandlerFile handler = new DownloadHandlerFile(_fileSavePath); + handler.removeFileOnAbort = true; + _webRequest.downloadHandler = handler; + _webRequest.disposeDownloadHandlerOnDispose = true; + _webRequest.SendWebRequest(); + } + private void DisposeWebRequest() + { + if (_webRequest != null) + { + //注意:引擎底层会自动调用Abort方法 + _webRequest.Dispose(); + _webRequest = null; + } + } + } + + internal sealed class DCFSDownloadResumeFileOperation : DefaultDownloadFileOperation + { + private readonly DefaultCacheFileSystem _fileSystem; + private DownloadHandlerFileRange _downloadHandle; + private VerifyTempFileOperation _verifyOperation; + private long _fileOriginLength = 0; + private string _fileSavePath; + private ESteps _steps = ESteps.None; + + + internal DCFSDownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string mainURL, string fallbackURL, int failedTryAgain, int timeout) + : base(bundle, mainURL, fallbackURL, failedTryAgain, timeout) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + _fileSavePath = _fileSystem.GetTempFilePath(Bundle); + + // 注意:检测文件是否存在 + if (_fileSystem.Exists(Bundle)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.CreateRequest; + } + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 创建下载器 + if (_steps == ESteps.CreateRequest) + { + FileUtility.CreateFileDirectory(_fileSavePath); + + // 获取请求地址 + _requestURL = GetRequestURL(); + + // 重置变量 + _isAbort = false; + _latestDownloadBytes = 0; + _latestDownloadRealtime = Time.realtimeSinceStartup; + _fileOriginLength = 0; + DownloadProgress = 0f; + DownloadedBytes = 0; + + // 重置计时器 + if (_tryAgainTimer > 0f) + YooLogger.Warning($"Try again download : {_requestURL}"); + _tryAgainTimer = 0f; + + // 获取下载起始位置 + long fileBeginLength = -1; + if (File.Exists(_fileSavePath)) + { + FileInfo fileInfo = new FileInfo(_fileSavePath); + fileBeginLength = fileInfo.Length; + _fileOriginLength = fileBeginLength; + DownloadedBytes = _fileOriginLength; + } + + // 检测下载起始位置 + if (fileBeginLength >= Bundle.FileSize) + { + // 删除临时文件 + if (File.Exists(_fileSavePath)) + File.Delete(_fileSavePath); + } + + // 创建下载器 + CreateWebRequest(fileBeginLength); + + _steps = ESteps.CheckRequest; + } + + // 检测下载结果 + if (_steps == ESteps.CheckRequest) + { + DownloadProgress = _webRequest.downloadProgress; + DownloadedBytes = _fileOriginLength + (long)_webRequest.downloadedBytes; + if (_webRequest.isDone == false) + { + CheckRequestTimeout(); + return; + } + + // 检查网络错误 + if (CheckRequestResult()) + _steps = ESteps.VerifyTempFile; + else + _steps = ESteps.TryAgain; + + // 在遇到特殊错误的时候删除文件 + ClearTempFileWhenError(); + + // 注意:最终释放请求器 + DisposeWebRequest(); + } + + // 验证下载文件 + if (_steps == ESteps.VerifyTempFile) + { + var element = new TempFileElement(_fileSavePath, Bundle.FileCRC, Bundle.FileSize); + _verifyOperation = new VerifyTempFileOperation(element); + OperationSystem.StartOperation(_fileSystem.PackageName, _verifyOperation); + _steps = ESteps.CheckVerifyTempFile; + } + + // 等待验证完成 + if (_steps == ESteps.CheckVerifyTempFile) + { + if (_verifyOperation.IsDone == false) + return; + + if (_verifyOperation.Status == EOperationStatus.Succeed) + { + if (_fileSystem.WriteFile(Bundle, _fileSavePath)) + { + Status = EOperationStatus.Succeed; + _steps = ESteps.Done; + } + else + { + Error = $"{_fileSystem.GetType().FullName} write file failed : {_fileSavePath}"; + Status = EOperationStatus.Failed; + _steps = ESteps.Done; + } + } + else + { + Error = _verifyOperation.Error; + _steps = ESteps.TryAgain; + } + + // 注意:验证完成后直接删除文件 + if (File.Exists(_fileSavePath)) + File.Delete(_fileSavePath); + } + + // 重新尝试下载 + if (_steps == ESteps.TryAgain) + { + if (FailedTryAgain <= 0) + { + Status = EOperationStatus.Failed; + _steps = ESteps.Done; + YooLogger.Error(Error); + return; + } + + _tryAgainTimer += Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + FailedTryAgain--; + _steps = ESteps.CreateRequest; + YooLogger.Warning(Error); + } + } + } + internal override void InternalOnAbort() + { + _steps = ESteps.Done; + DisposeWebRequest(); + } + public override void WaitForAsyncComplete() + { + while (true) + { + // 文件验证 + if (_verifyOperation != null) + { + if (_verifyOperation.IsDone == false) + _verifyOperation.WaitForAsyncComplete(); + } + + // 驱动流程 + InternalOnUpdate(); + + // 完成后退出 + if (IsDone) + break; + } + } + + private void CreateWebRequest(long beginLength) + { + _webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL); +#if UNITY_2019_4_OR_NEWER + var handler = new DownloadHandlerFile(_fileSavePath, true); + handler.removeFileOnAbort = false; +#else + var handler = new DownloadHandlerFileRange(FileSavePath, Bundle.FileSize, _webRequest); + _downloadHandle = handler; +#endif + _webRequest.downloadHandler = handler; + _webRequest.disposeDownloadHandlerOnDispose = true; + if (beginLength > 0) + _webRequest.SetRequestHeader("Range", $"bytes={beginLength}-"); + _webRequest.SendWebRequest(); + } + private void DisposeWebRequest() + { + if (_downloadHandle != null) + { + _downloadHandle.Cleanup(); + _downloadHandle = null; + } + + if (_webRequest != null) + { + //注意:引擎底层会自动调用Abort方法 + _webRequest.Dispose(); + _webRequest = null; + } + } + private void ClearTempFileWhenError() + { + if (_fileSystem.ResumeDownloadResponseCodes == null) + return; + + //说明:如果遇到以下错误返回码,验证失败直接删除文件 + if (_fileSystem.ResumeDownloadResponseCodes.Contains(HttpCode)) + { + if (File.Exists(_fileSavePath)) + File.Delete(_fileSavePath); + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSDownloadFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSDownloadFileOperation.cs.meta new file mode 100644 index 00000000..39eda641 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSDownloadFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d6f813e2460f55e4ba3f54527e6999e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs new file mode 100644 index 00000000..8243a34f --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs @@ -0,0 +1,87 @@ +using System.IO; +using UnityEngine; + +namespace YooAsset +{ + internal class DCFSInitializeOperation : FSInitializeFileSystemOperation + { + private enum ESteps + { + None, + CheckAppFootPrint, + SearchCacheFiles, + VerifyCacheFiles, + Done, + } + + private readonly DefaultCacheFileSystem _fileSytem; + private SearchCacheFilesOperation _searchCacheFilesOp; + private VerifyCacheFilesOperation _verifyCacheFilesOp; + private ESteps _steps = ESteps.None; + + + internal DCFSInitializeOperation(DefaultCacheFileSystem fileSystem) + { + _fileSytem = fileSystem; + } + internal override void InternalOnStart() + { + _steps = ESteps.CheckAppFootPrint; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckAppFootPrint) + { + var appFootPrint = new ApplicationFootPrint(_fileSytem); + appFootPrint.Load(_fileSytem.PackageName); + + // 如果水印发生变化,则说明覆盖安装后首次打开游戏 + if (appFootPrint.IsDirty()) + { + _fileSytem.DeleteAllManifestFiles(); + appFootPrint.Coverage(_fileSytem.PackageName); + YooLogger.Log("Delete manifest files when application foot print dirty !"); + } + + _steps = ESteps.SearchCacheFiles; + } + + if (_steps == ESteps.SearchCacheFiles) + { + if (_searchCacheFilesOp == null) + { + _searchCacheFilesOp = new SearchCacheFilesOperation(_fileSytem); + OperationSystem.StartOperation(_fileSytem.PackageName, _searchCacheFilesOp); + } + + Progress = _searchCacheFilesOp.Progress; + if (_searchCacheFilesOp.IsDone == false) + return; + + _steps = ESteps.VerifyCacheFiles; + } + + if (_steps == ESteps.VerifyCacheFiles) + { + if (_verifyCacheFilesOp == null) + { + _verifyCacheFilesOp = new VerifyCacheFilesOperation(_fileSytem, _searchCacheFilesOp.Result); + OperationSystem.StartOperation(_fileSytem.PackageName, _verifyCacheFilesOp); + } + + Progress = _verifyCacheFilesOp.Progress; + if (_verifyCacheFilesOp.IsDone == false) + return; + + // 注意:总是返回成功 + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + + YooLogger.Log($"Package '{_fileSytem.PackageName}' cached files count : {_fileSytem.FileCount}"); + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs.meta new file mode 100644 index 00000000..2bac299b --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 443aa31f081edfd458a90e3385a75203 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs new file mode 100644 index 00000000..6d6e62b3 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs @@ -0,0 +1,330 @@ +using System.IO; +using UnityEngine; + +namespace YooAsset +{ + internal class DCFSLoadAssetBundleOperation : FSLoadBundleOperation + { + private enum ESteps + { + None, + DownloadFile, + LoadAssetBundle, + CheckResult, + Done, + } + + private readonly DefaultCacheFileSystem _fileSystem; + private readonly PackageBundle _bundle; + private FSDownloadFileOperation _downloadFileOp; + private AssetBundleCreateRequest _createRequest; + private bool _isWaitForAsyncComplete = false; + private ESteps _steps = ESteps.None; + + + internal DCFSLoadAssetBundleOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle) + { + _fileSystem = fileSystem; + _bundle = bundle; + } + internal override void InternalOnStart() + { + if (_fileSystem.CheckNeedDownload(_bundle)) + { + DownloadProgress = 0f; + DownloadedBytes = 0; + _steps = ESteps.DownloadFile; + } + else + { + DownloadProgress = 1f; + DownloadedBytes = _bundle.FileSize; + _steps = ESteps.LoadAssetBundle; + } + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.DownloadFile) + { + if (_downloadFileOp == null) + { + int failedTryAgain = int.MaxValue; + int timeout = 60; + _downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, null, failedTryAgain, timeout); + } + + DownloadProgress = _downloadFileOp.DownloadProgress; + DownloadedBytes = _downloadFileOp.DownloadedBytes; + if (_downloadFileOp.IsDone == false) + return; + + if (_downloadFileOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadAssetBundle; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadFileOp.Error; + } + } + + if (_steps == ESteps.LoadAssetBundle) + { + string filePath = _fileSystem.GetFileLoadPath(_bundle); + if (_isWaitForAsyncComplete) + { + Result = AssetBundle.LoadFromFile(filePath); + } + else + { + _createRequest = AssetBundle.LoadFromFileAsync(filePath); + } + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (_createRequest != null) + { + if (_isWaitForAsyncComplete) + { + // 强制挂起主线程(注意:该操作会很耗时) + YooLogger.Warning("Suspend the main thread to load unity bundle."); + Result = _createRequest.assetBundle; + } + else + { + if (_createRequest.isDone == false) + return; + Result = _createRequest.assetBundle; + } + } + + if (Result != null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + // 注意:当缓存文件的校验等级为Low的时候,并不能保证缓存文件的完整性。 + // 说明:在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性! + EFileVerifyResult result = _fileSystem.VerifyFile(_bundle); + if (result == EFileVerifyResult.Succeed) + { + // 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。 + // 说明:大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发! + string filePath = _fileSystem.GetFileLoadPath(_bundle); + byte[] fileData = FileUtility.ReadAllBytes(filePath); + if (fileData != null && fileData.Length > 0) + { + Result = AssetBundle.LoadFromMemory(fileData); + if (Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load assetBundle from memory : {_bundle.BundleName}"; + YooLogger.Error(Error); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to read assetBundle file bytes : {_bundle.BundleName}"; + YooLogger.Error(Error); + } + } + else + { + _steps = ESteps.Done; + _fileSystem.DeleteFile(_bundle); + Status = EOperationStatus.Failed; + Error = $"Find corrupted file and delete the file : {_bundle.BundleName}"; + YooLogger.Error(Error); + } + } + } + } + + public override void WaitForAsyncComplete() + { + _isWaitForAsyncComplete = true; + + int frame = 1000; + while (true) + { + // 保险机制 + // 注意:如果需要从远端下载资源,可能会触发保险机制! + frame--; + if (frame == 0) + { + Status = EOperationStatus.Failed; + Error = $"{nameof(WaitForAsyncComplete)} failed ! Try load bundle {_bundle.BundleName} from remote with sync load method !"; + _steps = ESteps.Done; + YooLogger.Error(Error); + } + + // 驱动流程 + InternalOnUpdate(); + + // 完成后退出 + if (IsDone) + break; + } + } + public override void AbortDownloadOperation() + { + if (_steps == ESteps.DownloadFile) + { + if (_downloadFileOp != null) + _downloadFileOp.SetAbort(); + } + } + } + + internal class DCFSLoadRawBundleOperation : FSLoadBundleOperation + { + private enum ESteps + { + None, + DownloadFile, + LoadRawBundle, + CheckResult, + Done, + } + + private readonly DefaultCacheFileSystem _fileSystem; + private readonly PackageBundle _bundle; + private FSDownloadFileOperation _downloadFileOp; + private ESteps _steps = ESteps.None; + + + internal DCFSLoadRawBundleOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle) + { + _fileSystem = fileSystem; + _bundle = bundle; + } + internal override void InternalOnStart() + { + if (_fileSystem.CheckNeedDownload(_bundle)) + { + DownloadProgress = 0f; + DownloadedBytes = 0; + _steps = ESteps.DownloadFile; + } + else + { + DownloadProgress = 1f; + DownloadedBytes = _bundle.FileSize; + _steps = ESteps.LoadRawBundle; + } + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.DownloadFile) + { + if (_downloadFileOp == null) + { + int failedTryAgain = int.MaxValue; + int timeout = 60; + _downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, null, failedTryAgain, timeout); + } + + DownloadProgress = _downloadFileOp.DownloadProgress; + DownloadedBytes = _downloadFileOp.DownloadedBytes; + if (_downloadFileOp.IsDone == false) + return; + + if (_downloadFileOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadRawBundle; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadFileOp.Error; + } + } + + if (_steps == ESteps.LoadRawBundle) + { + string filePath = _fileSystem.GetFileLoadPath(_bundle); + Result = filePath; + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (Result != null) + { + string filePath = Result as string; + if (File.Exists(filePath)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Can not found raw bundle file : {filePath}"; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed load raw bundle file : {_bundle.BundleName}"; + } + } + } + + public override void WaitForAsyncComplete() + { + int frame = 1000; + while (true) + { + // 保险机制 + // 注意:如果需要从远端下载资源,可能会触发保险机制! + frame--; + if (frame == 0) + { + Status = EOperationStatus.Failed; + Error = $"{nameof(WaitForAsyncComplete)} failed ! Try load bundle {_bundle.BundleName} from remote with sync load method !"; + _steps = ESteps.Done; + YooLogger.Error(Error); + } + + // 驱动流程 + InternalOnUpdate(); + + // 完成后退出 + if (IsDone) + break; + } + } + public override void AbortDownloadOperation() + { + if (_steps == ESteps.DownloadFile) + { + if (_downloadFileOp != null) + _downloadFileOp.SetAbort(); + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs.meta new file mode 100644 index 00000000..b18d6bf9 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a653cabf995909d48935a0486db6116f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs new file mode 100644 index 00000000..c55fe377 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs @@ -0,0 +1,159 @@ +using System.IO; + +namespace YooAsset +{ + internal class DCFSLoadPackageManifestOperation : FSLoadPackageManifestOperation + { + private enum ESteps + { + None, + DownloadPackageHash, + DownloadPackageManifest, + LoadCachePackageHash, + LoadCachePackageManifest, + Done, + } + + private readonly DefaultCacheFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly int _timeout; + private DownloadPackageHashOperation _downloadPackageHashOp; + private DownloadPackageManifestOperation _downloadPackageManifestOp; + private LoadCachePackageHashOperation _loadCachePackageHashOp; + private LoadCachePackageManifestOperation _loadCachePackageManifestOp; + private ESteps _steps = ESteps.None; + + + internal DCFSLoadPackageManifestOperation(DefaultCacheFileSystem fileSystem, string packageVersion, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _steps = ESteps.DownloadPackageHash; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.DownloadPackageHash) + { + if (_downloadPackageHashOp == null) + { + _downloadPackageHashOp = new DownloadPackageHashOperation(_fileSystem, _packageVersion, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _downloadPackageHashOp); + } + + if (_downloadPackageHashOp.IsDone == false) + return; + + if (_downloadPackageHashOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.DownloadPackageManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadPackageHashOp.Error; + } + } + + if (_steps == ESteps.DownloadPackageManifest) + { + if (_downloadPackageManifestOp == null) + { + _downloadPackageManifestOp = new DownloadPackageManifestOperation(_fileSystem, _packageVersion, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _downloadPackageManifestOp); + } + + if (_downloadPackageManifestOp.IsDone == false) + return; + + if (_downloadPackageManifestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadCachePackageHash; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadPackageManifestOp.Error; + } + } + + if (_steps == ESteps.LoadCachePackageHash) + { + if (_loadCachePackageHashOp == null) + { + _loadCachePackageHashOp = new LoadCachePackageHashOperation(_fileSystem, _packageVersion); + OperationSystem.StartOperation(_fileSystem.PackageName, _loadCachePackageHashOp); + } + + if (_loadCachePackageHashOp.IsDone == false) + return; + + if (_loadCachePackageHashOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadCachePackageManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadCachePackageHashOp.Error; + ClearCacheFatalFile(); + } + } + + if (_steps == ESteps.LoadCachePackageManifest) + { + if (_loadCachePackageManifestOp == null) + { + string packageHash = _loadCachePackageHashOp.PackageHash; + _loadCachePackageManifestOp = new LoadCachePackageManifestOperation(_fileSystem, _packageVersion, packageHash); + OperationSystem.StartOperation(_fileSystem.PackageName, _loadCachePackageManifestOp); + } + + Progress = _loadCachePackageManifestOp.Progress; + if (_loadCachePackageManifestOp.IsDone == false) + return; + + if (_loadCachePackageManifestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Result = _loadCachePackageManifestOp.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadCachePackageManifestOp.Error; + ClearCacheFatalFile(); + } + } + } + + private void ClearCacheFatalFile() + { + // 注意:如果加载沙盒内的清单报错,为了避免流程被卡住,主动把损坏的文件删除。 + string manifestFilePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion); + if (File.Exists(manifestFilePath)) + { + YooLogger.Warning($"Failed to load cache manifest file : {Error}"); + YooLogger.Warning($"Invalid cache manifest file have been removed : {manifestFilePath}"); + File.Delete(manifestFilePath); + } + + string hashFilePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion); + if (File.Exists(hashFilePath)) + { + File.Delete(hashFilePath); + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs.meta new file mode 100644 index 00000000..33187cb4 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2447826454481704ab785153ae89be3a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs new file mode 100644 index 00000000..228f5b19 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs @@ -0,0 +1,66 @@ + +namespace YooAsset +{ + internal class DCFSRequestPackageVersionOperation : FSRequestPackageVersionOperation + { + private enum ESteps + { + None, + GetPackageVersion, + Done, + } + + private readonly DefaultCacheFileSystem _fileSystem; + private readonly bool _appendTimeTicks; + private readonly int _timeout; + private DefaultGetRemotePackageVersionOperation _getRemotePackageVersionOp; + private ESteps _steps = ESteps.None; + + + internal DCFSRequestPackageVersionOperation(DefaultCacheFileSystem fileSystem, bool appendTimeTicks, int timeout) + { + _fileSystem = fileSystem; + _appendTimeTicks = appendTimeTicks; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _steps = ESteps.GetPackageVersion; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.GetPackageVersion) + { + if (_getRemotePackageVersionOp == null) + { + string packageName = _fileSystem.PackageName; + string fileName = YooAssetSettingsData.GetPackageVersionFileName(packageName); + string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(fileName); + string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName); + _getRemotePackageVersionOp = new DefaultGetRemotePackageVersionOperation(packageName, mainURL, fallbackURL, _appendTimeTicks, _timeout); + OperationSystem.StartOperation(packageName, _getRemotePackageVersionOp); + } + + Progress = _getRemotePackageVersionOp.Progress; + if (_getRemotePackageVersionOp.IsDone == false) + return; + + if (_getRemotePackageVersionOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + PackageVersion = _getRemotePackageVersionOp.PackageVersion; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _getRemotePackageVersionOp.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs.meta new file mode 100644 index 00000000..001fd338 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 856b1334d67ed4d41b31a583f713c449 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal.meta new file mode 100644 index 00000000..d5629ef8 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3414bfb159816a74f917270b7d48c25f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ApplicationFootPrint.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ApplicationFootPrint.cs new file mode 100644 index 00000000..cb492ce9 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ApplicationFootPrint.cs @@ -0,0 +1,63 @@ +using System.IO; +using UnityEngine; + +namespace YooAsset +{ + /// + /// 应用程序水印 + /// + internal class ApplicationFootPrint + { + private readonly DefaultCacheFileSystem _fileSystem; + private string _footPrint; + + + public ApplicationFootPrint(DefaultCacheFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + + /// + /// 读取应用程序水印 + /// + public void Load(string packageName) + { + string footPrintFilePath = _fileSystem.GetSandboxAppFootPrintFilePath(); + if (File.Exists(footPrintFilePath)) + { + _footPrint = FileUtility.ReadAllText(footPrintFilePath); + } + else + { + Coverage(packageName); + } + } + + /// + /// 检测水印是否发生变化 + /// + public bool IsDirty() + { +#if UNITY_EDITOR + return _footPrint != Application.version; +#else + return _footPrint != Application.buildGUID; +#endif + } + + /// + /// 覆盖掉水印 + /// + public void Coverage(string packageName) + { +#if UNITY_EDITOR + _footPrint = Application.version; +#else + _footPrint = Application.buildGUID; +#endif + string footPrintFilePath = _fileSystem.GetSandboxAppFootPrintFilePath(); + FileUtility.WriteAllText(footPrintFilePath, _footPrint); + YooLogger.Log($"Save application foot print : {_footPrint}"); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ApplicationFootPrint.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ApplicationFootPrint.cs.meta new file mode 100644 index 00000000..90536b59 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ApplicationFootPrint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c9d96ea955bc07149a08471e33915556 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/DownloadHandlerFileRange.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadHandlerFileRange.cs similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/Requester/DownloadHandlerFileRange.cs rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadHandlerFileRange.cs diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/DownloadHandlerFileRange.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadHandlerFileRange.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/Requester/DownloadHandlerFileRange.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadHandlerFileRange.cs.meta diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs new file mode 100644 index 00000000..39fb9463 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs @@ -0,0 +1,92 @@ +using System.IO; + +namespace YooAsset +{ + internal class DownloadPackageHashOperation : AsyncOperationBase + { + private enum ESteps + { + None, + CheckExist, + DownloadFile, + Done, + } + + private readonly DefaultCacheFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly int _timeout; + private UnityWebFileRequestOperation _webFileRequestOp; + private int _requestCount = 0; + private ESteps _steps = ESteps.None; + + + internal DownloadPackageHashOperation(DefaultCacheFileSystem fileSystem, string packageVersion, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(DownloadPackageHashOperation)); + _steps = ESteps.CheckExist; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckExist) + { + string filePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion); + if (File.Exists(filePath)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.DownloadFile; + } + } + + if (_steps == ESteps.DownloadFile) + { + if (_webFileRequestOp == null) + { + string savePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion); + string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, _packageVersion); + string webURL = GetWebRequestURL(fileName); + YooLogger.Log($"Beginning to download package hash file : {webURL}"); + _webFileRequestOp = new UnityWebFileRequestOperation(webURL, savePath, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _webFileRequestOp); + } + + if (_webFileRequestOp.IsDone == false) + return; + + if (_webFileRequestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webFileRequestOp.Error; + WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(DownloadPackageHashOperation)); + } + } + } + + private string GetWebRequestURL(string fileName) + { + // 轮流返回请求地址 + if (_requestCount % 2 == 0) + return _fileSystem.RemoteServices.GetRemoteMainURL(fileName); + else + return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs.meta new file mode 100644 index 00000000..4dc9a9b4 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8604af2bf2c8a1d4684cb59d81ab9445 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs new file mode 100644 index 00000000..e14bc2c4 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs @@ -0,0 +1,92 @@ +using System.IO; + +namespace YooAsset +{ + internal class DownloadPackageManifestOperation : AsyncOperationBase + { + private enum ESteps + { + None, + CheckExist, + DownloadFile, + Done, + } + + private readonly DefaultCacheFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly int _timeout; + private UnityWebFileRequestOperation _webFileRequestOp; + private int _requestCount = 0; + private ESteps _steps = ESteps.None; + + + internal DownloadPackageManifestOperation(DefaultCacheFileSystem fileSystem, string packageVersion, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(DownloadPackageManifestOperation)); + _steps = ESteps.DownloadFile; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckExist) + { + string filePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion); + if (File.Exists(filePath)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.DownloadFile; + } + } + + if (_steps == ESteps.DownloadFile) + { + if (_webFileRequestOp == null) + { + string savePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion); + string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion); + string webURL = GetDownloadRequestURL(fileName); + YooLogger.Log($"Beginning to download package manifest file : {webURL}"); + _webFileRequestOp = new UnityWebFileRequestOperation(webURL, savePath, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _webFileRequestOp); + } + + if (_webFileRequestOp.IsDone == false) + return; + + if (_webFileRequestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webFileRequestOp.Error; + WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(DownloadPackageManifestOperation)); + } + } + } + + private string GetDownloadRequestURL(string fileName) + { + // 轮流返回请求地址 + if (_requestCount % 2 == 0) + return _fileSystem.RemoteServices.GetRemoteMainURL(fileName); + else + return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs.meta new file mode 100644 index 00000000..0a5383c6 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d5983f1b32b2e14c8b4c5b539bee8fa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs similarity index 74% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageHashOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs index 72f8ed9a..94d1bc32 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageHashOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs @@ -2,16 +2,16 @@ namespace YooAsset { - internal class QueryCachePackageHashOperation : AsyncOperationBase + internal class LoadCachePackageHashOperation : AsyncOperationBase { private enum ESteps { None, - LoadCachePackageHashFile, + LoadPackageHash, Done, } - private readonly PersistentManager _persistent; + private readonly DefaultCacheFileSystem _fileSystem; private readonly string _packageVersion; private ESteps _steps = ESteps.None; @@ -21,23 +21,23 @@ namespace YooAsset public string PackageHash { private set; get; } - public QueryCachePackageHashOperation(PersistentManager persistent, string packageVersion) + internal LoadCachePackageHashOperation(DefaultCacheFileSystem fileSystem, string packageVersion) { - _persistent = persistent; + _fileSystem = fileSystem; _packageVersion = packageVersion; } internal override void InternalOnStart() { - _steps = ESteps.LoadCachePackageHashFile; + _steps = ESteps.LoadPackageHash; } internal override void InternalOnUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.LoadCachePackageHashFile) + if (_steps == ESteps.LoadPackageHash) { - string filePath = _persistent.GetSandboxPackageHashFilePath(_packageVersion); + string filePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion); if (File.Exists(filePath) == false) { _steps = ESteps.Done; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs.meta new file mode 100644 index 00000000..ef75bc8e --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db66f75d31bfeca4e897e9ee0946b1de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs new file mode 100644 index 00000000..1d2df41f --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs @@ -0,0 +1,102 @@ +using System.IO; + +namespace YooAsset +{ + internal class LoadCachePackageManifestOperation : AsyncOperationBase + { + private enum ESteps + { + None, + LoadFileData, + VerifyFileData, + LoadManifest, + Done, + } + + private readonly DefaultCacheFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly string _packageHash; + private DeserializeManifestOperation _deserializer; + private byte[] _fileData; + private ESteps _steps = ESteps.None; + + /// + /// 加载的清单实例 + /// + public PackageManifest Manifest { private set; get; } + + + internal LoadCachePackageManifestOperation(DefaultCacheFileSystem fileSystem, string packageVersion, string packageHash) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _packageHash = packageHash; + } + internal override void InternalOnStart() + { + _steps = ESteps.LoadFileData; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadFileData) + { + string manifestFilePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion); + if (File.Exists(manifestFilePath)) + { + _steps = ESteps.VerifyFileData; + _fileData = File.ReadAllBytes(manifestFilePath); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Cache manifest file not found : {manifestFilePath}"; + } + } + + if (_steps == ESteps.VerifyFileData) + { + string fileHash = HashUtility.BytesMD5(_fileData); + if (fileHash == _packageHash) + { + _steps = ESteps.LoadManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Failed to verify cache package manifest file!"; + } + } + + if (_steps == ESteps.LoadManifest) + { + if (_deserializer == null) + { + _deserializer = new DeserializeManifestOperation(_fileData); + OperationSystem.StartOperation(_fileSystem.PackageName, _deserializer); + } + + Progress = _deserializer.Progress; + if (_deserializer.IsDone == false) + return; + + if (_deserializer.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Manifest = _deserializer.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _deserializer.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs.meta new file mode 100644 index 00000000..06a58497 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: acd84795f7cc3e348ab2b6cde03c8a22 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/FindCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs similarity index 61% rename from Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/FindCacheFilesOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs index da6d2f8f..f17fa16c 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/FindCacheFilesOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs @@ -5,18 +5,17 @@ using System.Collections.Generic; namespace YooAsset { - internal sealed class FindCacheFilesOperation : AsyncOperationBase + internal sealed class SearchCacheFilesOperation : AsyncOperationBase { private enum ESteps { None, Prepare, - UpdateCacheFiles, + SearchFiles, Done, } - private readonly PersistentManager _persistent; - private readonly CacheManager _cache; + private readonly DefaultCacheFileSystem _fileSystem; private IEnumerator _filesEnumerator = null; private float _verifyStartTime; private ESteps _steps = ESteps.None; @@ -24,12 +23,12 @@ namespace YooAsset /// /// 需要验证的元素 /// - public readonly List VerifyElements = new List(5000); + public readonly List Result = new List(5000); - public FindCacheFilesOperation(PersistentManager persistent, CacheManager cache) + + internal SearchCacheFilesOperation(DefaultCacheFileSystem fileSystem) { - _persistent = persistent; - _cache = cache; + _fileSystem = fileSystem; } internal override void InternalOnStart() { @@ -43,30 +42,29 @@ namespace YooAsset if (_steps == ESteps.Prepare) { - string rootPath = _persistent.SandboxCacheFilesRoot; - DirectoryInfo rootDirectory = new DirectoryInfo(rootPath); + DirectoryInfo rootDirectory = new DirectoryInfo(_fileSystem.GetCacheFilesRoot()); if (rootDirectory.Exists) { var directorieInfos = rootDirectory.EnumerateDirectories(); _filesEnumerator = directorieInfos.GetEnumerator(); } - _steps = ESteps.UpdateCacheFiles; + _steps = ESteps.SearchFiles; } - if (_steps == ESteps.UpdateCacheFiles) + if (_steps == ESteps.SearchFiles) { - if (UpdateCacheFiles()) + if (SearchFiles()) return; // 注意:总是返回成功 _steps = ESteps.Done; Status = EOperationStatus.Succeed; float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; - YooLogger.Log($"Find cache files elapsed time {costTime:f1} seconds"); + YooLogger.Log($"Search cache files elapsed time {costTime:f1} seconds"); } } - private bool UpdateCacheFiles() + private bool SearchFiles() { if (_filesEnumerator == null) return false; @@ -82,29 +80,25 @@ namespace YooAsset var childDirectories = rootFoder.GetDirectories(); foreach (var chidDirectory in childDirectories) { - string cacheGUID = chidDirectory.Name; - if (_cache.IsCached(cacheGUID)) + string bundleGUID = chidDirectory.Name; + if (_fileSystem.Exists(bundleGUID)) continue; // 创建验证元素类 string fileRootPath = chidDirectory.FullName; - string dataFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleDataFileName}"; - string infoFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleInfoFileName}"; - string dataFileExtension = FindDataFileExtension(chidDirectory); + string dataFilePath = $"{fileRootPath}/{ DefaultCacheFileSystemDefine.SaveBundleDataFileName}"; + string infoFilePath = $"{fileRootPath}/{ DefaultCacheFileSystemDefine.SaveBundleInfoFileName}"; - // 跳过断点续传的临时文件 - if (dataFileExtension == ".temp") - continue; - - // 注意:根据配置需求数据文件会带文件格式 - if (_persistent.AppendFileExtension) + // 存储的数据文件追加文件格式 + if (_fileSystem.AppendFileExtension) { + string dataFileExtension = FindDataFileExtension(chidDirectory); if (string.IsNullOrEmpty(dataFileExtension) == false) dataFilePath += dataFileExtension; } - VerifyCacheFileElement element = new VerifyCacheFileElement(_cache.PackageName, cacheGUID, fileRootPath, dataFilePath, infoFilePath); - VerifyElements.Add(element); + var element = new CacheFileElement(_fileSystem.PackageName, bundleGUID, fileRootPath, dataFilePath, infoFilePath); + Result.Add(element); } if (OperationSystem.IsBusy) @@ -119,7 +113,7 @@ namespace YooAsset var fileInfos = directoryInfo.GetFiles(); foreach (var fileInfo in fileInfos) { - if (fileInfo.Name.StartsWith(YooAssetSettings.CacheBundleDataFileName)) + if (fileInfo.Name.StartsWith(DefaultCacheFileSystemDefine.SaveBundleDataFileName)) { dataFileExtension = fileInfo.Extension; break; diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs.meta new file mode 100644 index 00000000..e977ef00 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8adb017a806563548b1d4c47f7b343e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs new file mode 100644 index 00000000..8459ebf9 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Threading; + +namespace YooAsset +{ + internal class CacheFileElement + { + public string PackageName { private set; get; } + public string BundleGUID { private set; get; } + public string FileRootPath { private set; get; } + public string DataFilePath { private set; get; } + public string InfoFilePath { private set; get; } + + public EFileVerifyResult Result; + public string DataFileCRC; + public long DataFileSize; + + public CacheFileElement(string packageName, string bundleGUID, string fileRootPath, string dataFilePath, string infoFilePath) + { + PackageName = packageName; + BundleGUID = bundleGUID; + FileRootPath = fileRootPath; + DataFilePath = dataFilePath; + InfoFilePath = infoFilePath; + } + + public void DeleteFiles() + { + try + { + Directory.Delete(FileRootPath, true); + } + catch (System.Exception e) + { + YooLogger.Warning($"Failed delete cache bundle folder : {e}"); + } + } + } + + /// + /// 缓存文件验证(线程版) + /// + internal class VerifyCacheFilesOperation : AsyncOperationBase + { + private enum ESteps + { + None, + InitVerify, + UpdateVerify, + Done, + } + + private readonly ThreadSyncContext _syncContext = new ThreadSyncContext(); + private readonly DefaultCacheFileSystem _fileSystem; + private List _waitingList; + private List _verifyingList; + private EFileVerifyLevel _verifyLevel = EFileVerifyLevel.Middle; + private int _verifyMaxNum; + private int _verifyTotalCount; + private float _verifyStartTime; + private int _succeedCount; + private int _failedCount; + private ESteps _steps = ESteps.None; + + + internal VerifyCacheFilesOperation(DefaultCacheFileSystem fileSystem, List elements) + { + _fileSystem = fileSystem; + _waitingList = elements; + _verifyLevel = _fileSystem.FileVerifyLevel; + } + internal override void InternalOnStart() + { + _steps = ESteps.InitVerify; + _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.InitVerify) + { + int fileCount = _waitingList.Count; + + // 设置同时验证的最大数 + ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads); + YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}"); + _verifyMaxNum = Math.Min(workerThreads, ioThreads); + _verifyTotalCount = fileCount; + if (_verifyMaxNum < 1) + _verifyMaxNum = 1; + + _verifyingList = new List(_verifyMaxNum); + _steps = ESteps.UpdateVerify; + } + + if (_steps == ESteps.UpdateVerify) + { + _syncContext.Update(); + + Progress = GetProgress(); + if (_waitingList.Count == 0 && _verifyingList.Count == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; + YooLogger.Log($"Verify cache files elapsed time {costTime:f1} seconds"); + } + + for (int i = _waitingList.Count - 1; i >= 0; i--) + { + if (OperationSystem.IsBusy) + break; + + if (_verifyingList.Count >= _verifyMaxNum) + break; + + var element = _waitingList[i]; + if (BeginVerifyFileWithThread(element)) + { + _waitingList.RemoveAt(i); + _verifyingList.Add(element); + } + else + { + YooLogger.Warning("The thread pool is failed queued."); + break; + } + } + } + } + + private float GetProgress() + { + if (_verifyTotalCount == 0) + return 1f; + return (float)(_succeedCount + _failedCount) / _verifyTotalCount; + } + private bool BeginVerifyFileWithThread(CacheFileElement element) + { + return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element); + } + private void VerifyInThread(object obj) + { + CacheFileElement element = (CacheFileElement)obj; + element.Result = VerifyingCacheFile(element, _verifyLevel); + _syncContext.Post(VerifyCallback, element); + } + private void VerifyCallback(object obj) + { + CacheFileElement element = (CacheFileElement)obj; + _verifyingList.Remove(element); + + if (element.Result == EFileVerifyResult.Succeed) + { + _succeedCount++; + var fileWrapper = new DefaultCacheFileSystem.FileWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize); + _fileSystem.Record(element.BundleGUID, fileWrapper); + } + else + { + _failedCount++; + + YooLogger.Warning($"Failed verify file {element.Result} and delete files : {element.FileRootPath}"); + element.DeleteFiles(); + } + } + + /// + /// 验证缓存文件(子线程内操作) + /// + private EFileVerifyResult VerifyingCacheFile(CacheFileElement element, EFileVerifyLevel verifyLevel) + { + try + { + if (verifyLevel == EFileVerifyLevel.Low) + { + if (File.Exists(element.InfoFilePath) == false) + return EFileVerifyResult.InfoFileNotExisted; + if (File.Exists(element.DataFilePath) == false) + return EFileVerifyResult.DataFileNotExisted; + return EFileVerifyResult.Succeed; + } + else + { + if (File.Exists(element.InfoFilePath) == false) + return EFileVerifyResult.InfoFileNotExisted; + + // 解析信息文件获取验证数据 + _fileSystem.ReadInfoFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize); + } + } + catch (Exception) + { + return EFileVerifyResult.Exception; + } + + return FileSystemHelper.FileVerify(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyCacheFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs.meta index c0aa9baf..62a7722f 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyCacheFilesOperation.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 868188d19436b674b8c403d2d90afeaf +guid: 5e9325baa24ae234ea0208d70dd3347e MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs new file mode 100644 index 00000000..b3fa80a0 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs @@ -0,0 +1,112 @@ +using System; +using System.Threading; + +namespace YooAsset +{ + internal class TempFileElement + { + public string TempFilePath { private set; get; } + public string TempFileCRC { private set; get; } + public long TempFileSize { private set; get; } + + /// + /// 注意:原子操作对象 + /// + public int Result = 0; + + public TempFileElement(string filePath, string fileCRC, long fileSize) + { + TempFilePath = filePath; + TempFileCRC = fileCRC; + TempFileSize = fileSize; + } + } + + /// + /// 下载文件验证(线程版) + /// + internal class VerifyTempFileOperation : AsyncOperationBase + { + private enum ESteps + { + None, + VerifyFile, + Waiting, + Done, + } + + private readonly TempFileElement _element; + private ESteps _steps = ESteps.None; + + /// + /// 验证结果 + /// + public EFileVerifyResult VerifyResult { protected set; get; } + + + internal VerifyTempFileOperation(TempFileElement element) + { + _element = element; + } + internal override void InternalOnStart() + { + _steps = ESteps.VerifyFile; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.VerifyFile) + { + if (BeginVerifyFileWithThread(_element)) + { + _steps = ESteps.Waiting; + } + } + + if (_steps == ESteps.Waiting) + { + int result = _element.Result; + if (result == 0) + return; + + VerifyResult = (EFileVerifyResult)result; + if (VerifyResult == EFileVerifyResult.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed verify file : {_element.TempFilePath} ! ErrorCode : {VerifyResult}"; + } + } + } + public override void WaitForAsyncComplete() + { + while (true) + { + // 驱动流程 + InternalOnUpdate(); + + // 完成后退出 + if (IsDone) + break; + } + } + + private bool BeginVerifyFileWithThread(TempFileElement element) + { + return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element); + } + private void VerifyInThread(object obj) + { + TempFileElement element = (TempFileElement)obj; + int result = (int)FileSystemHelper.FileVerify(element.TempFilePath, element.TempFileSize, element.TempFileCRC, EFileVerifyLevel.High); + element.Result = result; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyTempFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyTempFileOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs.meta index 9abd50f2..36ed7d72 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyTempFileOperation.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: cd356e68c5b4ef04ab018a6388f5173a +guid: 764ac4f47afd3be4a8d583578f51126d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem.meta new file mode 100644 index 00000000..93b1ffb0 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ca2dc2186da7a2847b300c398600e472 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs new file mode 100644 index 00000000..efe00e2d --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs @@ -0,0 +1,206 @@ +using System; +using System.IO; +using System.Collections.Generic; +using UnityEngine; + +namespace YooAsset +{ + /// + /// 内置文件系统 + /// + internal class DefaultEditorFileSystem : IFileSystem + { + protected string _packageRoot; + + + /// + /// 包裹名称 + /// + public string PackageName { private set; get; } + + /// + /// 文件访问权限 + /// + public EFileAccess FileSystemAccess + { + get + { + return EFileAccess.Read; + } + } + + /// + /// 文件根目录 + /// + public string FileRoot + { + get + { + return _packageRoot; + } + } + + /// + /// 文件数量 + /// + public int FileCount + { + get + { + return 0; + } + } + + #region 自定义参数 + /// + /// 自定义参数:模拟运行的资源清单文件路径 + /// + public string SimulateManifestFilePath { private set; get; } = string.Empty; + #endregion + + + public DefaultEditorFileSystem() + { + } + public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + { + var operation = new DEFSInitializeOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(params object[] args) + { + var operation = new DEFSLoadPackageManifestOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(params object[] args) + { + throw new System.NotImplementedException(); + } + public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync(params object[] args) + { + var operation = new DEFSClearAllBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(params object[] args) + { + var operation = new DEFSClearUnusedBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSDownloadFileOperation DownloadFileAsync(params object[] args) + { + PackageBundle bundle = args[0] as PackageBundle; + var operation = new DEFSDownloadFileOperation(bundle); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + + public virtual void SetParameter(string name, object value) + { + if (name == "SIMULATE_MANIFEST_FILE_PATH") + { + SimulateManifestFilePath = (string)value; + } + else + { + YooLogger.Warning($"Invalid parameter : {name}"); + } + } + public virtual void OnCreate(string packageName, string rootDirectory) + { + PackageName = packageName; + + if (string.IsNullOrEmpty(rootDirectory)) + rootDirectory = GetDefaultRoot(); + + _packageRoot = PathUtility.Combine(rootDirectory, packageName); + } + public virtual void OnUpdate() + { + } + + public virtual bool Belong(PackageBundle bundle) + { + return true; + } + public virtual bool Belong(string bundleGUID) + { + return true; + } + public virtual bool Exists(PackageBundle bundle) + { + return true; + } + public virtual bool Exists(string bundleGUID) + { + return true; + } + + public virtual bool CheckNeedDownload(PackageBundle bundle) + { + return false; + } + public virtual bool CheckNeedUnpack(PackageBundle bundle) + { + return false; + } + public virtual bool CheckNeedImport(PackageBundle bundle) + { + return false; + } + + public virtual bool WriteFile(PackageBundle bundle, string copyPath) + { + return true; + } + public virtual bool DeleteFile(PackageBundle bundle) + { + return true; + } + public virtual bool DeleteFile(string bundleGUID) + { + return true; + } + public virtual EFileVerifyResult VerifyFile(PackageBundle bundle) + { + return EFileVerifyResult.Succeed; + } + + public virtual byte[] ReadFileBytes(PackageBundle bundle) + { + throw new System.NotImplementedException(); + } + public virtual string ReadFileText(PackageBundle bundle) + { + throw new System.NotImplementedException(); + } + + public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + { + var operation = new DEFSLoadBundleOperation(this, bundle); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual void UnloadBundleFile(PackageBundle bundle, object result) + { + } + + #region 内部方法 + protected string GetDefaultRoot() + { + return "Assets/"; + } + + /// + /// 记录缓存信息 + /// + public bool Record(string bundleGUID, object value) + { + return true; + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs.meta new file mode 100644 index 00000000..0f3718ce --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 53f40d241c7bcf340841a33459678568 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs new file mode 100644 index 00000000..eb0771e2 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs @@ -0,0 +1,7 @@ + +namespace YooAsset +{ + internal class DefaultEditorFileSystemDefine + { + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs.meta new file mode 100644 index 00000000..75b6d175 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d6d4ba58bf1a1bb4db469b2cdd741ad0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation.meta new file mode 100644 index 00000000..1919e6f9 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3779423aa03ffb6499efda626280c72a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearAllBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearAllBundleFilesOperation.cs new file mode 100644 index 00000000..557bb425 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearAllBundleFilesOperation.cs @@ -0,0 +1,20 @@ + +namespace YooAsset +{ + internal sealed class DEFSClearAllBundleFilesOperation : FSClearAllBundleFilesOperation + { + private readonly DefaultEditorFileSystem _fileSystem; + + internal DEFSClearAllBundleFilesOperation(DefaultEditorFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + Status = EOperationStatus.Succeed; + } + internal override void InternalOnUpdate() + { + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearAllBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearAllBundleFilesOperation.cs.meta new file mode 100644 index 00000000..982b339a --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearAllBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a16dae8497d54984daa95a3682a7beb4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearUnusedBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearUnusedBundleFilesOperation.cs new file mode 100644 index 00000000..268f1043 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearUnusedBundleFilesOperation.cs @@ -0,0 +1,20 @@ + +namespace YooAsset +{ + internal sealed class DEFSClearUnusedBundleFilesOperation : FSClearUnusedBundleFilesOperation + { + private readonly DefaultEditorFileSystem _fileSystem; + + internal DEFSClearUnusedBundleFilesOperation(DefaultEditorFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + Status = EOperationStatus.Succeed; + } + internal override void InternalOnUpdate() + { + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearUnusedBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearUnusedBundleFilesOperation.cs.meta new file mode 100644 index 00000000..abf8526f --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearUnusedBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f86d3bce4381694b8c619ceda2e7309 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSDownloadFileOperation.cs new file mode 100644 index 00000000..bf8f3ff1 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSDownloadFileOperation.cs @@ -0,0 +1,17 @@ + +namespace YooAsset +{ + internal class DEFSDownloadFileOperation : FSDownloadFileOperation + { + internal DEFSDownloadFileOperation(PackageBundle bundle) : base(bundle) + { + } + internal override void InternalOnStart() + { + Status = EOperationStatus.Succeed; + } + internal override void InternalOnUpdate() + { + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSDownloadFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSDownloadFileOperation.cs.meta new file mode 100644 index 00000000..3e8607bb --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSDownloadFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06a8abe71cf3fe64180ec076a79b4b66 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs new file mode 100644 index 00000000..8172e85e --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs @@ -0,0 +1,20 @@ + +namespace YooAsset +{ + internal class DEFSInitializeOperation : FSInitializeFileSystemOperation + { + private readonly DefaultEditorFileSystem _fileSytem; + + internal DEFSInitializeOperation(DefaultEditorFileSystem fileSystem) + { + _fileSytem = fileSystem; + } + internal override void InternalOnStart() + { + Status = EOperationStatus.Succeed; + } + internal override void InternalOnUpdate() + { + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs.meta new file mode 100644 index 00000000..01a90c46 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 99cfeba8095613442992a0e21a248b73 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs new file mode 100644 index 00000000..c5119f17 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs @@ -0,0 +1,31 @@ + +namespace YooAsset +{ + internal class DEFSLoadBundleOperation : FSLoadBundleOperation + { + private readonly DefaultEditorFileSystem _fileSystem; + private readonly PackageBundle _bundle; + + internal DEFSLoadBundleOperation(DefaultEditorFileSystem fileSystem, PackageBundle bundle) + { + _fileSystem = fileSystem; + _bundle = bundle; + } + internal override void InternalOnStart() + { + DownloadProgress = 1f; + DownloadedBytes = _bundle.FileSize; + Status = EOperationStatus.Succeed; + } + internal override void InternalOnUpdate() + { + } + + public override void WaitForAsyncComplete() + { + } + public override void AbortDownloadOperation() + { + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs.meta new file mode 100644 index 00000000..e35fb24e --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 47b871368218c7c49920927c10c6955e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs new file mode 100644 index 00000000..bf65e449 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs @@ -0,0 +1,58 @@ + +namespace YooAsset +{ + internal class DEFSLoadPackageManifestOperation : FSLoadPackageManifestOperation + { + private enum ESteps + { + None, + LoadEditorPackageManifest, + Done, + } + + private readonly DefaultEditorFileSystem _fileSystem; + private LoadEditorPackageManifestOperation _loadEditorPackageManifestOp; + private ESteps _steps = ESteps.None; + + + internal DEFSLoadPackageManifestOperation(DefaultEditorFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + _steps = ESteps.LoadEditorPackageManifest; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadEditorPackageManifest) + { + if (_loadEditorPackageManifestOp == null) + { + _loadEditorPackageManifestOp = new LoadEditorPackageManifestOperation(_fileSystem); + OperationSystem.StartOperation(_fileSystem.PackageName, _loadEditorPackageManifestOp); + } + + Progress = _loadEditorPackageManifestOp.Progress; + if (_loadEditorPackageManifestOp.IsDone == false) + return; + + if (_loadEditorPackageManifestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Result = _loadEditorPackageManifestOp.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadEditorPackageManifestOp.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs.meta new file mode 100644 index 00000000..d933afcb --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3abaff43b56f62489688162296203cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal.meta new file mode 100644 index 00000000..69f062b2 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cf9de625784f5fe41a8d4fc53bf71ff0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadEditorManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs similarity index 53% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadEditorManifestOperation.cs rename to Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs index 2dc1093b..a25cccef 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadEditorManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs @@ -2,19 +2,19 @@ namespace YooAsset { - internal class LoadEditorManifestOperation : AsyncOperationBase + internal class LoadEditorPackageManifestOperation : AsyncOperationBase { private enum ESteps { None, - LoadEditorManifest, - CheckDeserializeManifest, + LoadFileData, + LoadManifest, Done, } - private readonly string _packageName; - private readonly string _manifestFilePath; + private readonly DefaultEditorFileSystem _fileSystem; private DeserializeManifestOperation _deserializer; + private byte[] _fileData; private ESteps _steps = ESteps.None; /// @@ -23,47 +23,51 @@ namespace YooAsset public PackageManifest Manifest { private set; get; } - public LoadEditorManifestOperation(string packageName, string manifestFilePath) + internal LoadEditorPackageManifestOperation(DefaultEditorFileSystem fileSystem) { - _packageName = packageName; - _manifestFilePath = manifestFilePath; + _fileSystem = fileSystem; } internal override void InternalOnStart() { - _steps = ESteps.LoadEditorManifest; + _steps = ESteps.LoadFileData; } internal override void InternalOnUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.LoadEditorManifest) + if (_steps == ESteps.LoadFileData) { - if (File.Exists(_manifestFilePath) == false) + string manifestFilePath = _fileSystem.SimulateManifestFilePath; + if (File.Exists(manifestFilePath)) + { + _steps = ESteps.LoadManifest; + _fileData = FileUtility.ReadAllBytes(manifestFilePath); + } + else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Not found simulation manifest file : {_manifestFilePath}"; - return; + Error = $"Simulation manifest file not found : {manifestFilePath}"; } - - YooLogger.Log($"Load editor manifest file : {_manifestFilePath}"); - byte[] bytesData = FileUtility.ReadAllBytes(_manifestFilePath); - _deserializer = new DeserializeManifestOperation(bytesData); - OperationSystem.StartOperation(_packageName, _deserializer); - _steps = ESteps.CheckDeserializeManifest; } - if (_steps == ESteps.CheckDeserializeManifest) + if (_steps == ESteps.LoadManifest) { + if (_deserializer == null) + { + _deserializer = new DeserializeManifestOperation(_fileData); + OperationSystem.StartOperation(_fileSystem.PackageName, _deserializer); + } + Progress = _deserializer.Progress; if (_deserializer.IsDone == false) return; if (_deserializer.Status == EOperationStatus.Succeed) { - Manifest = _deserializer.Manifest; _steps = ESteps.Done; + Manifest = _deserializer.Manifest; Status = EOperationStatus.Succeed; } else diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs.meta new file mode 100644 index 00000000..eb985ede --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6504949dca3fbf4fbb8c61c3ab9c51f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem.meta new file mode 100644 index 00000000..343af569 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 07e60a75ff092314cb4d9ba6d5b14296 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs new file mode 100644 index 00000000..0d6fbaa4 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs @@ -0,0 +1,21 @@ + +namespace YooAsset +{ + /// + /// 缓存文件系统 + /// + internal class DefaultUnpackFileSystem : DefaultCacheFileSystem + { + public DefaultUnpackFileSystem() + { + } + public override void OnCreate(string packageName, string rootDirectory) + { + base.OnCreate(packageName, rootDirectory); + + // 注意:重写保存根目录和临时目录 + _saveFileRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.SaveFilesFolderName); + _tempFileRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.TempFilesFolderName); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs.meta new file mode 100644 index 00000000..9d0d1db6 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0bb4584d46f520741bcf6f52b67746d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs new file mode 100644 index 00000000..2cc50180 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs @@ -0,0 +1,21 @@ + +namespace YooAsset +{ + internal class DefaultUnpackFileSystemDefine + { + /// + /// 文件系统的优先级 + /// + public const int DefaultPriority = 11; + + /// + /// 保存的资源文件的文件夹名称 + /// + public const string SaveFilesFolderName = "UnpackFiles"; + + /// + /// 下载的临时文件的文件夹名称 + /// + public const string TempFilesFolderName = "UnpackTempFiles"; + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs.meta new file mode 100644 index 00000000..ca2e3da2 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee46c041e2affd349929df43af3f21c1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem.meta new file mode 100644 index 00000000..eca7b1f4 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 17d469f0c029a034bafe8d17a3db9ee5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/DefaultWebFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/DefaultWebFileSystem.cs new file mode 100644 index 00000000..1b7e9d09 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/DefaultWebFileSystem.cs @@ -0,0 +1,277 @@ +using System; +using System.IO; +using System.Collections.Generic; +using UnityEngine; + +namespace YooAsset +{ + internal class DefaultWebFileSystem : IFileSystem + { + public class FileWrapper + { + public string FileName { private set; get; } + + public FileWrapper(string fileName) + { + FileName = fileName; + } + } + + protected readonly Dictionary _wrappers = new Dictionary(10000); + protected readonly Dictionary _webFilePaths = new Dictionary(10000); + protected string _webPackageRoot = string.Empty; + + + /// + /// 包裹名称 + /// + public string PackageName { private set; get; } + + /// + /// 文件访问权限 + /// + public EFileAccess FileSystemAccess + { + get + { + return EFileAccess.ReadWrite; + } + } + + /// + /// 文件根目录 + /// + public string FileRoot + { + get + { + return _webPackageRoot; + } + } + + /// + /// 文件数量 + /// + public int FileCount + { + get + { + return 0; + } + } + + #region 自定义参数 + public bool AllowCrossAccess { private set; get; } = false; + + /// + /// 自定义参数:远程服务接口 + /// + public IRemoteServices RemoteServices { private set; get; } = null; + #endregion + + + public DefaultWebFileSystem() + { + } + public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + { + var operation = new DWFSInitializeOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(params object[] args) + { + string packageVersion = args[0] as string; + int timeout = (int)args[1]; + + if (AllowCrossAccess) + { + var operation = new DWFSLoadRemotePackageManifestOperation(this, packageVersion, timeout); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + else + { + var operation = new DWFSLoadWebPackageManifestOperation(this, timeout); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + } + public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(params object[] args) + { + bool appendTimeTicks = (bool)args[0]; + int timeout = (int)args[1]; + var operation = new DWFSRequestPackageVersionOperation(this, appendTimeTicks, timeout); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync(params object[] args) + { + var operation = new DWFSClearAllBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(params object[] args) + { + var operation = new DWFSClearUnusedBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSDownloadFileOperation DownloadFileAsync(params object[] args) + { + throw new System.NotImplementedException(); + } + + public virtual void SetParameter(string name, object value) + { + if (name == "ALLOW_CROSS_ACCESS") + { + AllowCrossAccess = (bool)value; + } + else if (name == "REMOTE_SERVICES") + { + RemoteServices = (IRemoteServices)value; + } + else + { + YooLogger.Warning($"Invalid parameter : {name}"); + } + } + public virtual void OnCreate(string packageName, string rootDirectory) + { + PackageName = packageName; + + if (string.IsNullOrEmpty(rootDirectory)) + rootDirectory = GetDefaultWebRoot(); + + _webPackageRoot = PathUtility.Combine(rootDirectory, packageName); + } + public virtual void OnUpdate() + { + } + + public virtual bool Belong(PackageBundle bundle) + { + return true; + } + public virtual bool Belong(string bundleGUID) + { + return true; + } + public virtual bool Exists(PackageBundle bundle) + { + return false; + } + public virtual bool Exists(string bundleGUID) + { + return false; + } + + public virtual bool CheckNeedDownload(PackageBundle bundle) + { + return false; + } + public virtual bool CheckNeedUnpack(PackageBundle bundle) + { + return false; + } + public virtual bool CheckNeedImport(PackageBundle bundle) + { + return false; + } + + public virtual bool WriteFile(PackageBundle bundle, string copyPath) + { + throw new System.NotImplementedException(); + } + public virtual bool DeleteFile(PackageBundle bundle) + { + throw new System.NotImplementedException(); + } + public virtual bool DeleteFile(string bundleGUID) + { + throw new System.NotImplementedException(); + } + public virtual EFileVerifyResult VerifyFile(PackageBundle bundle) + { + return EFileVerifyResult.Succeed; + } + + public virtual byte[] ReadFileBytes(PackageBundle bundle) + { + throw new System.NotImplementedException(); + } + public virtual string ReadFileText(PackageBundle bundle) + { + throw new System.NotImplementedException(); + } + + public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + { + var operation = new DWFSLoadAssetBundleOperation(this, bundle); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual void UnloadBundleFile(PackageBundle bundle, object result) + { + AssetBundle assetBundle = result as AssetBundle; + if (assetBundle == null) + return; + + if (assetBundle != null) + assetBundle.Unload(true); + } + + #region 内部方法 + protected string GetDefaultWebRoot() + { + string path = PathUtility.Combine(UnityEngine.Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName); + return path; + } + public string GetWebFileLoadPath(PackageBundle bundle) + { + if (_webFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false) + { + filePath = PathUtility.Combine(_webPackageRoot, bundle.FileName); + _webFilePaths.Add(bundle.BundleGUID, filePath); + } + return filePath; + } + public string GetCatalogFileLoadPath() + { + string fileName = Path.GetFileNameWithoutExtension(DefaultBuildinFileSystemDefine.BuildinCatalogFileName); + return PathUtility.Combine(YooAssetSettingsData.Setting.DefaultYooFolderName, PackageName, fileName); + } + public string GetWebPackageVersionFilePath() + { + string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName); + return PathUtility.Combine(FileRoot, fileName); + } + public string GetWebPackageHashFilePath(string packageVersion) + { + string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion); + return PathUtility.Combine(FileRoot, fileName); + } + public string GetWebPackageManifestFilePath(string packageVersion) + { + string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion); + return PathUtility.Combine(FileRoot, fileName); + } + + /// + /// 记录缓存信息 + /// + public bool Record(string bundleGUID, FileWrapper wrapper) + { + if (_wrappers.ContainsKey(bundleGUID)) + { + YooLogger.Error($"{nameof(DefaultWebFileSystem)} has element : {bundleGUID}"); + return false; + } + + _wrappers.Add(bundleGUID, wrapper); + return true; + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/DefaultWebFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/DefaultWebFileSystem.cs.meta new file mode 100644 index 00000000..fd8fb455 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/DefaultWebFileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0772e17daa1b32b4a80a6211396a50e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation.meta new file mode 100644 index 00000000..03b9c15d --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fe53f557bb5cf3242a04b3fce756dd38 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearAllBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearAllBundleFilesOperation.cs new file mode 100644 index 00000000..439a8ccf --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearAllBundleFilesOperation.cs @@ -0,0 +1,20 @@ + +namespace YooAsset +{ + internal sealed class DWFSClearAllBundleFilesOperation : FSClearAllBundleFilesOperation + { + private readonly DefaultWebFileSystem _fileSystem; + + internal DWFSClearAllBundleFilesOperation(DefaultWebFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + Status = EOperationStatus.Succeed; + } + internal override void InternalOnUpdate() + { + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearAllBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearAllBundleFilesOperation.cs.meta new file mode 100644 index 00000000..cd41a65a --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearAllBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 68578d4c5e39a554aa3df2e7ec5218e9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearUnusedBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearUnusedBundleFilesOperation.cs new file mode 100644 index 00000000..6ce6b0f4 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearUnusedBundleFilesOperation.cs @@ -0,0 +1,20 @@ + +namespace YooAsset +{ + internal sealed class DWFSClearUnusedBundleFilesOperation : FSClearUnusedBundleFilesOperation + { + private readonly DefaultWebFileSystem _fileSystem; + + internal DWFSClearUnusedBundleFilesOperation(DefaultWebFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + Status = EOperationStatus.Succeed; + } + internal override void InternalOnUpdate() + { + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearUnusedBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearUnusedBundleFilesOperation.cs.meta new file mode 100644 index 00000000..1d8a7b0c --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearUnusedBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1560968379b66d440a94382b2a311a15 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSDownloadFileOperation.cs new file mode 100644 index 00000000..46ad3534 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSDownloadFileOperation.cs @@ -0,0 +1,137 @@ +using System.IO; +using UnityEngine; +using UnityEngine.Networking; + +namespace YooAsset +{ + internal class DWFSDownloadWebFileOperation : DefaultDownloadFileOperation + { + private readonly DefaultWebFileSystem _fileSystem; + private DownloadHandlerAssetBundle _downloadhandler; + private ESteps _steps = ESteps.None; + + /// + /// 下载结果 + /// + public AssetBundle Result { private set; get; } + + + internal DWFSDownloadWebFileOperation(DefaultWebFileSystem fileSystem, PackageBundle bundle, string mainURL, string fallbackURL, int failedTryAgain, int timeout) + : base(bundle, mainURL, fallbackURL, failedTryAgain, timeout) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 创建下载器 + if (_steps == ESteps.CreateRequest) + { + // 获取请求地址 + _requestURL = GetRequestURL(); + + // 重置变量 + _isAbort = false; + _latestDownloadBytes = 0; + _latestDownloadRealtime = Time.realtimeSinceStartup; + DownloadProgress = 0f; + DownloadedBytes = 0; + + // 重置计时器 + if (_tryAgainTimer > 0f) + YooLogger.Warning($"Try again download : {_requestURL}"); + _tryAgainTimer = 0f; + + // 创建下载器 + CreateWebRequest(); + + _steps = ESteps.CheckRequest; + } + + // 检测下载结果 + if (_steps == ESteps.CheckRequest) + { + DownloadProgress = _webRequest.downloadProgress; + DownloadedBytes = (long)_webRequest.downloadedBytes; + Progress = DownloadProgress; + if (_webRequest.isDone == false) + { + CheckRequestTimeout(); + return; + } + + // 检查网络错误 + if (CheckRequestResult()) + { + _steps = ESteps.Done; + Result = _downloadhandler.assetBundle; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.TryAgain; + } + + // 注意:最终释放请求器 + DisposeWebRequest(); + } + + // 重新尝试下载 + if (_steps == ESteps.TryAgain) + { + if (FailedTryAgain <= 0) + { + Status = EOperationStatus.Failed; + _steps = ESteps.Done; + YooLogger.Error(Error); + return; + } + + _tryAgainTimer += Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + FailedTryAgain--; + _steps = ESteps.CreateRequest; + YooLogger.Warning(Error); + } + } + } + internal override void InternalOnAbort() + { + _steps = ESteps.Done; + DisposeWebRequest(); + } + + private void CreateWebRequest() + { + uint unityCRC = Bundle.UnityCRC; + Hash128 fileHash = Hash128.Parse(Bundle.FileHash); + + // 注意:优先从浏览器缓存里获取文件 + // The file hash defining the version of the asset bundle. + _webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL); + _downloadhandler = new DownloadHandlerAssetBundle(_requestURL, fileHash, unityCRC); +#if UNITY_2020_3_OR_NEWER + _downloadhandler.autoLoadAssetBundle = false; +#endif + _webRequest.downloadHandler = _downloadhandler; + _webRequest.disposeDownloadHandlerOnDispose = true; + _webRequest.SendWebRequest(); + } + private void DisposeWebRequest() + { + if (_webRequest != null) + { + //注意:引擎底层会自动调用Abort方法 + _webRequest.Dispose(); + _webRequest = null; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSDownloadFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSDownloadFileOperation.cs.meta new file mode 100644 index 00000000..08958f56 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSDownloadFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b82b4b846083d34b958320b584d8d9b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSInitializeOperation.cs new file mode 100644 index 00000000..f46ce372 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSInitializeOperation.cs @@ -0,0 +1,49 @@ + +namespace YooAsset +{ + internal partial class DWFSInitializeOperation : FSInitializeFileSystemOperation + { + private enum ESteps + { + None, + LoadCatalogFile, + Done, + } + + private readonly DefaultWebFileSystem _fileSystem; + private LoadWebCatalogFileOperation _loadCatalogFileOp; + private ESteps _steps = ESteps.None; + + + public DWFSInitializeOperation(DefaultWebFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + _steps = ESteps.LoadCatalogFile; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadCatalogFile) + { + if (_loadCatalogFileOp == null) + { + _loadCatalogFileOp = new LoadWebCatalogFileOperation(_fileSystem); + OperationSystem.StartOperation(_fileSystem.PackageName, _loadCatalogFileOp); + } + + if (_loadCatalogFileOp.IsDone == false) + return; + + // 说明:应用程序内不一定存在序列化文件 + // 注意:总是返回成功 + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSInitializeOperation.cs.meta new file mode 100644 index 00000000..a941c141 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c7cf2dca805b0b4d91cb5e0782dcb0c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadBundleOperation.cs new file mode 100644 index 00000000..1313863f --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadBundleOperation.cs @@ -0,0 +1,87 @@ + +namespace YooAsset +{ + internal class DWFSLoadAssetBundleOperation : FSLoadBundleOperation + { + private enum ESteps + { + None, + DownloadFile, + CheckResult, + Done, + } + + private readonly DefaultWebFileSystem _fileSystem; + private readonly PackageBundle _bundle; + private DWFSDownloadWebFileOperation _downloadWebFileOp; + private ESteps _steps = ESteps.None; + + + internal DWFSLoadAssetBundleOperation(DefaultWebFileSystem fileSystem, PackageBundle bundle) + { + _fileSystem = fileSystem; + _bundle = bundle; + } + internal override void InternalOnStart() + { + DownloadProgress = 0f; + DownloadedBytes = 0; + _steps = ESteps.DownloadFile; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.DownloadFile) + { + if (_downloadWebFileOp == null) + { + int failedTryAgain = int.MaxValue; + int timeout = 60; + string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); + string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName); + _downloadWebFileOp = new DWFSDownloadWebFileOperation(_fileSystem, _bundle, mainURL, fallbackURL, failedTryAgain, timeout); + } + + DownloadProgress = _downloadWebFileOp.DownloadProgress; + DownloadedBytes = _downloadWebFileOp.DownloadedBytes; + Progress = _downloadWebFileOp.Progress; + if (_downloadWebFileOp.IsDone == false) + return; + + if (_downloadWebFileOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Result = _downloadWebFileOp.Result; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadWebFileOp.Error; + } + } + } + + public override void WaitForAsyncComplete() + { + if (IsDone == false) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "WebGL platform not support sync load method !"; + UnityEngine.Debug.LogError(Error); + } + } + public override void AbortDownloadOperation() + { + if (_steps == ESteps.DownloadFile) + { + if (_downloadWebFileOp != null) + _downloadWebFileOp.SetAbort(); + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadBundleOperation.cs.meta new file mode 100644 index 00000000..67b3f784 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a50dacdf7a3ad7c40a4195126425bbec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadPackageManifestOperation.cs new file mode 100644 index 00000000..12ca51d8 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadPackageManifestOperation.cs @@ -0,0 +1,198 @@ + +namespace YooAsset +{ + internal class DWFSLoadWebPackageManifestOperation : FSLoadPackageManifestOperation + { + private enum ESteps + { + None, + RequestWebPackageVersion, + RequestWebPackageHash, + LoadWebPackageManifest, + Done, + } + + private readonly DefaultWebFileSystem _fileSystem; + private readonly int _timeout; + private RequestWebPackageVersionOperation _requestWebPackageVersionOp; + private RequestWebPackageHashOperation _requestWebPackageHashOp; + private LoadWebPackageManifestOperation _loadWebPackageManifestOp; + private ESteps _steps = ESteps.None; + + + public DWFSLoadWebPackageManifestOperation(DefaultWebFileSystem fileSystem, int timeout) + { + _fileSystem = fileSystem; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _steps = ESteps.RequestWebPackageVersion; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestWebPackageVersion) + { + if (_requestWebPackageVersionOp == null) + { + _requestWebPackageVersionOp = new RequestWebPackageVersionOperation(_fileSystem, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _requestWebPackageVersionOp); + } + + if (_requestWebPackageVersionOp.IsDone == false) + return; + + if (_requestWebPackageVersionOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.RequestWebPackageHash; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _requestWebPackageVersionOp.Error; + } + } + + if (_steps == ESteps.RequestWebPackageHash) + { + if (_requestWebPackageHashOp == null) + { + string packageVersion = _requestWebPackageVersionOp.PackageVersion; + _requestWebPackageHashOp = new RequestWebPackageHashOperation(_fileSystem, packageVersion, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _requestWebPackageHashOp); + } + + if (_requestWebPackageHashOp.IsDone == false) + return; + + if (_requestWebPackageHashOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadWebPackageManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _requestWebPackageHashOp.Error; + } + } + + if (_steps == ESteps.LoadWebPackageManifest) + { + if (_loadWebPackageManifestOp == null) + { + string packageVersion = _requestWebPackageVersionOp.PackageVersion; + string packageHash = _requestWebPackageHashOp.PackageHash; + _loadWebPackageManifestOp = new LoadWebPackageManifestOperation(_fileSystem, packageVersion, packageHash); + OperationSystem.StartOperation(_fileSystem.PackageName, _loadWebPackageManifestOp); + } + + Progress = _loadWebPackageManifestOp.Progress; + if (_loadWebPackageManifestOp.IsDone == false) + return; + + if (_loadWebPackageManifestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Result = _loadWebPackageManifestOp.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadWebPackageManifestOp.Error; + } + } + } + } + + internal class DWFSLoadRemotePackageManifestOperation : FSLoadPackageManifestOperation + { + private enum ESteps + { + None, + RequestRemotePackageHash, + LoadRemotePackageManifest, + Done, + } + + private readonly DefaultWebFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly int _timeout; + private RequestRemotePackageHashOperation _requestRemotePackageHashOp; + private LoadRemotePackageManifestOperation _loadRemotePackageManifestOp; + private ESteps _steps = ESteps.None; + + + public DWFSLoadRemotePackageManifestOperation(DefaultWebFileSystem fileSystem, string packageVersion, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _steps = ESteps.RequestRemotePackageHash; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestRemotePackageHash) + { + if (_requestRemotePackageHashOp == null) + { + _requestRemotePackageHashOp = new RequestRemotePackageHashOperation(_fileSystem, _packageVersion, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _requestRemotePackageHashOp); + } + + if (_requestRemotePackageHashOp.IsDone == false) + return; + + if (_requestRemotePackageHashOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadRemotePackageManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _requestRemotePackageHashOp.Error; + } + } + + if (_steps == ESteps.LoadRemotePackageManifest) + { + if (_loadRemotePackageManifestOp == null) + { + string packageHash = _requestRemotePackageHashOp.PackageHash; + _loadRemotePackageManifestOp = new LoadRemotePackageManifestOperation(_fileSystem, _packageVersion, packageHash, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _loadRemotePackageManifestOp); + } + + Progress = _loadRemotePackageManifestOp.Progress; + if (_loadRemotePackageManifestOp.IsDone == false) + return; + + if (_loadRemotePackageManifestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Result = _loadRemotePackageManifestOp.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadRemotePackageManifestOp.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadPackageManifestOperation.cs.meta new file mode 100644 index 00000000..40d0fe56 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0d0f8063cfabb5d40b364f162ce49fc0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSRequestPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSRequestPackageVersionOperation.cs new file mode 100644 index 00000000..384616ae --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSRequestPackageVersionOperation.cs @@ -0,0 +1,66 @@ + +namespace YooAsset +{ + internal class DWFSRequestPackageVersionOperation : FSRequestPackageVersionOperation + { + private enum ESteps + { + None, + GetPackageVersion, + Done, + } + + private readonly DefaultWebFileSystem _fileSystem; + private readonly bool _appendTimeTicks; + private readonly int _timeout; + private DefaultGetRemotePackageVersionOperation _getRemotePackageVersionOp; + private ESteps _steps = ESteps.None; + + + internal DWFSRequestPackageVersionOperation(DefaultWebFileSystem fileSystem, bool appendTimeTicks, int timeout) + { + _fileSystem = fileSystem; + _appendTimeTicks = appendTimeTicks; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _steps = ESteps.GetPackageVersion; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.GetPackageVersion) + { + if (_getRemotePackageVersionOp == null) + { + string packageName = _fileSystem.PackageName; + string fileName = YooAssetSettingsData.GetPackageVersionFileName(packageName); + string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(fileName); + string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName); + _getRemotePackageVersionOp = new DefaultGetRemotePackageVersionOperation(packageName, mainURL, fallbackURL, _appendTimeTicks, _timeout); + OperationSystem.StartOperation(packageName, _getRemotePackageVersionOp); + } + + Progress = _getRemotePackageVersionOp.Progress; + if (_getRemotePackageVersionOp.IsDone == false) + return; + + if (_getRemotePackageVersionOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + PackageVersion = _getRemotePackageVersionOp.PackageVersion; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _getRemotePackageVersionOp.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSRequestPackageVersionOperation.cs.meta new file mode 100644 index 00000000..4b85fd96 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSRequestPackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 212a79e362fe6234c81fa79c3924dd20 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal.meta new file mode 100644 index 00000000..53accb53 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0e91f62e8fc7c1f4592681b7881ad925 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadRemotePackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadRemotePackageManifestOperation.cs new file mode 100644 index 00000000..42edc568 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadRemotePackageManifestOperation.cs @@ -0,0 +1,125 @@ + +namespace YooAsset +{ + internal class LoadRemotePackageManifestOperation : AsyncOperationBase + { + private enum ESteps + { + None, + RequestFileData, + VerifyFileData, + LoadManifest, + Done, + } + + private readonly DefaultWebFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly string _packageHash; + private readonly int _timeout; + private UnityWebDataRequestOperation _webDataRequestOp; + private DeserializeManifestOperation _deserializer; + private int _requestCount = 0; + private ESteps _steps = ESteps.None; + + /// + /// 加载的清单实例 + /// + public PackageManifest Manifest { private set; get; } + + + internal LoadRemotePackageManifestOperation(DefaultWebFileSystem fileSystem, string packageVersion, string packageHash, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _packageHash = packageHash; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(LoadRemotePackageManifestOperation)); + _steps = ESteps.RequestFileData; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestFileData) + { + if (_webDataRequestOp == null) + { + string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion); + string url = GetDownloadRequestURL(fileName); + _webDataRequestOp = new UnityWebDataRequestOperation(url, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _webDataRequestOp); + } + + Progress = _webDataRequestOp.Progress; + if (_webDataRequestOp.IsDone == false) + return; + + if (_webDataRequestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.VerifyFileData; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webDataRequestOp.Error; + WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(LoadRemotePackageManifestOperation)); + } + } + + if (_steps == ESteps.VerifyFileData) + { + string fileHash = HashUtility.BytesMD5(_webDataRequestOp.Result); + if (fileHash == _packageHash) + { + _steps = ESteps.LoadManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Failed to verify remote package manifest file!"; + } + } + + if (_steps == ESteps.LoadManifest) + { + if (_deserializer == null) + { + _deserializer = new DeserializeManifestOperation(_webDataRequestOp.Result); + OperationSystem.StartOperation(_fileSystem.PackageName, _deserializer); + } + + Progress = _deserializer.Progress; + if (_deserializer.IsDone == false) + return; + + if (_deserializer.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Manifest = _deserializer.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _deserializer.Error; + } + } + } + + private string GetDownloadRequestURL(string fileName) + { + // 轮流返回请求地址 + if (_requestCount % 2 == 0) + return _fileSystem.RemoteServices.GetRemoteMainURL(fileName); + else + return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadRemotePackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadRemotePackageManifestOperation.cs.meta new file mode 100644 index 00000000..183900fb --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadRemotePackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c2153284d246964fb2146f9fdda311c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebCatalogFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebCatalogFileOperation.cs new file mode 100644 index 00000000..a6fa1cad --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebCatalogFileOperation.cs @@ -0,0 +1,72 @@ +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace YooAsset +{ + internal sealed class LoadWebCatalogFileOperation : AsyncOperationBase + { + private enum ESteps + { + None, + LoadCatalog, + Done, + } + + private readonly DefaultWebFileSystem _fileSystem; + private ESteps _steps = ESteps.None; + + /// + /// 内置清单版本 + /// + public string PackageVersion { private set; get; } + + internal LoadWebCatalogFileOperation(DefaultWebFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + _steps = ESteps.LoadCatalog; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadCatalog) + { + string catalogFilePath = _fileSystem.GetCatalogFileLoadPath(); + var catalog = Resources.Load(catalogFilePath); + if (catalog == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load catalog file : {catalogFilePath}"; + return; + } + + if (catalog.PackageName != _fileSystem.PackageName) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"The catalog file package name {catalog.PackageName} cannot match the file system package name {_fileSystem.PackageName}"; + return; + } + + PackageVersion = catalog.PackageVersion; + foreach (var wrapper in catalog.Wrappers) + { + var fileWrapper = new DefaultWebFileSystem.FileWrapper(wrapper.FileName); + _fileSystem.Record(wrapper.BundleGUID, fileWrapper); + } + + YooLogger.Log($"Package '{_fileSystem.PackageName}' catalog files count : {catalog.Wrappers.Count}"); + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebCatalogFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebCatalogFileOperation.cs.meta new file mode 100644 index 00000000..e5931448 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebCatalogFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c34c01e10454c842819e066eef488cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebPackageManifestOperation.cs new file mode 100644 index 00000000..7b1a866f --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebPackageManifestOperation.cs @@ -0,0 +1,109 @@ + +namespace YooAsset +{ + internal class LoadWebPackageManifestOperation : AsyncOperationBase + { + private enum ESteps + { + None, + RequestFileData, + VerifyFileData, + LoadManifest, + Done, + } + + private readonly DefaultWebFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly string _packageHash; + private UnityWebDataRequestOperation _webDataRequestOp; + private DeserializeManifestOperation _deserializer; + private ESteps _steps = ESteps.None; + + /// + /// 加载的清单实例 + /// + public PackageManifest Manifest { private set; get; } + + internal LoadWebPackageManifestOperation(DefaultWebFileSystem fileSystem, string packageVersion, string packageHash) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _packageHash = packageHash; + } + internal override void InternalOnStart() + { + _steps = ESteps.RequestFileData; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestFileData) + { + if (_webDataRequestOp == null) + { + string filePath = _fileSystem.GetWebPackageManifestFilePath(_packageVersion); + string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + _webDataRequestOp = new UnityWebDataRequestOperation(url); + OperationSystem.StartOperation(_fileSystem.PackageName, _webDataRequestOp); + } + + if (_webDataRequestOp.IsDone == false) + return; + + if (_webDataRequestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.VerifyFileData; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webDataRequestOp.Error; + } + } + + if (_steps == ESteps.VerifyFileData) + { + string fileHash = HashUtility.BytesMD5(_webDataRequestOp.Result); + if (fileHash == _packageHash) + { + _steps = ESteps.LoadManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Failed to verify web package manifest file!"; + } + } + + if (_steps == ESteps.LoadManifest) + { + if (_deserializer == null) + { + _deserializer = new DeserializeManifestOperation(_webDataRequestOp.Result); + OperationSystem.StartOperation(_fileSystem.PackageName, _deserializer); + } + + Progress = _deserializer.Progress; + if (_deserializer.IsDone == false) + return; + + if (_deserializer.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Manifest = _deserializer.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _deserializer.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebPackageManifestOperation.cs.meta new file mode 100644 index 00000000..2e4eb98a --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 04a60c61990d93b4cb934ab1901a44f5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestRemotePackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestRemotePackageHashOperation.cs new file mode 100644 index 00000000..0e9b1d7c --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestRemotePackageHashOperation.cs @@ -0,0 +1,90 @@ + +namespace YooAsset +{ + internal class RequestRemotePackageHashOperation : AsyncOperationBase + { + private enum ESteps + { + None, + RequestPackageHash, + Done, + } + + private readonly DefaultWebFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly int _timeout; + private UnityWebTextRequestOperation _webTextRequestOp; + private int _requestCount = 0; + private ESteps _steps = ESteps.None; + + /// + /// 包裹哈希值 + /// + public string PackageHash { private set; get; } + + + public RequestRemotePackageHashOperation(DefaultWebFileSystem fileSystem, string packageVersion, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestRemotePackageHashOperation)); + _steps = ESteps.RequestPackageHash; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestPackageHash) + { + if (_webTextRequestOp == null) + { + string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, _packageVersion); + string url = GetDownloadRequestURL(fileName); + _webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp); + } + + Progress = _webTextRequestOp.Progress; + if (_webTextRequestOp.IsDone == false) + return; + + if (_webTextRequestOp.Status != EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webTextRequestOp.Error; + WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(RequestRemotePackageHashOperation)); + } + else + { + PackageHash = _webTextRequestOp.Result; + if (string.IsNullOrEmpty(PackageHash)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Remote package hash file content is empty !"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + } + + private string GetDownloadRequestURL(string fileName) + { + // 轮流返回请求地址 + if (_requestCount % 2 == 0) + return _fileSystem.RemoteServices.GetRemoteMainURL(fileName); + else + return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestRemotePackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestRemotePackageHashOperation.cs.meta new file mode 100644 index 00000000..c2f4ed99 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestRemotePackageHashOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f8269507a575884f935f9fbc71396ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageHashOperation.cs new file mode 100644 index 00000000..5ef9cd25 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageHashOperation.cs @@ -0,0 +1,78 @@ + +namespace YooAsset +{ + internal class RequestWebPackageHashOperation : AsyncOperationBase + { + private enum ESteps + { + None, + RequestPackageHash, + Done, + } + + private readonly DefaultWebFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly int _timeout; + private UnityWebTextRequestOperation _webTextRequestOp; + private ESteps _steps = ESteps.None; + + /// + /// 包裹哈希值 + /// + public string PackageHash { private set; get; } + + + public RequestWebPackageHashOperation(DefaultWebFileSystem fileSystem, string packageVersion, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _steps = ESteps.RequestPackageHash; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestPackageHash) + { + if (_webTextRequestOp == null) + { + string filePath = _fileSystem.GetWebPackageHashFilePath(_packageVersion); + string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + _webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp); + } + + Progress = _webTextRequestOp.Progress; + if (_webTextRequestOp.IsDone == false) + return; + + if (_webTextRequestOp.Status != EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webTextRequestOp.Error; + } + else + { + PackageHash = _webTextRequestOp.Result; + if (string.IsNullOrEmpty(PackageHash)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Web package hash file content is empty !"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageHashOperation.cs.meta new file mode 100644 index 00000000..4b49e5df --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageHashOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ead93dc6c4d5ed942b209ec2202087dc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageVersionOperation.cs new file mode 100644 index 00000000..20f1fd2a --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageVersionOperation.cs @@ -0,0 +1,75 @@ + +namespace YooAsset +{ + internal class RequestWebPackageVersionOperation : AsyncOperationBase + { + private enum ESteps + { + None, + RequestPackageVersion, + Done, + } + + private readonly DefaultWebFileSystem _fileSystem; + private readonly int _timeout; + private UnityWebTextRequestOperation _webTextRequestOp; + private ESteps _steps = ESteps.None; + + /// + /// 包裹版本 + /// + public string PackageVersion { private set; get; } + + + internal RequestWebPackageVersionOperation(DefaultWebFileSystem fileSystem, int timeout) + { + _fileSystem = fileSystem; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _steps = ESteps.RequestPackageVersion; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestPackageVersion) + { + if (_webTextRequestOp == null) + { + string filePath = _fileSystem.GetWebPackageVersionFilePath(); + string url = DownloadSystemHelper.ConvertToWWWPath(filePath); + _webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp); + } + + if (_webTextRequestOp.IsDone == false) + return; + + if (_webTextRequestOp.Status != EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webTextRequestOp.Error; + } + else + { + PackageVersion = _webTextRequestOp.Result; + if (string.IsNullOrEmpty(PackageVersion)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Web package version file content is empty !"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageVersionOperation.cs.meta new file mode 100644 index 00000000..4e7e4b8b --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bfa0e562b63f31141bbf04d4d5336d87 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileAccess.cs b/Assets/YooAsset/Runtime/FileSystem/EFileAccess.cs new file mode 100644 index 00000000..a350ad8d --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/EFileAccess.cs @@ -0,0 +1,21 @@ + +namespace YooAsset +{ + internal enum EFileAccess + { + /// + /// 只可读 + /// + Read = 0, + + /// + /// 只可写 + /// + Write = 1, + + /// + /// 可读写 + /// + ReadWrite = 2 + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileAccess.cs.meta b/Assets/YooAsset/Runtime/FileSystem/EFileAccess.cs.meta new file mode 100644 index 00000000..09d836fd --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/EFileAccess.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ec116be6f4596f4db2cb4c627d9fe51 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs similarity index 73% rename from Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs rename to Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs index 966a922f..711cf3f8 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs +++ b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs @@ -2,23 +2,23 @@ namespace YooAsset { /// - /// 下载文件校验等级 + /// 文件校验等级 /// - public enum EVerifyLevel + public enum EFileVerifyLevel { /// /// 验证文件存在 /// - Low, + Low = 1, /// /// 验证文件大小 /// - Middle, + Middle = 2, /// /// 验证文件大小和CRC /// - High, + High = 3, } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs.meta b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs.meta new file mode 100644 index 00000000..b93496fa --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5023ed6a87d5e5a4482f5559c3d80122 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs similarity index 94% rename from Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs rename to Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs index c8636e35..12b9ad19 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs @@ -2,9 +2,9 @@ namespace YooAsset { /// - /// 下载文件校验结果 + /// 文件校验结果 /// - internal enum EVerifyResult + internal enum EFileVerifyResult { /// /// 验证异常 diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs.meta b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs.meta new file mode 100644 index 00000000..8422fe26 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1c71d42855e9484409e0dc352acb176a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystemHelper.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystemHelper.cs new file mode 100644 index 00000000..b2f606bc --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystemHelper.cs @@ -0,0 +1,45 @@ +using System; +using System.IO; + +namespace YooAsset +{ + internal class FileSystemHelper + { + /// + /// 文件校验 + /// + public static EFileVerifyResult FileVerify(string filePath, long fileSize, string fileCRC, EFileVerifyLevel verifyLevel) + { + try + { + if (File.Exists(filePath) == false) + return EFileVerifyResult.DataFileNotExisted; + + // 先验证文件大小 + long size = FileUtility.GetFileSize(filePath); + if (size < fileSize) + return EFileVerifyResult.FileNotComplete; + else if (size > fileSize) + return EFileVerifyResult.FileOverflow; + + // 再验证文件CRC + if (verifyLevel == EFileVerifyLevel.High) + { + string crc = HashUtility.FileCRC32Safely(filePath); + if (crc == fileCRC) + return EFileVerifyResult.Succeed; + else + return EFileVerifyResult.FileCrcError; + } + else + { + return EFileVerifyResult.Succeed; + } + } + catch (Exception) + { + return EFileVerifyResult.Exception; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystemHelper.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystemHelper.cs.meta new file mode 100644 index 00000000..a2091cde --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystemHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cbc12d398555ced46b201626eec6825e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Interface.meta b/Assets/YooAsset/Runtime/FileSystem/Interface.meta new file mode 100644 index 00000000..26ba3b13 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Interface.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0b81b60c4748e3447967805ca3884d07 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs new file mode 100644 index 00000000..a3d5d950 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs @@ -0,0 +1,153 @@ + +namespace YooAsset +{ + internal interface IFileSystem + { + /// + /// 包裹名称 + /// + string PackageName { get; } + + /// + /// 文件访问权限 + /// + EFileAccess FileSystemAccess { get; } + + /// + /// 文件根目录 + /// + string FileRoot { get; } + + /// + /// 文件数量 + /// + int FileCount { get; } + + + /// + /// 初始化缓存系统 + /// + FSInitializeFileSystemOperation InitializeFileSystemAsync(); + + /// + /// 加载包裹清单 + /// + FSLoadPackageManifestOperation LoadPackageManifestAsync(params object[] args); + + /// + /// 查询最新的版本 + /// + FSRequestPackageVersionOperation RequestPackageVersionAsync(params object[] args); + + /// + /// 清空所有的文件 + /// + FSClearAllBundleFilesOperation ClearAllBundleFilesAsync(params object[] args); + + /// + /// 清空未使用的文件 + /// + FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(params object[] args); + + /// + /// 下载远端文件 + /// + FSDownloadFileOperation DownloadFileAsync(params object[] args); + + + /// + /// 设置自定义参数 + /// + void SetParameter(string name, object value); + + /// + /// 创建缓存系统 + /// + void OnCreate(string packageName, string rootDirectory); + + /// + /// 更新文件系统 + /// + void OnUpdate(); + + + /// + /// 查询文件归属 + /// + bool Belong(PackageBundle bundle); + + /// + /// 查询文件归属 + /// + bool Belong(string bundleGUID); + + /// + /// 查询文件是否存在 + /// + bool Exists(PackageBundle bundle); + + /// + /// 查询文件是否存在 + /// + bool Exists(string bundleGUID); + + + /// + /// 检测是否需要下载 + /// + bool CheckNeedDownload(PackageBundle bundle); + + /// + /// 检测是否需要解压 + /// + bool CheckNeedUnpack(PackageBundle bundle); + + /// + /// 检测是否需要导入 + /// + bool CheckNeedImport(PackageBundle bundle); + + + /// + /// 写入文件 + /// + bool WriteFile(PackageBundle bundle, string copyPath); + + /// + /// 删除文件 + /// + bool DeleteFile(PackageBundle bundle); + + /// + /// 删除文件 + /// + bool DeleteFile(string bundleGUID); + + /// + /// 校验文件 + /// + EFileVerifyResult VerifyFile(PackageBundle bundle); + + + /// + /// 读取文件的二进制数据 + /// + byte[] ReadFileBytes(PackageBundle bundle); + + /// + /// 读取文件的文本数据 + /// + string ReadFileText(PackageBundle bundle); + + + /// + /// 加载Bundle文件 + /// + FSLoadBundleOperation LoadBundleFile(PackageBundle bundle); + + /// + /// 卸载Bundle文件 + /// + void UnloadBundleFile(PackageBundle bundle, object result); + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs.meta new file mode 100644 index 00000000..cdd6a064 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 960fb79a45e1fa147943ced59f2fb61c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/Operation.meta new file mode 100644 index 00000000..8766bbc9 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7ea2c2e5d4ba0f142a8ecd5d5f79c360 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal.meta new file mode 100644 index 00000000..766b9a6a --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 97923f5987c469a4898718033af09e99 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultDownloadFileOperation.cs new file mode 100644 index 00000000..73844f99 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultDownloadFileOperation.cs @@ -0,0 +1,118 @@ +using UnityEngine.Networking; + +namespace YooAsset +{ + internal abstract class DefaultDownloadFileOperation : FSDownloadFileOperation + { + protected enum ESteps + { + None, + CreateRequest, + CheckRequest, + VerifyTempFile, + CheckVerifyTempFile, + TryAgain, + Done, + } + + // 初始参数 + protected readonly string _mainURL; + protected readonly string _fallbackURL; + protected readonly int _failedTryAgain; + protected readonly int _timeout; + + // 请求相关 + protected UnityWebRequest _webRequest; + protected string _requestURL; + protected int _requestCount = 0; + + // 超时相关 + protected bool _isAbort = false; + protected long _latestDownloadBytes; + protected float _latestDownloadRealtime; + protected float _tryAgainTimer; + + // 失败相关 + protected int FailedTryAgain; + + + internal DefaultDownloadFileOperation(PackageBundle bundle, + string mainURL, string fallbackURL, int failedTryAgain, int timeout) : base(bundle) + { + _mainURL = mainURL; + _fallbackURL = fallbackURL; + _failedTryAgain = failedTryAgain; + _timeout = timeout; + + FailedTryAgain = failedTryAgain; + } + + /// + /// 获取网络请求地址 + /// + protected string GetRequestURL() + { + // 轮流返回请求地址 + _requestCount++; + if (_requestCount % 2 == 0) + return _fallbackURL; + else + return _mainURL; + } + + /// + /// 检测请求超时 + /// + protected void CheckRequestTimeout() + { + // 注意:在连续时间段内无新增下载数据及判定为超时 + if (_isAbort == false) + { + if (_latestDownloadBytes != DownloadedBytes) + { + _latestDownloadBytes = DownloadedBytes; + _latestDownloadRealtime = UnityEngine.Time.realtimeSinceStartup; + } + + float offset = UnityEngine.Time.realtimeSinceStartup - _latestDownloadRealtime; + if (offset > _timeout) + { + YooLogger.Warning($"Web file request timeout : {_requestURL}"); + if (_webRequest != null) + _webRequest.Abort(); + _isAbort = true; + } + } + } + + /// + /// 检测请求结果 + /// + protected bool CheckRequestResult() + { + HttpCode = _webRequest.responseCode; + +#if UNITY_2020_3_OR_NEWER + if (_webRequest.result != UnityWebRequest.Result.Success) + { + Error = _webRequest.error; + return false; + } + else + { + return true; + } +#else + if (_webRequest.isNetworkError || _webRequest.isHttpError) + { + Error = _webRequest.error; + return false; + } + else + { + return true; + } +#endif + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultDownloadFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultDownloadFileOperation.cs.meta new file mode 100644 index 00000000..411526b8 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultDownloadFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af07b7cdf729e944dbb6d60204c71235 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultGetRemotePackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultGetRemotePackageVersionOperation.cs new file mode 100644 index 00000000..9ba2ee64 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultGetRemotePackageVersionOperation.cs @@ -0,0 +1,102 @@ + +namespace YooAsset +{ + internal class DefaultGetRemotePackageVersionOperation : AsyncOperationBase + { + private enum ESteps + { + None, + RequestPackageVersion, + Done, + } + + private readonly string _packageName; + private readonly string _mainURL; + private readonly string _fallbackURL; + private readonly bool _appendTimeTicks; + private readonly int _timeout; + private UnityWebTextRequestOperation _webTextRequestOp; + private int _requestCount = 0; + private ESteps _steps = ESteps.None; + + /// + /// 查询的远端版本信息 + /// + internal string PackageVersion { set; get; } + + + internal DefaultGetRemotePackageVersionOperation(string packageName, string mainURL, string fallbackURL, bool appendTimeTicks, int timeout) + { + _packageName = packageName; + _mainURL = mainURL; + _fallbackURL = fallbackURL; + _appendTimeTicks = appendTimeTicks; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_packageName, nameof(DefaultGetRemotePackageVersionOperation)); + _steps = ESteps.RequestPackageVersion; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestPackageVersion) + { + if (_webTextRequestOp == null) + { + string url = GetPackageVersionRequestURL(); + YooLogger.Log($"Beginning to request package version : {url}"); + _webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout); + OperationSystem.StartOperation(_packageName, _webTextRequestOp); + } + + Progress = _webTextRequestOp.Progress; + if (_webTextRequestOp.IsDone == false) + return; + + if (_webTextRequestOp.Status != EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webTextRequestOp.Error; + WebRequestCounter.RecordRequestFailed(_packageName, nameof(DefaultGetRemotePackageVersionOperation)); + } + else + { + PackageVersion = _webTextRequestOp.Result; + if (string.IsNullOrEmpty(PackageVersion)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Remote package version file content is empty !"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + } + + private string GetPackageVersionRequestURL() + { + string url; + + // 轮流返回请求地址 + if (_requestCount % 2 == 0) + url = _mainURL; + else + url = _fallbackURL; + + // 在URL末尾添加时间戳 + if (_appendTimeTicks) + return $"{url}?{System.DateTime.UtcNow.Ticks}"; + else + return url; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultGetRemotePackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultGetRemotePackageVersionOperation.cs.meta new file mode 100644 index 00000000..e2049f65 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultGetRemotePackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b078a220cc4f7d4392d77ccc77c001e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearAllBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearAllBundleFilesOperation.cs new file mode 100644 index 00000000..cba25d35 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearAllBundleFilesOperation.cs @@ -0,0 +1,7 @@ + +namespace YooAsset +{ + internal abstract class FSClearAllBundleFilesOperation : AsyncOperationBase + { + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearAllBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearAllBundleFilesOperation.cs.meta new file mode 100644 index 00000000..e39f22d8 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearAllBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9fe9171073a87746a7393f7d1fcb924 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearUnusedBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearUnusedBundleFilesOperation.cs new file mode 100644 index 00000000..a0d8f88f --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearUnusedBundleFilesOperation.cs @@ -0,0 +1,7 @@ + +namespace YooAsset +{ + internal abstract class FSClearUnusedBundleFilesOperation : AsyncOperationBase + { + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearUnusedBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearUnusedBundleFilesOperation.cs.meta new file mode 100644 index 00000000..a29a42d1 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearUnusedBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 857423cdfd4f9184eab094be01c62480 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSDownloadFileOperation.cs new file mode 100644 index 00000000..f9fa7e26 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSDownloadFileOperation.cs @@ -0,0 +1,46 @@ + +namespace YooAsset +{ + internal abstract class FSDownloadFileOperation : AsyncOperationBase + { + public PackageBundle Bundle { private set; get; } + + /// + /// 引用计数 + /// + public int RefCount { private set; get; } + + /// + /// HTTP返回码 + /// + public long HttpCode { protected set; get; } + + /// + /// 当前下载的字节数 + /// + public long DownloadedBytes { protected set; get; } + + /// + /// 当前下载进度(0f - 1f) + /// + public float DownloadProgress { protected set; get; } + + + public FSDownloadFileOperation(PackageBundle bundle) + { + Bundle = bundle; + RefCount = 0; + HttpCode = 0; + DownloadedBytes = 0; + DownloadProgress = 0; + } + public void Release() + { + RefCount--; + } + public void Reference() + { + RefCount++; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSDownloadFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSDownloadFileOperation.cs.meta new file mode 100644 index 00000000..3a1ea952 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSDownloadFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5e61f870d9802cf4ab18d0050aa38ae7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSInitializeFileSystemOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSInitializeFileSystemOperation.cs new file mode 100644 index 00000000..d9a5666c --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSInitializeFileSystemOperation.cs @@ -0,0 +1,7 @@ + +namespace YooAsset +{ + internal abstract class FSInitializeFileSystemOperation : AsyncOperationBase + { + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSInitializeFileSystemOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSInitializeFileSystemOperation.cs.meta new file mode 100644 index 00000000..9835c333 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSInitializeFileSystemOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5de0f7b58d8d2114680a9ff319db5d26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadBundleFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadBundleFileOperation.cs new file mode 100644 index 00000000..63133960 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadBundleFileOperation.cs @@ -0,0 +1,27 @@ +using UnityEngine; + +namespace YooAsset +{ + internal abstract class FSLoadBundleOperation : AsyncOperationBase + { + /// + /// 加载结果 + /// + public object Result { protected set; get; } + + /// + /// 下载进度 + /// + public float DownloadProgress { protected set; get; } + + /// + /// 下载大小 + /// + public long DownloadedBytes { protected set; get; } + + /// + /// 终止下载任务 + /// + public abstract void AbortDownloadOperation(); + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadBundleFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadBundleFileOperation.cs.meta new file mode 100644 index 00000000..bceb8832 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadBundleFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9d1f8374e0d38b4f9a7d1db62bb062e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadPackageManifestOperation.cs new file mode 100644 index 00000000..a9aaf6b1 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadPackageManifestOperation.cs @@ -0,0 +1,11 @@ + +namespace YooAsset +{ + internal abstract class FSLoadPackageManifestOperation : AsyncOperationBase + { + /// + /// 加载结果 + /// + internal PackageManifest Result { set; get; } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadPackageManifestOperation.cs.meta new file mode 100644 index 00000000..9b054e7a --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d486c0822a1831438865d132c4690a9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSQueryPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSQueryPackageVersionOperation.cs new file mode 100644 index 00000000..1f269dac --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSQueryPackageVersionOperation.cs @@ -0,0 +1,11 @@ + +namespace YooAsset +{ + internal abstract class FSRequestPackageVersionOperation : AsyncOperationBase + { + /// + /// 查询的最新版本信息 + /// + internal string PackageVersion { set; get; } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSQueryPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSQueryPackageVersionOperation.cs.meta new file mode 100644 index 00000000..5ed2e5ff --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSQueryPackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a98e69d7c0b9024a84093bcc7835a15 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/InitializeParameters.cs b/Assets/YooAsset/Runtime/InitializeParameters.cs index b66f40b6..cd4684b7 100644 --- a/Assets/YooAsset/Runtime/InitializeParameters.cs +++ b/Assets/YooAsset/Runtime/InitializeParameters.cs @@ -1,4 +1,6 @@ - +using System; +using System.Collections.Generic; + namespace YooAsset { /// @@ -48,48 +50,147 @@ namespace YooAsset WebPlayMode, } + /// + /// 文件系统参数 + /// + public class FileSystemParameters + { + internal Dictionary CreateParameters = new Dictionary(); + + /// + /// 文件系统类 + /// 格式: "namespace.class,assembly" + /// 格式: "命名空间.类型名,程序集" + /// + public string FileSystemClass { private set; get; } + + /// + /// 文件系统的根目录 + /// + public string RootDirectory { private set; get; } + + + public FileSystemParameters(string fileSystemClass, string rootDirectory) + { + FileSystemClass = fileSystemClass; + RootDirectory = rootDirectory; + } + + /// + /// 添加自定义参数 + /// + public void AddParameter(string name, object value) + { + CreateParameters.Add(name, value); + } + + + /// + /// 创建默认的编辑器文件系统参数 + /// 用于模拟运行的资源清单路径 + /// + public static FileSystemParameters CreateDefaultEditorFileSystemParameters(string simulateManifestFilePath) + { + string fileSystemClass = typeof(DefaultEditorFileSystem).FullName; + var fileSystemParams = new FileSystemParameters(fileSystemClass, null); + fileSystemParams.AddParameter("SIMULATE_MANIFEST_FILE_PATH", simulateManifestFilePath); + return fileSystemParams; + } + + /// + /// 创建默认的内置文件系统参数 + /// + /// 缓存文件的校验等级 + /// 内置文件的根路径 + public static FileSystemParameters CreateDefaultBuildinFileSystemParameters(EFileVerifyLevel verifyLevel = EFileVerifyLevel.Middle, string rootDirectory = null) + { + string fileSystemClass = typeof(DefaultBuildinFileSystem).FullName; + var fileSystemParams = new FileSystemParameters(fileSystemClass, rootDirectory); + fileSystemParams.AddParameter("FILE_VERIFY_LEVEL", verifyLevel); + return fileSystemParams; + } + + /// + /// 创建默认的内置文件系统参数(原生文件) + /// + /// 缓存文件的校验等级 + /// 内置文件的根路径 + public static FileSystemParameters CreateDefaultBuildinRawFileSystemParameters(EFileVerifyLevel verifyLevel = EFileVerifyLevel.Middle, string rootDirectory = null) + { + string fileSystemClass = typeof(DefaultBuildinFileSystem).FullName; + var fileSystemParams = new FileSystemParameters(fileSystemClass, rootDirectory); + fileSystemParams.AddParameter("FILE_VERIFY_LEVEL", verifyLevel); + fileSystemParams.AddParameter("APPEND_FILE_EXTENSION", true); + fileSystemParams.AddParameter("RAW_FILE_BUILD_PIPELINE", true); + return fileSystemParams; + } + + /// + /// 创建默认的缓存文件系统参数 + /// + /// 远端资源地址查询服务类 + /// 缓存文件的校验等级 + /// 文件系统的根目录 + public static FileSystemParameters CreateDefaultCacheFileSystemParameters(IRemoteServices remoteServices, EFileVerifyLevel verifyLevel = EFileVerifyLevel.Middle, string rootDirectory = null) + { + string fileSystemClass = typeof(DefaultCacheFileSystem).FullName; + var fileSystemParams = new FileSystemParameters(fileSystemClass, rootDirectory); + fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices); + fileSystemParams.AddParameter("FILE_VERIFY_LEVEL", verifyLevel); + return fileSystemParams; + } + + /// + /// 创建默认的缓存文件系统参数(原生文件) + /// + /// 远端资源地址查询服务类 + /// 缓存文件的校验等级 + /// 文件系统的根目录 + public static FileSystemParameters CreateDefaultCacheRawFileSystemParameters(IRemoteServices remoteServices, EFileVerifyLevel verifyLevel = EFileVerifyLevel.Middle, string rootDirectory = null) + { + string fileSystemClass = typeof(DefaultCacheFileSystem).FullName; + var fileSystemParams = new FileSystemParameters(fileSystemClass, rootDirectory); + fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices); + fileSystemParams.AddParameter("FILE_VERIFY_LEVEL", verifyLevel); + fileSystemParams.AddParameter("APPEND_FILE_EXTENSION", true); + fileSystemParams.AddParameter("RAW_FILE_BUILD_PIPELINE", true); + return fileSystemParams; + } + + /// + /// 创建默认的Web文件系统参数 + /// + public static FileSystemParameters CreateDefaultWebFileSystemParameters() + { + string fileSystemClass = typeof(DefaultWebFileSystem).FullName; + var fileSystemParams = new FileSystemParameters(fileSystemClass, null); + fileSystemParams.AddParameter("ALLOW_CROSS_ACCESS", false); + return fileSystemParams; + } + + /// + /// 创建默认的Web文件系统参数 + /// + /// 远端资源地址查询服务类 + public static FileSystemParameters CreateDefaultWebFileSystemParameters(IRemoteServices remoteServices) + { + string fileSystemClass = typeof(DefaultWebFileSystem).FullName; + var fileSystemParams = new FileSystemParameters(fileSystemClass, null); + fileSystemParams.AddParameter("ALLOW_CROSS_ACCESS", true); + fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices); + return fileSystemParams; + } + } + /// /// 初始化参数 /// public abstract class InitializeParameters { - /// - /// 内置文件的根路径 - /// 注意:当参数为空的时候会使用默认的根目录。 - /// - public string BuildinRootDirectory = string.Empty; - - /// - /// 沙盒文件的根路径 - /// 注意:当参数为空的时候会使用默认的根目录。 - /// - public string SandboxRootDirectory = string.Empty; - - /// - /// 缓存文件追加原始后缀格式 - /// - public bool CacheFileAppendExtension = false; - - /// - /// 缓存系统启动时的验证级别 - /// - public EVerifyLevel CacheBootVerifyLevel = EVerifyLevel.Middle; - /// /// 自动销毁不再使用的资源提供者 /// public bool AutoDestroyAssetProvider = false; - - /// - /// 启用断点续传参数 - /// 说明:当文件的大小大于设置的字节数时启用断点续传下载器 - /// - public uint BreakpointResumeFileSize = int.MaxValue; - - /// - /// 文件解密服务接口 - /// - public IDecryptionServices DecryptionServices = null; } /// @@ -97,10 +198,7 @@ namespace YooAsset /// public class EditorSimulateModeParameters : InitializeParameters { - /// - /// 用于模拟运行的资源清单路径 - /// - public string SimulateManifestFilePath = string.Empty; + public FileSystemParameters EditorFileSystemParameters; } /// @@ -108,6 +206,7 @@ namespace YooAsset /// public class OfflinePlayModeParameters : InitializeParameters { + public FileSystemParameters BuildinFileSystemParameters; } /// @@ -115,25 +214,9 @@ namespace YooAsset /// public class HostPlayModeParameters : InitializeParameters { - /// - /// 远端资源地址查询服务类 - /// - public IRemoteServices RemoteServices = null; - - /// - /// 内置资源查询服务接口 - /// - public IBuildinQueryServices BuildinQueryServices = null; - - /// - /// 分发资源查询服务接口 - /// - public IDeliveryQueryServices DeliveryQueryServices = null; - - /// - /// 分发资源加载服务接口 - /// - public IDeliveryLoadServices DeliveryLoadServices = null; + public FileSystemParameters BuildinFileSystemParameters; + public FileSystemParameters DeliveryFileSystemParameters; + public FileSystemParameters CacheFileSystemParameters; } /// @@ -141,19 +224,6 @@ namespace YooAsset /// public class WebPlayModeParameters : InitializeParameters { - /// - /// 远端资源地址查询服务类 - /// - public IRemoteServices RemoteServices = null; - - /// - /// 内置资源查询服务接口 - /// - public IBuildinQueryServices BuildinQueryServices = null; - - /// - /// 微信缓存查询服务接口 - /// - public IWechatQueryServices WechatQueryServices = null; + public FileSystemParameters WebFileSystemParameters; } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs b/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs index 711c774f..8e8d4397 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs +++ b/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs @@ -10,14 +10,12 @@ namespace YooAsset // 用户请求的回调 private Action _callback; + // 所属包裹 + private string _packageName = null; + // 是否已经完成 internal bool IsFinish = false; - /// - /// 所属包裹 - /// - public string PackageName { private set; get; } - /// /// 优先级 /// @@ -88,9 +86,13 @@ namespace YooAsset internal abstract void InternalOnUpdate(); internal virtual void InternalOnAbort() { } + internal string GetPackageName() + { + return _packageName; + } internal void SetPackageName(string packageName) { - PackageName = packageName; + _packageName = packageName; } internal void SetStart() { @@ -116,11 +118,19 @@ namespace YooAsset { Status = EOperationStatus.Failed; Error = "user abort"; - YooLogger.Warning($"Async operaiton has been abort : {this.GetType().Name}"); + YooLogger.Warning($"Async operaiton {this.GetType().Name} has been abort !"); InternalOnAbort(); } } + /// + /// 等待异步执行完毕 + /// + public virtual void WaitForAsyncComplete() + { + throw new System.NotImplementedException(this.GetType().Name); + } + /// /// 清空完成回调 /// diff --git a/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs b/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs index 2c420c6b..98a7e001 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs +++ b/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs @@ -112,7 +112,7 @@ namespace YooAsset // 终止临时队列里的任务 foreach (var operation in _newList) { - if (operation.PackageName == packageName) + if (operation.GetPackageName() == packageName) { operation.SetAbort(); } @@ -121,7 +121,7 @@ namespace YooAsset // 终止正在进行的任务 foreach (var operation in _operations) { - if (operation.PackageName == packageName) + if (operation.GetPackageName() == packageName) { operation.SetAbort(); } @@ -137,14 +137,5 @@ namespace YooAsset operation.SetPackageName(packageName); operation.SetStart(); } - - /// - /// 开始处理异步操作类 - /// - public static void StartOperation(AsyncOperationBase operation) - { - _newList.Add(operation); - operation.SetStart(); - } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleFileLoader.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleFileLoader.cs deleted file mode 100644 index cdd66654..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleFileLoader.cs +++ /dev/null @@ -1,319 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace YooAsset -{ - internal sealed class AssetBundleFileLoader : BundleLoaderBase - { - private enum ESteps - { - None = 0, - Download, - CheckDownload, - Unpack, - CheckUnpack, - LoadBundleFile, - LoadDeliveryFile, - CheckLoadFile, - Done, - } - - private ESteps _steps = ESteps.None; - private bool _isWaitForAsyncComplete = false; - private bool _isShowWaitForAsyncError = false; - private DownloaderBase _unpacker; - private DownloaderBase _downloader; - private AssetBundleCreateRequest _createRequest; - private Stream _managedStream; - - - public AssetBundleFileLoader(ResourceManager 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.CachedDataFilePath; - } - else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming) - { -#if UNITY_ANDROID - if (MainBundleInfo.Bundle.Encrypted) - { - _steps = ESteps.Unpack; - FileLoadPath = MainBundleInfo.CachedDataFilePath; - } - else - { - _steps = ESteps.LoadBundleFile; - FileLoadPath = MainBundleInfo.BuildinFilePath; - } -#else - _steps = ESteps.LoadBundleFile; - FileLoadPath = MainBundleInfo.BuildinFilePath; -#endif - } - else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) - { - _steps = ESteps.LoadBundleFile; - FileLoadPath = MainBundleInfo.CachedDataFilePath; - } - else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromDelivery) - { - _steps = ESteps.LoadDeliveryFile; - FileLoadPath = MainBundleInfo.DeliveryFilePath; - } - else - { - throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString()); - } - } - - // 1. 从服务器下载 - if (_steps == ESteps.Download) - { - _downloader = MainBundleInfo.CreateDownloader(int.MaxValue); - _downloader.SendRequest(); - _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.LoadBundleFile; - return; //下载完毕等待一帧再去加载! - } - } - - // 3. 内置文件解压 - if (_steps == ESteps.Unpack) - { - int failedTryAgain = 1; - _unpacker = MainBundleInfo.CreateUnpacker(failedTryAgain); - _unpacker.SendRequest(); - _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.LoadBundleFile; - } - } - - // 5. 加载AssetBundle - if (_steps == ESteps.LoadBundleFile) - { -#if UNITY_EDITOR - // 注意:Unity2017.4编辑器模式下,如果AssetBundle文件不存在会导致编辑器崩溃,这里做了预判。 - if (System.IO.File.Exists(FileLoadPath) == false) - { - _steps = ESteps.Done; - Status = EStatus.Failed; - LastError = $"Not found assetBundle file : {FileLoadPath}"; - YooLogger.Error(LastError); - return; - } -#endif - - // 设置下载进度 - DownloadProgress = 1f; - DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize; - - // 加载AssetBundle资源对象 - // 注意:解密服务类可能会返回空的对象。 - if (_isWaitForAsyncComplete) - CacheBundle = MainBundleInfo.LoadAssetBundle(FileLoadPath, out _managedStream); - else - _createRequest = MainBundleInfo.LoadAssetBundleAsync(FileLoadPath, out _managedStream); - - _steps = ESteps.CheckLoadFile; - } - - // 6. 加载AssetBundle - if (_steps == ESteps.LoadDeliveryFile) - { - // 设置下载进度 - DownloadProgress = 1f; - DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize; - - // Load assetBundle file - if (_isWaitForAsyncComplete) - CacheBundle = MainBundleInfo.LoadDeliveryAssetBundle(FileLoadPath); - else - _createRequest = MainBundleInfo.LoadDeliveryAssetBundleAsync(FileLoadPath); - - _steps = ESteps.CheckLoadFile; - } - - // 7. 检测AssetBundle加载结果 - if (_steps == ESteps.CheckLoadFile) - { - if (_createRequest != null) - { - if (_isWaitForAsyncComplete || IsForceDestroyComplete) - { - // 强制挂起主线程(注意:该操作会很耗时) - YooLogger.Warning("Suspend the main thread to load unity bundle."); - CacheBundle = _createRequest.assetBundle; - } - else - { - if (_createRequest.isDone == false) - return; - CacheBundle = _createRequest.assetBundle; - } - } - - // Check error - if (CacheBundle == null) - { - // 注意:当缓存文件的校验等级为Low的时候,并不能保证缓存文件的完整性。 - // 在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性! - if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) - { - var result = MainBundleInfo.VerifySelf(); - if (result == EVerifyResult.Succeed) - { - // 说明:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。 - // 大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发! - byte[] fileData = FileUtility.ReadAllBytes(FileLoadPath); - if (fileData != null && fileData.Length > 0) - CacheBundle = AssetBundle.LoadFromMemory(fileData); - if (CacheBundle == null) - { - _steps = ESteps.Done; - Status = EStatus.Failed; - LastError = $"Failed to load assetBundle from memory : {MainBundleInfo.Bundle.BundleName}"; - YooLogger.Error(LastError); - } - else - { - _steps = ESteps.Done; - Status = EStatus.Succeed; - } - } - else - { - _steps = ESteps.Done; - Status = EStatus.Failed; - LastError = $"Found possibly corrupt file ! {MainBundleInfo.Bundle.CacheGUID} Verify result : {result}"; - YooLogger.Error(LastError); - MainBundleInfo.CacheDiscard(); - } - } - else - { - _steps = ESteps.Done; - Status = EStatus.Failed; - LastError = $"Failed to load assetBundle : {MainBundleInfo.Bundle.BundleName}"; - YooLogger.Error(LastError); - } - } - else - { - _steps = ESteps.Done; - Status = EStatus.Succeed; - } - } - } - - /// - /// 销毁 - /// - public override void Destroy() - { - base.Destroy(); - - if (_managedStream != null) - { - _managedStream.Close(); - _managedStream.Dispose(); - _managedStream = null; - } - } - - /// - /// 主线程等待异步操作完毕 - /// - public override void WaitForAsyncComplete() - { - _isWaitForAsyncComplete = true; - - int frame = 1000; - while (true) - { - // 文件解压 - if (_unpacker != null) - { - if (_unpacker.IsDone() == false) - { - _unpacker.WaitForAsyncComplete = true; - _unpacker.Update(); - continue; - } - } - - // 保险机制 - // 注意:如果需要从WEB端下载资源,可能会触发保险机制! - frame--; - if (frame == 0) - { - if (_isShowWaitForAsyncError == false) - { - _isShowWaitForAsyncError = true; - YooLogger.Error($"{nameof(WaitForAsyncComplete)} failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !"); - } - break; - } - - // 驱动流程 - Update(); - - // 完成后退出 - if (IsDone()) - break; - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleFileLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleFileLoader.cs.meta deleted file mode 100644 index a88ab9c7..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleFileLoader.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 64d0a51f59c2a964eaf97b87db47428f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleWebLoader.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleWebLoader.cs deleted file mode 100644 index 2d43aed7..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleWebLoader.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.Networking; - -namespace YooAsset -{ - /// - /// WebGL平台加载器 - /// - internal sealed class AssetBundleWebLoader : BundleLoaderBase - { - private enum ESteps - { - None = 0, - LoadWebSiteFile, - LoadRemoteFile, - CheckLoadFile, - Done, - } - - private ESteps _steps = ESteps.None; - private DownloaderBase _downloader; - - - public AssetBundleWebLoader(ResourceManager 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.LoadRemoteFile; - FileLoadPath = string.Empty; - } - else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming) - { - _steps = ESteps.LoadWebSiteFile; - FileLoadPath = string.Empty; - } - else - { - throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString()); - } - } - - // 1. 跨域获取资源包 - if (_steps == ESteps.LoadRemoteFile) - { - _downloader = MainBundleInfo.CreateDownloader(int.MaxValue); - _downloader.SendRequest(true); - _steps = ESteps.CheckLoadFile; - } - - // 2. 从站点获取资源包 - if (_steps == ESteps.LoadWebSiteFile) - { - _downloader = MainBundleInfo.CreateUnpacker(int.MaxValue); - _downloader.SendRequest(true); - _steps = ESteps.CheckLoadFile; - } - - // 3. 检测加载结果 - if (_steps == ESteps.CheckLoadFile) - { - DownloadProgress = _downloader.DownloadProgress; - DownloadedBytes = _downloader.DownloadedBytes; - if (_downloader.IsDone() == false) - return; - - CacheBundle = _downloader.GetAssetBundle(); - if (CacheBundle == null) - { - _steps = ESteps.Done; - Status = EStatus.Failed; - LastError = $"AssetBundle file is invalid : {MainBundleInfo.Bundle.BundleName}"; - YooLogger.Error(LastError); - } - else - { - _steps = ESteps.Done; - Status = EStatus.Succeed; - } - } - } - - /// - /// 主线程等待异步操作完毕 - /// - public override void WaitForAsyncComplete() - { - if (IsDone() == false) - { - Status = EStatus.Failed; - LastError = $"{nameof(WaitForAsyncComplete)} failed ! WebGL platform not support sync load method !"; - YooLogger.Error(LastError); - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleWebLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleWebLoader.cs.meta deleted file mode 100644 index 3b5e44bf..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleWebLoader.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bd1ad395c62c5804589ec9b267ea0484 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleLoaderBase.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleFileLoader.cs similarity index 60% rename from Assets/YooAsset/Runtime/ResourceManager/Loader/BundleLoaderBase.cs rename to Assets/YooAsset/Runtime/ResourceManager/Loader/BundleFileLoader.cs index 6039f89a..cfc49ba0 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleLoaderBase.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleFileLoader.cs @@ -5,7 +5,7 @@ using UnityEngine; namespace YooAsset { - internal abstract class BundleLoaderBase + internal class BundleFileLoader { public enum EStatus { @@ -14,21 +14,17 @@ namespace YooAsset Failed } - /// - /// 所属资源系统 - /// - public ResourceManager Impl { private set; get; } + private readonly ResourceManager _resourceManager; + private readonly List _providers = new List(100); + private readonly List _removeList = new List(100); + private FSLoadBundleOperation _loadBundleOp; + private bool _isDone = false; /// /// 资源包文件信息 /// public BundleInfo MainBundleInfo { private set; get; } - /// - /// 引用计数 - /// - public int RefCount { private set; get; } - /// /// 加载状态 /// @@ -37,30 +33,87 @@ namespace YooAsset /// /// 最近的错误信息 /// - public string LastError { protected set; get; } + public string LastError { protected set; get; } = string.Empty; /// /// 是否已经销毁 /// public bool IsDestroyed { private set; get; } = false; - private readonly List _providers = new List(100); - private readonly List _removeList = new List(100); - protected bool IsForceDestroyComplete { private set; get; } = false; - internal AssetBundle CacheBundle { set; get; } - internal string FileLoadPath { set; get; } - internal float DownloadProgress { set; get; } - internal ulong DownloadedBytes { set; get; } + /// + /// 引用计数 + /// + public int RefCount { private set; get; } = 0; + + /// + /// 下载进度 + /// + public float DownloadProgress { set; get; } = 0; + + /// + /// 下载大小 + /// + public long DownloadedBytes { set; get; } = 0; + + /// + /// 下载结果 + /// + public object Result { set; get; } - public BundleLoaderBase(ResourceManager impl, BundleInfo bundleInfo) + public BundleFileLoader(ResourceManager resourceManager, BundleInfo bundleInfo) { - Impl = impl; + _resourceManager = resourceManager; MainBundleInfo = bundleInfo; - RefCount = 0; Status = EStatus.None; } + /// + /// 轮询更新 + /// + public void Update() + { + if (_isDone) + return; + + if (_loadBundleOp == null) + _loadBundleOp = MainBundleInfo.LoadBundleFile(); + + DownloadProgress = _loadBundleOp.DownloadProgress; + DownloadedBytes = _loadBundleOp.DownloadedBytes; + if (_loadBundleOp.IsDone == false) + return; + + if (_loadBundleOp.Status == EOperationStatus.Succeed) + { + _isDone = true; + Status = EStatus.Succeed; + Result = _loadBundleOp.Result; + } + else + { + _isDone = true; + Status = EStatus.Failed; + LastError = _loadBundleOp.Error; + } + } + + /// + /// 销毁 + /// + public void Destroy() + { + IsDestroyed = true; + + // Check fatal + if (RefCount > 0) + 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.Bundle.BundleName}"); + + MainBundleInfo.UnloadBundleFile(Result); + } + /// /// 引用(引用计数递加) /// @@ -130,52 +183,40 @@ namespace YooAsset // 移除资源提供者 if (_removeList.Count > 0) { - Impl.RemoveBundleProviders(_removeList); + _resourceManager.RemoveBundleProviders(_removeList); _removeList.Clear(); } } - - /// - /// 轮询更新 - /// - public abstract void Update(); - - /// - /// 销毁 - /// - public virtual void Destroy() - { - IsDestroyed = true; - - // Check fatal - if (RefCount > 0) - 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.Bundle.BundleName}"); - - if (CacheBundle != null) - { - CacheBundle.Unload(true); - CacheBundle = null; - } - } - - /// - /// 强制销毁资源提供者 - /// - public void ForceDestroyComplete() - { - IsForceDestroyComplete = true; - - // 注意:主动轮询更新完成同步加载 - // 说明:如果正在下载或解压也可以放心销毁。 - Update(); - } - /// /// 主线程等待异步操作完毕 /// - public abstract void WaitForAsyncComplete(); + public void WaitForAsyncComplete() + { + while (true) + { + if (_loadBundleOp != null) + { + if (_loadBundleOp.IsDone == false) + _loadBundleOp.WaitForAsyncComplete(); + } + + // 驱动流程 + Update(); + + // 完成后退出 + if (IsDone()) + break; + } + } + + /// + /// 终止下载任务 + /// + public void AbortDownloadOperation() + { + if (_loadBundleOp != null) + _loadBundleOp.AbortDownloadOperation(); + } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleFileLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleFileLoader.cs.meta new file mode 100644 index 00000000..2aae8658 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleFileLoader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 031287bf937f83e4fa18a0db797abb42 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleLoaderBase.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleLoaderBase.cs.meta deleted file mode 100644 index 5cd8fa4f..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleLoaderBase.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b8aaabc43e74af14d8eb3c7c85e19cda -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/DependAssetBundles.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/DependAssetBundles.cs.meta deleted file mode 100644 index d770c0d6..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/DependAssetBundles.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b7eeccc96e4c31c45bd105b0dbc3fd6e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/DependAssetBundles.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/DependFileLoaders.cs similarity index 89% rename from Assets/YooAsset/Runtime/ResourceManager/Loader/DependAssetBundles.cs rename to Assets/YooAsset/Runtime/ResourceManager/Loader/DependFileLoaders.cs index d2e5496b..c484afd3 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/DependAssetBundles.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Loader/DependFileLoaders.cs @@ -4,15 +4,15 @@ using System.Collections.Generic; namespace YooAsset { - internal class DependAssetBundles + internal class DependFileLoaders { /// /// 依赖的资源包加载器列表 /// - internal readonly List DependList; + internal readonly List DependList; - public DependAssetBundles(List dpendList) + public DependFileLoaders(List dpendList) { DependList = dpendList; } @@ -37,7 +37,7 @@ namespace YooAsset { foreach (var loader in DependList) { - if (loader.Status != BundleLoaderBase.EStatus.Succeed) + if (loader.Status != BundleFileLoader.EStatus.Succeed) { return false; } @@ -52,7 +52,7 @@ namespace YooAsset { foreach (var loader in DependList) { - if (loader.Status != BundleLoaderBase.EStatus.Succeed) + if (loader.Status != BundleFileLoader.EStatus.Succeed) { return loader.LastError; } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/DependFileLoaders.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/DependFileLoaders.cs.meta new file mode 100644 index 00000000..edd0393a --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Loader/DependFileLoaders.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3834f832061fdd74fbfb1eba381b1b3e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadStatus.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/DownloadStatus.cs similarity index 57% rename from Assets/YooAsset/Runtime/DownloadSystem/DownloadStatus.cs rename to Assets/YooAsset/Runtime/ResourceManager/Loader/DownloadStatus.cs index 880d81d1..038503c1 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadStatus.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Loader/DownloadStatus.cs @@ -4,32 +4,28 @@ namespace YooAsset public struct DownloadStatus { /// - /// 下载是否完成 + /// 下载是否已经完成 /// public bool IsDone; /// - /// 下载进度(0f~1f) + /// 下载进度(0-1f) /// public float Progress; /// - /// 需要下载的总字节数 + /// 下载文件的总大小 /// - public ulong TotalBytes; + public long TotalBytes; /// - /// 已经下载的字节数 + /// 已经下载的文件大小 /// - public ulong DownloadedBytes; + public long DownloadedBytes; public static DownloadStatus CreateDefaultStatus() { DownloadStatus status = new DownloadStatus(); - status.IsDone = false; - status.Progress = 0f; - status.TotalBytes = 0; - status.DownloadedBytes = 0; return status; } } diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadStatus.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/DownloadStatus.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/DownloadSystem/DownloadStatus.cs.meta rename to Assets/YooAsset/Runtime/ResourceManager/Loader/DownloadStatus.cs.meta index 43818f2f..28567282 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadStatus.cs.meta +++ b/Assets/YooAsset/Runtime/ResourceManager/Loader/DownloadStatus.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d40b8341fcd4ad2478eb1a890ebf0476 +guid: 26dbf3c6610209e40bcf31c9c66739bc MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleFileLoader.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleFileLoader.cs deleted file mode 100644 index f1163ee7..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleFileLoader.cs +++ /dev/null @@ -1,188 +0,0 @@ -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(ResourceManager 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.CachedDataFilePath; - } - else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming) - { -#if UNITY_ANDROID - _steps = ESteps.Unpack; - FileLoadPath = MainBundleInfo.CachedDataFilePath; -#else - _steps = ESteps.CheckFile; - FileLoadPath = MainBundleInfo.BuildinFilePath; -#endif - } - else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) - { - _steps = ESteps.CheckFile; - FileLoadPath = MainBundleInfo.CachedDataFilePath; - } - else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromDelivery) - { - _steps = ESteps.CheckFile; - FileLoadPath = MainBundleInfo.DeliveryFilePath; - } - else - { - throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString()); - } - } - - // 1. 下载远端文件 - if (_steps == ESteps.Download) - { - _downloader = MainBundleInfo.CreateDownloader(int.MaxValue); - _downloader.SendRequest(); - _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 = 1; - _unpacker = MainBundleInfo.CreateUnpacker(failedTryAgain); - _unpacker.SendRequest(); - _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; - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleFileLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleFileLoader.cs.meta deleted file mode 100644 index 011a6a35..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleFileLoader.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fa39f24727abe514093f18787c0c7e27 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleWebLoader.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleWebLoader.cs deleted file mode 100644 index 18c37a31..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleWebLoader.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System.IO; - -namespace YooAsset -{ - /// - /// WebGL平台加载器 - /// - internal class RawBundleWebLoader : BundleLoaderBase - { - private enum ESteps - { - None, - Download, - CheckDownload, - Website, - CheckWebsite, - CheckFile, - Done, - } - - private ESteps _steps = ESteps.None; - private DownloaderBase _website; - private DownloaderBase _downloader; - - - public RawBundleWebLoader(ResourceManager 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.CachedDataFilePath; - } - else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming) - { - _steps = ESteps.Website; - FileLoadPath = MainBundleInfo.CachedDataFilePath; - } - else - { - throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString()); - } - } - - // 1. 下载远端文件 - if (_steps == ESteps.Download) - { - _downloader = MainBundleInfo.CreateDownloader(int.MaxValue); - _downloader.SendRequest(); - _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.Website) - { - _website = MainBundleInfo.CreateUnpacker(int.MaxValue); - _website.SendRequest(); - _steps = ESteps.CheckWebsite; - } - - // 4. 检测站点下载 - if (_steps == ESteps.CheckWebsite) - { - DownloadProgress = _website.DownloadProgress; - DownloadedBytes = _website.DownloadedBytes; - if (_website.IsDone() == false) - return; - - if (_website.HasError()) - { - _steps = ESteps.Done; - Status = EStatus.Failed; - LastError = _website.GetLastError(); - } - else - { - _steps = ESteps.CheckFile; - } - } - - // 5. 检测结果 - if (_steps == ESteps.CheckFile) - { - // 设置下载进度 - DownloadProgress = 1f; - DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize; - - _steps = ESteps.Done; - if (File.Exists(FileLoadPath)) - { - Status = EStatus.Succeed; - } - else - { - Status = EStatus.Failed; - LastError = $"Raw file not found : {FileLoadPath}"; - } - } - } - - /// - /// 主线程等待异步操作完毕 - /// - public override void WaitForAsyncComplete() - { - if (IsDone() == false) - { - Status = EStatus.Failed; - LastError = $"{nameof(WaitForAsyncComplete)} failed ! WebGL platform not support sync load method !"; - YooLogger.Error(LastError); - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleWebLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleWebLoader.cs.meta deleted file mode 100644 index 6420e988..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleWebLoader.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1d16b689f73611e44bd01a4cc429a6ac -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/VirtualBundleFileLoader.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/VirtualBundleFileLoader.cs deleted file mode 100644 index c90a6ddc..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/VirtualBundleFileLoader.cs +++ /dev/null @@ -1,82 +0,0 @@ - -namespace YooAsset -{ - internal class VirtualBundleFileLoader : BundleLoaderBase - { - private enum ESteps - { - None, - CheckFile, - Done, - } - - private ESteps _steps = ESteps.None; - - public VirtualBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo) - { - } - - /// - /// 轮询更新 - /// - public override void Update() - { - if (_steps == ESteps.Done) - return; - - if (_steps == ESteps.None) - { - if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromEditor) - { - _steps = ESteps.CheckFile; - } - else - { - throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString()); - } - } - - // 1. 检测结果 - if (_steps == ESteps.CheckFile) - { - // 设置下载进度 - DownloadProgress = 1f; - DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize; - - _steps = ESteps.Done; - Status = EStatus.Succeed; - } - } - - /// - /// 主线程等待异步操作完毕 - /// - public override void WaitForAsyncComplete() - { - int frame = 1000; - while (true) - { - // 保险机制 - // 注意:如果需要从远端下载资源,可能会触发保险机制! - 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; - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/VirtualBundleFileLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/VirtualBundleFileLoader.cs.meta deleted file mode 100644 index c8289e17..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/Loader/VirtualBundleFileLoader.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7b9023a940b496549894d9d8872219fb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs index 1b4b762b..68158a47 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs @@ -72,23 +72,10 @@ namespace YooAsset } } - /// - /// 取消实例化对象操作 - /// - public void Cancel() - { - if (IsDone == false) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"User cancelled !"; - } - } - /// /// 等待异步实例化结束 /// - public void WaitForAsyncComplete() + public override void WaitForAsyncComplete() { if (_steps == ESteps.Done) return; @@ -96,6 +83,14 @@ namespace YooAsset InternalOnUpdate(); } + /// + /// 取消实例化对象操作 + /// + public void Cancel() + { + SetAbort(); + } + internal static GameObject InstantiateInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) { if (assetObject == null) diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs new file mode 100644 index 00000000..b0563fb7 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs @@ -0,0 +1,94 @@ +using System; +using UnityEngine; + +namespace YooAsset +{ + public sealed class UnloadAllAssetsOperation : AsyncOperationBase + { + private enum ESteps + { + None, + AbortDownload, + CheckLoading, + UnloadAll, + Done, + } + + private readonly ResourceManager _resManager; + private ESteps _steps = ESteps.None; + + internal UnloadAllAssetsOperation(ResourceManager resourceManager) + { + _resManager = resourceManager; + } + internal override void InternalOnStart() + { + _steps = ESteps.AbortDownload; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.AbortDownload) + { + // 注意:终止所有下载任务 + var loaderList = _resManager._loaderList; + foreach (var loader in loaderList) + { + loader.AbortDownloadOperation(); + } + _steps = ESteps.CheckLoading; + } + + if (_steps == ESteps.CheckLoading) + { + // 注意:等待所有任务完成 + var providerDic = _resManager._providerDic; + foreach (var provider in providerDic.Values) + { + if (provider.IsDone == false) + return; + } + _steps = ESteps.UnloadAll; + } + + if (_steps == ESteps.UnloadAll) + { + var loaderList = _resManager._loaderList; + var loaderDic = _resManager._loaderDic; + var providerDic = _resManager._providerDic; + + // 释放所有资源句柄 + foreach (var provider in providerDic.Values) + { + provider.ReleaseAllHandles(); + } + + // 强制销毁资源提供者 + foreach (var provider in providerDic.Values) + { + provider.Destroy(); + } + + // 强制销毁文件加载器 + foreach (var loader in loaderList) + { + loader.Destroy(); + } + + // 清空数据 + providerDic.Clear(); + loaderList.Clear(); + loaderDic.Clear(); + _resManager.ClearSceneHandle(); + + // 注意:调用底层接口释放所有资源 + Resources.UnloadUnusedAssets(); + + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs.meta new file mode 100644 index 00000000..f76659be --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 97b5f55d30137a4438d3cbed93819c6b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs new file mode 100644 index 00000000..9c4708d8 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs @@ -0,0 +1,62 @@ +using System; +using UnityEngine; + +namespace YooAsset +{ + public sealed class UnloadUnusedAssetsOperation : AsyncOperationBase + { + private enum ESteps + { + None, + UnloadUnused, + Done, + } + + private readonly ResourceManager _resManager; + private ESteps _steps = ESteps.None; + + internal UnloadUnusedAssetsOperation(ResourceManager resourceManager) + { + _resManager = resourceManager; + } + internal override void InternalOnStart() + { + _steps = ESteps.UnloadUnused; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.UnloadUnused) + { + var loaderList = _resManager._loaderList; + var loaderDic = _resManager._loaderDic; + + for (int i = loaderList.Count - 1; i >= 0; i--) + { + BundleFileLoader loader = loaderList[i]; + loader.TryDestroyProviders(); + } + + for (int i = loaderList.Count - 1; i >= 0; i--) + { + BundleFileLoader loader = loaderList[i]; + if (loader.CanDestroy()) + { + string bundleName = loader.MainBundleInfo.Bundle.BundleName; + loader.Destroy(); + loaderList.RemoveAt(i); + loaderDic.Remove(bundleName); + } + } + + // 注意:调用底层接口释放所有资源 + Resources.UnloadUnusedAssets(); + + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs.meta new file mode 100644 index 00000000..6556c042 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90a7cd6101e04ac48ae6aa383572d2c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAllAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAllAssetsProvider.cs index 7182738b..0266506b 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAllAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAllAssetsProvider.cs @@ -6,6 +6,7 @@ namespace YooAsset { internal sealed class BundledAllAssetsProvider : ProviderBase { + private AssetBundle _assetBundle; private AssetBundleRequest _cacheRequest; public BundledAllAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo) @@ -30,54 +31,62 @@ namespace YooAsset { if (IsWaitForAsyncComplete) { - DependBundles.WaitForAsyncComplete(); - OwnerBundle.WaitForAsyncComplete(); + DependLoaders.WaitForAsyncComplete(); + FileLoader.WaitForAsyncComplete(); } - if (DependBundles.IsDone() == false) + if (DependLoaders.IsDone() == false) return; - if (OwnerBundle.IsDone() == false) + if (FileLoader.IsDone() == false) return; - if (DependBundles.IsSucceed() == false) + if (DependLoaders.IsSucceed() == false) { - string error = DependBundles.GetLastError(); + string error = DependLoaders.GetLastError(); InvokeCompletion(error, EOperationStatus.Failed); return; } - if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + if (FileLoader.Status != BundleFileLoader.EStatus.Succeed) { - string error = OwnerBundle.LastError; + string error = FileLoader.LastError; InvokeCompletion(error, EOperationStatus.Failed); return; } - if (OwnerBundle.CacheBundle == null) + if (FileLoader.Result == null) { - ProcessCacheBundleException(); + ProcessFatalEvent(); return; } + if (FileLoader.Result is AssetBundle == false) + { + string error = "Try load raw file using load assetbundle method !"; + InvokeCompletion(error, EOperationStatus.Failed); + return; + } + + _assetBundle = FileLoader.Result as AssetBundle; _steps = ESteps.Loading; } // 2. 加载资源对象 if (_steps == ESteps.Loading) { - if (IsWaitForAsyncComplete || IsForceDestroyComplete) + if (IsWaitForAsyncComplete) { if (MainAssetInfo.AssetType == null) - AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets(); + AllAssetObjects = _assetBundle.LoadAllAssets(); else - AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets(MainAssetInfo.AssetType); + AllAssetObjects = _assetBundle.LoadAllAssets(MainAssetInfo.AssetType); } else { if (MainAssetInfo.AssetType == null) - _cacheRequest = OwnerBundle.CacheBundle.LoadAllAssetsAsync(); + _cacheRequest = _assetBundle.LoadAllAssetsAsync(); else - _cacheRequest = OwnerBundle.CacheBundle.LoadAllAssetsAsync(MainAssetInfo.AssetType); + _cacheRequest = _assetBundle.LoadAllAssetsAsync(MainAssetInfo.AssetType); } _steps = ESteps.Checking; } @@ -87,7 +96,7 @@ namespace YooAsset { if (_cacheRequest != null) { - if (IsWaitForAsyncComplete || IsForceDestroyComplete) + if (IsWaitForAsyncComplete) { // 强制挂起主线程(注意:该操作会很耗时) YooLogger.Warning("Suspend the main thread to load unity asset."); @@ -106,9 +115,9 @@ namespace YooAsset { string error; if (MainAssetInfo.AssetType == null) - error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}"; + error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {FileLoader.MainBundleInfo.Bundle.BundleName}"; else - error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}"; + error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {FileLoader.MainBundleInfo.Bundle.BundleName}"; YooLogger.Error(error); InvokeCompletion(error, EOperationStatus.Failed); } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAssetProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAssetProvider.cs index a77a1f34..7af1d013 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAssetProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAssetProvider.cs @@ -6,6 +6,7 @@ namespace YooAsset { internal sealed class BundledAssetProvider : ProviderBase { + private AssetBundle _assetBundle; private AssetBundleRequest _cacheRequest; public BundledAssetProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo) @@ -30,54 +31,62 @@ namespace YooAsset { if (IsWaitForAsyncComplete) { - DependBundles.WaitForAsyncComplete(); - OwnerBundle.WaitForAsyncComplete(); + DependLoaders.WaitForAsyncComplete(); + FileLoader.WaitForAsyncComplete(); } - if (DependBundles.IsDone() == false) + if (DependLoaders.IsDone() == false) return; - if (OwnerBundle.IsDone() == false) + if (FileLoader.IsDone() == false) return; - if (DependBundles.IsSucceed() == false) + if (DependLoaders.IsSucceed() == false) { - string error = DependBundles.GetLastError(); + string error = DependLoaders.GetLastError(); InvokeCompletion(error, EOperationStatus.Failed); return; } - if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + if (FileLoader.Status != BundleFileLoader.EStatus.Succeed) { - string error = OwnerBundle.LastError; + string error = FileLoader.LastError; InvokeCompletion(error, EOperationStatus.Failed); return; } - if (OwnerBundle.CacheBundle == null) + if (FileLoader.Result == null) { - ProcessCacheBundleException(); + ProcessFatalEvent(); return; } + if (FileLoader.Result is AssetBundle == false) + { + string error = "Try load raw file using load assetbundle method !"; + InvokeCompletion(error, EOperationStatus.Failed); + return; + } + + _assetBundle = FileLoader.Result as AssetBundle; _steps = ESteps.Loading; } // 2. 加载资源对象 if (_steps == ESteps.Loading) { - if (IsWaitForAsyncComplete || IsForceDestroyComplete) + if (IsWaitForAsyncComplete) { if (MainAssetInfo.AssetType == null) - AssetObject = OwnerBundle.CacheBundle.LoadAsset(MainAssetInfo.AssetPath); + AssetObject = _assetBundle.LoadAsset(MainAssetInfo.AssetPath); else - AssetObject = OwnerBundle.CacheBundle.LoadAsset(MainAssetInfo.AssetPath, MainAssetInfo.AssetType); + AssetObject = _assetBundle.LoadAsset(MainAssetInfo.AssetPath, MainAssetInfo.AssetType); } else { if (MainAssetInfo.AssetType == null) - _cacheRequest = OwnerBundle.CacheBundle.LoadAssetAsync(MainAssetInfo.AssetPath); + _cacheRequest = _assetBundle.LoadAssetAsync(MainAssetInfo.AssetPath); else - _cacheRequest = OwnerBundle.CacheBundle.LoadAssetAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType); + _cacheRequest = _assetBundle.LoadAssetAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType); } _steps = ESteps.Checking; } @@ -87,7 +96,7 @@ namespace YooAsset { if (_cacheRequest != null) { - if (IsWaitForAsyncComplete || IsForceDestroyComplete) + if (IsWaitForAsyncComplete) { // 强制挂起主线程(注意:该操作会很耗时) YooLogger.Warning("Suspend the main thread to load unity asset."); @@ -106,9 +115,9 @@ namespace YooAsset { string error; if (MainAssetInfo.AssetType == null) - error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}"; + error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {FileLoader.MainBundleInfo.Bundle.BundleName}"; else - error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}"; + error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {FileLoader.MainBundleInfo.Bundle.BundleName}"; YooLogger.Error(error); InvokeCompletion(error, EOperationStatus.Failed); } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledRawFileProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledRawFileProvider.cs index 4a104a83..1ef2a9de 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledRawFileProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledRawFileProvider.cs @@ -24,16 +24,21 @@ namespace YooAsset if (_steps == ESteps.CheckBundle) { if (IsWaitForAsyncComplete) - { - OwnerBundle.WaitForAsyncComplete(); - } + FileLoader.WaitForAsyncComplete(); - if (OwnerBundle.IsDone() == false) + if (FileLoader.IsDone() == false) return; - if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + if (FileLoader.Status != BundleFileLoader.EStatus.Succeed) { - string error = OwnerBundle.LastError; + string error = FileLoader.LastError; + InvokeCompletion(error, EOperationStatus.Failed); + return; + } + + if (FileLoader.Result is string == false) + { + string error = "Try load AssetBundle file using load raw file method !"; InvokeCompletion(error, EOperationStatus.Failed); return; } @@ -44,7 +49,7 @@ namespace YooAsset // 2. 检测加载结果 if (_steps == ESteps.Checking) { - RawFilePath = OwnerBundle.FileLoadPath; + RawFilePath = FileLoader.Result as string; InvokeCompletion(string.Empty, EOperationStatus.Succeed); } } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSceneProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSceneProvider.cs index eda57712..b684bd9d 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSceneProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSceneProvider.cs @@ -37,25 +37,25 @@ namespace YooAsset { if (IsWaitForAsyncComplete) { - DependBundles.WaitForAsyncComplete(); - OwnerBundle.WaitForAsyncComplete(); + DependLoaders.WaitForAsyncComplete(); + FileLoader.WaitForAsyncComplete(); } - if (DependBundles.IsDone() == false) + if (DependLoaders.IsDone() == false) return; - if (OwnerBundle.IsDone() == false) + if (FileLoader.IsDone() == false) return; - if (DependBundles.IsSucceed() == false) + if (DependLoaders.IsSucceed() == false) { - string error = DependBundles.GetLastError(); + string error = DependLoaders.GetLastError(); InvokeCompletion(error, EOperationStatus.Failed); return; } - if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + if (FileLoader.Status != BundleFileLoader.EStatus.Succeed) { - string error = OwnerBundle.LastError; + string error = FileLoader.LastError; InvokeCompletion(error, EOperationStatus.Failed); return; } @@ -66,7 +66,7 @@ namespace YooAsset // 2. 加载场景 if (_steps == ESteps.Loading) { - if (IsWaitForAsyncComplete || IsForceDestroyComplete) + if (IsWaitForAsyncComplete) { // 注意:场景同步加载方法不会立即加载场景,而是在下一帧加载。 LoadSceneParameters parameters = new LoadSceneParameters(SceneMode); @@ -99,7 +99,7 @@ namespace YooAsset { if (_asyncOperation != null) { - if (IsWaitForAsyncComplete || IsForceDestroyComplete) + if (IsWaitForAsyncComplete) { // 场景加载无法强制异步转同步 YooLogger.Error("The scene is loading asyn !"); diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSubAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSubAssetsProvider.cs index acc86410..7bc8e72e 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSubAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSubAssetsProvider.cs @@ -6,6 +6,7 @@ namespace YooAsset { internal sealed class BundledSubAssetsProvider : ProviderBase { + private AssetBundle _assetBundle; private AssetBundleRequest _cacheRequest; public BundledSubAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo) @@ -30,54 +31,62 @@ namespace YooAsset { if (IsWaitForAsyncComplete) { - DependBundles.WaitForAsyncComplete(); - OwnerBundle.WaitForAsyncComplete(); + DependLoaders.WaitForAsyncComplete(); + FileLoader.WaitForAsyncComplete(); } - if (DependBundles.IsDone() == false) + if (DependLoaders.IsDone() == false) return; - if (OwnerBundle.IsDone() == false) + if (FileLoader.IsDone() == false) return; - if (DependBundles.IsSucceed() == false) + if (DependLoaders.IsSucceed() == false) { - string error = DependBundles.GetLastError(); + string error = DependLoaders.GetLastError(); InvokeCompletion(error, EOperationStatus.Failed); return; } - if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + if (FileLoader.Status != BundleFileLoader.EStatus.Succeed) { - string error = OwnerBundle.LastError; + string error = FileLoader.LastError; InvokeCompletion(error, EOperationStatus.Failed); return; } - if (OwnerBundle.CacheBundle == null) + if (FileLoader.Result == null) { - ProcessCacheBundleException(); + ProcessFatalEvent(); return; } + if (FileLoader.Result is AssetBundle == false) + { + string error = "Try load raw file using load assetbundle method !"; + InvokeCompletion(error, EOperationStatus.Failed); + return; + } + + _assetBundle = FileLoader.Result as AssetBundle; _steps = ESteps.Loading; } // 2. 加载资源对象 if (_steps == ESteps.Loading) { - if (IsWaitForAsyncComplete || IsForceDestroyComplete) + if (IsWaitForAsyncComplete) { if (MainAssetInfo.AssetType == null) - AllAssetObjects = OwnerBundle.CacheBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath); + AllAssetObjects = _assetBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath); else - AllAssetObjects = OwnerBundle.CacheBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath, MainAssetInfo.AssetType); + AllAssetObjects = _assetBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath, MainAssetInfo.AssetType); } else { if (MainAssetInfo.AssetType == null) - _cacheRequest = OwnerBundle.CacheBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath); + _cacheRequest = _assetBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath); else - _cacheRequest = OwnerBundle.CacheBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType); + _cacheRequest = _assetBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType); } _steps = ESteps.Checking; } @@ -87,7 +96,7 @@ namespace YooAsset { if (_cacheRequest != null) { - if (IsWaitForAsyncComplete || IsForceDestroyComplete) + if (IsWaitForAsyncComplete) { // 强制挂起主线程(注意:该操作会很耗时) YooLogger.Warning("Suspend the main thread to load unity asset."); @@ -106,9 +115,9 @@ namespace YooAsset { string error; if (MainAssetInfo.AssetType == null) - error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}"; + error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {FileLoader.MainBundleInfo.Bundle.BundleName}"; else - error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}"; + error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {FileLoader.MainBundleInfo.Bundle.BundleName}"; YooLogger.Error(error); InvokeCompletion(error, EOperationStatus.Failed); } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAllAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAllAssetsProvider.cs index 8e192718..d8a9604a 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAllAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAllAssetsProvider.cs @@ -43,15 +43,15 @@ namespace YooAsset { if (IsWaitForAsyncComplete) { - OwnerBundle.WaitForAsyncComplete(); + FileLoader.WaitForAsyncComplete(); } - if (OwnerBundle.IsDone() == false) + if (FileLoader.IsDone() == false) return; - if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + if (FileLoader.Status != BundleFileLoader.EStatus.Succeed) { - string error = OwnerBundle.LastError; + string error = FileLoader.LastError; InvokeCompletion(error, EOperationStatus.Failed); return; } @@ -65,7 +65,7 @@ namespace YooAsset if (MainAssetInfo.AssetType == null) { List result = new List(); - foreach (var assetPath in OwnerBundle.MainBundleInfo.IncludeAssetsInEditor) + foreach (var assetPath in FileLoader.MainBundleInfo.IncludeAssetsInEditor) { UnityEngine.Object mainAsset = UnityEditor.AssetDatabase.LoadMainAssetAtPath(assetPath); if (mainAsset != null) @@ -76,7 +76,7 @@ namespace YooAsset else { List result = new List(); - foreach (var assetPath in OwnerBundle.MainBundleInfo.IncludeAssetsInEditor) + foreach (var assetPath in FileLoader.MainBundleInfo.IncludeAssetsInEditor) { UnityEngine.Object mainAsset = UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath, MainAssetInfo.AssetType); if (mainAsset != null) diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAssetProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAssetProvider.cs index d42b2662..3e0d5a81 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAssetProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAssetProvider.cs @@ -43,15 +43,15 @@ namespace YooAsset { if (IsWaitForAsyncComplete) { - OwnerBundle.WaitForAsyncComplete(); + FileLoader.WaitForAsyncComplete(); } - if (OwnerBundle.IsDone() == false) + if (FileLoader.IsDone() == false) return; - if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + if (FileLoader.Status != BundleFileLoader.EStatus.Succeed) { - string error = OwnerBundle.LastError; + string error = FileLoader.LastError; InvokeCompletion(error, EOperationStatus.Failed); return; } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseRawFileProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseRawFileProvider.cs index ddfb56f1..c2c7ea18 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseRawFileProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseRawFileProvider.cs @@ -40,15 +40,15 @@ namespace YooAsset { if (IsWaitForAsyncComplete) { - OwnerBundle.WaitForAsyncComplete(); + FileLoader.WaitForAsyncComplete(); } - if (OwnerBundle.IsDone() == false) + if (FileLoader.IsDone() == false) return; - if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + if (FileLoader.Status != BundleFileLoader.EStatus.Succeed) { - string error = OwnerBundle.LastError; + string error = FileLoader.LastError; InvokeCompletion(error, EOperationStatus.Failed); return; } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSceneProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSceneProvider.cs index 11b55fd7..cf779e78 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSceneProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSceneProvider.cs @@ -38,15 +38,15 @@ namespace YooAsset { if (IsWaitForAsyncComplete) { - OwnerBundle.WaitForAsyncComplete(); + FileLoader.WaitForAsyncComplete(); } - if (OwnerBundle.IsDone() == false) + if (FileLoader.IsDone() == false) return; - if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + if (FileLoader.Status != BundleFileLoader.EStatus.Succeed) { - string error = OwnerBundle.LastError; + string error = FileLoader.LastError; InvokeCompletion(error, EOperationStatus.Failed); return; } @@ -57,7 +57,7 @@ namespace YooAsset // 2. 加载资源对象 if (_steps == ESteps.Loading) { - if (IsWaitForAsyncComplete || IsForceDestroyComplete) + if (IsWaitForAsyncComplete) { LoadSceneParameters loadSceneParameters = new LoadSceneParameters(SceneMode); SceneObject = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneInPlayMode(MainAssetInfo.AssetPath, loadSceneParameters); @@ -88,7 +88,7 @@ namespace YooAsset { if (_asyncOperation != null) { - if (IsWaitForAsyncComplete || IsForceDestroyComplete) + if (IsWaitForAsyncComplete) { // 场景加载无法强制异步转同步 YooLogger.Error("The scene is loading asyn !"); diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSubAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSubAssetsProvider.cs index c3e2e821..53706d56 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSubAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSubAssetsProvider.cs @@ -43,15 +43,15 @@ namespace YooAsset { if (IsWaitForAsyncComplete) { - OwnerBundle.WaitForAsyncComplete(); + FileLoader.WaitForAsyncComplete(); } - if (OwnerBundle.IsDone() == false) + if (FileLoader.IsDone() == false) return; - if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed) + if (FileLoader.Status != BundleFileLoader.EStatus.Succeed) { - string error = OwnerBundle.LastError; + string error = FileLoader.LastError; InvokeCompletion(error, EOperationStatus.Failed); return; } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderBase.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderBase.cs index 5a54f112..4c50af11 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderBase.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderBase.cs @@ -1,7 +1,6 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.Threading.Tasks; using System; namespace YooAsset @@ -69,10 +68,9 @@ namespace YooAsset protected ESteps _steps = ESteps.None; - protected BundleLoaderBase OwnerBundle { private set; get; } - protected DependAssetBundles DependBundles { private set; get; } + protected BundleFileLoader FileLoader { private set; get; } + protected DependFileLoaders DependLoaders { private set; get; } protected bool IsWaitForAsyncComplete { private set; get; } = false; - protected bool IsForceDestroyComplete { private set; get; } = false; private readonly List _handles = new List(); @@ -85,13 +83,30 @@ namespace YooAsset // 创建资源包加载器 if (manager != null) { - OwnerBundle = manager.CreateOwnerAssetBundleLoader(assetInfo); - OwnerBundle.Reference(); - OwnerBundle.AddProvider(this); + FileLoader = manager.CreateOwnerFileLoader(assetInfo); + FileLoader.Reference(); + FileLoader.AddProvider(this); - var dependList = manager.CreateDependAssetBundleLoaders(assetInfo); - DependBundles = new DependAssetBundles(dependList); - DependBundles.Reference(); + var dependList = manager.CreateDependFileLoaders(assetInfo); + DependLoaders = new DependFileLoaders(dependList); + DependLoaders.Reference(); + } + } + + /// + /// 等待异步执行完毕 + /// + public override void WaitForAsyncComplete() + { + IsWaitForAsyncComplete = true; + + // 注意:主动轮询更新完成同步加载 + InternalOnUpdate(); + + // 验证结果 + if (IsDone == false) + { + YooLogger.Warning($"{nameof(WaitForAsyncComplete)} failed to loading : {MainAssetInfo.AssetPath}"); } } @@ -110,15 +125,15 @@ namespace YooAsset } // 释放资源包加载器 - if (OwnerBundle != null) + if (FileLoader != null) { - OwnerBundle.Release(); - OwnerBundle = null; + FileLoader.Release(); + FileLoader = null; } - if (DependBundles != null) + if (DependLoaders != null) { - DependBundles.Release(); - DependBundles = null; + DependLoaders.Release(); + DependLoaders = null; } } @@ -188,43 +203,14 @@ namespace YooAsset } /// - /// 等待异步执行完毕 + /// 处理致命问题 /// - public void WaitForAsyncComplete() + protected void ProcessFatalEvent() { - IsWaitForAsyncComplete = true; - - // 注意:主动轮询更新完成同步加载 - InternalOnUpdate(); - - // 验证结果 - if (IsDone == false) - { - YooLogger.Warning($"{nameof(WaitForAsyncComplete)} failed to loading : {MainAssetInfo.AssetPath}"); - } - } - - /// - /// 强制销毁资源提供者 - /// - public void ForceDestroyComplete() - { - IsForceDestroyComplete = true; - - // 注意:主动轮询更新完成同步加载 - // 说明:如果资源包未准备完毕也可以放心销毁。 - InternalOnUpdate(); - } - - /// - /// 处理特殊异常 - /// - protected void ProcessCacheBundleException() - { - if (OwnerBundle.IsDestroyed) + if (FileLoader.IsDestroyed) throw new System.Exception("Should never get here !"); - string error = $"The bundle {OwnerBundle.MainBundleInfo.Bundle.BundleName} has been destroyed by unity bugs !"; + string error = $"The bundle {FileLoader.MainBundleInfo.Bundle.BundleName} has been destroyed by unity bugs !"; YooLogger.Error(error); InvokeCompletion(Error, EOperationStatus.Failed); } @@ -252,6 +238,28 @@ namespace YooAsset } } + /// + /// 获取下载报告 + /// + public DownloadStatus GetDownloadStatus() + { + DownloadStatus status = new DownloadStatus(); + status.TotalBytes = FileLoader.MainBundleInfo.Bundle.FileSize; + status.DownloadedBytes = FileLoader.DownloadedBytes; + foreach (var dependBundle in DependLoaders.DependList) + { + status.TotalBytes += dependBundle.MainBundleInfo.Bundle.FileSize; + status.DownloadedBytes += dependBundle.DownloadedBytes; + } + + if (status.TotalBytes == 0) + throw new System.Exception("Should never get here !"); + + status.IsDone = status.DownloadedBytes == status.TotalBytes; + status.Progress = (float)status.DownloadedBytes / status.TotalBytes; + return status; + } + #region 调试信息相关 /// /// 出生的场景 @@ -304,40 +312,18 @@ namespace YooAsset } } - /// - /// 获取下载报告 - /// - internal DownloadStatus GetDownloadStatus() - { - DownloadStatus status = new DownloadStatus(); - status.TotalBytes = (ulong)OwnerBundle.MainBundleInfo.Bundle.FileSize; - status.DownloadedBytes = OwnerBundle.DownloadedBytes; - foreach (var dependBundle in DependBundles.DependList) - { - status.TotalBytes += (ulong)dependBundle.MainBundleInfo.Bundle.FileSize; - status.DownloadedBytes += dependBundle.DownloadedBytes; - } - - if (status.TotalBytes == 0) - throw new System.Exception("Should never get here !"); - - status.IsDone = status.DownloadedBytes == status.TotalBytes; - status.Progress = (float)status.DownloadedBytes / status.TotalBytes; - return status; - } - /// /// 获取资源包的调试信息列表 /// internal void GetBundleDebugInfos(List output) { var bundleInfo = new DebugBundleInfo(); - bundleInfo.BundleName = OwnerBundle.MainBundleInfo.Bundle.BundleName; - bundleInfo.RefCount = OwnerBundle.RefCount; - bundleInfo.Status = OwnerBundle.Status.ToString(); + bundleInfo.BundleName = FileLoader.MainBundleInfo.Bundle.BundleName; + bundleInfo.RefCount = FileLoader.RefCount; + bundleInfo.Status = FileLoader.Status.ToString(); output.Add(bundleInfo); - DependBundles.GetBundleDebugInfos(output); + DependLoaders.GetBundleDebugInfos(output); } #endregion } diff --git a/Assets/YooAsset/Runtime/ResourceManager/ResourceLoader.cs b/Assets/YooAsset/Runtime/ResourceManager/ResourceLoader.cs deleted file mode 100644 index 029c0b7e..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/ResourceLoader.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System.IO; -using UnityEngine; - -namespace YooAsset -{ - internal class ResourceLoader - { - private IDecryptionServices _decryption; - private IDeliveryLoadServices _delivery; - - public void Init(IDecryptionServices decryption, IDeliveryLoadServices delivery) - { - _decryption = decryption; - _delivery = delivery; - } - - /// - /// 同步加载资源包对象 - /// - public AssetBundle LoadAssetBundle(BundleInfo bundleInfo, string fileLoadPath, out Stream managedStream) - { - managedStream = null; - if (bundleInfo.Bundle.Encrypted) - { - if (_decryption == null) - { - YooLogger.Error($"{nameof(IDecryptionServices)} is null ! when load asset bundle {bundleInfo.Bundle.BundleName}!"); - return null; - } - - DecryptFileInfo fileInfo = new DecryptFileInfo(); - fileInfo.BundleName = bundleInfo.Bundle.BundleName; - fileInfo.FileLoadPath = fileLoadPath; - fileInfo.ConentCRC = bundleInfo.Bundle.UnityCRC; - return _decryption.LoadAssetBundle(fileInfo, out managedStream); - } - else - { - return AssetBundle.LoadFromFile(fileLoadPath); - } - } - - /// - /// 异步加载资源包对象 - /// - public AssetBundleCreateRequest LoadAssetBundleAsync(BundleInfo bundleInfo, string fileLoadPath, out Stream managedStream) - { - managedStream = null; - if (bundleInfo.Bundle.Encrypted) - { - if (_decryption == null) - { - YooLogger.Error($"{nameof(IDecryptionServices)} is null ! when load asset bundle {bundleInfo.Bundle.BundleName}!"); - return null; - } - - DecryptFileInfo fileInfo = new DecryptFileInfo(); - fileInfo.BundleName = bundleInfo.Bundle.BundleName; - fileInfo.FileLoadPath = fileLoadPath; - fileInfo.ConentCRC = bundleInfo.Bundle.UnityCRC; - return _decryption.LoadAssetBundleAsync(fileInfo, out managedStream); - } - else - { - return AssetBundle.LoadFromFileAsync(fileLoadPath); - } - } - - /// - /// 同步加载分发的资源包对象 - /// - public AssetBundle LoadDeliveryAssetBundle(BundleInfo bundleInfo, string fileLoadPath) - { - if (_delivery == null) - throw new System.Exception("Should never get here !"); - - // 注意:对于已经加密的资源包,需要开发者自行解密。 - DeliveryFileInfo fileInfo = new DeliveryFileInfo(); - fileInfo.BundleName = bundleInfo.Bundle.BundleName; - fileInfo.FileLoadPath = fileLoadPath; - fileInfo.ConentCRC = bundleInfo.Bundle.UnityCRC; - fileInfo.Encrypted = bundleInfo.Bundle.Encrypted; - return _delivery.LoadAssetBundle(fileInfo); - } - - /// - /// 异步加载分发的资源包对象 - /// - public AssetBundleCreateRequest LoadDeliveryAssetBundleAsync(BundleInfo bundleInfo, string fileLoadPath) - { - if (_delivery == null) - throw new System.Exception("Should never get here !"); - - // 注意:对于已经加密的资源包,需要开发者自行解密。 - DeliveryFileInfo fileInfo = new DeliveryFileInfo(); - fileInfo.BundleName = bundleInfo.Bundle.BundleName; - fileInfo.FileLoadPath = fileLoadPath; - fileInfo.ConentCRC = bundleInfo.Bundle.UnityCRC; - fileInfo.Encrypted = bundleInfo.Bundle.Encrypted; - return _delivery.LoadAssetBundleAsync(fileInfo); - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/ResourceLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/ResourceLoader.cs.meta deleted file mode 100644 index 21c5f910..00000000 --- a/Assets/YooAsset/Runtime/ResourceManager/ResourceLoader.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3818e5adef4eaea4a85b112f953c4f7b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs b/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs index dfb2745f..b07237b5 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs @@ -13,9 +13,9 @@ namespace YooAsset private readonly static Dictionary _sceneHandles = new Dictionary(100); private static long _sceneCreateCount = 0; - private readonly Dictionary _providerDic = new Dictionary(5000); - private readonly Dictionary _loaderDic = new Dictionary(5000); - private readonly List _loaderList = new List(5000); + internal readonly Dictionary _providerDic = new Dictionary(5000); + internal readonly Dictionary _loaderDic = new Dictionary(5000); + internal readonly List _loaderList = new List(5000); private bool _simulationOnEditor; private bool _autoDestroyAssetProvider; @@ -35,10 +35,10 @@ namespace YooAsset /// /// 初始化 /// - public void Initialize(bool simulationOnEditor, bool autoDestroyAssetProvider, IBundleQuery bundleServices) + public void Initialize(InitializeParameters initializeParameters, IBundleQuery bundleServices) { - _simulationOnEditor = simulationOnEditor; - _autoDestroyAssetProvider = autoDestroyAssetProvider; + _simulationOnEditor = initializeParameters is EditorSimulateModeParameters; + _autoDestroyAssetProvider = initializeParameters.AutoDestroyAssetProvider; _bundleQuery = bundleServices; } @@ -56,30 +56,6 @@ namespace YooAsset } } - /// - /// 资源回收(卸载引用计数为零的资源) - /// - public void UnloadUnusedAssets() - { - for (int i = _loaderList.Count - 1; i >= 0; i--) - { - BundleLoaderBase loader = _loaderList[i]; - loader.TryDestroyProviders(); - } - - for (int i = _loaderList.Count - 1; i >= 0; i--) - { - BundleLoaderBase loader = _loaderList[i]; - if (loader.CanDestroy()) - { - string bundleName = loader.MainBundleInfo.Bundle.BundleName; - loader.Destroy(); - _loaderList.RemoveAt(i); - _loaderDic.Remove(bundleName); - } - } - } - /// /// 尝试卸载指定资源的资源包(包括依赖资源) /// @@ -92,8 +68,8 @@ namespace YooAsset } // 卸载主资源包加载器 - string manBundleName = _bundleQuery.GetMainBundleName(assetInfo); - var mainLoader = TryGetAssetBundleLoader(manBundleName); + string mainBundleName = _bundleQuery.GetMainBundleName(assetInfo); + var mainLoader = TryGetFileLoader(mainBundleName); if (mainLoader != null) { mainLoader.TryDestroyProviders(); @@ -110,7 +86,7 @@ namespace YooAsset string[] dependBundleNames = _bundleQuery.GetDependBundleNames(assetInfo); foreach (var dependBundleName in dependBundleNames) { - var dependLoader = TryGetAssetBundleLoader(dependBundleName); + var dependLoader = TryGetFileLoader(dependBundleName); if (dependLoader != null) { if (dependLoader.CanDestroy()) @@ -124,57 +100,6 @@ namespace YooAsset } } - /// - /// 强制回收所有资源 - /// 注意:加载器在销毁后关联的下载器还会继续下载! - /// - public void ForceUnloadAllAssets() - { -#if UNITY_WEBGL - throw new Exception($"WebGL not support invoke {nameof(ForceUnloadAllAssets)}"); -#else - // 注意:因为场景无法异步转同步,需要等待所有场景加载完毕! - foreach (var sceneHandlePair in _sceneHandles) - { - var sceneHandle = sceneHandlePair.Value; - if (sceneHandle.PackageName == PackageName) - { - if (sceneHandle.IsDone == false) - throw new Exception($"{nameof(ForceUnloadAllAssets)} cannot be called when loading the scene !"); - } - } - - // 释放所有资源句柄 - foreach (var provider in _providerDic.Values) - { - provider.ReleaseAllHandles(); - } - - // 强制销毁资源提供者 - foreach (var provider in _providerDic.Values) - { - provider.ForceDestroyComplete(); - provider.Destroy(); - } - - // 强制销毁资源加载器 - foreach (var loader in _loaderList) - { - loader.ForceDestroyComplete(); - loader.Destroy(); - } - - // 清空数据 - _providerDic.Clear(); - _loaderList.Clear(); - _loaderDic.Clear(); - ClearSceneHandle(); - - // 注意:调用底层接口释放所有资源 - Resources.UnloadUnusedAssets(); -#endif - } - /// /// 加载场景对象 /// 注意:返回的场景句柄是唯一的,每个场景句柄对应自己的场景提供者对象。 @@ -336,6 +261,7 @@ namespace YooAsset return provider.CreateHandle(); } + internal void UnloadSubScene(string sceneName) { List removeKeys = new List(); @@ -355,7 +281,7 @@ namespace YooAsset _sceneHandles.Remove(key); } } - private void UnloadAllScene() + internal void UnloadAllScene() { // 释放所有场景句柄 foreach (var valuePair in _sceneHandles) @@ -364,7 +290,7 @@ namespace YooAsset } _sceneHandles.Clear(); } - private void ClearSceneHandle() + internal void ClearSceneHandle() { // 释放资源包下的所有场景 if (_bundleQuery.ManifestValid()) @@ -385,18 +311,18 @@ namespace YooAsset } } - internal BundleLoaderBase CreateOwnerAssetBundleLoader(AssetInfo assetInfo) + internal BundleFileLoader CreateOwnerFileLoader(AssetInfo assetInfo) { BundleInfo bundleInfo = _bundleQuery.GetMainBundleInfo(assetInfo); - return CreateAssetBundleLoaderInternal(bundleInfo); + return CreateFileLoaderInternal(bundleInfo); } - internal List CreateDependAssetBundleLoaders(AssetInfo assetInfo) + internal List CreateDependFileLoaders(AssetInfo assetInfo) { BundleInfo[] depends = _bundleQuery.GetDependBundleInfos(assetInfo); - List result = new List(depends.Length); + List result = new List(depends.Length); foreach (var bundleInfo in depends) { - BundleLoaderBase dependLoader = CreateAssetBundleLoaderInternal(bundleInfo); + BundleFileLoader dependLoader = CreateFileLoaderInternal(bundleInfo); result.Add(dependLoader); } return result; @@ -413,41 +339,23 @@ namespace YooAsset return _loaderList.Count > 0; } - private BundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo) + private BundleFileLoader CreateFileLoaderInternal(BundleInfo bundleInfo) { // 如果加载器已经存在 string bundleName = bundleInfo.Bundle.BundleName; - BundleLoaderBase loader = TryGetAssetBundleLoader(bundleName); + BundleFileLoader loader = TryGetFileLoader(bundleName); if (loader != null) return loader; // 新增下载需求 - if (_simulationOnEditor) - { - loader = new VirtualBundleFileLoader(this, bundleInfo); - } - else - { -#if UNITY_WEBGL - if (bundleInfo.Bundle.Buildpipeline== EDefaultBuildPipeline.RawFileBuildPipeline.ToString()) - loader = new RawBundleWebLoader(this, bundleInfo); - else - loader = new AssetBundleWebLoader(this, bundleInfo); -#else - if (bundleInfo.Bundle.Buildpipeline == EDefaultBuildPipeline.RawFileBuildPipeline.ToString()) - loader = new RawBundleFileLoader(this, bundleInfo); - else - loader = new AssetBundleFileLoader(this, bundleInfo); -#endif - } - + loader = new BundleFileLoader(this, bundleInfo); _loaderList.Add(loader); _loaderDic.Add(bundleName, loader); return loader; } - private BundleLoaderBase TryGetAssetBundleLoader(string bundleName) + private BundleFileLoader TryGetFileLoader(string bundleName) { - if (_loaderDic.TryGetValue(bundleName, out BundleLoaderBase value)) + if (_loaderDic.TryGetValue(bundleName, out BundleFileLoader value)) return value; else return null; diff --git a/Assets/YooAsset/Runtime/ResourcePackage/AssetInfo.cs b/Assets/YooAsset/Runtime/ResourcePackage/AssetInfo.cs index 189feb6b..3114b314 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/AssetInfo.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/AssetInfo.cs @@ -43,7 +43,7 @@ namespace YooAsset /// /// 身份是否无效 /// - internal bool IsInvalid + public bool IsInvalid { get { @@ -77,11 +77,6 @@ namespace YooAsset } } - - private AssetInfo() - { - // 注意:禁止从外部创建该类 - } internal AssetInfo(string packageName, PackageAsset packageAsset, System.Type assetType) { if (packageAsset == null) diff --git a/Assets/YooAsset/Runtime/ResourcePackage/BundleInfo.cs b/Assets/YooAsset/Runtime/ResourcePackage/BundleInfo.cs index 5a0dcd68..a87d2f45 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/BundleInfo.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/BundleInfo.cs @@ -6,204 +6,71 @@ namespace YooAsset { internal class BundleInfo { - public enum ELoadMode - { - None, - LoadFromDelivery, - LoadFromStreaming, - LoadFromCache, - LoadFromRemote, - LoadFromEditor, - } - - private readonly ResourceAssist _assist; + private readonly string _importFilePath; + private readonly IFileSystem _fileSystem; /// /// 资源包对象 /// public readonly PackageBundle Bundle; - /// - /// 资源包加载模式 - /// - public readonly ELoadMode LoadMode; - - /// - /// 远端下载地址 - /// - public string RemoteMainURL { private set; get; } - - /// - /// 远端下载备用地址 - /// - public string RemoteFallbackURL { private set; get; } - - /// - /// 分发资源文件路径 - /// - public string DeliveryFilePath { private set; get; } - /// /// 注意:该字段只用于帮助编辑器下的模拟模式。 /// public string[] IncludeAssetsInEditor; - private BundleInfo() + + public BundleInfo(IFileSystem fileSystem, PackageBundle bundle) { - } - public BundleInfo(ResourceAssist assist, PackageBundle bundle, ELoadMode loadMode, string mainURL, string fallbackURL) - { - _assist = assist; + _fileSystem = fileSystem; Bundle = bundle; - LoadMode = loadMode; - RemoteMainURL = mainURL; - RemoteFallbackURL = fallbackURL; - DeliveryFilePath = string.Empty; + _importFilePath = null; } - public BundleInfo(ResourceAssist assist, PackageBundle bundle, ELoadMode loadMode, string deliveryFilePath) + public BundleInfo(IFileSystem fileSystem, PackageBundle bundle, string importFilePath) { - _assist = assist; + _fileSystem = fileSystem; Bundle = bundle; - LoadMode = loadMode; - RemoteMainURL = string.Empty; - RemoteFallbackURL = string.Empty; - DeliveryFilePath = deliveryFilePath; - } - public BundleInfo(ResourceAssist assist, PackageBundle bundle, ELoadMode loadMode) - { - _assist = assist; - Bundle = bundle; - LoadMode = loadMode; - RemoteMainURL = string.Empty; - RemoteFallbackURL = string.Empty; - DeliveryFilePath = string.Empty; - } - - #region Cache - public bool IsCached() - { - return _assist.Cache.IsCached(Bundle.CacheGUID); - } - public void CacheRecord() - { - string infoFilePath = CachedInfoFilePath; - string dataFilePath = CachedDataFilePath; - string dataFileCRC = Bundle.FileCRC; - long dataFileSize = Bundle.FileSize; - var wrapper = new CacheManager.RecordWrapper(infoFilePath, dataFilePath, dataFileCRC, dataFileSize); - _assist.Cache.Record(Bundle.CacheGUID, wrapper); - } - public void CacheDiscard() - { - _assist.Cache.Discard(Bundle.CacheGUID); - } - public EVerifyResult VerifySelf() - { - return CacheHelper.VerifyingRecordFile(_assist.Cache, Bundle.CacheGUID); - } - #endregion - - #region Persistent - public string CachedDataFilePath - { - get - { - return _assist.Persistent.GetCachedDataFilePath(Bundle); - } - } - public string CachedInfoFilePath - { - get - { - return _assist.Persistent.GetCachedInfoFilePath(Bundle); - } - } - public string TempDataFilePath - { - get - { - return _assist.Persistent.GetTempDataFilePath(Bundle); - } - } - public string BuildinFilePath - { - get - { - return _assist.Persistent.GetBuildinFilePath(Bundle); - } - } - #endregion - - #region Download - public DownloaderBase CreateDownloader(int failedTryAgain, int timeout = 60) - { - return _assist.Download.CreateDownload(this, failedTryAgain, timeout); - } - public DownloaderBase CreateUnpacker(int failedTryAgain, int timeout = 60) - { - var unpackBundleInfo = ConvertToUnpackInfo(); - return _assist.Download.CreateDownload(unpackBundleInfo, failedTryAgain, timeout); - } - #endregion - - #region AssetBundle - internal AssetBundle LoadAssetBundle(string fileLoadPath, out Stream managedStream) - { - return _assist.Loader.LoadAssetBundle(this, fileLoadPath, out managedStream); - } - internal AssetBundleCreateRequest LoadAssetBundleAsync(string fileLoadPath, out Stream managedStream) - { - return _assist.Loader.LoadAssetBundleAsync(this, fileLoadPath, out managedStream); - } - internal AssetBundle LoadDeliveryAssetBundle(string fileLoadPath) - { - return _assist.Loader.LoadDeliveryAssetBundle(this, fileLoadPath); - } - internal AssetBundleCreateRequest LoadDeliveryAssetBundleAsync(string fileLoadPath) - { - return _assist.Loader.LoadDeliveryAssetBundleAsync(this, fileLoadPath); - } - #endregion - - /// - /// 转换为解压BundleInfo - /// - private BundleInfo ConvertToUnpackInfo() - { - string streamingPath = PersistentHelper.ConvertToWWWPath(BuildinFilePath); - BundleInfo newBundleInfo = new BundleInfo(_assist, Bundle, ELoadMode.LoadFromStreaming, streamingPath, streamingPath); - return newBundleInfo; + _importFilePath = importFilePath; } /// - /// 批量创建解压BundleInfo + /// 加载资源文件 /// - public static List CreateUnpackInfos(ResourceAssist assist, List unpackList) + public FSLoadBundleOperation LoadBundleFile() { - List result = new List(unpackList.Count); - foreach (var packageBundle in unpackList) - { - var bundleInfo = CreateUnpackInfo(assist, packageBundle); - result.Add(bundleInfo); - } - return result; - } - private static BundleInfo CreateUnpackInfo(ResourceAssist assist, PackageBundle packageBundle) - { - string streamingPath = PersistentHelper.ConvertToWWWPath(assist.Persistent.GetBuildinFilePath(packageBundle)); - BundleInfo newBundleInfo = new BundleInfo(assist, packageBundle, ELoadMode.LoadFromStreaming, streamingPath, streamingPath); - return newBundleInfo; + return _fileSystem.LoadBundleFile(Bundle); } /// - /// 创建导入BundleInfo + /// 卸载资源文件 /// - public static BundleInfo CreateImportInfo(ResourceAssist assist, PackageBundle packageBundle, string filePath) + public void UnloadBundleFile(object result) { - // 注意:我们把本地文件路径指定为远端下载地址 - string persistentPath = PersistentHelper.ConvertToWWWPath(filePath); - BundleInfo bundleInfo = new BundleInfo(assist, packageBundle, BundleInfo.ELoadMode.None, persistentPath, persistentPath); - return bundleInfo; + _fileSystem.UnloadBundleFile(Bundle, result); + } + + /// + /// 创建下载器 + /// + public FSDownloadFileOperation CreateDownloader(int failedTryAgain, int timeout) + { + return _fileSystem.DownloadFileAsync(Bundle, _importFilePath, failedTryAgain, timeout); + } + + /// + /// 是否需要从远端下载 + /// + public bool IsNeedDownloadFromRemote() + { + return _fileSystem.CheckNeedDownload(Bundle); + } + + /// + /// 下载器合并识别码 + /// + public string GetDownloadCombineGUID() + { + return $"{_fileSystem.GetHashCode()}_{Bundle.BundleGUID}"; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs b/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs index ca51c1e1..a526e5f9 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs @@ -4,30 +4,40 @@ namespace YooAsset internal interface IPlayMode { /// - /// 激活的清单 + /// 当前激活的清单 /// PackageManifest ActiveManifest { set; get; } /// - /// 保存清单版本文件到沙盒 + /// 更新游戏模式 /// - void FlushManifestVersionFile(); + void UpdatePlayMode(); /// /// 向网络端请求最新的资源版本 /// - UpdatePackageVersionOperation UpdatePackageVersionAsync(bool appendTimeTicks, int timeout); + RequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout); /// /// 向网络端请求并更新清单 /// - UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout); + UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, int timeout); /// /// 预下载指定版本的包裹内容 /// PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout); + /// + /// 清空所有文件 + /// + ClearAllBundleFilesOperation ClearAllBundleFilesAsync(); + + /// + /// 清空未使用的文件 + /// + ClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(); + // 下载相关 ResourceDownloaderOperation CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout); ResourceDownloaderOperation CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout); diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearAllBundleFilesOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearAllBundleFilesOperation.cs new file mode 100644 index 00000000..7f054013 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearAllBundleFilesOperation.cs @@ -0,0 +1,286 @@ + +namespace YooAsset +{ + /// + /// 清理所有文件 + /// + public abstract class ClearAllBundleFilesOperation : AsyncOperationBase + { + } + + /// + /// 编辑器下模拟模式 + /// + internal sealed class EditorSimulateModeClearAllBundleFilesOperation : ClearAllBundleFilesOperation + { + private enum ESteps + { + None, + ClearAllBundleFiles, + Done, + } + + private readonly EditorSimulateModeImpl _impl; + private FSClearAllBundleFilesOperation _clearAllBundleFilesOp; + private ESteps _steps = ESteps.None; + + internal EditorSimulateModeClearAllBundleFilesOperation(EditorSimulateModeImpl impl) + { + _impl = impl; + } + internal override void InternalOnStart() + { + _steps = ESteps.ClearAllBundleFiles; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearAllBundleFiles) + { + if (_clearAllBundleFilesOp == null) + { + _clearAllBundleFilesOp = _impl.EditorFileSystem.ClearAllBundleFilesAsync(); + } + + Progress = _clearAllBundleFilesOp.Progress; + if (_clearAllBundleFilesOp.IsDone == false) + return; + + if (_clearAllBundleFilesOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearAllBundleFilesOp.Error; + } + } + } + } + + /// + /// 离线运行模式 + /// + internal sealed class OfflinePlayModeClearAllBundleFilesOperation : ClearAllBundleFilesOperation + { + private enum ESteps + { + None, + ClearAllBundleFiles, + Done, + } + + private readonly OfflinePlayModeImpl _impl; + private FSClearAllBundleFilesOperation _clearAllBundleFilesOp; + private ESteps _steps = ESteps.None; + + internal OfflinePlayModeClearAllBundleFilesOperation(OfflinePlayModeImpl impl) + { + _impl = impl; + } + internal override void InternalOnStart() + { + _steps = ESteps.ClearAllBundleFiles; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearAllBundleFiles) + { + if (_clearAllBundleFilesOp == null) + { + _clearAllBundleFilesOp = _impl.BuildinFileSystem.ClearAllBundleFilesAsync(); + } + + Progress = _clearAllBundleFilesOp.Progress; + if (_clearAllBundleFilesOp.IsDone == false) + return; + + if (_clearAllBundleFilesOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearAllBundleFilesOp.Error; + } + } + } + } + + /// + /// 联机运行模式 + /// + internal sealed class HostPlayModeClearAllBundleFilesOperation : ClearAllBundleFilesOperation + { + private enum ESteps + { + None, + ClearBuildinAllBundleFiles, + ClearDeliveryAllBundleFiles, + ClearCacheAllBundleFiles, + Done, + } + + private readonly HostPlayModeImpl _impl; + private FSClearAllBundleFilesOperation _clearBuildinAllBundleFilesOp; + private FSClearAllBundleFilesOperation _clearDeliveryAllBundleFilesOp; + private FSClearAllBundleFilesOperation _clearCacheAllBundleFilesOp; + private ESteps _steps = ESteps.None; + + internal HostPlayModeClearAllBundleFilesOperation(HostPlayModeImpl impl) + { + _impl = impl; + } + internal override void InternalOnStart() + { + _steps = ESteps.ClearBuildinAllBundleFiles; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearBuildinAllBundleFiles) + { + if (_clearBuildinAllBundleFilesOp == null) + { + _clearBuildinAllBundleFilesOp = _impl.BuildinFileSystem.ClearAllBundleFilesAsync(); + } + + Progress = _clearBuildinAllBundleFilesOp.Progress; + if (_clearBuildinAllBundleFilesOp.IsDone == false) + return; + + if (_clearBuildinAllBundleFilesOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.ClearDeliveryAllBundleFiles; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearBuildinAllBundleFilesOp.Error; + } + } + + if (_steps == ESteps.ClearDeliveryAllBundleFiles) + { + if (_impl.DeliveryFileSystem == null) + { + _steps = ESteps.ClearCacheAllBundleFiles; + return; + } + + if (_clearDeliveryAllBundleFilesOp == null) + { + _clearDeliveryAllBundleFilesOp = _impl.DeliveryFileSystem.ClearAllBundleFilesAsync(); + } + + Progress = _clearDeliveryAllBundleFilesOp.Progress; + if (_clearDeliveryAllBundleFilesOp.IsDone == false) + return; + + if (_clearDeliveryAllBundleFilesOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.ClearCacheAllBundleFiles; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearDeliveryAllBundleFilesOp.Error; + } + } + + if (_steps == ESteps.ClearCacheAllBundleFiles) + { + if (_clearCacheAllBundleFilesOp == null) + { + _clearCacheAllBundleFilesOp = _impl.CacheFileSystem.ClearAllBundleFilesAsync(); + } + + Progress = _clearCacheAllBundleFilesOp.Progress; + if (_clearCacheAllBundleFilesOp.IsDone == false) + return; + + if (_clearCacheAllBundleFilesOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearCacheAllBundleFilesOp.Error; + } + } + } + } + + /// + /// WebGL运行模式 + /// + internal sealed class WebPlayModeClearAllBundleFilesOperation : ClearAllBundleFilesOperation + { + private enum ESteps + { + None, + ClearAllBundleFiles, + Done, + } + + private readonly WebPlayModeImpl _impl; + private FSClearAllBundleFilesOperation _clearAllBundleFilesOp; + private ESteps _steps = ESteps.None; + + internal WebPlayModeClearAllBundleFilesOperation(WebPlayModeImpl impl) + { + _impl = impl; + } + internal override void InternalOnStart() + { + _steps = ESteps.ClearAllBundleFiles; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearAllBundleFiles) + { + if (_clearAllBundleFilesOp == null) + { + _clearAllBundleFilesOp = _impl.WebFileSystem.ClearAllBundleFilesAsync(); + } + + Progress = _clearAllBundleFilesOp.Progress; + if (_clearAllBundleFilesOp.IsDone == false) + return; + + if (_clearAllBundleFilesOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearAllBundleFilesOp.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearAllBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearAllBundleFilesOperation.cs.meta new file mode 100644 index 00000000..302fb64f --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearAllBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f25029d71d0d8c4dad70987bda364bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearUnusedBundleFilesOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearUnusedBundleFilesOperation.cs new file mode 100644 index 00000000..0cef2416 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearUnusedBundleFilesOperation.cs @@ -0,0 +1,287 @@ + +namespace YooAsset +{ + /// + /// 清理未使用的文件 + /// + public abstract class ClearUnusedBundleFilesOperation : AsyncOperationBase + { + } + + /// + /// 编辑器下模拟模式 + /// + internal sealed class EditorSimulateModeClearUnusedBundleFilesOperation : ClearUnusedBundleFilesOperation + { + private enum ESteps + { + None, + ClearUnusedBundleFiles, + Done, + } + + private readonly EditorSimulateModeImpl _impl; + private FSClearUnusedBundleFilesOperation _clearUnusedBundleFilesOp; + private ESteps _steps = ESteps.None; + + internal EditorSimulateModeClearUnusedBundleFilesOperation(EditorSimulateModeImpl impl) + { + _impl = impl; + } + internal override void InternalOnStart() + { + _steps = ESteps.ClearUnusedBundleFiles; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearUnusedBundleFiles) + { + if (_clearUnusedBundleFilesOp == null) + { + _clearUnusedBundleFilesOp = _impl.EditorFileSystem.ClearUnusedBundleFilesAsync(_impl.ActiveManifest); + } + + Progress = _clearUnusedBundleFilesOp.Progress; + if (_clearUnusedBundleFilesOp.IsDone == false) + return; + + if (_clearUnusedBundleFilesOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearUnusedBundleFilesOp.Error; + } + } + } + } + + /// + /// 离线运行模式 + /// + internal sealed class OfflinePlayModeClearUnusedBundleFilesOperation : ClearUnusedBundleFilesOperation + { + private enum ESteps + { + None, + ClearUnusedBundleFiles, + Done, + } + + private readonly OfflinePlayModeImpl _impl; + private FSClearUnusedBundleFilesOperation _clearUnusedBundleFilesOp; + private ESteps _steps = ESteps.None; + + internal OfflinePlayModeClearUnusedBundleFilesOperation(OfflinePlayModeImpl impl) + { + _impl = impl; + } + internal override void InternalOnStart() + { + _steps = ESteps.ClearUnusedBundleFiles; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearUnusedBundleFiles) + { + if (_clearUnusedBundleFilesOp == null) + { + _clearUnusedBundleFilesOp = _impl.BuildinFileSystem.ClearUnusedBundleFilesAsync(_impl.ActiveManifest); + } + + Progress = _clearUnusedBundleFilesOp.Progress; + if (_clearUnusedBundleFilesOp.IsDone == false) + return; + + if (_clearUnusedBundleFilesOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearUnusedBundleFilesOp.Error; + } + } + } + } + + /// + /// 联机运行模式 + /// + internal sealed class HostPlayModeClearUnusedBundleFilesOperation : ClearUnusedBundleFilesOperation + { + private enum ESteps + { + None, + ClearBuildinUnusedBundleFiles, + ClearDeliveryUnusedBundleFiles, + ClearCacheUnusedBundleFiles, + Done, + } + + private readonly HostPlayModeImpl _impl; + private FSClearUnusedBundleFilesOperation _clearBuildinUnusedBundleFilesOp; + private FSClearUnusedBundleFilesOperation _clearDeliveryUnusedBundleFilesOp; + private FSClearUnusedBundleFilesOperation _clearCacheUnusedBundleFilesOp; + private ESteps _steps = ESteps.None; + + internal HostPlayModeClearUnusedBundleFilesOperation(HostPlayModeImpl impl) + { + _impl = impl; + } + internal override void InternalOnStart() + { + _steps = ESteps.ClearBuildinUnusedBundleFiles; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearBuildinUnusedBundleFiles) + { + if (_clearBuildinUnusedBundleFilesOp == null) + { + _clearBuildinUnusedBundleFilesOp = _impl.BuildinFileSystem.ClearUnusedBundleFilesAsync(_impl.ActiveManifest); + } + + Progress = _clearBuildinUnusedBundleFilesOp.Progress; + if (_clearBuildinUnusedBundleFilesOp.IsDone == false) + return; + + if (_clearBuildinUnusedBundleFilesOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.ClearDeliveryUnusedBundleFiles; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearBuildinUnusedBundleFilesOp.Error; + } + } + + if (_steps == ESteps.ClearDeliveryUnusedBundleFiles) + { + if (_impl.DeliveryFileSystem == null) + { + _steps = ESteps.ClearCacheUnusedBundleFiles; + return; + } + + if (_clearDeliveryUnusedBundleFilesOp == null) + { + _clearDeliveryUnusedBundleFilesOp = _impl.DeliveryFileSystem.ClearUnusedBundleFilesAsync(_impl.ActiveManifest); + } + + Progress = _clearDeliveryUnusedBundleFilesOp.Progress; + if (_clearDeliveryUnusedBundleFilesOp.IsDone == false) + return; + + if (_clearDeliveryUnusedBundleFilesOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.ClearCacheUnusedBundleFiles; + + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearDeliveryUnusedBundleFilesOp.Error; + } + } + + if (_steps == ESteps.ClearCacheUnusedBundleFiles) + { + if (_clearCacheUnusedBundleFilesOp == null) + { + _clearCacheUnusedBundleFilesOp = _impl.CacheFileSystem.ClearUnusedBundleFilesAsync(_impl.ActiveManifest); + } + + Progress = _clearCacheUnusedBundleFilesOp.Progress; + if (_clearCacheUnusedBundleFilesOp.IsDone == false) + return; + + if (_clearCacheUnusedBundleFilesOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearCacheUnusedBundleFilesOp.Error; + } + } + } + } + + /// + /// WebGL运行模式 + /// + internal sealed class WebPlayModeClearUnusedBundleFilesOperation : ClearUnusedBundleFilesOperation + { + private enum ESteps + { + None, + ClearUnusedBundleFiles, + Done, + } + + private readonly WebPlayModeImpl _impl; + private FSClearUnusedBundleFilesOperation _clearUnusedBundleFilesOp; + private ESteps _steps = ESteps.None; + + internal WebPlayModeClearUnusedBundleFilesOperation(WebPlayModeImpl impl) + { + _impl = impl; + } + internal override void InternalOnStart() + { + _steps = ESteps.ClearUnusedBundleFiles; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearUnusedBundleFiles) + { + if (_clearUnusedBundleFilesOp == null) + { + _clearUnusedBundleFilesOp = _impl.WebFileSystem.ClearUnusedBundleFilesAsync(_impl.ActiveManifest); + } + + Progress = _clearUnusedBundleFilesOp.Progress; + if (_clearUnusedBundleFilesOp.IsDone == false) + return; + + if (_clearUnusedBundleFilesOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _clearUnusedBundleFilesOp.Error; + } + } + } + } +} diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearUnusedBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearUnusedBundleFilesOperation.cs.meta new file mode 100644 index 00000000..a0bb9234 --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/ClearUnusedBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39028a4006030f1469b636b0c8b3805a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyOperation.cs new file mode 100644 index 00000000..9dd1ac5e --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyOperation.cs @@ -0,0 +1,67 @@ + +namespace YooAsset +{ + public class DestroyOperation : AsyncOperationBase + { + private enum ESteps + { + None, + UnloadAllAssets, + DestroyPackage, + Done, + } + + private readonly ResourcePackage _resourcePackage; + private UnloadAllAssetsOperation _unloadAllAssetsOp; + private ESteps _steps = ESteps.None; + + + public DestroyOperation(ResourcePackage resourcePackage) + { + _resourcePackage = resourcePackage; + } + + internal override void InternalOnStart() + { + _steps = ESteps.UnloadAllAssets; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.UnloadAllAssets) + { + if (_unloadAllAssetsOp == null) + _unloadAllAssetsOp = _resourcePackage.UnloadAllAssetsAsync(); + + if (_unloadAllAssetsOp.IsDone == false) + return; + + if (_unloadAllAssetsOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.DestroyPackage; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _unloadAllAssetsOp.Error; + } + } + + if (_steps == ESteps.DestroyPackage) + { + // 销毁包裹 + _resourcePackage.DestroyPackage(); + + // 最后清理该包裹的异步任务 + // 注意:对于有线程操作的异步任务,需要保证线程安全释放。 + OperationSystem.ClearPackageOperation(_resourcePackage.PackageName); + + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyOperation.cs.meta new file mode 100644 index 00000000..6c81ecfe --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DestroyOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 61a8757fa3c6b5c42a45e97198a645a4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOperation.cs index 377a6dd8..a2cee5fb 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOperation.cs @@ -20,15 +20,14 @@ namespace YooAsset public delegate void OnDownloadError(string fileName, string error); public delegate void OnStartDownloadFile(string fileName, long sizeBytes); - private readonly DownloadManager _downloadMgr; private readonly string _packageName; private readonly int _downloadingMaxNumber; private readonly int _failedTryAgain; private readonly int _timeout; private readonly List _bundleInfoList; - private readonly List _downloaders = new List(MAX_LOADER_COUNT); - private readonly List _removeList = new List(MAX_LOADER_COUNT); - private readonly List _failedList = new List(MAX_LOADER_COUNT); + private readonly List _downloaders = new List(MAX_LOADER_COUNT); + private readonly List _removeList = new List(MAX_LOADER_COUNT); + private readonly List _failedList = new List(MAX_LOADER_COUNT); // 数据相关 private bool _isPause = false; @@ -86,9 +85,8 @@ namespace YooAsset public OnStartDownloadFile OnStartDownloadFileCallback { set; get; } - internal DownloaderOperation(DownloadManager downloadMgr, string packageName, List downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout) + internal DownloaderOperation(string packageName, List downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout) { - _downloadMgr = downloadMgr; _packageName = packageName; _bundleInfoList = downloadList; _downloadingMaxNumber = UnityEngine.Mathf.Clamp(downloadingMaxNumber, 1, MAX_LOADER_COUNT); ; @@ -103,7 +101,7 @@ namespace YooAsset } internal override void InternalOnStart() { - YooLogger.Log($"Begine to download : {TotalDownloadCount} files and {TotalDownloadBytes} bytes"); + YooLogger.Log($"Begine to download {TotalDownloadCount} files and {TotalDownloadBytes} bytes"); _steps = ESteps.Check; } internal override void InternalOnUpdate() @@ -133,11 +131,11 @@ namespace YooAsset foreach (var downloader in _downloaders) { downloadBytes += (long)downloader.DownloadedBytes; - if (downloader.IsDone() == false) + if (downloader.IsDone == false) continue; // 检测是否下载失败 - if (downloader.HasError()) + if (downloader.Status != EOperationStatus.Succeed) { _removeList.Add(downloader); _failedList.Add(downloader); @@ -147,13 +145,13 @@ namespace YooAsset // 下载成功 _removeList.Add(downloader); _cachedDownloadCount++; - _cachedDownloadBytes += downloader.GetDownloadFileSize(); + _cachedDownloadBytes += (long)downloader.DownloadedBytes; } // 移除已经完成的下载器(无论成功或失败) - foreach (var loader in _removeList) + foreach (var downloader in _removeList) { - _downloaders.Remove(loader); + _downloaders.Remove(downloader); } // 如果下载进度发生变化 @@ -177,7 +175,6 @@ namespace YooAsset int index = _bundleInfoList.Count - 1; var bundleInfo = _bundleInfoList[index]; var downloader = bundleInfo.CreateDownloader(_failedTryAgain, _timeout); - downloader.SendRequest(); _downloaders.Add(downloader); _bundleInfoList.RemoveAt(index); OnStartDownloadFileCallback?.Invoke(bundleInfo.Bundle.BundleName, bundleInfo.Bundle.FileSize); @@ -190,11 +187,11 @@ namespace YooAsset if (_failedList.Count > 0) { var failedDownloader = _failedList[0]; - string bundleName = failedDownloader.GetDownloadBundleName(); + string bundleName = failedDownloader.Bundle.BundleName; _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = $"Failed to download file : {bundleName}"; - OnDownloadErrorCallback?.Invoke(bundleName, failedDownloader.GetLastError()); + OnDownloadErrorCallback?.Invoke(bundleName, failedDownloader.Error); OnDownloadOverCallback?.Invoke(false); } else @@ -246,16 +243,18 @@ namespace YooAsset HashSet temper = new HashSet(); foreach (var bundleInfo in _bundleInfoList) { - if (temper.Contains(bundleInfo.CachedDataFilePath) == false) + string combineGUID = bundleInfo.GetDownloadCombineGUID(); + if (temper.Contains(combineGUID) == false) { - temper.Add(bundleInfo.CachedDataFilePath); + temper.Add(combineGUID); } } // 合并下载列表 foreach (var bundleInfo in downloader._bundleInfoList) { - if (temper.Contains(bundleInfo.CachedDataFilePath) == false) + string combineGUID = bundleInfo.GetDownloadCombineGUID(); + if (temper.Contains(combineGUID) == false) { _bundleInfoList.Add(bundleInfo); } @@ -272,7 +271,7 @@ namespace YooAsset { if (_steps == ESteps.None) { - OperationSystem.StartOperation(this); + OperationSystem.StartOperation(_packageName, this); } } @@ -302,69 +301,63 @@ namespace YooAsset _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = "User cancel."; - ReleaseAllDownloader(); - } - } - private void ReleaseAllDownloader() - { - foreach (var downloader in _downloaders) - { - downloader.Release(); - } - // 注意:停止不再使用的下载器 - _downloadMgr.AbortUnusedDownloader(); + foreach (var downloader in _downloaders) + { + downloader.Release(); + } + } } } public sealed class ResourceDownloaderOperation : DownloaderOperation { - internal ResourceDownloaderOperation(DownloadManager downloadMgr, string packageName, List downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout) - : base(downloadMgr, packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout) + internal ResourceDownloaderOperation(string packageName, List downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout) + : base(packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout) { } /// /// 创建空的下载器 /// - internal static ResourceDownloaderOperation CreateEmptyDownloader(DownloadManager downloadMgr, string packageName, int downloadingMaxNumber, int failedTryAgain, int timeout) + internal static ResourceDownloaderOperation CreateEmptyDownloader(string packageName, int downloadingMaxNumber, int failedTryAgain, int timeout) { List downloadList = new List(); - var operation = new ResourceDownloaderOperation(downloadMgr, packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + var operation = new ResourceDownloaderOperation(packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } } public sealed class ResourceUnpackerOperation : DownloaderOperation { - internal ResourceUnpackerOperation(DownloadManager downloadMgr, string packageName, List downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout) - : base(downloadMgr, packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout) + internal ResourceUnpackerOperation(string packageName, List downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout) + : base(packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout) { } /// /// 创建空的解压器 /// - internal static ResourceUnpackerOperation CreateEmptyUnpacker(DownloadManager downloadMgr, string packageName, int upackingMaxNumber, int failedTryAgain, int timeout) + internal static ResourceUnpackerOperation CreateEmptyUnpacker(string packageName, int upackingMaxNumber, int failedTryAgain, int timeout) { List downloadList = new List(); - var operation = new ResourceUnpackerOperation(downloadMgr, packageName, downloadList, upackingMaxNumber, failedTryAgain, int.MaxValue); + var operation = new ResourceUnpackerOperation(packageName, downloadList, upackingMaxNumber, failedTryAgain, int.MaxValue); return operation; } } public sealed class ResourceImporterOperation : DownloaderOperation { - internal ResourceImporterOperation(DownloadManager downloadMgr, string packageName, List downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout) - : base(downloadMgr, packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout) + internal ResourceImporterOperation(string packageName, List downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout) + : base(packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout) { } /// /// 创建空的导入器 /// - internal static ResourceImporterOperation CreateEmptyImporter(DownloadManager downloadMgr, string packageName, int upackingMaxNumber, int failedTryAgain, int timeout) + internal static ResourceImporterOperation CreateEmptyImporter(string packageName, int upackingMaxNumber, int failedTryAgain, int timeout) { List downloadList = new List(); - var operation = new ResourceImporterOperation(downloadMgr, packageName, downloadList, upackingMaxNumber, failedTryAgain, int.MaxValue); + var operation = new ResourceImporterOperation(packageName, downloadList, upackingMaxNumber, failedTryAgain, int.MaxValue); return operation; } } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializationOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializationOperation.cs index e67993c6..0d081523 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializationOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/InitializationOperation.cs @@ -1,8 +1,4 @@ -using System.Collections; -using System.Collections.Generic; -using System.IO; -using UnityEngine; - + namespace YooAsset { /// @@ -10,429 +6,434 @@ namespace YooAsset /// public abstract class InitializationOperation : AsyncOperationBase { - public string PackageVersion { protected set; get; } } /// - /// 编辑器下模拟模式的初始化操作 + /// 编辑器下模拟模式 /// internal sealed class EditorSimulateModeInitializationOperation : InitializationOperation { private enum ESteps { None, - LoadEditorManifest, + CreateFileSystem, + InitFileSystem, + LoadManifestFile, Done, } private readonly EditorSimulateModeImpl _impl; - private readonly string _simulateManifestFilePath; - private LoadEditorManifestOperation _loadEditorManifestOp; + private readonly EditorSimulateModeParameters _parameters; + private FSInitializeFileSystemOperation _initFileSystemOp; + private FSLoadPackageManifestOperation _loadPackageManifestOp; private ESteps _steps = ESteps.None; - internal EditorSimulateModeInitializationOperation(EditorSimulateModeImpl impl, string simulateManifestFilePath) + internal EditorSimulateModeInitializationOperation(EditorSimulateModeImpl impl, EditorSimulateModeParameters parameters) { _impl = impl; - _simulateManifestFilePath = simulateManifestFilePath; + _parameters = parameters; } internal override void InternalOnStart() { - _steps = ESteps.LoadEditorManifest; + _steps = ESteps.CreateFileSystem; } internal override void InternalOnUpdate() { - if (_steps == ESteps.LoadEditorManifest) + if (_steps == ESteps.CreateFileSystem) { - if (_loadEditorManifestOp == null) + if (_parameters.EditorFileSystemParameters == null) { - _loadEditorManifestOp = new LoadEditorManifestOperation(_impl.PackageName, _simulateManifestFilePath); - OperationSystem.StartOperation(_impl.PackageName, _loadEditorManifestOp); + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Editor file system parameters is null"; + return; } - if (_loadEditorManifestOp.IsDone == false) + _impl.EditorFileSystem = PlayModeHelper.CreateFileSystem(_impl.PackageName, _parameters.EditorFileSystemParameters); + if (_impl.EditorFileSystem == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Failed to create editor file system"; + return; + } + + _steps = ESteps.InitFileSystem; + } + + if (_steps == ESteps.InitFileSystem) + { + if (_initFileSystemOp == null) + _initFileSystemOp = _impl.EditorFileSystem.InitializeFileSystemAsync(); + + Progress = _initFileSystemOp.Progress; + if (_initFileSystemOp.IsDone == false) return; - if (_loadEditorManifestOp.Status == EOperationStatus.Succeed) + if (_initFileSystemOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadManifestFile; + } + else { - PackageVersion = _loadEditorManifestOp.Manifest.PackageVersion; - _impl.ActiveManifest = _loadEditorManifestOp.Manifest; _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _initFileSystemOp.Error; + } + } + + if (_steps == ESteps.LoadManifestFile) + { + if (_loadPackageManifestOp == null) + _loadPackageManifestOp = _impl.EditorFileSystem.LoadPackageManifestAsync(null); + + Progress = _loadPackageManifestOp.Progress; + if (_loadPackageManifestOp.IsDone == false) + return; + + if (_loadPackageManifestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + _impl.ActiveManifest = _loadPackageManifestOp.Result; Status = EOperationStatus.Succeed; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _loadEditorManifestOp.Error; + Error = _loadPackageManifestOp.Error; } } } } /// - /// 离线运行模式的初始化操作 + /// 离线运行模式 /// internal sealed class OfflinePlayModeInitializationOperation : InitializationOperation { private enum ESteps { None, - QueryBuildinPackageVersion, - LoadBuildinManifest, - PackageCaching, + CreateFileSystem, + InitFileSystem, + LoadManifestFile, Done, } private readonly OfflinePlayModeImpl _impl; - private QueryBuildinPackageVersionOperation _queryBuildinPackageVersionOp; - private LoadBuildinManifestOperation _loadBuildinManifestOp; - private PackageCachingOperation _cachingOperation; + private readonly OfflinePlayModeParameters _parameters; + private FSInitializeFileSystemOperation _initFileSystemOp; + private FSLoadPackageManifestOperation _loadPackageManifestOp; private ESteps _steps = ESteps.None; - internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl) + internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl, OfflinePlayModeParameters parameters) { _impl = impl; + _parameters = parameters; } internal override void InternalOnStart() { - _steps = ESteps.QueryBuildinPackageVersion; + _steps = ESteps.CreateFileSystem; } internal override void InternalOnUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.QueryBuildinPackageVersion) + if (_steps == ESteps.CreateFileSystem) { - if (_queryBuildinPackageVersionOp == null) + if (_parameters.BuildinFileSystemParameters == null) { - _queryBuildinPackageVersionOp = new QueryBuildinPackageVersionOperation(_impl.Persistent); - OperationSystem.StartOperation(_impl.PackageName, _queryBuildinPackageVersionOp); + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Buildin file system parameters is null"; + return; } - if (_queryBuildinPackageVersionOp.IsDone == false) + _impl.BuildinFileSystem = PlayModeHelper.CreateFileSystem(_impl.PackageName, _parameters.BuildinFileSystemParameters); + if (_impl.BuildinFileSystem == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Failed to create buildin file system"; + return; + } + + _steps = ESteps.InitFileSystem; + } + + if (_steps == ESteps.InitFileSystem) + { + if (_initFileSystemOp == null) + _initFileSystemOp = _impl.BuildinFileSystem.InitializeFileSystemAsync(); + + Progress = _initFileSystemOp.Progress; + if (_initFileSystemOp.IsDone == false) return; - if (_queryBuildinPackageVersionOp.Status == EOperationStatus.Succeed) + if (_initFileSystemOp.Status == EOperationStatus.Succeed) { - _steps = ESteps.LoadBuildinManifest; + _steps = ESteps.LoadManifestFile; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _queryBuildinPackageVersionOp.Error; + Error = _initFileSystemOp.Error; } } - if (_steps == ESteps.LoadBuildinManifest) + if (_steps == ESteps.LoadManifestFile) { - if (_loadBuildinManifestOp == null) - { - _loadBuildinManifestOp = new LoadBuildinManifestOperation(_impl.Persistent, _queryBuildinPackageVersionOp.PackageVersion); - OperationSystem.StartOperation(_impl.PackageName, _loadBuildinManifestOp); - } + if (_loadPackageManifestOp == null) + _loadPackageManifestOp = _impl.BuildinFileSystem.LoadPackageManifestAsync(null); - Progress = _loadBuildinManifestOp.Progress; - if (_loadBuildinManifestOp.IsDone == false) + Progress = _loadPackageManifestOp.Progress; + if (_loadPackageManifestOp.IsDone == false) return; - if (_loadBuildinManifestOp.Status == EOperationStatus.Succeed) - { - PackageVersion = _loadBuildinManifestOp.Manifest.PackageVersion; - _impl.ActiveManifest = _loadBuildinManifestOp.Manifest; - _steps = ESteps.PackageCaching; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _loadBuildinManifestOp.Error; - } - } - - if (_steps == ESteps.PackageCaching) - { - if (_cachingOperation == null) - { - _cachingOperation = new PackageCachingOperation(_impl.Persistent, _impl.Cache); - OperationSystem.StartOperation(_impl.PackageName, _cachingOperation); - } - - Progress = _cachingOperation.Progress; - if (_cachingOperation.IsDone) + if (_loadPackageManifestOp.Status == EOperationStatus.Succeed) { _steps = ESteps.Done; + _impl.ActiveManifest = _loadPackageManifestOp.Result; Status = EOperationStatus.Succeed; } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadPackageManifestOp.Error; + } } } } /// - /// 联机运行模式的初始化操作 - /// 注意:优先从沙盒里加载清单,如果沙盒里不存在就尝试把内置清单拷贝到沙盒并加载该清单。 + /// 联机运行模式 /// internal sealed class HostPlayModeInitializationOperation : InitializationOperation { private enum ESteps { None, - CheckAppFootPrint, - QueryCachePackageVersion, - TryLoadCacheManifest, - QueryBuildinPackageVersion, - UnpackBuildinManifest, - LoadBuildinManifest, - PackageCaching, + CreateFileSystem, + InitBuildinFileSystem, + InitDeliveryFileSystem, + InitCacheFileSystem, Done, } private readonly HostPlayModeImpl _impl; - private QueryBuildinPackageVersionOperation _queryBuildinPackageVersionOp; - private QueryCachePackageVersionOperation _queryCachePackageVersionOp; - private UnpackBuildinManifestOperation _unpackBuildinManifestOp; - private LoadBuildinManifestOperation _loadBuildinManifestOp; - private LoadCacheManifestOperation _loadCacheManifestOp; - private PackageCachingOperation _cachingOperation; + private readonly HostPlayModeParameters _parameters; + private FSInitializeFileSystemOperation _initBuildinFileSystemOp; + private FSInitializeFileSystemOperation _initDeliveryFileSystemOp; + private FSInitializeFileSystemOperation _initCacheFileSystemOp; private ESteps _steps = ESteps.None; - internal HostPlayModeInitializationOperation(HostPlayModeImpl impl) + internal HostPlayModeInitializationOperation(HostPlayModeImpl impl, HostPlayModeParameters parameters) { _impl = impl; + _parameters = parameters; } internal override void InternalOnStart() { - _steps = ESteps.CheckAppFootPrint; + _steps = ESteps.CreateFileSystem; } internal override void InternalOnUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.CheckAppFootPrint) + if (_steps == ESteps.CreateFileSystem) { - var appFootPrint = new AppFootPrint(_impl.Persistent); - appFootPrint.Load(_impl.PackageName); - - // 如果水印发生变化,则说明覆盖安装后首次打开游戏 - if (appFootPrint.IsDirty()) + if (_parameters.BuildinFileSystemParameters == null) { - _impl.Persistent.DeleteSandboxManifestFilesFolder(); - appFootPrint.Coverage(_impl.PackageName); - YooLogger.Log("Delete manifest files when application foot print dirty !"); + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Buildin file system parameters is null"; + return; } - _steps = ESteps.QueryCachePackageVersion; + + if (_parameters.CacheFileSystemParameters == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Cache file system parameters is null"; + return; + } + + if (_parameters.DeliveryFileSystemParameters != null) + { + _impl.DeliveryFileSystem = PlayModeHelper.CreateFileSystem(_impl.PackageName, _parameters.DeliveryFileSystemParameters); + if (_impl.DeliveryFileSystem == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Failed to create delivery file system"; + return; + } + } + + _impl.BuildinFileSystem = PlayModeHelper.CreateFileSystem(_impl.PackageName, _parameters.BuildinFileSystemParameters); + if (_impl.BuildinFileSystem == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Failed to create buildin file system"; + return; + } + + _impl.CacheFileSystem = PlayModeHelper.CreateFileSystem(_impl.PackageName, _parameters.CacheFileSystemParameters); + if (_impl.CacheFileSystem == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Failed to create cache file system"; + return; + } + + _steps = ESteps.InitBuildinFileSystem; } - if (_steps == ESteps.QueryCachePackageVersion) + if (_steps == ESteps.InitBuildinFileSystem) { - if (_queryCachePackageVersionOp == null) - { - _queryCachePackageVersionOp = new QueryCachePackageVersionOperation(_impl.Persistent); - OperationSystem.StartOperation(_impl.PackageName, _queryCachePackageVersionOp); - } + if (_initBuildinFileSystemOp == null) + _initBuildinFileSystemOp = _impl.BuildinFileSystem.InitializeFileSystemAsync(); - if (_queryCachePackageVersionOp.IsDone == false) + Progress = _initBuildinFileSystemOp.Progress; + if (_initBuildinFileSystemOp.IsDone == false) return; - if (_queryCachePackageVersionOp.Status == EOperationStatus.Succeed) + if (_initBuildinFileSystemOp.Status == EOperationStatus.Succeed) { - _steps = ESteps.TryLoadCacheManifest; - } - else - { - _steps = ESteps.QueryBuildinPackageVersion; - } - } - - if (_steps == ESteps.TryLoadCacheManifest) - { - if (_loadCacheManifestOp == null) - { - _loadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _queryCachePackageVersionOp.PackageVersion); - OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp); - } - - if (_loadCacheManifestOp.IsDone == false) - return; - - if (_loadCacheManifestOp.Status == EOperationStatus.Succeed) - { - PackageVersion = _loadCacheManifestOp.Manifest.PackageVersion; - _impl.ActiveManifest = _loadCacheManifestOp.Manifest; - _steps = ESteps.PackageCaching; - } - else - { - _steps = ESteps.QueryBuildinPackageVersion; - } - } - - if (_steps == ESteps.QueryBuildinPackageVersion) - { - if (_queryBuildinPackageVersionOp == null) - { - _queryBuildinPackageVersionOp = new QueryBuildinPackageVersionOperation(_impl.Persistent); - OperationSystem.StartOperation(_impl.PackageName, _queryBuildinPackageVersionOp); - } - - if (_queryBuildinPackageVersionOp.IsDone == false) - return; - - if (_queryBuildinPackageVersionOp.Status == EOperationStatus.Succeed) - { - _steps = ESteps.UnpackBuildinManifest; - } - else - { - // 注意:为了兼容MOD模式,初始化动态新增的包裹的时候,如果内置清单不存在也不需要报错! - _steps = ESteps.PackageCaching; - string error = _queryBuildinPackageVersionOp.Error; - YooLogger.Log($"Failed to load buildin package version file : {error}"); - } - } - - if (_steps == ESteps.UnpackBuildinManifest) - { - if (_unpackBuildinManifestOp == null) - { - _unpackBuildinManifestOp = new UnpackBuildinManifestOperation(_impl.Persistent, _queryBuildinPackageVersionOp.PackageVersion); - OperationSystem.StartOperation(_impl.PackageName, _unpackBuildinManifestOp); - } - - if (_unpackBuildinManifestOp.IsDone == false) - return; - - if (_unpackBuildinManifestOp.Status == EOperationStatus.Succeed) - { - _steps = ESteps.LoadBuildinManifest; + _steps = ESteps.InitDeliveryFileSystem; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _unpackBuildinManifestOp.Error; + Error = _initBuildinFileSystemOp.Error; } } - if (_steps == ESteps.LoadBuildinManifest) + if (_steps == ESteps.InitDeliveryFileSystem) { - if (_loadBuildinManifestOp == null) + // 注意:分发文件系统可以为空 + if (_impl.DeliveryFileSystem == null) { - _loadBuildinManifestOp = new LoadBuildinManifestOperation(_impl.Persistent, _queryBuildinPackageVersionOp.PackageVersion); - OperationSystem.StartOperation(_impl.PackageName, _loadBuildinManifestOp); + _steps = ESteps.InitCacheFileSystem; + return; } - Progress = _loadBuildinManifestOp.Progress; - if (_loadBuildinManifestOp.IsDone == false) + Progress = _initDeliveryFileSystemOp.Progress; + if (_initDeliveryFileSystemOp == null) + _initDeliveryFileSystemOp = _impl.DeliveryFileSystem.InitializeFileSystemAsync(); + + if (_initDeliveryFileSystemOp.IsDone == false) return; - if (_loadBuildinManifestOp.Status == EOperationStatus.Succeed) + if (_initDeliveryFileSystemOp.Status == EOperationStatus.Succeed) { - PackageVersion = _loadBuildinManifestOp.Manifest.PackageVersion; - _impl.ActiveManifest = _loadBuildinManifestOp.Manifest; - _impl.FlushManifestVersionFile(); //注意:解压内置清单并加载成功后保存该清单版本。 - _steps = ESteps.PackageCaching; + _steps = ESteps.InitCacheFileSystem; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _loadBuildinManifestOp.Error; + Error = _initDeliveryFileSystemOp.Error; } } - if (_steps == ESteps.PackageCaching) + if (_steps == ESteps.InitCacheFileSystem) { - if (_cachingOperation == null) - { - _cachingOperation = new PackageCachingOperation(_impl.Persistent, _impl.Cache); - OperationSystem.StartOperation(_impl.PackageName, _cachingOperation); - } + if (_initCacheFileSystemOp == null) + _initCacheFileSystemOp = _impl.CacheFileSystem.InitializeFileSystemAsync(); - Progress = _cachingOperation.Progress; - if (_cachingOperation.IsDone) + Progress = _initCacheFileSystemOp.Progress; + if (_initCacheFileSystemOp.IsDone == false) + return; + + if (_initCacheFileSystemOp.Status == EOperationStatus.Succeed) { _steps = ESteps.Done; Status = EOperationStatus.Succeed; } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _initCacheFileSystemOp.Error; + } } } } /// - /// WebGL运行模式的初始化操作 + /// WebGL运行模式 /// internal sealed class WebPlayModeInitializationOperation : InitializationOperation { private enum ESteps { None, - QueryWebPackageVersion, - LoadWebManifest, + CreateFileSystem, + InitWebFileSystem, Done, } private readonly WebPlayModeImpl _impl; - private QueryBuildinPackageVersionOperation _queryWebPackageVersionOp; - private LoadBuildinManifestOperation _loadWebManifestOp; + private readonly WebPlayModeParameters _parameters; + private FSInitializeFileSystemOperation _initWebFileSystemOp; private ESteps _steps = ESteps.None; - internal WebPlayModeInitializationOperation(WebPlayModeImpl impl) + internal WebPlayModeInitializationOperation(WebPlayModeImpl impl, WebPlayModeParameters parameters) { _impl = impl; + _parameters = parameters; } internal override void InternalOnStart() { - _steps = ESteps.QueryWebPackageVersion; + _steps = ESteps.CreateFileSystem; } internal override void InternalOnUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.QueryWebPackageVersion) + if (_steps == ESteps.CreateFileSystem) { - if (_queryWebPackageVersionOp == null) + if (_parameters.WebFileSystemParameters == null) { - _queryWebPackageVersionOp = new QueryBuildinPackageVersionOperation(_impl.Persistent); - OperationSystem.StartOperation(_impl.PackageName, _queryWebPackageVersionOp); - } - - if (_queryWebPackageVersionOp.IsDone == false) - return; - - if (_queryWebPackageVersionOp.Status == EOperationStatus.Succeed) - { - _steps = ESteps.LoadWebManifest; - } - else - { - // 注意:WebGL平台可能因为网络的原因会导致请求失败。如果内置清单不存在或者超时也不需要报错! _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - string error = _queryWebPackageVersionOp.Error; - YooLogger.Log($"Failed to load web package version file : {error}"); + Status = EOperationStatus.Failed; + Error = "Web file system parameters is null"; + return; } + + _impl.WebFileSystem = PlayModeHelper.CreateFileSystem(_impl.PackageName, _parameters.WebFileSystemParameters); + if (_impl.WebFileSystem == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Failed to create web file system"; + return; + } + + _steps = ESteps.InitWebFileSystem; } - if (_steps == ESteps.LoadWebManifest) + if (_steps == ESteps.InitWebFileSystem) { - if (_loadWebManifestOp == null) - { - _loadWebManifestOp = new LoadBuildinManifestOperation(_impl.Persistent, _queryWebPackageVersionOp.PackageVersion); - OperationSystem.StartOperation(_impl.PackageName, _loadWebManifestOp); - } + if (_initWebFileSystemOp == null) + _initWebFileSystemOp = _impl.WebFileSystem.InitializeFileSystemAsync(); - Progress = _loadWebManifestOp.Progress; - if (_loadWebManifestOp.IsDone == false) + Progress = _initWebFileSystemOp.Progress; + if (_initWebFileSystemOp.IsDone == false) return; - if (_loadWebManifestOp.Status == EOperationStatus.Succeed) + if (_initWebFileSystemOp.Status == EOperationStatus.Succeed) { - PackageVersion = _loadWebManifestOp.Manifest.PackageVersion; - _impl.ActiveManifest = _loadWebManifestOp.Manifest; _steps = ESteps.Done; Status = EOperationStatus.Succeed; } @@ -440,66 +441,9 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _loadWebManifestOp.Error; + Error = _initWebFileSystemOp.Error; } } } } - - /// - /// 应用程序水印 - /// - internal class AppFootPrint - { - private PersistentManager _persistent; - private string _footPrint; - - public AppFootPrint(PersistentManager persistent) - { - _persistent = persistent; - } - - /// - /// 读取应用程序水印 - /// - public void Load(string packageName) - { - string footPrintFilePath = _persistent.SandboxAppFootPrintFilePath; - if (File.Exists(footPrintFilePath)) - { - _footPrint = FileUtility.ReadAllText(footPrintFilePath); - } - else - { - Coverage(packageName); - } - } - - /// - /// 检测水印是否发生变化 - /// - public bool IsDirty() - { -#if UNITY_EDITOR - return _footPrint != Application.version; -#else - return _footPrint != Application.buildGUID; -#endif - } - - /// - /// 覆盖掉水印 - /// - public void Coverage(string packageName) - { -#if UNITY_EDITOR - _footPrint = Application.version; -#else - _footPrint = Application.buildGUID; -#endif - string footPrintFilePath = _persistent.SandboxAppFootPrintFilePath; - FileUtility.WriteAllText(footPrintFilePath, _footPrint); - YooLogger.Log($"Save application foot print : {_footPrint}"); - } - } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DeserializeManifestOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DeserializeManifestOperation.cs index 77e088b7..1793dbce 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DeserializeManifestOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DeserializeManifestOperation.cs @@ -212,9 +212,9 @@ namespace YooAsset Manifest.BundleDic1.Add(packageBundle.BundleName, packageBundle); Manifest.BundleDic2.Add(packageBundle.FileName, packageBundle); - // 注意:原始文件可能存在相同的CacheGUID - if (Manifest.BundleDic3.ContainsKey(packageBundle.CacheGUID) == false) - Manifest.BundleDic3.Add(packageBundle.CacheGUID, packageBundle); + // 注意:原始文件可能存在相同的BundleGUID + if (Manifest.BundleDic3.ContainsKey(packageBundle.BundleGUID) == false) + Manifest.BundleDic3.Add(packageBundle.BundleGUID, packageBundle); _packageBundleCount--; Progress = 1f - _packageBundleCount / _progressTotalValue; diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DownloadManifestOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DownloadManifestOperation.cs deleted file mode 100644 index d0454b19..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DownloadManifestOperation.cs +++ /dev/null @@ -1,113 +0,0 @@ - -namespace YooAsset -{ - internal class DownloadManifestOperation : AsyncOperationBase - { - private enum ESteps - { - None, - DownloadPackageHashFile, - DownloadManifestFile, - Done, - } - - private readonly PersistentManager _persistent; - private readonly IRemoteServices _remoteServices; - private readonly string _packageVersion; - private readonly int _timeout; - private UnityWebFileRequester _downloader1; - private UnityWebFileRequester _downloader2; - private ESteps _steps = ESteps.None; - private int _requestCount = 0; - - internal DownloadManifestOperation(PersistentManager persistent, IRemoteServices remoteServices, string packageVersion, int timeout) - { - _persistent = persistent; - _remoteServices = remoteServices; - _packageVersion = packageVersion; - _timeout = timeout; - } - internal override void InternalOnStart() - { - _requestCount = RequestHelper.GetRequestFailedCount(_persistent.PackageName, nameof(DownloadManifestOperation)); - _steps = ESteps.DownloadPackageHashFile; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.DownloadPackageHashFile) - { - if (_downloader1 == null) - { - string savePath = _persistent.GetSandboxPackageHashFilePath(_packageVersion); - string fileName = YooAssetSettingsData.GetPackageHashFileName(_persistent.PackageName, _packageVersion); - string webURL = GetDownloadRequestURL(fileName); - YooLogger.Log($"Beginning to download package hash file : {webURL}"); - _downloader1 = new UnityWebFileRequester(); - _downloader1.SendRequest(webURL, savePath, _timeout); - } - - _downloader1.CheckTimeout(); - if (_downloader1.IsDone() == false) - return; - - if (_downloader1.HasError()) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloader1.GetError(); - RequestHelper.RecordRequestFailed(_persistent.PackageName, nameof(DownloadManifestOperation)); - } - else - { - _steps = ESteps.DownloadManifestFile; - } - - _downloader1.Dispose(); - } - - if (_steps == ESteps.DownloadManifestFile) - { - if (_downloader2 == null) - { - string savePath = _persistent.GetSandboxPackageManifestFilePath(_packageVersion); - string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_persistent.PackageName, _packageVersion); - string webURL = GetDownloadRequestURL(fileName); - YooLogger.Log($"Beginning to download package manifest file : {webURL}"); - _downloader2 = new UnityWebFileRequester(); - _downloader2.SendRequest(webURL, savePath, _timeout); - } - - _downloader2.CheckTimeout(); - if (_downloader2.IsDone() == false) - return; - - if (_downloader2.HasError()) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloader2.GetError(); - RequestHelper.RecordRequestFailed(_persistent.PackageName, nameof(DownloadManifestOperation)); - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - - _downloader2.Dispose(); - } - } - - private string GetDownloadRequestURL(string fileName) - { - // 轮流返回请求地址 - if (_requestCount % 2 == 0) - return _remoteServices.GetRemoteMainURL(fileName); - else - return _remoteServices.GetRemoteFallbackURL(fileName); - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DownloadManifestOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DownloadManifestOperation.cs.meta deleted file mode 100644 index adeccf87..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/DownloadManifestOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fccaa9437207a174d858ce44f14f5a03 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadBuildinManifestOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadBuildinManifestOperation.cs deleted file mode 100644 index 98d1c22c..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadBuildinManifestOperation.cs +++ /dev/null @@ -1,91 +0,0 @@ - -namespace YooAsset -{ - internal class LoadBuildinManifestOperation : AsyncOperationBase - { - private enum ESteps - { - None, - LoadBuildinManifest, - CheckDeserializeManifest, - Done, - } - - private readonly PersistentManager _persistent; - private readonly string _buildinPackageVersion; - private UnityWebDataRequester _downloader; - private DeserializeManifestOperation _deserializer; - private ESteps _steps = ESteps.None; - - /// - /// 加载的清单实例 - /// - public PackageManifest Manifest { private set; get; } - - - public LoadBuildinManifestOperation(PersistentManager persistent, string buildinPackageVersion) - { - _persistent = persistent; - _buildinPackageVersion = buildinPackageVersion; - } - internal override void InternalOnStart() - { - _steps = ESteps.LoadBuildinManifest; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.LoadBuildinManifest) - { - if (_downloader == null) - { - string filePath = _persistent.GetBuildinPackageManifestFilePath(_buildinPackageVersion); - string url = PersistentHelper.ConvertToWWWPath(filePath); - _downloader = new UnityWebDataRequester(); - _downloader.SendRequest(url); - } - - if (_downloader.IsDone() == false) - return; - - if (_downloader.HasError()) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloader.GetError(); - } - else - { - byte[] bytesData = _downloader.GetData(); - _deserializer = new DeserializeManifestOperation(bytesData); - OperationSystem.StartOperation(_persistent.PackageName, _deserializer); - _steps = ESteps.CheckDeserializeManifest; - } - - _downloader.Dispose(); - } - - if (_steps == ESteps.CheckDeserializeManifest) - { - Progress = _deserializer.Progress; - if (_deserializer.IsDone == false) - return; - - if (_deserializer.Status == EOperationStatus.Succeed) - { - Manifest = _deserializer.Manifest; - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _deserializer.Error; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadBuildinManifestOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadBuildinManifestOperation.cs.meta deleted file mode 100644 index 11f55b2b..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadBuildinManifestOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f3a2fe7d8d4747d43b3ac48097341e36 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadCacheManifestOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadCacheManifestOperation.cs deleted file mode 100644 index 9ff63e11..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadCacheManifestOperation.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System.IO; - -namespace YooAsset -{ - internal class LoadCacheManifestOperation : AsyncOperationBase - { - private enum ESteps - { - None, - QueryCachePackageHash, - VerifyFileHash, - LoadCacheManifest, - CheckDeserializeManifest, - Done, - } - - private readonly PersistentManager _persistent; - private readonly string _packageVersion; - private QueryCachePackageHashOperation _queryCachePackageHashOp; - private DeserializeManifestOperation _deserializer; - private string _manifestFilePath; - private ESteps _steps = ESteps.None; - - /// - /// 加载的清单实例 - /// - public PackageManifest Manifest { private set; get; } - - - public LoadCacheManifestOperation(PersistentManager persistent, string packageVersion) - { - _persistent = persistent; - _packageVersion = packageVersion; - } - internal override void InternalOnStart() - { - _steps = ESteps.QueryCachePackageHash; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.QueryCachePackageHash) - { - if (_queryCachePackageHashOp == null) - { - _queryCachePackageHashOp = new QueryCachePackageHashOperation(_persistent, _packageVersion); - OperationSystem.StartOperation(_persistent.PackageName, _queryCachePackageHashOp); - } - - if (_queryCachePackageHashOp.IsDone == false) - return; - - if (_queryCachePackageHashOp.Status == EOperationStatus.Succeed) - { - _steps = ESteps.VerifyFileHash; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _queryCachePackageHashOp.Error; - ClearCacheFile(); - } - } - - if (_steps == ESteps.VerifyFileHash) - { - _manifestFilePath = _persistent.GetSandboxPackageManifestFilePath(_packageVersion); - if (File.Exists(_manifestFilePath) == false) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Not found cache manifest file : {_manifestFilePath}"; - ClearCacheFile(); - return; - } - - string fileHash = HashUtility.FileMD5Safely(_manifestFilePath); - if (fileHash != _queryCachePackageHashOp.PackageHash) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Failed to verify cache manifest file hash !"; - ClearCacheFile(); - } - else - { - _steps = ESteps.LoadCacheManifest; - } - } - - if (_steps == ESteps.LoadCacheManifest) - { - byte[] bytesData = File.ReadAllBytes(_manifestFilePath); - _deserializer = new DeserializeManifestOperation(bytesData); - OperationSystem.StartOperation(_persistent.PackageName, _deserializer); - _steps = ESteps.CheckDeserializeManifest; - } - - if (_steps == ESteps.CheckDeserializeManifest) - { - Progress = _deserializer.Progress; - if (_deserializer.IsDone == false) - return; - - if (_deserializer.Status == EOperationStatus.Succeed) - { - Manifest = _deserializer.Manifest; - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _deserializer.Error; - ClearCacheFile(); - } - } - } - - private void ClearCacheFile() - { - // 注意:如果加载沙盒内的清单报错,为了避免流程被卡住,主动把损坏的文件删除。 - if (File.Exists(_manifestFilePath)) - { - YooLogger.Warning($"Failed to load cache manifest file : {Error}"); - YooLogger.Warning($"Invalid cache manifest file have been removed : {_manifestFilePath}"); - File.Delete(_manifestFilePath); - } - - string hashFilePath = _persistent.GetSandboxPackageHashFilePath(_packageVersion); - if (File.Exists(hashFilePath)) - { - File.Delete(hashFilePath); - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadCacheManifestOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadCacheManifestOperation.cs.meta deleted file mode 100644 index 6b4377e2..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadCacheManifestOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5067db2d5b2aa1240aef2f9a952a2e0c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadEditorManifestOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadEditorManifestOperation.cs.meta deleted file mode 100644 index a306e38e..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadEditorManifestOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 246df4d20b431c648a0821231a805e6b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadRemoteManifestOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadRemoteManifestOperation.cs deleted file mode 100644 index 7cd168d6..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadRemoteManifestOperation.cs +++ /dev/null @@ -1,151 +0,0 @@ - -namespace YooAsset -{ - internal class LoadRemoteManifestOperation : AsyncOperationBase - { - private enum ESteps - { - None, - DownloadPackageHashFile, - DownloadManifestFile, - VerifyFileHash, - CheckDeserializeManifest, - Done, - } - - private readonly IRemoteServices _remoteServices; - private readonly string _packageName; - private readonly string _packageVersion; - private readonly int _timeout; - private QueryRemotePackageHashOperation _queryRemotePackageHashOp; - private UnityWebDataRequester _downloader; - private DeserializeManifestOperation _deserializer; - private byte[] _fileData; - private ESteps _steps = ESteps.None; - private int _requestCount = 0; - - /// - /// 加载的清单实例 - /// - public PackageManifest Manifest { private set; get; } - - - internal LoadRemoteManifestOperation(IRemoteServices remoteServices, string packageName, string packageVersion, int timeout) - { - _remoteServices = remoteServices; - _packageName = packageName; - _packageVersion = packageVersion; - _timeout = timeout; - } - internal override void InternalOnStart() - { - _requestCount = RequestHelper.GetRequestFailedCount(_packageName, nameof(LoadRemoteManifestOperation)); - _steps = ESteps.DownloadPackageHashFile; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.DownloadPackageHashFile) - { - if (_queryRemotePackageHashOp == null) - { - _queryRemotePackageHashOp = new QueryRemotePackageHashOperation(_remoteServices, _packageName, _packageVersion, _timeout); - OperationSystem.StartOperation(_packageName, _queryRemotePackageHashOp); - } - - if (_queryRemotePackageHashOp.IsDone == false) - return; - - if (_queryRemotePackageHashOp.Status == EOperationStatus.Succeed) - { - _steps = ESteps.DownloadManifestFile; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _queryRemotePackageHashOp.Error; - } - } - - if (_steps == ESteps.DownloadManifestFile) - { - if (_downloader == null) - { - string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_packageName, _packageVersion); - string webURL = GetDownloadRequestURL(fileName); - YooLogger.Log($"Beginning to download manifest file : {webURL}"); - _downloader = new UnityWebDataRequester(); - _downloader.SendRequest(webURL, _timeout); - } - - _downloader.CheckTimeout(); - if (_downloader.IsDone() == false) - return; - - if (_downloader.HasError()) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloader.GetError(); - RequestHelper.RecordRequestFailed(_packageName, nameof(LoadRemoteManifestOperation)); - } - else - { - _fileData = _downloader.GetData(); - _steps = ESteps.VerifyFileHash; - } - - _downloader.Dispose(); - } - - if (_steps == ESteps.VerifyFileHash) - { - string fileHash = HashUtility.BytesMD5(_fileData); - if (fileHash != _queryRemotePackageHashOp.PackageHash) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "Failed to verify remote manifest file hash !"; - } - else - { - _deserializer = new DeserializeManifestOperation(_fileData); - OperationSystem.StartOperation(_packageName, _deserializer); - _steps = ESteps.CheckDeserializeManifest; - } - } - - if (_steps == ESteps.CheckDeserializeManifest) - { - Progress = _deserializer.Progress; - if (_deserializer.IsDone == false) - return; - - if (_deserializer.Status == EOperationStatus.Succeed) - { - Manifest = _deserializer.Manifest; - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _deserializer.Error; - } - } - } - - private string GetDownloadRequestURL(string fileName) - { - // 轮流返回请求地址 - if (_requestCount % 2 == 0) - return _remoteServices.GetRemoteMainURL(fileName); - else - return _remoteServices.GetRemoteFallbackURL(fileName); - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadRemoteManifestOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadRemoteManifestOperation.cs.meta deleted file mode 100644 index 8bd94885..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadRemoteManifestOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 486ce3e7ad16f2948a36d49ecabd76b2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryBuildinPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryBuildinPackageVersionOperation.cs.meta deleted file mode 100644 index 6430963d..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryBuildinPackageVersionOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bdc251ea99d82e54199dfba540f2814d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageHashOperation.cs.meta deleted file mode 100644 index 14ff2ea3..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageHashOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 60db6a6586340664ab7e9f85cec0eef4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageVersionOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageVersionOperation.cs deleted file mode 100644 index 25849400..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageVersionOperation.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System.IO; - -namespace YooAsset -{ - internal class QueryCachePackageVersionOperation : AsyncOperationBase - { - private enum ESteps - { - None, - LoadCachePackageVersionFile, - Done, - } - - private readonly PersistentManager _persistent; - private ESteps _steps = ESteps.None; - - /// - /// 包裹版本 - /// - public string PackageVersion { private set; get; } - - - public QueryCachePackageVersionOperation(PersistentManager persistent) - { - _persistent = persistent; - } - internal override void InternalOnStart() - { - _steps = ESteps.LoadCachePackageVersionFile; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.LoadCachePackageVersionFile) - { - string filePath = _persistent.GetSandboxPackageVersionFilePath(); - if (File.Exists(filePath) == false) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Cache package version file not found : {filePath}"; - return; - } - - PackageVersion = FileUtility.ReadAllText(filePath); - if (string.IsNullOrEmpty(PackageVersion)) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Cache package version file content is empty !"; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageVersionOperation.cs.meta deleted file mode 100644 index 0465bbc3..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageVersionOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 29a2cbdd051ba1247a24693d56cdc2c3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryRemotePackageHashOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryRemotePackageHashOperation.cs deleted file mode 100644 index 7ce2b8e7..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryRemotePackageHashOperation.cs +++ /dev/null @@ -1,100 +0,0 @@ - -namespace YooAsset -{ - internal class QueryRemotePackageHashOperation : AsyncOperationBase - { - private enum ESteps - { - None, - DownloadPackageHash, - Done, - } - - private readonly IRemoteServices _remoteServices; - private readonly string _packageName; - private readonly string _packageVersion; - private readonly int _timeout; - private UnityWebDataRequester _downloader; - private ESteps _steps = ESteps.None; - private int _requestCount = 0; - - /// - /// 包裹哈希值 - /// - public string PackageHash { private set; get; } - - - public QueryRemotePackageHashOperation(IRemoteServices remoteServices, string packageName, string packageVersion, int timeout) - { - _remoteServices = remoteServices; - _packageName = packageName; - _packageVersion = packageVersion; - _timeout = timeout; - } - internal override void InternalOnStart() - { - _requestCount = RequestHelper.GetRequestFailedCount(_packageName, nameof(QueryRemotePackageHashOperation)); - _steps = ESteps.DownloadPackageHash; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.DownloadPackageHash) - { - if (_downloader == null) - { - string fileName = YooAssetSettingsData.GetPackageHashFileName(_packageName, _packageVersion); - string webURL = GetPackageHashRequestURL(fileName); - YooLogger.Log($"Beginning to request package hash : {webURL}"); - _downloader = new UnityWebDataRequester(); - _downloader.SendRequest(webURL, _timeout); - } - - Progress = _downloader.Progress(); - _downloader.CheckTimeout(); - if (_downloader.IsDone() == false) - return; - - if (_downloader.HasError()) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloader.GetError(); - RequestHelper.RecordRequestFailed(_packageName, nameof(QueryRemotePackageHashOperation)); - } - else - { - PackageHash = _downloader.GetText(); - if (string.IsNullOrEmpty(PackageHash)) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Remote package hash is empty : {_downloader.URL}"; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - } - - _downloader.Dispose(); - } - } - - private string GetPackageHashRequestURL(string fileName) - { - string url; - - // 轮流返回请求地址 - if (_requestCount % 2 == 0) - url = _remoteServices.GetRemoteMainURL(fileName); - else - url = _remoteServices.GetRemoteFallbackURL(fileName); - - return url; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryRemotePackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryRemotePackageHashOperation.cs.meta deleted file mode 100644 index c2e3a61b..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryRemotePackageHashOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ef77260f58172dd42ad10cfb862b78ec -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryRemotePackageVersionOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryRemotePackageVersionOperation.cs deleted file mode 100644 index 47c0faff..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryRemotePackageVersionOperation.cs +++ /dev/null @@ -1,104 +0,0 @@ - -namespace YooAsset -{ - internal class QueryRemotePackageVersionOperation : AsyncOperationBase - { - private enum ESteps - { - None, - DownloadPackageVersion, - Done, - } - - private readonly IRemoteServices _remoteServices; - private readonly string _packageName; - private readonly bool _appendTimeTicks; - private readonly int _timeout; - private UnityWebDataRequester _downloader; - private ESteps _steps = ESteps.None; - private int _requestCount = 0; - - /// - /// 包裹版本 - /// - public string PackageVersion { private set; get; } - - - public QueryRemotePackageVersionOperation(IRemoteServices remoteServices, string packageName, bool appendTimeTicks, int timeout) - { - _remoteServices = remoteServices; - _packageName = packageName; - _appendTimeTicks = appendTimeTicks; - _timeout = timeout; - } - internal override void InternalOnStart() - { - _requestCount = RequestHelper.GetRequestFailedCount(_packageName, nameof(QueryRemotePackageVersionOperation)); - _steps = ESteps.DownloadPackageVersion; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.DownloadPackageVersion) - { - if (_downloader == null) - { - string fileName = YooAssetSettingsData.GetPackageVersionFileName(_packageName); - string webURL = GetPackageVersionRequestURL(fileName); - YooLogger.Log($"Beginning to request package version : {webURL}"); - _downloader = new UnityWebDataRequester(); - _downloader.SendRequest(webURL, _timeout); - } - - Progress = _downloader.Progress(); - _downloader.CheckTimeout(); - if (_downloader.IsDone() == false) - return; - - if (_downloader.HasError()) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloader.GetError(); - RequestHelper.RecordRequestFailed(_packageName, nameof(QueryRemotePackageVersionOperation)); - } - else - { - PackageVersion = _downloader.GetText(); - if (string.IsNullOrEmpty(PackageVersion)) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Remote package version is empty : {_downloader.URL}"; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - } - - _downloader.Dispose(); - } - } - - private string GetPackageVersionRequestURL(string fileName) - { - string url; - - // 轮流返回请求地址 - if (_requestCount % 2 == 0) - url = _remoteServices.GetRemoteMainURL(fileName); - else - url = _remoteServices.GetRemoteFallbackURL(fileName); - - // 在URL末尾添加时间戳 - if (_appendTimeTicks) - return $"{url}?{System.DateTime.UtcNow.Ticks}"; - else - return url; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryRemotePackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryRemotePackageVersionOperation.cs.meta deleted file mode 100644 index 608c0d1b..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryRemotePackageVersionOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1d702a1a39789a34da99cbb854708b82 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/UnpackBuildinManifestOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/UnpackBuildinManifestOperation.cs deleted file mode 100644 index 477c2b2f..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/UnpackBuildinManifestOperation.cs +++ /dev/null @@ -1,92 +0,0 @@ - -namespace YooAsset -{ - internal class UnpackBuildinManifestOperation : AsyncOperationBase - { - private enum ESteps - { - None, - UnpackManifestHashFile, - UnpackManifestFile, - Done, - } - - private readonly PersistentManager _persistent; - private readonly string _buildinPackageVersion; - private UnityWebFileRequester _downloader1; - private UnityWebFileRequester _downloader2; - private ESteps _steps = ESteps.None; - - public UnpackBuildinManifestOperation(PersistentManager persistent, string buildinPackageVersion) - { - _persistent = persistent; - _buildinPackageVersion = buildinPackageVersion; - } - internal override void InternalOnStart() - { - _steps = ESteps.UnpackManifestHashFile; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.UnpackManifestHashFile) - { - if (_downloader1 == null) - { - string savePath = _persistent.GetSandboxPackageHashFilePath(_buildinPackageVersion); - string filePath = _persistent.GetBuildinPackageHashFilePath(_buildinPackageVersion); - string url = PersistentHelper.ConvertToWWWPath(filePath); - _downloader1 = new UnityWebFileRequester(); - _downloader1.SendRequest(url, savePath); - } - - if (_downloader1.IsDone() == false) - return; - - if (_downloader1.HasError()) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloader1.GetError(); - } - else - { - _steps = ESteps.UnpackManifestFile; - } - - _downloader1.Dispose(); - } - - if (_steps == ESteps.UnpackManifestFile) - { - if (_downloader2 == null) - { - string savePath = _persistent.GetSandboxPackageManifestFilePath(_buildinPackageVersion); - string filePath = _persistent.GetBuildinPackageManifestFilePath(_buildinPackageVersion); - string url = PersistentHelper.ConvertToWWWPath(filePath); - _downloader2 = new UnityWebFileRequester(); - _downloader2.SendRequest(url, savePath); - } - - if (_downloader2.IsDone() == false) - return; - - if (_downloader2.HasError()) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloader2.GetError(); - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - - _downloader2.Dispose(); - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/UnpackBuildinManifestOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/UnpackBuildinManifestOperation.cs.meta deleted file mode 100644 index cae38538..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/UnpackBuildinManifestOperation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3a7685e67b0e948439ffba34513b78c0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs index c2286328..023c1c12 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs @@ -51,11 +51,11 @@ namespace YooAsset public abstract ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60); } - internal class EditorPlayModePreDownloadContentOperation : PreDownloadContentOperation + internal class EditorSimulateModePreDownloadContentOperation : PreDownloadContentOperation { private readonly EditorSimulateModeImpl _impl; - public EditorPlayModePreDownloadContentOperation(EditorSimulateModeImpl impl) + public EditorSimulateModePreDownloadContentOperation(EditorSimulateModeImpl impl) { _impl = impl; } @@ -69,23 +69,23 @@ namespace YooAsset public override ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } } internal class OfflinePlayModePreDownloadContentOperation : PreDownloadContentOperation @@ -106,23 +106,23 @@ namespace YooAsset public override ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } } internal class HostPlayModePreDownloadContentOperation : PreDownloadContentOperation @@ -130,19 +130,16 @@ namespace YooAsset private enum ESteps { None, + CheckParams, CheckActiveManifest, - TryLoadCacheManifest, - DownloadManifest, - LoadCacheManifest, + LoadPackageManifest, Done, } private readonly HostPlayModeImpl _impl; private readonly string _packageVersion; private readonly int _timeout; - private LoadCacheManifestOperation _tryLoadCacheManifestOp; - private LoadCacheManifestOperation _loadCacheManifestOp; - private DownloadManifestOperation _downloadManifestOp; + private FSLoadPackageManifestOperation _loadPackageManifestOp; private PackageManifest _manifest; private ESteps _steps = ESteps.None; @@ -155,13 +152,26 @@ namespace YooAsset } internal override void InternalOnStart() { - _steps = ESteps.CheckActiveManifest; + _steps = ESteps.CheckParams; } internal override void InternalOnUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; + if (_steps == ESteps.CheckParams) + { + if (string.IsNullOrEmpty(_packageVersion)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Package version is null or empty."; + return; + } + + _steps = ESteps.CheckActiveManifest; + } + if (_steps == ESteps.CheckActiveManifest) { // 检测当前激活的清单对象 @@ -175,69 +185,22 @@ namespace YooAsset return; } } - _steps = ESteps.TryLoadCacheManifest; + _steps = ESteps.LoadPackageManifest; } - if (_steps == ESteps.TryLoadCacheManifest) + if (_steps == ESteps.LoadPackageManifest) { - if (_tryLoadCacheManifestOp == null) + if (_loadPackageManifestOp == null) { - _tryLoadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _packageVersion); - OperationSystem.StartOperation(_impl.PackageName, _tryLoadCacheManifestOp); + _loadPackageManifestOp = _impl.CacheFileSystem.LoadPackageManifestAsync(_packageVersion, _timeout); } - if (_tryLoadCacheManifestOp.IsDone == false) + if (_loadPackageManifestOp.IsDone == false) return; - if (_tryLoadCacheManifestOp.Status == EOperationStatus.Succeed) + if (_loadPackageManifestOp.Status == EOperationStatus.Succeed) { - _manifest = _tryLoadCacheManifestOp.Manifest; - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.DownloadManifest; - } - } - - if (_steps == ESteps.DownloadManifest) - { - if (_downloadManifestOp == null) - { - _downloadManifestOp = new DownloadManifestOperation(_impl.Persistent, _impl.RemoteServices, _packageVersion, _timeout); - OperationSystem.StartOperation(_impl.PackageName, _downloadManifestOp); - } - - if (_downloadManifestOp.IsDone == false) - return; - - if (_downloadManifestOp.Status == EOperationStatus.Succeed) - { - _steps = ESteps.LoadCacheManifest; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloadManifestOp.Error; - } - } - - if (_steps == ESteps.LoadCacheManifest) - { - if (_loadCacheManifestOp == null) - { - _loadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _packageVersion); - OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp); - } - - if (_loadCacheManifestOp.IsDone == false) - return; - - if (_loadCacheManifestOp.Status == EOperationStatus.Succeed) - { - _manifest = _loadCacheManifestOp.Manifest; + _manifest = _loadPackageManifestOp.Result; _steps = ESteps.Done; Status = EOperationStatus.Succeed; } @@ -245,7 +208,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _loadCacheManifestOp.Error; + Error = _loadPackageManifestOp.Error; } } } @@ -255,11 +218,11 @@ namespace YooAsset if (Status != EOperationStatus.Succeed) { YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } - List downloadList = _impl.GetDownloadListByAll(_manifest); - var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByAll(_manifest, _impl.BuildinFileSystem, _impl.DeliveryFileSystem, _impl.CacheFileSystem); + var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) @@ -267,11 +230,11 @@ namespace YooAsset if (Status != EOperationStatus.Succeed) { YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } - List downloadList = _impl.GetDownloadListByTags(_manifest, new string[] { tag }); - var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByTags(_manifest, new string[] { tag }, _impl.BuildinFileSystem, _impl.DeliveryFileSystem, _impl.CacheFileSystem); + var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) @@ -279,11 +242,11 @@ namespace YooAsset if (Status != EOperationStatus.Succeed) { YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } - List downloadList = _impl.GetDownloadListByTags(_manifest, tags); - var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByTags(_manifest, tags, _impl.BuildinFileSystem, _impl.DeliveryFileSystem, _impl.CacheFileSystem); + var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) @@ -291,15 +254,15 @@ namespace YooAsset if (Status != EOperationStatus.Succeed) { YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } List assetInfos = new List(); var assetInfo = _manifest.ConvertLocationToAssetInfo(location, null); assetInfos.Add(assetInfo); - List downloadList = _impl.GetDownloadListByPaths(_manifest, assetInfos.ToArray()); - var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByPaths(_manifest, assetInfos.ToArray(), _impl.BuildinFileSystem, _impl.DeliveryFileSystem, _impl.CacheFileSystem); + var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) @@ -307,7 +270,7 @@ namespace YooAsset if (Status != EOperationStatus.Succeed) { YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !"); - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } List assetInfos = new List(locations.Length); @@ -317,8 +280,8 @@ namespace YooAsset assetInfos.Add(assetInfo); } - List downloadList = _impl.GetDownloadListByPaths(_manifest, assetInfos.ToArray()); - var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByPaths(_manifest, assetInfos.ToArray(), _impl.BuildinFileSystem, _impl.DeliveryFileSystem, _impl.CacheFileSystem); + var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } } @@ -340,23 +303,23 @@ namespace YooAsset public override ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { - return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); + return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageVersionOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestPackageVersionOperation.cs similarity index 50% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageVersionOperation.cs rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestPackageVersionOperation.cs index 4ca4dfc7..4bb42e01 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestPackageVersionOperation.cs @@ -1,13 +1,10 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - + namespace YooAsset { /// - /// 请求远端包裹的最新版本 + /// 查询远端包裹的最新版本 /// - public abstract class UpdatePackageVersionOperation : AsyncOperationBase + public abstract class RequestPackageVersionOperation : AsyncOperationBase { /// /// 当前最新的包裹版本 @@ -16,9 +13,9 @@ namespace YooAsset } /// - /// 编辑器下模拟模式的请求远端包裹的最新版本 + /// 编辑器下模拟运行 /// - internal sealed class EditorPlayModeUpdatePackageVersionOperation : UpdatePackageVersionOperation + internal class EditorSimulateModeRequestPackageVersionOperation : RequestPackageVersionOperation { internal override void InternalOnStart() { @@ -30,9 +27,9 @@ namespace YooAsset } /// - /// 离线模式的请求远端包裹的最新版本 + /// 离线运行模式 /// - internal sealed class OfflinePlayModeUpdatePackageVersionOperation : UpdatePackageVersionOperation + internal class OfflinePlayModeRequestPackageVersionOperation : RequestPackageVersionOperation { internal override void InternalOnStart() { @@ -44,24 +41,24 @@ namespace YooAsset } /// - /// 联机模式的请求远端包裹的最新版本 + /// 联机运行模式 /// - internal sealed class HostPlayModeUpdatePackageVersionOperation : UpdatePackageVersionOperation + internal class HostPlayModeRequestPackageVersionOperation : RequestPackageVersionOperation { private enum ESteps { None, - QueryRemotePackageVersion, + QueryPackageVersion, Done, } private readonly HostPlayModeImpl _impl; private readonly bool _appendTimeTicks; private readonly int _timeout; - private QueryRemotePackageVersionOperation _queryRemotePackageVersionOp; + private FSRequestPackageVersionOperation _queryPackageVersionOp; private ESteps _steps = ESteps.None; - internal HostPlayModeUpdatePackageVersionOperation(HostPlayModeImpl impl, bool appendTimeTicks, int timeout) + internal HostPlayModeRequestPackageVersionOperation(HostPlayModeImpl impl, bool appendTimeTicks, int timeout) { _impl = impl; _appendTimeTicks = appendTimeTicks; @@ -69,27 +66,26 @@ namespace YooAsset } internal override void InternalOnStart() { - _steps = ESteps.QueryRemotePackageVersion; + _steps = ESteps.QueryPackageVersion; } internal override void InternalOnUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.QueryRemotePackageVersion) + if (_steps == ESteps.QueryPackageVersion) { - if (_queryRemotePackageVersionOp == null) + if (_queryPackageVersionOp == null) { - _queryRemotePackageVersionOp = new QueryRemotePackageVersionOperation(_impl.RemoteServices, _impl.PackageName, _appendTimeTicks, _timeout); - OperationSystem.StartOperation(_impl.PackageName, _queryRemotePackageVersionOp); + _queryPackageVersionOp = _impl.CacheFileSystem.RequestPackageVersionAsync(_appendTimeTicks, _timeout); } - if (_queryRemotePackageVersionOp.IsDone == false) + if (_queryPackageVersionOp.IsDone == false) return; - if (_queryRemotePackageVersionOp.Status == EOperationStatus.Succeed) + if (_queryPackageVersionOp.Status == EOperationStatus.Succeed) { - PackageVersion = _queryRemotePackageVersionOp.PackageVersion; + PackageVersion = _queryPackageVersionOp.PackageVersion; _steps = ESteps.Done; Status = EOperationStatus.Succeed; } @@ -97,31 +93,31 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _queryRemotePackageVersionOp.Error; + Error = _queryPackageVersionOp.Error; } } } } /// - /// WebGL模式的请求远端包裹的最新版本 + /// WebGL运行模式 /// - internal sealed class WebPlayModeUpdatePackageVersionOperation : UpdatePackageVersionOperation + internal class WebPlayModeRequestPackageVersionOperation : RequestPackageVersionOperation { private enum ESteps { None, - QueryRemotePackageVersion, + QueryPackageVersion, Done, } private readonly WebPlayModeImpl _impl; private readonly bool _appendTimeTicks; private readonly int _timeout; - private QueryRemotePackageVersionOperation _queryRemotePackageVersionOp; + private FSRequestPackageVersionOperation _queryPackageVersionOp; private ESteps _steps = ESteps.None; - internal WebPlayModeUpdatePackageVersionOperation(WebPlayModeImpl impl, bool appendTimeTicks, int timeout) + internal WebPlayModeRequestPackageVersionOperation(WebPlayModeImpl impl, bool appendTimeTicks, int timeout) { _impl = impl; _appendTimeTicks = appendTimeTicks; @@ -129,27 +125,26 @@ namespace YooAsset } internal override void InternalOnStart() { - _steps = ESteps.QueryRemotePackageVersion; + _steps = ESteps.QueryPackageVersion; } internal override void InternalOnUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.QueryRemotePackageVersion) + if (_steps == ESteps.QueryPackageVersion) { - if (_queryRemotePackageVersionOp == null) + if (_queryPackageVersionOp == null) { - _queryRemotePackageVersionOp = new QueryRemotePackageVersionOperation(_impl.RemoteServices, _impl.PackageName, _appendTimeTicks, _timeout); - OperationSystem.StartOperation(_impl.PackageName, _queryRemotePackageVersionOp); + _queryPackageVersionOp = _impl.WebFileSystem.RequestPackageVersionAsync(_appendTimeTicks, _timeout); } - if (_queryRemotePackageVersionOp.IsDone == false) + if (_queryPackageVersionOp.IsDone == false) return; - if (_queryRemotePackageVersionOp.Status == EOperationStatus.Succeed) + if (_queryPackageVersionOp.Status == EOperationStatus.Succeed) { - PackageVersion = _queryRemotePackageVersionOp.PackageVersion; + PackageVersion = _queryPackageVersionOp.PackageVersion; _steps = ESteps.Done; Status = EOperationStatus.Succeed; } @@ -157,7 +152,7 @@ namespace YooAsset { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _queryRemotePackageVersionOp.Error; + Error = _queryPackageVersionOp.Error; } } } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestPackageVersionOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageVersionOperation.cs.meta rename to Assets/YooAsset/Runtime/ResourcePackage/Operation/RequestPackageVersionOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageManifestOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageManifestOperation.cs index 0019b211..088210e8 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/UpdatePackageManifestOperation.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections; -using System.Collections.Generic; - + namespace YooAsset { /// @@ -9,18 +6,14 @@ namespace YooAsset /// public abstract class UpdatePackageManifestOperation : AsyncOperationBase { - /// - /// 保存当前清单的版本,用于下次启动时自动加载的版本。 - /// - public virtual void SavePackageVersion() { } } /// - /// 编辑器下模拟运行的更新清单操作 + /// 编辑器下模拟运行 /// - internal sealed class EditorPlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation + internal sealed class EditorSimulateModeUpdatePackageManifestOperation : UpdatePackageManifestOperation { - public EditorPlayModeUpdatePackageManifestOperation() + public EditorSimulateModeUpdatePackageManifestOperation() { } internal override void InternalOnStart() @@ -33,7 +26,7 @@ namespace YooAsset } /// - /// 离线模式的更新清单操作 + /// 离线运行模式 /// internal sealed class OfflinePlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation { @@ -50,8 +43,7 @@ namespace YooAsset } /// - /// 联机模式的更新清单操作 - /// 注意:优先加载沙盒里缓存的清单文件,如果缓存没找到就下载远端清单文件,并保存到本地。 + /// 联机运行模式 /// internal sealed class HostPlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation { @@ -60,27 +52,21 @@ namespace YooAsset None, CheckParams, CheckActiveManifest, - TryLoadCacheManifest, - DownloadManifest, - LoadCacheManifest, + LoadPackageManifest, Done, } private readonly HostPlayModeImpl _impl; private readonly string _packageVersion; - private readonly bool _autoSaveVersion; private readonly int _timeout; - private LoadCacheManifestOperation _tryLoadCacheManifestOp; - private LoadCacheManifestOperation _loadCacheManifestOp; - private DownloadManifestOperation _downloadManifestOp; + private FSLoadPackageManifestOperation _loadPackageManifestOp; private ESteps _steps = ESteps.None; - internal HostPlayModeUpdatePackageManifestOperation(HostPlayModeImpl impl, string packageVersion, bool autoSaveVersion, int timeout) + internal HostPlayModeUpdatePackageManifestOperation(HostPlayModeImpl impl, string packageVersion, int timeout) { _impl = impl; _packageVersion = packageVersion; - _autoSaveVersion = autoSaveVersion; _timeout = timeout; } internal override void InternalOnStart() @@ -99,10 +85,11 @@ namespace YooAsset _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = "Package version is null or empty."; - return; } - - _steps = ESteps.CheckActiveManifest; + else + { + _steps = ESteps.CheckActiveManifest; + } } if (_steps == ESteps.CheckActiveManifest) @@ -115,94 +102,36 @@ namespace YooAsset } else { - _steps = ESteps.TryLoadCacheManifest; + _steps = ESteps.LoadPackageManifest; } } - if (_steps == ESteps.TryLoadCacheManifest) + if (_steps == ESteps.LoadPackageManifest) { - if (_tryLoadCacheManifestOp == null) - { - _tryLoadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _packageVersion); - OperationSystem.StartOperation(_impl.PackageName, _tryLoadCacheManifestOp); - } + if (_loadPackageManifestOp == null) + _loadPackageManifestOp = _impl.CacheFileSystem.LoadPackageManifestAsync(_packageVersion, _timeout); - if (_tryLoadCacheManifestOp.IsDone == false) + if (_loadPackageManifestOp.IsDone == false) return; - if (_tryLoadCacheManifestOp.Status == EOperationStatus.Succeed) - { - _impl.ActiveManifest = _tryLoadCacheManifestOp.Manifest; - if (_autoSaveVersion) - SavePackageVersion(); - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.DownloadManifest; - } - } - - if (_steps == ESteps.DownloadManifest) - { - if (_downloadManifestOp == null) - { - _downloadManifestOp = new DownloadManifestOperation(_impl.Persistent, _impl.RemoteServices, _packageVersion, _timeout); - OperationSystem.StartOperation(_impl.PackageName, _downloadManifestOp); - } - - if (_downloadManifestOp.IsDone == false) - return; - - if (_downloadManifestOp.Status == EOperationStatus.Succeed) - { - _steps = ESteps.LoadCacheManifest; - } - else + if (_loadPackageManifestOp.Status == EOperationStatus.Succeed) { _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _downloadManifestOp.Error; - } - } - - if (_steps == ESteps.LoadCacheManifest) - { - if (_loadCacheManifestOp == null) - { - _loadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _packageVersion); - OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp); - } - - if (_loadCacheManifestOp.IsDone == false) - return; - - if (_loadCacheManifestOp.Status == EOperationStatus.Succeed) - { - _impl.ActiveManifest = _loadCacheManifestOp.Manifest; - if (_autoSaveVersion) - SavePackageVersion(); - _steps = ESteps.Done; + _impl.ActiveManifest = _loadPackageManifestOp.Result; Status = EOperationStatus.Succeed; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _loadCacheManifestOp.Error; + Error = _loadPackageManifestOp.Error; } } } - - public override void SavePackageVersion() - { - _impl.FlushManifestVersionFile(); - } } /// - /// WebGL模式的更新清单操作 + /// WebGL运行模式 /// internal sealed class WebPlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation { @@ -218,7 +147,7 @@ namespace YooAsset private readonly WebPlayModeImpl _impl; private readonly string _packageVersion; private readonly int _timeout; - private LoadRemoteManifestOperation _loadCacheManifestOp; + private FSLoadPackageManifestOperation _loadPackageManifestOp; private ESteps _steps = ESteps.None; @@ -244,10 +173,11 @@ namespace YooAsset _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = "Package version is null or empty."; - return; } - - _steps = ESteps.CheckActiveManifest; + else + { + _steps = ESteps.CheckActiveManifest; + } } if (_steps == ESteps.CheckActiveManifest) @@ -266,26 +196,23 @@ namespace YooAsset if (_steps == ESteps.LoadRemoteManifest) { - if (_loadCacheManifestOp == null) - { - _loadCacheManifestOp = new LoadRemoteManifestOperation(_impl.RemoteServices, _impl.PackageName, _packageVersion, _timeout); - OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp); - } + if (_loadPackageManifestOp == null) + _loadPackageManifestOp = _impl.WebFileSystem.LoadPackageManifestAsync(_packageVersion, _timeout); - if (_loadCacheManifestOp.IsDone == false) + if (_loadPackageManifestOp.IsDone == false) return; - if (_loadCacheManifestOp.Status == EOperationStatus.Succeed) + if (_loadPackageManifestOp.Status == EOperationStatus.Succeed) { - _impl.ActiveManifest = _loadCacheManifestOp.Manifest; _steps = ESteps.Done; + _impl.ActiveManifest = _loadPackageManifestOp.Result; Status = EOperationStatus.Succeed; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = _loadCacheManifestOp.Error; + Error = _loadPackageManifestOp.Error; } } } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs index f390838a..8efbd0f7 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs @@ -55,12 +55,12 @@ namespace YooAsset /// /// 所属的构建管线 /// - public string Buildpipeline { private set; get; } + public string BuildPipeline { private set; get; } /// - /// 缓存GUID + /// 资源包GUID /// - public string CacheGUID + public string BundleGUID { get { return FileHash; } } @@ -104,7 +104,7 @@ namespace YooAsset public void ParseBundle(PackageManifest manifest) { PackageName = manifest.PackageName; - Buildpipeline = manifest.BuildPipeline; + BuildPipeline = manifest.BuildPipeline; _fileExtension = ManifestTools.GetRemoteBundleFileExtension(BundleName); _fileName = ManifestTools.GetRemoteBundleFileName(manifest.OutputNameStyle, BundleName, _fileExtension, FileHash); } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs index 53a52fe7..3bac3e6a 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs @@ -76,7 +76,7 @@ namespace YooAsset public Dictionary BundleDic2; /// - /// 资源包集合(提供CacheGUID获取PackageBundle) + /// 资源包集合(提供BundleGUID获取PackageBundle) /// [NonSerialized] public Dictionary BundleDic3; @@ -192,17 +192,17 @@ namespace YooAsset /// /// 尝试获取包裹的资源包 /// - public bool TryGetPackageBundleByCacheGUID(string cacheGUID, out PackageBundle result) + public bool TryGetPackageBundleByBundleGUID(string bundleGUID, out PackageBundle result) { - return BundleDic3.TryGetValue(cacheGUID, out result); + return BundleDic3.TryGetValue(bundleGUID, out result); } /// /// 是否包含资源文件 /// - public bool IsIncludeBundleFile(string cacheGUID) + public bool IsIncludeBundleFile(string bundleGUID) { - return BundleDic3.ContainsKey(cacheGUID); + return BundleDic3.ContainsKey(bundleGUID); } /// diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeImpl.cs b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeImpl.cs index 159842e3..af25a01b 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeImpl.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeImpl.cs @@ -6,14 +6,9 @@ namespace YooAsset { internal class EditorSimulateModeImpl : IPlayMode, IBundleQuery { - private PackageManifest _activeManifest; - private ResourceAssist _assist; - public readonly string PackageName; - public DownloadManager Download - { - get { return _assist.Download; } - } + public IFileSystem EditorFileSystem { set; get; } + public EditorSimulateModeImpl(string packageName) { @@ -23,75 +18,89 @@ namespace YooAsset /// /// 异步初始化 /// - public InitializationOperation InitializeAsync(ResourceAssist assist, string simulateManifestFilePath) + public InitializationOperation InitializeAsync(EditorSimulateModeParameters initParameters) { - _assist = assist; - - var operation = new EditorSimulateModeInitializationOperation(this, simulateManifestFilePath); + var operation = new EditorSimulateModeInitializationOperation(this, initParameters); OperationSystem.StartOperation(PackageName, operation); return operation; } #region IPlayMode接口 - public PackageManifest ActiveManifest - { - set - { - _activeManifest = value; - } - get - { - return _activeManifest; - } - } - public void FlushManifestVersionFile() + public PackageManifest ActiveManifest { set; get; } + + void IPlayMode.UpdatePlayMode() { + if (EditorFileSystem != null) + EditorFileSystem.OnUpdate(); } - UpdatePackageVersionOperation IPlayMode.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout) + RequestPackageVersionOperation IPlayMode.RequestPackageVersionAsync(bool appendTimeTicks, int timeout) { - var operation = new EditorPlayModeUpdatePackageVersionOperation(); + var operation = new EditorSimulateModeRequestPackageVersionOperation(); OperationSystem.StartOperation(PackageName, operation); return operation; } - UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout) + UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, int timeout) { - var operation = new EditorPlayModeUpdatePackageManifestOperation(); + var operation = new EditorSimulateModeUpdatePackageManifestOperation(); OperationSystem.StartOperation(PackageName, operation); return operation; } PreDownloadContentOperation IPlayMode.PreDownloadContentAsync(string packageVersion, int timeout) { - var operation = new EditorPlayModePreDownloadContentOperation(this); + var operation = new EditorSimulateModePreDownloadContentOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + + ClearAllBundleFilesOperation IPlayMode.ClearAllBundleFilesAsync() + { + var operation = new EditorSimulateModeClearAllBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + ClearUnusedBundleFilesOperation IPlayMode.ClearUnusedBundleFilesAsync() + { + var operation = new EditorSimulateModeClearUnusedBundleFilesOperation(this); OperationSystem.StartOperation(PackageName, operation); return operation; } ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) { - return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByAll(ActiveManifest, EditorFileSystem); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + return operation; } ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout) { - return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByTags(ActiveManifest, tags, EditorFileSystem); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + return operation; } ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) { - return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByPaths(ActiveManifest, assetInfos, EditorFileSystem); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + return operation; } - ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout) { - return ResourceUnpackerOperation.CreateEmptyUnpacker(Download, PackageName, upackingMaxNumber, failedTryAgain, timeout); + List unpcakList = PlayModeHelper.GetUnpackListByAll(ActiveManifest, EditorFileSystem); + var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); + return operation; } ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) { - return ResourceUnpackerOperation.CreateEmptyUnpacker(Download, PackageName, upackingMaxNumber, failedTryAgain, timeout); + List unpcakList = PlayModeHelper.GetUnpackListByTags(ActiveManifest, tags, EditorFileSystem); + var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); + return operation; } - ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout) { - return ResourceImporterOperation.CreateEmptyImporter(Download, PackageName, importerMaxNumber, failedTryAgain, timeout); + List importerList = PlayModeHelper.GetImporterListByFilePaths(ActiveManifest, filePaths, EditorFileSystem); + var operation = new ResourceImporterOperation(PackageName, importerList, importerMaxNumber, failedTryAgain, timeout); + return operation; } #endregion @@ -101,9 +110,14 @@ namespace YooAsset if (packageBundle == null) throw new Exception("Should never get here !"); - BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromEditor); - bundleInfo.IncludeAssetsInEditor = _activeManifest.GetBundleIncludeAssets(assetInfo.AssetPath); - return bundleInfo; + if (EditorFileSystem.Belong(packageBundle)) + { + BundleInfo bundleInfo = new BundleInfo(EditorFileSystem, packageBundle); + bundleInfo.IncludeAssetsInEditor = ActiveManifest.GetBundleIncludeAssets(assetInfo.AssetPath); + return bundleInfo; + } + + throw new Exception($"Can not found belong file system : {packageBundle.BundleName}"); } BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo) { @@ -111,7 +125,7 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath); + var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.AssetPath); return CreateBundleInfo(packageBundle, assetInfo); } BundleInfo[] IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo) @@ -120,7 +134,7 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); + var depends = ActiveManifest.GetAllDependencies(assetInfo.AssetPath); List result = new List(depends.Length); foreach (var packageBundle in depends) { @@ -135,7 +149,7 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath); + var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.AssetPath); return packageBundle.BundleName; } string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo) @@ -144,7 +158,7 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); + var depends = ActiveManifest.GetAllDependencies(assetInfo.AssetPath); List result = new List(depends.Length); foreach (var packageBundle in depends) { @@ -154,7 +168,7 @@ namespace YooAsset } bool IBundleQuery.ManifestValid() { - return _activeManifest != null; + return ActiveManifest != null; } #endregion } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/HostPlayModeImpl.cs b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/HostPlayModeImpl.cs index 601f61ec..1a433635 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/HostPlayModeImpl.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/HostPlayModeImpl.cs @@ -6,29 +6,10 @@ namespace YooAsset { internal class HostPlayModeImpl : IPlayMode, IBundleQuery { - private PackageManifest _activeManifest; - private ResourceAssist _assist; - private IBuildinQueryServices _buildinQueryServices; - private IDeliveryQueryServices _deliveryQueryServices; - private IRemoteServices _remoteServices; - public readonly string PackageName; - public DownloadManager Download - { - get { return _assist.Download; } - } - public PersistentManager Persistent - { - get { return _assist.Persistent; } - } - public CacheManager Cache - { - get { return _assist.Cache; } - } - public IRemoteServices RemoteServices - { - get { return _remoteServices; } - } + public IFileSystem BuildinFileSystem { set; get; } + public IFileSystem DeliveryFileSystem { set; get; } //可以为空! + public IFileSystem CacheFileSystem { set; get; } public HostPlayModeImpl(string packageName) @@ -39,82 +20,37 @@ namespace YooAsset /// /// 异步初始化 /// - public InitializationOperation InitializeAsync(ResourceAssist assist, IBuildinQueryServices buildinQueryServices, IDeliveryQueryServices deliveryQueryServices, IRemoteServices remoteServices) + public InitializationOperation InitializeAsync(HostPlayModeParameters initParameters) { - _assist = assist; - _buildinQueryServices = buildinQueryServices; - _deliveryQueryServices = deliveryQueryServices; - _remoteServices = remoteServices; - - var operation = new HostPlayModeInitializationOperation(this); + var operation = new HostPlayModeInitializationOperation(this, initParameters); OperationSystem.StartOperation(PackageName, operation); return operation; } - // 下载相关 - private List ConvertToDownloadList(List downloadList) - { - List result = new List(downloadList.Count); - foreach (var packageBundle in downloadList) - { - var bundleInfo = ConvertToDownloadInfo(packageBundle); - result.Add(bundleInfo); - } - return result; - } - private BundleInfo ConvertToDownloadInfo(PackageBundle packageBundle) - { - string remoteMainURL = _remoteServices.GetRemoteMainURL(packageBundle.FileName); - string remoteFallbackURL = _remoteServices.GetRemoteFallbackURL(packageBundle.FileName); - BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromRemote, remoteMainURL, remoteFallbackURL); - return bundleInfo; - } - - // 查询相关 - private bool IsDeliveryPackageBundle(PackageBundle packageBundle) - { - if (_deliveryQueryServices == null) - return false; - return _deliveryQueryServices.Query(PackageName, packageBundle.FileName, packageBundle.FileCRC); - } - private bool IsCachedPackageBundle(PackageBundle packageBundle) - { - return _assist.Cache.IsCached(packageBundle.CacheGUID); - } - private bool IsBuildinPackageBundle(PackageBundle packageBundle) - { - return _buildinQueryServices.Query(PackageName, packageBundle.FileName, packageBundle.FileCRC); - } - #region IPlayMode接口 - public PackageManifest ActiveManifest + public PackageManifest ActiveManifest { set; get; } + + void IPlayMode.UpdatePlayMode() { - set - { - _activeManifest = value; - } - get - { - return _activeManifest; - } - } - public void FlushManifestVersionFile() - { - if (_activeManifest != null) - { - _assist.Persistent.SaveSandboxPackageVersionFile(_activeManifest.PackageVersion); - } + if (BuildinFileSystem != null) + BuildinFileSystem.OnUpdate(); + + if (DeliveryFileSystem != null) + DeliveryFileSystem.OnUpdate(); + + if (CacheFileSystem != null) + CacheFileSystem.OnUpdate(); } - UpdatePackageVersionOperation IPlayMode.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout) + RequestPackageVersionOperation IPlayMode.RequestPackageVersionAsync(bool appendTimeTicks, int timeout) { - var operation = new HostPlayModeUpdatePackageVersionOperation(this, appendTimeTicks, timeout); + var operation = new HostPlayModeRequestPackageVersionOperation(this, appendTimeTicks, timeout); OperationSystem.StartOperation(PackageName, operation); return operation; } - UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout) + UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, int timeout) { - var operation = new HostPlayModeUpdatePackageManifestOperation(this, packageVersion, autoSaveVersion, timeout); + var operation = new HostPlayModeUpdatePackageManifestOperation(this, packageVersion, timeout); OperationSystem.StartOperation(PackageName, operation); return operation; } @@ -125,241 +61,80 @@ namespace YooAsset return operation; } + ClearAllBundleFilesOperation IPlayMode.ClearAllBundleFilesAsync() + { + var operation = new HostPlayModeClearAllBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + ClearUnusedBundleFilesOperation IPlayMode.ClearUnusedBundleFilesAsync() + { + var operation = new HostPlayModeClearUnusedBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) { - List downloadList = GetDownloadListByAll(_activeManifest); - var operation = new ResourceDownloaderOperation(Download, PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByAll(ActiveManifest, BuildinFileSystem, DeliveryFileSystem, CacheFileSystem); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - public List GetDownloadListByAll(PackageManifest manifest) - { - List downloadList = new List(1000); - foreach (var packageBundle in manifest.BundleList) - { - // 忽略分发文件 - if (IsDeliveryPackageBundle(packageBundle)) - continue; - - // 忽略缓存文件 - if (IsCachedPackageBundle(packageBundle)) - continue; - - // 忽略APP资源 - if (IsBuildinPackageBundle(packageBundle)) - continue; - - downloadList.Add(packageBundle); - } - - return ConvertToDownloadList(downloadList); - } - ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout) { - List downloadList = GetDownloadListByTags(_activeManifest, tags); - var operation = new ResourceDownloaderOperation(Download, PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByTags(ActiveManifest, tags, BuildinFileSystem, DeliveryFileSystem, CacheFileSystem); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - public List GetDownloadListByTags(PackageManifest manifest, string[] tags) - { - List downloadList = new List(1000); - foreach (var packageBundle in manifest.BundleList) - { - // 忽略分发文件 - if (IsDeliveryPackageBundle(packageBundle)) - continue; - - // 忽略缓存文件 - if (IsCachedPackageBundle(packageBundle)) - continue; - - // 忽略APP资源 - if (IsBuildinPackageBundle(packageBundle)) - continue; - - // 如果未带任何标记,则统一下载 - if (packageBundle.HasAnyTags() == false) - { - downloadList.Add(packageBundle); - } - else - { - // 查询DLC资源 - if (packageBundle.HasTag(tags)) - { - downloadList.Add(packageBundle); - } - } - } - - return ConvertToDownloadList(downloadList); - } - ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) { - List downloadList = GetDownloadListByPaths(_activeManifest, assetInfos); - var operation = new ResourceDownloaderOperation(Download, PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByPaths(ActiveManifest, assetInfos, BuildinFileSystem, DeliveryFileSystem, CacheFileSystem); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - public List GetDownloadListByPaths(PackageManifest manifest, AssetInfo[] assetInfos) - { - // 获取资源对象的资源包和所有依赖资源包 - List checkList = new List(); - foreach (var assetInfo in assetInfos) - { - if (assetInfo.IsInvalid) - { - YooLogger.Warning(assetInfo.Error); - continue; - } - - // 注意:如果清单里未找到资源包会抛出异常! - PackageBundle mainBundle = manifest.GetMainPackageBundle(assetInfo.AssetPath); - if (checkList.Contains(mainBundle) == false) - checkList.Add(mainBundle); - - // 注意:如果清单里未找到资源包会抛出异常! - PackageBundle[] dependBundles = manifest.GetAllDependencies(assetInfo.AssetPath); - foreach (var dependBundle in dependBundles) - { - if (checkList.Contains(dependBundle) == false) - checkList.Add(dependBundle); - } - } - - List downloadList = new List(1000); - foreach (var packageBundle in checkList) - { - // 忽略分发文件 - if (IsDeliveryPackageBundle(packageBundle)) - continue; - - // 忽略缓存文件 - if (IsCachedPackageBundle(packageBundle)) - continue; - - // 忽略APP资源 - if (IsBuildinPackageBundle(packageBundle)) - continue; - - downloadList.Add(packageBundle); - } - - return ConvertToDownloadList(downloadList); - } - ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout) { - List unpcakList = GetUnpackListByAll(_activeManifest); - var operation = new ResourceUnpackerOperation(Download, PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); + List unpcakList = PlayModeHelper.GetUnpackListByAll(ActiveManifest, BuildinFileSystem, DeliveryFileSystem, CacheFileSystem); + var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); return operation; } - private List GetUnpackListByAll(PackageManifest manifest) - { - List downloadList = new List(1000); - foreach (var packageBundle in manifest.BundleList) - { - // 忽略缓存文件 - if (IsCachedPackageBundle(packageBundle)) - continue; - - if (IsBuildinPackageBundle(packageBundle)) - { - downloadList.Add(packageBundle); - } - } - - return BundleInfo.CreateUnpackInfos(_assist, downloadList); - } - ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) { - List unpcakList = GetUnpackListByTags(_activeManifest, tags); - var operation = new ResourceUnpackerOperation(Download, PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); + List unpcakList = PlayModeHelper.GetUnpackListByTags(ActiveManifest, tags, BuildinFileSystem, DeliveryFileSystem, CacheFileSystem); + var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); return operation; } - private List GetUnpackListByTags(PackageManifest manifest, string[] tags) - { - List downloadList = new List(1000); - foreach (var packageBundle in manifest.BundleList) - { - // 忽略缓存文件 - if (IsCachedPackageBundle(packageBundle)) - continue; - - // 查询DLC资源 - if (IsBuildinPackageBundle(packageBundle)) - { - if (packageBundle.HasTag(tags)) - { - downloadList.Add(packageBundle); - } - } - } - - return BundleInfo.CreateUnpackInfos(_assist, downloadList); - } - ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout) { - List importerList = GetImporterListByFilePaths(_activeManifest, filePaths); - var operation = new ResourceImporterOperation(Download, PackageName, importerList, importerMaxNumber, failedTryAgain, timeout); + List importerList = PlayModeHelper.GetImporterListByFilePaths(ActiveManifest, filePaths, BuildinFileSystem, DeliveryFileSystem, CacheFileSystem); + var operation = new ResourceImporterOperation(PackageName, importerList, importerMaxNumber, failedTryAgain, timeout); return operation; } - private List GetImporterListByFilePaths(PackageManifest manifest, string[] filePaths) - { - List result = new List(); - foreach (var filePath in filePaths) - { - string fileName = System.IO.Path.GetFileName(filePath); - if (manifest.TryGetPackageBundleByFileName(fileName, out PackageBundle packageBundle)) - { - // 忽略缓存文件 - if (IsCachedPackageBundle(packageBundle)) - continue; - - var bundleInfo = BundleInfo.CreateImportInfo(_assist, packageBundle, filePath); - result.Add(bundleInfo); - } - else - { - YooLogger.Warning($"Not found package bundle, importer file path : {filePath}"); - } - } - return result; - } #endregion #region IBundleQuery接口 - private BundleInfo CreateBundleInfo(PackageBundle packageBundle) + private BundleInfo CreateBundleInfo(PackageBundle packageBundle, AssetInfo assetInfo) { if (packageBundle == null) throw new Exception("Should never get here !"); - // 查询分发资源 - if (IsDeliveryPackageBundle(packageBundle)) + if (BuildinFileSystem.Belong(packageBundle)) { - string deliveryFilePath = _deliveryQueryServices.GetFilePath(PackageName, packageBundle.FileName); - BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromDelivery, deliveryFilePath); + BundleInfo bundleInfo = new BundleInfo(BuildinFileSystem, packageBundle); + return bundleInfo; + } + if (DeliveryFileSystem != null && DeliveryFileSystem.Belong(packageBundle)) + { + BundleInfo bundleInfo = new BundleInfo(DeliveryFileSystem, packageBundle); + return bundleInfo; + } + if (CacheFileSystem.Belong(packageBundle)) + { + BundleInfo bundleInfo = new BundleInfo(CacheFileSystem, packageBundle); return bundleInfo; } - // 查询沙盒资源 - if (IsCachedPackageBundle(packageBundle)) - { - BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromCache); - return bundleInfo; - } - - // 查询APP资源 - if (IsBuildinPackageBundle(packageBundle)) - { - BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromStreaming); - return bundleInfo; - } - - // 从服务端下载 - return ConvertToDownloadInfo(packageBundle); + throw new Exception($"Can not found belong file system : {packageBundle.BundleName}"); } BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo) { @@ -367,8 +142,8 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath); - return CreateBundleInfo(packageBundle); + var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.AssetPath); + return CreateBundleInfo(packageBundle, assetInfo); } BundleInfo[] IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo) { @@ -376,11 +151,11 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); + var depends = ActiveManifest.GetAllDependencies(assetInfo.AssetPath); List result = new List(depends.Length); foreach (var packageBundle in depends) { - BundleInfo bundleInfo = CreateBundleInfo(packageBundle); + BundleInfo bundleInfo = CreateBundleInfo(packageBundle, assetInfo); result.Add(bundleInfo); } return result.ToArray(); @@ -391,7 +166,7 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath); + var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.AssetPath); return packageBundle.BundleName; } string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo) @@ -400,7 +175,7 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); + var depends = ActiveManifest.GetAllDependencies(assetInfo.AssetPath); List result = new List(depends.Length); foreach (var packageBundle in depends) { @@ -410,7 +185,7 @@ namespace YooAsset } bool IBundleQuery.ManifestValid() { - return _activeManifest != null; + return ActiveManifest != null; } #endregion } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/OfflinePlayModeImpl.cs b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/OfflinePlayModeImpl.cs index c6d7cc92..d3530a34 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/OfflinePlayModeImpl.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/OfflinePlayModeImpl.cs @@ -6,22 +6,8 @@ namespace YooAsset { internal class OfflinePlayModeImpl : IPlayMode, IBundleQuery { - private PackageManifest _activeManifest; - private ResourceAssist _assist; - public readonly string PackageName; - public DownloadManager Download - { - get { return _assist.Download; } - } - public PersistentManager Persistent - { - get { return _assist.Persistent; } - } - public CacheManager Cache - { - get { return _assist.Cache; } - } + public IFileSystem BuildinFileSystem { set; get; } public OfflinePlayModeImpl(string packageName) @@ -32,44 +18,29 @@ namespace YooAsset /// /// 异步初始化 /// - public InitializationOperation InitializeAsync(ResourceAssist assist) + public InitializationOperation InitializeAsync(OfflinePlayModeParameters initParameters) { - _assist = assist; - - var operation = new OfflinePlayModeInitializationOperation(this); + var operation = new OfflinePlayModeInitializationOperation(this, initParameters); OperationSystem.StartOperation(PackageName, operation); return operation; } - // 查询相关 - private bool IsCachedPackageBundle(PackageBundle packageBundle) - { - return _assist.Cache.IsCached(packageBundle.CacheGUID); - } - #region IPlayMode接口 - public PackageManifest ActiveManifest - { - set - { - _activeManifest = value; - } - get - { - return _activeManifest; - } - } - public void FlushManifestVersionFile() + public PackageManifest ActiveManifest { set; get; } + + void IPlayMode.UpdatePlayMode() { + if (BuildinFileSystem != null) + BuildinFileSystem.OnUpdate(); } - UpdatePackageVersionOperation IPlayMode.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout) + RequestPackageVersionOperation IPlayMode.RequestPackageVersionAsync(bool appendTimeTicks, int timeout) { - var operation = new OfflinePlayModeUpdatePackageVersionOperation(); + var operation = new OfflinePlayModeRequestPackageVersionOperation(); OperationSystem.StartOperation(PackageName, operation); return operation; } - UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout) + UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, int timeout) { var operation = new OfflinePlayModeUpdatePackageManifestOperation(); OperationSystem.StartOperation(PackageName, operation); @@ -82,113 +53,70 @@ namespace YooAsset return operation; } + ClearAllBundleFilesOperation IPlayMode.ClearAllBundleFilesAsync() + { + var operation = new OfflinePlayModeClearAllBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + ClearUnusedBundleFilesOperation IPlayMode.ClearUnusedBundleFilesAsync() + { + var operation = new OfflinePlayModeClearUnusedBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) { - return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByAll(ActiveManifest, BuildinFileSystem); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + return operation; } ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout) { - return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByTags(ActiveManifest, tags, BuildinFileSystem); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + return operation; } ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) { - return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByPaths(ActiveManifest, assetInfos, BuildinFileSystem); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + return operation; } - ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout) { - List unpcakList = GetUnpackListByAll(_activeManifest); - var operation = new ResourceUnpackerOperation(Download, PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); + List unpcakList = PlayModeHelper.GetUnpackListByAll(ActiveManifest, BuildinFileSystem); + var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); return operation; } - private List GetUnpackListByAll(PackageManifest manifest) - { - List downloadList = new List(1000); - foreach (var packageBundle in manifest.BundleList) - { - // 忽略缓存文件 - if (IsCachedPackageBundle(packageBundle)) - continue; - - downloadList.Add(packageBundle); - } - - return BundleInfo.CreateUnpackInfos(_assist, downloadList); - } - ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) { - List unpcakList = GetUnpackListByTags(_activeManifest, tags); - var operation = new ResourceUnpackerOperation(Download, PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); + List unpcakList = PlayModeHelper.GetUnpackListByTags(ActiveManifest, tags, BuildinFileSystem); + var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); return operation; } - private List GetUnpackListByTags(PackageManifest manifest, string[] tags) - { - List downloadList = new List(1000); - foreach (var packageBundle in manifest.BundleList) - { - // 忽略缓存文件 - if (IsCachedPackageBundle(packageBundle)) - continue; - - // 查询DLC资源 - if (packageBundle.HasTag(tags)) - { - downloadList.Add(packageBundle); - } - } - - return BundleInfo.CreateUnpackInfos(_assist, downloadList); - } - ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout) { - List importerList = GetImporterListByFilePaths(_activeManifest, filePaths); - var operation = new ResourceImporterOperation(Download, PackageName, importerList, importerMaxNumber, failedTryAgain, timeout); + List importerList = PlayModeHelper.GetImporterListByFilePaths(ActiveManifest, filePaths, BuildinFileSystem); + var operation = new ResourceImporterOperation(PackageName, importerList, importerMaxNumber, failedTryAgain, timeout); return operation; } - private List GetImporterListByFilePaths(PackageManifest manifest, string[] filePaths) - { - List result = new List(); - foreach (var filePath in filePaths) - { - string fileName = System.IO.Path.GetFileName(filePath); - if (manifest.TryGetPackageBundleByFileName(fileName, out PackageBundle packageBundle)) - { - // 忽略缓存文件 - if (IsCachedPackageBundle(packageBundle)) - continue; - - var bundleInfo = BundleInfo.CreateImportInfo(_assist, packageBundle, filePath); - result.Add(bundleInfo); - } - else - { - YooLogger.Warning($"Not found package bundle, importer file path : {filePath}"); - } - } - return result; - } #endregion #region IBundleQuery接口 - private BundleInfo CreateBundleInfo(PackageBundle packageBundle) + private BundleInfo CreateBundleInfo(PackageBundle packageBundle, AssetInfo assetInfo) { if (packageBundle == null) throw new Exception("Should never get here !"); - // 查询沙盒资源 - if (IsCachedPackageBundle(packageBundle)) + if (BuildinFileSystem.Belong(packageBundle)) { - BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromCache); + BundleInfo bundleInfo = new BundleInfo(BuildinFileSystem, packageBundle); return bundleInfo; } - // 查询APP资源 - { - BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromStreaming); - return bundleInfo; - } + throw new Exception($"Can not found belong file system : {packageBundle.BundleName}"); } BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo) { @@ -196,8 +124,8 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath); - return CreateBundleInfo(packageBundle); + var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.AssetPath); + return CreateBundleInfo(packageBundle, assetInfo); } BundleInfo[] IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo) { @@ -205,11 +133,11 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); + var depends = ActiveManifest.GetAllDependencies(assetInfo.AssetPath); List result = new List(depends.Length); foreach (var packageBundle in depends) { - BundleInfo bundleInfo = CreateBundleInfo(packageBundle); + BundleInfo bundleInfo = CreateBundleInfo(packageBundle, assetInfo); result.Add(bundleInfo); } return result.ToArray(); @@ -220,7 +148,7 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath); + var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.AssetPath); return packageBundle.BundleName; } string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo) @@ -229,7 +157,7 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); + var depends = ActiveManifest.GetAllDependencies(assetInfo.AssetPath); List result = new List(depends.Length); foreach (var packageBundle in depends) { @@ -239,7 +167,7 @@ namespace YooAsset } bool IBundleQuery.ManifestValid() { - return _activeManifest != null; + return ActiveManifest != null; } #endregion } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeHelper.cs b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeHelper.cs new file mode 100644 index 00000000..985b302e --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeHelper.cs @@ -0,0 +1,282 @@ +using System; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class PlayModeHelper + { + public static IFileSystem CreateFileSystem(string packageName, FileSystemParameters parameters) + { + Type classType = Type.GetType(parameters.FileSystemClass); + if (classType == null) + { + YooLogger.Error($"Not found file system class type {parameters.FileSystemClass}"); + return null; + } + + var instance = (IFileSystem)System.Activator.CreateInstance(classType, true); + if (instance == null) + { + YooLogger.Error($"Failed to create file system instance {parameters.FileSystemClass}"); + return null; + } + + foreach (var param in parameters.CreateParameters) + { + instance.SetParameter(param.Key, param.Value); + } + instance.OnCreate(packageName, parameters.RootDirectory); + return instance; + } + + public static List GetDownloadListByAll(PackageManifest manifest, IFileSystem fileSystemA = null, IFileSystem fileSystemB = null, IFileSystem fileSystemC = null) + { + List result = new List(1000); + foreach (var packageBundle in manifest.BundleList) + { + IFileSystem fileSystem = null; + if (fileSystemA != null && fileSystemA.Belong(packageBundle)) + { + if (fileSystemA.CheckNeedDownload(packageBundle)) + fileSystem = fileSystemA; + } + else if (fileSystemB != null && fileSystemB.Belong(packageBundle)) + { + if (fileSystemB.CheckNeedDownload(packageBundle)) + fileSystem = fileSystemB; + } + else if (fileSystemC != null && fileSystemC.Belong(packageBundle)) + { + if (fileSystemC.CheckNeedDownload(packageBundle)) + fileSystem = fileSystemC; + } + else + { + YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}"); + } + if (fileSystem == null) + continue; + + var bundleInfo = new BundleInfo(fileSystem, packageBundle); + result.Add(bundleInfo); + } + return result; + } + public static List GetDownloadListByTags(PackageManifest manifest, string[] tags, IFileSystem fileSystemA = null, IFileSystem fileSystemB = null, IFileSystem fileSystemC = null) + { + List result = new List(1000); + foreach (var packageBundle in manifest.BundleList) + { + IFileSystem fileSystem = null; + if (fileSystemA != null && fileSystemA.Belong(packageBundle)) + { + if (fileSystemA.CheckNeedDownload(packageBundle)) + fileSystem = fileSystemA; + } + else if (fileSystemB != null && fileSystemB.Belong(packageBundle)) + { + if (fileSystemB.CheckNeedDownload(packageBundle)) + fileSystem = fileSystemB; + } + else if (fileSystemC != null && fileSystemC.Belong(packageBundle)) + { + if (fileSystemC.CheckNeedDownload(packageBundle)) + fileSystem = fileSystemC; + } + else + { + YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}"); + } + if (fileSystem == null) + continue; + + // 如果未带任何标记,则统一下载 + if (packageBundle.HasAnyTags() == false) + { + var bundleInfo = new BundleInfo(fileSystem, packageBundle); + result.Add(bundleInfo); + } + else + { + // 查询DLC资源 + if (packageBundle.HasTag(tags)) + { + var bundleInfo = new BundleInfo(fileSystem, packageBundle); + result.Add(bundleInfo); + } + } + } + return result; + } + public static List GetDownloadListByPaths(PackageManifest manifest, AssetInfo[] assetInfos, IFileSystem fileSystemA = null, IFileSystem fileSystemB = null, IFileSystem fileSystemC = null) + { + // 获取资源对象的资源包和所有依赖资源包 + List checkList = new List(); + foreach (var assetInfo in assetInfos) + { + if (assetInfo.IsInvalid) + { + YooLogger.Warning(assetInfo.Error); + continue; + } + + // 注意:如果清单里未找到资源包会抛出异常! + PackageBundle mainBundle = manifest.GetMainPackageBundle(assetInfo.AssetPath); + if (checkList.Contains(mainBundle) == false) + checkList.Add(mainBundle); + + // 注意:如果清单里未找到资源包会抛出异常! + PackageBundle[] dependBundles = manifest.GetAllDependencies(assetInfo.AssetPath); + foreach (var dependBundle in dependBundles) + { + if (checkList.Contains(dependBundle) == false) + checkList.Add(dependBundle); + } + } + + List result = new List(1000); + foreach (var packageBundle in checkList) + { + IFileSystem fileSystem = null; + if (fileSystemA != null && fileSystemA.Belong(packageBundle)) + { + if (fileSystemA.CheckNeedDownload(packageBundle)) + fileSystem = fileSystemA; + } + else if (fileSystemB != null && fileSystemB.Belong(packageBundle)) + { + if (fileSystemB.CheckNeedDownload(packageBundle)) + fileSystem = fileSystemB; + } + else if (fileSystemC != null && fileSystemC.Belong(packageBundle)) + { + if (fileSystemC.CheckNeedDownload(packageBundle)) + fileSystem = fileSystemC; + } + else + { + YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}"); + } + if (fileSystem == null) + continue; + + var bundleInfo = new BundleInfo(fileSystem, packageBundle); + result.Add(bundleInfo); + } + return result; + } + public static List GetUnpackListByAll(PackageManifest manifest, IFileSystem fileSystemA = null, IFileSystem fileSystemB = null, IFileSystem fileSystemC = null) + { + List result = new List(1000); + foreach (var packageBundle in manifest.BundleList) + { + IFileSystem fileSystem = null; + if (fileSystemA != null && fileSystemA.Belong(packageBundle)) + { + if (fileSystemA.CheckNeedUnpack(packageBundle)) + fileSystem = fileSystemA; + } + else if (fileSystemB != null && fileSystemB.Belong(packageBundle)) + { + if (fileSystemB.CheckNeedUnpack(packageBundle)) + fileSystem = fileSystemB; + } + else if (fileSystemC != null && fileSystemC.Belong(packageBundle)) + { + if (fileSystemC.CheckNeedUnpack(packageBundle)) + fileSystem = fileSystemC; + } + else + { + YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}"); + } + if (fileSystem == null) + continue; + + var bundleInfo = new BundleInfo(fileSystem, packageBundle); + result.Add(bundleInfo); + } + + return result; + } + public static List GetUnpackListByTags(PackageManifest manifest, string[] tags, IFileSystem fileSystemA = null, IFileSystem fileSystemB = null, IFileSystem fileSystemC = null) + { + List result = new List(1000); + foreach (var packageBundle in manifest.BundleList) + { + IFileSystem fileSystem = null; + if (fileSystemA != null && fileSystemA.Belong(packageBundle)) + { + if (fileSystemA.CheckNeedUnpack(packageBundle)) + fileSystem = fileSystemA; + } + else if (fileSystemB != null && fileSystemB.Belong(packageBundle)) + { + if (fileSystemB.CheckNeedUnpack(packageBundle)) + fileSystem = fileSystemB; + } + else if (fileSystemC != null && fileSystemC.Belong(packageBundle)) + { + if (fileSystemC.CheckNeedUnpack(packageBundle)) + fileSystem = fileSystemC; + } + else + { + YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}"); + } + if (fileSystem == null) + continue; + + // 查询DLC资源 + if (packageBundle.HasTag(tags)) + { + var bundleInfo = new BundleInfo(fileSystem, packageBundle); + result.Add(bundleInfo); + } + } + + return result; + } + public static List GetImporterListByFilePaths(PackageManifest manifest, string[] filePaths, IFileSystem fileSystemA = null, IFileSystem fileSystemB = null, IFileSystem fileSystemC = null) + { + List result = new List(); + foreach (var filePath in filePaths) + { + string fileName = System.IO.Path.GetFileName(filePath); + if (manifest.TryGetPackageBundleByFileName(fileName, out PackageBundle packageBundle)) + { + IFileSystem fileSystem = null; + if (fileSystemA != null && fileSystemA.Belong(packageBundle)) + { + if (fileSystemA.CheckNeedImport(packageBundle)) + fileSystem = fileSystemA; + } + else if (fileSystemB != null && fileSystemB.Belong(packageBundle)) + { + if (fileSystemB.CheckNeedImport(packageBundle)) + fileSystem = fileSystemB; + } + else if (fileSystemC != null && fileSystemC.Belong(packageBundle)) + { + if (fileSystemC.CheckNeedImport(packageBundle)) + fileSystem = fileSystemC; + } + else + { + YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}"); + } + if (fileSystem == null) + continue; + + var bundleInfo = new BundleInfo(fileSystem, packageBundle, filePath); + result.Add(bundleInfo); + } + else + { + YooLogger.Warning($"Not found package bundle, importer file path : {filePath}"); + } + } + return result; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeHelper.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeHelper.cs.meta new file mode 100644 index 00000000..8d222d8b --- /dev/null +++ b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fbbce8ae4b0d0784683413d6466d27f8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/WebPlayModeImpl.cs b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/WebPlayModeImpl.cs index 5b9cc70d..530ce938 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/WebPlayModeImpl.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/WebPlayModeImpl.cs @@ -6,25 +6,8 @@ namespace YooAsset { internal class WebPlayModeImpl : IPlayMode, IBundleQuery { - private PackageManifest _activeManifest; - private ResourceAssist _assist; - private IBuildinQueryServices _buildinQueryServices; - private IRemoteServices _remoteServices; - private IWechatQueryServices _wechatQueryServices; - public readonly string PackageName; - public DownloadManager Download - { - get { return _assist.Download; } - } - public PersistentManager Persistent - { - get { return _assist.Persistent; } - } - public IRemoteServices RemoteServices - { - get { return _remoteServices; } - } + public IFileSystem WebFileSystem { set; get; } public WebPlayModeImpl(string packageName) @@ -35,73 +18,29 @@ namespace YooAsset /// /// 异步初始化 /// - public InitializationOperation InitializeAsync(ResourceAssist assist, IBuildinQueryServices buildinQueryServices, IRemoteServices remoteServices, IWechatQueryServices wechatQueryServices) + public InitializationOperation InitializeAsync(WebPlayModeParameters initParameters) { - _assist = assist; - _buildinQueryServices = buildinQueryServices; - _remoteServices = remoteServices; - _wechatQueryServices = wechatQueryServices; - - var operation = new WebPlayModeInitializationOperation(this); + var operation = new WebPlayModeInitializationOperation(this, initParameters); OperationSystem.StartOperation(PackageName, operation); return operation; } - // 下载相关 - private BundleInfo ConvertToDownloadInfo(PackageBundle packageBundle) - { - string remoteMainURL = _remoteServices.GetRemoteMainURL(packageBundle.FileName); - string remoteFallbackURL = _remoteServices.GetRemoteFallbackURL(packageBundle.FileName); - BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromRemote, remoteMainURL, remoteFallbackURL); - return bundleInfo; - } - private List ConvertToDownloadList(List downloadList) - { - List result = new List(downloadList.Count); - foreach (var packageBundle in downloadList) - { - var bundleInfo = ConvertToDownloadInfo(packageBundle); - result.Add(bundleInfo); - } - return result; - } - - // 查询相关 - private bool IsCachedPackageBundle(PackageBundle packageBundle) - { - if (_wechatQueryServices != null) - return _wechatQueryServices.Query(PackageName, packageBundle.FileName, packageBundle.FileCRC); - else - return false; - } - private bool IsBuildinPackageBundle(PackageBundle packageBundle) - { - return _buildinQueryServices.Query(PackageName, packageBundle.FileName, packageBundle.FileCRC); - } - #region IPlayMode接口 - public PackageManifest ActiveManifest - { - set - { - _activeManifest = value; - } - get - { - return _activeManifest; - } - } - public void FlushManifestVersionFile() + public PackageManifest ActiveManifest { set; get; } + + void IPlayMode.UpdatePlayMode() { + if (WebFileSystem != null) + WebFileSystem.OnUpdate(); } - UpdatePackageVersionOperation IPlayMode.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout) + RequestPackageVersionOperation IPlayMode.RequestPackageVersionAsync(bool appendTimeTicks, int timeout) { - var operation = new WebPlayModeUpdatePackageVersionOperation(this, appendTimeTicks, timeout); + var operation = new WebPlayModeRequestPackageVersionOperation(this, appendTimeTicks, timeout); OperationSystem.StartOperation(PackageName, operation); return operation; } - UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout) + UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, int timeout) { var operation = new WebPlayModeUpdatePackageManifestOperation(this, packageVersion, timeout); OperationSystem.StartOperation(PackageName, operation); @@ -114,147 +53,70 @@ namespace YooAsset return operation; } + ClearAllBundleFilesOperation IPlayMode.ClearAllBundleFilesAsync() + { + var operation = new WebPlayModeClearAllBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + ClearUnusedBundleFilesOperation IPlayMode.ClearUnusedBundleFilesAsync() + { + var operation = new WebPlayModeClearUnusedBundleFilesOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) { - List downloadList = GetDownloadListByAll(_activeManifest); - var operation = new ResourceDownloaderOperation(Download, PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByAll(ActiveManifest, WebFileSystem); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - public List GetDownloadListByAll(PackageManifest manifest) - { - List downloadList = new List(1000); - foreach (var packageBundle in manifest.BundleList) - { - // 忽略缓存文件 - if (IsCachedPackageBundle(packageBundle)) - continue; - - // 忽略APP资源 - if (IsBuildinPackageBundle(packageBundle)) - continue; - - downloadList.Add(packageBundle); - } - - return ConvertToDownloadList(downloadList); - } - ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout) { - List downloadList = GetDownloadListByTags(_activeManifest, tags); - var operation = new ResourceDownloaderOperation(Download, PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByTags(ActiveManifest, tags, WebFileSystem); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - public List GetDownloadListByTags(PackageManifest manifest, string[] tags) - { - List downloadList = new List(1000); - foreach (var packageBundle in manifest.BundleList) - { - // 忽略缓存文件 - if (IsCachedPackageBundle(packageBundle)) - continue; - - // 忽略APP资源 - if (IsBuildinPackageBundle(packageBundle)) - continue; - - // 如果未带任何标记,则统一下载 - if (packageBundle.HasAnyTags() == false) - { - downloadList.Add(packageBundle); - } - else - { - // 查询DLC资源 - if (packageBundle.HasTag(tags)) - { - downloadList.Add(packageBundle); - } - } - } - - return ConvertToDownloadList(downloadList); - } - ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) { - List downloadList = GetDownloadListByPaths(_activeManifest, assetInfos); - var operation = new ResourceDownloaderOperation(Download, PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); + List downloadList = PlayModeHelper.GetDownloadListByPaths(ActiveManifest, assetInfos, WebFileSystem); + var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - public List GetDownloadListByPaths(PackageManifest manifest, AssetInfo[] assetInfos) - { - // 获取资源对象的资源包和所有依赖资源包 - List checkList = new List(); - foreach (var assetInfo in assetInfos) - { - if (assetInfo.IsInvalid) - { - YooLogger.Warning(assetInfo.Error); - continue; - } - - // 注意:如果清单里未找到资源包会抛出异常! - PackageBundle mainBundle = manifest.GetMainPackageBundle(assetInfo.AssetPath); - if (checkList.Contains(mainBundle) == false) - checkList.Add(mainBundle); - - // 注意:如果清单里未找到资源包会抛出异常! - PackageBundle[] dependBundles = manifest.GetAllDependencies(assetInfo.AssetPath); - foreach (var dependBundle in dependBundles) - { - if (checkList.Contains(dependBundle) == false) - checkList.Add(dependBundle); - } - } - - List downloadList = new List(1000); - foreach (var packageBundle in checkList) - { - // 忽略缓存文件 - if (IsCachedPackageBundle(packageBundle)) - continue; - - // 忽略APP资源 - if (IsBuildinPackageBundle(packageBundle)) - continue; - - downloadList.Add(packageBundle); - } - - return ConvertToDownloadList(downloadList); - } - ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout) { - return ResourceUnpackerOperation.CreateEmptyUnpacker(Download, PackageName, upackingMaxNumber, failedTryAgain, timeout); + List unpcakList = PlayModeHelper.GetUnpackListByAll(ActiveManifest, WebFileSystem); + var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); + return operation; } ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) { - return ResourceUnpackerOperation.CreateEmptyUnpacker(Download, PackageName, upackingMaxNumber, failedTryAgain, timeout); + List unpcakList = PlayModeHelper.GetUnpackListByTags(ActiveManifest, tags, WebFileSystem); + var operation = new ResourceUnpackerOperation(PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout); + return operation; } - ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout) { - return ResourceImporterOperation.CreateEmptyImporter(Download, PackageName, importerMaxNumber, failedTryAgain, timeout); + List importerList = PlayModeHelper.GetImporterListByFilePaths(ActiveManifest, filePaths, WebFileSystem); + var operation = new ResourceImporterOperation(PackageName, importerList, importerMaxNumber, failedTryAgain, timeout); + return operation; } #endregion #region IBundleQuery接口 - private BundleInfo CreateBundleInfo(PackageBundle packageBundle) + private BundleInfo CreateBundleInfo(PackageBundle packageBundle, AssetInfo assetInfo) { if (packageBundle == null) throw new Exception("Should never get here !"); - // 查询APP资源 - if (IsBuildinPackageBundle(packageBundle)) + if (WebFileSystem.Belong(packageBundle)) { - BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromStreaming); + BundleInfo bundleInfo = new BundleInfo(WebFileSystem, packageBundle); return bundleInfo; } - // 从服务端下载 - return ConvertToDownloadInfo(packageBundle); + throw new Exception($"Can not found belong file system : {packageBundle.BundleName}"); } BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo) { @@ -262,8 +124,8 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath); - return CreateBundleInfo(packageBundle); + var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.AssetPath); + return CreateBundleInfo(packageBundle, assetInfo); } BundleInfo[] IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo) { @@ -271,11 +133,11 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); + var depends = ActiveManifest.GetAllDependencies(assetInfo.AssetPath); List result = new List(depends.Length); foreach (var packageBundle in depends) { - BundleInfo bundleInfo = CreateBundleInfo(packageBundle); + BundleInfo bundleInfo = CreateBundleInfo(packageBundle, assetInfo); result.Add(bundleInfo); } return result.ToArray(); @@ -286,7 +148,7 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath); + var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.AssetPath); return packageBundle.BundleName; } string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo) @@ -295,7 +157,7 @@ namespace YooAsset throw new Exception("Should never get here !"); // 注意:如果清单里未找到资源包会抛出异常! - var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath); + var depends = ActiveManifest.GetAllDependencies(assetInfo.AssetPath); List result = new List(depends.Length); foreach (var packageBundle in depends) { @@ -305,7 +167,7 @@ namespace YooAsset } bool IBundleQuery.ManifestValid() { - return _activeManifest != null; + return ActiveManifest != null; } #endregion } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ResourceAssist.cs b/Assets/YooAsset/Runtime/ResourcePackage/ResourceAssist.cs deleted file mode 100644 index be919017..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/ResourceAssist.cs +++ /dev/null @@ -1,11 +0,0 @@ - -namespace YooAsset -{ - internal class ResourceAssist - { - public CacheManager Cache { set; get; } - public PersistentManager Persistent { set; get; } - public DownloadManager Download { set; get; } - public ResourceLoader Loader { set; get; } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ResourceAssist.cs.meta b/Assets/YooAsset/Runtime/ResourcePackage/ResourceAssist.cs.meta deleted file mode 100644 index 0e932728..00000000 --- a/Assets/YooAsset/Runtime/ResourcePackage/ResourceAssist.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 395d187f862588340b6fe7c437f477ec -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs index 0629bdb1..0502eaf5 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs @@ -14,11 +14,7 @@ namespace YooAsset private EPlayMode _playMode; // 管理器 - private CacheManager _cacheMgr; - private PersistentManager _persistentMgr; - private DownloadManager _downloadMgr; - private ResourceManager _resourceMgr; - private ResourceLoader _resourceLoader; + private ResourceManager _resourceManager; private IBundleQuery _bundleQuery; private IPlayMode _playModeImpl; @@ -36,9 +32,6 @@ namespace YooAsset } - private ResourcePackage() - { - } internal ResourcePackage(string packageName) { PackageName = packageName; @@ -49,11 +42,11 @@ namespace YooAsset /// internal void UpdatePackage() { - if (_resourceMgr != null) - _resourceMgr.Update(); + if (_resourceManager != null) + _resourceManager.Update(); - if (_downloadMgr != null) - _downloadMgr.Update(); + if (_playModeImpl != null) + _playModeImpl.UpdatePlayMode(); } /// @@ -67,32 +60,9 @@ namespace YooAsset _initializeError = string.Empty; _initializeStatus = EOperationStatus.None; + _resourceManager = null; _bundleQuery = null; _playModeImpl = null; - _persistentMgr = null; - _resourceLoader = null; - - if (_resourceMgr != null) - { - _resourceMgr.ForceUnloadAllAssets(); - _resourceMgr = null; - } - - if (_downloadMgr != null) - { - _downloadMgr.DestroyAll(); - _downloadMgr = null; - } - - if (_cacheMgr != null) - { - _cacheMgr.ClearAll(); - _cacheMgr = null; - } - - // 最后清理该包裹的异步任务 - // 注意:对于有线程操作的异步任务,需要保证线程安全释放。 - OperationSystem.ClearPackageOperation(PackageName); } } @@ -101,91 +71,54 @@ namespace YooAsset /// public InitializationOperation InitializeAsync(InitializeParameters parameters) { - // 注意:WebGL平台因为网络原因可能会初始化失败! + // 注意:联机平台因为网络原因可能会初始化失败! ResetInitializeAfterFailed(); // 检测初始化参数合法性 CheckInitializeParameters(parameters); - // 创建缓存管理器 - _cacheMgr = new CacheManager(PackageName, parameters.CacheBootVerifyLevel); - - // 创建持久化管理器 - _persistentMgr = new PersistentManager(PackageName); - _persistentMgr.Initialize(parameters.BuildinRootDirectory, parameters.SandboxRootDirectory, parameters.CacheFileAppendExtension); - - // 创建下载管理器 - _downloadMgr = new DownloadManager(PackageName); - _downloadMgr.Initialize(parameters.BreakpointResumeFileSize); - - // 创建资源包加载器 - if (_playMode == EPlayMode.HostPlayMode) - { - var initializeParameters = parameters as HostPlayModeParameters; - _resourceLoader = new ResourceLoader(); - _resourceLoader.Init(parameters.DecryptionServices, initializeParameters.DeliveryLoadServices); - } - else - { - _resourceLoader = new ResourceLoader(); - _resourceLoader.Init(parameters.DecryptionServices, null); - } - - // 创建资源协助类 - ResourceAssist assist = new ResourceAssist(); - assist.Cache = _cacheMgr; - assist.Persistent = _persistentMgr; - assist.Download = _downloadMgr; - assist.Loader = _resourceLoader; - // 创建资源管理器 InitializationOperation initializeOperation; - _resourceMgr = new ResourceManager(PackageName); + _resourceManager = new ResourceManager(PackageName); if (_playMode == EPlayMode.EditorSimulateMode) { var editorSimulateModeImpl = new EditorSimulateModeImpl(PackageName); _bundleQuery = editorSimulateModeImpl; _playModeImpl = editorSimulateModeImpl; - _resourceMgr.Initialize(true, parameters.AutoDestroyAssetProvider, _bundleQuery); + _resourceManager.Initialize(parameters, _bundleQuery); var initializeParameters = parameters as EditorSimulateModeParameters; - initializeOperation = editorSimulateModeImpl.InitializeAsync(assist, initializeParameters.SimulateManifestFilePath); + initializeOperation = editorSimulateModeImpl.InitializeAsync(initializeParameters); } else if (_playMode == EPlayMode.OfflinePlayMode) { var offlinePlayModeImpl = new OfflinePlayModeImpl(PackageName); _bundleQuery = offlinePlayModeImpl; _playModeImpl = offlinePlayModeImpl; - _resourceMgr.Initialize(false, parameters.AutoDestroyAssetProvider, _bundleQuery); + _resourceManager.Initialize(parameters, _bundleQuery); var initializeParameters = parameters as OfflinePlayModeParameters; - initializeOperation = offlinePlayModeImpl.InitializeAsync(assist); + initializeOperation = offlinePlayModeImpl.InitializeAsync(initializeParameters); } else if (_playMode == EPlayMode.HostPlayMode) { var hostPlayModeImpl = new HostPlayModeImpl(PackageName); _bundleQuery = hostPlayModeImpl; _playModeImpl = hostPlayModeImpl; - _resourceMgr.Initialize(false, parameters.AutoDestroyAssetProvider, _bundleQuery); + _resourceManager.Initialize(parameters, _bundleQuery); var initializeParameters = parameters as HostPlayModeParameters; - initializeOperation = hostPlayModeImpl.InitializeAsync(assist, - initializeParameters.BuildinQueryServices, - initializeParameters.DeliveryQueryServices, - initializeParameters.RemoteServices); + initializeOperation = hostPlayModeImpl.InitializeAsync(initializeParameters); } else if (_playMode == EPlayMode.WebPlayMode) { var webPlayModeImpl = new WebPlayModeImpl(PackageName); _bundleQuery = webPlayModeImpl; _playModeImpl = webPlayModeImpl; - _resourceMgr.Initialize(false, parameters.AutoDestroyAssetProvider, _bundleQuery); + _resourceManager.Initialize(parameters, _bundleQuery); var initializeParameters = parameters as WebPlayModeParameters; - initializeOperation = webPlayModeImpl.InitializeAsync(assist, - initializeParameters.BuildinQueryServices, - initializeParameters.RemoteServices, - initializeParameters.WechatQueryServices); + initializeOperation = webPlayModeImpl.InitializeAsync(initializeParameters); } else { @@ -219,27 +152,6 @@ namespace YooAsset throw new Exception($"Editor simulate mode only support unity editor."); #endif - if (parameters is EditorSimulateModeParameters) - { - var editorSimulateModeParameters = parameters as EditorSimulateModeParameters; - if (string.IsNullOrEmpty(editorSimulateModeParameters.SimulateManifestFilePath)) - throw new Exception($"{nameof(editorSimulateModeParameters.SimulateManifestFilePath)} is null or empty."); - } - - if (parameters is HostPlayModeParameters) - { - var hostPlayModeParameters = parameters as HostPlayModeParameters; - if (hostPlayModeParameters.RemoteServices == null) - throw new Exception($"{nameof(IRemoteServices)} is null."); - if (hostPlayModeParameters.BuildinQueryServices == null) - throw new Exception($"{nameof(IBuildinQueryServices)} is null."); - if (hostPlayModeParameters.DeliveryQueryServices != null) - { - if (hostPlayModeParameters.DeliveryLoadServices == null) - throw new Exception($"{nameof(IDeliveryLoadServices)} is null."); - } - } - // 鉴定运行模式 if (parameters is EditorSimulateModeParameters) _playMode = EPlayMode.EditorSimulateMode; @@ -258,7 +170,7 @@ namespace YooAsset #if UNITY_WEBGL if (_playMode != EPlayMode.WebPlayMode) { - throw new Exception($"{_playMode} can not support WebGL plateform ! Please use {nameof(EPlayMode.WebPlayMode)}"); + throw new Exception($"{_playMode} can not support WebGL plateform !"); } #else if (_playMode == EPlayMode.WebPlayMode) @@ -274,34 +186,43 @@ namespace YooAsset _initializeError = op.Error; } + /// + /// 异步销毁 + /// + public DestroyOperation DestroyAsync() + { + var operation = new DestroyOperation(this); + OperationSystem.StartOperation(null, operation); + return operation; + } + /// /// 向网络端请求最新的资源版本 /// /// 在URL末尾添加时间戳 /// 超时时间(默认值:60秒) - public UpdatePackageVersionOperation UpdatePackageVersionAsync(bool appendTimeTicks = true, int timeout = 60) + public RequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks = true, int timeout = 60) { DebugCheckInitialize(false); - return _playModeImpl.UpdatePackageVersionAsync(appendTimeTicks, timeout); + return _playModeImpl.RequestPackageVersionAsync(appendTimeTicks, timeout); } /// /// 向网络端请求并更新清单 /// /// 更新的包裹版本 - /// 更新成功后自动保存版本号,作为下次初始化的版本。 /// 超时时间(默认值:60秒) - public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion = true, int timeout = 60) + public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, int timeout = 60) { DebugCheckInitialize(false); // 注意:强烈建议在更新之前保持加载器为空! - if (_resourceMgr.HasAnyLoader()) + if (_resourceManager.HasAnyLoader()) { - YooLogger.Warning($"Found loaded bundle before update manifest ! Recommended to call the {nameof(ForceUnloadAllAssets)} method to release loaded bundle !"); + YooLogger.Warning($"Found loaded bundle before update manifest ! Recommended to call the {nameof(UnloadAllAssetsAsync)} method to release loaded bundle !"); } - return _playModeImpl.UpdatePackageManifestAsync(packageVersion, autoSaveVersion, timeout); + return _playModeImpl.UpdatePackageManifestAsync(packageVersion, timeout); } /// @@ -315,6 +236,24 @@ namespace YooAsset return _playModeImpl.PreDownloadContentAsync(packageVersion, timeout); } + /// + /// 清理文件系统所有的资源文件 + /// + public ClearAllBundleFilesOperation ClearAllBundleFilesAsync() + { + DebugCheckInitialize(); + return _playModeImpl.ClearAllBundleFilesAsync(); + } + + /// + /// 清理文件系统未使用的资源文件 + /// + public ClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync() + { + DebugCheckInitialize(); + return _playModeImpl.ClearUnusedBundleFilesAsync(); + } + /// /// 获取本地包裹的版本信息 /// @@ -324,106 +263,49 @@ namespace YooAsset return _playModeImpl.ActiveManifest.PackageVersion; } - #region 资源卸载 + #region 资源回收 /// - /// 资源回收(卸载引用计数为零的资源) + /// 强制回收所有资源 /// - public void UnloadUnusedAssets() + public UnloadAllAssetsOperation UnloadAllAssetsAsync() { DebugCheckInitialize(); - _resourceMgr.UnloadUnusedAssets(); + var operation = new UnloadAllAssetsOperation(_resourceManager); + OperationSystem.StartOperation(PackageName, operation); + return operation; } /// - /// 资源回收(尝试卸载指定的资源) + /// 回收不再使用的资源 + /// 说明:卸载引用计数为零的资源 + /// + public UnloadUnusedAssetsOperation UnloadUnusedAssetsAsync() + { + DebugCheckInitialize(); + var operation = new UnloadUnusedAssetsOperation(_resourceManager); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + + /// + /// 资源回收 + /// 说明:尝试卸载指定的资源 /// public void TryUnloadUnusedAsset(string location) { DebugCheckInitialize(); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null); - _resourceMgr.TryUnloadUnusedAsset(assetInfo); + _resourceManager.TryUnloadUnusedAsset(assetInfo); } /// - /// 资源回收(尝试卸载指定的资源) + /// 资源回收 + /// 说明:尝试卸载指定的资源 /// public void TryUnloadUnusedAsset(AssetInfo assetInfo) { DebugCheckInitialize(); - _resourceMgr.TryUnloadUnusedAsset(assetInfo); - } - - /// - /// 强制回收所有资源 - /// - public void ForceUnloadAllAssets() - { - DebugCheckInitialize(); - _resourceMgr.ForceUnloadAllAssets(); - } - #endregion - - #region 沙盒相关 - /// - /// 获取包裹的内置文件根路径 - /// - public string GetPackageBuildinRootDirectory() - { - DebugCheckInitialize(); - return _persistentMgr.BuildinRoot; - } - - /// - /// 获取包裹的沙盒文件根路径 - /// - public string GetPackageSandboxRootDirectory() - { - DebugCheckInitialize(); - return _persistentMgr.SandboxRoot; - } - - /// - /// 清空包裹的沙盒目录 - /// - public void ClearPackageSandbox() - { - DebugCheckInitialize(); - _persistentMgr.DeleteSandboxPackageFolder(); - _cacheMgr.ClearAll(); - } - - /// - /// 清理包裹未使用的缓存文件 - /// - public ClearUnusedCacheFilesOperation ClearUnusedCacheFilesAsync() - { - DebugCheckInitialize(); - var operation = new ClearUnusedCacheFilesOperation(this, _cacheMgr); - OperationSystem.StartOperation(PackageName, operation); - return operation; - } - - /// - /// 清理包裹本地所有的缓存文件 - /// - public ClearAllCacheFilesOperation ClearAllCacheFilesAsync() - { - DebugCheckInitialize(); - var operation = new ClearAllCacheFilesOperation(_cacheMgr); - OperationSystem.StartOperation(PackageName, operation); - return operation; - } - - /// - /// 获取指定版本的缓存信息 - /// - public GetAllCacheFileInfosOperation GetAllCacheFileInfosAsync(string packageVersion) - { - DebugCheckInitialize(); - - var operation = new GetAllCacheFileInfosOperation(_persistentMgr, _cacheMgr, packageVersion); - OperationSystem.StartOperation(PackageName, operation); - return operation; + _resourceManager.TryUnloadUnusedAsset(assetInfo); } #endregion @@ -532,13 +414,13 @@ namespace YooAsset } BundleInfo bundleInfo = _bundleQuery.GetMainBundleInfo(assetInfo); - if (bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote) + if (bundleInfo.IsNeedDownloadFromRemote()) return true; BundleInfo[] depends = _bundleQuery.GetDependBundleInfos(assetInfo); foreach (var depend in depends) { - if (depend.LoadMode == BundleInfo.ELoadMode.LoadFromRemote) + if (depend.IsNeedDownloadFromRemote()) return true; } @@ -594,8 +476,7 @@ namespace YooAsset private RawFileHandle LoadRawFileInternal(AssetInfo assetInfo, bool waitForAsyncComplete, uint priority) { - DebugCheckRawFileLoadMethod(nameof(LoadRawFileAsync)); - var handle = _resourceMgr.LoadRawFileAsync(assetInfo, priority); + var handle = _resourceManager.LoadRawFileAsync(assetInfo, priority); if (waitForAsyncComplete) handle.WaitForAsyncComplete(); return handle; @@ -655,9 +536,8 @@ namespace YooAsset private SceneHandle LoadSceneInternal(AssetInfo assetInfo, bool waitForAsyncComplete, LoadSceneMode sceneMode, bool suspendLoad, uint priority) { - DebugCheckAssetLoadMethod(nameof(LoadAssetAsync)); DebugCheckAssetLoadType(assetInfo.AssetType); - var handle = _resourceMgr.LoadSceneAsync(assetInfo, sceneMode, suspendLoad, priority); + var handle = _resourceManager.LoadSceneAsync(assetInfo, sceneMode, suspendLoad, priority); if (waitForAsyncComplete) handle.WaitForAsyncComplete(); return handle; @@ -765,9 +645,8 @@ namespace YooAsset private AssetHandle LoadAssetInternal(AssetInfo assetInfo, bool waitForAsyncComplete, uint priority) { - DebugCheckAssetLoadMethod(nameof(LoadAssetAsync)); DebugCheckAssetLoadType(assetInfo.AssetType); - var handle = _resourceMgr.LoadAssetAsync(assetInfo, priority); + var handle = _resourceManager.LoadAssetAsync(assetInfo, priority); if (waitForAsyncComplete) handle.WaitForAsyncComplete(); return handle; @@ -875,9 +754,8 @@ namespace YooAsset private SubAssetsHandle LoadSubAssetsInternal(AssetInfo assetInfo, bool waitForAsyncComplete, uint priority) { - DebugCheckAssetLoadMethod(nameof(LoadSubAssetsAsync)); DebugCheckAssetLoadType(assetInfo.AssetType); - var handle = _resourceMgr.LoadSubAssetsAsync(assetInfo, priority); + var handle = _resourceManager.LoadSubAssetsAsync(assetInfo, priority); if (waitForAsyncComplete) handle.WaitForAsyncComplete(); return handle; @@ -985,9 +863,8 @@ namespace YooAsset private AllAssetsHandle LoadAllAssetsInternal(AssetInfo assetInfo, bool waitForAsyncComplete, uint priority) { - DebugCheckAssetLoadMethod(nameof(LoadAllAssetsAsync)); DebugCheckAssetLoadType(assetInfo.AssetType); - var handle = _resourceMgr.LoadAllAssetsAsync(assetInfo, priority); + var handle = _resourceManager.LoadAllAssetsAsync(assetInfo, priority); if (waitForAsyncComplete) handle.WaitForAsyncComplete(); return handle; @@ -1148,17 +1025,6 @@ namespace YooAsset #endregion #region 内部方法 - /// - /// 是否包含资源文件 - /// - internal bool IsIncludeBundleFile(string cacheGUID) - { - // NOTE : 编辑器模拟模式下始终返回TRUE - if (_playMode == EPlayMode.EditorSimulateMode) - return true; - return _playModeImpl.ActiveManifest.IsIncludeBundleFile(cacheGUID); - } - private AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType) { return _playModeImpl.ActiveManifest.ConvertLocationToAssetInfo(location, assetType); @@ -1185,24 +1051,6 @@ namespace YooAsset } } - [Conditional("DEBUG")] - private void DebugCheckRawFileLoadMethod(string method) - { - if (_playModeImpl.ActiveManifest.BuildPipeline != EDefaultBuildPipeline.RawFileBuildPipeline.ToString()) - { - throw new Exception($"Cannot load asset bundle file using {method} method !"); - } - } - - [Conditional("DEBUG")] - private void DebugCheckAssetLoadMethod(string method) - { - if (_playModeImpl.ActiveManifest.BuildPipeline == EDefaultBuildPipeline.RawFileBuildPipeline.ToString()) - { - throw new Exception($"Cannot load raw file using {method} method !"); - } - } - [Conditional("DEBUG")] private void DebugCheckAssetLoadType(System.Type type) { @@ -1226,7 +1074,7 @@ namespace YooAsset { DebugPackageData data = new DebugPackageData(); data.PackageName = PackageName; - data.ProviderInfos = _resourceMgr.GetDebugReportInfos(); + data.ProviderInfos = _resourceManager.GetDebugReportInfos(); return data; } #endregion diff --git a/Assets/YooAsset/Runtime/Services/IBuildinQueryServices.cs b/Assets/YooAsset/Runtime/Services/IBuildinQueryServices.cs deleted file mode 100644 index 81250ca5..00000000 --- a/Assets/YooAsset/Runtime/Services/IBuildinQueryServices.cs +++ /dev/null @@ -1,15 +0,0 @@ - -namespace YooAsset -{ - public interface IBuildinQueryServices - { - /// - /// 查询是否为应用程序内置的资源文件 - /// - /// 包裹名称 - /// 文件名称(包含文件的后缀格式) - /// 文件哈希值 - /// 返回查询结果 - bool Query(string packageName, string fileName, string fileCRC); - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Services/IBuildinQueryServices.cs.meta b/Assets/YooAsset/Runtime/Services/IBuildinQueryServices.cs.meta deleted file mode 100644 index 97264993..00000000 --- a/Assets/YooAsset/Runtime/Services/IBuildinQueryServices.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 71b4ac2c7d7f15b40a457f355d535f33 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs b/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs index a85877e1..9f7f6f5f 100644 --- a/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs +++ b/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs @@ -3,9 +3,6 @@ using UnityEngine; namespace YooAsset { - /// - /// 解密文件的信息 - /// public struct DecryptFileInfo { /// @@ -21,12 +18,9 @@ namespace YooAsset /// /// Unity引擎用于内容校验的CRC /// - public uint ConentCRC; + public uint FileLoadCRC; } - /// - /// 解密类服务接口 - /// public interface IDecryptionServices { /// diff --git a/Assets/YooAsset/Runtime/Services/IDeliveryLoadServices.cs b/Assets/YooAsset/Runtime/Services/IDeliveryLoadServices.cs deleted file mode 100644 index f6c84d47..00000000 --- a/Assets/YooAsset/Runtime/Services/IDeliveryLoadServices.cs +++ /dev/null @@ -1,43 +0,0 @@ -using UnityEngine; - -namespace YooAsset -{ - /// - /// 分发的资源信息 - /// - public struct DeliveryFileInfo - { - /// - /// 资源包名称 - /// - public string BundleName; - - /// - /// 文件加载路径 - /// - public string FileLoadPath; - - /// - /// Unity引擎用于内容校验的CRC - /// - public uint ConentCRC; - - /// - /// 资源包是否加密 - /// - public bool Encrypted; - } - - public interface IDeliveryLoadServices - { - /// - /// 同步方式获取分发的资源包对象 - /// - AssetBundle LoadAssetBundle(DeliveryFileInfo fileInfo); - - /// - /// 异步方式获取分发的资源包对象 - /// - AssetBundleCreateRequest LoadAssetBundleAsync(DeliveryFileInfo fileInfo); - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Services/IDeliveryLoadServices.cs.meta b/Assets/YooAsset/Runtime/Services/IDeliveryLoadServices.cs.meta deleted file mode 100644 index 49ee7dd2..00000000 --- a/Assets/YooAsset/Runtime/Services/IDeliveryLoadServices.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5233328bd3a1b944da521581d61aae78 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/Services/IDeliveryQueryServices.cs b/Assets/YooAsset/Runtime/Services/IDeliveryQueryServices.cs deleted file mode 100644 index 79a2b8ec..00000000 --- a/Assets/YooAsset/Runtime/Services/IDeliveryQueryServices.cs +++ /dev/null @@ -1,23 +0,0 @@ - -namespace YooAsset -{ - public interface IDeliveryQueryServices - { - /// - /// 查询是否为开发者分发的资源文件 - /// - /// 包裹名称 - /// 文件名称(包含文件的后缀格式) - /// 文件哈希值 - /// 返回查询结果 - bool Query(string packageName, string fileName, string fileCRC); - - /// - /// 获取分发资源文件的路径 - /// - /// 包裹名称 - /// 文件名称(包含文件的后缀格式) - /// 返回资源文件的路径 - string GetFilePath(string packageName, string fileName); - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Services/IDeliveryQueryServices.cs.meta b/Assets/YooAsset/Runtime/Services/IDeliveryQueryServices.cs.meta deleted file mode 100644 index 5941a59b..00000000 --- a/Assets/YooAsset/Runtime/Services/IDeliveryQueryServices.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7edb4ad6b8dd5cf4bbe1b84a019f6303 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs b/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs index cc68a1ff..2a23961b 100644 --- a/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs +++ b/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs @@ -24,12 +24,9 @@ namespace YooAsset /// /// 文件路径 /// - public string FilePath; + public string FileLoadPath; } - /// - /// 加密服务类接口 - /// public interface IEncryptionServices { EncryptResult Encrypt(EncryptFileInfo fileInfo); diff --git a/Assets/YooAsset/Runtime/Services/IWechatQueryServices.cs b/Assets/YooAsset/Runtime/Services/IWechatQueryServices.cs deleted file mode 100644 index c225bdb5..00000000 --- a/Assets/YooAsset/Runtime/Services/IWechatQueryServices.cs +++ /dev/null @@ -1,15 +0,0 @@ - -namespace YooAsset -{ - public interface IWechatQueryServices - { - /// - /// 查询是否为微信缓存的资源文件 - /// - /// 包裹名称 - /// 文件名称(包含文件的后缀格式) - /// 文件哈希值 - /// 返回查询结果 - bool Query(string packageName, string fileName, string fileCRC); - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Services/IWechatQueryServices.cs.meta b/Assets/YooAsset/Runtime/Services/IWechatQueryServices.cs.meta deleted file mode 100644 index e7455b44..00000000 --- a/Assets/YooAsset/Runtime/Services/IWechatQueryServices.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e6b28ce9425f5eb4f972dcda9fd864f3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs b/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs index 99b18ad5..853a098b 100644 --- a/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs +++ b/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs @@ -32,32 +32,6 @@ namespace YooAsset public const string ManifestFileVersion = "2.0.0"; - /// - /// 缓存的数据文件名称 - /// - public const string CacheBundleDataFileName = "__data"; - - /// - /// 缓存的信息文件名称 - /// - public const string CacheBundleInfoFileName = "__info"; - - /// - /// 缓存的资源文件的文件夹名称 - /// - public const string CacheFilesFolderName = "CacheFiles"; - - /// - /// 缓存的清单文件的文件夹名称 - /// - public const string ManifestFolderName = "ManifestFiles"; - - /// - /// 记录应用程序版本的文件名称 - /// - public const string AppFootPrintFileName = "ApplicationFootPrint.bytes"; - - /// /// 构建输出文件夹名称 /// diff --git a/Assets/YooAsset/Runtime/YooAssets.cs b/Assets/YooAsset/Runtime/YooAssets.cs index 8d3a5c84..cc9fc76a 100644 --- a/Assets/YooAsset/Runtime/YooAssets.cs +++ b/Assets/YooAsset/Runtime/YooAssets.cs @@ -52,28 +52,6 @@ namespace YooAsset } } - /// - /// 销毁资源系统 - /// - public static void Destroy() - { - if (_isInitialize) - { - OperationSystem.DestroyAll(); - - foreach (var package in _packages) - { - package.DestroyPackage(); - } - _packages.Clear(); - - _isInitialize = false; - if (_driver != null) - GameObject.Destroy(_driver); - YooLogger.Log($"{nameof(YooAssets)} destroy all !"); - } - } - /// /// 更新资源系统 /// @@ -90,6 +68,18 @@ namespace YooAsset } } + /// + /// 应用程序退出处理 + /// + internal static void OnApplicationQuit() + { + // 说明:在编辑器下确保播放被停止时IO类操作被终止。 + foreach (var package in _packages) + { + OperationSystem.ClearPackageOperation(package.PackageName); + } + OperationSystem.DestroyAll(); + } /// /// 创建资源包 @@ -131,19 +121,25 @@ namespace YooAsset } /// - /// 销毁资源包 + /// 移除资源包 /// /// 资源包名称 - public static void DestroyPackage(string packageName) + public static bool RemovePackage(string packageName) { CheckException(packageName); ResourcePackage package = GetPackageInternal(packageName); if (package == null) - return; + return false; - YooLogger.Log($"Destroy resource package : {packageName}"); + if (package.InitializeStatus != EOperationStatus.None) + { + YooLogger.Error($"The resource package {packageName} has not been destroyed, please call the method {nameof(ResourcePackage.DestroyAsync)} to destroy!"); + return false; + } + + YooLogger.Log($"Remove resource package : {packageName}"); _packages.Remove(package); - package.DestroyPackage(); + return true; } /// @@ -187,20 +183,12 @@ namespace YooAsset } #region 系统参数 - /// - /// 设置下载系统参数,下载失败后清理文件的HTTP错误码 - /// - public static void SetDownloadSystemClearFileResponseCode(List codes) - { - DownloadHelper.ClearFileResponseCodes = codes; - } - /// /// 设置下载系统参数,自定义下载请求 /// - public static void SetDownloadSystemUnityWebRequest(DownloadRequestDelegate requestDelegate) + public static void SetDownloadSystemUnityWebRequest(UnityWebRequestDelegate createDelegate) { - DownloadHelper.RequestDelegate = requestDelegate; + DownloadSystemHelper.UnityWebRequestCreater = createDelegate; } /// @@ -215,14 +203,6 @@ namespace YooAsset } OperationSystem.MaxTimeSlice = milliseconds; } - - /// - /// 设置缓存系统参数,禁用缓存在WebGL平台 - /// - public static void SetCacheSystemDisableCacheOnWebGL() - { - CacheHelper.DisableUnityCacheOnWebGL = true; - } #endregion #region 调试信息 diff --git a/Assets/YooAsset/Runtime/YooAssetsDriver.cs b/Assets/YooAsset/Runtime/YooAssetsDriver.cs index 338f29bb..176104f8 100644 --- a/Assets/YooAsset/Runtime/YooAssetsDriver.cs +++ b/Assets/YooAsset/Runtime/YooAssetsDriver.cs @@ -13,6 +13,13 @@ namespace YooAsset YooAssets.Update(); } +#if UNITY_EDITOR + void OnApplicationQuit() + { + YooAssets.OnApplicationQuit(); + } +#endif + [Conditional("DEBUG")] private void DebugCheckDuplicateDriver() {