在游戏开发中,对内存的优化非常重要,是一个游戏性能优化的核心。而对象池的使用对于游戏中内存的优化至关重要。对象的频繁创建与回收对应游戏的性能和运行效率会有很大的影响。
所以合理使用对象池,对应游戏性能优化来说是比较重要的一个环节。下面分享一个在游戏通用的
对象池实现方法。
ES6的代码实现
class Pool{
/**对象存储数据*/
static _poolDic = {};
/**是否在对象池中标志*/
static InPool = "InPool";
/**类id计数器*/
static _CLSID = 0;
/**
获取某个类的的对象池列表
@param:sign 类的名字标识
*/
static getPoolBySign(sign){
return Pool._poolDic[sign] || (Pool._poolDic[sign] = []);
}
/**清除某个类的对象池*/
static clearBySign(sign) {
if (Pool._poolDic[sign])
Pool._poolDic[sign].length = 0;
}
/**对象回收到对象池*/
static recover(sign, item) {
if (item[Pool.InPool])
return;
item[Pool.InPool] = true;
Pool.getPoolBySign(sign).push(item);
}
/**从对象池取出某个类的对象*/
static getItemByClass(sign, cls) {
if (!Pool._poolDic[sign])
return new cls();
var pool = Pool.getPoolBySign(sign);
if (pool.length) {
var rst = pool.pop();
rst[Pool.InPool] = false;
}
else {
rst = new cls();
}
return rst;
}
/**回收对象实例*/
static recoverByClass(instance) {
if (instance) {
var className = instance.constructor["__className"] ||instance.constructor._$gid;
if (className)
Pool.recover(className, instance);
}
}
/**获取类的标识*/
static _getClassSign(cla) {
if (!cla["__className"]) cla["__className"] = cla["name"]; // 使用class.name
var className = cla["__className"] || cla["_$gid"];
if (!className) {
cla["_$gid"] = className = Pool._CLSID + "";
Pool._CLSID++;
}
return className;
}
/**根据类获取对象*/
static createByClass(cls) {
return Pool.getItemByClass(Pool._getClassSign(cls), cls);
}
/**从对象池获取类标识对象,如果对象池没有对象,不创建*/
static getItem(sign) {
var pool = Pool.getPoolBySign(sign);
var it = pool.length ? pool.pop() : null;
if (it) {
it[Pool.InPool] = false;
}
return it;
}
}
ES5的代码实现:
var Pool = (function () {
// 静态属性
var _poolDic = {};
var InPool = "InPool";
var _CLSID = 0;
// 静态类构造函数(模拟)
function Pool() {
throw new Error("Pool can't be instantiated.");
}
// 获取某个类的的对象池列表
Pool.getPoolBySign = function (sign) {
return _poolDic[sign] || (_poolDic[sign] = []);
};
// 清除某个类的对象池
Pool.clearBySign = function (sign) {
if (_poolDic[sign])
_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) {
if (!Pool._poolDic[sign]) return new cls();
var pool = Pool.getPoolBySign(sign);
var rst;
if (pool.length) {
rst = pool.pop();
rst[InPool] = false;
} else {
rst = new cls();
}
return rst;
};
// 回收对象实例
Pool.recoverByClass = function (instance) {
if (instance) {
var className = instance.constructor["__className"] || instance.constructor._$gid;
if (className)
Pool.recover(className, instance);
}
};
// 获取类的标识
Pool._getClassSign = function (cla) {
if (!cla["__className"]) {
cla["__className"] = cla.name || ("Class_" + (_CLSID++));
}
var className = cla["__className"] || cla._$gid;
if (!className) {
cla._$gid = className = "Class_" + (_CLSID++);
}
return className;
};
// 根据类获取对象
Pool.createByClass = function (cls) {
return Pool.getItemByClass(Pool._getClassSign(cls), cls);
};
// 从对象池获取类标识对象,如果对象池没有对象,不创建
Pool.getItem = function (sign) {
var pool = Pool.getPoolBySign(sign);
var it = pool.length ? pool.pop() : null;
if (it) {
it[InPool] = false;
}
return it;
};
return Pool;
})();