From cddb45b654ff9a5ec972cd121f02262c29ddd17a Mon Sep 17 00:00:00 2001 From: ALEXTANG <574809918@qq.com> Date: Sun, 4 Sep 2022 17:11:10 +0800 Subject: [PATCH] ObjectPool ObjectPool --- Assets/TEngine/EntryPrefab/TEngine.prefab | 45 ++++ .../Inspector/ObjectPoolManagerInspector.cs | 41 ++++ .../ObjectPoolManagerInspector.cs.meta | 11 + .../Core/Utility/Utility.GameObjectUtils.cs | 180 ++++++++++++++ .../Utility/Utility.GameObjectUtils.cs.meta | 3 + .../TEngine/Scripts/Runtime/ObjectPool.meta | 8 + .../Scripts/Runtime/ObjectPool/Helper.meta | 8 + .../Helper/DefaultObjectPoolHelper.cs | 221 ++++++++++++++++++ .../Helper/DefaultObjectPoolHelper.cs.meta | 11 + .../ObjectPool/Helper/IObjectPoolHelper.cs | 87 +++++++ .../Helper/IObjectPoolHelper.cs.meta | 11 + .../Runtime/ObjectPool/Helper/ObjectPool.cs | 106 +++++++++ .../ObjectPool/Helper/ObjectPool.cs.meta | 11 + .../Runtime/ObjectPool/ObjectPoolManager.cs | 129 ++++++++++ .../ObjectPool/ObjectPoolManager.cs.meta | 11 + 15 files changed, 883 insertions(+) create mode 100644 Assets/TEngine/Scripts/Editor/Inspector/ObjectPoolManagerInspector.cs create mode 100644 Assets/TEngine/Scripts/Editor/Inspector/ObjectPoolManagerInspector.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/Utility/Utility.GameObjectUtils.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/Utility/Utility.GameObjectUtils.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/ObjectPool.meta create mode 100644 Assets/TEngine/Scripts/Runtime/ObjectPool/Helper.meta create mode 100644 Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/DefaultObjectPoolHelper.cs create mode 100644 Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/DefaultObjectPoolHelper.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/IObjectPoolHelper.cs create mode 100644 Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/IObjectPoolHelper.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/ObjectPool.cs create mode 100644 Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/ObjectPool.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/ObjectPool/ObjectPoolManager.cs create mode 100644 Assets/TEngine/Scripts/Runtime/ObjectPool/ObjectPoolManager.cs.meta diff --git a/Assets/TEngine/EntryPrefab/TEngine.prefab b/Assets/TEngine/EntryPrefab/TEngine.prefab index 1246a00d..32d417cc 100644 --- a/Assets/TEngine/EntryPrefab/TEngine.prefab +++ b/Assets/TEngine/EntryPrefab/TEngine.prefab @@ -1,5 +1,49 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!1 &1672025513 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1672025514} + - component: {fileID: 1672025515} + m_Layer: 0 + m_Name: ObjectPool + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1672025514 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1672025513} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 3463045026180535779} + m_RootOrder: 6 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1672025515 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1672025513} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: bef095b963a40b54fa82ba105bd1e98e, type: 3} + m_Name: + m_EditorClassIdentifier: + Limit: 100 --- !u!1 &3463045025307533287 GameObject: m_ObjectHideFlags: 0 @@ -290,6 +334,7 @@ Transform: - {fileID: 3463045025836799505} - {fileID: 3463045026010536331} - {fileID: 3463045025307533286} + - {fileID: 1672025514} m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/TEngine/Scripts/Editor/Inspector/ObjectPoolManagerInspector.cs b/Assets/TEngine/Scripts/Editor/Inspector/ObjectPoolManagerInspector.cs new file mode 100644 index 00000000..d20f512b --- /dev/null +++ b/Assets/TEngine/Scripts/Editor/Inspector/ObjectPoolManagerInspector.cs @@ -0,0 +1,41 @@ +using TEngine.Runtime; +using UnityEditor; +using UnityEngine; + +namespace TEngine.Editor +{ + [CustomEditor(typeof(ObjectPoolManager))] + internal sealed class ObjectPoolManagerInspector : TEngineInspector + { + public override void OnInspectorGUI() + { + if (!EditorApplication.isPlaying) + { + EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info); + return; + } + + if (ObjectPoolManager.Instance.Helper.ObjectPools.Count == 0) + { + GUILayout.BeginHorizontal(); + GUILayout.Label("No Runtime Data!"); + GUILayout.EndHorizontal(); + } + + foreach (var pool in ObjectPoolManager.Instance.Helper.ObjectPools) + { + GUILayout.BeginHorizontal(); + GUILayout.Space(20); + GUILayout.Label(pool.Key + ": " + pool.Value.Count); + GUILayout.FlexibleSpace(); + GUI.enabled = pool.Value.Count > 0; + if (GUILayout.Button("Clear", EditorStyles.miniButton)) + { + pool.Value.Clear(); + } + GUI.enabled = true; + GUILayout.EndHorizontal(); + } + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Editor/Inspector/ObjectPoolManagerInspector.cs.meta b/Assets/TEngine/Scripts/Editor/Inspector/ObjectPoolManagerInspector.cs.meta new file mode 100644 index 00000000..7488aa47 --- /dev/null +++ b/Assets/TEngine/Scripts/Editor/Inspector/ObjectPoolManagerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a49fa7335fa305d4bbef4478b39ed39a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/Utility/Utility.GameObjectUtils.cs b/Assets/TEngine/Scripts/Runtime/Core/Utility/Utility.GameObjectUtils.cs new file mode 100644 index 00000000..2d21de83 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/Utility/Utility.GameObjectUtils.cs @@ -0,0 +1,180 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace TEngine.Runtime +{ + public static partial class Utility + { + /// + /// GameObject相关的实用函数。 + /// + public static class GameObjectUtils + { + #region Static Method + + /// + /// 克隆实例 + /// + /// 实例类型 + /// 初始对象 + /// 克隆的新对象 + public static T Clone(T original) where T : Object + { + return Object.Instantiate(original); + } + + /// + /// 克隆实例 + /// + /// 实例类型 + /// 初始对象 + /// 新对象的位置 + /// 新对象的旋转 + /// 克隆的新对象 + public static T Clone(T original, Vector3 position, Quaternion rotation) where T : Object + { + return Object.Instantiate(original, position, rotation); + } + + /// + /// 克隆实例 + /// + /// 实例类型 + /// 初始对象 + /// 新对象的位置 + /// 新对象的旋转 + /// 新对象的父物体 + /// 克隆的新对象 + public static T Clone(T original, Vector3 position, Quaternion rotation, Transform parent) + where T : Object + { + return Object.Instantiate(original, position, rotation, parent); + } + + /// + /// 克隆实例 + /// + /// 实例类型 + /// 初始对象 + /// 新对象的父物体 + /// 克隆的新对象 + public static T Clone(T original, Transform parent) where T : Object + { + return Object.Instantiate(original, parent); + } + + /// + /// 克隆实例 + /// + /// 实例类型 + /// 初始对象 + /// 新对象的父物体 + /// 是否保持世界位置不变 + /// 克隆的新对象 + public static T Clone(T original, Transform parent, bool worldPositionStays) where T : Object + { + return Object.Instantiate(original, parent, worldPositionStays); + } + + /// + /// 克隆 GameObject 实例 + /// + /// 初始对象 + /// 是否是UI对象 + /// 克隆的新对象 + public static GameObject CloneGameObject(GameObject original, bool isUI = false) + { + GameObject obj = Object.Instantiate(original); + obj.transform.SetParent(original.transform.parent); + if (isUI) + { + RectTransform rect = obj.rectTransform(); + RectTransform originalRect = original.rectTransform(); + rect.anchoredPosition3D = originalRect.anchoredPosition3D; + rect.sizeDelta = originalRect.sizeDelta; + rect.offsetMin = originalRect.offsetMin; + rect.offsetMax = originalRect.offsetMax; + rect.anchorMin = originalRect.anchorMin; + rect.anchorMax = originalRect.anchorMax; + rect.pivot = originalRect.pivot; + } + else + { + obj.transform.localPosition = original.transform.localPosition; + } + + obj.transform.localRotation = original.transform.localRotation; + obj.transform.localScale = original.transform.localScale; + obj.SetActive(true); + return obj; + } + + /// + /// 杀死实例 + /// + /// 实例对象 + public static void Kill(Object obj) + { + Object.Destroy(obj); + } + + /// + /// 立即杀死实例 + /// + /// 实例对象 + public static void KillImmediate(Object obj) + { + Object.DestroyImmediate(obj); + } + + /// + /// 杀死一群实例 + /// + /// 实例类型 + /// 实例集合 + public static void Kills(List objs) where T : Object + { + for (int i = 0; i < objs.Count; i++) + { + Object.Destroy(objs[i]); + } + + objs.Clear(); + } + + /// + /// 杀死一群实例 + /// + /// 实例类型 + /// 实例数组 + public static void Kills(T[] objs) where T : Object + { + for (int i = 0; i < objs.Length; i++) + { + Object.Destroy(objs[i]); + } + } + + #endregion + } + } + + public static class GameObjectExt + { + /// + /// 获取RectTransform组件 + /// + public static RectTransform rectTransform(this GameObject obj) + { + return obj.GetComponent(); + } + + /// + /// 获取RectTransform组件 + /// + public static RectTransform rectTransform(this MonoBehaviour mono) + { + return mono.GetComponent(); + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/Utility/Utility.GameObjectUtils.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/Utility/Utility.GameObjectUtils.cs.meta new file mode 100644 index 00000000..b896f02d --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/Utility/Utility.GameObjectUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8a631f70e55a4d419de768a51347edab +timeCreated: 1662280007 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/ObjectPool.meta b/Assets/TEngine/Scripts/Runtime/ObjectPool.meta new file mode 100644 index 00000000..1ad3cbea --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/ObjectPool.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 18905312db3bc3d448630110b4a9bcd3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper.meta b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper.meta new file mode 100644 index 00000000..cc235d82 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: eaa7867dbaa447e42b63eb98f3dd8687 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/DefaultObjectPoolHelper.cs b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/DefaultObjectPoolHelper.cs new file mode 100644 index 00000000..956da101 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/DefaultObjectPoolHelper.cs @@ -0,0 +1,221 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace TEngine.Runtime +{ + /// + /// 默认的对象池管理器助手 + /// + public sealed class DefaultObjectPoolHelper : IObjectPoolHelper + { + /// + /// 对象池默认上限 + /// + private int _limit; + + /// + /// 所有对象池 + /// + public Dictionary ObjectPools { get; private set; } = + new Dictionary(); + + /// + /// 初始化助手 + /// + public DefaultObjectPoolHelper() + { + _limit = ObjectPoolManager.Instance.Limit; + } + + /// + /// ShutDown + /// + public void ShutDown() + { + ClearAll(); + } + + /// + /// 注册对象池 + /// + /// 对象池名称 + /// 对象模板 + /// 对象生成时初始化委托 + /// 对象回收时处理委托 + /// 对象池上限,等于0时,表示使用默认值 + public void RegisterPool(string name, GameObject allocItem, Action onAlloc, + Action onRelease, int limit) + { + if (allocItem == null) + return; + + if (!ObjectPools.ContainsKey(name)) + { + ObjectPools.Add(name, new ObjectPool(allocItem, limit <= 0 ? _limit : limit, onAlloc, onRelease)); + } + else + { + Log.Error("注册对象池失败:已存在对象池 " + name + " !"); + } + } + + /// + /// 是否存在指定名称的对象池 + /// + /// 对象池名称 + /// 是否存在 + public bool IsExistPool(string name) + { + return ObjectPools.ContainsKey(name); + } + + /// + /// 移除已注册的对象池 + /// + /// 对象池名称 + public void UnRegisterPool(string name) + { + if (ObjectPools.ContainsKey(name)) + { + ObjectPools[name].Clear(); + ObjectPools.Remove(name); + } + else + { + Log.Error("移除对象池失败:不存在对象池 " + name + " !"); + } + } + + /// + /// 获取对象池中对象数量 + /// + /// 对象池名称 + /// 对象数量 + public int GetPoolCount(string name) + { + if (ObjectPools.ContainsKey(name)) + { + return ObjectPools[name].Count; + } + else + { + Log.Warning("获取对象数量失败:不存在对象池 " + name + " !"); + return 0; + } + } + + /// + /// 生成对象 + /// + /// 对象池名称 + /// 对象 + public GameObject Alloc(string name) + { + if (ObjectPools.ContainsKey(name)) + { + return ObjectPools[name].Alloc(); + } + else + { + Log.Error("生成对象失败:不存在对象池 " + name + " !"); + return null; + } + } + + /// + /// 回收对象 + /// + /// 对象池名称 + /// 对象 + public void Release(string name, GameObject target) + { + if (target == null) + return; + + if (ObjectPools.ContainsKey(name)) + { + ObjectPools[name].Release(target); + } + else + { + Log.Error("回收对象失败:不存在对象池 " + name + " !"); + } + } + + /// + /// 批量回收对象 + /// + /// 对象池名称 + /// 对象数组 + public void Releases(string name, GameObject[] targets) + { + if (targets == null) + return; + + if (ObjectPools.ContainsKey(name)) + { + for (int i = 0; i < targets.Length; i++) + { + ObjectPools[name].Release(targets[i]); + } + } + else + { + Log.Error("回收对象失败:不存在对象池 " + name + " !"); + } + } + + /// + /// 批量回收对象 + /// + /// 对象池名称 + /// 对象集合 + public void Releases(string name, List targets) + { + if (targets == null) + return; + + if (ObjectPools.ContainsKey(name)) + { + for (int i = 0; i < targets.Count; i++) + { + ObjectPools[name].Release(targets[i]); + } + + targets.Clear(); + } + else + { + Log.Error("回收对象失败:不存在对象池 " + name + " !"); + } + } + + /// + /// 清空指定的对象池 + /// + /// 对象池名称 + public void Clear(string name) + { + if (ObjectPools.ContainsKey(name)) + { + ObjectPools[name].Clear(); + } + else + { + Log.Error("清空对象池失败:不存在对象池 " + name + " !"); + } + } + + /// + /// 清空所有对象池 + /// + public void ClearAll() + { + foreach (var pool in ObjectPools) + { + pool.Value.Clear(); + } + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/DefaultObjectPoolHelper.cs.meta b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/DefaultObjectPoolHelper.cs.meta new file mode 100644 index 00000000..646e2226 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/DefaultObjectPoolHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f19a0d9040fd24439a22aa1b33b1752 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 701b9bfeb6deef341a599f8d0f1ec080, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/IObjectPoolHelper.cs b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/IObjectPoolHelper.cs new file mode 100644 index 00000000..84d3abd3 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/IObjectPoolHelper.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace TEngine.Runtime +{ + /// + /// 对象池管理器的助手接口 + /// + public interface IObjectPoolHelper + { + /// + /// 所有对象池 + /// + Dictionary ObjectPools { get; } + + /// + /// 注册对象池 + /// + /// 对象池名称 + /// 对象模板 + /// 对象生成时初始化委托 + /// 对象回收时处理委托 + /// 对象池上限,等于0时,表示使用默认值 + void RegisterPool(string name, GameObject allocItem, Action onAlloc, + Action onRelease, int limit); + + /// + /// 是否存在指定名称的对象池 + /// + /// 对象池名称 + /// 是否存在 + bool IsExistPool(string name); + + /// + /// 移除已注册的对象池 + /// + /// 对象池名称 + void UnRegisterPool(string name); + + /// + /// 获取对象池中对象数量 + /// + /// 对象池名称 + /// 对象数量 + int GetPoolCount(string name); + + /// + /// 生成对象 + /// + /// 对象池名称 + /// 对象 + GameObject Alloc(string name); + + /// + /// 回收对象 + /// + /// 对象池名称 + /// 对象 + void Release(string name, GameObject target); + + /// + /// 批量回收对象 + /// + /// 对象池名称 + /// 对象数组 + void Releases(string name, GameObject[] targets); + + /// + /// 批量回收对象 + /// + /// 对象池名称 + /// 对象集合 + void Releases(string name, List targets); + + /// + /// 清空指定的对象池 + /// + /// 对象池名称 + void Clear(string name); + + /// + /// 清空所有对象池 + /// + void ClearAll(); + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/IObjectPoolHelper.cs.meta b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/IObjectPoolHelper.cs.meta new file mode 100644 index 00000000..5c62b232 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/IObjectPoolHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f0af4beea5247d40a447b27c807de3a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 701b9bfeb6deef341a599f8d0f1ec080, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/ObjectPool.cs b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/ObjectPool.cs new file mode 100644 index 00000000..3a9a41f1 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/ObjectPool.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace TEngine.Runtime +{ + /// + /// 对象池 + /// + public sealed class ObjectPool + { + private readonly GameObject _allocItem; + private readonly int _limit = 100; + private readonly Queue _objectQueue = new Queue(); + private readonly Action _onAlloc; + private readonly Action _onRelease; + + /// + /// 对象数量 + /// + public int Count + { + get { return _objectQueue.Count; } + } + + /// + /// 构造函数对象池 + /// + /// + /// + /// + /// + public ObjectPool(GameObject allocItem, int limit, Action onAlloc, + Action onRelease) + { + _allocItem = allocItem; + _limit = limit; + _onAlloc = onAlloc; + _onRelease = onRelease; + } + + /// + /// 生成对象 + /// + /// 对象 + public GameObject Alloc() + { + GameObject obj; + if (_objectQueue.Count > 0) + { + obj = _objectQueue.Dequeue(); + } + else + { + obj = Utility.GameObjectUtils.CloneGameObject(_allocItem); + } + + obj.SetActive(true); + + obj.transform.SetParent(null); + + _onAlloc?.Invoke(obj); + + return obj; + } + + /// + /// 回收对象 + /// + /// 对象 + public void Release(GameObject obj) + { + if (_objectQueue.Count >= _limit) + { + _onRelease?.Invoke(obj); + + Utility.GameObjectUtils.Kill(obj); + } + else + { + obj.SetActive(false); + + _onRelease?.Invoke(obj); + + _objectQueue.Enqueue(obj); + + obj.transform.SetParent(ObjectPoolManager.Instance.gameObject.transform); + } + } + + /// + /// 清空所有对象 + /// + public void Clear() + { + while (_objectQueue.Count > 0) + { + GameObject obj = _objectQueue.Dequeue(); + if (obj) + { + Utility.GameObjectUtils.Kill(obj); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/ObjectPool.cs.meta b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/ObjectPool.cs.meta new file mode 100644 index 00000000..d1d11628 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/ObjectPool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 27382aff833de094e97dd246ad567aad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 701b9bfeb6deef341a599f8d0f1ec080, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/ObjectPool/ObjectPoolManager.cs b/Assets/TEngine/Scripts/Runtime/ObjectPool/ObjectPoolManager.cs new file mode 100644 index 00000000..e2843c3f --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/ObjectPool/ObjectPoolManager.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace TEngine.Runtime +{ + /// + /// 对象池管理器 + /// + public sealed class ObjectPoolManager : UnitySingleton + { + private IObjectPoolHelper _helper; + + public IObjectPoolHelper Helper => _helper; + + public override int Priority => -1; + + public override void Awake() + { + base.Awake(); + _helper = new DefaultObjectPoolHelper(); + } + + /// + /// 单个对象池上限 + /// + [SerializeField] internal int Limit = 100; + + /// + /// 注册对象池 + /// + /// 对象池名称 + /// 对象模板 + /// 对象生成时初始化委托 + /// 对象回收时处理委托 + /// 对象池上限,等于0时,表示使用默认值 + public void RegisterPool(string name, GameObject allocItem, Action onAlloc = null, + Action onRelease = null, int limit = 0) + { + _helper.RegisterPool(name, allocItem, onAlloc, onRelease, limit); + } + + /// + /// 是否存在指定名称的对象池 + /// + /// 对象池名称 + /// 是否存在 + public bool IsExistPool(string name) + { + return _helper.IsExistPool(name); + } + + /// + /// 移除已注册的对象池 + /// + /// 对象池名称 + public void UnRegisterPool(string name) + { + _helper.UnRegisterPool(name); + } + + /// + /// 获取对象池中对象数量 + /// + /// 对象池名称 + /// 对象数量 + public int GetPoolCount(string name) + { + return _helper.GetPoolCount(name); + } + + /// + /// 生成对象 + /// + /// 对象池名称 + /// 对象 + public GameObject Alloc(string name) + { + return _helper.Alloc(name); + } + + /// + /// 回收对象 + /// + /// 对象池名称 + /// 对象 + public void Release(string name, GameObject target) + { + _helper.Release(name, target); + } + + /// + /// 批量回收对象 + /// + /// 对象池名称 + /// 对象数组 + public void Releases(string name, GameObject[] targets) + { + _helper.Releases(name, targets); + } + + /// + /// 批量回收对象 + /// + /// 对象池名称 + /// 对象集合 + public void Releases(string name, List targets) + { + _helper.Releases(name, targets); + } + + /// + /// 清空指定的对象池 + /// + /// 对象池名称 + public void Clear(string name) + { + _helper.Clear(name); + } + + /// + /// 清空所有对象池 + /// + public void ClearAll() + { + _helper.ClearAll(); + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/ObjectPool/ObjectPoolManager.cs.meta b/Assets/TEngine/Scripts/Runtime/ObjectPool/ObjectPoolManager.cs.meta new file mode 100644 index 00000000..fccde163 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/ObjectPool/ObjectPoolManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bef095b963a40b54fa82ba105bd1e98e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: