ObjectPool.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. using XGame.Framework.Memory;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.Reflection;
  6. using XGame.Framework.Interfaces;
  7. namespace XGame.Framework
  8. {
  9. /// <summary>
  10. /// 非泛型对象池
  11. /// * 非线程安全
  12. /// </summary>
  13. public static partial class ObjectPool
  14. {
  15. static readonly Dictionary<Type, Stack<object>> pool = new();
  16. const int CACHE_LIMIT = 32;
  17. internal static void Initialize()
  18. {
  19. MemoryMonitor.Register(Clear);
  20. }
  21. internal static void Dispose()
  22. {
  23. pool.Clear();
  24. MemoryMonitor.UnRegister(Clear);
  25. }
  26. public static void Clear()
  27. {
  28. pool.Clear();
  29. }
  30. /// <summary>
  31. /// 获取ReusableObject (需与Recycle成对)
  32. /// </summary>
  33. /// <typeparam name="T"></typeparam>
  34. /// <returns></returns>
  35. public static T Acquire<T>() where T : class, IReference, new()
  36. {
  37. Type type = typeof(T);
  38. T instance = (T)Create(type);
  39. return instance;
  40. }
  41. /// <summary>
  42. /// 回收 (需与Acquire成对)
  43. /// </summary>
  44. /// <param name="obj"></param>
  45. public static void Recycle(IReference obj)/* where T : class, IReference, new()*/
  46. {
  47. Assert.IsNotNull(obj, $"ObjectPool.Recycle: args不能为null");
  48. var type = obj.GetType();
  49. Assert.IsNotNull(type);
  50. Assert.IsFalse(type.IsInterface, $"ObjectPool.Recycle: type不能是接口, type: {type.FullName}");
  51. Assert.IsFalse(type.IsValueType, $"ObjectPool.Recycle: type不能是值类型, type: {type.FullName}");
  52. Assert.IsFalse(type.IsEnum, $"ObjectPool.Recycle: type不能是枚举, type: {type.FullName}");
  53. Assert.IsFalse(type.IsAbstract, $"ObjectPool.Recycle: type不能是抽象类, type: {type.FullName}");
  54. Assert.IsFalse(type.IsGenericType, $"ObjectPool.Recycle: type不能是泛型类型, type: {type.FullName}");
  55. Assert.IsFalse(type.IsGenericTypeDefinition, $"ObjectPool.Recycle: type不能是泛型定义类型, type: {type.FullName}");
  56. Assert.IsFalse(type.IsArray, $"ObjectPool.Recycle: type不能是数组, type: {type.FullName}");
  57. Assert.IsFalse(type.IsPointer, $"ObjectPool.Recycle: type不能是指针, type: {type.FullName}");
  58. Assert.IsTrue(type.IsClass, $"ObjectPool.Recycle: type不是Class, type: {type.FullName}");
  59. CheckConstructor(type);
  60. if (!pool.TryGetValue(type, out var stack))
  61. {
  62. stack = new Stack<object>();
  63. pool.Add(type, stack);
  64. }
  65. obj.Clear();
  66. if (stack.Count >= CACHE_LIMIT)
  67. stack.Clear();
  68. else if (stack.Contains(obj))
  69. {
  70. Log.Error($"ObjectPool.Recycle 重复回收, type: {type.FullName}");
  71. return;
  72. }
  73. stack.Push(obj);
  74. }
  75. static object Create(Type type)
  76. {
  77. Assert.IsNotNull(type);
  78. Assert.IsFalse(type.IsInterface, $"ObjectPool.AutoCreate: type不能是接口, type: {type.FullName}");
  79. Assert.IsFalse(type.IsValueType, $"ObjectPool.AutoCreate: type不能是值类型, type: {type.FullName}");
  80. Assert.IsFalse(type.IsEnum, $"ObjectPool.AutoCreate: type不能是枚举, type: {type.FullName}");
  81. Assert.IsFalse(type.IsAbstract, $"ObjectPool.AutoCreate: type不能是抽象类, type: {type.FullName}");
  82. Assert.IsFalse(type.IsGenericType, $"ObjectPool.AutoCreate: type不能是泛型类型, type: {type.FullName}");
  83. Assert.IsFalse(type.IsGenericTypeDefinition, $"ObjectPool.AutoCreate: type不能是泛型定义类型, type: {type.FullName}");
  84. Assert.IsFalse(type.IsArray, $"ObjectPool.AutoCreate: type不能是数组, type: {type.FullName}");
  85. Assert.IsFalse(type.IsPointer, $"ObjectPool.AutoCreate: type不能是指针, type: {type.FullName}");
  86. Assert.IsTrue(type.IsClass, $"ObjectPool.AutoCreate: type不是Class, type: {type.FullName}");
  87. CheckConstructor(type);
  88. if (pool.ContainsKey(type))
  89. {
  90. var stack = pool[type];
  91. if (stack.Count > 0)
  92. return stack.Pop();
  93. }
  94. return Activator.CreateInstance(type);
  95. }
  96. [Conditional(MacroDefine.DEBUG), Conditional(MacroDefine.UNITY_EDITOR)]
  97. static void CheckConstructor(Type type)
  98. {
  99. BindingFlags flag = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
  100. Type[] args = new Type[] { };
  101. var ctor_0 = type.GetConstructor(flag, null, args, null);
  102. if (ctor_0 == null)
  103. throw new InvalidOperationException($"Error: These is no parameter constructor at: {type.FullName}");
  104. }
  105. }
  106. }