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);
}
}
}