123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- using XGame.Framework.Memory;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Reflection;
- using XGame.Framework.Interfaces;
- namespace XGame.Framework
- {
- /// <summary>
- /// 非泛型对象池
- /// * 非线程安全
- /// </summary>
- public static partial class ObjectPool
- {
- static readonly Dictionary<Type, Stack<object>> 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();
- }
- /// <summary>
- /// 获取ReusableObject (需与Recycle成对)
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <returns></returns>
- public static T Acquire<T>() where T : class, IReference, new()
- {
- Type type = typeof(T);
- T instance = (T)Create(type);
- return instance;
- }
- /// <summary>
- /// 回收 (需与Acquire成对)
- /// </summary>
- /// <param name="obj"></param>
- 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<object>();
- 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}");
- }
- }
- }
|