From 6eb915c129fc90c6f4c82ae097dd6ffad5239efc Mon Sep 17 00:00:00 2001 From: chai Date: Mon, 25 Jan 2021 14:28:30 +0800 Subject: +scripts --- .../Scripts/XUtliPoolLib/AssetBundleManager.cs | 649 +++++++++++++++++++++ 1 file changed, 649 insertions(+) create mode 100644 Client/Assets/Scripts/XUtliPoolLib/AssetBundleManager.cs (limited to 'Client/Assets/Scripts/XUtliPoolLib/AssetBundleManager.cs') 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 _requestQueue = new Queue(); + + private List _currentLoadQueue = new List(); + + private HashSet _nonCompleteLoaderSet = new HashSet(); + + private HashSet _thisTimeLoaderSet = new HashSet(); + + private Dictionary _loadedAssetBundle = new Dictionary(); + + private Dictionary _loaderCache = new Dictionary(); + + private bool _isCurrentLoading; + + private Queue _requestUnloadBundleQueue = new Queue(); + + 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.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("dep"); + bool flag2 = textAsset != null; + if (flag2) + { + this.Init(textAsset.bytes, null); + Resources.UnloadAsset(textAsset); + } + else + { + XSingleton.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.singleton.XHashLowerRelpaceDot(0u, prefix); + } + else + { + num = this._defaultHash; + } + bool flag4 = location != null; + if (flag4) + { + num = XSingleton.singleton.XHashLowerRelpaceDot(num, location); + } + bool flag5 = suffix != null; + if (flag5) + { + num = XSingleton.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 list = ListPool.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.Release(list); + } + } + + private void StartLoadImm() + { + bool flag = this._nonCompleteLoaderSet.Count > 0; + if (flag) + { + bool flag2 = this._nonCompleteLoaderSet.Count == 1; + if (flag2) + { + HashSet.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 list = ListPool.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.Release(list); + } + } + } + + public void RemoveAll() + { + this._currentLoadQueue.Clear(); + this._requestQueue.Clear(); + foreach (KeyValuePair keyValuePair in this._loadedAssetBundle) + { + keyValuePair.Value.Dispose(); + } + this._loadedAssetBundle.Clear(); + this._loaderCache.Clear(); + this._requestUnloadBundleQueue.Clear(); + } + + public AssetBundleInfo GetBundleInfo(uint key) + { + foreach (KeyValuePair 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.singleton.isCurrentLoading) || force; + bool flag2 = flag; + if (flag2) + { + List list = ListPool.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.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 list = ListPool.Get(); + list.AddRange(this._loadedAssetBundle.Keys); + List list2 = ListPool.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.Release(list); + ListPool.Release(list2); + } + + private void RemoveLoadingLoader(uint hash, List 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); + } + } + } +} -- cgit v1.1-26-g67d0