Skip to content

Instantly share code, notes, and snippets.

@AimWhy
Created March 2, 2025 01:00
Show Gist options
  • Save AimWhy/5b8cf8385d0e32ba66d91e8a5770cd7c to your computer and use it in GitHub Desktop.
Save AimWhy/5b8cf8385d0e32ba66d91e8a5770cd7c to your computer and use it in GitHub Desktop.

Revisions

  1. AimWhy created this gist Mar 2, 2025.
    66 changes: 66 additions & 0 deletions ObjectPool.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,66 @@
    export interface IDisposable {
    dispose(): void;
    }

    export interface IReference<T> extends IDisposable {
    readonly object: T;
    }

    export interface IObjectData {
    getId(): unknown;
    }

    export interface IPooledObject<TData> extends IDisposable {
    setData(data: TData): void;
    }

    export class ObjectPool<TData extends IObjectData, T extends IPooledObject<TData>> implements IDisposable {
    private readonly _unused = new Set<T>();
    private readonly _used = new Set<T>();
    private readonly _itemData = new Map<T, TData>();

    constructor(
    private readonly _create: (data: TData) => T,
    private readonly retain: number = 5
    ) { }

    public getUnusedObj(data: TData): IReference<T> {
    let obj: T;

    if (this._unused.size === 0) {
    obj = this._create(data);
    this._itemData.set(obj, data);
    } else {
    const values = [...this._unused.values()];
    obj = values.find(obj => this._itemData.get(obj)!.getId() === data.getId()) ?? values[0];
    this._unused.delete(obj);
    this._itemData.set(obj, data);
    obj.setData(data);
    }

    this._used.add(obj);

    return {
    object: obj,
    dispose: () => {
    this._used.delete(obj);
    if (this._unused.size > this.retain) {
    obj.dispose();
    } else {
    this._unused.add(obj);
    }
    }
    };
    }

    dispose(): void {
    for (const obj of this._used) {
    obj.dispose();
    }
    for (const obj of this._unused) {
    obj.dispose();
    }
    this._used.clear();
    this._unused.clear();
    }
    }