@nimbus2d/core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +18433 -0
- package/package.json +39 -0
- package/src/base/EventEmitter.js +187 -0
- package/src/base/Subsystem.js +183 -0
- package/src/base/index.js +6 -0
- package/src/core/Application/AppState.js +27 -0
- package/src/core/Application/Application.js +480 -0
- package/src/core/Application/DefaultConfig.js +63 -0
- package/src/core/Application/index.js +7 -0
- package/src/core/AssetManager/AssetManager.js +711 -0
- package/src/core/AssetManager/AssetTypes.js +108 -0
- package/src/core/AssetManager/adapters/IResourceAdapter.js +50 -0
- package/src/core/AssetManager/adapters/PixiAdapter.js +90 -0
- package/src/core/AssetManager/core/RefCounter.js +167 -0
- package/src/core/AssetManager/core/ResourceCache.js +281 -0
- package/src/core/AssetManager/core/ResourceEntry.js +191 -0
- package/src/core/AssetManager/core/ResourceEventBus.js +127 -0
- package/src/core/AssetManager/handlers/IResourceHandler.js +45 -0
- package/src/core/AssetManager/index.js +26 -0
- package/src/core/AssetManager/plugins/IResourcePlugin.js +56 -0
- package/src/core/Camera/Camera.js +534 -0
- package/src/core/Camera/CameraTypes.js +59 -0
- package/src/core/Camera/index.js +13 -0
- package/src/core/ConfigSystem/ConfigLayer.js +230 -0
- package/src/core/ConfigSystem/ConfigLayerType.js +31 -0
- package/src/core/ConfigSystem/ConfigMerger.js +50 -0
- package/src/core/ConfigSystem/ConfigPath.js +96 -0
- package/src/core/ConfigSystem/ConfigSystem.js +378 -0
- package/src/core/ConfigSystem/ConfigTypes.js +29 -0
- package/src/core/ConfigSystem/ConfigWatcher.js +84 -0
- package/src/core/ConfigSystem/index.js +19 -0
- package/src/core/EventBus/EventBus.js +797 -0
- package/src/core/EventBus/Interceptor.js +26 -0
- package/src/core/EventBus/PerformanceStats.js +105 -0
- package/src/core/EventBus/index.js +7 -0
- package/src/core/Lifecycle/Lifecycle.js +265 -0
- package/src/core/Lifecycle/LifecycleState.js +31 -0
- package/src/core/Lifecycle/index.js +6 -0
- package/src/core/Logger/ConsoleHandler.js +55 -0
- package/src/core/Logger/LogHandler.js +34 -0
- package/src/core/Logger/LogLevel.js +38 -0
- package/src/core/Logger/Logger.js +234 -0
- package/src/core/Logger/index.js +8 -0
- package/src/core/PluginSystem/Plugin.js +156 -0
- package/src/core/PluginSystem/PluginEntry.js +102 -0
- package/src/core/PluginSystem/PluginState.js +30 -0
- package/src/core/PluginSystem/PluginSystem.js +530 -0
- package/src/core/PluginSystem/index.js +8 -0
- package/src/core/PoolManager/DefaultConfig.js +19 -0
- package/src/core/PoolManager/ObjectPool.js +326 -0
- package/src/core/PoolManager/PoolManager.js +253 -0
- package/src/core/PoolManager/PoolTypes.js +92 -0
- package/src/core/PoolManager/index.js +15 -0
- package/src/core/SceneManager/FadeTransition.js +64 -0
- package/src/core/SceneManager/MaskTransition.js +234 -0
- package/src/core/SceneManager/Scene.js +221 -0
- package/src/core/SceneManager/SceneManager.js +658 -0
- package/src/core/SceneManager/SceneState.js +29 -0
- package/src/core/SceneManager/SlideTransition.js +113 -0
- package/src/core/SceneManager/Transition.js +102 -0
- package/src/core/SceneManager/ZoomTransition.js +119 -0
- package/src/core/SceneManager/index.js +12 -0
- package/src/core/SpriteGPULayer/SpriteGPULayer.js +321 -0
- package/src/core/SpriteGPULayer/SpriteGPULayerTypes.js +49 -0
- package/src/core/SpriteGPULayer/index.js +11 -0
- package/src/core/Timeline/Clip.js +101 -0
- package/src/core/Timeline/DefaultConfig.js +41 -0
- package/src/core/Timeline/Easing.js +176 -0
- package/src/core/Timeline/Timeline.js +458 -0
- package/src/core/Timeline/TimelineTypes.js +89 -0
- package/src/core/Timeline/Track.js +202 -0
- package/src/core/Timeline/index.js +22 -0
- package/src/errors/ConfigError.js +47 -0
- package/src/errors/LifecycleError.js +58 -0
- package/src/errors/NimbusError.js +43 -0
- package/src/errors/PluginError.js +138 -0
- package/src/errors/ResourceError.js +166 -0
- package/src/errors/SceneError.js +124 -0
- package/src/errors/SubsystemError.js +68 -0
- package/src/errors/index.js +53 -0
- package/src/index.js +86 -0
- package/src/types/index.js +141 -0
- package/src/utils/MemoryChecker.js +374 -0
- package/src/utils/Validator.js +60 -0
- package/src/utils/index.js +84 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Nimbus2D - 泛型对象池
|
|
3
|
+
// ----------------------------------------------------------------------------
|
|
4
|
+
// 职责:
|
|
5
|
+
// 提供通用对象复用能力,支持任意类型的对象池化。
|
|
6
|
+
// 通过 create 函数创建新对象,通过 reset 函数重置对象状态,
|
|
7
|
+
// 通过 validate 函数校验归还的对象是否可复用。
|
|
8
|
+
//
|
|
9
|
+
// 设计决策:
|
|
10
|
+
// - 使用数组作为空闲列表(freeList),pop() 为 O(1)
|
|
11
|
+
// - 使用 Set 追踪使用中对象(inUse),has/delete 为 O(1)
|
|
12
|
+
// - maxSize 限制总对象数(空闲 + 使用中),防止内存无限增长
|
|
13
|
+
// - 池耗尽时触发 onExhausted 回调并抛出 PoolExhaustedError
|
|
14
|
+
// - validate 校验失败的对象被丢弃(不归还空闲列表)
|
|
15
|
+
// - drain() 排空所有空闲对象,shrink() 缩减到指定大小
|
|
16
|
+
// - 不继承 Subsystem,作为轻量级独立组件由 PoolManager 管理
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
import { PoolState, PoolError, PoolStateError, PoolExhaustedError } from './PoolTypes.js'
|
|
20
|
+
|
|
21
|
+
class ObjectPool {
|
|
22
|
+
// --------------------------------------------------------------------------
|
|
23
|
+
// 构造函数
|
|
24
|
+
// --------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 构造函数
|
|
28
|
+
* @param {Object} options - 池配置
|
|
29
|
+
* @param {string} [options.name='unnamed'] - 池名称(用于错误消息和事件)
|
|
30
|
+
* @param {Function} options.create - 创建函数 () => T
|
|
31
|
+
* @param {Function} [options.reset] - 重置函数 (obj: T) => void
|
|
32
|
+
* @param {Function} [options.validate] - 验证函数 (obj: T) => boolean(归还时校验)
|
|
33
|
+
* @param {Function} [options.onExhausted] - 池耗尽回调 (name: string, maxSize: number) => void
|
|
34
|
+
* @param {number} [options.initialSize=0] - 初始预分配数量
|
|
35
|
+
* @param {number} [options.maxSize=Infinity] - 最大容量(空闲+使用中总数)
|
|
36
|
+
* @throws {PoolError} create 函数缺失时抛出
|
|
37
|
+
*/
|
|
38
|
+
constructor(options) {
|
|
39
|
+
// 参数校验
|
|
40
|
+
if (!options || typeof options.create !== 'function') {
|
|
41
|
+
throw new PoolError('create 函数是必需的')
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** @type {string} 池名称 */
|
|
45
|
+
this._name = options.name || 'unnamed'
|
|
46
|
+
|
|
47
|
+
/** @type {Function} 创建函数 */
|
|
48
|
+
this._create = options.create
|
|
49
|
+
|
|
50
|
+
/** @type {Function} 重置函数 */
|
|
51
|
+
this._reset = options.reset || (() => {})
|
|
52
|
+
|
|
53
|
+
/** @type {Function} 验证函数 */
|
|
54
|
+
this._validate = options.validate || (() => true)
|
|
55
|
+
|
|
56
|
+
/** @type {Function|null} 池耗尽回调(由 PoolManager 注册时设置) */
|
|
57
|
+
this._onExhausted = options.onExhausted || null
|
|
58
|
+
|
|
59
|
+
/** @type {number} 最大容量 */
|
|
60
|
+
this._maxSize = options.maxSize ?? Infinity
|
|
61
|
+
|
|
62
|
+
/** @type {PoolState} 池状态 */
|
|
63
|
+
this._state = PoolState.ACTIVE
|
|
64
|
+
|
|
65
|
+
/** @type {Array<T>} 空闲对象列表 */
|
|
66
|
+
this._freeList = []
|
|
67
|
+
|
|
68
|
+
/** @type {Set<T>} 正在使用的对象集合 */
|
|
69
|
+
this._inUse = new Set()
|
|
70
|
+
|
|
71
|
+
/** @type {Object} 统计信息 */
|
|
72
|
+
this._stats = {
|
|
73
|
+
/** @type {number} 总创建数量(空闲+使用中) */
|
|
74
|
+
size: 0,
|
|
75
|
+
/** @type {number} 可用数量 */
|
|
76
|
+
available: 0,
|
|
77
|
+
/** @type {number} 使用中数量 */
|
|
78
|
+
inUse: 0,
|
|
79
|
+
/** @type {number} 累计获取次数 */
|
|
80
|
+
totalAcquired: 0,
|
|
81
|
+
/** @type {number} 累计归还次数 */
|
|
82
|
+
totalReleased: 0,
|
|
83
|
+
/** @type {number} 累计创建次数 */
|
|
84
|
+
totalCreated: 0
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 预分配
|
|
88
|
+
if (options.initialSize > 0) {
|
|
89
|
+
this.preallocate(options.initialSize)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// --------------------------------------------------------------------------
|
|
94
|
+
// Getter
|
|
95
|
+
// --------------------------------------------------------------------------
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 池名称
|
|
99
|
+
* @type {string}
|
|
100
|
+
*/
|
|
101
|
+
get name() {
|
|
102
|
+
return this._name
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* 最大容量
|
|
107
|
+
* @type {number}
|
|
108
|
+
*/
|
|
109
|
+
get maxSize() {
|
|
110
|
+
return this._maxSize
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 池状态
|
|
115
|
+
* @type {PoolState}
|
|
116
|
+
*/
|
|
117
|
+
get state() {
|
|
118
|
+
return this._state
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* 当前可用对象数量
|
|
123
|
+
* @type {number}
|
|
124
|
+
*/
|
|
125
|
+
get available() {
|
|
126
|
+
return this._stats.available
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* 当前使用中对象数量
|
|
131
|
+
* @type {number}
|
|
132
|
+
*/
|
|
133
|
+
get inUseCount() {
|
|
134
|
+
return this._stats.inUse
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* 总对象数量(空闲+使用中)
|
|
139
|
+
* @type {number}
|
|
140
|
+
*/
|
|
141
|
+
get size() {
|
|
142
|
+
return this._stats.size
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 是否已销毁
|
|
147
|
+
* @type {boolean}
|
|
148
|
+
*/
|
|
149
|
+
get isDestroyed() {
|
|
150
|
+
return this._state === PoolState.DESTROYED
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// --------------------------------------------------------------------------
|
|
154
|
+
// 核心方法
|
|
155
|
+
// --------------------------------------------------------------------------
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* 预分配对象
|
|
159
|
+
* 在池初始化或需要提前创建对象时调用
|
|
160
|
+
* @param {number} count - 预分配数量
|
|
161
|
+
* @returns {void}
|
|
162
|
+
*/
|
|
163
|
+
preallocate(count) {
|
|
164
|
+
// 已销毁的池不允许预分配
|
|
165
|
+
if (this._state === PoolState.DESTROYED) return
|
|
166
|
+
|
|
167
|
+
for (let i = 0; i < count && this._stats.size < this._maxSize; i++) {
|
|
168
|
+
const obj = this._create()
|
|
169
|
+
this._freeList.push(obj)
|
|
170
|
+
this._stats.size++
|
|
171
|
+
this._stats.available++
|
|
172
|
+
this._stats.totalCreated++
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 从池中获取对象
|
|
178
|
+
* 优先从空闲列表取出,空闲列表为空则创建新对象,
|
|
179
|
+
* 达到 maxSize 限制时触发耗尽回调并抛出 PoolExhaustedError
|
|
180
|
+
* @returns {T} 获取的对象
|
|
181
|
+
* @throws {PoolExhaustedError} 池已满且无可用对象
|
|
182
|
+
*/
|
|
183
|
+
acquire() {
|
|
184
|
+
// 已销毁的池不允许获取
|
|
185
|
+
if (this._state === PoolState.DESTROYED) {
|
|
186
|
+
throw new PoolExhaustedError(this._name, 0)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 已排空的池不允许获取(需要先重新预分配或重建)
|
|
190
|
+
if (this._state === PoolState.DRAINED) {
|
|
191
|
+
throw new PoolStateError(`对象池 '${this._name}' 已排空,无法获取对象`)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
let obj
|
|
195
|
+
|
|
196
|
+
if (this._freeList.length > 0) {
|
|
197
|
+
// 从空闲列表取出
|
|
198
|
+
obj = this._freeList.pop()
|
|
199
|
+
this._stats.available--
|
|
200
|
+
} else if (this._stats.size < this._maxSize) {
|
|
201
|
+
// 创建新对象
|
|
202
|
+
obj = this._create()
|
|
203
|
+
this._stats.size++
|
|
204
|
+
this._stats.totalCreated++
|
|
205
|
+
} else {
|
|
206
|
+
// 池已耗尽:触发回调并抛出专用错误
|
|
207
|
+
if (this._onExhausted) {
|
|
208
|
+
this._onExhausted(this._name, this._maxSize)
|
|
209
|
+
}
|
|
210
|
+
throw new PoolExhaustedError(this._name, this._maxSize)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
this._inUse.add(obj)
|
|
214
|
+
this._stats.inUse++
|
|
215
|
+
this._stats.totalAcquired++
|
|
216
|
+
return obj
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* 将对象归还到池
|
|
221
|
+
* 归还时会调用 reset 重置对象状态,然后调用 validate 校验对象是否可复用。
|
|
222
|
+
* 校验失败的对象被丢弃(不归还空闲列表,size 递减)。
|
|
223
|
+
* @param {T} obj - 归还的对象
|
|
224
|
+
* @returns {void}
|
|
225
|
+
*/
|
|
226
|
+
release(obj) {
|
|
227
|
+
// 已销毁的池忽略归还
|
|
228
|
+
if (this._state === PoolState.DESTROYED) return
|
|
229
|
+
|
|
230
|
+
if (!this._inUse.has(obj)) {
|
|
231
|
+
// 归还未知对象始终警告(可能是重复归还或归还了非本池对象,属于编程错误)
|
|
232
|
+
console.warn(`[ObjectPool '${this._name}'] 尝试归还不属于本池的对象`)
|
|
233
|
+
return
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
this._inUse.delete(obj)
|
|
237
|
+
this._stats.inUse--
|
|
238
|
+
|
|
239
|
+
// 重置对象状态
|
|
240
|
+
this._reset(obj)
|
|
241
|
+
|
|
242
|
+
// 验证对象(可选)
|
|
243
|
+
if (this._validate(obj)) {
|
|
244
|
+
this._freeList.push(obj)
|
|
245
|
+
this._stats.available++
|
|
246
|
+
} else {
|
|
247
|
+
// 验证失败,丢弃对象
|
|
248
|
+
this._stats.size--
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
this._stats.totalReleased++
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* 排空池中所有空闲对象
|
|
256
|
+
* 使用中的对象不受影响,size 调整为使用中数量
|
|
257
|
+
* @returns {void}
|
|
258
|
+
*/
|
|
259
|
+
drain() {
|
|
260
|
+
if (this._state === PoolState.DESTROYED) return
|
|
261
|
+
|
|
262
|
+
this._freeList.length = 0
|
|
263
|
+
this._stats.available = 0
|
|
264
|
+
this._stats.size = this._stats.inUse
|
|
265
|
+
this._state = PoolState.DRAINED
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* 缩减池到指定大小
|
|
270
|
+
* 仅移除空闲列表末尾的对象,使用中的对象不受影响
|
|
271
|
+
* @param {number} targetSize - 目标大小(空闲+使用中总数)
|
|
272
|
+
* @returns {void}
|
|
273
|
+
*/
|
|
274
|
+
shrink(targetSize) {
|
|
275
|
+
if (this._state === PoolState.DESTROYED) return
|
|
276
|
+
if (typeof targetSize !== 'number' || targetSize < 0) return
|
|
277
|
+
|
|
278
|
+
while (this._freeList.length > 0 && this._stats.size > targetSize) {
|
|
279
|
+
this._freeList.pop()
|
|
280
|
+
this._stats.size--
|
|
281
|
+
this._stats.available--
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// --------------------------------------------------------------------------
|
|
286
|
+
// 统计
|
|
287
|
+
// --------------------------------------------------------------------------
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* 获取统计信息
|
|
291
|
+
* 返回统计信息的浅拷贝,避免外部修改内部状态
|
|
292
|
+
* @returns {Object} 统计信息对象
|
|
293
|
+
*/
|
|
294
|
+
getStats() {
|
|
295
|
+
return { ...this._stats }
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// --------------------------------------------------------------------------
|
|
299
|
+
// 销毁
|
|
300
|
+
// --------------------------------------------------------------------------
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* 销毁对象池
|
|
304
|
+
* 清空所有列表和集合,释放引用,状态标记为 DESTROYED
|
|
305
|
+
* 使用中的对象不会被自动释放(由调用方负责)
|
|
306
|
+
* @returns {void}
|
|
307
|
+
*/
|
|
308
|
+
destroy() {
|
|
309
|
+
if (this._state === PoolState.DESTROYED) return
|
|
310
|
+
|
|
311
|
+
this._freeList.length = 0
|
|
312
|
+
this._inUse.clear()
|
|
313
|
+
this._stats.size = 0
|
|
314
|
+
this._stats.available = 0
|
|
315
|
+
this._stats.inUse = 0
|
|
316
|
+
this._state = PoolState.DESTROYED
|
|
317
|
+
|
|
318
|
+
// 释放函数引用
|
|
319
|
+
this._create = null
|
|
320
|
+
this._reset = null
|
|
321
|
+
this._validate = null
|
|
322
|
+
this._onExhausted = null
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export { ObjectPool }
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Nimbus2D - 对象池管理器
|
|
3
|
+
// ----------------------------------------------------------------------------
|
|
4
|
+
// 职责:
|
|
5
|
+
// 提供通用对象池注册和管理能力。采用池注册表模式——PoolManager
|
|
6
|
+
// 不预知任何对象类型,插件通过 register() 注册自己的对象池,
|
|
7
|
+
// 通过 unregister() 注销。
|
|
8
|
+
//
|
|
9
|
+
// 继承关系:
|
|
10
|
+
// EventEmitter → Subsystem → PoolManager
|
|
11
|
+
//
|
|
12
|
+
// 设计决策:
|
|
13
|
+
// - 池注册表模式:PoolManager 只管理注册/注销,不关心对象类型
|
|
14
|
+
// - register() 时自动为池设置耗尽回调(onExhausted),使 ObjectPool
|
|
15
|
+
// 在耗尽时通过 PoolManager 广播事件
|
|
16
|
+
// - unregister() 时自动调用 pool.drain() 排空池
|
|
17
|
+
// - destroy() 时排空并注销所有池
|
|
18
|
+
// - 事件通过全局 EventBus 广播(pool:registered/pool:unregistered/pool:exhausted)
|
|
19
|
+
// - 在 PluginSystem 之前初始化,确保插件安装时池管理器已就绪
|
|
20
|
+
// ============================================================================
|
|
21
|
+
|
|
22
|
+
import { Subsystem } from '../../base/Subsystem.js'
|
|
23
|
+
import { ObjectPool } from './ObjectPool.js'
|
|
24
|
+
import { PoolError, PoolStateError } from './PoolTypes.js'
|
|
25
|
+
import { validateDev, isNonEmptyString } from '../../utils/Validator.js'
|
|
26
|
+
|
|
27
|
+
class PoolManager extends Subsystem {
|
|
28
|
+
// --------------------------------------------------------------------------
|
|
29
|
+
// 构造函数
|
|
30
|
+
// --------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 构造函数
|
|
34
|
+
* @param {import('../../core/EventBus/EventBus.js').EventBus} eventBus - 全局事件总线
|
|
35
|
+
* @param {import('../../core/ConfigSystem/ConfigSystem.js').ConfigSystem} config - 配置系统
|
|
36
|
+
* @param {import('../../core/Logger/Logger.js').Logger|null} [logger=null] - 日志系统
|
|
37
|
+
*/
|
|
38
|
+
constructor(eventBus, config, logger = null) {
|
|
39
|
+
super(eventBus, config, logger)
|
|
40
|
+
|
|
41
|
+
/** @type {Map<string, ObjectPool>|null} 池注册表(name → ObjectPool) */
|
|
42
|
+
this._pools = null
|
|
43
|
+
|
|
44
|
+
/** @type {Object} 统计信息 */
|
|
45
|
+
this._stats = null
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// --------------------------------------------------------------------------
|
|
49
|
+
// Getter
|
|
50
|
+
// --------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 子系统名称
|
|
54
|
+
* @type {string}
|
|
55
|
+
*/
|
|
56
|
+
get name() {
|
|
57
|
+
return 'poolManager'
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// --------------------------------------------------------------------------
|
|
61
|
+
// 池管理
|
|
62
|
+
// --------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 注册对象池
|
|
66
|
+
* @param {string} name - 池名称(如 'collider'、'physicsBody')
|
|
67
|
+
* @param {ObjectPool} pool - 对象池实例
|
|
68
|
+
* @returns {PoolManager} - this(链式调用)
|
|
69
|
+
* @throws {PoolError} 名称已存在、池已销毁或参数无效
|
|
70
|
+
*/
|
|
71
|
+
register(name, pool) {
|
|
72
|
+
// 已销毁检查
|
|
73
|
+
if (this.isDestroyed) {
|
|
74
|
+
throw new PoolError('PoolManager 已销毁,无法注册对象池')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// 开发模式:初始化状态守卫(PoolManager 必须先初始化才能注册对象池)
|
|
78
|
+
validateDev(this._config, this.isInitialized, 'PoolManager 尚未初始化,无法注册对象池', PoolStateError)
|
|
79
|
+
|
|
80
|
+
// 开发模式:完整参数校验
|
|
81
|
+
validateDev(this._config, isNonEmptyString(name), '池名称必须是非空字符串', PoolError)
|
|
82
|
+
validateDev(this._config, pool && typeof pool.acquire === 'function', 'pool 必须是 ObjectPool 实例', PoolError)
|
|
83
|
+
|
|
84
|
+
// 生产模式:仅检查 name 存在性
|
|
85
|
+
if (!name) {
|
|
86
|
+
throw new PoolError('池名称不能为空')
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (this._pools.has(name)) {
|
|
90
|
+
throw new PoolError(`对象池 '${name}' 已存在`)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 设置池耗尽回调,使 ObjectPool 在耗尽时通过 PoolManager 广播事件
|
|
94
|
+
if (!pool._onExhausted) {
|
|
95
|
+
pool._onExhausted = (poolName, maxSize) => {
|
|
96
|
+
this._eventBus.emit('pool:exhausted', { name: poolName, maxSize })
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this._pools.set(name, pool)
|
|
101
|
+
this._stats.totalRegistered++
|
|
102
|
+
this._eventBus.emit('pool:registered', { name, pool })
|
|
103
|
+
|
|
104
|
+
this._logger.debug('PoolManager.register', `对象池 '${name}' 已注册`)
|
|
105
|
+
return this
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 注销对象池
|
|
110
|
+
* 注销时默认调用 pool.drain() 排空池中空闲对象。
|
|
111
|
+
* 若 options.destroy 为 true,则额外调用 pool.destroy() 彻底销毁池对象,
|
|
112
|
+
* 释放内部函数引用和统计信息,防止内存泄漏。
|
|
113
|
+
*
|
|
114
|
+
* @param {string} name - 池名称
|
|
115
|
+
* @param {Object} [options={}] - 注销选项
|
|
116
|
+
* @param {boolean} [options.destroy=true] - 是否彻底销毁池对象(默认 true)
|
|
117
|
+
* true: drain() + destroy(),彻底释放
|
|
118
|
+
* false: 仅 drain(),保留池对象供复用
|
|
119
|
+
* @returns {boolean} - 是否注销成功(池不存在时返回 false)
|
|
120
|
+
*/
|
|
121
|
+
unregister(name, options = {}) {
|
|
122
|
+
// 已销毁检查
|
|
123
|
+
if (this.isDestroyed) return false
|
|
124
|
+
|
|
125
|
+
if (!this._pools.has(name)) return false
|
|
126
|
+
|
|
127
|
+
// 参数容错:options 为 null 时使用空对象
|
|
128
|
+
/** @type {Object} 安全的 options 对象 */
|
|
129
|
+
const safeOptions = options || {}
|
|
130
|
+
/** @type {boolean} 是否彻底销毁池对象(默认 true) */
|
|
131
|
+
const shouldDestroy = safeOptions.destroy !== false
|
|
132
|
+
|
|
133
|
+
const pool = this._pools.get(name)
|
|
134
|
+
pool.drain()
|
|
135
|
+
if (shouldDestroy) {
|
|
136
|
+
// 彻底销毁池对象,释放内部函数引用和统计信息
|
|
137
|
+
pool.destroy()
|
|
138
|
+
}
|
|
139
|
+
this._pools.delete(name)
|
|
140
|
+
this._eventBus.emit('pool:unregistered', { name })
|
|
141
|
+
|
|
142
|
+
this._logger.debug('PoolManager.unregister', `对象池 '${name}' 已注销${shouldDestroy ? '(已销毁)' : '(仅排空)'}`)
|
|
143
|
+
return true
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* 获取对象池
|
|
148
|
+
* @param {string} name - 池名称
|
|
149
|
+
* @returns {ObjectPool|undefined} 对象池实例,不存在时返回 undefined
|
|
150
|
+
*/
|
|
151
|
+
get(name) {
|
|
152
|
+
if (!this._pools) return undefined
|
|
153
|
+
return this._pools.get(name)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* 检查池是否存在
|
|
158
|
+
* @param {string} name - 池名称
|
|
159
|
+
* @returns {boolean}
|
|
160
|
+
*/
|
|
161
|
+
has(name) {
|
|
162
|
+
if (!this._pools) return false
|
|
163
|
+
return this._pools.has(name)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* 列出所有已注册的池名称
|
|
168
|
+
* @returns {string[]}
|
|
169
|
+
*/
|
|
170
|
+
list() {
|
|
171
|
+
if (!this._pools) return []
|
|
172
|
+
return Array.from(this._pools.keys())
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// --------------------------------------------------------------------------
|
|
176
|
+
// 统计
|
|
177
|
+
// --------------------------------------------------------------------------
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* 获取所有池的统计信息
|
|
181
|
+
* @returns {Object} 包含 totalRegistered 和各池统计的对象
|
|
182
|
+
*/
|
|
183
|
+
getStats() {
|
|
184
|
+
if (!this._pools) {
|
|
185
|
+
return { totalRegistered: 0, pools: {} }
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const stats = {}
|
|
189
|
+
for (const [name, pool] of this._pools) {
|
|
190
|
+
stats[name] = pool.getStats()
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
totalRegistered: this._pools.size,
|
|
194
|
+
pools: stats
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// --------------------------------------------------------------------------
|
|
199
|
+
// 生命周期(继承自 Subsystem)
|
|
200
|
+
// --------------------------------------------------------------------------
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* 初始化对象池管理器
|
|
204
|
+
* 创建池注册表和统计信息
|
|
205
|
+
* @returns {Promise<void>}
|
|
206
|
+
*/
|
|
207
|
+
async initialize() {
|
|
208
|
+
await super.initialize()
|
|
209
|
+
|
|
210
|
+
this._pools = new Map()
|
|
211
|
+
this._stats = { totalRegistered: 0 }
|
|
212
|
+
|
|
213
|
+
this._logger.info('PoolManager.initialize', '对象池管理器已初始化')
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* 每帧更新
|
|
218
|
+
* 池操作由 acquire/release 同步完成,无需每帧逻辑
|
|
219
|
+
* @param {number} delta - 距上一帧的时间增量(秒)
|
|
220
|
+
* @returns {void}
|
|
221
|
+
*/
|
|
222
|
+
update(delta) {
|
|
223
|
+
// 空实现——池操作由 acquire/release 同步完成
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* 销毁对象池管理器
|
|
228
|
+
* 排空并注销所有已注册的池
|
|
229
|
+
* @returns {Promise<void>}
|
|
230
|
+
*/
|
|
231
|
+
async destroy() {
|
|
232
|
+
if (this.isDestroyed) return
|
|
233
|
+
|
|
234
|
+
// 排空并销毁所有已注册的池
|
|
235
|
+
if (this._pools) {
|
|
236
|
+
for (const [name, pool] of this._pools) {
|
|
237
|
+
pool.drain()
|
|
238
|
+
pool.destroy()
|
|
239
|
+
this._eventBus.emit('pool:unregistered', { name })
|
|
240
|
+
}
|
|
241
|
+
this._pools.clear()
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
this._pools = null
|
|
245
|
+
this._stats = null
|
|
246
|
+
|
|
247
|
+
this._logger.info('PoolManager.destroy', '对象池管理器已销毁')
|
|
248
|
+
|
|
249
|
+
await super.destroy()
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export { PoolManager }
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Nimbus2D - 对象池类型定义
|
|
3
|
+
// ----------------------------------------------------------------------------
|
|
4
|
+
// 定义对象池模块的枚举类型和错误类。
|
|
5
|
+
//
|
|
6
|
+
// 包含:
|
|
7
|
+
// - PoolState:对象池状态枚举
|
|
8
|
+
// - PoolError:对象池错误基类(继承 NimbusError)
|
|
9
|
+
// - PoolStateError:对象池状态错误
|
|
10
|
+
// - PoolExhaustedError:对象池已满错误
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
import { NimbusError } from '../../errors/NimbusError.js'
|
|
14
|
+
|
|
15
|
+
// ----------------------------------------------------------------------------
|
|
16
|
+
// 枚举
|
|
17
|
+
// ----------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 对象池状态枚举
|
|
21
|
+
* @enum {string}
|
|
22
|
+
*/
|
|
23
|
+
const PoolState = {
|
|
24
|
+
/** 正常运行 */
|
|
25
|
+
ACTIVE: 'ACTIVE',
|
|
26
|
+
/** 已排空 */
|
|
27
|
+
DRAINED: 'DRAINED',
|
|
28
|
+
/** 已销毁 */
|
|
29
|
+
DESTROYED: 'DESTROYED'
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ----------------------------------------------------------------------------
|
|
33
|
+
// 错误类
|
|
34
|
+
// ----------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 对象池错误基类
|
|
38
|
+
* @extends NimbusError
|
|
39
|
+
*/
|
|
40
|
+
class PoolError extends NimbusError {
|
|
41
|
+
/**
|
|
42
|
+
* 构造函数
|
|
43
|
+
* @param {string} message - 错误信息
|
|
44
|
+
* @param {string} [code='POOL_ERROR'] - 错误码
|
|
45
|
+
* @param {Error|null} [cause=null] - 原始错误
|
|
46
|
+
*/
|
|
47
|
+
constructor(message, code = 'POOL_ERROR', cause = null) {
|
|
48
|
+
super(message, code, 'PoolManager', cause)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 对象池状态错误
|
|
54
|
+
* 当对处于无效状态的对象池执行操作时抛出
|
|
55
|
+
* @extends PoolError
|
|
56
|
+
*/
|
|
57
|
+
class PoolStateError extends PoolError {
|
|
58
|
+
/**
|
|
59
|
+
* 构造函数
|
|
60
|
+
* @param {string} message - 错误信息
|
|
61
|
+
*/
|
|
62
|
+
constructor(message) {
|
|
63
|
+
super(message, 'POOL_STATE_ERROR')
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 对象池已满错误
|
|
69
|
+
* 当 acquire() 时池已达最大容量且无可用对象时抛出
|
|
70
|
+
* @extends PoolError
|
|
71
|
+
*/
|
|
72
|
+
class PoolExhaustedError extends PoolError {
|
|
73
|
+
/**
|
|
74
|
+
* 构造函数
|
|
75
|
+
* @param {string} poolName - 池名称
|
|
76
|
+
* @param {number} maxSize - 最大容量
|
|
77
|
+
*/
|
|
78
|
+
constructor(poolName, maxSize) {
|
|
79
|
+
super(`对象池 '${poolName}' 已满(maxSize=${maxSize})`, 'POOL_EXHAUSTED')
|
|
80
|
+
/** @type {string} 池名称 */
|
|
81
|
+
this.poolName = poolName
|
|
82
|
+
/** @type {number} 最大容量 */
|
|
83
|
+
this.maxSize = maxSize
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export {
|
|
88
|
+
PoolState,
|
|
89
|
+
PoolError,
|
|
90
|
+
PoolStateError,
|
|
91
|
+
PoolExhaustedError
|
|
92
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Nimbus2D - 对象池模块入口
|
|
3
|
+
// ----------------------------------------------------------------------------
|
|
4
|
+
// 统一导出 PoolManager 模块的所有公开类、枚举和错误类。
|
|
5
|
+
// ============================================================================
|
|
6
|
+
|
|
7
|
+
export { PoolManager } from './PoolManager.js'
|
|
8
|
+
export { ObjectPool } from './ObjectPool.js'
|
|
9
|
+
export {
|
|
10
|
+
PoolState,
|
|
11
|
+
PoolError,
|
|
12
|
+
PoolStateError,
|
|
13
|
+
PoolExhaustedError
|
|
14
|
+
} from './PoolTypes.js'
|
|
15
|
+
export { PoolDefaultConfig } from './DefaultConfig.js'
|