From 026a1f458cf8ceab0ca533cd478012ffa85bf82f Mon Sep 17 00:00:00 2001
From: ALEXTANG <574809918@qq.com>
Date: Wed, 10 May 2023 22:45:31 +0800
Subject: [PATCH] =?UTF-8?q?[+]=20AssetReference=20=E8=87=AA=E5=8A=A8?=
=?UTF-8?q?=E5=BC=95=E7=94=A8=E8=AE=A1=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[+] AssetReference 自动引用计数
---
.../GameFramework/Resource/AssetGroup.cs | 21 ++-
.../GameFramework/Resource/AssetReference.cs | 150 ++++++++++++++++++
.../Resource/AssetReference.cs.meta | 3 +
.../GameFramework/Resource/ResourceManager.cs | 22 ++-
4 files changed, 177 insertions(+), 19 deletions(-)
create mode 100644 Assets/TEngine/Runtime/GameFramework/Resource/AssetReference.cs
create mode 100644 Assets/TEngine/Runtime/GameFramework/Resource/AssetReference.cs.meta
diff --git a/Assets/TEngine/Runtime/GameFramework/Resource/AssetGroup.cs b/Assets/TEngine/Runtime/GameFramework/Resource/AssetGroup.cs
index ad481b45..1909f018 100644
--- a/Assets/TEngine/Runtime/GameFramework/Resource/AssetGroup.cs
+++ b/Assets/TEngine/Runtime/GameFramework/Resource/AssetGroup.cs
@@ -1,5 +1,4 @@
-using System.Collections.Generic;
-using System.Threading;
+using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using YooAsset;
@@ -83,11 +82,11 @@ namespace TEngine
/// 注册资源数据到资源组内。
///
/// 资源操作句柄。
- /// 资源标识。
+ /// 资源标识。
/// 是否注册成功。
- 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);
return true;
}
@@ -95,14 +94,14 @@ namespace TEngine
///
/// 从资源组内反注册资源数据。
///
- ///
+ ///
///
- public bool UnRegister(string tag)
+ public bool UnRegister(string assetTag)
{
AssetHandleData founded = null;
foreach (var assetHandleData in _assetHandleDataLinkedList)
{
- if (assetHandleData.Tag == tag)
+ if (assetHandleData.Tag == assetTag)
{
founded = assetHandleData;
break;
@@ -116,7 +115,7 @@ namespace TEngine
return true;
}
- Log.Warning($"UnRegister AssetHandleData Tag:{tag} Failed");
+ Log.Warning($"UnRegister AssetHandleData Tag:{assetTag} Failed");
return false;
}
@@ -201,7 +200,7 @@ namespace TEngine
return default;
}
- AssetOperationHandle handle = YooAssets.LoadAssetSync(assetName);
+ AssetOperationHandle handle = GameModule.Resource.LoadAssetGetOperation(assetName);
Register(handle);
@@ -231,7 +230,7 @@ namespace TEngine
return default;
}
- AssetOperationHandle handle = YooAssets.LoadAssetSync(assetName);
+ AssetOperationHandle handle = GameModule.Resource.LoadAssetGetOperation(assetName);
Register(handle);
diff --git a/Assets/TEngine/Runtime/GameFramework/Resource/AssetReference.cs b/Assets/TEngine/Runtime/GameFramework/Resource/AssetReference.cs
new file mode 100644
index 00000000..b4ec05bd
--- /dev/null
+++ b/Assets/TEngine/Runtime/GameFramework/Resource/AssetReference.cs
@@ -0,0 +1,150 @@
+using System.Threading;
+using Cysharp.Threading.Tasks;
+using UnityEngine;
+using YooAsset;
+
+namespace TEngine
+{
+ ///
+ /// 资源引用标识。
+ ///
+ [DisallowMultipleComponent, AddComponentMenu("")]
+ public sealed class AssetReference: MonoBehaviour
+ {
+ private AssetOperationHandle _operationHandle;
+ private int _instanceID = 0;
+ private string _assetLocation;
+ private AssetGroup _assetGroup;
+
+ ///
+ /// 资源组。
+ ///
+ 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
+ ///
+ /// 注册资源数据到资源组内。
+ ///
+ /// 资源操作句柄。
+ /// 资源标识。
+ /// 是否注册成功。
+ public bool Register(AssetOperationHandle handle,string assetTag = "")
+ {
+ return _assetGroup.Register(handle,assetTag);
+ }
+
+ ///
+ /// 从资源组内反注册资源数据。
+ ///
+ ///
+ ///
+ public bool UnRegister(string assetTag)
+ {
+ return _assetGroup.UnRegister(assetTag);
+ }
+
+ ///
+ /// 从资源组内反注册资源数据。
+ ///
+ ///
+ ///
+ public bool UnRegister(AssetOperationHandle handle)
+ {
+ return _assetGroup.UnRegister(handle);
+ }
+
+
+ ///
+ /// 同步加载资源。
+ ///
+ /// 要加载资源的名称。
+ /// 要加载资源的类型。
+ /// 资源实例。
+ public T LoadAsset(string assetName) where T : Object
+ {
+ return _assetGroup.LoadAsset(assetName);
+ }
+
+ ///
+ /// 同步加载资源。
+ ///
+ /// 要加载资源的名称。
+ /// 父节点位置。
+ /// 要加载资源的类型。
+ /// 资源实例。
+ public T LoadAsset(string assetName, Transform parent) where T : Object
+ {
+ return _assetGroup.LoadAsset(assetName,parent);
+ }
+
+ ///
+ /// 异步加载资源实例。
+ ///
+ /// 要加载的实例名称。
+ /// 取消操作Token。
+ /// 资源实实例。
+ public async UniTask LoadAssetAsync(string assetName, CancellationToken cancellationToken) where T : Object
+ {
+ return await _assetGroup.LoadAssetAsync(assetName,cancellationToken);
+ }
+
+ ///
+ /// 异步加载游戏物体。
+ ///
+ /// 要加载的游戏物体名称。
+ /// 取消操作Token。
+ /// 异步游戏物体实例。
+ public async UniTask 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().Bind(handle,location);
+
+ return true;
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Assets/TEngine/Runtime/GameFramework/Resource/AssetReference.cs.meta b/Assets/TEngine/Runtime/GameFramework/Resource/AssetReference.cs.meta
new file mode 100644
index 00000000..0fc44bc5
--- /dev/null
+++ b/Assets/TEngine/Runtime/GameFramework/Resource/AssetReference.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: c0700d496fd54f88aaba0b8d199dfefc
+timeCreated: 1683728391
\ No newline at end of file
diff --git a/Assets/TEngine/Runtime/GameFramework/Resource/ResourceManager.cs b/Assets/TEngine/Runtime/GameFramework/Resource/ResourceManager.cs
index 9b2598e3..3fdc1b46 100644
--- a/Assets/TEngine/Runtime/GameFramework/Resource/ResourceManager.cs
+++ b/Assets/TEngine/Runtime/GameFramework/Resource/ResourceManager.cs
@@ -292,7 +292,6 @@ namespace TEngine
///
/// 要加载资源的名称。
/// 要加载资源的类型。
- /// 不计入引用计数,直接释放!
/// 资源实例。
public T LoadAsset(string assetName) where T : Object
{
@@ -306,7 +305,7 @@ namespace TEngine
if (typeof(T) == typeof(GameObject))
{
GameObject ret = handle.InstantiateSync();
- handle.Dispose();
+ AssetReference.BindAssetReference(ret, handle, assetName);
return ret as T;
}
else
@@ -323,7 +322,6 @@ namespace TEngine
/// 要加载资源的名称。
/// 父节点位置。
/// 要加载资源的类型。
- /// 不计入引用计数,直接释放!
/// 资源实例。
public T LoadAsset(string assetName, Transform parent) where T : Object
{
@@ -337,7 +335,7 @@ namespace TEngine
if (typeof(T) == typeof(GameObject))
{
GameObject ret = handle.InstantiateSync();
- handle.Dispose();
+ AssetReference.BindAssetReference(ret, handle, assetName);
return ret as T;
}
else
@@ -416,8 +414,17 @@ namespace TEngine
AssetOperationHandle handle = LoadAssetAsyncHandle(assetName);
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;
+ }
}
///
@@ -429,10 +436,9 @@ namespace TEngine
public async UniTask LoadGameObjectAsync(string assetName, CancellationToken cancellationToken)
{
AssetOperationHandle handle = LoadAssetAsyncHandle(assetName);
-
await handle.ToUniTask(cancellationToken:cancellationToken);
-
GameObject ret = handle.InstantiateSync();
+ AssetReference.BindAssetReference(ret, handle, assetName);
return ret;
}