Egret中的对象池Pool

为了可以让对象复用,防止大量重复创建对象,导致资源浪费,使用对象池来管理。

/**
 * 对象池
 * @author chenkai 2019.10.25
 */
class Pool {
    private static poolMap = {};

    /**
     * 根据签名获取对象
     * @param sign 签名
     * @param clz 类名,对象池空,则根据类名创建新对象
     */
    public static getItemBySign(sign:string,clz:any){
        let pool = (this.poolMap[sign] || (this.poolMap[sign] = []));
        if (pool.length) {
            return pool.pop();
        }
        let obj: any = new clz();
        obj.poolKey = sign;
        return obj;
    }
    
    /**
     * 获取对象
     * @param clz 对象类名
     * @param args
     */
    public static getItemByClass(clz: any) {
        let clzName = clz.prototype["__class__"];
        return this.getItemBySign(clzName, clz);
    }

    /**
     * 根据签名回收对象
     * @param sign 签名
     * @param ins 对象实例
     */
    public static recoverBySign(sign:string, ins:any){
        this.poolMap[sign] && this.poolMap[sign].push(ins);
    }

    /**
     * 回收对象
     * @param ins 对象实例
     */
    public static recoverByIns(ins: any) {
        this.recoverBySign(ins.poolKey, ins);
    }

    /**
     * 根据签名清理对象
     * @param sign 签名
     */
    public static clearBySign(sign:string){
        let pool = this.poolMap[sign];
        if(pool){
            let len = pool.length;
            for(let i=0;i<len;i++){
                pool[i].destroy && pool[i].destroy();
            }
            pool.length = 0;
            delete this.poolMap[sign];
        }
    }

    /**
     * 清理对象。对象会执行destroy。
     * @param clz 对象类名
     */
    public static clearByClass(clz: any) {
        let clzName = clz.prototype["__class__"];
        this.clearBySign(clzName);
    }

    

    /**清理所有对象 */
    public static clearAll(){
        for(let key in this.poolMap){
           this.clearBySign(key);
        } 
    }

}

  

//获取一个Ball
let ball:Ball = Pool.getItemByClass(Ball);

//回收一个Ball
Pool.recoverByIns(ball);

 

以下是Laya的对象池源码,可以参考学习下

/**
*<p> <code>Pool</code> 是对象池类,用于对象的存贮、重复使用。</p>
*<p>合理使用对象池,可以有效减少对象创建的开销,避免频繁的垃圾回收,从而优化游戏流畅度。</p>
*/
//class laya.utils.Pool
var Pool=(function(){
    function Pool(){}
    __class(Pool,'laya.utils.Pool');
    Pool.getPoolBySign=function(sign){
        return Pool._poolDic[sign] || (Pool._poolDic[sign]=[]);
    }
 
    Pool.clearBySign=function(sign){
        if (Pool._poolDic[sign])Pool._poolDic[sign].length=0;
    }
 
    Pool.recover=function(sign,item){
        if (item["__InPool"])return;
        item["__InPool"]=true;
        Pool.getPoolBySign(sign).push(item);
    }
 
    Pool.getItemByClass=function(sign,cls){
        var pool=Pool.getPoolBySign(sign);
        var rst=pool.length ? pool.pop():new cls();
        rst["__InPool"]=false;
        return rst;
    }
 
    Pool.getItemByCreateFun=function(sign,createFun){
        var pool=Pool.getPoolBySign(sign);
        var rst=pool.length ? pool.pop():createFun();
        rst["__InPool"]=false;
        return rst;
    }
 
    Pool.getItem=function(sign){
        var pool=Pool.getPoolBySign(sign);
        var rst=pool.length ? pool.pop():null;
        if (rst){
            rst["__InPool"]=false;
        }
        return rst;
    }
 
    Pool._poolDic={};
    Pool.InPoolSign="__InPool";
    return Pool;
})()

  

 

原文地址:https://www.cnblogs.com/gamedaybyday/p/6083164.html