export default abstract class Pool<T>{
    private data: T[] = [];

    public get(): T {
        if (this.data.length > 0) {
            let e = this.data.pop();
            this.onElementInit(e);
            return e;
        } else {
            return this.createElement();
        }
    }

    public recycle(element: T) {
        this.onElementRecycle(element);
        this.data.push(element);
    }

    protected abstract onElementRecycle(element: T): void;
    protected abstract onElementInit(element: T): void;

    protected abstract createElement(): T;
}

export abstract class PoolGroup<T>{
    private data: {
        [key: string]: Pool<T>
    } = {};

    public get(key: string): T {
        return this.getValue(key).get();
    }

    public recycle(key: string, element: T) {

        this.getValue(key).recycle(element);
    }

    private getValue(key: string) {
        this.data[key] = this.data[key] || this.createPool(key);
        return this.data[key];
    }

    protected abstract createPool(key: string): Pool<T>;
}