using XGame.Framework.Memory; using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using XGame.Framework.Interfaces; namespace XGame.Framework { /// /// 非泛型对象池 /// * 非线程安全 /// public static partial class ObjectPool { static readonly Dictionary> pool = new(); const int CACHE_LIMIT = 32; internal static void Initialize() { MemoryMonitor.Register(Clear); } internal static void Dispose() { pool.Clear(); MemoryMonitor.UnRegister(Clear); } public static void Clear() { pool.Clear(); } /// /// 获取ReusableObject (需与Recycle成对) /// /// /// public static T Acquire() where T : class, IReference, new() { Type type = typeof(T); T instance = (T)Create(type); return instance; } /// /// 回收 (需与Acquire成对) /// /// public static void Recycle(IReference obj)/* where T : class, IReference, new()*/ { Assert.IsNotNull(obj, $"ObjectPool.Recycle: args不能为null"); var type = obj.GetType(); Assert.IsNotNull(type); Assert.IsFalse(type.IsInterface, $"ObjectPool.Recycle: type不能是接口, type: {type.FullName}"); Assert.IsFalse(type.IsValueType, $"ObjectPool.Recycle: type不能是值类型, type: {type.FullName}"); Assert.IsFalse(type.IsEnum, $"ObjectPool.Recycle: type不能是枚举, type: {type.FullName}"); Assert.IsFalse(type.IsAbstract, $"ObjectPool.Recycle: type不能是抽象类, type: {type.FullName}"); Assert.IsFalse(type.IsGenericType, $"ObjectPool.Recycle: type不能是泛型类型, type: {type.FullName}"); Assert.IsFalse(type.IsGenericTypeDefinition, $"ObjectPool.Recycle: type不能是泛型定义类型, type: {type.FullName}"); Assert.IsFalse(type.IsArray, $"ObjectPool.Recycle: type不能是数组, type: {type.FullName}"); Assert.IsFalse(type.IsPointer, $"ObjectPool.Recycle: type不能是指针, type: {type.FullName}"); Assert.IsTrue(type.IsClass, $"ObjectPool.Recycle: type不是Class, type: {type.FullName}"); CheckConstructor(type); if (!pool.TryGetValue(type, out var stack)) { stack = new Stack(); pool.Add(type, stack); } obj.Clear(); if (stack.Count >= CACHE_LIMIT) stack.Clear(); else if (stack.Contains(obj)) { Log.Error($"ObjectPool.Recycle 重复回收, type: {type.FullName}"); return; } stack.Push(obj); } static object Create(Type type) { Assert.IsNotNull(type); Assert.IsFalse(type.IsInterface, $"ObjectPool.AutoCreate: type不能是接口, type: {type.FullName}"); Assert.IsFalse(type.IsValueType, $"ObjectPool.AutoCreate: type不能是值类型, type: {type.FullName}"); Assert.IsFalse(type.IsEnum, $"ObjectPool.AutoCreate: type不能是枚举, type: {type.FullName}"); Assert.IsFalse(type.IsAbstract, $"ObjectPool.AutoCreate: type不能是抽象类, type: {type.FullName}"); Assert.IsFalse(type.IsGenericType, $"ObjectPool.AutoCreate: type不能是泛型类型, type: {type.FullName}"); Assert.IsFalse(type.IsGenericTypeDefinition, $"ObjectPool.AutoCreate: type不能是泛型定义类型, type: {type.FullName}"); Assert.IsFalse(type.IsArray, $"ObjectPool.AutoCreate: type不能是数组, type: {type.FullName}"); Assert.IsFalse(type.IsPointer, $"ObjectPool.AutoCreate: type不能是指针, type: {type.FullName}"); Assert.IsTrue(type.IsClass, $"ObjectPool.AutoCreate: type不是Class, type: {type.FullName}"); CheckConstructor(type); if (pool.ContainsKey(type)) { var stack = pool[type]; if (stack.Count > 0) return stack.Pop(); } return Activator.CreateInstance(type); } [Conditional(MacroDefine.DEBUG), Conditional(MacroDefine.UNITY_EDITOR)] static void CheckConstructor(Type type) { BindingFlags flag = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly; Type[] args = new Type[] { }; var ctor_0 = type.GetConstructor(flag, null, args, null); if (ctor_0 == null) throw new InvalidOperationException($"Error: These is no parameter constructor at: {type.FullName}"); } } }