pinball/assets/_Game/Scripts/Pool/ObjectPool.ts

91 lines
2.8 KiB
TypeScript

import { Component, Node, Prefab, __private, director, instantiate } from 'cc';
export default class ObjectPool {
private _inactives: Node[] = [];
private _actives: Node[] = [];
private _prefab: Prefab;
private _expandable;
public get countInactive() {
return this._inactives.length;
}
public get countActive() {
return this._actives.length;
}
public get countAll() {
return this.countInactive + this.countActive;
}
constructor(prefab: Prefab, size: number, expandable = true) {
this._expandable = expandable;
this._prefab = prefab;
for (let i = 0; i < size; ++i) {
let obj = instantiate(this._prefab); // create node instance
obj.active = false;
this._inactives.push(obj); // populate your pool with put method
}
}
public get(parent?: Node): Node;
public get<T extends Component>(
parent?: Node,
classConstructor?:
| __private._types_globals__Constructor<T>
| __private._types_globals__AbstractedConstructor<T>,
): T;
public get<T extends Component>(
parent?: Node,
classConstructor?:
| __private._types_globals__Constructor<T>
| __private._types_globals__AbstractedConstructor<T>,
): T | Node {
let obj: Node = null;
let p = parent || director.getScene();
if (this._inactives.length > 0) {
// use size method to check if there're nodes available in the pool
obj = this._inactives.pop();
obj.setParent(p);
this._actives.push(obj);
} else if (this._expandable) {
// if not enough node in the pool, we call cc.instantiate to create node
obj = instantiate(this._prefab);
obj.setParent(p);
this._actives.push(obj);
} else {
obj = this._actives.shift();
this._actives.push(obj);
}
obj.active = true;
if (classConstructor) {
return obj.getComponent(classConstructor);
}
return obj;
}
public release(obj: Node);
public release<T extends Component>(obj: T);
public release<T extends Component>(obj: T | Node) {
if (obj instanceof Node) {
obj.active = false;
const index = this._actives.indexOf(obj);
this._actives.splice(index, 1);
this._inactives.push(obj);
} else {
obj.node.active = false;
const index = this._actives.indexOf(obj.node);
this._actives.splice(index, 1);
this._inactives.push(obj.node);
}
}
public clear() {
this._inactives.forEach((obj) => obj.destroy());
this._inactives = [];
this._actives = [];
}
}