using System.Collections.Generic; using System.Threading; using Cysharp.Threading.Tasks; using UnityEngine; using YooAsset; namespace TEngine { /// /// 资源句柄数据。 /// public class AssetHandleData : IMemory { /// /// 资源操作句柄。 /// private AssetOperationHandle _handle; /// /// 资源操作句柄。 /// public AssetOperationHandle Handle => _handle; /// /// 标签。 /// public string Tag { private set; get; } /// /// 释放资源句柄数据对象。 /// public void Clear() { if (_handle != null) { _handle.Dispose(); } _handle = null; Tag = string.Empty; } /// /// 从内存池中获取资源句柄数据。 /// /// 资源操作句柄。 /// 标签。 /// 资源句柄数据。 public static AssetHandleData Alloc(AssetOperationHandle handle, string tag = "") { AssetHandleData assetHandleData = MemoryPool.Acquire(); assetHandleData._handle = handle; assetHandleData.Tag = tag; return assetHandleData; } /// /// 释放资源句柄数据到内存池。 /// /// 释放资源句柄数据。 public static void Release(AssetHandleData assetHandleData) { if (assetHandleData == null) { Log.Fatal("Release AssetHandleData Failed !"); return; } MemoryPool.Release(assetHandleData); } } /// /// 资源组数据。 /// DisposeGroup。 /// public class AssetGroup : IMemory { private readonly Dictionary _assetHandleDataMap = new Dictionary(); /// /// 引用资源数据到资源组内。 /// /// 资源操作句柄。 /// 资源标识。 /// 是否注册成功。 public bool Reference(AssetOperationHandle handle,string assetTag = "") { AssetHandleData handleData = AssetHandleData.Alloc(handle,assetTag); _assetHandleDataMap[handleData.Handle.GetAssetInfo().Address] = handleData; return true; } /// /// 引用资源数据到资源组内。 /// /// 资源定位地址。 /// 资源操作句柄。 /// 资源标识。 /// 是否注册成功。 public bool Reference(string address,AssetOperationHandle handle,string assetTag = "") { AssetHandleData handleData = AssetHandleData.Alloc(handle,assetTag); _assetHandleDataMap[address] = handleData; return true; } /// /// 从资源组内释放资源数据。 /// /// 资源标签。 /// 是否释放成功。 public bool ReleaseByTag(string assetTag) { AssetHandleData founded = null; foreach (var assetHandleData in _assetHandleDataMap.Values) { if (assetHandleData.Tag == assetTag) { founded = assetHandleData; break; } } if (founded != null) { _assetHandleDataMap.Remove(founded.Handle.GetAssetInfo().Address); AssetHandleData.Release(founded); return true; } Log.Warning($"Release AssetHandleData Tag:{assetTag} Failed"); return false; } /// /// 从资源组内释放资源数据。 /// /// 资源定位地址。 /// 是否释放成功。 public bool Release(string address) { if (_assetHandleDataMap.TryGetValue(address,out var assetHandleData)) { _assetHandleDataMap.Remove(assetHandleData.Handle.GetAssetInfo().Address); AssetHandleData.Release(assetHandleData); return true; } Log.Warning($"Release AssetHandleData Address:{address} Failed"); return false; } /// /// 从资源组内释放资源数据。 /// /// 资源操作句柄。 /// 是否释放成功。 public bool Release(AssetOperationHandle handle) { AssetHandleData founded = null; foreach (var assetHandleData in _assetHandleDataMap.Values) { if (assetHandleData.Handle == handle) { founded = assetHandleData; break; } } if (founded != null) { _assetHandleDataMap.Remove(founded.Handle.GetAssetInfo().Address); AssetHandleData.Release(founded); return true; } Log.Warning($"Release AssetHandleData Handle:{handle} Failed"); return false; } public void Clear() { var etr = _assetHandleDataMap.GetEnumerator(); while (etr.MoveNext()) { AssetHandleData assetHandleData = etr.Current.Value; AssetHandleData.Release(assetHandleData); } etr.Dispose(); _assetHandleDataMap.Clear(); } /// /// 从内存池中获取资源分组数据。 /// /// 资源分组数据。 public static AssetGroup Alloc() { AssetGroup assetGroup = MemoryPool.Acquire(); return assetGroup; } /// /// 将内存对象归还内存池。 /// /// public static void Release(AssetGroup assetGroup) { if (assetGroup == null) { Log.Fatal("Release AssetGroup Failed !"); return; } MemoryPool.Release(assetGroup); } /// /// 同步加载资源。 /// /// 要加载资源的名称。 /// 父节点位置。 /// 要加载资源的类型。 /// 资源实例。 public T LoadAsset(string assetName, Transform parent = null) where T : Object { if (string.IsNullOrEmpty(assetName)) { Log.Error("Asset name is invalid."); return default; } if (_assetHandleDataMap.TryGetValue(assetName,out var assetHandleData)) { if (typeof(T) == typeof(GameObject)) { GameObject ret = assetHandleData.Handle.InstantiateSync(parent); return ret as T; } else { return assetHandleData.Handle.AssetObject as T; } } AssetOperationHandle handle = GameModule.Resource.LoadAssetGetOperation(assetName); Reference(handle); if (typeof(T) == typeof(GameObject)) { GameObject ret = handle.InstantiateSync(parent); return ret as T; } else { return handle.AssetObject as T; } } /// /// 同步加载资源。 /// /// 要加载资源的名称。 /// 要加载资源的类型。 /// 资源操作句柄。 /// 资源实例。 public T LoadAsset(string assetName,out AssetOperationHandle assetOperationHandle) where T : Object { assetOperationHandle = null; if (string.IsNullOrEmpty(assetName)) { Log.Error("Asset name is invalid."); return default; } if (_assetHandleDataMap.TryGetValue(assetName,out var assetHandleData)) { if (typeof(T) == typeof(GameObject)) { GameObject ret = assetHandleData.Handle.InstantiateSync(); return ret as T; } else { return assetHandleData.Handle.AssetObject as T; } } assetOperationHandle = GameModule.Resource.LoadAssetGetOperation(assetName); Reference(assetOperationHandle); if (typeof(T) == typeof(GameObject)) { GameObject ret = assetOperationHandle.InstantiateSync(); return ret as T; } else { return assetOperationHandle.AssetObject as T; } } /// /// 同步加载资源。 /// /// 要加载资源的名称。 /// 父节点位置。 /// 资源操作句柄。 /// 要加载资源的类型。 /// 资源实例。 public T LoadAsset(string assetName, Transform parent,out AssetOperationHandle assetOperationHandle) where T : Object { assetOperationHandle = null; if (string.IsNullOrEmpty(assetName)) { Log.Error("Asset name is invalid."); return default; } if (_assetHandleDataMap.TryGetValue(assetName,out var assetHandleData)) { if (typeof(T) == typeof(GameObject)) { GameObject ret = assetHandleData.Handle.InstantiateSync(); return ret as T; } else { return assetHandleData.Handle.AssetObject as T; } } assetOperationHandle = GameModule.Resource.LoadAssetGetOperation(assetName); Reference(assetOperationHandle); if (typeof(T) == typeof(GameObject)) { GameObject ret = assetOperationHandle.InstantiateSync(parent); return ret as T; } else { return assetOperationHandle.AssetObject as T; } } /// /// 异步加载资源实例。 /// /// 要加载的实例名称。 /// 取消操作Token。 /// 资源操作句柄。 /// 资源实实例。 // ReSharper disable once UnusedParameter.Global // ReSharper disable once RedundantAssignment public async UniTask LoadAssetAsync(string assetName, CancellationToken cancellationToken,AssetOperationHandle assetOperationHandle = null) where T : Object { if (string.IsNullOrEmpty(assetName)) { Log.Error("Asset name is invalid."); return default; } if (_assetHandleDataMap.TryGetValue(assetName,out var assetHandleData)) { if (typeof(T) == typeof(GameObject)) { GameObject ret = assetHandleData.Handle.InstantiateSync(); return ret as T; } else { return assetHandleData.Handle.AssetObject as T; } } AssetOperationHandle handle = GameModule.Resource.LoadAssetAsyncHandle(assetName); Reference(handle); bool cancelOrFailed = await handle.ToUniTask(cancellationToken: cancellationToken).SuppressCancellationThrow(); if (cancelOrFailed) { Release(handle); return null; } assetOperationHandle = handle; if (typeof(T) == typeof(GameObject)) { GameObject ret = handle.InstantiateSync(); return ret as T; } else { return handle.AssetObject as T; } } /// /// 异步加载游戏物体。 /// /// 要加载的游戏物体名称。 /// 取消操作Token。 /// 异步游戏物体实例。 public async UniTask LoadGameObjectAsync(string assetName, CancellationToken cancellationToken) { return await LoadAssetAsync(assetName,cancellationToken); } /// /// 异步加载游戏物体。 /// /// 要加载的游戏物体名称。 /// 取消操作Token。 /// 资源操作句柄。 /// 异步游戏物体实例。 public async UniTask LoadGameObjectAsync(string assetName, CancellationToken cancellationToken,AssetOperationHandle assetOperationHandle) { return await LoadAssetAsync(assetName,cancellationToken,assetOperationHandle); } } }