Skip to content

Instantly share code, notes, and snippets.

@bartread
Last active October 15, 2020 16:43
Show Gist options
  • Save bartread/cc8ab828fa2d9a8a30eb6301cf6d7813 to your computer and use it in GitHub Desktop.
Save bartread/cc8ab828fa2d9a8a30eb6301cf6d7813 to your computer and use it in GitHub Desktop.
Simple JavaScript object pool implementation with some validation in place - depends on pinjector.js
(function () {
'use strict';
pinjector
.module('starCastle')
.factory(
'objectPool',
[
objectPool
]);
function objectPool() {
var service = {
createPool: createPool
};
var nextPoolId = 1;
return service;
function createPool(objectConstructor, objectTypeName) {
var freeList = [];
var liveObjectCount = 0;
var objectCount = 0;
var poolId = nextPoolId;
++nextPoolId;
var pool = {
create: create,
release: release,
getLiveObjectCount: getLiveObjectCount
};
return pool;
function create() {
var returnValue;
if (freeList.length > 0) {
returnValue = freeList.pop();
if (!returnValue.__creationCount) {
throw new Error("No creation count set on object retrieved from freeList - seems like it wasn't created by this pool");
}
++returnValue.__creationCount;
} else {
returnValue = objectConstructor();
returnValue.__poolId = poolId;
returnValue.__creationCount = 1;
++objectCount;
if (objectTypeName) {
returnValue.__name = objectTypeName + '-' + objectCount;
}
}
returnValue.isNew = true;
if (returnValue.__returnCount) {
returnValue.__returnCount--;
if (returnValue.__returnCount > 0) {
throw new Error('Somehow created an object with return value already > 0.');
}
}
++liveObjectCount;
return returnValue;
}
function release(object) {
if (!object) {
return;
} else if (!object.__poolId) {
throw new Error(
"Attempted to return object not created by an object pool.");
}
if (object.__poolId !== poolId) {
throw new Error(
"Object's pool ID " + object.__poolId + " does not match expected pool ID of " + poolId);
}
if (!object.__returnCount) {
object.__returnCount = 1;
} else {
if (object.__returnCount > 0) {
for (var index = 0, size = freeList.length; index < size; ++index) {
if (freeList[index] === object) {
throw new Error("Attempted to return object to pool that already exists in freeList at index " + index);
}
}
throw new Error("Attempted to return object to pool more than once but object does not exist in freeList.");
}
++object.__returnCount;
}
freeList.push(object);
--liveObjectCount;
if (liveObjectCount < 0) {
throw new Error("Attempted to return object to pool for which no live objects exist.");
}
}
function getLiveObjectCount() {
return liveObjectCount;
}
}
}
}());
/*
This code is licensed under the terms of the MIT License as described
in LICENSE.txt.
Copyright (c) 2015 - 2017 Bart Read, arcade.ly (https://arcade.ly),
and bartread.com Ltd (http://www.bartread.com/)
The objectPool service creates and manages object pools, which are a handy
way to avoid too much churn on the heap causing framerate issues on less
powerful devices.
Depends on pinjector.js, which can be found at:
https://gist.github.com/bartread/ee632195cdc1a40e5909abf05f96547e
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment