| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using UnityEngine;
- using UnityEngine.SceneManagement;
- namespace YooAsset
- {
- internal class ResourceManager
- {
- internal readonly Dictionary<string, ProviderOperation> ProviderDic = new Dictionary<string, ProviderOperation>(5000);
- internal readonly Dictionary<string, LoadBundleFileOperation> LoaderDic = new Dictionary<string, LoadBundleFileOperation>(5000);
- internal readonly List<SceneHandle> SceneHandles = new List<SceneHandle>(100);
- private long _sceneCreateIndex = 0;
- private IBundleQuery _bundleQuery;
- /// <summary>
- /// 所属包裹
- /// </summary>
- public readonly string PackageName;
- /// <summary>
- /// 锁定加载操作
- /// </summary>
- public bool LockLoadOperation = false;
- public ResourceManager(string packageName)
- {
- PackageName = packageName;
- }
- /// <summary>
- /// 初始化
- /// </summary>
- public void Initialize(IBundleQuery bundleServices)
- {
- _bundleQuery = bundleServices;
- SceneManager.sceneUnloaded += OnSceneUnloaded;
- }
- /// <summary>
- /// 销毁管理器
- /// </summary>
- public void Destroy()
- {
- SceneManager.sceneUnloaded -= OnSceneUnloaded;
- }
- /// <summary>
- /// 尝试卸载指定资源的资源包(包括依赖资源)
- /// </summary>
- public void TryUnloadUnusedAsset(AssetInfo assetInfo)
- {
- if (assetInfo.IsInvalid)
- {
- YooLogger.Error($"Failed to unload asset ! {assetInfo.Error}");
- return;
- }
- // 卸载主资源包加载器
- string mainBundleName = _bundleQuery.GetMainBundleName(assetInfo);
- var mainLoader = TryGetBundleFileLoader(mainBundleName);
- if (mainLoader != null)
- {
- mainLoader.TryDestroyProviders();
- if (mainLoader.CanDestroyLoader())
- {
- string bundleName = mainLoader.LoadBundleInfo.Bundle.BundleName;
- mainLoader.DestroyLoader();
- LoaderDic.Remove(bundleName);
- }
- }
- // 卸载依赖资源包加载器
- string[] dependBundleNames = _bundleQuery.GetDependBundleNames(assetInfo);
- foreach (var dependBundleName in dependBundleNames)
- {
- var dependLoader = TryGetBundleFileLoader(dependBundleName);
- if (dependLoader != null)
- {
- if (dependLoader.CanDestroyLoader())
- {
- string bundleName = dependLoader.LoadBundleInfo.Bundle.BundleName;
- dependLoader.DestroyLoader();
- LoaderDic.Remove(bundleName);
- }
- }
- }
- }
- /// <summary>
- /// 加载场景对象
- /// 注意:返回的场景句柄是唯一的,每个场景句柄对应自己的场景提供者对象。
- /// 注意:业务逻辑层应该避免同时加载一个子场景。
- /// </summary>
- public SceneHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool suspendLoad, uint priority)
- {
- if (LockLoadOperation)
- {
- string error = $"The load operation locked !";
- YooLogger.Error(error);
- CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
- completedProvider.SetCompletedWithError(error);
- return completedProvider.CreateHandle<SceneHandle>();
- }
- if (assetInfo.IsInvalid)
- {
- YooLogger.Error($"Failed to load scene ! {assetInfo.Error}");
- CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
- completedProvider.SetCompletedWithError(assetInfo.Error);
- return completedProvider.CreateHandle<SceneHandle>();
- }
- // 注意:同一个场景的ProviderGUID每次加载都会变化
- string providerGUID = $"{assetInfo.GUID}-{++_sceneCreateIndex}";
- ProviderOperation provider;
- {
- provider = new SceneProvider(this, providerGUID, assetInfo, loadSceneParams, suspendLoad);
- provider.InitProviderDebugInfo();
- ProviderDic.Add(providerGUID, provider);
- OperationSystem.StartOperation(PackageName, provider);
- }
- provider.Priority = priority;
- var handle = provider.CreateHandle<SceneHandle>();
- handle.PackageName = PackageName;
- SceneHandles.Add(handle);
- return handle;
- }
- /// <summary>
- /// 加载资源对象
- /// </summary>
- public AssetHandle LoadAssetAsync(AssetInfo assetInfo, uint priority)
- {
- if (LockLoadOperation)
- {
- string error = $"The load operation locked !";
- YooLogger.Error(error);
- CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
- completedProvider.SetCompletedWithError(error);
- return completedProvider.CreateHandle<AssetHandle>();
- }
- if (assetInfo.IsInvalid)
- {
- YooLogger.Error($"Failed to load asset ! {assetInfo.Error}");
- CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
- completedProvider.SetCompletedWithError(assetInfo.Error);
- return completedProvider.CreateHandle<AssetHandle>();
- }
- string providerGUID = nameof(LoadAssetAsync) + assetInfo.GUID;
- ProviderOperation provider = TryGetAssetProvider(providerGUID);
- if (provider == null)
- {
- provider = new AssetProvider(this, providerGUID, assetInfo);
- provider.InitProviderDebugInfo();
- ProviderDic.Add(providerGUID, provider);
- OperationSystem.StartOperation(PackageName, provider);
- }
- provider.Priority = priority;
- return provider.CreateHandle<AssetHandle>();
- }
- /// <summary>
- /// 加载子资源对象
- /// </summary>
- public SubAssetsHandle LoadSubAssetsAsync(AssetInfo assetInfo, uint priority)
- {
- if (LockLoadOperation)
- {
- string error = $"The load operation locked !";
- YooLogger.Error(error);
- CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
- completedProvider.SetCompletedWithError(error);
- return completedProvider.CreateHandle<SubAssetsHandle>();
- }
- if (assetInfo.IsInvalid)
- {
- YooLogger.Error($"Failed to load sub assets ! {assetInfo.Error}");
- CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
- completedProvider.SetCompletedWithError(assetInfo.Error);
- return completedProvider.CreateHandle<SubAssetsHandle>();
- }
- string providerGUID = nameof(LoadSubAssetsAsync) + assetInfo.GUID;
- ProviderOperation provider = TryGetAssetProvider(providerGUID);
- if (provider == null)
- {
- provider = new SubAssetsProvider(this, providerGUID, assetInfo);
- provider.InitProviderDebugInfo();
- ProviderDic.Add(providerGUID, provider);
- OperationSystem.StartOperation(PackageName, provider);
- }
- provider.Priority = priority;
- return provider.CreateHandle<SubAssetsHandle>();
- }
- /// <summary>
- /// 加载所有资源对象
- /// </summary>
- public AllAssetsHandle LoadAllAssetsAsync(AssetInfo assetInfo, uint priority)
- {
- if (LockLoadOperation)
- {
- string error = $"The load operation locked !";
- YooLogger.Error(error);
- CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
- completedProvider.SetCompletedWithError(error);
- return completedProvider.CreateHandle<AllAssetsHandle>();
- }
- if (assetInfo.IsInvalid)
- {
- YooLogger.Error($"Failed to load all assets ! {assetInfo.Error}");
- CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
- completedProvider.SetCompletedWithError(assetInfo.Error);
- return completedProvider.CreateHandle<AllAssetsHandle>();
- }
- string providerGUID = nameof(LoadAllAssetsAsync) + assetInfo.GUID;
- ProviderOperation provider = TryGetAssetProvider(providerGUID);
- if (provider == null)
- {
- provider = new AllAssetsProvider(this, providerGUID, assetInfo);
- provider.InitProviderDebugInfo();
- ProviderDic.Add(providerGUID, provider);
- OperationSystem.StartOperation(PackageName, provider);
- }
- provider.Priority = priority;
- return provider.CreateHandle<AllAssetsHandle>();
- }
- /// <summary>
- /// 加载原生文件
- /// </summary>
- public RawFileHandle LoadRawFileAsync(AssetInfo assetInfo, uint priority)
- {
- if (LockLoadOperation)
- {
- string error = $"The load operation locked !";
- YooLogger.Error(error);
- CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
- completedProvider.SetCompletedWithError(error);
- return completedProvider.CreateHandle<RawFileHandle>();
- }
- if (assetInfo.IsInvalid)
- {
- YooLogger.Error($"Failed to load raw file ! {assetInfo.Error}");
- CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
- completedProvider.SetCompletedWithError(assetInfo.Error);
- return completedProvider.CreateHandle<RawFileHandle>();
- }
- string providerGUID = nameof(LoadRawFileAsync) + assetInfo.GUID;
- ProviderOperation provider = TryGetAssetProvider(providerGUID);
- if (provider == null)
- {
- provider = new RawFileProvider(this, providerGUID, assetInfo);
- provider.InitProviderDebugInfo();
- ProviderDic.Add(providerGUID, provider);
- OperationSystem.StartOperation(PackageName, provider);
- }
- provider.Priority = priority;
- return provider.CreateHandle<RawFileHandle>();
- }
- internal LoadBundleFileOperation CreateMainBundleFileLoader(AssetInfo assetInfo)
- {
- BundleInfo bundleInfo = _bundleQuery.GetMainBundleInfo(assetInfo);
- return CreateBundleFileLoaderInternal(bundleInfo);
- }
- internal List<LoadBundleFileOperation> CreateDependBundleFileLoaders(AssetInfo assetInfo)
- {
- BundleInfo[] bundleInfos = _bundleQuery.GetDependBundleInfos(assetInfo);
- List<LoadBundleFileOperation> result = new List<LoadBundleFileOperation>(bundleInfos.Length);
- foreach (var bundleInfo in bundleInfos)
- {
- var bundleLoader = CreateBundleFileLoaderInternal(bundleInfo);
- result.Add(bundleLoader);
- }
- return result;
- }
- internal void RemoveBundleProviders(List<ProviderOperation> removeList)
- {
- foreach (var provider in removeList)
- {
- ProviderDic.Remove(provider.ProviderGUID);
- }
- }
- internal bool CheckBundleDestroyed(int bundleID)
- {
- string bundleName = _bundleQuery.GetMainBundleName(bundleID);
- var bundleFileLoader = TryGetBundleFileLoader(bundleName);
- if (bundleFileLoader == null)
- return true;
- return bundleFileLoader.IsDestroyed;
- }
- internal bool HasAnyLoader()
- {
- return LoaderDic.Count > 0;
- }
- private LoadBundleFileOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo)
- {
- // 如果加载器已经存在
- string bundleName = bundleInfo.Bundle.BundleName;
- LoadBundleFileOperation loaderOperation = TryGetBundleFileLoader(bundleName);
- if (loaderOperation != null)
- return loaderOperation;
- // 新增下载需求
- loaderOperation = new LoadBundleFileOperation(this, bundleInfo);
- LoaderDic.Add(bundleName, loaderOperation);
- return loaderOperation;
- }
- private LoadBundleFileOperation TryGetBundleFileLoader(string bundleName)
- {
- if (LoaderDic.TryGetValue(bundleName, out LoadBundleFileOperation value))
- return value;
- else
- return null;
- }
- private ProviderOperation TryGetAssetProvider(string providerGUID)
- {
- if (ProviderDic.TryGetValue(providerGUID, out ProviderOperation value))
- return value;
- else
- return null;
- }
- private void OnSceneUnloaded(Scene scene)
- {
- List<SceneHandle> removeList = new List<SceneHandle>();
- foreach (var sceneHandle in SceneHandles)
- {
- if (sceneHandle.IsValid)
- {
- if (sceneHandle.SceneObject == scene)
- {
- sceneHandle.Release();
- removeList.Add(sceneHandle);
- }
- }
- }
- foreach (var sceneHandle in removeList)
- {
- SceneHandles.Remove(sceneHandle);
- }
- }
- #region 调试信息
- internal List<DebugProviderInfo> GetDebugProviderInfos()
- {
- List<DebugProviderInfo> result = new List<DebugProviderInfo>(ProviderDic.Count);
- foreach (var provider in ProviderDic.Values)
- {
- DebugProviderInfo providerInfo = new DebugProviderInfo();
- providerInfo.AssetPath = provider.MainAssetInfo.AssetPath;
- providerInfo.SpawnScene = provider.SpawnScene;
- providerInfo.BeginTime = provider.BeginTime;
- providerInfo.LoadingTime = provider.ProcessTime;
- providerInfo.RefCount = provider.RefCount;
- providerInfo.Status = provider.Status.ToString();
- providerInfo.DependBundles = provider.GetDebugDependBundles();
- result.Add(providerInfo);
- }
- return result;
- }
- internal List<DebugBundleInfo> GetDebugBundleInfos()
- {
- List<DebugBundleInfo> result = new List<DebugBundleInfo>(LoaderDic.Values.Count);
- foreach (var bundleLoader in LoaderDic.Values)
- {
- var packageBundle = bundleLoader.LoadBundleInfo.Bundle;
- var bundleInfo = new DebugBundleInfo();
- bundleInfo.BundleName = packageBundle.BundleName;
- bundleInfo.RefCount = bundleLoader.RefCount;
- bundleInfo.Status = bundleLoader.Status.ToString();
- bundleInfo.ReferenceBundles = FilterReferenceBundles(packageBundle);
- result.Add(bundleInfo);
- }
- return result;
- }
- internal List<string> FilterReferenceBundles(PackageBundle packageBundle)
- {
- // 注意:引用的资源包不一定在内存中,所以需要过滤
- var referenceBundles = packageBundle.GetDebugReferenceBundles();
- List<string> result = new List<string>(referenceBundles.Count);
- foreach (var bundleName in referenceBundles)
- {
- if (LoaderDic.ContainsKey(bundleName))
- result.Add(bundleName);
- }
- return result;
- }
- #endregion
- }
- }
|