123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- using System.Collections.Generic;
- using UnityEngine;
- namespace XGame.Framework.Asset
- {
- //internal partial class AssetBundleLoader
- //{
- //}
- /// <summary>
- /// AssetBundleLoader已加载的Bundle仓库
- /// </summary>
- internal class BundleRepository
- {
- /// <summary>
- /// 已加载的Bundle
- /// key:bundleName
- /// </summary>
- private Dictionary<string, BundleAsset> BundleMap { set; get; }
- /// <summary>
- /// 已加载的Asset的InstanceId
- /// UnityEngine.Object用InstanceId代替HashCode,hash值可能出现重复
- /// </summary>
- private Dictionary<int, string> UsingHashCodeMap { set; get; }
- /// <summary>
- /// 等待卸载的Asset
- /// </summary>
- private Dictionary<string, Object> UnusedAssetMap { set; get; }
- public BundleRepository()
- {
- BundleMap = new Dictionary<string, BundleAsset>();
- UsingHashCodeMap = new Dictionary<int, string>();
- UnusedAssetMap = new Dictionary<string, Object>();
- }
- #region Bundle
- public bool ContainsBundle(string bundleName)
- {
- return BundleMap.ContainsKey(bundleName);
- }
- public void AddBundle(BundleAsset bundleAsset)
- {
- if (bundleAsset == null)
- {
- AssetsLog.Warn("Bundle Repository Add Invalid Bundle.");
- return;
- }
- var bundleName = bundleAsset.AddressableName;
- if (BundleMap.ContainsKey(bundleName))
- {
- AssetsLog.Warn($"Add Bundle Repeat. Name:{bundleName}");
- return;
- }
- BundleMap.Add(bundleName, bundleAsset);
- }
- public BundleAsset GetBundle(string bundleName)
- {
- BundleMap.TryGetValue(bundleName, out var bundle);
- return bundle;
- }
- public void RemoveBundle(string bundleName)
- {
- BundleMap.Remove(bundleName);
- }
- public void RetainBundle(string bundleName)
- {
- if (BundleMap.TryGetValue(bundleName, out var bundle))
- {
- bundle.Retain();
- }
- }
- public void ReleaseBundle(string bundleName)
- {
- if (BundleMap.TryGetValue(bundleName, out var bundle))
- {
- bundle.Release();
- }
- }
- #endregion
- #region AssetHashCode
- public bool RegistAssetHash(int hashCode, string addressableName)
- {
- if (!UsingHashCodeMap.ContainsKey(hashCode))
- {
- UsingHashCodeMap.Add(hashCode, addressableName);
- return true;
- }
- AssetsLog.Warn($"Bundle asset hash repeat. Hash:{hashCode} Last:{UsingHashCodeMap[hashCode]} Next:{addressableName}");
- return false;
- }
- // ReSharper disable once IdentifierTypo
- public void UnRegistAssetHash(int hashCode)
- {
- if (UsingHashCodeMap.ContainsKey(hashCode))
- {
- UsingHashCodeMap.Remove(hashCode);
- }
- }
- public string GetAssetNameByHash(int hashCode)
- {
- UsingHashCodeMap.TryGetValue(hashCode, out var addressableName);
- return addressableName;
- }
- public bool ContainsAssetHash(int hashCode)
- {
- return UsingHashCodeMap.ContainsKey(hashCode);
- }
- public bool ContainsAsset(string addressableName)
- {
- return UsingHashCodeMap.ContainsValue(addressableName);
- }
- #endregion
- #region UnusedAsset
- public bool ContainsUnusedAsset(string addressableName)
- {
- UnusedAssetMap.TryGetValue(addressableName, out var asset);
- return asset != null;
- }
- public void PushUnusedAsset(Object source)
- {
- if (source == null) return;
- var instanceId = source.GetInstanceID();
- var addressableName = GetAssetNameByHash(instanceId);
- if (string.IsNullOrEmpty(addressableName))
- {
- AssetsLog.Debug($"Object is unregistered. Hash:{instanceId} Name:{source.name}");
- return;
- }
- if (UnusedAssetMap.ContainsKey(addressableName))
- {
- AssetsLog.Debug($"Object had in map. But add repeat. Name:{addressableName} Next:{instanceId} Last:{UnusedAssetMap[addressableName]?.GetInstanceID()}");
- return;
- }
- UnusedAssetMap.Add(addressableName, source);
- }
- public Object PopUnusedAsset(string addressableName)
- {
- if (UnusedAssetMap.TryGetValue(addressableName, out var source))
- {
- UnusedAssetMap.Remove(addressableName);
- }
- return source;
- }
- public void UnloadUnusedAssets(System.Func<string, bool> isReferencing, System.Action<string> onUnloadAsset)
- {
- //释放未被引用的Asset
- var unloadList = new List<string>();
- foreach (var item in UnusedAssetMap)
- {
- var addressableName = item.Key;
- if (!isReferencing(item.Key))
- {
- unloadList.Add(addressableName);
- }
- }
- foreach (var addressableName in unloadList)
- {
- var asset = UnusedAssetMap[addressableName];
- var instanceId = asset?.GetInstanceID() ?? 0;
- UnRegistAssetHash(instanceId);
- UnusedAssetMap.Remove(addressableName);
- onUnloadAsset?.Invoke(addressableName);
- asset.Unload();
- //if (asset is Component || asset is GameObject || asset is AssetBundle)
- //{
- // //非独立资源
- // //Object.Destroy(asset);
- //}
- //else
- //{
- // //独立资源才能使用Resources.UnloadAsset
- // Resources.UnloadAsset(asset);
- //}
- AssetsLog.Debug($"Resources UnloadAsset: {addressableName}");
- }
- unloadList.Clear();
- //释放引用计数为零的Bundle
- foreach (var bundleItem in BundleMap)
- {
- if (bundleItem.Value.Reference <= 0)
- {
- unloadList.Add(bundleItem.Key);
- }
- }
- foreach (var bundlePath in unloadList)
- {
- var bundleAsset = BundleMap[bundlePath];
- BundleMap.Remove(bundlePath);
- bundleAsset.Dispose();
- AssetsLog.Debug($"AssetBundle Unload: {bundlePath}");
- }
- unloadList.Clear();
- Resources.UnloadUnusedAssets();
- }
- #endregion
- public void Dispose()
- {
- foreach (var asset in UnusedAssetMap)
- {
- asset.Value.Unload();
- //Resources.UnloadAsset(asset.Value);
- }
- UnusedAssetMap.Clear();
- foreach (var it in BundleMap)
- {
- it.Value.Dispose();
- }
- BundleMap.Clear();
- UsingHashCodeMap.Clear();
- }
- }
- }
|