[+] AssetReference 自动引用计数

[+] AssetReference 自动引用计数
This commit is contained in:
ALEXTANG
2023-05-10 22:45:31 +08:00
parent 6fddedf0b2
commit 026a1f458c
4 changed files with 177 additions and 19 deletions

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Threading;
using System.Threading;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using UnityEngine; using UnityEngine;
using YooAsset; using YooAsset;
@@ -83,11 +82,11 @@ namespace TEngine
/// 注册资源数据到资源组内。 /// 注册资源数据到资源组内。
/// </summary> /// </summary>
/// <param name="handle">资源操作句柄。</param> /// <param name="handle">资源操作句柄。</param>
/// <param name="tag">资源标识。</param> /// <param name="assetTag">资源标识。</param>
/// <returns>是否注册成功。</returns> /// <returns>是否注册成功。</returns>
public bool Register(AssetOperationHandle handle,string tag = "") public bool Register(AssetOperationHandle handle,string assetTag = "")
{ {
AssetHandleData handleData = AssetHandleData.Alloc(handle,tag); AssetHandleData handleData = AssetHandleData.Alloc(handle,assetTag);
_assetHandleDataLinkedList.AddLast(handleData); _assetHandleDataLinkedList.AddLast(handleData);
return true; return true;
} }
@@ -95,14 +94,14 @@ namespace TEngine
/// <summary> /// <summary>
/// 从资源组内反注册资源数据。 /// 从资源组内反注册资源数据。
/// </summary> /// </summary>
/// <param name="tag"></param> /// <param name="assetTag"></param>
/// <returns></returns> /// <returns></returns>
public bool UnRegister(string tag) public bool UnRegister(string assetTag)
{ {
AssetHandleData founded = null; AssetHandleData founded = null;
foreach (var assetHandleData in _assetHandleDataLinkedList) foreach (var assetHandleData in _assetHandleDataLinkedList)
{ {
if (assetHandleData.Tag == tag) if (assetHandleData.Tag == assetTag)
{ {
founded = assetHandleData; founded = assetHandleData;
break; break;
@@ -116,7 +115,7 @@ namespace TEngine
return true; return true;
} }
Log.Warning($"UnRegister AssetHandleData Tag:{tag} Failed"); Log.Warning($"UnRegister AssetHandleData Tag:{assetTag} Failed");
return false; return false;
} }
@@ -201,7 +200,7 @@ namespace TEngine
return default; return default;
} }
AssetOperationHandle handle = YooAssets.LoadAssetSync<T>(assetName); AssetOperationHandle handle = GameModule.Resource.LoadAssetGetOperation<T>(assetName);
Register(handle); Register(handle);
@@ -231,7 +230,7 @@ namespace TEngine
return default; return default;
} }
AssetOperationHandle handle = YooAssets.LoadAssetSync<T>(assetName); AssetOperationHandle handle = GameModule.Resource.LoadAssetGetOperation<T>(assetName);
Register(handle); Register(handle);

View File

@@ -0,0 +1,150 @@
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using YooAsset;
namespace TEngine
{
/// <summary>
/// 资源引用标识。
/// </summary>
[DisallowMultipleComponent, AddComponentMenu("")]
public sealed class AssetReference: MonoBehaviour
{
private AssetOperationHandle _operationHandle;
private int _instanceID = 0;
private string _assetLocation;
private AssetGroup _assetGroup;
/// <summary>
/// 资源组。
/// </summary>
public AssetGroup AssetGroup => _assetGroup;
private void Awake()
{
if (_assetGroup == null)
{
_assetGroup = AssetGroup.Alloc();
}
}
public void Bind(AssetOperationHandle operation,string assetLocation)
{
_operationHandle = operation;
this._assetLocation = assetLocation;
_instanceID = gameObject.GetInstanceID();
}
private void OnDestroy()
{
if (_operationHandle != null)
{
_operationHandle.Release();
_operationHandle = null;
}
if (_assetGroup == null)
{
AssetGroup.Release(_assetGroup);
_assetGroup = null;
}
}
#region Public Methods
/// <summary>
/// 注册资源数据到资源组内。
/// </summary>
/// <param name="handle">资源操作句柄。</param>
/// <param name="assetTag">资源标识。</param>
/// <returns>是否注册成功。</returns>
public bool Register(AssetOperationHandle handle,string assetTag = "")
{
return _assetGroup.Register(handle,assetTag);
}
/// <summary>
/// 从资源组内反注册资源数据。
/// </summary>
/// <param name="assetTag"></param>
/// <returns></returns>
public bool UnRegister(string assetTag)
{
return _assetGroup.UnRegister(assetTag);
}
/// <summary>
/// 从资源组内反注册资源数据。
/// </summary>
/// <param name="handle"></param>
/// <returns></returns>
public bool UnRegister(AssetOperationHandle handle)
{
return _assetGroup.UnRegister(handle);
}
/// <summary>
/// 同步加载资源。
/// </summary>
/// <param name="assetName">要加载资源的名称。</param>
/// <typeparam name="T">要加载资源的类型。</typeparam>
/// <returns>资源实例。</returns>
public T LoadAsset<T>(string assetName) where T : Object
{
return _assetGroup.LoadAsset<T>(assetName);
}
/// <summary>
/// 同步加载资源。
/// </summary>
/// <param name="assetName">要加载资源的名称。</param>
/// <param name="parent">父节点位置。</param>
/// <typeparam name="T">要加载资源的类型。</typeparam>
/// <returns>资源实例。</returns>
public T LoadAsset<T>(string assetName, Transform parent) where T : Object
{
return _assetGroup.LoadAsset<T>(assetName,parent);
}
/// <summary>
/// 异步加载资源实例。
/// </summary>
/// <param name="assetName">要加载的实例名称。</param>
/// <param name="cancellationToken">取消操作Token。</param>
/// <returns>资源实实例。</returns>
public async UniTask<T> LoadAssetAsync<T>(string assetName, CancellationToken cancellationToken) where T : Object
{
return await _assetGroup.LoadAssetAsync<T>(assetName,cancellationToken);
}
/// <summary>
/// 异步加载游戏物体。
/// </summary>
/// <param name="assetName">要加载的游戏物体名称。</param>
/// <param name="cancellationToken">取消操作Token。</param>
/// <returns>异步游戏物体实例。</returns>
public async UniTask<GameObject> LoadGameObjectAsync(string assetName, CancellationToken cancellationToken)
{
return await _assetGroup.LoadGameObjectAsync(assetName,cancellationToken);
}
public static bool BindAssetReference(GameObject go,AssetOperationHandle handle,string location)
{
if (go == null)
{
throw new GameFrameworkException($"BindAssetReference Failed => GameObject is null!");
}
if (handle == null)
{
throw new GameFrameworkException($"BindAssetReference Failed => AssetOperationHandle is null!");
}
go.AddComponent<AssetReference>().Bind(handle,location);
return true;
}
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c0700d496fd54f88aaba0b8d199dfefc
timeCreated: 1683728391

View File

@@ -292,7 +292,6 @@ namespace TEngine
/// </summary> /// </summary>
/// <param name="assetName">要加载资源的名称。</param> /// <param name="assetName">要加载资源的名称。</param>
/// <typeparam name="T">要加载资源的类型。</typeparam> /// <typeparam name="T">要加载资源的类型。</typeparam>
/// <remarks>不计入引用计数,直接释放!</remarks>
/// <returns>资源实例。</returns> /// <returns>资源实例。</returns>
public T LoadAsset<T>(string assetName) where T : Object public T LoadAsset<T>(string assetName) where T : Object
{ {
@@ -306,7 +305,7 @@ namespace TEngine
if (typeof(T) == typeof(GameObject)) if (typeof(T) == typeof(GameObject))
{ {
GameObject ret = handle.InstantiateSync(); GameObject ret = handle.InstantiateSync();
handle.Dispose(); AssetReference.BindAssetReference(ret, handle, assetName);
return ret as T; return ret as T;
} }
else else
@@ -323,7 +322,6 @@ namespace TEngine
/// <param name="assetName">要加载资源的名称。</param> /// <param name="assetName">要加载资源的名称。</param>
/// <param name="parent">父节点位置。</param> /// <param name="parent">父节点位置。</param>
/// <typeparam name="T">要加载资源的类型。</typeparam> /// <typeparam name="T">要加载资源的类型。</typeparam>
/// <remarks>不计入引用计数,直接释放!</remarks>
/// <returns>资源实例。</returns> /// <returns>资源实例。</returns>
public T LoadAsset<T>(string assetName, Transform parent) where T : Object public T LoadAsset<T>(string assetName, Transform parent) where T : Object
{ {
@@ -337,7 +335,7 @@ namespace TEngine
if (typeof(T) == typeof(GameObject)) if (typeof(T) == typeof(GameObject))
{ {
GameObject ret = handle.InstantiateSync(); GameObject ret = handle.InstantiateSync();
handle.Dispose(); AssetReference.BindAssetReference(ret, handle, assetName);
return ret as T; return ret as T;
} }
else else
@@ -417,7 +415,16 @@ namespace TEngine
await handle.ToUniTask(cancellationToken:cancellationToken); await handle.ToUniTask(cancellationToken:cancellationToken);
return handle.AssetObject as T; if (typeof(T) == typeof(GameObject))
{
GameObject ret = handle.InstantiateSync();
AssetReference.BindAssetReference(ret, handle, assetName);
return ret as T;
}
else
{
return handle.AssetObject as T;
}
} }
/// <summary> /// <summary>
@@ -429,10 +436,9 @@ namespace TEngine
public async UniTask<GameObject> LoadGameObjectAsync(string assetName, CancellationToken cancellationToken) public async UniTask<GameObject> LoadGameObjectAsync(string assetName, CancellationToken cancellationToken)
{ {
AssetOperationHandle handle = LoadAssetAsyncHandle<GameObject>(assetName); AssetOperationHandle handle = LoadAssetAsyncHandle<GameObject>(assetName);
await handle.ToUniTask(cancellationToken:cancellationToken); await handle.ToUniTask(cancellationToken:cancellationToken);
GameObject ret = handle.InstantiateSync(); GameObject ret = handle.InstantiateSync();
AssetReference.BindAssetReference(ret, handle, assetName);
return ret; return ret;
} }