為了可以讓對象復用,防止大量重復創建對象,導致資源浪費,使用對象池來管理。
/**
* 對象池
* @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;
})()
