@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.
- package/.cj-ecs.md +12 -0
- package/assets/common/component/MoveComponent.ts +292 -0
- package/assets/common/component/MoveComponent.ts.meta +9 -0
- package/assets/common/component/NodeComponent.ts +315 -0
- package/assets/common/component/NodeComponent.ts.meta +9 -0
- package/assets/common/component.meta +12 -0
- package/assets/common/system/MoveSystem.ts +108 -0
- package/assets/common/system/MoveSystem.ts.meta +9 -0
- package/assets/common/system.meta +12 -0
- package/assets/common.meta +12 -0
- package/assets/ecs/EcsComponent.ts +244 -0
- package/assets/ecs/EcsComponent.ts.meta +9 -0
- package/assets/ecs/EcsDirty.ts +459 -0
- package/assets/ecs/EcsDirty.ts.meta +9 -0
- package/assets/ecs/EcsEntity.ts +430 -0
- package/assets/ecs/EcsEntity.ts.meta +9 -0
- package/assets/ecs/EcsSingleton.ts +6 -0
- package/assets/ecs/EcsSingleton.ts.meta +9 -0
- package/assets/ecs/EcsSystem.ts +191 -0
- package/assets/ecs/EcsSystem.ts.meta +9 -0
- package/assets/ecs.meta +12 -0
- package/assets/ecs.ts +339 -0
- package/assets/ecs.ts.meta +9 -0
- package/assets/lib/EcsCache.ts +43 -0
- package/assets/lib/EcsCache.ts.meta +9 -0
- package/assets/lib/EcsFilter.ts +210 -0
- package/assets/lib/EcsFilter.ts.meta +9 -0
- package/assets/lib/EcsManager.ts +502 -0
- package/assets/lib/EcsManager.ts.meta +9 -0
- package/assets/lib/EcsObject.ts +422 -0
- package/assets/lib/EcsObject.ts.meta +9 -0
- package/assets/lib/EcsTimer.ts +239 -0
- package/assets/lib/EcsTimer.ts.meta +9 -0
- package/assets/lib/EcsTween.ts +486 -0
- package/assets/lib/EcsTween.ts.meta +9 -0
- package/assets/lib/EcsUtils.ts +352 -0
- package/assets/lib/EcsUtils.ts.meta +9 -0
- package/assets/lib.meta +12 -0
- package/assets.meta +9 -0
- package/index.ts +33 -0
- package/index.ts.meta +9 -0
- package/package.json +20 -0
- package/package.json.meta +11 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
import { Node } from 'cc';
|
|
2
|
+
import type { EcsDirtyMask, IEcsComponentDirtySink, IEcsObservedQuery } from '../ecs/EcsDirty';
|
|
3
|
+
import { UuidMaker } from './EcsUtils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 过滤器
|
|
7
|
+
*/
|
|
8
|
+
export interface IFilter {
|
|
9
|
+
/**
|
|
10
|
+
* 有这些组件中的任何一个
|
|
11
|
+
*/
|
|
12
|
+
any(...args: ITypeofComponent[]): this
|
|
13
|
+
/**
|
|
14
|
+
* 必须包含所有这些组件
|
|
15
|
+
* - 让数量最少的组件作为第一个参数,会获得更好的性能
|
|
16
|
+
*/
|
|
17
|
+
all(...args: ITypeofComponent[]): this
|
|
18
|
+
/**
|
|
19
|
+
* 仅仅只有这些组件
|
|
20
|
+
* - 让数量最少的组件作为第一个参数,会获得更好的性能
|
|
21
|
+
*/
|
|
22
|
+
only(...args: ITypeofComponent[]): this
|
|
23
|
+
/**
|
|
24
|
+
* 不能包含其中的任何一个组件
|
|
25
|
+
*/
|
|
26
|
+
exclude(...args: ITypeofComponent[]): this
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**uuid生成器 */
|
|
30
|
+
export const entityUuidMaker = new UuidMaker();
|
|
31
|
+
export const componentUuidMaker = new UuidMaker();
|
|
32
|
+
export const systemUuidMaker = new UuidMaker();
|
|
33
|
+
export const singletonUuidMaker = new UuidMaker();
|
|
34
|
+
|
|
35
|
+
export abstract class EcsBase {
|
|
36
|
+
/**类名 */
|
|
37
|
+
static ecsName = 'EcsBase';
|
|
38
|
+
/**类名 */
|
|
39
|
+
public get ecsName() {
|
|
40
|
+
return (this.constructor as typeof EcsBase).ecsName;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**实体基类 */
|
|
45
|
+
export abstract class EcsBaseEntity extends EcsBase {
|
|
46
|
+
static updateUUID(ins: EcsBaseEntity) {
|
|
47
|
+
ins._uuid = entityUuidMaker.create();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static init(entity: EcsBaseEntity, ecs: IECS, node: Node | null = null) {
|
|
51
|
+
return entity.innerInit(ecs, node);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static addComponent(entity: EcsBaseEntity, com: IComponent) {
|
|
55
|
+
return entity.innerAddComponent(com);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static removeComponent(entity: EcsBaseEntity, com: IComponent) {
|
|
59
|
+
return entity.innerRemoveComponent(com);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**唯一ID */
|
|
63
|
+
private _uuid = entityUuidMaker.create();
|
|
64
|
+
public get uuid() {
|
|
65
|
+
return this._uuid;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**允许回收复用(默认false) */
|
|
69
|
+
static allowRecycling = false;
|
|
70
|
+
/**允许回收复用(默认false) */
|
|
71
|
+
public get allowRecycling() {
|
|
72
|
+
return (this.constructor as typeof EcsBaseEntity).allowRecycling;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**添加*/
|
|
76
|
+
protected abstract onAdd(): any;
|
|
77
|
+
/**生效*/
|
|
78
|
+
protected abstract onEnable(): any;
|
|
79
|
+
/**失效*/
|
|
80
|
+
protected abstract onDisable(): any;
|
|
81
|
+
/**移除*/
|
|
82
|
+
protected abstract onRemove(): any;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 内部初始化函数
|
|
86
|
+
*/
|
|
87
|
+
protected abstract innerInit(ecs: IECS, node?: Node | null): void;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* 添加组件(内部调用)
|
|
91
|
+
*/
|
|
92
|
+
protected abstract innerAddComponent(com: IComponent): void;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* 移除组件(内部调用)
|
|
96
|
+
*/
|
|
97
|
+
protected abstract innerRemoveComponent(com: IComponent): void;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**组件基类 */
|
|
101
|
+
export abstract class EcsBaseComponent extends EcsBase {
|
|
102
|
+
/**内部函数 */
|
|
103
|
+
static updateUUID(ins: EcsBaseComponent) {
|
|
104
|
+
ins._uuid = componentUuidMaker.create();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**唯一ID */
|
|
108
|
+
private _uuid = componentUuidMaker.create();
|
|
109
|
+
public get uuid() {
|
|
110
|
+
return this._uuid;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**允许回收复用(默认false) */
|
|
114
|
+
static allowRecycling = false;
|
|
115
|
+
/**允许回收复用(默认false) */
|
|
116
|
+
public get allowRecycling() {
|
|
117
|
+
return (this.constructor as typeof EcsBaseComponent).allowRecycling;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**允许在同一个实体中重复添加(默认false) */
|
|
121
|
+
static allowMultiple = false;
|
|
122
|
+
/**允许在同一个实体中重复添加(默认false) */
|
|
123
|
+
public get allowMultiple() {
|
|
124
|
+
return (this.constructor as typeof EcsBaseComponent).allowMultiple;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**添加*/
|
|
128
|
+
protected abstract onAdd(): any;
|
|
129
|
+
/**生效*/
|
|
130
|
+
protected abstract onEnable(): any;
|
|
131
|
+
/**失效*/
|
|
132
|
+
protected abstract onDisable(): any;
|
|
133
|
+
/**移除*/
|
|
134
|
+
protected abstract onRemove(): any;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**系统基类 */
|
|
138
|
+
export abstract class EcsBaseSystem extends EcsBase {
|
|
139
|
+
/**唯一ID */
|
|
140
|
+
private _uuid = systemUuidMaker.create();
|
|
141
|
+
public get uuid() {
|
|
142
|
+
return this._uuid;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
static onAdd(system: EcsBaseSystem) {
|
|
146
|
+
system.onAdd();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static onRemove(system: EcsBaseSystem) {
|
|
150
|
+
system.onRemove();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
static execute(system: EcsBaseSystem, dt: number, args: any[]) {
|
|
154
|
+
system.execute(dt, ...args);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
static beforeExecute(system: EcsBaseSystem, dt: number, args: any[]) {
|
|
158
|
+
system.beforeExecute(dt, ...args);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static afterExecute(system: EcsBaseSystem, dt: number, args: any[]) {
|
|
162
|
+
system.afterExecute(dt, ...args);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
static update(system: EcsBaseSystem, dt: number, args: any[]) {
|
|
166
|
+
system.update(dt, ...args);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
static beforeUpdate(system: EcsBaseSystem, dt: number, args: any[]) {
|
|
170
|
+
system.beforeUpdate(dt, ...args);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
static afterUpdate(system: EcsBaseSystem, dt: number, args: any[]) {
|
|
174
|
+
system.afterUpdate(dt, ...args);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**添加*/
|
|
178
|
+
protected abstract onAdd(): any;
|
|
179
|
+
/**移除*/
|
|
180
|
+
protected abstract onRemove(): any;
|
|
181
|
+
|
|
182
|
+
protected abstract execute(dt?: number, ...args: any[]): any;
|
|
183
|
+
protected abstract beforeExecute(dt?: number, ...args: any[]): any;
|
|
184
|
+
protected abstract afterExecute(dt?: number, ...args: any[]): any;
|
|
185
|
+
|
|
186
|
+
// 由ecs.update驱动
|
|
187
|
+
protected abstract update(dt?: number, ...args: any[]): any;
|
|
188
|
+
protected abstract beforeUpdate(dt?: number, ...args: any[]): any;
|
|
189
|
+
protected abstract afterUpdate(dt?: number, ...args: any[]): any;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**单例基类 */
|
|
193
|
+
export abstract class EcsBaseSingleton extends EcsBase {
|
|
194
|
+
/**唯一ID */
|
|
195
|
+
private _uuid = singletonUuidMaker.create();
|
|
196
|
+
public get uuid() {
|
|
197
|
+
return this._uuid;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export type IEntityUUID = number;
|
|
202
|
+
export type IComponentName = string;
|
|
203
|
+
export type IComponentUUID = number;
|
|
204
|
+
export type IFlag = number[];
|
|
205
|
+
|
|
206
|
+
export type ITypeofEntity = { new(): IEntity, ecsName: string, allowRecycling: boolean };
|
|
207
|
+
export type ITypeofComponent = { new(): IComponent, ecsName: string, allowRecycling: boolean, allowMultiple: boolean };
|
|
208
|
+
export type ITypeofSystem = { new(ecs: IECS): ISystem, ecsName: string };
|
|
209
|
+
export type ITypeofSingleton = { new(): ISingleton, ecsName: string };
|
|
210
|
+
|
|
211
|
+
export interface IEntity extends EcsBaseEntity {
|
|
212
|
+
/**
|
|
213
|
+
* 是否有效
|
|
214
|
+
*/
|
|
215
|
+
readonly isValid: boolean
|
|
216
|
+
/**
|
|
217
|
+
* 绑定的节点
|
|
218
|
+
*/
|
|
219
|
+
node: Node | null
|
|
220
|
+
/**
|
|
221
|
+
* 标记是否生效(为false后将不会被查询到)
|
|
222
|
+
*/
|
|
223
|
+
enabled: boolean
|
|
224
|
+
/**
|
|
225
|
+
* 销毁
|
|
226
|
+
* 会在触发onDisable和移除所有组件之后才会isValid设为false
|
|
227
|
+
*/
|
|
228
|
+
destroy(): boolean
|
|
229
|
+
/**
|
|
230
|
+
* 检查是否仅包含全部
|
|
231
|
+
*/
|
|
232
|
+
checkFlagAll(flag: IFlag): boolean
|
|
233
|
+
/**
|
|
234
|
+
* 检查是否包含任一
|
|
235
|
+
*/
|
|
236
|
+
checkFlagAny(flag: IFlag): boolean
|
|
237
|
+
/**
|
|
238
|
+
* 检查是否仅包含全部
|
|
239
|
+
*/
|
|
240
|
+
checkFlagOnly(flag: IFlag): boolean
|
|
241
|
+
/**
|
|
242
|
+
* 是否存在指定名字的启用组件
|
|
243
|
+
*/
|
|
244
|
+
hasEnabledComponentName(componentName: IComponentName): boolean
|
|
245
|
+
/**
|
|
246
|
+
* 添加相应类型的组件
|
|
247
|
+
* @see 同add
|
|
248
|
+
* @param param 类型
|
|
249
|
+
*/
|
|
250
|
+
addComponent<T extends ITypeofComponent>(Com: T): InstanceType<T> | null
|
|
251
|
+
/**
|
|
252
|
+
* 添加相应类型的组件
|
|
253
|
+
* @param param 类型
|
|
254
|
+
* @returns
|
|
255
|
+
*/
|
|
256
|
+
add<T extends ITypeofComponent>(Com: T): InstanceType<T> | null
|
|
257
|
+
/**
|
|
258
|
+
* 移除相应类型的第一个组件
|
|
259
|
+
* @see 同remove
|
|
260
|
+
* @param param 类型
|
|
261
|
+
*/
|
|
262
|
+
removeComponent(Com: ITypeofComponent | IComponent): boolean
|
|
263
|
+
/**
|
|
264
|
+
* 移除相应类型的第一个组件
|
|
265
|
+
* @param param 类型
|
|
266
|
+
*/
|
|
267
|
+
remove(Com: ITypeofComponent | IComponent): boolean
|
|
268
|
+
/**
|
|
269
|
+
* 移除相应组件的所有组件
|
|
270
|
+
* @see 同removeAll
|
|
271
|
+
* @param Com 类型
|
|
272
|
+
*/
|
|
273
|
+
removeComponents(Com: ITypeofComponent): boolean;
|
|
274
|
+
/**
|
|
275
|
+
* 移除相应组件的所有组件
|
|
276
|
+
* @param Com 类型
|
|
277
|
+
* @returns
|
|
278
|
+
*/
|
|
279
|
+
removeAll(Com: ITypeofComponent): boolean;
|
|
280
|
+
/**
|
|
281
|
+
* 有没有相应类型的组件
|
|
282
|
+
* @see 同has
|
|
283
|
+
*/
|
|
284
|
+
hasComponent(Com: ITypeofComponent): boolean
|
|
285
|
+
/**
|
|
286
|
+
* 有没有相应类型的组件
|
|
287
|
+
*/
|
|
288
|
+
has(Com: ITypeofComponent): boolean
|
|
289
|
+
/**
|
|
290
|
+
* 获取相应类型的组件
|
|
291
|
+
* @see 同get
|
|
292
|
+
*/
|
|
293
|
+
getComponent<T extends ITypeofComponent>(Com: T): InstanceType<T> | null
|
|
294
|
+
/**
|
|
295
|
+
* 获取相应类型的组件
|
|
296
|
+
*/
|
|
297
|
+
get<T extends ITypeofComponent>(Com: T): InstanceType<T> | null
|
|
298
|
+
/**
|
|
299
|
+
* 获取相应类型的组件
|
|
300
|
+
* @see 同getAll
|
|
301
|
+
*/
|
|
302
|
+
getComponents<T extends ITypeofComponent>(Com: T): InstanceType<T>[]
|
|
303
|
+
/**
|
|
304
|
+
* 获取相应类型的组件
|
|
305
|
+
*/
|
|
306
|
+
getAll<T extends ITypeofComponent>(Com: T): InstanceType<T>[]
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export interface IComponent<E extends IEntity = IEntity> extends EcsBaseComponent {
|
|
310
|
+
/**是否有效*/
|
|
311
|
+
readonly isValid: boolean
|
|
312
|
+
|
|
313
|
+
/**是否有效(如果当前正处于销毁流程中,也会返回false)*/
|
|
314
|
+
readonly isStrictValid: boolean
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* 标记是否生效(为false代表不会被查询到)
|
|
318
|
+
*/
|
|
319
|
+
enabled: boolean
|
|
320
|
+
/**
|
|
321
|
+
* 表示该组件是否被启用并且所在的实体也处于启用状态(为false代表不会被查询到)
|
|
322
|
+
*/
|
|
323
|
+
readonly enabledInHierarchy: boolean
|
|
324
|
+
/**当前组件所在的实体 */
|
|
325
|
+
readonly entity: E | null;
|
|
326
|
+
readonly dirty: boolean;
|
|
327
|
+
readonly dirtyMask: EcsDirtyMask;
|
|
328
|
+
readonly dirtyVersion: number;
|
|
329
|
+
hasDirty(mask: EcsDirtyMask): boolean;
|
|
330
|
+
markDirty(mask?: EcsDirtyMask): void;
|
|
331
|
+
clearDirty(mask?: EcsDirtyMask): void;
|
|
332
|
+
clearDirtySilent(): void;
|
|
333
|
+
/**销毁当前组件 */
|
|
334
|
+
destroy(): boolean;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export type ISystem = EcsBaseSystem;
|
|
338
|
+
|
|
339
|
+
export type ISingleton = EcsBaseSingleton;
|
|
340
|
+
|
|
341
|
+
export interface IECS {
|
|
342
|
+
/**
|
|
343
|
+
* 查询实体
|
|
344
|
+
*/
|
|
345
|
+
query<T extends IEntity>(filter: IFilter): T[];
|
|
346
|
+
query<T extends IComponent>(filter: IFilter, Component: { new(): T }): T[];
|
|
347
|
+
query<T>(filter: IFilter, Component?: ITypeofComponent): T[];
|
|
348
|
+
/**
|
|
349
|
+
* 查询实体
|
|
350
|
+
*/
|
|
351
|
+
find<T extends IEntity>(filter: IFilter): T;
|
|
352
|
+
find<T extends IComponent>(filter: IFilter, Component: { new(): T }): T;
|
|
353
|
+
find<T>(filter: IFilter, Component?: ITypeofComponent): T;
|
|
354
|
+
/**
|
|
355
|
+
* 查询实体是否存在
|
|
356
|
+
*/
|
|
357
|
+
exist(filter: IFilter): boolean;
|
|
358
|
+
/**
|
|
359
|
+
* 根据uuid查询实体
|
|
360
|
+
*/
|
|
361
|
+
findByUuid(uuid: IEntityUUID): IEntity | null;
|
|
362
|
+
/**
|
|
363
|
+
* 根据uuid查询实体是否存在
|
|
364
|
+
*/
|
|
365
|
+
existByUuid(uuid: IEntityUUID): boolean;
|
|
366
|
+
/**
|
|
367
|
+
* 添加系统
|
|
368
|
+
*/
|
|
369
|
+
addSystem<T extends ITypeofSystem>(System: T): void
|
|
370
|
+
/**
|
|
371
|
+
* 移除系统
|
|
372
|
+
*/
|
|
373
|
+
removeSystem<T extends ITypeofSystem>(System: T): void
|
|
374
|
+
/**
|
|
375
|
+
* 添加单例组件
|
|
376
|
+
*/
|
|
377
|
+
addSingleton<T extends ITypeofSingleton>(param: T): InstanceType<T>
|
|
378
|
+
/**
|
|
379
|
+
* 添加单例组件
|
|
380
|
+
*/
|
|
381
|
+
addSingleton<T extends ISingleton>(param: T): T
|
|
382
|
+
/**
|
|
383
|
+
* 获取单例组件
|
|
384
|
+
*/
|
|
385
|
+
getSingleton<T extends ITypeofSingleton>(param: T): InstanceType<T> | null
|
|
386
|
+
/**
|
|
387
|
+
* 移除单例组件
|
|
388
|
+
*/
|
|
389
|
+
removeSingleton<T extends ITypeofSingleton>(param: T): InstanceType<T> | null
|
|
390
|
+
/**
|
|
391
|
+
* 创建一个实体
|
|
392
|
+
*/
|
|
393
|
+
createEntity<T extends ITypeofEntity>(Entity: T, options?: Node | { node?: Node }): InstanceType<T>
|
|
394
|
+
/**
|
|
395
|
+
* 清理系统、实体、组件、单例组件(都不会触发生命周期)
|
|
396
|
+
*/
|
|
397
|
+
clear(): any
|
|
398
|
+
/**
|
|
399
|
+
* 开始批量组件增删,延迟刷新系统 matcher
|
|
400
|
+
*/
|
|
401
|
+
beginMutation(): void
|
|
402
|
+
/**
|
|
403
|
+
* 结束批量组件增删,并刷新受影响实体的系统 matcher
|
|
404
|
+
*/
|
|
405
|
+
endMutation(): void
|
|
406
|
+
setDirtySink(sink: IEcsComponentDirtySink | null): void
|
|
407
|
+
getDirtySink(): IEcsComponentDirtySink | null
|
|
408
|
+
setObservedQuery(query: IEcsObservedQuery | null): void
|
|
409
|
+
getObservedQuery(): IEcsObservedQuery | null
|
|
410
|
+
/**
|
|
411
|
+
* 用于逻辑帧
|
|
412
|
+
* 执行顺序:
|
|
413
|
+
* [系统的beforeExecute] -> [系统的execute] ->[系统的afterExecute]
|
|
414
|
+
*/
|
|
415
|
+
execute(dt: number, ...args: any[]): any
|
|
416
|
+
/**
|
|
417
|
+
* 用于渲染帧
|
|
418
|
+
* 执行顺序:
|
|
419
|
+
* [系统的beforeUpdate] -> [系统的update] -> [系统的afterUpdate]
|
|
420
|
+
*/
|
|
421
|
+
update(dt: number, ...args: any[]): any
|
|
422
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { EcsBase } from './EcsObject';
|
|
2
|
+
|
|
3
|
+
interface ICallback {
|
|
4
|
+
(...args: any[]): any
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
let tid = 0;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 定时器
|
|
11
|
+
*/
|
|
12
|
+
export class Timer {
|
|
13
|
+
static step(timer: Timer, dt: number) {
|
|
14
|
+
timer.time += dt;
|
|
15
|
+
|
|
16
|
+
if (timer.first) {
|
|
17
|
+
if (timer.time < timer._delay) return true;
|
|
18
|
+
timer.first = false;
|
|
19
|
+
timer.time = 0;
|
|
20
|
+
} else if (timer.time < timer._interval) {
|
|
21
|
+
return true;
|
|
22
|
+
} else {
|
|
23
|
+
timer.time = 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
timer.callback.call(timer.target);
|
|
27
|
+
|
|
28
|
+
// 执行次数达到上限,则移除
|
|
29
|
+
if (timer._repeat >= 0 && --timer._repeat < 0) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private _id = ++tid;
|
|
37
|
+
public get id() {
|
|
38
|
+
return this._id;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**是否执行过 */
|
|
42
|
+
private first = true;
|
|
43
|
+
/**执行计时 */
|
|
44
|
+
private time = 0;
|
|
45
|
+
|
|
46
|
+
/**回调函数 */
|
|
47
|
+
private callback!: ICallback;
|
|
48
|
+
private _target: EcsBase | null = null;
|
|
49
|
+
public get target(): EcsBase | null {
|
|
50
|
+
return this._target;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**首次执行的延迟时间 */
|
|
54
|
+
private _delay = 0;
|
|
55
|
+
|
|
56
|
+
/**重复执行的间隔时间 */
|
|
57
|
+
private _interval = 0;
|
|
58
|
+
|
|
59
|
+
/**重复执行次数(<0为无限次) */
|
|
60
|
+
private _repeat = -1;
|
|
61
|
+
|
|
62
|
+
constructor(callback: ICallback, target: EcsBase | null = null) {
|
|
63
|
+
this._target = target;
|
|
64
|
+
this.callback = callback;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 首次执行延迟时间
|
|
69
|
+
* @param value
|
|
70
|
+
* @returns
|
|
71
|
+
*/
|
|
72
|
+
delay(value: number) {
|
|
73
|
+
this._delay = Math.max(0, value);
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 重复执行间隔时间
|
|
79
|
+
* @param value
|
|
80
|
+
* @returns
|
|
81
|
+
*/
|
|
82
|
+
interval(value: number) {
|
|
83
|
+
this._interval = Math.max(0, value);
|
|
84
|
+
return this;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* 重复执行次数(<0为无限次)
|
|
89
|
+
* - 初始值为-1
|
|
90
|
+
* - 实际执行次数为repeat + 1
|
|
91
|
+
* @param value
|
|
92
|
+
* @returns
|
|
93
|
+
*/
|
|
94
|
+
repeat(value: number) {
|
|
95
|
+
this._repeat = value;
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 创建一个定时器
|
|
102
|
+
*/
|
|
103
|
+
export function timer(callback: ICallback, target: EcsBase | null = null) {
|
|
104
|
+
return new Timer(callback, target);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* 定时器管理器
|
|
109
|
+
*/
|
|
110
|
+
export class TimerManager {
|
|
111
|
+
private map = new Map<number, Timer>();
|
|
112
|
+
private pausing = new Map<number, true>();
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 添加定时器
|
|
116
|
+
* @param timer
|
|
117
|
+
* @returns id 永远大于0
|
|
118
|
+
*/
|
|
119
|
+
add(timer: Timer) {
|
|
120
|
+
this.map.set(timer.id, timer);
|
|
121
|
+
return timer.id;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* 移除指定的定时器
|
|
126
|
+
* @param id
|
|
127
|
+
*/
|
|
128
|
+
remove(id: number): void;
|
|
129
|
+
/**
|
|
130
|
+
* 移除指定的定时器
|
|
131
|
+
* @param timer
|
|
132
|
+
*/
|
|
133
|
+
remove(timer: Timer): void;
|
|
134
|
+
/**
|
|
135
|
+
* 移除指定的定时器
|
|
136
|
+
* @param target
|
|
137
|
+
*/
|
|
138
|
+
remove(target: EcsBase): void;
|
|
139
|
+
remove(param: number | Timer | EcsBase) {
|
|
140
|
+
if (typeof param === 'number') {
|
|
141
|
+
this.map.delete(param);
|
|
142
|
+
this.pausing.delete(param);
|
|
143
|
+
} else if (param instanceof Timer) {
|
|
144
|
+
this.map.delete(param.id);
|
|
145
|
+
this.pausing.delete(param.id);
|
|
146
|
+
} else {
|
|
147
|
+
this.map.forEach((tween, tid) => {
|
|
148
|
+
if (tween.target === param) {
|
|
149
|
+
this.map.delete(tid);
|
|
150
|
+
this.pausing.delete(tid);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* 暂停指定的定时器
|
|
158
|
+
* @param id
|
|
159
|
+
*/
|
|
160
|
+
pause(id: number): void;
|
|
161
|
+
/**
|
|
162
|
+
* 暂停指定的定时器
|
|
163
|
+
* @param timer
|
|
164
|
+
*/
|
|
165
|
+
pause(timer: Timer): void;
|
|
166
|
+
/**
|
|
167
|
+
* 暂停指定的定时器
|
|
168
|
+
* @param target
|
|
169
|
+
*/
|
|
170
|
+
pause(target: EcsBase): void;
|
|
171
|
+
pause(param: number | Timer | EcsBase) {
|
|
172
|
+
if (typeof param === 'number') {
|
|
173
|
+
this.pausing.set(param, true);
|
|
174
|
+
} else if (param instanceof Timer) {
|
|
175
|
+
this.pausing.set(param.id, true);
|
|
176
|
+
} else {
|
|
177
|
+
this.map.forEach((tween, tid) => {
|
|
178
|
+
if (tween.target === param) {
|
|
179
|
+
this.pausing.set(tid, true);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* 恢复指定的定时器
|
|
187
|
+
* @param id
|
|
188
|
+
*/
|
|
189
|
+
resume(id: number): void;
|
|
190
|
+
/**
|
|
191
|
+
* 恢复指定的定时器
|
|
192
|
+
* @param timer
|
|
193
|
+
*/
|
|
194
|
+
resume(timer: Timer): void;
|
|
195
|
+
/**
|
|
196
|
+
* 恢复指定的定时器
|
|
197
|
+
* @param target
|
|
198
|
+
*/
|
|
199
|
+
resume(target: EcsBase): void;
|
|
200
|
+
resume(param: number | Timer | EcsBase) {
|
|
201
|
+
if (typeof param === 'number') {
|
|
202
|
+
this.pausing.delete(param);
|
|
203
|
+
} else if (param instanceof Timer) {
|
|
204
|
+
this.pausing.delete(param.id);
|
|
205
|
+
} else {
|
|
206
|
+
this.map.forEach((tween, tid) => {
|
|
207
|
+
if (tween.target === param) {
|
|
208
|
+
this.pausing.delete(tid);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* 迭代一次
|
|
216
|
+
*/
|
|
217
|
+
step(dt: number) {
|
|
218
|
+
this.map.forEach((timer, tid) => {
|
|
219
|
+
// 暂停中,则跳过
|
|
220
|
+
if (this.pausing.has(tid)) return;
|
|
221
|
+
// 执行次数达到上限,则移除
|
|
222
|
+
if (Timer.step(timer, dt) === false) {
|
|
223
|
+
this.map.delete(tid);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
get size() {
|
|
229
|
+
return this.map.size;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* 清空
|
|
234
|
+
*/
|
|
235
|
+
clear() {
|
|
236
|
+
this.map.clear();
|
|
237
|
+
this.pausing.clear();
|
|
238
|
+
}
|
|
239
|
+
}
|