@esengine/ecs-framework 2.0.3

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.
Files changed (187) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +277 -0
  3. package/bin/Core.d.ts +198 -0
  4. package/bin/Core.d.ts.map +1 -0
  5. package/bin/Core.js +249 -0
  6. package/bin/Core.js.map +1 -0
  7. package/bin/ECS/Component.d.ts +119 -0
  8. package/bin/ECS/Component.d.ts.map +1 -0
  9. package/bin/ECS/Component.js +129 -0
  10. package/bin/ECS/Component.js.map +1 -0
  11. package/bin/ECS/Components/IUpdatable.d.ts +22 -0
  12. package/bin/ECS/Components/IUpdatable.d.ts.map +1 -0
  13. package/bin/ECS/Components/IUpdatable.js +17 -0
  14. package/bin/ECS/Components/IUpdatable.js.map +1 -0
  15. package/bin/ECS/Components/SceneComponent.d.ts +40 -0
  16. package/bin/ECS/Components/SceneComponent.d.ts.map +1 -0
  17. package/bin/ECS/Components/SceneComponent.js +57 -0
  18. package/bin/ECS/Components/SceneComponent.js.map +1 -0
  19. package/bin/ECS/Core/ComponentStorage.d.ts +182 -0
  20. package/bin/ECS/Core/ComponentStorage.d.ts.map +1 -0
  21. package/bin/ECS/Core/ComponentStorage.js +346 -0
  22. package/bin/ECS/Core/ComponentStorage.js.map +1 -0
  23. package/bin/ECS/Core/EventSystem.d.ts +236 -0
  24. package/bin/ECS/Core/EventSystem.d.ts.map +1 -0
  25. package/bin/ECS/Core/EventSystem.js +476 -0
  26. package/bin/ECS/Core/EventSystem.js.map +1 -0
  27. package/bin/ECS/Core/FluentAPI.d.ts +392 -0
  28. package/bin/ECS/Core/FluentAPI.d.ts.map +1 -0
  29. package/bin/ECS/Core/FluentAPI.js +575 -0
  30. package/bin/ECS/Core/FluentAPI.js.map +1 -0
  31. package/bin/ECS/Core/QuerySystem.d.ts +574 -0
  32. package/bin/ECS/Core/QuerySystem.d.ts.map +1 -0
  33. package/bin/ECS/Core/QuerySystem.js +1356 -0
  34. package/bin/ECS/Core/QuerySystem.js.map +1 -0
  35. package/bin/ECS/CoreEvents.d.ts +19 -0
  36. package/bin/ECS/CoreEvents.d.ts.map +1 -0
  37. package/bin/ECS/CoreEvents.js +20 -0
  38. package/bin/ECS/CoreEvents.js.map +1 -0
  39. package/bin/ECS/Entity.d.ts +585 -0
  40. package/bin/ECS/Entity.d.ts.map +1 -0
  41. package/bin/ECS/Entity.js +1079 -0
  42. package/bin/ECS/Entity.js.map +1 -0
  43. package/bin/ECS/Scene.d.ts +210 -0
  44. package/bin/ECS/Scene.d.ts.map +1 -0
  45. package/bin/ECS/Scene.js +267 -0
  46. package/bin/ECS/Scene.js.map +1 -0
  47. package/bin/ECS/Systems/EntitySystem.d.ts +185 -0
  48. package/bin/ECS/Systems/EntitySystem.d.ts.map +1 -0
  49. package/bin/ECS/Systems/EntitySystem.js +278 -0
  50. package/bin/ECS/Systems/EntitySystem.js.map +1 -0
  51. package/bin/ECS/Systems/IntervalSystem.d.ts +33 -0
  52. package/bin/ECS/Systems/IntervalSystem.d.ts.map +1 -0
  53. package/bin/ECS/Systems/IntervalSystem.js +50 -0
  54. package/bin/ECS/Systems/IntervalSystem.js.map +1 -0
  55. package/bin/ECS/Systems/PassiveSystem.d.ts +20 -0
  56. package/bin/ECS/Systems/PassiveSystem.d.ts.map +1 -0
  57. package/bin/ECS/Systems/PassiveSystem.js +21 -0
  58. package/bin/ECS/Systems/PassiveSystem.js.map +1 -0
  59. package/bin/ECS/Systems/ProcessingSystem.d.ts +24 -0
  60. package/bin/ECS/Systems/ProcessingSystem.d.ts.map +1 -0
  61. package/bin/ECS/Systems/ProcessingSystem.js +22 -0
  62. package/bin/ECS/Systems/ProcessingSystem.js.map +1 -0
  63. package/bin/ECS/Systems/index.d.ts +5 -0
  64. package/bin/ECS/Systems/index.d.ts.map +1 -0
  65. package/bin/ECS/Systems/index.js +6 -0
  66. package/bin/ECS/Systems/index.js.map +1 -0
  67. package/bin/ECS/Transform.d.ts +178 -0
  68. package/bin/ECS/Transform.d.ts.map +1 -0
  69. package/bin/ECS/Transform.js +249 -0
  70. package/bin/ECS/Transform.js.map +1 -0
  71. package/bin/ECS/Utils/Bits.d.ts +74 -0
  72. package/bin/ECS/Utils/Bits.d.ts.map +1 -0
  73. package/bin/ECS/Utils/Bits.js +142 -0
  74. package/bin/ECS/Utils/Bits.js.map +1 -0
  75. package/bin/ECS/Utils/ComponentTypeManager.d.ts +50 -0
  76. package/bin/ECS/Utils/ComponentTypeManager.d.ts.map +1 -0
  77. package/bin/ECS/Utils/ComponentTypeManager.js +84 -0
  78. package/bin/ECS/Utils/ComponentTypeManager.js.map +1 -0
  79. package/bin/ECS/Utils/EntityList.d.ts +108 -0
  80. package/bin/ECS/Utils/EntityList.d.ts.map +1 -0
  81. package/bin/ECS/Utils/EntityList.js +249 -0
  82. package/bin/ECS/Utils/EntityList.js.map +1 -0
  83. package/bin/ECS/Utils/EntityProcessorList.d.ts +53 -0
  84. package/bin/ECS/Utils/EntityProcessorList.d.ts.map +1 -0
  85. package/bin/ECS/Utils/EntityProcessorList.js +96 -0
  86. package/bin/ECS/Utils/EntityProcessorList.js.map +1 -0
  87. package/bin/ECS/Utils/IdentifierPool.d.ts +18 -0
  88. package/bin/ECS/Utils/IdentifierPool.d.ts.map +1 -0
  89. package/bin/ECS/Utils/IdentifierPool.js +27 -0
  90. package/bin/ECS/Utils/IdentifierPool.js.map +1 -0
  91. package/bin/ECS/Utils/Matcher.d.ts +63 -0
  92. package/bin/ECS/Utils/Matcher.d.ts.map +1 -0
  93. package/bin/ECS/Utils/Matcher.js +140 -0
  94. package/bin/ECS/Utils/Matcher.js.map +1 -0
  95. package/bin/ECS/Utils/index.d.ts +7 -0
  96. package/bin/ECS/Utils/index.d.ts.map +1 -0
  97. package/bin/ECS/Utils/index.js +8 -0
  98. package/bin/ECS/Utils/index.js.map +1 -0
  99. package/bin/ECS/index.d.ts +8 -0
  100. package/bin/ECS/index.d.ts.map +1 -0
  101. package/bin/ECS/index.js +9 -0
  102. package/bin/ECS/index.js.map +1 -0
  103. package/bin/Math/Edge.d.ts +23 -0
  104. package/bin/Math/Edge.d.ts.map +1 -0
  105. package/bin/Math/Edge.js +24 -0
  106. package/bin/Math/Edge.js.map +1 -0
  107. package/bin/Math/MathHelper.d.ts +75 -0
  108. package/bin/Math/MathHelper.d.ts.map +1 -0
  109. package/bin/Math/MathHelper.js +91 -0
  110. package/bin/Math/MathHelper.js.map +1 -0
  111. package/bin/Math/Rectangle.d.ts +126 -0
  112. package/bin/Math/Rectangle.d.ts.map +1 -0
  113. package/bin/Math/Rectangle.js +181 -0
  114. package/bin/Math/Rectangle.js.map +1 -0
  115. package/bin/Math/Vector2.d.ts +229 -0
  116. package/bin/Math/Vector2.d.ts.map +1 -0
  117. package/bin/Math/Vector2.js +338 -0
  118. package/bin/Math/Vector2.js.map +1 -0
  119. package/bin/Math/index.d.ts +5 -0
  120. package/bin/Math/index.d.ts.map +1 -0
  121. package/bin/Math/index.js +6 -0
  122. package/bin/Math/index.js.map +1 -0
  123. package/bin/Types/index.d.ts +22 -0
  124. package/bin/Types/index.d.ts.map +1 -0
  125. package/bin/Types/index.js +20 -0
  126. package/bin/Types/index.js.map +1 -0
  127. package/bin/Utils/Emitter.d.ts +43 -0
  128. package/bin/Utils/Emitter.d.ts.map +1 -0
  129. package/bin/Utils/Emitter.js +69 -0
  130. package/bin/Utils/Emitter.js.map +1 -0
  131. package/bin/Utils/Extensions/EdgeExt.d.ts +26 -0
  132. package/bin/Utils/Extensions/EdgeExt.d.ts.map +1 -0
  133. package/bin/Utils/Extensions/EdgeExt.js +41 -0
  134. package/bin/Utils/Extensions/EdgeExt.js.map +1 -0
  135. package/bin/Utils/Extensions/NumberExtension.d.ts +13 -0
  136. package/bin/Utils/Extensions/NumberExtension.d.ts.map +1 -0
  137. package/bin/Utils/Extensions/NumberExtension.js +17 -0
  138. package/bin/Utils/Extensions/NumberExtension.js.map +1 -0
  139. package/bin/Utils/Extensions/TypeUtils.d.ts +13 -0
  140. package/bin/Utils/Extensions/TypeUtils.d.ts.map +1 -0
  141. package/bin/Utils/Extensions/TypeUtils.js +15 -0
  142. package/bin/Utils/Extensions/TypeUtils.js.map +1 -0
  143. package/bin/Utils/Extensions/index.d.ts +4 -0
  144. package/bin/Utils/Extensions/index.d.ts.map +1 -0
  145. package/bin/Utils/Extensions/index.js +5 -0
  146. package/bin/Utils/Extensions/index.js.map +1 -0
  147. package/bin/Utils/GlobalManager.d.ts +32 -0
  148. package/bin/Utils/GlobalManager.d.ts.map +1 -0
  149. package/bin/Utils/GlobalManager.js +53 -0
  150. package/bin/Utils/GlobalManager.js.map +1 -0
  151. package/bin/Utils/PerformanceMonitor.d.ts +211 -0
  152. package/bin/Utils/PerformanceMonitor.d.ts.map +1 -0
  153. package/bin/Utils/PerformanceMonitor.js +270 -0
  154. package/bin/Utils/PerformanceMonitor.js.map +1 -0
  155. package/bin/Utils/Pool.d.ts +239 -0
  156. package/bin/Utils/Pool.d.ts.map +1 -0
  157. package/bin/Utils/Pool.js +449 -0
  158. package/bin/Utils/Pool.js.map +1 -0
  159. package/bin/Utils/Screen.d.ts +12 -0
  160. package/bin/Utils/Screen.d.ts.map +1 -0
  161. package/bin/Utils/Screen.js +14 -0
  162. package/bin/Utils/Screen.js.map +1 -0
  163. package/bin/Utils/Time.d.ts +55 -0
  164. package/bin/Utils/Time.d.ts.map +1 -0
  165. package/bin/Utils/Time.js +78 -0
  166. package/bin/Utils/Time.js.map +1 -0
  167. package/bin/Utils/Timers/ITimer.d.ts +16 -0
  168. package/bin/Utils/Timers/ITimer.d.ts.map +1 -0
  169. package/bin/Utils/Timers/ITimer.js +2 -0
  170. package/bin/Utils/Timers/ITimer.js.map +1 -0
  171. package/bin/Utils/Timers/Timer.d.ts +22 -0
  172. package/bin/Utils/Timers/Timer.d.ts.map +1 -0
  173. package/bin/Utils/Timers/Timer.js +46 -0
  174. package/bin/Utils/Timers/Timer.js.map +1 -0
  175. package/bin/Utils/Timers/TimerManager.d.ts +19 -0
  176. package/bin/Utils/Timers/TimerManager.d.ts.map +1 -0
  177. package/bin/Utils/Timers/TimerManager.js +33 -0
  178. package/bin/Utils/Timers/TimerManager.js.map +1 -0
  179. package/bin/Utils/index.d.ts +6 -0
  180. package/bin/Utils/index.d.ts.map +1 -0
  181. package/bin/Utils/index.js +7 -0
  182. package/bin/Utils/index.js.map +1 -0
  183. package/bin/index.d.ts +21 -0
  184. package/bin/index.d.ts.map +1 -0
  185. package/bin/index.js +26 -0
  186. package/bin/index.js.map +1 -0
  187. package/package.json +68 -0
@@ -0,0 +1,1356 @@
1
+ import { ComponentRegistry } from './ComponentStorage';
2
+ /**
3
+ * 查询条件类型
4
+ */
5
+ export var QueryConditionType;
6
+ (function (QueryConditionType) {
7
+ /** 必须包含所有指定组件 */
8
+ QueryConditionType["ALL"] = "all";
9
+ /** 必须包含任意一个指定组件 */
10
+ QueryConditionType["ANY"] = "any";
11
+ /** 不能包含任何指定组件 */
12
+ QueryConditionType["NONE"] = "none";
13
+ })(QueryConditionType || (QueryConditionType = {}));
14
+ /**
15
+ * 高性能实体查询系统
16
+ * 使用位掩码进行快速组件匹配,支持多级索引和智能缓存
17
+ */
18
+ export class QuerySystem {
19
+ constructor() {
20
+ this.entities = [];
21
+ this.queryCache = new Map();
22
+ this.cacheTimeout = 1000; // 缓存超时时间(毫秒)
23
+ this.maxCacheSize = 100; // 最大缓存数量
24
+ this.cacheHits = 0;
25
+ this.cacheMisses = 0;
26
+ // 多级索引系统
27
+ this.entityIndex = {
28
+ byMask: new Map(),
29
+ byComponentType: new Map(),
30
+ byTag: new Map(),
31
+ byName: new Map()
32
+ };
33
+ // 性能统计
34
+ this.performanceStats = {
35
+ totalQueries: 0,
36
+ averageExecutionTime: 0,
37
+ cacheHitRate: 0,
38
+ indexHitRate: 0,
39
+ slowQueries: []
40
+ };
41
+ // 索引更新标志
42
+ this.indexDirty = true;
43
+ this.lastIndexUpdate = 0;
44
+ this.indexUpdateThreshold = 100; // 毫秒
45
+ // 批量操作缓冲区
46
+ this.pendingEntityAdds = [];
47
+ this.pendingEntityRemoves = [];
48
+ this.batchUpdateScheduled = false;
49
+ }
50
+ /**
51
+ * 设置实体列表
52
+ * @param entities 实体数组
53
+ */
54
+ setEntities(entities) {
55
+ this.entities = entities;
56
+ this.invalidateIndexes();
57
+ this.clearCache();
58
+ }
59
+ /**
60
+ * 添加实体
61
+ * @param entity 实体
62
+ */
63
+ addEntity(entity) {
64
+ this.pendingEntityAdds.push(entity);
65
+ this.scheduleBatchUpdate();
66
+ }
67
+ /**
68
+ * 批量添加实体
69
+ * @param entities 实体数组
70
+ */
71
+ addEntities(entities) {
72
+ this.pendingEntityAdds.push(...entities);
73
+ this.scheduleBatchUpdate();
74
+ }
75
+ /**
76
+ * 移除实体
77
+ * @param entity 实体
78
+ */
79
+ removeEntity(entity) {
80
+ this.pendingEntityRemoves.push(entity);
81
+ this.scheduleBatchUpdate();
82
+ }
83
+ /**
84
+ * 批量移除实体
85
+ * @param entities 实体数组
86
+ */
87
+ removeEntities(entities) {
88
+ this.pendingEntityRemoves.push(...entities);
89
+ this.scheduleBatchUpdate();
90
+ }
91
+ /**
92
+ * 调度批量更新
93
+ */
94
+ scheduleBatchUpdate() {
95
+ if (!this.batchUpdateScheduled) {
96
+ this.batchUpdateScheduled = true;
97
+ // 使用微任务确保在当前执行栈完成后立即执行
98
+ Promise.resolve().then(() => this.processBatchUpdates());
99
+ }
100
+ }
101
+ /**
102
+ * 处理批量更新
103
+ */
104
+ processBatchUpdates() {
105
+ this.batchUpdateScheduled = false;
106
+ // 处理添加
107
+ if (this.pendingEntityAdds.length > 0) {
108
+ this.entities.push(...this.pendingEntityAdds);
109
+ // 更新索引
110
+ for (const entity of this.pendingEntityAdds) {
111
+ this.addEntityToIndexes(entity);
112
+ }
113
+ this.pendingEntityAdds.length = 0;
114
+ }
115
+ // 处理移除
116
+ if (this.pendingEntityRemoves.length > 0) {
117
+ const removeSet = new Set(this.pendingEntityRemoves);
118
+ // 从实体列表中移除
119
+ this.entities = this.entities.filter(entity => !removeSet.has(entity));
120
+ // 从索引中移除
121
+ for (const entity of this.pendingEntityRemoves) {
122
+ this.removeEntityFromIndexes(entity);
123
+ }
124
+ this.pendingEntityRemoves.length = 0;
125
+ }
126
+ // 清空缓存
127
+ this.clearCache();
128
+ }
129
+ /**
130
+ * 强制立即处理所有待处理的更新
131
+ */
132
+ flushUpdates() {
133
+ if (this.batchUpdateScheduled) {
134
+ this.processBatchUpdates();
135
+ }
136
+ }
137
+ /**
138
+ * 无效化所有索引
139
+ */
140
+ invalidateIndexes() {
141
+ this.indexDirty = true;
142
+ this.entityIndex.byMask.clear();
143
+ this.entityIndex.byComponentType.clear();
144
+ this.entityIndex.byTag.clear();
145
+ this.entityIndex.byName.clear();
146
+ }
147
+ /**
148
+ * 将实体添加到索引
149
+ * @param entity 实体
150
+ */
151
+ addEntityToIndexes(entity) {
152
+ // 按位掩码索引
153
+ const mask = entity.componentMask;
154
+ if (!this.entityIndex.byMask.has(mask)) {
155
+ this.entityIndex.byMask.set(mask, new Set());
156
+ }
157
+ this.entityIndex.byMask.get(mask).add(entity);
158
+ // 按组件类型索引
159
+ for (const component of entity.components) {
160
+ const componentType = component.constructor;
161
+ if (!this.entityIndex.byComponentType.has(componentType)) {
162
+ this.entityIndex.byComponentType.set(componentType, new Set());
163
+ }
164
+ this.entityIndex.byComponentType.get(componentType).add(entity);
165
+ }
166
+ // 按标签索引
167
+ const tag = entity.tag;
168
+ if (!this.entityIndex.byTag.has(tag)) {
169
+ this.entityIndex.byTag.set(tag, new Set());
170
+ }
171
+ this.entityIndex.byTag.get(tag).add(entity);
172
+ // 按名称索引
173
+ const name = entity.name;
174
+ if (!this.entityIndex.byName.has(name)) {
175
+ this.entityIndex.byName.set(name, new Set());
176
+ }
177
+ this.entityIndex.byName.get(name).add(entity);
178
+ }
179
+ /**
180
+ * 从索引中移除实体
181
+ * @param entity 实体
182
+ */
183
+ removeEntityFromIndexes(entity) {
184
+ // 从位掩码索引移除
185
+ const mask = entity.componentMask;
186
+ const maskSet = this.entityIndex.byMask.get(mask);
187
+ if (maskSet) {
188
+ maskSet.delete(entity);
189
+ if (maskSet.size === 0) {
190
+ this.entityIndex.byMask.delete(mask);
191
+ }
192
+ }
193
+ // 从组件类型索引移除
194
+ for (const component of entity.components) {
195
+ const componentType = component.constructor;
196
+ const typeSet = this.entityIndex.byComponentType.get(componentType);
197
+ if (typeSet) {
198
+ typeSet.delete(entity);
199
+ if (typeSet.size === 0) {
200
+ this.entityIndex.byComponentType.delete(componentType);
201
+ }
202
+ }
203
+ }
204
+ // 从标签索引移除
205
+ const tagSet = this.entityIndex.byTag.get(entity.tag);
206
+ if (tagSet) {
207
+ tagSet.delete(entity);
208
+ if (tagSet.size === 0) {
209
+ this.entityIndex.byTag.delete(entity.tag);
210
+ }
211
+ }
212
+ // 从名称索引移除
213
+ const nameSet = this.entityIndex.byName.get(entity.name);
214
+ if (nameSet) {
215
+ nameSet.delete(entity);
216
+ if (nameSet.size === 0) {
217
+ this.entityIndex.byName.delete(entity.name);
218
+ }
219
+ }
220
+ }
221
+ /**
222
+ * 重建所有索引
223
+ */
224
+ rebuildIndexes() {
225
+ if (!this.indexDirty)
226
+ return;
227
+ this.invalidateIndexes();
228
+ for (const entity of this.entities) {
229
+ this.addEntityToIndexes(entity);
230
+ }
231
+ this.indexDirty = false;
232
+ this.lastIndexUpdate = Date.now();
233
+ }
234
+ /**
235
+ * 确保索引是最新的
236
+ */
237
+ ensureIndexesUpdated() {
238
+ const now = Date.now();
239
+ if (this.indexDirty || (now - this.lastIndexUpdate) > this.indexUpdateThreshold) {
240
+ this.rebuildIndexes();
241
+ }
242
+ }
243
+ /**
244
+ * 查询包含所有指定组件的实体
245
+ * @param componentTypes 组件类型数组
246
+ * @returns 查询结果
247
+ */
248
+ queryAll(...componentTypes) {
249
+ return this.query({
250
+ type: QueryConditionType.ALL,
251
+ componentTypes,
252
+ mask: this.createMask(componentTypes)
253
+ });
254
+ }
255
+ /**
256
+ * 查询包含任意指定组件的实体
257
+ * @param componentTypes 组件类型数组
258
+ * @returns 查询结果
259
+ */
260
+ queryAny(...componentTypes) {
261
+ return this.query({
262
+ type: QueryConditionType.ANY,
263
+ componentTypes,
264
+ mask: this.createMask(componentTypes)
265
+ });
266
+ }
267
+ /**
268
+ * 查询不包含任何指定组件的实体
269
+ * @param componentTypes 组件类型数组
270
+ * @returns 查询结果
271
+ */
272
+ queryNone(...componentTypes) {
273
+ return this.query({
274
+ type: QueryConditionType.NONE,
275
+ componentTypes,
276
+ mask: this.createMask(componentTypes)
277
+ });
278
+ }
279
+ /**
280
+ * 复合查询:同时满足多个条件
281
+ * @param conditions 查询条件数组
282
+ * @returns 查询结果
283
+ */
284
+ queryComplex(...conditions) {
285
+ const startTime = performance.now();
286
+ // 生成复合查询的缓存键
287
+ const cacheKey = this.generateComplexCacheKey(conditions);
288
+ // 检查缓存
289
+ const cached = this.getCachedResult(cacheKey);
290
+ if (cached) {
291
+ return {
292
+ entities: cached.entities,
293
+ count: cached.entities.length,
294
+ executionTime: performance.now() - startTime,
295
+ fromCache: true
296
+ };
297
+ }
298
+ // 执行查询
299
+ let result = this.entities.slice(); // 从所有实体开始
300
+ for (const condition of conditions) {
301
+ result = this.filterEntitiesByCondition(result, condition);
302
+ }
303
+ const executionTime = performance.now() - startTime;
304
+ // 缓存结果
305
+ this.cacheResult(cacheKey, result);
306
+ return {
307
+ entities: result,
308
+ count: result.length,
309
+ executionTime,
310
+ fromCache: false
311
+ };
312
+ }
313
+ /**
314
+ * 流式查询构建器
315
+ * @returns 查询构建器实例
316
+ */
317
+ createQuery() {
318
+ return new QueryBuilder(this);
319
+ }
320
+ /**
321
+ * 根据标签查询实体
322
+ * @param tag 标签
323
+ * @returns 查询结果
324
+ */
325
+ queryByTag(tag) {
326
+ const startTime = performance.now();
327
+ this.ensureIndexesUpdated();
328
+ const entities = Array.from(this.entityIndex.byTag.get(tag) || []);
329
+ const executionTime = performance.now() - startTime;
330
+ this.updatePerformanceStats(executionTime, true);
331
+ return {
332
+ entities,
333
+ count: entities.length,
334
+ executionTime,
335
+ fromCache: false
336
+ };
337
+ }
338
+ /**
339
+ * 根据名称查询实体
340
+ * @param name 名称
341
+ * @returns 查询结果
342
+ */
343
+ queryByName(name) {
344
+ const startTime = performance.now();
345
+ this.ensureIndexesUpdated();
346
+ const entities = Array.from(this.entityIndex.byName.get(name) || []);
347
+ const executionTime = performance.now() - startTime;
348
+ this.updatePerformanceStats(executionTime, true);
349
+ return {
350
+ entities,
351
+ count: entities.length,
352
+ executionTime,
353
+ fromCache: false
354
+ };
355
+ }
356
+ /**
357
+ * 根据单个组件类型快速查询
358
+ * @param componentType 组件类型
359
+ * @returns 查询结果
360
+ */
361
+ queryByComponent(componentType) {
362
+ const startTime = performance.now();
363
+ this.ensureIndexesUpdated();
364
+ const entities = Array.from(this.entityIndex.byComponentType.get(componentType) || []);
365
+ const executionTime = performance.now() - startTime;
366
+ this.updatePerformanceStats(executionTime, true);
367
+ return {
368
+ entities,
369
+ count: entities.length,
370
+ executionTime,
371
+ fromCache: false
372
+ };
373
+ }
374
+ /**
375
+ * 类型安全的查询所有指定组件的实体
376
+ * @param componentTypes 组件类型数组
377
+ * @returns 类型安全的查询结果
378
+ */
379
+ queryAllTyped(...componentTypes) {
380
+ const startTime = performance.now();
381
+ this.ensureIndexesUpdated();
382
+ const condition = {
383
+ type: QueryConditionType.ALL,
384
+ componentTypes: [...componentTypes],
385
+ mask: this.createMask([...componentTypes])
386
+ };
387
+ const entities = this.queryWithIndexOptimization(condition) ||
388
+ this.filterEntitiesByCondition(this.entities, condition);
389
+ // 提取组件
390
+ const components = [];
391
+ for (const entity of entities) {
392
+ const entityComponents = [];
393
+ let hasAllComponents = true;
394
+ for (const type of componentTypes) {
395
+ const component = entity.getComponent(type);
396
+ if (component === null) {
397
+ hasAllComponents = false;
398
+ break;
399
+ }
400
+ entityComponents.push(component);
401
+ }
402
+ if (hasAllComponents) {
403
+ components.push(entityComponents);
404
+ }
405
+ }
406
+ const executionTime = performance.now() - startTime;
407
+ this.updatePerformanceStats(executionTime, false);
408
+ return {
409
+ entities,
410
+ components,
411
+ count: entities.length,
412
+ executionTime,
413
+ fromCache: false
414
+ };
415
+ }
416
+ /**
417
+ * 查询具有特定组件组合的实体并返回组件实例
418
+ * @param componentTypes 组件类型数组
419
+ * @returns 实体和对应组件的映射
420
+ */
421
+ queryWithComponents(...componentTypes) {
422
+ const result = this.queryAllTyped(...componentTypes);
423
+ return result.entities.map((entity, index) => ({
424
+ entity,
425
+ components: result.components[index]
426
+ }));
427
+ }
428
+ /**
429
+ * 迭代查询结果,为每个匹配的实体执行回调
430
+ * @param componentTypes 组件类型数组
431
+ * @param callback 回调函数
432
+ */
433
+ forEachWithComponents(componentTypes, callback) {
434
+ const result = this.queryAllTyped(...componentTypes);
435
+ for (let i = 0; i < result.entities.length; i++) {
436
+ callback(result.entities[i], result.components[i]);
437
+ }
438
+ }
439
+ /**
440
+ * 查询单个组件类型的实体,返回类型安全的结果
441
+ * @param componentType 组件类型
442
+ * @returns 实体和组件的配对数组
443
+ */
444
+ queryComponentTyped(componentType) {
445
+ const startTime = performance.now();
446
+ this.ensureIndexesUpdated();
447
+ const entities = Array.from(this.entityIndex.byComponentType.get(componentType) || []);
448
+ const result = [];
449
+ for (const entity of entities) {
450
+ const component = entity.getComponent(componentType);
451
+ if (component) {
452
+ result.push({ entity, component });
453
+ }
454
+ }
455
+ const executionTime = performance.now() - startTime;
456
+ this.updatePerformanceStats(executionTime, true);
457
+ return result;
458
+ }
459
+ /**
460
+ * 查询两个组件类型的实体,返回类型安全的结果
461
+ * @param componentType1 第一个组件类型
462
+ * @param componentType2 第二个组件类型
463
+ * @returns 实体和组件的配对数组
464
+ */
465
+ queryTwoComponents(componentType1, componentType2) {
466
+ const result = this.queryAllTyped(componentType1, componentType2);
467
+ return result.entities.map((entity, index) => ({
468
+ entity,
469
+ component1: result.components[index][0],
470
+ component2: result.components[index][1]
471
+ }));
472
+ }
473
+ /**
474
+ * 查询三个组件类型的实体,返回类型安全的结果
475
+ * @param componentType1 第一个组件类型
476
+ * @param componentType2 第二个组件类型
477
+ * @param componentType3 第三个组件类型
478
+ * @returns 实体和组件的配对数组
479
+ */
480
+ queryThreeComponents(componentType1, componentType2, componentType3) {
481
+ const result = this.queryAllTyped(componentType1, componentType2, componentType3);
482
+ return result.entities.map((entity, index) => ({
483
+ entity,
484
+ component1: result.components[index][0],
485
+ component2: result.components[index][1],
486
+ component3: result.components[index][2]
487
+ }));
488
+ }
489
+ /**
490
+ * 执行单个条件查询
491
+ * @param condition 查询条件
492
+ * @returns 查询结果
493
+ */
494
+ query(condition) {
495
+ const startTime = performance.now();
496
+ // 确保索引是最新的
497
+ this.ensureIndexesUpdated();
498
+ // 生成缓存键
499
+ const cacheKey = this.generateCacheKey(condition);
500
+ // 检查缓存
501
+ const cached = this.getCachedResult(cacheKey);
502
+ if (cached) {
503
+ this.updatePerformanceStats(performance.now() - startTime, false);
504
+ return {
505
+ entities: cached.entities,
506
+ count: cached.entities.length,
507
+ executionTime: performance.now() - startTime,
508
+ fromCache: true
509
+ };
510
+ }
511
+ // 尝试使用索引优化查询
512
+ let result = this.queryWithIndexOptimization(condition);
513
+ // 如果索引优化失败,回退到传统查询
514
+ if (!result) {
515
+ result = this.filterEntitiesByCondition(this.entities, condition);
516
+ }
517
+ const executionTime = performance.now() - startTime;
518
+ // 缓存结果
519
+ this.cacheResult(cacheKey, result);
520
+ // 更新性能统计
521
+ this.updatePerformanceStats(executionTime, false);
522
+ return {
523
+ entities: result,
524
+ count: result.length,
525
+ executionTime,
526
+ fromCache: false
527
+ };
528
+ }
529
+ /**
530
+ * 使用索引优化查询
531
+ * @param condition 查询条件
532
+ * @returns 查询结果或null(如果无法优化)
533
+ */
534
+ queryWithIndexOptimization(condition) {
535
+ // 对于单组件查询,直接使用组件索引
536
+ if (condition.componentTypes.length === 1 && condition.type === QueryConditionType.ALL) {
537
+ const componentType = condition.componentTypes[0];
538
+ const entities = this.entityIndex.byComponentType.get(componentType);
539
+ return entities ? Array.from(entities) : [];
540
+ }
541
+ // 对于多组件ALL查询,找到最小的组件集合作为起点
542
+ if (condition.type === QueryConditionType.ALL && condition.componentTypes.length > 1) {
543
+ let smallestSet = null;
544
+ let smallestSize = Infinity;
545
+ for (const componentType of condition.componentTypes) {
546
+ const entities = this.entityIndex.byComponentType.get(componentType);
547
+ if (!entities)
548
+ return []; // 如果任何组件都没有实体,结果为空
549
+ if (entities.size < smallestSize) {
550
+ smallestSize = entities.size;
551
+ smallestSet = entities;
552
+ }
553
+ }
554
+ if (!smallestSet)
555
+ return [];
556
+ // 从最小集合开始,检查每个实体是否包含所有其他组件
557
+ const result = [];
558
+ for (const entity of smallestSet) {
559
+ if (this.matchesCondition(entity, condition)) {
560
+ result.push(entity);
561
+ }
562
+ }
563
+ return result;
564
+ }
565
+ // 对于ANY查询,合并所有相关组件的实体集合
566
+ if (condition.type === QueryConditionType.ANY) {
567
+ const entitySet = new Set();
568
+ for (const componentType of condition.componentTypes) {
569
+ const entities = this.entityIndex.byComponentType.get(componentType);
570
+ if (entities) {
571
+ for (const entity of entities) {
572
+ entitySet.add(entity);
573
+ }
574
+ }
575
+ }
576
+ return Array.from(entitySet);
577
+ }
578
+ // 对于NONE查询,从所有实体中排除包含指定组件的实体
579
+ if (condition.type === QueryConditionType.NONE) {
580
+ const excludeSet = new Set();
581
+ for (const componentType of condition.componentTypes) {
582
+ const entities = this.entityIndex.byComponentType.get(componentType);
583
+ if (entities) {
584
+ for (const entity of entities) {
585
+ excludeSet.add(entity);
586
+ }
587
+ }
588
+ }
589
+ return this.entities.filter(entity => !excludeSet.has(entity));
590
+ }
591
+ return null; // 无法优化
592
+ }
593
+ /**
594
+ * 更新性能统计
595
+ * @param executionTime 执行时间
596
+ * @param fromIndex 是否来自索引
597
+ */
598
+ updatePerformanceStats(executionTime, fromIndex) {
599
+ this.performanceStats.totalQueries++;
600
+ // 更新平均执行时间
601
+ const totalTime = this.performanceStats.averageExecutionTime * (this.performanceStats.totalQueries - 1) + executionTime;
602
+ this.performanceStats.averageExecutionTime = totalTime / this.performanceStats.totalQueries;
603
+ // 更新缓存命中率
604
+ this.performanceStats.cacheHitRate = this.cacheHits / (this.cacheHits + this.cacheMisses);
605
+ // 更新索引命中率
606
+ if (fromIndex) {
607
+ this.performanceStats.indexHitRate = (this.performanceStats.indexHitRate * (this.performanceStats.totalQueries - 1) + 1) / this.performanceStats.totalQueries;
608
+ }
609
+ else {
610
+ this.performanceStats.indexHitRate = (this.performanceStats.indexHitRate * (this.performanceStats.totalQueries - 1)) / this.performanceStats.totalQueries;
611
+ }
612
+ // 记录慢查询
613
+ if (executionTime > 10) { // 超过10ms的查询被认为是慢查询
614
+ this.performanceStats.slowQueries.push({
615
+ query: `执行时间: ${executionTime.toFixed(2)}ms`,
616
+ executionTime,
617
+ timestamp: Date.now()
618
+ });
619
+ // 只保留最近的50个慢查询
620
+ if (this.performanceStats.slowQueries.length > 50) {
621
+ this.performanceStats.slowQueries.shift();
622
+ }
623
+ }
624
+ }
625
+ /**
626
+ * 根据条件过滤实体
627
+ * @param entities 实体数组
628
+ * @param condition 查询条件
629
+ * @returns 过滤后的实体数组
630
+ */
631
+ filterEntitiesByCondition(entities, condition) {
632
+ const result = [];
633
+ for (const entity of entities) {
634
+ if (this.matchesCondition(entity, condition)) {
635
+ result.push(entity);
636
+ }
637
+ }
638
+ return result;
639
+ }
640
+ /**
641
+ * 检查实体是否匹配条件
642
+ * @param entity 实体
643
+ * @param condition 查询条件
644
+ * @returns 是否匹配
645
+ */
646
+ matchesCondition(entity, condition) {
647
+ const entityMask = entity.componentMask;
648
+ switch (condition.type) {
649
+ case QueryConditionType.ALL:
650
+ // 实体必须包含所有指定组件
651
+ return (entityMask & condition.mask) === condition.mask;
652
+ case QueryConditionType.ANY:
653
+ // 实体必须包含至少一个指定组件
654
+ return (entityMask & condition.mask) !== BigInt(0);
655
+ case QueryConditionType.NONE:
656
+ // 实体不能包含任何指定组件
657
+ return (entityMask & condition.mask) === BigInt(0);
658
+ default:
659
+ return false;
660
+ }
661
+ }
662
+ /**
663
+ * 创建组件类型的位掩码
664
+ * @param componentTypes 组件类型数组
665
+ * @returns 位掩码
666
+ */
667
+ createMask(componentTypes) {
668
+ let mask = BigInt(0);
669
+ for (const componentType of componentTypes) {
670
+ if (ComponentRegistry.isRegistered(componentType)) {
671
+ mask |= ComponentRegistry.getBitMask(componentType);
672
+ }
673
+ }
674
+ return mask;
675
+ }
676
+ /**
677
+ * 生成缓存键
678
+ * @param condition 查询条件
679
+ * @returns 缓存键
680
+ */
681
+ generateCacheKey(condition) {
682
+ const typeNames = condition.componentTypes.map(t => t.name).sort().join(',');
683
+ return `${condition.type}:${typeNames}`;
684
+ }
685
+ /**
686
+ * 生成复合查询的缓存键
687
+ * @param conditions 查询条件数组
688
+ * @returns 缓存键
689
+ */
690
+ generateComplexCacheKey(conditions) {
691
+ const conditionKeys = conditions.map(c => this.generateCacheKey(c));
692
+ return `complex:${conditionKeys.join('|')}`;
693
+ }
694
+ /**
695
+ * 获取缓存结果
696
+ * @param cacheKey 缓存键
697
+ * @returns 缓存项或null
698
+ */
699
+ getCachedResult(cacheKey) {
700
+ const cached = this.queryCache.get(cacheKey);
701
+ if (cached) {
702
+ const now = Date.now();
703
+ if (now - cached.lastUpdate < this.cacheTimeout) {
704
+ cached.hitCount++;
705
+ this.cacheHits++;
706
+ return cached;
707
+ }
708
+ else {
709
+ // 缓存过期,删除
710
+ this.queryCache.delete(cacheKey);
711
+ }
712
+ }
713
+ this.cacheMisses++;
714
+ return null;
715
+ }
716
+ /**
717
+ * 缓存查询结果
718
+ * @param cacheKey 缓存键
719
+ * @param entities 实体数组
720
+ */
721
+ cacheResult(cacheKey, entities) {
722
+ // 如果缓存已满,删除最少使用的项
723
+ if (this.queryCache.size >= this.maxCacheSize) {
724
+ this.evictLeastUsedCache();
725
+ }
726
+ this.queryCache.set(cacheKey, {
727
+ entities: entities.slice(), // 创建副本
728
+ lastUpdate: Date.now(),
729
+ hitCount: 0
730
+ });
731
+ }
732
+ /**
733
+ * 清空查询缓存
734
+ */
735
+ clearCache() {
736
+ this.queryCache.clear();
737
+ }
738
+ /**
739
+ * 删除最少使用的缓存项
740
+ */
741
+ evictLeastUsedCache() {
742
+ let leastUsedKey = '';
743
+ let minHitCount = Number.MAX_VALUE;
744
+ for (const [key, item] of this.queryCache.entries()) {
745
+ if (item.hitCount < minHitCount) {
746
+ minHitCount = item.hitCount;
747
+ leastUsedKey = key;
748
+ }
749
+ }
750
+ if (leastUsedKey) {
751
+ this.queryCache.delete(leastUsedKey);
752
+ }
753
+ }
754
+ /**
755
+ * 获取详细的查询统计信息
756
+ */
757
+ getStats() {
758
+ const totalQueries = this.cacheHits + this.cacheMisses;
759
+ const hitRate = totalQueries > 0 ? this.cacheHits / totalQueries : 0;
760
+ return {
761
+ entityCount: this.entities.length,
762
+ cacheSize: this.queryCache.size,
763
+ cacheHits: this.cacheHits,
764
+ cacheMisses: this.cacheMisses,
765
+ hitRate,
766
+ maxCacheSize: this.maxCacheSize,
767
+ indexStats: {
768
+ maskIndexSize: this.entityIndex.byMask.size,
769
+ componentIndexSize: this.entityIndex.byComponentType.size,
770
+ tagIndexSize: this.entityIndex.byTag.size,
771
+ nameIndexSize: this.entityIndex.byName.size
772
+ },
773
+ performanceStats: { ...this.performanceStats }
774
+ };
775
+ }
776
+ /**
777
+ * 获取性能报告
778
+ */
779
+ getPerformanceReport() {
780
+ const stats = this.getStats();
781
+ let report = '=== 查询系统性能报告 ===\n';
782
+ report += `实体数量: ${stats.entityCount}\n`;
783
+ report += `总查询次数: ${stats.performanceStats.totalQueries}\n`;
784
+ report += `平均执行时间: ${stats.performanceStats.averageExecutionTime.toFixed(2)}ms\n`;
785
+ report += `缓存命中率: ${(stats.performanceStats.cacheHitRate * 100).toFixed(1)}%\n`;
786
+ report += `索引命中率: ${(stats.performanceStats.indexHitRate * 100).toFixed(1)}%\n`;
787
+ report += '\n=== 索引统计 ===\n';
788
+ report += `位掩码索引: ${stats.indexStats.maskIndexSize} 项\n`;
789
+ report += `组件类型索引: ${stats.indexStats.componentIndexSize} 项\n`;
790
+ report += `标签索引: ${stats.indexStats.tagIndexSize} 项\n`;
791
+ report += `名称索引: ${stats.indexStats.nameIndexSize} 项\n`;
792
+ if (stats.performanceStats.slowQueries.length > 0) {
793
+ report += '\n=== 慢查询记录 ===\n';
794
+ stats.performanceStats.slowQueries.slice(-10).forEach((query, index) => {
795
+ const time = new Date(query.timestamp).toLocaleTimeString();
796
+ report += `${index + 1}. ${query.query} (${time})\n`;
797
+ });
798
+ }
799
+ return report;
800
+ }
801
+ /**
802
+ * 优化索引配置
803
+ */
804
+ optimizeIndexes() {
805
+ // 根据查询模式优化索引更新频率
806
+ if (this.performanceStats.totalQueries > 1000) {
807
+ // 高频查询场景,降低索引更新阈值
808
+ this.indexUpdateThreshold = 50;
809
+ }
810
+ else {
811
+ // 低频查询场景,提高索引更新阈值
812
+ this.indexUpdateThreshold = 200;
813
+ }
814
+ // 根据缓存命中率调整缓存大小
815
+ if (this.performanceStats.cacheHitRate < 0.5 && this.maxCacheSize < 200) {
816
+ this.maxCacheSize = Math.min(200, this.maxCacheSize * 1.5);
817
+ }
818
+ else if (this.performanceStats.cacheHitRate > 0.9 && this.maxCacheSize > 50) {
819
+ this.maxCacheSize = Math.max(50, this.maxCacheSize * 0.8);
820
+ }
821
+ }
822
+ /**
823
+ * 批量查询多个条件
824
+ * @param queries 查询条件数组
825
+ * @returns 查询结果数组
826
+ */
827
+ batchQuery(queries) {
828
+ const startTime = performance.now();
829
+ this.ensureIndexesUpdated();
830
+ const results = [];
831
+ for (const query of queries) {
832
+ const result = this.query(query);
833
+ results.push(result);
834
+ }
835
+ const totalTime = performance.now() - startTime;
836
+ console.log(`批量查询 ${queries.length} 个条件,总耗时: ${totalTime.toFixed(2)}ms`);
837
+ return results;
838
+ }
839
+ /**
840
+ * 设置缓存配置
841
+ * @param maxSize 最大缓存大小
842
+ * @param timeout 缓存超时时间(毫秒)
843
+ */
844
+ setCacheConfig(maxSize, timeout) {
845
+ this.maxCacheSize = maxSize;
846
+ this.cacheTimeout = timeout;
847
+ }
848
+ /**
849
+ * 重置统计信息
850
+ */
851
+ resetStats() {
852
+ this.cacheHits = 0;
853
+ this.cacheMisses = 0;
854
+ this.performanceStats = {
855
+ totalQueries: 0,
856
+ averageExecutionTime: 0,
857
+ cacheHitRate: 0,
858
+ indexHitRate: 0,
859
+ slowQueries: []
860
+ };
861
+ }
862
+ /**
863
+ * 预热查询缓存
864
+ * @param commonQueries 常用查询条件数组
865
+ */
866
+ warmUpCache(commonQueries) {
867
+ console.log('开始预热查询缓存...');
868
+ const startTime = performance.now();
869
+ for (const condition of commonQueries) {
870
+ this.query(condition);
871
+ }
872
+ const endTime = performance.now();
873
+ console.log(`缓存预热完成,耗时: ${(endTime - startTime).toFixed(2)}ms`);
874
+ }
875
+ /**
876
+ * 获取实体变更监听器
877
+ * @param condition 查询条件
878
+ * @param callback 变更回调
879
+ * @returns 取消监听的函数
880
+ */
881
+ watchQuery(condition, callback) {
882
+ let lastResult = this.query(condition).entities;
883
+ const checkChanges = () => {
884
+ const currentResult = this.query(condition).entities;
885
+ // 检查新增的实体
886
+ const added = currentResult.filter(entity => !lastResult.includes(entity));
887
+ if (added.length > 0) {
888
+ callback(added, 'added');
889
+ }
890
+ // 检查移除的实体
891
+ const removed = lastResult.filter(entity => !currentResult.includes(entity));
892
+ if (removed.length > 0) {
893
+ callback(removed, 'removed');
894
+ }
895
+ lastResult = currentResult;
896
+ };
897
+ // 使用定时器定期检查变更(实际项目中可能需要更高效的实现)
898
+ const intervalId = setInterval(checkChanges, 100);
899
+ return () => {
900
+ clearInterval(intervalId);
901
+ };
902
+ }
903
+ /**
904
+ * 获取查询结果的快照
905
+ * @param condition 查询条件
906
+ * @returns 查询快照
907
+ */
908
+ createSnapshot(condition) {
909
+ const result = this.query(condition);
910
+ return {
911
+ entities: [...result.entities], // 创建副本
912
+ timestamp: Date.now(),
913
+ condition: { ...condition }
914
+ };
915
+ }
916
+ /**
917
+ * 比较两个查询快照
918
+ * @param snapshot1 第一个快照
919
+ * @param snapshot2 第二个快照
920
+ * @returns 比较结果
921
+ */
922
+ compareSnapshots(snapshot1, snapshot2) {
923
+ const set1 = new Set(snapshot1.entities);
924
+ const set2 = new Set(snapshot2.entities);
925
+ const added = snapshot2.entities.filter(entity => !set1.has(entity));
926
+ const removed = snapshot1.entities.filter(entity => !set2.has(entity));
927
+ const unchanged = snapshot1.entities.filter(entity => set2.has(entity));
928
+ return { added, removed, unchanged };
929
+ }
930
+ /**
931
+ * 执行并行查询
932
+ * @param conditions 查询条件数组
933
+ * @returns Promise<查询结果数组>
934
+ */
935
+ async parallelQuery(conditions) {
936
+ const promises = conditions.map(condition => Promise.resolve(this.query(condition)));
937
+ return Promise.all(promises);
938
+ }
939
+ /**
940
+ * 获取查询建议
941
+ * @param entities 实体数组
942
+ * @returns 查询优化建议
943
+ */
944
+ getQuerySuggestions(entities) {
945
+ const suggestions = [];
946
+ // 分析组件使用频率
947
+ const componentFrequency = new Map();
948
+ for (const entity of entities) {
949
+ for (const component of entity.components) {
950
+ const type = component.constructor;
951
+ componentFrequency.set(type, (componentFrequency.get(type) || 0) + 1);
952
+ }
953
+ }
954
+ // 建议基于高频组件的查询
955
+ const sortedComponents = Array.from(componentFrequency.entries())
956
+ .sort((a, b) => b[1] - a[1])
957
+ .slice(0, 5);
958
+ for (const [componentType, count] of sortedComponents) {
959
+ suggestions.push(`考虑为组件 ${componentType.name} 创建专门的查询(使用频率: ${count})`);
960
+ }
961
+ // 建议缓存配置
962
+ if (this.performanceStats.cacheHitRate < 0.5) {
963
+ suggestions.push('缓存命中率较低,考虑增加缓存大小或调整缓存策略');
964
+ }
965
+ // 建议索引优化
966
+ if (this.performanceStats.indexHitRate < 0.7) {
967
+ suggestions.push('索引命中率较低,考虑重建索引或优化查询条件');
968
+ }
969
+ return suggestions;
970
+ }
971
+ /**
972
+ * 导出查询统计数据
973
+ * @returns 统计数据的JSON字符串
974
+ */
975
+ exportStats() {
976
+ const stats = this.getStats();
977
+ return JSON.stringify(stats, null, 2);
978
+ }
979
+ /**
980
+ * 导入查询统计数据
981
+ * @param statsJson 统计数据的JSON字符串
982
+ */
983
+ importStats(statsJson) {
984
+ try {
985
+ const stats = JSON.parse(statsJson);
986
+ this.cacheHits = stats.cacheHits || 0;
987
+ this.cacheMisses = stats.cacheMisses || 0;
988
+ this.performanceStats = stats.performanceStats || this.performanceStats;
989
+ }
990
+ catch (error) {
991
+ console.error('导入统计数据失败:', error);
992
+ }
993
+ }
994
+ }
995
+ /**
996
+ * 流式查询构建器
997
+ * 提供链式调用的查询API
998
+ */
999
+ export class QueryBuilder {
1000
+ constructor(querySystem) {
1001
+ this.conditions = [];
1002
+ this.querySystem = querySystem;
1003
+ }
1004
+ /**
1005
+ * 添加"包含所有"条件
1006
+ * @param componentTypes 组件类型
1007
+ * @returns 查询构建器
1008
+ */
1009
+ withAll(...componentTypes) {
1010
+ this.conditions.push({
1011
+ type: QueryConditionType.ALL,
1012
+ componentTypes,
1013
+ mask: this.createMask(componentTypes)
1014
+ });
1015
+ return this;
1016
+ }
1017
+ /**
1018
+ * 添加"包含任意"条件
1019
+ * @param componentTypes 组件类型
1020
+ * @returns 查询构建器
1021
+ */
1022
+ withAny(...componentTypes) {
1023
+ this.conditions.push({
1024
+ type: QueryConditionType.ANY,
1025
+ componentTypes,
1026
+ mask: this.createMask(componentTypes)
1027
+ });
1028
+ return this;
1029
+ }
1030
+ /**
1031
+ * 添加"不包含"条件
1032
+ * @param componentTypes 组件类型
1033
+ * @returns 查询构建器
1034
+ */
1035
+ without(...componentTypes) {
1036
+ this.conditions.push({
1037
+ type: QueryConditionType.NONE,
1038
+ componentTypes,
1039
+ mask: this.createMask(componentTypes)
1040
+ });
1041
+ return this;
1042
+ }
1043
+ /**
1044
+ * 执行查询
1045
+ * @returns 查询结果
1046
+ */
1047
+ execute() {
1048
+ let result;
1049
+ if (this.conditions.length === 0) {
1050
+ // 如果没有组件条件,但有其他过滤条件
1051
+ if (this.tagFilter !== undefined) {
1052
+ result = this.querySystem.queryByTag(this.tagFilter);
1053
+ }
1054
+ else if (this.nameFilter !== undefined) {
1055
+ result = this.querySystem.queryByName(this.nameFilter);
1056
+ }
1057
+ else {
1058
+ return {
1059
+ entities: [],
1060
+ count: 0,
1061
+ executionTime: 0,
1062
+ fromCache: false
1063
+ };
1064
+ }
1065
+ }
1066
+ else if (this.conditions.length === 1) {
1067
+ // 单条件查询,使用优化路径
1068
+ const condition = this.conditions[0];
1069
+ switch (condition.type) {
1070
+ case QueryConditionType.ALL:
1071
+ result = this.querySystem.queryAll(...condition.componentTypes);
1072
+ break;
1073
+ case QueryConditionType.ANY:
1074
+ result = this.querySystem.queryAny(...condition.componentTypes);
1075
+ break;
1076
+ case QueryConditionType.NONE:
1077
+ result = this.querySystem.queryNone(...condition.componentTypes);
1078
+ break;
1079
+ default:
1080
+ return {
1081
+ entities: [],
1082
+ count: 0,
1083
+ executionTime: 0,
1084
+ fromCache: false
1085
+ };
1086
+ }
1087
+ }
1088
+ else {
1089
+ // 多条件查询
1090
+ result = this.querySystem.queryComplex(...this.conditions);
1091
+ }
1092
+ // 应用额外的过滤条件
1093
+ let entities = result.entities;
1094
+ // 标签过滤
1095
+ if (this.tagFilter !== undefined) {
1096
+ entities = entities.filter(entity => entity.tag === this.tagFilter);
1097
+ }
1098
+ // 名称过滤
1099
+ if (this.nameFilter !== undefined) {
1100
+ entities = entities.filter(entity => entity.name === this.nameFilter);
1101
+ }
1102
+ // 排序
1103
+ if (this.sortFunction) {
1104
+ entities = [...entities].sort(this.sortFunction);
1105
+ }
1106
+ // 偏移
1107
+ if (this.offsetCount !== undefined && this.offsetCount > 0) {
1108
+ entities = entities.slice(this.offsetCount);
1109
+ }
1110
+ // 限制
1111
+ if (this.limitCount !== undefined && this.limitCount > 0) {
1112
+ entities = entities.slice(0, this.limitCount);
1113
+ }
1114
+ return {
1115
+ entities,
1116
+ count: entities.length,
1117
+ executionTime: result.executionTime,
1118
+ fromCache: result.fromCache
1119
+ };
1120
+ }
1121
+ /**
1122
+ * 获取第一个匹配的实体
1123
+ * @returns 实体或null
1124
+ */
1125
+ first() {
1126
+ const result = this.execute();
1127
+ return result.entities.length > 0 ? result.entities[0] : null;
1128
+ }
1129
+ /**
1130
+ * 检查是否有匹配的实体
1131
+ * @returns 是否有匹配
1132
+ */
1133
+ any() {
1134
+ const result = this.execute();
1135
+ return result.count > 0;
1136
+ }
1137
+ /**
1138
+ * 获取匹配实体的数量
1139
+ * @returns 实体数量
1140
+ */
1141
+ count() {
1142
+ const result = this.execute();
1143
+ return result.count;
1144
+ }
1145
+ /**
1146
+ * 对每个匹配的实体执行操作
1147
+ * @param callback 回调函数
1148
+ */
1149
+ forEach(callback) {
1150
+ const result = this.execute();
1151
+ result.entities.forEach(callback);
1152
+ }
1153
+ /**
1154
+ * 转换为数组
1155
+ * @returns 实体数组
1156
+ */
1157
+ toArray() {
1158
+ const result = this.execute();
1159
+ return result.entities;
1160
+ }
1161
+ /**
1162
+ * 创建组件类型的位掩码
1163
+ * @param componentTypes 组件类型数组
1164
+ * @returns 位掩码
1165
+ */
1166
+ createMask(componentTypes) {
1167
+ let mask = BigInt(0);
1168
+ for (const componentType of componentTypes) {
1169
+ if (ComponentRegistry.isRegistered(componentType)) {
1170
+ mask |= ComponentRegistry.getBitMask(componentType);
1171
+ }
1172
+ }
1173
+ return mask;
1174
+ }
1175
+ /**
1176
+ * 重置查询条件
1177
+ * @returns 查询构建器
1178
+ */
1179
+ reset() {
1180
+ this.conditions.length = 0;
1181
+ this.tagFilter = undefined;
1182
+ this.nameFilter = undefined;
1183
+ this.limitCount = undefined;
1184
+ this.offsetCount = undefined;
1185
+ this.sortFunction = undefined;
1186
+ return this;
1187
+ }
1188
+ /**
1189
+ * 添加标签过滤条件
1190
+ * @param tag 标签
1191
+ * @returns 查询构建器实例
1192
+ */
1193
+ withTag(tag) {
1194
+ this.tagFilter = tag;
1195
+ return this;
1196
+ }
1197
+ /**
1198
+ * 添加名称过滤条件
1199
+ * @param name 名称
1200
+ * @returns 查询构建器实例
1201
+ */
1202
+ withName(name) {
1203
+ this.nameFilter = name;
1204
+ return this;
1205
+ }
1206
+ /**
1207
+ * 限制结果数量
1208
+ * @param limit 最大结果数量
1209
+ * @returns 查询构建器实例
1210
+ */
1211
+ limit(limit) {
1212
+ this.limitCount = limit;
1213
+ return this;
1214
+ }
1215
+ /**
1216
+ * 跳过指定数量的结果
1217
+ * @param offset 跳过的数量
1218
+ * @returns 查询构建器实例
1219
+ */
1220
+ offset(offset) {
1221
+ this.offsetCount = offset;
1222
+ return this;
1223
+ }
1224
+ /**
1225
+ * 对结果进行排序
1226
+ * @param compareFn 比较函数
1227
+ * @returns 查询构建器实例
1228
+ */
1229
+ orderBy(compareFn) {
1230
+ this.sortFunction = compareFn;
1231
+ return this;
1232
+ }
1233
+ /**
1234
+ * 按更新顺序排序
1235
+ * @returns 查询构建器实例
1236
+ */
1237
+ orderByUpdateOrder() {
1238
+ return this.orderBy((a, b) => a.updateOrder - b.updateOrder);
1239
+ }
1240
+ /**
1241
+ * 按ID排序
1242
+ * @returns 查询构建器实例
1243
+ */
1244
+ orderById() {
1245
+ return this.orderBy((a, b) => a.id - b.id);
1246
+ }
1247
+ /**
1248
+ * 按名称排序
1249
+ * @returns 查询构建器实例
1250
+ */
1251
+ orderByName() {
1252
+ return this.orderBy((a, b) => a.name.localeCompare(b.name));
1253
+ }
1254
+ /**
1255
+ * 克隆查询构建器
1256
+ * @returns 新的查询构建器
1257
+ */
1258
+ clone() {
1259
+ const newBuilder = new QueryBuilder(this.querySystem);
1260
+ newBuilder.conditions = this.conditions.map(c => ({ ...c }));
1261
+ newBuilder.tagFilter = this.tagFilter;
1262
+ newBuilder.nameFilter = this.nameFilter;
1263
+ newBuilder.limitCount = this.limitCount;
1264
+ newBuilder.offsetCount = this.offsetCount;
1265
+ newBuilder.sortFunction = this.sortFunction;
1266
+ return newBuilder;
1267
+ }
1268
+ /**
1269
+ * 添加自定义过滤器
1270
+ * @param predicate 过滤谓词
1271
+ * @returns 查询构建器实例
1272
+ */
1273
+ filter(predicate) {
1274
+ const originalExecute = this.execute.bind(this);
1275
+ this.execute = () => {
1276
+ const result = originalExecute();
1277
+ const filteredEntities = result.entities.filter(predicate);
1278
+ return {
1279
+ ...result,
1280
+ entities: filteredEntities,
1281
+ count: filteredEntities.length
1282
+ };
1283
+ };
1284
+ return this;
1285
+ }
1286
+ /**
1287
+ * 映射查询结果
1288
+ * @param mapper 映射函数
1289
+ * @returns 映射后的结果数组
1290
+ */
1291
+ map(mapper) {
1292
+ const result = this.execute();
1293
+ return result.entities.map(mapper);
1294
+ }
1295
+ /**
1296
+ * 查找第一个满足条件的实体
1297
+ * @param predicate 查找谓词
1298
+ * @returns 实体或null
1299
+ */
1300
+ find(predicate) {
1301
+ const result = this.execute();
1302
+ if (predicate) {
1303
+ return result.entities.find(predicate) || null;
1304
+ }
1305
+ return result.entities[0] || null;
1306
+ }
1307
+ /**
1308
+ * 检查是否所有实体都满足条件
1309
+ * @param predicate 检查谓词
1310
+ * @returns 是否所有实体都满足条件
1311
+ */
1312
+ every(predicate) {
1313
+ const result = this.execute();
1314
+ return result.entities.every(predicate);
1315
+ }
1316
+ /**
1317
+ * 检查是否有实体满足条件
1318
+ * @param predicate 检查谓词
1319
+ * @returns 是否有实体满足条件
1320
+ */
1321
+ some(predicate) {
1322
+ const result = this.execute();
1323
+ return result.entities.some(predicate);
1324
+ }
1325
+ /**
1326
+ * 获取查询的调试信息
1327
+ * @returns 调试信息字符串
1328
+ */
1329
+ getDebugInfo() {
1330
+ let info = '=== 查询构建器调试信息 ===\n';
1331
+ if (this.conditions.length > 0) {
1332
+ info += '组件条件:\n';
1333
+ this.conditions.forEach((condition, index) => {
1334
+ const typeNames = condition.componentTypes.map(t => t.name).join(', ');
1335
+ info += ` ${index + 1}. ${condition.type}: [${typeNames}]\n`;
1336
+ });
1337
+ }
1338
+ if (this.tagFilter !== undefined) {
1339
+ info += `标签过滤: ${this.tagFilter}\n`;
1340
+ }
1341
+ if (this.nameFilter !== undefined) {
1342
+ info += `名称过滤: ${this.nameFilter}\n`;
1343
+ }
1344
+ if (this.limitCount !== undefined) {
1345
+ info += `限制数量: ${this.limitCount}\n`;
1346
+ }
1347
+ if (this.offsetCount !== undefined) {
1348
+ info += `偏移量: ${this.offsetCount}\n`;
1349
+ }
1350
+ if (this.sortFunction) {
1351
+ info += '已设置排序函数\n';
1352
+ }
1353
+ return info;
1354
+ }
1355
+ }
1356
+ //# sourceMappingURL=QuerySystem.js.map