@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
122 lines (94 loc) • 2.87 kB
JavaScript
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