NodePoolFactory.ts
3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import { ResUtils } from "simba-cc-resutils";
import { delay } from "simba-utils";
export namespace NodePoolFactory {
let arrPool: { [key: string]: cc.NodePool } = {};
let arrPrefab: { [key: string]: cc.Prefab } = {};
let creationTasks: { path: string, count: number, callback: () => void, poolHanderComp?: { prototype: cc.Component } | string }[] = [];
let processingTasks = false;
async function handleTasks() {
processingTasks = true;
while (creationTasks.length) {
let task = creationTasks.shift()!;
let prefab = await ResUtils.loadRes<cc.Prefab>(task.path, cc.Prefab);
if (prefab) {
let pool = new cc.NodePool(task.poolHanderComp);
for (let i = 0; i < task.count; i++) {
let node = cc.instantiate(prefab);
(node as any)._path = task.path;
pool.put(node);
if ((i + 1) % 5 == 0) await delay(0.01);
}
arrPrefab[task.path] = prefab;
arrPool[task.path] = pool;
} else {
cc.error("prefab path not find: ", task.path);
}
task.callback();
await delay(0.01);
}
processingTasks = false;
}
export async function createPool(path: string, count: number = 1, poolHandlerComp?: { prototype: cc.Component } | string) {
return new Promise((resolve) => {
if (arrPool[path]) {
resolve();
return;
}
creationTasks.push({
path,
count,
poolHanderComp: poolHandlerComp,
callback: () => resolve()
});
if (!processingTasks) {
handleTasks();
}
});
}
/**
* 获取对象池
* @param path 对象池名称
*/
export function getPool(path: string): cc.NodePool {
return arrPool[path];
}
/**
* 清空对象池
* @param path 对象池名称
*/
export function clearPool(...path: string[]) {
if (path == null || path.length <= 0) return
for (let i = 0; i < path.length; i++) {
let one = path[i];
if (arrPool[one]) {
arrPool[one].clear()
delete arrPool[one];
}
}
ResUtils.releaseResArray(path);
cc.sys.garbageCollect();
}
/**
* 从对象池中取出一个node对象
* @param path
*/
export function getNode(path: string) {
// cc.log("getNode:",path)
if (arrPool[path]) {
if (arrPool[path].size() > 0) {
return arrPool[path].get()
} else {
let node = cc.instantiate(arrPrefab[path]);
(node as any)._path = path;
return node;
}
} else {
console.error("pool not find:", path)
return null
}
}
/**
* 把对象放回对象池
* @param path
* @param obj
*/
export function putNode(obj: cc.Node) {
let path = (obj as any)._path;
if (arrPool[path]) {
arrPool[path].put(obj)
} else {
obj.removeFromParent(true);
console.error("pool not find:", path)
}
}
/**
* 清空所有对象池
*/
export function clearAll() {
let pathArr: string[] = []
for (const key in arrPool) {
if (arrPool.hasOwnProperty(key)) {
pathArr[pathArr.length] = key
const pool = arrPool[key];
pool.clear()
}
}
ResUtils.releaseResArray(pathArr)
arrPool = {}
arrPrefab = {}
cc.sys.garbageCollect();
}
}