summaryrefslogtreecommitdiff
path: root/Client/Assets/Scripts/XUtliPoolLib/AssetBundleManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Client/Assets/Scripts/XUtliPoolLib/AssetBundleManager.cs')
-rw-r--r--Client/Assets/Scripts/XUtliPoolLib/AssetBundleManager.cs649
1 files changed, 649 insertions, 0 deletions
diff --git a/Client/Assets/Scripts/XUtliPoolLib/AssetBundleManager.cs b/Client/Assets/Scripts/XUtliPoolLib/AssetBundleManager.cs
new file mode 100644
index 00000000..5cb6537b
--- /dev/null
+++ b/Client/Assets/Scripts/XUtliPoolLib/AssetBundleManager.cs
@@ -0,0 +1,649 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using UnityEngine;
+
+namespace XUtliPoolLib
+{
+ public class AssetBundleManager : MonoBehaviour
+ {
+ public int BundleCount
+ {
+ get
+ {
+ return this._bundleCount;
+ }
+ }
+
+ public AssetBundleDataReader depInfoReader
+ {
+ get
+ {
+ return this._depInfoReader;
+ }
+ }
+
+ public bool isCurrentLoading
+ {
+ get
+ {
+ return this._isCurrentLoading;
+ }
+ }
+
+ public static Version version = new Version(0, 1, 0);
+
+ public static AssetBundleManager Instance;
+
+ public static string NAME = "AssetBundleManager";
+
+ public static bool enableLog = false;
+
+ private const int MAX_REQUEST = 100;
+
+ private int _requestRemain = 100;
+
+ private Queue<AssetBundleLoader> _requestQueue = new Queue<AssetBundleLoader>();
+
+ private List<AssetBundleLoader> _currentLoadQueue = new List<AssetBundleLoader>();
+
+ private HashSet<AssetBundleLoader> _nonCompleteLoaderSet = new HashSet<AssetBundleLoader>();
+
+ private HashSet<AssetBundleLoader> _thisTimeLoaderSet = new HashSet<AssetBundleLoader>();
+
+ private Dictionary<uint, AssetBundleInfo> _loadedAssetBundle = new Dictionary<uint, AssetBundleInfo>();
+
+ private Dictionary<uint, AssetBundleLoader> _loaderCache = new Dictionary<uint, AssetBundleLoader>();
+
+ private bool _isCurrentLoading;
+
+ private Queue<AssetBundleInfo> _requestUnloadBundleQueue = new Queue<AssetBundleInfo>();
+
+ private AssetBundleLoadProgress _progress = new AssetBundleLoadProgress();
+
+ public AssetBundleManager.LoadProgressHandler onProgress;
+
+ public AssetBundlePathResolver pathResolver;
+
+ private AssetBundleDataReader _depInfoReader;
+
+ private int _bundleCount = 0;
+
+ private uint _defaultHash = 0u;
+
+ public delegate void LoadAssetCompleteHandler(AssetBundleInfo info, int handlerID);
+
+ public delegate void LoaderCompleteHandler(AssetBundleLoader info);
+
+ public delegate void LoadProgressHandler(AssetBundleLoadProgress progress);
+
+ public AssetBundleManager()
+ {
+ AssetBundleManager.Instance = this;
+ this.pathResolver = new AssetBundlePathResolver();
+ this._defaultHash = XSingleton<XCommon>.singleton.XHashLowerRelpaceDot(0u, "Assets.Resources.");
+ }
+
+ protected void Awake()
+ {
+ base.InvokeRepeating("CheckUnusedBundle", 0f, 5f);
+ }
+
+ public void Init()
+ {
+ this.RemoveAll();
+ this.LoadDepInfo();
+ }
+
+ public void Init(byte[] data, Action callback)
+ {
+ bool flag = data.Length > 4;
+ if (flag)
+ {
+ XBinaryReader xbinaryReader = XBinaryReader.Get();
+ xbinaryReader.InitByte(data, 0, 0);
+ bool flag2 = xbinaryReader.ReadChar() == 'A' && xbinaryReader.ReadChar() == 'B' && xbinaryReader.ReadChar() == 'D';
+ if (flag2)
+ {
+ bool flag3 = xbinaryReader.ReadChar() == 'T';
+ if (flag3)
+ {
+ this._depInfoReader = new AssetBundleDataReader();
+ }
+ else
+ {
+ this._depInfoReader = new AssetBundleDataBinaryReader();
+ }
+ this._depInfoReader.Read(xbinaryReader);
+ }
+ XBinaryReader.Return(xbinaryReader, false);
+ }
+ bool flag4 = callback != null;
+ if (flag4)
+ {
+ callback();
+ }
+ }
+
+ private void LoadDepInfo()
+ {
+ string path = string.Format("{0}/{1}", this.pathResolver.BundleCacheDir, this.pathResolver.DependFileName);
+ bool flag = File.Exists(path);
+ if (flag)
+ {
+ this.Init(File.ReadAllBytes(path), null);
+ }
+ else
+ {
+ TextAsset textAsset = Resources.Load<TextAsset>("dep");
+ bool flag2 = textAsset != null;
+ if (flag2)
+ {
+ this.Init(textAsset.bytes, null);
+ Resources.UnloadAsset(textAsset);
+ }
+ else
+ {
+ XSingleton<XDebug>.singleton.AddErrorLog("depFile not exist!", null, null, null, null, null);
+ }
+ }
+ }
+
+ private void OnDestroy()
+ {
+ this.RemoveAll();
+ }
+
+ public AssetBundleLoader Load(uint hash, string path, string suffix, string prefix = null, AssetBundleManager.LoadAssetCompleteHandler handler = null, int handlerID = -1)
+ {
+ bool flag = this.depInfoReader == null;
+ AssetBundleLoader result;
+ if (flag)
+ {
+ result = null;
+ }
+ else
+ {
+ AssetBundleLoader assetBundleLoader = this.CreateLoader(hash, path, suffix, prefix);
+ bool flag2 = assetBundleLoader == null;
+ if (flag2)
+ {
+ result = null;
+ }
+ else
+ {
+ assetBundleLoader.loadHandlerID = handlerID;
+ this._thisTimeLoaderSet.Add(assetBundleLoader);
+ bool isComplete = assetBundleLoader.isComplete;
+ if (isComplete)
+ {
+ bool flag3 = handler != null;
+ if (flag3)
+ {
+ handler(assetBundleLoader.bundleInfo, handlerID);
+ }
+ }
+ else
+ {
+ bool flag4 = handler != null;
+ if (flag4)
+ {
+ AssetBundleLoader assetBundleLoader2 = assetBundleLoader;
+ assetBundleLoader2.onComplete = (AssetBundleManager.LoadAssetCompleteHandler)Delegate.Combine(assetBundleLoader2.onComplete, handler);
+ }
+ this._isCurrentLoading = true;
+ bool flag5 = assetBundleLoader.state < LoadState.State_LoadingAsync;
+ if (flag5)
+ {
+ this._nonCompleteLoaderSet.Add(assetBundleLoader);
+ }
+ this.StartLoad();
+ }
+ result = assetBundleLoader;
+ }
+ }
+ return result;
+ }
+
+ public AssetBundleInfo LoadImm(uint hash, string path, string suffix, string prefix = null)
+ {
+ bool flag = this.depInfoReader == null;
+ AssetBundleInfo result;
+ if (flag)
+ {
+ result = null;
+ }
+ else
+ {
+ AssetBundleLoader assetBundleLoader = this.CreateLoader(hash, path, suffix, prefix);
+ bool flag2 = assetBundleLoader == null;
+ if (flag2)
+ {
+ result = null;
+ }
+ else
+ {
+ this._thisTimeLoaderSet.Add(assetBundleLoader);
+ bool isComplete = assetBundleLoader.isComplete;
+ if (isComplete)
+ {
+ result = assetBundleLoader.bundleInfo;
+ }
+ else
+ {
+ this._isCurrentLoading = true;
+ bool flag3 = assetBundleLoader.state < LoadState.State_Loading;
+ if (flag3)
+ {
+ this._nonCompleteLoaderSet.Add(assetBundleLoader);
+ }
+ this.StartLoadImm();
+ result = assetBundleLoader.bundleInfo;
+ }
+ }
+ }
+ return result;
+ }
+
+ public bool CheckInDep(uint hash)
+ {
+ bool flag = this.depInfoReader == null;
+ return !flag && this._depInfoReader.GetAssetBundleInfo(hash) != null;
+ }
+
+ internal AssetBundleLoader CreateLoader(uint abFileName, string location = null, string suffix = null, string prefix = null)
+ {
+ bool flag = this._loaderCache.ContainsKey(abFileName);
+ AssetBundleLoader assetBundleLoader;
+ if (flag)
+ {
+ assetBundleLoader = this._loaderCache[abFileName];
+ }
+ else
+ {
+ AssetBundleData assetBundleData = this._depInfoReader.GetAssetBundleInfo(abFileName);
+ bool flag2 = assetBundleData == null;
+ if (flag2)
+ {
+ bool flag3 = prefix != null;
+ uint num;
+ if (flag3)
+ {
+ num = XSingleton<XCommon>.singleton.XHashLowerRelpaceDot(0u, prefix);
+ }
+ else
+ {
+ num = this._defaultHash;
+ }
+ bool flag4 = location != null;
+ if (flag4)
+ {
+ num = XSingleton<XCommon>.singleton.XHashLowerRelpaceDot(num, location);
+ }
+ bool flag5 = suffix != null;
+ if (flag5)
+ {
+ num = XSingleton<XCommon>.singleton.XHashLowerRelpaceDot(num, suffix);
+ }
+ assetBundleData = this._depInfoReader.GetAssetBundleInfoByShortName(num);
+ }
+ bool flag6 = assetBundleData == null;
+ if (flag6)
+ {
+ return null;
+ }
+ assetBundleLoader = this.CreateLoader();
+ assetBundleLoader.bundleManager = this;
+ assetBundleLoader.bundleData = assetBundleData;
+ assetBundleLoader.bundleName = assetBundleData.fullName;
+ this._loaderCache[abFileName] = assetBundleLoader;
+ }
+ return assetBundleLoader;
+ }
+
+ protected virtual AssetBundleLoader CreateLoader()
+ {
+ RuntimePlatform platform = Application.platform;
+ AssetBundleLoader result;
+ if ((int)platform != 8)
+ {
+ if ((int)platform != 11)
+ {
+ result = new MobileAssetBundleLoader();
+ }
+ else
+ {
+ result = new AndroidAssetBundleLoader();
+ }
+ }
+ else
+ {
+ result = new IOSAssetBundleLoader();
+ }
+ return result;
+ }
+
+ private void StartLoad()
+ {
+ bool flag = this._nonCompleteLoaderSet.Count > 0;
+ if (flag)
+ {
+ List<AssetBundleLoader> list = ListPool<AssetBundleLoader>.Get();
+ list.AddRange(this._nonCompleteLoaderSet);
+ this._nonCompleteLoaderSet.Clear();
+ foreach (AssetBundleLoader item in list)
+ {
+ this._currentLoadQueue.Add(item);
+ }
+ this._progress = new AssetBundleLoadProgress();
+ this._progress.total = this._currentLoadQueue.Count;
+ foreach (AssetBundleLoader assetBundleLoader in list)
+ {
+ assetBundleLoader.Load();
+ }
+ ListPool<AssetBundleLoader>.Release(list);
+ }
+ }
+
+ private void StartLoadImm()
+ {
+ bool flag = this._nonCompleteLoaderSet.Count > 0;
+ if (flag)
+ {
+ bool flag2 = this._nonCompleteLoaderSet.Count == 1;
+ if (flag2)
+ {
+ HashSet<AssetBundleLoader>.Enumerator enumerator = this._nonCompleteLoaderSet.GetEnumerator();
+ enumerator.MoveNext();
+ this._currentLoadQueue.Add(enumerator.Current);
+ this._nonCompleteLoaderSet.Clear();
+ this._progress.percent = 0f;
+ this._progress.complete = 0;
+ this._progress.loader = null;
+ this._progress.total = this._currentLoadQueue.Count;
+ enumerator.Current.LoadImm();
+ }
+ else
+ {
+ List<AssetBundleLoader> list = ListPool<AssetBundleLoader>.Get();
+ list.AddRange(this._nonCompleteLoaderSet);
+ this._nonCompleteLoaderSet.Clear();
+ foreach (AssetBundleLoader item in list)
+ {
+ this._currentLoadQueue.Add(item);
+ }
+ this._progress.percent = 0f;
+ this._progress.complete = 0;
+ this._progress.loader = null;
+ this._progress.total = this._currentLoadQueue.Count;
+ foreach (AssetBundleLoader assetBundleLoader in list)
+ {
+ assetBundleLoader.LoadImm();
+ }
+ ListPool<AssetBundleLoader>.Release(list);
+ }
+ }
+ }
+
+ public void RemoveAll()
+ {
+ this._currentLoadQueue.Clear();
+ this._requestQueue.Clear();
+ foreach (KeyValuePair<uint, AssetBundleInfo> keyValuePair in this._loadedAssetBundle)
+ {
+ keyValuePair.Value.Dispose();
+ }
+ this._loadedAssetBundle.Clear();
+ this._loaderCache.Clear();
+ this._requestUnloadBundleQueue.Clear();
+ }
+
+ public AssetBundleInfo GetBundleInfo(uint key)
+ {
+ foreach (KeyValuePair<uint, AssetBundleInfo> keyValuePair in this._loadedAssetBundle)
+ {
+ AssetBundleInfo value = keyValuePair.Value;
+ bool flag = value.bundleName == key;
+ if (flag)
+ {
+ return value;
+ }
+ }
+ return null;
+ }
+
+ internal void RequestLoadBundle(AssetBundleLoader loader)
+ {
+ bool flag = this._requestRemain < 0;
+ if (flag)
+ {
+ this._requestRemain = 0;
+ }
+ bool flag2 = this._requestRemain == 0;
+ if (flag2)
+ {
+ this._requestQueue.Enqueue(loader);
+ }
+ else
+ {
+ this.LoadBundle(loader);
+ }
+ }
+
+ internal void RequestLoadBundleImm(AssetBundleLoader loader)
+ {
+ bool flag = this._requestRemain < 0;
+ if (flag)
+ {
+ this._requestRemain = 0;
+ }
+ bool flag2 = this._requestRemain == 0;
+ if (flag2)
+ {
+ this._requestQueue.Enqueue(loader);
+ }
+ else
+ {
+ this.LoadBundleImm(loader);
+ }
+ }
+
+ private void CheckRequestList()
+ {
+ while (this._requestRemain > 0 && this._requestQueue.Count > 0)
+ {
+ AssetBundleLoader loader = this._requestQueue.Dequeue();
+ this.LoadBundle(loader);
+ }
+ }
+
+ private void LoadBundle(AssetBundleLoader loader)
+ {
+ bool flag = !loader.isComplete;
+ if (flag)
+ {
+ loader.LoadBundle();
+ this._requestRemain--;
+ }
+ }
+
+ private void LoadBundleImm(AssetBundleLoader loader)
+ {
+ bool flag = !loader.isComplete;
+ if (flag)
+ {
+ loader.LoadBundleImm();
+ this._requestRemain--;
+ }
+ }
+
+ internal void LoadError(AssetBundleLoader loader)
+ {
+ this.LoadComplete(loader);
+ }
+
+ internal void LoadComplete(AssetBundleLoader loader)
+ {
+ this._requestRemain++;
+ this._currentLoadQueue.Remove(loader);
+ bool flag = this.onProgress != null;
+ if (flag)
+ {
+ this._progress.loader = loader;
+ this._progress.complete = this._progress.total - this._currentLoadQueue.Count;
+ this.onProgress(this._progress);
+ }
+ bool flag2 = this._currentLoadQueue.Count == 0 && this._nonCompleteLoaderSet.Count == 0;
+ if (flag2)
+ {
+ this._isCurrentLoading = false;
+ foreach (AssetBundleLoader assetBundleLoader in this._thisTimeLoaderSet)
+ {
+ bool flag3 = assetBundleLoader.bundleInfo != null;
+ if (flag3)
+ {
+ assetBundleLoader.bundleInfo.ResetLifeTime();
+ }
+ }
+ this._thisTimeLoaderSet.Clear();
+ }
+ else
+ {
+ this.CheckRequestList();
+ }
+ }
+
+ internal AssetBundleInfo CreateBundleInfo(AssetBundleLoader loader, AssetBundleInfo abi = null, AssetBundle assetBundle = null)
+ {
+ bool flag = abi == null;
+ if (flag)
+ {
+ abi = new AssetBundleInfo();
+ }
+ abi.bundleName = loader.bundleName;
+ abi.bundle = assetBundle;
+ abi.data = loader.bundleData;
+ this._loadedAssetBundle[abi.bundleName] = abi;
+ this._bundleCount++;
+ return abi;
+ }
+
+ public void DeleteBundleCount()
+ {
+ this._bundleCount--;
+ }
+
+ internal void RemoveBundleInfo(AssetBundleInfo abi)
+ {
+ abi.Dispose();
+ this._loadedAssetBundle.Remove(abi.bundleName);
+ }
+
+ private void CheckUnusedBundle()
+ {
+ this.UnloadUnusedBundle(false);
+ }
+
+ public void UnloadUnusedBundle(bool force = false)
+ {
+ bool flag = (!this._isCurrentLoading && !XSingleton<XResourceLoaderMgr>.singleton.isCurrentLoading) || force;
+ bool flag2 = flag;
+ if (flag2)
+ {
+ List<uint> list = ListPool<uint>.Get();
+ list.AddRange(this._loadedAssetBundle.Keys);
+ int num = force ? 100000 : 20;
+ int num2 = 0;
+ bool flag3;
+ do
+ {
+ flag3 = false;
+ int num3 = 0;
+ while (num3 < list.Count && flag && num2 < num)
+ {
+ uint key = list[num3];
+ AssetBundleInfo assetBundleInfo = this._loadedAssetBundle[key];
+ bool isUnused = assetBundleInfo.isUnused;
+ if (isUnused)
+ {
+ flag3 = true;
+ num2++;
+ this.RemoveBundleInfo(assetBundleInfo);
+ list.RemoveAt(num3);
+ num3--;
+ }
+ num3++;
+ }
+ }
+ while (flag3 && flag && num2 < num);
+ ListPool<uint>.Release(list);
+ while (this._requestUnloadBundleQueue.Count > 0 && flag && num2 < num)
+ {
+ AssetBundleInfo assetBundleInfo2 = this._requestUnloadBundleQueue.Dequeue();
+ bool flag4 = assetBundleInfo2 != null;
+ if (flag4)
+ {
+ assetBundleInfo2.UnloadBundle();
+ num2++;
+ }
+ }
+ }
+ }
+
+ public void UnloadNotUsedLoader()
+ {
+ List<uint> list = ListPool<uint>.Get();
+ list.AddRange(this._loadedAssetBundle.Keys);
+ List<AssetBundleLoader> list2 = ListPool<AssetBundleLoader>.Get();
+ list2.AddRange(this._nonCompleteLoaderSet);
+ list2.AddRange(this._currentLoadQueue);
+ foreach (AssetBundleLoader assetBundleLoader in list2)
+ {
+ this.RemoveLoadingLoader(assetBundleLoader.bundleName, list);
+ }
+ for (int i = 0; i < list.Count; i++)
+ {
+ AssetBundleInfo abi = this._loadedAssetBundle[list[i]];
+ this.RemoveBundleInfo(abi);
+ list.RemoveAt(i);
+ i--;
+ }
+ ListPool<uint>.Release(list);
+ ListPool<AssetBundleLoader>.Release(list2);
+ }
+
+ private void RemoveLoadingLoader(uint hash, List<uint> list)
+ {
+ AssetBundleData assetBundleInfo = this._depInfoReader.GetAssetBundleInfo(hash);
+ list.Remove(assetBundleInfo.fullName);
+ bool flag = assetBundleInfo.dependencies != null;
+ if (flag)
+ {
+ for (int i = 0; i < assetBundleInfo.dependencies.Length; i++)
+ {
+ this.RemoveLoadingLoader(assetBundleInfo.dependencies[i], list);
+ }
+ }
+ }
+
+ public void AddUnloadBundleQueue(AssetBundleInfo info)
+ {
+ this._requestUnloadBundleQueue.Enqueue(info);
+ bool flag = this._requestUnloadBundleQueue.Count > 3;
+ if (flag)
+ {
+ this.UnloadUnusedBundle(false);
+ }
+ }
+
+ public void RemoveBundle(uint key)
+ {
+ AssetBundleInfo bundleInfo = this.GetBundleInfo(key);
+ bool flag = bundleInfo != null;
+ if (flag)
+ {
+ this.RemoveBundleInfo(bundleInfo);
+ }
+ }
+ }
+}