Skip to content

Commit

Permalink
refactor: prevent duplicate instances to be added to pool
Browse files Browse the repository at this point in the history
  • Loading branch information
hornta committed Aug 6, 2024
1 parent a7b9094 commit 30b63f2
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
11 changes: 11 additions & 0 deletions packages/melonjs/src/system/pool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ test("can release objects from the pool", () => {
expect(pool.used()).toBe(1);
});

test("can not release instance that already exist in pool", () => {
const pool = createPool(() => {
return { instance: new GameObject() };
});
const object1 = pool.get();
pool.release(object1);
expect(() => {
pool.release(object1);
}).toThrow();
});

test("can manually purge", () => {
const pool = createPool(() => {
return { instance: new GameObject() };
Expand Down
20 changes: 15 additions & 5 deletions packages/melonjs/src/system/pool.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
const takeFromSet = <T>(set: Set<T>) => {
for (const value of set) {
set.delete(value);
return value;
}
};

export interface Pool<T, A extends unknown[]> {
get(...args: A): T;
release(object: T): void;
Expand All @@ -16,7 +23,7 @@ export interface CreatePoolOptions<T, A extends unknown[]> {
export const createPool = <T, A extends unknown[]>(
options: (...args: A) => CreatePoolOptions<T, A>,
): Pool<T, A> => {
const available: T[] = [];
const available = new Set<T>();
const instanceResetMethods = new Map<T, Reset<A>>();
let inUse: number = 0;

Expand All @@ -26,15 +33,18 @@ export const createPool = <T, A extends unknown[]>(
* @param instance The object to release.
*/
release: (instance: T) => {
available.push(instance);
if (available.has(instance)) {
throw new Error("Instance is already in pool.");
}
available.add(instance);
inUse--;
},
/**
* get an instance from the pool
* @param args The arguments for creating the instance.
*/
get: (...args) => {
const object = available.pop();
const object = takeFromSet(available);
if (object) {
const reset = instanceResetMethods.get(object);
reset?.(...args);
Expand All @@ -51,14 +61,14 @@ export const createPool = <T, A extends unknown[]>(
* purge the pool
*/
purge: () => {
available.length = 0;
available.clear();
inUse = 0;
},
/**
* get the current size of the pool (how many objects are available)
*/
size: () => {
return available.length;
return available.size;
},
/**
* get the number of objects currently in use
Expand Down

0 comments on commit 30b63f2

Please sign in to comment.