PoolManager.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { Node, NodePool, Prefab, instantiate, resources } from "cc";
  2. /**
  3. * 对象池管理器
  4. * 用于创建和管理对象池
  5. */
  6. export default class PoolManager {
  7. private static pools: { [key: string]: NodePool } = {};
  8. private static prefabPath: string = 'prefab/element/';
  9. private static maxPoolSize: number = 100; // 默认最大对象池容量
  10. /**
  11. * 获取对象
  12. * @param prefabName 预制体名称
  13. * @param savedComponents 需要保存属性的组件数组
  14. * @returns Promise<Node | null> 获取到的对象,如果对象池中没有可用对象则返回 null
  15. */
  16. public static async getObject(prefabName: string, savedComponents?: Function[]): Promise<Node | null> {
  17. const pool = this.pools[prefabName];
  18. if (!pool || pool.size() === 0) {
  19. const obj = await this.createNewObject(prefabName);
  20. if (obj && savedComponents) {
  21. this.resetComponents(obj, savedComponents);
  22. }
  23. return obj;
  24. }
  25. const obj = pool.get();
  26. if (savedComponents) {
  27. this.resetComponents(obj, savedComponents);
  28. }
  29. return obj;
  30. }
  31. /**
  32. * 将对象放回对象池
  33. * @param prefabName 预制体名称
  34. * @param obj 对象
  35. */
  36. public static putObject(prefabName: string, obj: Node) {
  37. let pool = this.pools[prefabName];
  38. if (!pool) {
  39. pool = new NodePool();
  40. this.pools[prefabName] = pool;
  41. }
  42. if (pool.size() < this.maxPoolSize) {
  43. pool.put(obj);
  44. } else {
  45. obj.destroy(); // 超出容量限制时销毁对象
  46. }
  47. }
  48. /**
  49. * 创建新的对象
  50. * @param prefabName 预制体名称
  51. * @returns Promise<Node | null> 创建的对象,如果加载预制体失败则返回 null
  52. */
  53. private static createNewObject(prefabName: string): Promise<Node | null> {
  54. return new Promise((resolve, reject) => {
  55. const prefabPath = `${this.prefabPath}${prefabName}`;
  56. resources.load(prefabPath, Prefab, (error, prefab) => {
  57. if (error) {
  58. console.warn(`无法加载预制体 "${prefabName}",请检查预制体路径`);
  59. resolve(null);
  60. return;
  61. }
  62. const obj = instantiate(prefab);
  63. resolve(obj);
  64. });
  65. });
  66. }
  67. /**
  68. * 重置对象的组件属性
  69. * @param obj 需要重置的对象
  70. * @param savedComponents 需要重置的组件数组
  71. */
  72. private static resetComponents(obj: Node, savedComponents: Function[]) {
  73. savedComponents.forEach(resetFn => resetFn(obj));
  74. }
  75. /**
  76. * 设置对象池最大容量
  77. * @param maxSize 最大容量
  78. */
  79. public static setMaxPoolSize(maxSize: number) {
  80. this.maxPoolSize = maxSize;
  81. }
  82. /**
  83. * 设置预制体的资源路径
  84. * @param path 资源路径
  85. */
  86. public static setPrefabPath(path: string) {
  87. this.prefabPath = path;
  88. }
  89. }