UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

122 lines (94 loc) 2.87 kB
import { assert } from "../../assert.js"; import { noop } from "../../function/noop.js"; /** * Object Pool pattern implementation. * Reuse objects instead of relying on garbage collector. Useful in cases where creating or destroying an object is costly, and objects are relatively short-lived * @template T */ export class ObjectPoolFactory { /** * @private * @type {Array<T>} */ pool = []; /** * @type {number} */ maxSize = 256; /** * @param {function():T} creator * @param {function(T)} destroyer * @param {function(T)} resetter */ constructor( creator, destroyer = noop, resetter = noop ) { assert.isFunction(creator, 'creator'); assert.isFunction(destroyer, 'destroyer'); assert.isFunction(resetter, 'resetter'); /** * @private * @type {function(): T} */ this.creator = creator; /** * @private * @type {function(T)} */ this.destroyer = destroyer; /** * @private * @type {function(T)} */ this.resetter = resetter; } /** * * @returns {T} */ get() { const pool = this.pool; if (pool.length > 0) { const oldInstance = pool.pop(); //reset the object this.resetter(oldInstance); assert.notNull(oldInstance, 'oldInstance'); assert.defined(oldInstance, 'oldInstance'); return oldInstance; } else { const newInstance = this.creator(); assert.notNull(newInstance, 'newInstance'); assert.defined(newInstance, 'newInstance'); return newInstance; } } /** * * @param {T} object * @returns {boolean} true if object was added back to the pool, false if pool was full and object was destroyed instead */ release(object) { assert.notNull(object, 'object'); assert.defined(object, 'object'); assert.isInstanceOf(this, ObjectPoolFactory, 'this'); const pool = this.pool; assert.arrayHasNo(pool, object, `Pool already contains object that is being attempted to be release`); if (pool.length >= this.maxSize) { //pool is too large, destroy and discard the object if (this.destroyer !== noop) { this.destroyer(object); } return false; } //add it to the pool pool.push(object); return true; } } /** * @deprecated use `get` instead * @type {function(): T} */ ObjectPoolFactory.prototype.create = ObjectPoolFactory.prototype.get