123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- import { Prefab, Node, instantiate } from "cc";
- import { UIHelper } from "../common/UIHelper";
- import { Framework } from "../Framework";
- import { resLoader } from "../res/ResLoader";
- import { TimeUtil } from "../util/TimeUtil";
- import { NodeEx } from "./NodeEx";
- //一维节点池支持Prefab和Node模式
- export class NodePool {
- private _ready: boolean = false; //节点是否初始化完毕
- private _size: number = 10; //池大小
- private _res: Prefab | Node = null; //资源
- private _pool: Node[] = []; //节点列表
- private _clear_time: number = 120; //清理时间(秒)
- private _timer = -1; //定时器uuid
- private _reinforce = false; //是否是二维池
- /**
- * 初始化节点池
- * @param bundle 包名
- * @param url 路径
- * @param size 节点池大小
- * @param clear 节点池清理时间(秒)
- * @param calback 初始化成功回调
- * @param reinforce 是否是二维节点池
- */
- init(res: Prefab | Node, size: number, clear: number, reinforce?: boolean)
- init(bundle: string, url: string, size: number, clear: number, calback: Function, reinforce?: boolean)
- init() {
- if (this._pool.length > 0) {
- this.clear()
- }
- if(this._res && (this._res instanceof Prefab)){
- this._res.decRef();
- this._res = null;
- }
- this._pool = [];
- if (arguments) {
- if (arguments.length == 4) {
- this._ready = true;
- this._res = arguments[0];
- //如果res在Asset原型链上则引用计数+1
- if (this._res instanceof Prefab) {
- this._res.addRef();
- }
- this._size = arguments[1];
- this._clear_time = arguments[2];
- if (this._clear_time > 0) {
- this._timer = Framework.time.schedule(() => {
- this._clearPool();
- }, this._clear_time);
- }
- this._reinforce = arguments[3] ? arguments[3] : false;
- } else {
- this._size = arguments[2];
- this._clear_time = arguments[3];
- resLoader.load(arguments[0], arguments[1], Prefab, (error: Error, prefab: Prefab) => {
- if (error) {
- console.error(error);
- } else {
- this._res = prefab;
- this._res.addRef();
- this._ready = true;
- arguments[4] && arguments[4]();
- if (this._clear_time > 0) {
- this._timer = Framework.time.schedule(() => {
- this._clearPool();
- }, this._clear_time);
- }
- }
- });
- this._reinforce = arguments[5] ? arguments[5] : false;
- }
- }
- }
- private _clearPool() {
- if (this._ready) {
- let cur_time = TimeUtil.getTimeEx(0);
- this._pool.forEach((node, idx) => {
- if (cur_time - node.getComponent(NodeEx).useTime >= this._clear_time) {
- node.getComponent(NodeEx)?.unuse();
- node.destroy();
- this._pool.splice(idx, 1);
- }
- });
- }
- }
- /**
- * 设置节点池大小
- * @param size 大小
- */
- setPoolSize(size: number) {
- this._size = size;
- }
- /**
- * 获取节点
- * @param parent 父节点
- * @param val 自定义参数
- */
- getNode(parent: Node = null, ...val: any[]) {
- if (this._ready) {
- let node = ((this._pool.length > 0) ? this._pool.shift() : instantiate(this._res)) as Node;
- if (!node.isValid) {
- while (true) {
- node = ((this._pool.length > 0) ? this._pool.shift() : instantiate(this._res)) as Node;
- if (node.isValid) {
- break;
- }
- }
- }
- node.active = true;
- if (parent) {
- UIHelper.setLayer(node, parent.layer);
- parent.addChild(node);
- }
- //如果是二维池则由二维池调用
- let template = node.getComponent(NodeEx);
- (!this._reinforce) && template.reuse(...val);
- return template;
- }
- return null;
- }
- /**
- * 归还节点,如果节点池已满将被销毁
- */
- putNode(template: NodeEx) {
- if (template && template.isValid) {
- template.unuse();
- if (this._pool.length >= this._size) {
- template.node.destroy();
- } else {
- template.node.removeFromParent();
- template.useTime = TimeUtil.getTimeEx(0);
- template.node.active = false;
- this._pool.push(template.node);
- }
- }
- }
- /**
- * 清理节点池
- */
- clear() {
- (this._timer != -1) && Framework.time.unschedule(this._timer);
- // for (let node of this._pool) {
- // node.destroy();
- // }
- if (this._res) {
- // (this._res instanceof Prefab) ? this._res.decRef() : this._res.destroy();
- console.log("NodePool clear",(this._res && this._res.name));
- if(this._res instanceof Prefab) this._res.decRef() ;
- this._res = null;
- }
- this._pool = [];
- this._ready = false;
- (this._timer > 0) && Framework.time.unschedule(this._timer);
- this._timer = -1;
- }
- }
|