66 lines
1.4 KiB
TypeScript
66 lines
1.4 KiB
TypeScript
export interface IPool {
|
|
use?(): any;
|
|
free?(): any;
|
|
}
|
|
export class Pool<T extends IPool> {
|
|
private _fn: () => T;
|
|
private _idx: number;
|
|
private _frees: T[];
|
|
|
|
public get freeCount() {
|
|
return this._frees.length;
|
|
}
|
|
|
|
constructor(fn: () => T, size: number) {
|
|
this._fn = fn;
|
|
this._idx = size - 1;
|
|
this._frees = new Array<T>(size);
|
|
|
|
for(let i=0; i<size; i++) {
|
|
this._frees[i] = fn();
|
|
}
|
|
}
|
|
|
|
public alloc(): T {
|
|
if(this._idx < 0) {
|
|
this._expand(Math.round(this._frees.length * 1.2) + 1);
|
|
}
|
|
const obj = this._frees[this._idx];
|
|
this._frees.splice(this._idx);
|
|
--this._idx;
|
|
|
|
obj.use && obj.use();
|
|
return obj;
|
|
}
|
|
|
|
public free(obj: T) {
|
|
++ this._idx;
|
|
obj.free && obj.free();
|
|
this._frees[this._idx] = obj;
|
|
}
|
|
|
|
public clear(fn: (obj: T) => void) {
|
|
for(let i=0; i<this._idx; i++) {
|
|
fn && fn(this._frees[i]);
|
|
}
|
|
this._frees.splice(0);
|
|
this._idx = -1;
|
|
}
|
|
|
|
|
|
private _expand(size: number) {
|
|
const old = this._frees;
|
|
this._frees = new Array(size);
|
|
|
|
const len = size - old.length;
|
|
for(let i=0; i<len; i++) {
|
|
this._frees[i] = this._fn();
|
|
}
|
|
|
|
for(let i=len,j=0; i<size; ++i, ++j) {
|
|
this._frees[i] = old[j];
|
|
}
|
|
|
|
this._idx += len;
|
|
}
|
|
} |