@cjhd/cj-ecs 1.0.0

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 (43) hide show
  1. package/.cj-ecs.md +12 -0
  2. package/assets/common/component/MoveComponent.ts +292 -0
  3. package/assets/common/component/MoveComponent.ts.meta +9 -0
  4. package/assets/common/component/NodeComponent.ts +315 -0
  5. package/assets/common/component/NodeComponent.ts.meta +9 -0
  6. package/assets/common/component.meta +12 -0
  7. package/assets/common/system/MoveSystem.ts +108 -0
  8. package/assets/common/system/MoveSystem.ts.meta +9 -0
  9. package/assets/common/system.meta +12 -0
  10. package/assets/common.meta +12 -0
  11. package/assets/ecs/EcsComponent.ts +244 -0
  12. package/assets/ecs/EcsComponent.ts.meta +9 -0
  13. package/assets/ecs/EcsDirty.ts +459 -0
  14. package/assets/ecs/EcsDirty.ts.meta +9 -0
  15. package/assets/ecs/EcsEntity.ts +430 -0
  16. package/assets/ecs/EcsEntity.ts.meta +9 -0
  17. package/assets/ecs/EcsSingleton.ts +6 -0
  18. package/assets/ecs/EcsSingleton.ts.meta +9 -0
  19. package/assets/ecs/EcsSystem.ts +191 -0
  20. package/assets/ecs/EcsSystem.ts.meta +9 -0
  21. package/assets/ecs.meta +12 -0
  22. package/assets/ecs.ts +339 -0
  23. package/assets/ecs.ts.meta +9 -0
  24. package/assets/lib/EcsCache.ts +43 -0
  25. package/assets/lib/EcsCache.ts.meta +9 -0
  26. package/assets/lib/EcsFilter.ts +210 -0
  27. package/assets/lib/EcsFilter.ts.meta +9 -0
  28. package/assets/lib/EcsManager.ts +502 -0
  29. package/assets/lib/EcsManager.ts.meta +9 -0
  30. package/assets/lib/EcsObject.ts +422 -0
  31. package/assets/lib/EcsObject.ts.meta +9 -0
  32. package/assets/lib/EcsTimer.ts +239 -0
  33. package/assets/lib/EcsTimer.ts.meta +9 -0
  34. package/assets/lib/EcsTween.ts +486 -0
  35. package/assets/lib/EcsTween.ts.meta +9 -0
  36. package/assets/lib/EcsUtils.ts +352 -0
  37. package/assets/lib/EcsUtils.ts.meta +9 -0
  38. package/assets/lib.meta +12 -0
  39. package/assets.meta +9 -0
  40. package/index.ts +33 -0
  41. package/index.ts.meta +9 -0
  42. package/package.json +20 -0
  43. package/package.json.meta +11 -0
package/assets/ecs.ts ADDED
@@ -0,0 +1,339 @@
1
+ import { Node } from 'cc';
2
+ import { DEV, EDITOR } from 'cc/env';
3
+ import { EcsComponent } from './ecs/EcsComponent';
4
+ import { EcsSystem } from './ecs/EcsSystem';
5
+ import type { IEcsComponentDirtySink, IEcsExtensionSink, IEcsObservedQuery } from './ecs/EcsDirty';
6
+ import { entityCache } from './lib/EcsCache';
7
+ import { Filter } from './lib/EcsFilter';
8
+ import { ComponentManager, EntityManager, SystemManager } from './lib/EcsManager';
9
+ import { EcsBase, EcsBaseEntity, EcsBaseSystem, IComponent, IECS, IEntity, IEntityUUID, ISingleton, ITypeofComponent, ITypeofEntity, ITypeofSingleton, ITypeofSystem } from './lib/EcsObject';
10
+
11
+ export class ECS implements IECS {
12
+ static create(): IECS {
13
+ return new ECS() as IECS;
14
+ }
15
+
16
+ private entityManager = new EntityManager();
17
+ private systemManager = new SystemManager();
18
+ private componentManager = new ComponentManager();
19
+ private singletons: ISingleton[] = [];
20
+ private mutationDepth = 0;
21
+ private dirtyEntities: Map<IEntityUUID, IEntity> = new Map();
22
+ private dirtySink: IEcsComponentDirtySink | null = null;
23
+ private observedQuery: IEcsObservedQuery | null = null;
24
+
25
+ /**
26
+ * 查询实体
27
+ */
28
+ public query<T extends IEntity>(filter: Filter): T[];
29
+ public query<T extends IComponent>(filter: Filter, Component: { new(): T }): T[];
30
+ public query<T>(filter: Filter, Component?: any): T[] {
31
+ const entities = Filter.query(this.entityManager, this.componentManager, filter);
32
+ if (!Component) return entities as T[];
33
+ return entities.map(entity => entity.get(Component as ITypeofComponent)) as T[];
34
+ }
35
+
36
+ /**
37
+ * 查询实体
38
+ */
39
+ public find<T extends IEntity>(filter: Filter): T | null;
40
+ public find<T extends IComponent>(filter: Filter, Component: { new(): T }): T | null;
41
+ public find<T>(filter: Filter, Component?: any): T | null {
42
+ const entity = Filter.find(this.entityManager, this.componentManager, filter);
43
+ if (!entity) return null;
44
+ if (!Component) return entity as T;
45
+ return entity.get(Component as ITypeofComponent) as T;
46
+ }
47
+
48
+ /**
49
+ * 查询实体是否存在
50
+ */
51
+ public exist(filter: Filter) {
52
+ return !!Filter.find(this.entityManager, this.componentManager, filter);
53
+ }
54
+
55
+ /**
56
+ * 根据uuid查询实体
57
+ */
58
+ public findByUuid(uuid: IEntityUUID) {
59
+ return this.entityManager.get(uuid);
60
+ }
61
+
62
+ /**
63
+ * 根据uuid查询实体是否存在
64
+ */
65
+ public existByUuid(uuid: IEntityUUID) {
66
+ return !!this.entityManager.has(uuid);
67
+ }
68
+
69
+ /**
70
+ * 添加单例组件
71
+ */
72
+ public addSingleton<T extends ITypeofSingleton>(param: T): InstanceType<T>;
73
+ public addSingleton<T extends ISingleton>(param: T): T;
74
+ public addSingleton(param: ITypeofSingleton | ISingleton) {
75
+ if (DEV && param.ecsName === 'EcsBase') {
76
+ console.error('请使用ecsclass修饰', param);
77
+ return null;
78
+ }
79
+ const com = this.singletons.find(com => com.ecsName === param.ecsName);
80
+ if (com) return com;
81
+
82
+ if (param instanceof EcsBase) {
83
+ this.singletons.push(param);
84
+ return param;
85
+ } else {
86
+ const com = new param();
87
+ this.singletons.push(com);
88
+ return com;
89
+ }
90
+ }
91
+
92
+ /**
93
+ * 获取单例组件
94
+ */
95
+ public getSingleton<T extends ITypeofSingleton>(param: T): InstanceType<T> | null {
96
+ return this.singletons.find(com => com.ecsName === param.ecsName) as InstanceType<T> || null;
97
+ }
98
+
99
+ /**
100
+ * 移除单例组件
101
+ */
102
+ public removeSingleton<T extends ITypeofSingleton>(param: T): InstanceType<T> | null {
103
+ const index = this.singletons.findIndex(com => com.ecsName === param.ecsName);
104
+ if (index >= 0) {
105
+ return this.singletons.splice(index, 1)[0] as InstanceType<T>;
106
+ }
107
+ return null;
108
+ }
109
+
110
+ /**
111
+ * 创建一个实体
112
+ */
113
+ public createEntity<T extends ITypeofEntity>(Entity: T, options?: Node | { node?: Node }): InstanceType<T> {
114
+ const entity = entityCache.get() || new Entity();
115
+ EcsBaseEntity.init(entity, this, Node.isNode(options) ? options : options?.node);
116
+ this.entityManager.add(entity);
117
+ return entity as InstanceType<T>;
118
+ }
119
+
120
+ /**
121
+ * 移除一个实体
122
+ */
123
+ public removeEntity(entity: IEntity) {
124
+ const sink = this.dirtySink as IEcsExtensionSink | null;
125
+ if (sink && sink.onEntityRemoved) {
126
+ sink.onEntityRemoved(entity);
127
+ }
128
+ this.entityManager.remove(entity);
129
+ if (entity.allowRecycling) {
130
+ EcsBaseEntity.updateUUID(entity);
131
+ entityCache.put(entity);
132
+ }
133
+ }
134
+
135
+ /**
136
+ * 添加一个组件
137
+ */
138
+ public addComponent(entity: IEntity, component: IComponent) {
139
+ // 先添加组件
140
+ EcsComponent.bindDirtySink(component as EcsComponent, this.dirtySink);
141
+ EcsBaseEntity.addComponent(entity, component);
142
+ this.componentManager.addComponent(component.ecsName, component);
143
+ const sink = this.dirtySink as IEcsExtensionSink | null;
144
+ if (sink && sink.onComponentAdded) {
145
+ sink.onComponentAdded(entity, component);
146
+ }
147
+
148
+ // 再触发系统的监听
149
+ this.markEntityDirty(entity);
150
+ }
151
+
152
+ /**
153
+ * 移除一个组件
154
+ */
155
+ public removeComponent(component: IComponent) {
156
+ const entity = component.entity;
157
+ const componentName = component.ecsName;
158
+
159
+ if (entity) {
160
+ const sink = this.dirtySink as IEcsExtensionSink | null;
161
+ if (sink && sink.onComponentRemoving) {
162
+ sink.onComponentRemoving(entity, component);
163
+ }
164
+ // 先触发系统的监听
165
+ EcsComponent.beforeRemove(component as EcsComponent);
166
+ if (this.mutationDepth === 0) {
167
+ this.refreshEntitySystems(entity);
168
+ }
169
+
170
+ // 再移除组件
171
+ EcsBaseEntity.removeComponent(entity, component);
172
+ if (this.mutationDepth > 0) {
173
+ this.markEntityDirty(entity);
174
+ }
175
+ }
176
+ this.componentManager.removeComponent(componentName, component);
177
+ }
178
+
179
+ /**
180
+ * 添加一个系统
181
+ */
182
+ public addSystem<T extends ITypeofSystem>(System: T): void {
183
+ const system = new System(this);
184
+ this.systemManager.add(system);
185
+ EcsBaseSystem.onAdd(system);
186
+
187
+ // 先添加实体后添加系统的情况,触发系统的监听
188
+ this.entityManager.each(function (entity) {
189
+ EcsSystem.matchEntity(system as EcsSystem, entity);
190
+ });
191
+ }
192
+
193
+ /**
194
+ * 移除一个系统
195
+ */
196
+ public removeSystem<T extends ITypeofSystem>(System: T): void {
197
+ const system = this.systemManager.remove(System);
198
+ if (system) EcsBaseSystem.onRemove(system);
199
+ }
200
+
201
+ /**
202
+ * 清理所有数据
203
+ */
204
+ public clear() {
205
+ this.systemManager.clear();
206
+ this.entityManager.each((entity) => {
207
+ const sink = this.dirtySink as IEcsExtensionSink | null;
208
+ if (sink && sink.onEntityRemoved) {
209
+ sink.onEntityRemoved(entity);
210
+ }
211
+ });
212
+ this.entityManager.clear();
213
+ this.componentManager.clear();
214
+ this.singletons.length = 0;
215
+ this.mutationDepth = 0;
216
+ this.dirtyEntities.clear();
217
+ }
218
+
219
+ /**
220
+ * 安装/卸载 dirty sink。
221
+ * observed runtime 通过这里接管组件 dirty 通知;传 null 后核心 ECS 仍可独立运行。
222
+ */
223
+ public setDirtySink(sink: IEcsComponentDirtySink | null): void {
224
+ this.dirtySink = sink;
225
+ this.componentManager.eachUnique((component) => {
226
+ EcsComponent.bindDirtySink(component as EcsComponent, sink);
227
+ });
228
+ }
229
+
230
+ /** 获取当前 dirty sink,主要给扩展包链式安装/恢复使用。 */
231
+ public getDirtySink(): IEcsComponentDirtySink | null {
232
+ return this.dirtySink;
233
+ }
234
+
235
+ /**
236
+ * 安装/卸载 observed 查询入口。
237
+ * 系统内可通过 this.observed 或 ecs.getObservedQuery() 获取 dirty/fieldDirty/index 查询。
238
+ */
239
+ public setObservedQuery(query: IEcsObservedQuery | null): void {
240
+ this.observedQuery = query;
241
+ }
242
+
243
+ /** 获取 observed 查询入口;未安装 observed runtime 时返回 null。 */
244
+ public getObservedQuery(): IEcsObservedQuery | null {
245
+ return this.observedQuery;
246
+ }
247
+
248
+ /** 开始批量结构变更,延迟刷新系统 matcher。适合一次性添加/移除多个组件。 */
249
+ public beginMutation() {
250
+ this.mutationDepth++;
251
+ }
252
+
253
+ /** 结束批量结构变更,并统一刷新受影响实体的系统 matcher。 */
254
+ public endMutation() {
255
+ if (this.mutationDepth <= 0) return;
256
+ this.mutationDepth--;
257
+ if (this.mutationDepth > 0) return;
258
+
259
+ this.dirtyEntities.forEach((entity) => {
260
+ this.refreshEntitySystems(entity);
261
+ });
262
+ this.dirtyEntities.clear();
263
+ }
264
+
265
+ private markEntityDirty(entity: IEntity) {
266
+ if (this.mutationDepth > 0) {
267
+ this.dirtyEntities.set(entity.uuid, entity);
268
+ return;
269
+ }
270
+ this.refreshEntitySystems(entity);
271
+ }
272
+
273
+ private refreshEntitySystems(entity: IEntity) {
274
+ this.systemManager.each(function (system) {
275
+ EcsSystem.matchEntity(system as EcsSystem, entity);
276
+ });
277
+ }
278
+
279
+ private executeSystem(dt: number, args: any[]) {
280
+ this.systemManager.each(function (system) {
281
+ EcsBaseSystem.execute(system, dt, args);
282
+ });
283
+ }
284
+ private beforeExecuteSystem(dt: number, args: any[]) {
285
+ this.systemManager.each(function (system) {
286
+ EcsBaseSystem.beforeExecute(system, dt, args);
287
+ });
288
+ }
289
+ private afterExecuteSystem(dt: number, args: any[]) {
290
+ this.systemManager.each(function (system) {
291
+ EcsBaseSystem.afterExecute(system, dt, args);
292
+ });
293
+ }
294
+
295
+ private updateSystem(dt: number, args: any[]) {
296
+ this.systemManager.each(function (system) {
297
+ EcsBaseSystem.update(system, dt, args);
298
+ });
299
+ }
300
+ private beforeUpdateSystem(dt: number, args: any[]) {
301
+ this.systemManager.each(function (system) {
302
+ EcsBaseSystem.beforeUpdate(system, dt, args);
303
+ });
304
+ }
305
+ private afterUpdateSystem(dt: number, args: any[]) {
306
+ this.systemManager.each(function (system) {
307
+ EcsBaseSystem.afterUpdate(system, dt, args);
308
+ });
309
+ }
310
+
311
+ /**
312
+ * 用于逻辑帧
313
+ * 执行顺序:
314
+ * [系统的beforeExecute] -> [系统的execute] ->[系统的afterExecute]
315
+ */
316
+ public execute(dt: number, ...args: any[]) {
317
+ this.beforeExecuteSystem(dt, args);
318
+ this.executeSystem(dt, args);
319
+ this.afterExecuteSystem(dt, args);
320
+ }
321
+
322
+ /**
323
+ * 用于渲染帧
324
+ * 执行顺序:
325
+ * [系统的beforeUpdate] -> [系统的update] -> [系统的afterUpdate]
326
+ */
327
+ public update(dt: number, ...args: any[]) {
328
+ this.beforeUpdateSystem(dt, args);
329
+ this.updateSystem(dt, args);
330
+ this.afterUpdateSystem(dt, args);
331
+ }
332
+ }
333
+
334
+ export const ecs = ECS.create();
335
+
336
+ if (DEV && !EDITOR) {
337
+ //@ts-ignore
338
+ window['ecs'] = ecs;
339
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "ver": "4.0.24",
3
+ "importer": "typescript",
4
+ "imported": true,
5
+ "uuid": "60d3dbb1-44bc-4e65-9cf1-f675847305fc",
6
+ "files": [],
7
+ "subMetas": {},
8
+ "userData": {}
9
+ }
@@ -0,0 +1,43 @@
1
+ import { IComponent, IEntity } from './EcsObject';
2
+
3
+ class Cache<V> {
4
+ private cache: V[] = [];
5
+ get() {
6
+ if (this.cache.length) {
7
+ return this.cache.pop();
8
+ }
9
+ return null;
10
+ }
11
+ put(v: V) {
12
+ this.cache.push(v);
13
+ }
14
+ clear() {
15
+ this.cache.length = 0;
16
+ }
17
+ }
18
+ /**实体缓存 */
19
+ export const entityCache = new Cache<IEntity>;
20
+
21
+ class CacheMap<V> {
22
+ private cache: Map<string, V[]> = new Map();
23
+ get(k: string) {
24
+ const array = this.cache.get(k);
25
+ if (array && array.length) {
26
+ return array.pop();
27
+ }
28
+ return null;
29
+ }
30
+ put(k: string, v: V) {
31
+ const array = this.cache.get(k);
32
+ if (array) {
33
+ array.push(v);
34
+ } else {
35
+ this.cache.set(k, [v]);
36
+ }
37
+ }
38
+ clear() {
39
+ this.cache.clear();
40
+ }
41
+ }
42
+ /**组件缓存 */
43
+ export const componentCache = new CacheMap<IComponent>();
@@ -0,0 +1,9 @@
1
+ {
2
+ "ver": "4.0.24",
3
+ "importer": "typescript",
4
+ "imported": true,
5
+ "uuid": "5a7613ea-530f-443d-817d-f4c2b6a9bc7f",
6
+ "files": [],
7
+ "subMetas": {},
8
+ "userData": {}
9
+ }
@@ -0,0 +1,210 @@
1
+ import { ComponentManager, EntityManager, flagManager } from './EcsManager';
2
+ import { IComponent, IComponentName, IEntity, IFilter, IFlag, ITypeofComponent } from './EcsObject';
3
+
4
+ /**
5
+ * 过滤器
6
+ */
7
+ export class Filter implements IFilter {
8
+ static check(entity: IEntity, filter: Filter) {
9
+ const pipeline = filter.pipeline;
10
+ for (let index = 0, length = pipeline.length; index < length; index++) {
11
+ if (!pipeline[index](entity)) return false;
12
+ }
13
+ return true;
14
+ }
15
+
16
+ static query(entityManager: EntityManager, componentManager: ComponentManager, filter: Filter) {
17
+ let result: IEntity[] = [];
18
+ if (!filter) return result;
19
+
20
+ const filterComp = (comp: IComponent) => {
21
+ if (!comp.enabledInHierarchy) return;
22
+ if (result.indexOf(comp.entity) >= 0) return;
23
+ result.push(comp.entity);
24
+ };
25
+
26
+ // 优先验证any
27
+ if (filter.anyList.length !== 0) {
28
+ filter.anyList.forEach(comName => {
29
+ componentManager.getComponents(comName)?.forEach(filterComp);
30
+ });
31
+ if (result.length === 0) return result;
32
+ }
33
+
34
+ // 其次验证include
35
+ if (result.length === 0 && filter.include) {
36
+ componentManager.getComponents(filter.include)?.forEach(filterComp);
37
+ if (result.length === 0) return result;
38
+ }
39
+
40
+ // 还查询不到,获取所有
41
+ if (result.length === 0 && !filter.hasSearch && filter.hasExclude) {
42
+ entityManager.each((entity) => {
43
+ if (!entity.enabled) return;
44
+ result.push(entity);
45
+ });
46
+ }
47
+
48
+ // 没有实体
49
+ if (result.length === 0) return result;
50
+
51
+ return result.filter(entity => this.check(entity, filter));
52
+ }
53
+
54
+ static find(entityManager: EntityManager, componentManager: ComponentManager, filter: Filter) {
55
+ if (!filter) return null;
56
+
57
+ // 优先验证any
58
+ if (filter.anyList.length) {
59
+ for (let index = 0, length = filter.anyList.length; index < length; index++) {
60
+ const comName = filter.anyList[index];
61
+ const com = componentManager.getComponents(comName)?.find((comp) => {
62
+ if (!comp.enabledInHierarchy) return false;
63
+ return this.check(comp.entity, filter);
64
+ });
65
+ // 只要有任何一个any符合筛选条件,就返回
66
+ if (com) return com.entity;
67
+ }
68
+ return null;
69
+ }
70
+
71
+ let result: IEntity[] = [];
72
+
73
+ // 其次验证include
74
+ if (filter.include) {
75
+ componentManager.getComponents(filter.include)?.forEach((comp) => {
76
+ if (!comp.enabledInHierarchy) return;
77
+ if (result.indexOf(comp.entity) >= 0) return;
78
+ result.push(comp.entity);
79
+ });
80
+ if (result.length === 0) return null;
81
+ }
82
+
83
+ // 获取所有
84
+ if (result.length === 0 && !filter.hasSearch && filter.hasExclude) {
85
+ entityManager.each((entity) => {
86
+ if (!entity.enabled) return;
87
+ result.push(entity);
88
+ });
89
+ }
90
+
91
+ if (result.length === 0) return null;
92
+
93
+ result = result.filter(entity => this.check(entity, filter));
94
+
95
+ return result.length > 0 ? result[0] : null;
96
+ }
97
+
98
+ private anyList: IComponentName[] = [];
99
+ private include: IComponentName = '';
100
+ private hasSearch: boolean = false;
101
+ private hasExclude: boolean = false;
102
+ private pipeline: ((entity: IEntity) => boolean)[] = [];
103
+
104
+ /**
105
+ * 有这些组件中的任何一个
106
+ */
107
+ any(...Comps: ITypeofComponent[]) {
108
+ this.hasSearch = true;
109
+ if (Comps.length === 0) return this;
110
+
111
+ Comps.forEach(Com => {
112
+ if (this.anyList.indexOf(Com.ecsName) >= 0) return;
113
+ this.anyList.push(Com.ecsName);
114
+ });
115
+ return this;
116
+ }
117
+ /**
118
+ * 必须包含所有这些组件
119
+ * 让数量最少的组件作为第一个参数,会获得更好的性能
120
+ */
121
+ all(...Comps: ITypeofComponent[]) {
122
+ this.hasSearch = true;
123
+ if (Comps.length === 0) return this;
124
+ if (!this.include) this.include = Comps[0].ecsName;
125
+
126
+ let flag: IFlag = null;
127
+ const componentNames = Comps.map(Com => Com.ecsName);
128
+ this.pipeline.push(function all(entity: IEntity) {
129
+ if (!flag) flag = flagManager.getByNames(componentNames);
130
+ if (!entity.checkFlagAll(flag)) return false;
131
+ for (let index = 0, length = componentNames.length; index < length; index++) {
132
+ if (!entity.hasEnabledComponentName(componentNames[index])) return false;
133
+ }
134
+ return true;
135
+ });
136
+ return this;
137
+ }
138
+ /**
139
+ * 仅仅只有这些组件
140
+ * 让数量最少的组件作为第一个参数,会获得更好的性能
141
+ */
142
+ only(...Comps: ITypeofComponent[]) {
143
+ this.hasSearch = true;
144
+ if (Comps.length === 0) return this;
145
+ if (!this.include) this.include = Comps[0].ecsName;
146
+
147
+ let flag: IFlag = null;
148
+ const componentNames = Comps.map(Com => Com.ecsName);
149
+ this.pipeline.push(function only(entity: IEntity) {
150
+ if (!flag) flag = flagManager.getByNames(componentNames);
151
+ if (!entity.checkFlagOnly(flag)) return false;
152
+ for (let index = 0, length = componentNames.length; index < length; index++) {
153
+ if (!entity.hasEnabledComponentName(componentNames[index])) return false;
154
+ }
155
+ return true;
156
+ });
157
+ return this;
158
+ }
159
+ /**
160
+ * 不能包含其中的任何一个组件
161
+ */
162
+ exclude(...Comps: ITypeofComponent[]) {
163
+ if (Comps.length === 0) return this;
164
+ this.hasExclude = true;
165
+
166
+ let flag: IFlag = null;
167
+ const componentNames = Comps.map(Com => Com.ecsName);
168
+ this.pipeline.push(function exclude(entity: IEntity) {
169
+ if (!flag) flag = flagManager.getByNames(componentNames);
170
+ if (!entity.checkFlagAny(flag)) return true;
171
+ for (let index = 0, length = componentNames.length; index < length; index++) {
172
+ if (entity.hasEnabledComponentName(componentNames[index])) return false;
173
+ }
174
+ return true;
175
+ });
176
+ return this;
177
+ }
178
+ }
179
+
180
+ /**
181
+ * 过滤条件
182
+ */
183
+ export const filter: IFilter = {
184
+ /**
185
+ * 必须包含所有这些组件
186
+ * - 让数量最少的组件作为第一个参数,会获得更好的性能
187
+ */
188
+ all(...comps: ITypeofComponent[]) {
189
+ return new Filter().all(...comps);
190
+ },
191
+ /**
192
+ * 有这些组件中的任何一个
193
+ */
194
+ any(...comps: ITypeofComponent[]) {
195
+ return new Filter().any(...comps);
196
+ },
197
+ /**
198
+ * 仅仅只有这些组件
199
+ * - 让数量最少的组件作为第一个参数,会获得更好的性能
200
+ */
201
+ only(...comps: ITypeofComponent[]) {
202
+ return new Filter().only(...comps);
203
+ },
204
+ /**
205
+ * 不能包含其中的任何一个组件
206
+ */
207
+ exclude(...comps: ITypeofComponent[]) {
208
+ return new Filter().exclude(...comps);
209
+ }
210
+ };
@@ -0,0 +1,9 @@
1
+ {
2
+ "ver": "4.0.24",
3
+ "importer": "typescript",
4
+ "imported": true,
5
+ "uuid": "a540f4ff-72e8-4b6e-ab68-56d62e640c28",
6
+ "files": [],
7
+ "subMetas": {},
8
+ "userData": {}
9
+ }