import { Component, Node, Prefab, __private, director, instantiate } from 'cc'; export default class ObjectPool { private _inactives: Node[] = []; private _actives: Node[] = []; private _prefab: Prefab; private _expandable; public get countInactive() { return this._inactives.length; } public get countActive() { return this._actives.length; } public get countAll() { return this.countInactive + this.countActive; } constructor(prefab: Prefab, size: number, expandable = true) { this._expandable = expandable; this._prefab = prefab; for (let i = 0; i < size; ++i) { let obj = instantiate(this._prefab); // create node instance obj.active = false; this._inactives.push(obj); // populate your pool with put method } } public get(parent?: Node): Node; public get( parent?: Node, classConstructor?: | __private._types_globals__Constructor | __private._types_globals__AbstractedConstructor, ): T; public get( parent?: Node, classConstructor?: | __private._types_globals__Constructor | __private._types_globals__AbstractedConstructor, ): T | Node { let obj: Node = null; let p = parent || director.getScene(); if (this._inactives.length > 0) { // use size method to check if there're nodes available in the pool obj = this._inactives.pop(); obj.setParent(p); this._actives.push(obj); } else if (this._expandable) { // if not enough node in the pool, we call cc.instantiate to create node obj = instantiate(this._prefab); obj.setParent(p); this._actives.push(obj); } else { obj = this._actives.shift(); this._actives.push(obj); } obj.active = true; if (classConstructor) { return obj.getComponent(classConstructor); } return obj; } public release(obj: Node); public release(obj: T); public release(obj: T | Node) { if (obj instanceof Node) { obj.active = false; const index = this._actives.indexOf(obj); this._actives.splice(index, 1); this._inactives.push(obj); } else { obj.node.active = false; const index = this._actives.indexOf(obj.node); this._actives.splice(index, 1); this._inactives.push(obj.node); } } public clear() { this._inactives.forEach((obj) => obj.destroy()); this._inactives = []; this._actives = []; } }