Last active
October 15, 2020 16:43
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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