TS 对象池


/**
 * 对象池泛型
 */
export class ObjPool {
    /** 数据类型 */
    protected objType;
    /** 对象池 */
    protected pool = [];
    /** 对象计数 */
    public objCount: number = 0;
    /** 初始化数量 */
    protected initNum: number = 0;
    /** 是否需要预填充对象 */
    protected poolMinSize: number = 0;
    /** 对象数量上限 */
    protected poolMaxSize: number = 50;

    public constructor(c: new () => T) {
        this.objType = c;
        this.pool.length = 0;
    }

    /**
     * 初始化
     * @param initNum 初始加载对象数
     * @param minSize 对象池最少对象数
     * @param maxSize 对象池最大对象数
     * maxSize一定大于minSize minSize最小为0
     */
    public init(initNum: number = 0, minSize: number = 0, maxSize: number = 50) {
        this.poolMinSize = Math.min(0, minSize);
        this.poolMaxSize = Math.max(maxSize, this.poolMinSize);
        this.preLoadObj(initNum);
    }

    /**
     * 回收
     */
    public push(obj: T) {
        this.pool.push(obj);
        if (this.objCount > this.poolMaxSize) {
            this.pool.unshift();
            return;
        }
        this.objCount++;
    }

    /**
     * 取对象
     */
    public pop(): T {
        if (this.objCount <= this.poolMinSize) {
            this.preLoadObj(this.poolMinSize)
        }
        this.objCount--;
        let item = this.pool.pop();
        // 这里再拿出的时候判断对象是否实现了IObjectReset接口,应为再拿完对象后一般需要把对象重置一下
        //这里提供了一个接口实现,具体是否需要看需求
        if (egret.is(item, "IObjectReset")) item.reset();
        return item;
    }

    /**
     * 预加载对象
     */
    private preLoadObj(num: number = this.poolMinSize) {
        let size = num ? num : this.poolMinSize;
        while (this.objCount <= size) {
            let item = new this.objType();
            this.pool.push(item);
            this.objCount++;
            // 如果池内对象数大于最大限制,只加载一个对象退出
            if (this.objCount > this.poolMaxSize) {
                return;
            }
        }
    }

    /**
     * 释放内存
     */
    public releaseAll() {
        this.pool.length = 0;
        this.objCount = 0;
    }
}
import { GDictionary } from "./GDictionary";
import { ObjPool } from "./ObjPool";

/**
 * 对象池管理类
 */
export class ObjPoolMgr {
    private static instance: ObjPoolMgr = null;
    public static get Instance(): ObjPoolMgr {
        if (this.instance == null) {
            this.instance = new ObjPoolMgr();
        }
        return this.instance;
    }
    private static pObjPoolDic: GDictionary> = new GDictionary>();

    constructor() { };

    public static getPool(c: new () => T): ObjPool {
        return ObjPoolMgr.Instance.get(c);
    }

    private get(c: new () => T): ObjPool {
        let key = c.prototype.__class__;
        let ret = ObjPoolMgr.pObjPoolDic[key];
        if (!ret) {
            ret = new ObjPool(c);
            ObjPoolMgr.pObjPoolDic[key] = ret;
        }
        return ret || null;
    }

    /**
     * 获取对象
     */
    public static getObject(c: new () => T): T {
        let pool = ObjPoolMgr.Instance.get(c);
        if (!pool) {
            return null;
        }
        return pool.pop();
    }

    /**
     * 回收
     */
    public static recyleObject(obj) {
        let key = egret.getQualifiedClassName(obj);
        if (this.pObjPoolDic.Has(key)) {
            this.pObjPoolDic.Get(key).push(obj);
        } else {
            let _constructor = obj.__proto__.constructor;
            if (_constructor) {
                ObjPoolMgr.Instance.get(_constructor).push(obj);
            }
        }
    }

    /**
     * 释放
     */
    public static releaseObjectPool(c: new () => T) {
        let key = c.prototype.__class__;
        if (this.pObjPoolDic.Has(key)) {
            this.pObjPoolDic.Get(key).releaseAll();
        }
    }

    /**
     * 释放全部
     */
    public static releaseAll() {
        let objPoolAry = ObjPoolMgr.pObjPoolDic.Values();
        for (let i = objPoolAry.length; i--; i) {
            objPoolAry[i].releaseAll();
        }
        ObjPoolMgr.pObjPoolDic.Clear();
    }
}
/**
  * 泛型字典类
  * let dictionary = new Dictionary(); // new一个对象
  * // 设置属性
  * dictionary.Set('gandalf', 'gandalf@email.com');
  * dictionary.Set('john', 'johnsnow@email.com');
  * dictionary.Set('tyrion', 'tyrion@email.com');
  * // 调用
  * console.log(dictionary.Size());
  * console.log(dictionary.Values());
  * console.log(dictionary.Get('tyrion'));
  */
 export class GDictionary {
    /**
     * 字典项目
     */
    private items = {}

    /**
     * 验证指定键是否在字典中
     * @param key 键
     * @returns 是否存在
     */
    public Has(key: string): boolean {
        return key in this.items
    }

    /**
     * 设置键值
     * @param key 键
     * @param value 值
     */
    public Set(key: string, value: T): void {
        this.items[key] = value
    }

    /**
     * 移除指定键
     * @param key 键
     * @returns 是否移除成功
     */
    public Remove(key: string): boolean {
        if (this.Has(key)) {
            delete this.items[key]
            return true
        }
        return false
    }

    /**
     * 查找特定键的值
     * @param key 键
     * @returns 值
     */
    public Get(key: string): T {
        return this.Has(key) ? this.items[key] : undefined
    }

    /**
     * 获取字典所有的键
     * @returns 键数组
     */
    public Keys(): Array {
        let values = new Array()//存到数组中返回
        for (let k in this.items) {
            if (this.Has(k)) {
                values.push(this.items[k])
            }
        }
        return values
    }

    /**
     * 获取字典所有的值
     * @returns 值数组
     */
    public Values(): Array {
        // 存到数组中返回
        let values = new Array()
        for (let k in this.items) {
            if (this.Has(k)) {
                values.push(this.items[k])
            }
        }
        return values
    }

    /**
     * 获取所有键值
     * @returns 键值对对象
     */
    public GetItems(): object {
        return this.items
    }

    /**
     * 清空字典
     */
    public Clear(): void {
        this.items = {}
    }

    /**
     * 获取字典大小
     * @returns 
     */
    public Size(): number {
        return Object.keys(this.items).length
    }
}