123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- using XGame.Framework.i18n;
- using System;
- using System.Collections.Generic;
- using XGame.Framework.Quality;
- using XGame.Framework.Asyncs;
- namespace XGame.Framework.Asset
- {
- public sealed partial class AssetManager : IAssetManager, IAsyncListener, IAssetCacheHandle
- {
- private enum OperateState : byte
- {
- None = 0,
- Prepare,
- Start,
- //End,
- }
- AssetRepository Repository { set; get; }
- Dictionary<string, IAssetAsync> AssetAsyncMap { set; get; }
- private List<IAsync> LoadingAsyncs { set; get; }
- IAssetLoader Loader { set; get; }
- IAddressableHandle AddressableHandler { set; get; }
- private LanguageType _languageType;
- private XQualityLevel _quality;
- private IAsync _disposeAsync;
- private bool _isDispose;
- private OperateState _unloadunusedOp;
- public AssetManager()
- {
- Repository = new AssetRepository();
- AssetAsyncMap = new Dictionary<string, IAssetAsync>();
- LoadingAsyncs = new List<IAsync>();
- //AsyncPool = new AssetAsyncPool(new AssetAsyncAgentBuilder());
- //AsyncPool.AgentLimit = 10;
- Loader = new LoaderBuilder().Build();
- AddressableHandler = Loader as IAddressableHandle;
- _isDispose = false;
- _unloadunusedOp = OperateState.None;
- }
- TResult IAssetManager.LoadSync<TResult>(string addressableName)
- {
- if (_isDispose) return default;
- addressableName = AddressableHandler.ConvertAddressableName(new ConvertOptions(){
- addressableName = addressableName,
- quality = _quality,
- langType = _languageType
- }); //addressableName?.ToLower();
- var result = Repository.Clone(addressableName);
- if (result != null)
- {
- return result.Convert<TResult>(addressableName);
- }
- result = Loader.LoadSync<TResult>(addressableName);
- if (result != null)
- {
- var asset = AssetCreator.Create(addressableName, result);
- Repository.AddAsset(asset);
- result = Repository.Clone(addressableName);
- return result.Convert<TResult>(addressableName);
- }
- return default;
- }
- IAssetLoadAsync<TResult> IAssetManager.LoadAsync<TResult>(string addressableName)
- {
- if (_isDispose) return default;
- addressableName = AddressableHandler.ConvertAddressableName(new ConvertOptions()
- {
- addressableName = addressableName,
- quality = _quality,
- langType = _languageType
- }); //addressableName?.ToLower();
- IAssetAsync assetAsync = null;
- if (!Repository.ContainsAsset(addressableName))
- { //仓库中没找到资源
- //先取未完成的async
- if (!AssetAsyncMap.TryGetValue(addressableName, out assetAsync))
- {
- assetAsync = Loader.LoadAsync<TResult>(addressableName);//未加载
- if (assetAsync != null)
- {
- AssetAsyncMap.Add(assetAsync.AddressableName, assetAsync);
- assetAsync.On(OnAssetAsyncCompleted);
- //这里多做一个监听,且order要保证该监听在Async的最后执行
- assetAsync.On(this, int.MaxValue);
- }
- }
- }
- //
- var loadAsync = new AssetLoadAsync<TResult>(addressableName, assetAsync, this);
- LoadingAsyncs.Add(loadAsync);
- return loadAsync;
- }
- void IAssetManager.Recycle(object obj)
- {
- Repository.Recycle(obj);
- }
- void IAssetManager.StopAsync<TResult>(IAssetLoadAsync<TResult> async)
- {
- //这里只能停止业务的监听事件,不能停止AssetAsync的事件
- async.RemoveAll();
- //((AssetResultAsync<TResult>)async).StopAsync();
- }
- void IAssetManager.UnloadUnusedAssets()
- {
- if (_unloadunusedOp != OperateState.None)
- return;
- if (AssetAsyncMap.Count <= 0)
- {
- InnerUnloadUnusedAssets();
- }
- else
- {
- _unloadunusedOp = OperateState.Prepare;
- }
- }
- IAsync IAssetManager.LoadSceneBundle(string sceneName)
- {
- if (_isDispose || string.IsNullOrEmpty(sceneName)) return default;
- sceneName = sceneName.ToLower();
- IAssetAsync bundleAsync = null;
- if (!Repository.ContainsAsset(sceneName))
- { //仓库中没找到资源
- //先取未完成的async
- if (!AssetAsyncMap.TryGetValue(sceneName, out bundleAsync))
- {
- bundleAsync = Loader.LoadSceneBundleAsync(sceneName);//未加载
- if (bundleAsync != null)
- {
- AssetAsyncMap.Add(bundleAsync.AddressableName, bundleAsync);
- bundleAsync.On(OnAssetAsyncCompleted);
- //这里多做一个监听,且order要保证该监听在Async的最后执行
- bundleAsync.On(this, int.MaxValue);
- }
- }
- }
- return bundleAsync;
- }
- void IAssetManager.UnLoadSceneBundle(string sceneName)
- {
- Loader.UnLoadSceneBundle(sceneName);
- }
- private void InnerUnloadUnusedAssets()
- {
- _unloadunusedOp = OperateState.Start;
- Repository.UnloadUnusedAssets(((assetPath, source) =>
- {
- Loader.Unload(assetPath, source);
- }));
- Loader.UnloadUnusedAssets();
- _unloadunusedOp = OperateState.None;
- }
- //void IDisposable.Dispose()
- //{
- // //AsyncPool.Dispose();
- // Repository.Dispose();
- // (Loader as IDisposable)?.Dispose();
- // Loader = null;
- // AssetAsyncMap.Clear();
- //}
- IAsync IAssetManager.Dispose()
- {
- var async = new ManagerDisposeAsync();
- _isDispose = true;
- if (AssetAsyncMap.Count == 0)
- {
- InnerDispose();
- async.Completed();
- return async;
- }
- _disposeAsync = async;
- return _disposeAsync;
- }
- private void InnerDispose()
- {
- Repository.Dispose();
- (Loader as IDisposable)?.Dispose();
- Loader = null;
- AddressableHandler = null;
- AssetAsyncMap.Clear();
- for(var i = LoadingAsyncs.Count - 1; i >= 0; i--)
- {
- LoadingAsyncs[i].RemoveAll();
- }
- LoadingAsyncs.Clear();
- _disposeAsync = null;
- Monitor.AssetsMonitor.Dispose();
- }
- private void SetLangueType(LanguageType langType)
- {
- _languageType = langType;
- }
- private void SetQuality(XQualityLevel quality)
- {
- _quality = quality;
- }
- /// <summary>
- /// 转换AddressableName
- /// 会根据游戏当前语言、品质等级返回对应的AddressableName
- /// </summary>
- /// <param name="addressableName"></param>
- /// <returns></returns>
- string IAssetManager.ConvertAddressableName(string addressableName)
- {
- return AddressableHandler?.ConvertAddressableName(new ConvertOptions()
- {
- addressableName = addressableName,
- quality = _quality,
- langType = _languageType,
- }) ?? addressableName;
- }
- object IAssetCacheHandle.GetAssetFromCache(string addressableName)
- {
- return Repository.Clone(addressableName);
- }
- void IAssetCacheHandle.ReleaseAsync(IAsync async)
- {
- LoadingAsyncs.Remove(async);
- }
- void IAssetCacheHandle.SetPreloadTag(string addressableName, bool isPreload)
- {
- Repository.SetPreloadSign(addressableName, isPreload);
- }
- #region 内部函数
- /// <summary>
- /// 该监听回调需要保证在IAssetAsync的Completed最后回调
- /// 用于释放资源或者Dispose
- /// </summary>
- /// <param name="aAsync"></param>
- void IAsyncListener.OnAsyncCompleted(IAsync aAsync)
- {
- if (AssetAsyncMap.Count <= 0)
- {
- if (_unloadunusedOp != OperateState.None)
- {
- InnerUnloadUnusedAssets();
- }
- if (_isDispose)
- {
- var async = _disposeAsync;
- InnerDispose();
- (async as Async)?.Completed();
- }
- }
- }
- private void OnAssetAsyncCompleted(IAsync async)
- {
- if (async is IAssetAsync assetAsync)
- {
- AssetAsyncMap.Remove(assetAsync.AddressableName);
- var result = assetAsync.GetResult();
- if (result != null)
- {
- var asset = AssetCreator.Create(assetAsync.AddressableName, result);
- Repository.AddAsset(asset);
- }
- }
- }
- #endregion
- }
- }
|