From 5e70e7972e3b308bb92dd73e8d0fbbf7494f0853 Mon Sep 17 00:00:00 2001 From: ALEXTANG <574809918@qq.com> Date: Mon, 16 Oct 2023 13:03:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=B5=84=E6=BA=90=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新资源模块接口 --- .../ResourceModule/IResourceManager.cs | 15 ++- .../Modules/ResourceModule/ResourceManager.cs | 114 ++++++++++++++---- .../Modules/ResourceModule/ResourceModule.cs | 27 +++-- 3 files changed, 113 insertions(+), 43 deletions(-) diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/IResourceManager.cs b/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/IResourceManager.cs index 89f6cbea..2833d28e 100644 --- a/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/IResourceManager.cs +++ b/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/IResourceManager.cs @@ -61,7 +61,7 @@ namespace TEngine /// 获取或设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒)。 /// long Milliseconds { get; set; } - + /// /// 资源缓存表容量。 /// @@ -164,18 +164,20 @@ namespace TEngine /// 同步加载资源。 /// /// 资源的定位地址。 + /// 是否需要实例化。 /// 要加载资源的类型。 /// 资源实例。 - T LoadAsset(string location) where T : Object; + T LoadAsset(string location, bool needInstance) where T : Object; /// /// 同步加载资源。 /// /// 资源的定位地址。 /// 父节点位置。 + /// 是否需要实例化。 /// 要加载资源的类型。 /// 资源实例。 - T LoadAsset(string location, Transform parent) where T : Object; + T LoadAsset(string location, Transform parent, bool needInstance) where T : Object; /// /// 同步加载资源。 @@ -239,7 +241,7 @@ namespace TEngine /// 资源类型。 /// 资源对象集合。 UniTask> LoadAssetsByTagAsync(string assetTag) where T : UnityEngine.Object; - + /// /// 异步加载场景。 /// @@ -248,7 +250,7 @@ namespace TEngine /// 加载完毕时是否主动挂起。 /// 优先级。 /// 异步加载场景句柄。 - SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false,int priority = 100); + SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100); /// /// 异步加载场景. @@ -266,9 +268,10 @@ namespace TEngine /// /// 资源定位地址。 /// 取消操作Token。 + /// 是否需要实例化。 /// 要加载资源的类型。 /// 异步资源实例。 - UniTask LoadAssetAsync(string location, CancellationToken cancellationToken = default) where T : Object; + UniTask LoadAssetAsync(string location, CancellationToken cancellationToken = default, bool needInstance = true) where T : Object; /// /// 异步加载游戏物体。 diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceManager.cs b/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceManager.cs index 63ee32e5..4fe4eada 100644 --- a/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceManager.cs +++ b/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceManager.cs @@ -90,6 +90,7 @@ namespace TEngine /// 资源缓存表容量。 /// public int ARCTableCapacity { get; set; } + #endregion #region 生命周期 @@ -101,10 +102,43 @@ namespace TEngine internal override void Shutdown() { + ReleaseAllHandle(); YooAssets.Destroy(); ResourcePool.Destroy(); } + private void ReleaseAllHandle() + { + var iter = _releaseMaps.Values.GetEnumerator(); + while (iter.MoveNext()) + { + AssetOperationHandle handle = iter.Current; + if (handle != null) + { + handle.Dispose(); + handle = null; + } + } + + iter.Dispose(); + _releaseMaps.Clear(); + + iter = _operationHandlesMaps.Values.GetEnumerator(); + while (iter.MoveNext()) + { + AssetOperationHandle handle = iter.Current; + if (handle != null) + { + handle.Dispose(); + handle = null; + } + } + + iter.Dispose(); + _operationHandlesMaps.Clear(); + _arcCacheTable = new ArcCacheTable(ARCTableCapacity, OnAddAsset, OnRemoveAsset); + } + #endregion #region 设置接口 @@ -140,23 +174,32 @@ namespace TEngine #endregion private Dictionary _releaseMaps; - + + private Dictionary _operationHandlesMaps; + private ArcCacheTable _arcCacheTable; - - private void OnAddAsset(string location,AssetOperationHandle handle) + + + private void OnAddAsset(string location, AssetOperationHandle handle) { + _operationHandlesMaps[location] = handle; if (_releaseMaps.ContainsKey(location)) { _releaseMaps.Remove(location); } } - private void OnRemoveAsset(string location,AssetOperationHandle handle) + private void OnRemoveAsset(string location, AssetOperationHandle handle) { + if (_operationHandlesMaps.ContainsKey(location)) + { + _operationHandlesMaps.Remove(location); + } + _releaseMaps[location] = handle; - GameModule.Resource.UnloadUnusedAssets(performGCCollect:false); + GameModule.Resource.UnloadUnusedAssets(performGCCollect: false); } - + /// /// 从缓存中获取同步资源句柄。 /// @@ -168,16 +211,17 @@ namespace TEngine AssetOperationHandle handle = null; // 尝试从从ARC缓存表取出对象。 handle = _arcCacheTable.GetCache(location); - + if (handle == null) { handle = YooAssets.LoadAssetSync(location); } + // 对象推入ARC缓存表。 _arcCacheTable.PutCache(location, handle); return handle; } - + /// /// 从缓存中获取异步资源句柄。 /// @@ -189,16 +233,17 @@ namespace TEngine AssetOperationHandle handle = null; // 尝试从从ARC缓存表取出对象。 handle = _arcCacheTable.GetCache(location); - + if (handle == null) { handle = YooAssets.LoadAssetAsync(location); } + // 对象推入ARC缓存表。 _arcCacheTable.PutCache(location, handle); return handle; } - + /// /// 初始化资源模块。 /// @@ -219,8 +264,9 @@ namespace TEngine } ResourcePool.Initialize(GameModule.Get().gameObject); - + _releaseMaps ??= new Dictionary(ARCTableCapacity); + _operationHandlesMaps ??= new Dictionary(ARCTableCapacity); _arcCacheTable ??= new ArcCacheTable(ARCTableCapacity, OnAddAsset, OnRemoveAsset); } @@ -277,7 +323,7 @@ namespace TEngine createParameters.RemoteServices = new RemoteServices(); initializationOperation = package.InitializeAsync(createParameters); } - + // WebGL运行模式 if (playMode == EPlayMode.WebPlayMode) { @@ -317,9 +363,10 @@ namespace TEngine handle = null; } } + iter.Dispose(); _releaseMaps.Clear(); - + if (DefaultPackage == null) { throw new GameFrameworkException("Package is invalid."); @@ -451,9 +498,10 @@ namespace TEngine /// 同步加载资源。 /// /// 资源的定位地址。 + /// 是否需要实例化。 /// 要加载资源的类型。 /// 资源实例。 - public T LoadAsset(string location) where T : Object + public T LoadAsset(string location, bool needInstance = true) where T : Object { if (string.IsNullOrEmpty(location)) { @@ -465,8 +513,13 @@ namespace TEngine if (typeof(T) == typeof(GameObject)) { - GameObject ret = handle.InstantiateSync(); - return ret as T; + if (needInstance) + { + GameObject ret = handle.InstantiateSync(); + return ret as T; + } + + return handle.AssetObject as T; } else { @@ -480,9 +533,10 @@ namespace TEngine /// /// 资源的定位地址。 /// 父节点位置。 + /// 是否需要实例化。 /// 要加载资源的类型。 /// 资源实例。 - public T LoadAsset(string location, Transform parent) where T : Object + public T LoadAsset(string location, Transform parent, bool needInstance = true) where T : Object { if (string.IsNullOrEmpty(location)) { @@ -494,8 +548,13 @@ namespace TEngine if (typeof(T) == typeof(GameObject)) { - GameObject ret = handle.InstantiateSync(parent); - return ret as T; + if (needInstance) + { + GameObject ret = handle.InstantiateSync(); + return ret as T; + } + + return handle.AssetObject as T; } else { @@ -542,7 +601,7 @@ namespace TEngine public T LoadAsset(string location, Transform parent, out AssetOperationHandle handle) where T : Object { handle = GetHandleSync(location); - + if (string.IsNullOrEmpty(location)) { Log.Error("Asset name is invalid."); @@ -610,14 +669,14 @@ namespace TEngine { return YooAssets.LoadSubAssetsSync(assetInfo); } - + /// /// 通过Tag加载资源对象集合。 /// /// 资源标识。 /// 资源类型。 /// 资源对象集合。 - public async UniTask>LoadAssetsByTagAsync(string assetTag) where T: UnityEngine.Object + public async UniTask> LoadAssetsByTagAsync(string assetTag) where T : UnityEngine.Object { LoadAssetsByTagOperation operation = new LoadAssetsByTagOperation(assetTag); YooAssets.StartOperation(operation); @@ -661,8 +720,9 @@ namespace TEngine /// /// 要加载的实例名称。 /// 取消操作Token。 + /// 是否需要实例化。 /// 资源实实例。 - public async UniTask LoadAssetAsync(string location, CancellationToken cancellationToken = default) where T : Object + public async UniTask LoadAssetAsync(string location, CancellationToken cancellationToken = default, bool needInstance = true) where T : Object { AssetOperationHandle handle = LoadAssetAsyncHandle(location); @@ -675,9 +735,13 @@ namespace TEngine if (typeof(T) == typeof(GameObject)) { - GameObject ret = handle.InstantiateSync(); + if (needInstance) + { + GameObject ret = handle.InstantiateSync(); + return ret as T; + } - return ret as T; + return handle.AssetObject as T; } else { diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceModule.cs b/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceModule.cs index 001f2c79..8a83b9a3 100644 --- a/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceModule.cs +++ b/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceModule.cs @@ -102,7 +102,7 @@ namespace TEngine /// 资源缓存表容量。 /// public int adaptiveReplacementCacheCapacity = 32; - + private IResourceManager m_ResourceManager; private AsyncOperation m_AsyncOperation = null; private bool m_ForceUnloadUnusedAssets = false; @@ -302,7 +302,7 @@ namespace TEngine { // YooAssets.ClearSandbox(); } - + /// /// 卸载资源。 /// @@ -311,7 +311,7 @@ namespace TEngine { m_ResourceManager.UnloadAsset(asset); } - + /// /// 预订执行释放未被使用的资源。 /// @@ -343,7 +343,7 @@ namespace TEngine m_LastUnloadUnusedAssetsOperationElapseSeconds += GameTime.unscaledDeltaTime; if (m_AsyncOperation == null && (m_ForceUnloadUnusedAssets || - m_LastUnloadUnusedAssetsOperationElapseSeconds >= maxUnloadUnusedAssetsInterval || + m_LastUnloadUnusedAssetsOperationElapseSeconds >= maxUnloadUnusedAssetsInterval || m_PreorderUnloadUnusedAssets && m_LastUnloadUnusedAssetsOperationElapseSeconds >= minUnloadUnusedAssetsInterval)) { Log.Info("Unload unused assets..."); @@ -448,11 +448,12 @@ namespace TEngine /// 同步加载资源。 /// /// 资源的定位地址。 + /// 是否需要实例化。 /// 要加载资源的类型。 /// 资源实例。 - public T LoadAsset(string location) where T : UnityEngine.Object + public T LoadAsset(string location, bool needInstance = true) where T : UnityEngine.Object { - return m_ResourceManager.LoadAsset(location); + return m_ResourceManager.LoadAsset(location, needInstance); } /// @@ -460,11 +461,12 @@ namespace TEngine /// /// 资源的定位地址。 /// 父节点位置。 + /// 是否需要实例化。 /// 要加载资源的类型。 /// 资源实例。 - public T LoadAsset(string location, Transform parent) where T : UnityEngine.Object + public T LoadAsset(string location, Transform parent, bool needInstance = true) where T : UnityEngine.Object { - return m_ResourceManager.LoadAsset(location, parent); + return m_ResourceManager.LoadAsset(location, parent, needInstance); } /// @@ -563,14 +565,14 @@ namespace TEngine return m_ResourceManager.LoadSubAssetsSync(assetInfo); } - + /// /// 通过Tag加载资源对象集合。 /// /// 资源标识。 /// 资源类型。 /// 资源对象集合。 - public async UniTask>LoadAssetsByTagAsync(string assetTag) where T: UnityEngine.Object + public async UniTask> LoadAssetsByTagAsync(string assetTag) where T : UnityEngine.Object { return await m_ResourceManager.LoadAssetsByTagAsync(assetTag); } @@ -608,11 +610,12 @@ namespace TEngine /// /// 资源的定位地址。 /// 取消操作Token。 + /// 是否需要实例化。 /// 要加载资源的类型。 /// 异步资源实例。 - public async UniTask LoadAssetAsync(string location, CancellationToken cancellationToken = default) where T : UnityEngine.Object + public async UniTask LoadAssetAsync(string location, CancellationToken cancellationToken = default, bool needInstance = true) where T : UnityEngine.Object { - return await m_ResourceManager.LoadAssetAsync(location, cancellationToken); + return await m_ResourceManager.LoadAssetAsync(location, cancellationToken, needInstance); } ///