/** * ObjectPool.js * Generic object pool for reusing frequently created/destroyed objects * (bullets, explosions, etc.) to avoid GC pressure in WeChat mini game. */ class ObjectPool { /** * @param {Function} createFn - Factory function that returns a new object instance. * @param {Function} [resetFn] - Optional function to reset an object before reuse. * @param {number} [initialSize=0] - Number of objects to pre-allocate. */ constructor(createFn, resetFn, initialSize = 0) { this._createFn = createFn; this._resetFn = resetFn || null; this._pool = []; this._activeCount = 0; // Pre-allocate for (let i = 0; i < initialSize; i++) { this._pool.push(this._createFn()); } } /** * Get an object from the pool. Creates a new one if pool is empty. * @returns {*} A reusable object instance. */ get() { let obj; if (this._pool.length > 0) { obj = this._pool.pop(); } else { obj = this._createFn(); } if (this._resetFn) { this._resetFn(obj); } this._activeCount++; return obj; } /** * Return an object back to the pool for future reuse. * @param {*} obj - The object to recycle. */ put(obj) { if (obj) { this._pool.push(obj); this._activeCount = Math.max(0, this._activeCount - 1); } } /** * Pre-allocate a number of objects into the pool. * @param {number} count */ preAllocate(count) { for (let i = 0; i < count; i++) { this._pool.push(this._createFn()); } } /** * Clear the pool entirely. */ clear() { this._pool.length = 0; this._activeCount = 0; } /** Number of objects currently in the pool (idle). */ get size() { return this._pool.length; } /** Number of objects currently in use. */ get activeCount() { return this._activeCount; } } module.exports = ObjectPool;