mani-game-engine 1.0.0-pre.8 → 1.0.0-pre.81
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/LICENSE +1 -1
- package/lib/clock.d.ts +63 -0
- package/lib/clock.js +147 -0
- package/lib/clock.js.map +1 -0
- package/lib/ecsInjector.d.ts +45 -0
- package/lib/ecsInjector.js +220 -0
- package/lib/ecsInjector.js.map +1 -0
- package/lib/entity.d.ts +40 -0
- package/lib/entity.js +199 -0
- package/lib/entity.js.map +1 -0
- package/lib/gameEngine.d.ts +99 -0
- package/lib/gameEngine.js +469 -0
- package/lib/gameEngine.js.map +1 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.js +37 -0
- package/lib/index.js.map +1 -0
- package/lib/injector.d.ts +125 -0
- package/lib/injector.js +305 -0
- package/lib/injector.js.map +1 -0
- package/lib/scope/scopeContext.d.ts +76 -0
- package/lib/scope/scopeContext.js +306 -0
- package/lib/scope/scopeContext.js.map +1 -0
- package/lib/systemContext.d.ts +18 -0
- package/lib/systemContext.js +54 -0
- package/lib/systemContext.js.map +1 -0
- package/lib/types.d.ts +80 -0
- package/lib/types.js +20 -0
- package/lib/types.js.map +1 -0
- package/lib/utils/map2k.d.ts +6 -0
- package/lib/utils/map2k.js +44 -0
- package/lib/utils/map2k.js.map +1 -0
- package/package.json +12 -15
- package/src/clock.ts +163 -82
- package/src/ecsInjector.ts +131 -36
- package/src/entity.ts +208 -83
- package/src/gameEngine.ts +521 -362
- package/src/index.ts +24 -9
- package/src/injector.ts +410 -0
- package/src/scope/scopeContext.ts +122 -35
- package/src/systemContext.ts +50 -14
- package/src/types.ts +20 -10
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {Class, EcsInjector, Signal, SignalBinding, SignalCallback} from '../index';
|
|
2
|
-
import {ID, putIfAbsent} from 'mani-injector';
|
|
3
2
|
import {signalHandlers} from '../ecsInjector';
|
|
3
|
+
import {ID, putIfAbsent} from '../injector';
|
|
4
4
|
|
|
5
5
|
export type ScopeSignalOptions = { keepAlive?: boolean | Scope[], group?: string }
|
|
6
6
|
|
|
@@ -15,6 +15,10 @@ export const OnScopeSignal = (id: ID, options?: ScopeSignalOptions) => (target:
|
|
|
15
15
|
}
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
export const SCOPE_CONTEXT = {
|
|
19
|
+
log: true,
|
|
20
|
+
};
|
|
21
|
+
|
|
18
22
|
export interface Scope {
|
|
19
23
|
[propName: string]: any; // disable weak type detection
|
|
20
24
|
onEnter?(): void;
|
|
@@ -46,11 +50,12 @@ class ScopeSignalBinding {
|
|
|
46
50
|
this.signalBinding.detach();
|
|
47
51
|
}
|
|
48
52
|
}
|
|
49
|
-
|
|
53
|
+
// TODO: rename to ScopeStack to something like InternalScopeTreeSingleton with an interface
|
|
50
54
|
class ScopeStack {
|
|
51
55
|
readonly stack: ScopeContext[] = [];
|
|
52
|
-
queuedScopeChanges:
|
|
56
|
+
queuedScopeChanges: (() => Promise<void>)[] = [];
|
|
53
57
|
ongoingChange = false;
|
|
58
|
+
target?: Scope;
|
|
54
59
|
|
|
55
60
|
constructor(readonly rootScope: ScopeContext) {
|
|
56
61
|
this.stack.push(rootScope);
|
|
@@ -63,21 +68,32 @@ class ScopeStack {
|
|
|
63
68
|
get activeContext() {
|
|
64
69
|
return this.stack[this.stack.length - 1];
|
|
65
70
|
}
|
|
66
|
-
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
export type ScopeMapping = (params: {
|
|
70
74
|
injector: EcsInjector,
|
|
71
75
|
registerScopeService: (serviceClass: Class) => void,
|
|
72
|
-
|
|
76
|
+
onEnter: Signal<ScopeContext>,
|
|
77
|
+
onExit: Signal<ScopeContext>,
|
|
78
|
+
onSubReturn: Signal<ScopeContext>,
|
|
79
|
+
onSubExit: Signal<ScopeContext>,
|
|
80
|
+
onActivate: Signal<ScopeContext>,
|
|
81
|
+
onDeactivate: Signal<ScopeContext>,
|
|
82
|
+
|
|
83
|
+
}) => any | Promise<void>;
|
|
73
84
|
|
|
74
85
|
interface AddScopeSignalOptions extends ScopeSignalOptions {
|
|
75
86
|
context?: unknown;
|
|
76
87
|
}
|
|
77
88
|
|
|
89
|
+
export type ScopeChangeParams = {
|
|
90
|
+
from: ScopeContext;
|
|
91
|
+
to: ScopeContext;
|
|
92
|
+
}
|
|
93
|
+
|
|
78
94
|
// TODO: maybe move Signal resolver to Injector and dont use EcsInjector here?
|
|
79
|
-
export class ScopeContext {
|
|
80
|
-
readonly scope
|
|
95
|
+
export class ScopeContext<T extends Class = Class<Scope>> {
|
|
96
|
+
readonly scope!: InstanceType<T>;
|
|
81
97
|
readonly injector: EcsInjector;
|
|
82
98
|
private readonly stack: ScopeStack; // TODO: naming
|
|
83
99
|
private readonly signalBindings: ScopeSignalBinding[] = [];
|
|
@@ -88,41 +104,81 @@ export class ScopeContext {
|
|
|
88
104
|
private closed = false;
|
|
89
105
|
private muteKeepAliveSignals = false;
|
|
90
106
|
|
|
91
|
-
|
|
107
|
+
readonly onEnter = new Signal<ScopeContext>();
|
|
108
|
+
readonly onExit = new Signal<ScopeContext>();
|
|
109
|
+
readonly onSubReturn = new Signal<ScopeContext>();
|
|
110
|
+
readonly onSubExit = new Signal<ScopeContext>();
|
|
111
|
+
readonly onActivate = new Signal<ScopeContext>();
|
|
112
|
+
readonly onDeactivate = new Signal<ScopeContext>();
|
|
113
|
+
private readonly creationTime: DOMHighResTimeStamp;
|
|
114
|
+
readonly onScopeChange: Signal<ScopeChangeParams>;
|
|
115
|
+
|
|
116
|
+
get runtime() {
|
|
117
|
+
return (performance.now() - this.creationTime) / 1000;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
constructor(injector: EcsInjector, scopeClass: T, mapping?: ScopeMapping, private parent?: ScopeContext, resolve?: () => void) {
|
|
121
|
+
this.creationTime = performance.now();
|
|
92
122
|
if (!parent) {
|
|
93
123
|
this.stack = new ScopeStack(this);
|
|
124
|
+
this.onScopeChange = new Signal<ScopeChangeParams>();
|
|
94
125
|
|
|
95
126
|
} else {
|
|
96
127
|
this.stack = parent.stack;
|
|
128
|
+
this.onScopeChange = parent.onScopeChange;
|
|
97
129
|
this.stack.stack.push(this);
|
|
98
130
|
}
|
|
99
131
|
|
|
132
|
+
// TODO: disable this for the rootscope?
|
|
100
133
|
this.injector = injector.createChild();
|
|
134
|
+
|
|
101
135
|
//TODO: i think it would really be better if we implement an injector.injectIntoUnmapped() instead of mapping here
|
|
102
136
|
this.injector.map(scopeClass).toSingleton();
|
|
103
137
|
this.injector.map(ScopeContext).toValue(this);
|
|
104
138
|
|
|
105
|
-
mapping?.({
|
|
139
|
+
const result = mapping?.({
|
|
106
140
|
injector: this.injector,
|
|
107
141
|
registerScopeService: serviceClass => {
|
|
108
142
|
this.injector.map(serviceClass).toSingleton();
|
|
109
143
|
this.mapServiceSignals(this.injector.get(serviceClass));
|
|
110
144
|
},
|
|
145
|
+
onEnter: this.onEnter,
|
|
146
|
+
onExit: this.onExit,
|
|
147
|
+
onSubReturn: this.onSubReturn,
|
|
148
|
+
onSubExit: this.onSubExit,
|
|
149
|
+
onActivate: this.onActivate,
|
|
150
|
+
onDeactivate: this.onDeactivate,
|
|
111
151
|
});
|
|
112
152
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
153
|
+
const completeScopeChange = () => {
|
|
154
|
+
(this.scope as Scope) = this.injector.get(scopeClass);
|
|
155
|
+
this.mapScopeSignals();
|
|
156
|
+
this.updateSignalBindings();
|
|
157
|
+
// TODO: maybe the scope needs to prepare resources or something before it can react to signals, so we should move onEnter bevore the signal mapping and make it async (not working in constructor though)
|
|
158
|
+
this.scope.onEnter?.();
|
|
159
|
+
this.onEnter.dispatch(this);
|
|
160
|
+
this.scope.onActivate?.();
|
|
161
|
+
this.onActivate.dispatch(this);
|
|
162
|
+
resolve?.();
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
if (result instanceof Promise) {
|
|
166
|
+
result.then(completeScopeChange);
|
|
167
|
+
} else {
|
|
168
|
+
completeScopeChange();
|
|
169
|
+
}
|
|
119
170
|
}
|
|
120
171
|
|
|
121
|
-
get isRoot() {
|
|
172
|
+
get isRoot(): boolean {
|
|
122
173
|
return this === this.stack.rootScope;
|
|
123
174
|
}
|
|
124
175
|
|
|
125
|
-
|
|
176
|
+
// TODO: test this
|
|
177
|
+
get target() {
|
|
178
|
+
return this.stack.target;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
get isActive(): boolean {
|
|
126
182
|
return this === this.stack.activeContext;
|
|
127
183
|
}
|
|
128
184
|
|
|
@@ -133,54 +189,63 @@ export class ScopeContext {
|
|
|
133
189
|
* @param scopeClass
|
|
134
190
|
* @param mapping
|
|
135
191
|
*/
|
|
136
|
-
enterScope(scopeClass: Class, mapping?: ScopeMapping)
|
|
137
|
-
let newContext;
|
|
138
|
-
const doChange = () => {
|
|
139
|
-
|
|
192
|
+
async enterScope(scopeClass: Class, mapping?: ScopeMapping) {
|
|
193
|
+
let newContext: ScopeContext | undefined;
|
|
194
|
+
const doChange = async () => {
|
|
195
|
+
const oldContext = this.activeContext;
|
|
140
196
|
this.activeContext.scope.onSubExit?.();
|
|
197
|
+
this.activeContext.onSubExit.dispatch(this);
|
|
141
198
|
this.activeContext.scope.onDeactivate?.();
|
|
199
|
+
this.activeContext.onDeactivate.dispatch(this);
|
|
142
200
|
|
|
143
|
-
|
|
201
|
+
await new Promise<void>(resolve => {
|
|
202
|
+
newContext = new ScopeContext(this.activeContext.injector, scopeClass, mapping, this.activeContext, resolve);
|
|
203
|
+
});
|
|
144
204
|
|
|
145
205
|
this.logStack();
|
|
206
|
+
this.onScopeChange.dispatch({
|
|
207
|
+
from: oldContext,
|
|
208
|
+
to: newContext!,
|
|
209
|
+
})
|
|
146
210
|
const nextChange = this.stack.queuedScopeChanges.shift();
|
|
147
211
|
if (nextChange) {
|
|
148
|
-
nextChange();
|
|
212
|
+
await nextChange();
|
|
149
213
|
} else {
|
|
150
214
|
this.stack.ongoingChange = false;
|
|
151
215
|
}
|
|
152
216
|
};
|
|
153
|
-
// TODO: this queued changes
|
|
217
|
+
// TODO: this queued changes are somewhat experimental
|
|
154
218
|
if (!this.stack.ongoingChange) {
|
|
155
219
|
this.stack.ongoingChange = true;
|
|
156
|
-
doChange();
|
|
220
|
+
await doChange();
|
|
157
221
|
} else {
|
|
158
222
|
this.stack.queuedScopeChanges.push(doChange);
|
|
159
223
|
}
|
|
160
|
-
return newContext
|
|
224
|
+
return newContext!;
|
|
161
225
|
}
|
|
162
226
|
|
|
163
227
|
/**
|
|
164
228
|
* Exits this scope (and all open subscopes=), if a scope class is given. all scopes from the stack are closed until after the scope with the given class
|
|
165
229
|
*/
|
|
166
|
-
exitScope(target?: Scope) {
|
|
167
|
-
const doChange = () => {
|
|
230
|
+
async exitScope(target?: Scope) {
|
|
231
|
+
const doChange = async () => {
|
|
168
232
|
if (this.closed) throw new Error(`Scope already closed`);
|
|
169
233
|
// TODO: check if target is in stack?
|
|
170
|
-
|
|
234
|
+
this.stack.target = target || this.scope.constructor;
|
|
171
235
|
while (true) {
|
|
172
236
|
const ctx = this.stack.stack.pop();
|
|
173
237
|
if (!ctx) {
|
|
174
238
|
throw new Error('no scope in stack');
|
|
175
239
|
}
|
|
176
240
|
ctx!.exitThis();
|
|
177
|
-
if (ctx!.scope.constructor === target) {
|
|
241
|
+
if (ctx!.scope.constructor === this.stack.target) {
|
|
178
242
|
break;
|
|
179
243
|
}
|
|
180
244
|
}
|
|
245
|
+
this.stack.target = undefined;
|
|
181
246
|
const nextChange = this.stack.queuedScopeChanges.shift();
|
|
182
247
|
if (nextChange) {
|
|
183
|
-
nextChange();
|
|
248
|
+
await nextChange();
|
|
184
249
|
} else {
|
|
185
250
|
this.stack.ongoingChange = false;
|
|
186
251
|
}
|
|
@@ -188,13 +253,14 @@ export class ScopeContext {
|
|
|
188
253
|
};
|
|
189
254
|
if (!this.stack.ongoingChange) {
|
|
190
255
|
this.stack.ongoingChange = true;
|
|
191
|
-
doChange();
|
|
256
|
+
await doChange();
|
|
192
257
|
} else {
|
|
193
258
|
this.stack.queuedScopeChanges.push(doChange);
|
|
194
259
|
}
|
|
195
260
|
}
|
|
196
261
|
|
|
197
262
|
closeSubScopes() {
|
|
263
|
+
this.stack.target = this.scope.constructor;
|
|
198
264
|
while (!this.isActive) {
|
|
199
265
|
const ctx = this.stack.stack.pop();
|
|
200
266
|
if (!ctx) {
|
|
@@ -202,10 +268,13 @@ export class ScopeContext {
|
|
|
202
268
|
}
|
|
203
269
|
ctx.exitThis();
|
|
204
270
|
}
|
|
271
|
+
this.stack.target = undefined;
|
|
205
272
|
}
|
|
206
273
|
|
|
207
274
|
private logStack() {
|
|
208
|
-
|
|
275
|
+
if (SCOPE_CONTEXT.log) {
|
|
276
|
+
console.debug('%c' + this.stack.stack.map(c => c.scope.constructor.name).join(' -> '), 'color:yellow');
|
|
277
|
+
}
|
|
209
278
|
}
|
|
210
279
|
|
|
211
280
|
getStackClasses(): Scope[] {
|
|
@@ -213,7 +282,7 @@ export class ScopeContext {
|
|
|
213
282
|
}
|
|
214
283
|
|
|
215
284
|
addScopeSignal<T>(signal: Signal<T>, callback: SignalCallback<T>, params?: AddScopeSignalOptions) {
|
|
216
|
-
const signalBinding = new ScopeSignalBinding(signal.add(callback, params?.context), params);
|
|
285
|
+
const signalBinding = new ScopeSignalBinding(signal.add(callback, {context:params?.context}), params);
|
|
217
286
|
this.signalBindings.push(signalBinding);
|
|
218
287
|
}
|
|
219
288
|
|
|
@@ -274,7 +343,7 @@ export class ScopeContext {
|
|
|
274
343
|
|
|
275
344
|
for (const [field, id] of handlers) {
|
|
276
345
|
const signal = this.injector.getSignal(id);
|
|
277
|
-
const signalBinding = signal.add((<any>scopeService) [field], scopeService);
|
|
346
|
+
const signalBinding = signal.add((<any>scopeService) [field], {context:scopeService});
|
|
278
347
|
this.serviceBindings.push(signalBinding);
|
|
279
348
|
}
|
|
280
349
|
}
|
|
@@ -292,14 +361,32 @@ export class ScopeContext {
|
|
|
292
361
|
if (!this.parent) {
|
|
293
362
|
throw new Error('can\'t exit root scope?!');
|
|
294
363
|
}
|
|
364
|
+
|
|
295
365
|
this.logStack();
|
|
296
366
|
this.detachSignalBindings();
|
|
297
367
|
this.detachServiceBindings();
|
|
298
368
|
this.scope.onDeactivate?.();
|
|
369
|
+
this.onDeactivate.dispatch(this);
|
|
370
|
+
|
|
299
371
|
this.scope.onExit?.();
|
|
372
|
+
this.onExit.dispatch(this);
|
|
373
|
+
this.onScopeChange.dispatch({from: this, to: this.parent});
|
|
374
|
+
// this.injector._dispose();
|
|
375
|
+
|
|
300
376
|
this.parent.updateSignalBindings();
|
|
301
377
|
this.parent.scope.onSubReturn?.();
|
|
378
|
+
this.parent.onSubReturn.dispatch(this);
|
|
379
|
+
this.onSubReturn.dispatch(this);
|
|
302
380
|
this.parent.scope.onActivate?.();
|
|
381
|
+
this.parent.onActivate.dispatch(this);
|
|
303
382
|
this.closed = true;
|
|
383
|
+
|
|
384
|
+
this.onEnter.detachAll();
|
|
385
|
+
this.onExit.detachAll();
|
|
386
|
+
this.onSubReturn.detachAll();
|
|
387
|
+
this.onSubExit.detachAll();
|
|
388
|
+
this.onActivate.detachAll();
|
|
389
|
+
this.onDeactivate.detachAll();
|
|
390
|
+
|
|
304
391
|
}
|
|
305
392
|
}
|
package/src/systemContext.ts
CHANGED
|
@@ -1,22 +1,58 @@
|
|
|
1
1
|
import {System} from './types';
|
|
2
|
-
import {Signal, SignalBinding, SignalCallback} from './index';
|
|
2
|
+
import {Entity, GameEngine, ID, putIfAbsent, Signal, SignalBinding, SignalCallback} from './index';
|
|
3
|
+
import {AddSignalOptions} from 'mani-signal/src/signal';
|
|
4
|
+
|
|
5
|
+
export const entitySignalHandlers = new Map<Object, [string, ID][]>();
|
|
6
|
+
export const OnEntitySignal = (id: ID) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
|
|
7
|
+
if (target instanceof Function) {
|
|
8
|
+
throw new Error('only allowed on non static methods');
|
|
9
|
+
} else {
|
|
10
|
+
const mappingList = putIfAbsent(entitySignalHandlers, target.constructor, (): [string, ID][] => []);
|
|
11
|
+
mappingList.push([propertyKey, id]);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
3
14
|
|
|
4
15
|
export class SystemContext<T extends System = System> {
|
|
5
|
-
|
|
6
|
-
|
|
16
|
+
readonly system!: T;
|
|
17
|
+
readonly onDispose = new Signal();
|
|
18
|
+
private readonly abortController = new AbortController();
|
|
19
|
+
get abortSignal() {
|
|
20
|
+
return this.abortController.signal;
|
|
21
|
+
}
|
|
22
|
+
private signalBindings = new Set<SignalBinding>();
|
|
23
|
+
|
|
24
|
+
constructor(readonly entity: Entity) {
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// TODO: is this a bit hacky?
|
|
28
|
+
addSignalById<S>(signalId: string | symbol, callback: SignalCallback<S>, options: AddSignalOptions = {}) {
|
|
29
|
+
this.signalBindings.add(((this.entity as any).gameEngine as GameEngine).getSignal<S>(signalId).add(callback, options));
|
|
30
|
+
}
|
|
7
31
|
|
|
8
|
-
|
|
9
|
-
|
|
32
|
+
// returns a function that can be called to remove the signal
|
|
33
|
+
addSignal<S>(signal: Signal<S>, callback: SignalCallback<S>, options: AddSignalOptions = {}) {
|
|
34
|
+
const binding = signal.add(callback, options);
|
|
35
|
+
this.signalBindings.add(binding);
|
|
36
|
+
return () => {
|
|
37
|
+
binding.detach();
|
|
38
|
+
this.signalBindings.delete(binding);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
10
41
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
42
|
+
addSignalOnce<S>(signal: Signal<S>, callback: SignalCallback<S>, options: AddSignalOptions = {}) {
|
|
43
|
+
const binding = signal.addOnce(callback, options);
|
|
44
|
+
this.signalBindings.add(binding);
|
|
45
|
+
return () => {
|
|
46
|
+
binding.detach();
|
|
47
|
+
this.signalBindings.delete(binding);
|
|
48
|
+
};
|
|
14
49
|
|
|
15
|
-
|
|
16
|
-
this.signalBindings.push(signal.addOnce(callback, thisArg));
|
|
17
|
-
}
|
|
50
|
+
}
|
|
18
51
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
52
|
+
dispose() {
|
|
53
|
+
this.abortController.abort();
|
|
54
|
+
for (const binding of this.signalBindings) binding.detach();
|
|
55
|
+
this.onDispose.dispatch();
|
|
56
|
+
this.onDispose.detachAll();
|
|
57
|
+
}
|
|
22
58
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
import {GameEngine} from './gameEngine';
|
|
2
|
+
import {Entity} from './entity';
|
|
2
3
|
|
|
3
4
|
export interface System {
|
|
4
5
|
[propName: string]: any;
|
|
5
6
|
onPrepare?(): Promise<void>;
|
|
6
7
|
onStart?(): void;
|
|
7
|
-
onEnd?(): void
|
|
8
|
-
onPreFixedUpdate?(): void;
|
|
9
|
-
onEarlyUpdate?(time: number, deltaTime: number): void;
|
|
8
|
+
onEnd?(): void | Promise<void>;
|
|
9
|
+
onPreFixedUpdate?(time: number, deltaTime: number): void;
|
|
10
10
|
onFixedUpdate?(time: number, deltaTime: number): void;
|
|
11
|
-
onPrePhysicUpdate?(time: number, deltaTime: number): void;
|
|
12
11
|
onPhysicsUpdate?(time: number, deltaTime: number): void;
|
|
13
12
|
onUpdate?(time: number, deltaTime: number, alpha: number): void;
|
|
14
13
|
onLateUpdate?(time: number, deltaTime: number, alpha: number): void;
|
|
14
|
+
onPrePhysicsUpdate?(time: number, deltaTime: number): void;
|
|
15
15
|
onPostPhysicsUpdate?(time: number, deltaTime: number): void;
|
|
16
16
|
onLateFixedUpdate?(time: number, deltaTime: number): void;
|
|
17
17
|
onRender?(time: number, deltaTime: number, alpha: number): void;
|
|
18
|
+
onAddEntity?(entity: Entity): void;
|
|
19
|
+
onRemoveEntity?(entity: Entity): void;
|
|
20
|
+
// new(...args: any[]): System;
|
|
18
21
|
// new(): GameSystem;
|
|
19
22
|
}
|
|
20
23
|
|
|
@@ -27,15 +30,17 @@ export interface Service {
|
|
|
27
30
|
onPrepare?(): Promise<void>;
|
|
28
31
|
onStart?(): void;
|
|
29
32
|
onEnd?(): void;
|
|
30
|
-
onPreFixedUpdate?(): void;
|
|
33
|
+
onPreFixedUpdate?(time: number, deltaTime: number): void;
|
|
31
34
|
onPostPhysicsUpdate?(time: number, deltaTime: number): void;
|
|
32
35
|
onLateFixedUpdate?(time: number, deltaTime: number): void;
|
|
33
36
|
onFixedUpdate?(time: number, deltaTime: number): void;
|
|
34
|
-
onPrePhysicUpdate?(time: number, deltaTime: number): void;
|
|
35
37
|
onPhysicsUpdate?(time: number, deltaTime: number): void;
|
|
38
|
+
onPrePhysicsUpdate?(time: number, deltaTime: number): void;
|
|
36
39
|
onUpdate?(time: number, deltaTime: number, alpha: number): void;
|
|
37
40
|
onLateUpdate?(time: number, deltaTime: number, alpha: number): void;
|
|
38
|
-
onRender?(): void;
|
|
41
|
+
onRender?(time: number, deltaTime: number, alpha: number): void;
|
|
42
|
+
onAddEntity?(entity: Entity): void;
|
|
43
|
+
onRemoveEntity?(entity: Entity): void;
|
|
39
44
|
// new(): GameSystem;
|
|
40
45
|
}
|
|
41
46
|
|
|
@@ -74,12 +79,17 @@ export type Class<T = any> = { new(...args: any[]): T; }
|
|
|
74
79
|
|
|
75
80
|
export const EngineSignals = {
|
|
76
81
|
OnStart: Symbol('OnStart'),
|
|
82
|
+
OnEnd: Symbol('OnEnd'),
|
|
77
83
|
OnUpdate: Symbol('OnUpdate'),
|
|
78
84
|
OnLateUpdate: Symbol('OnLateUpdate'),
|
|
79
85
|
OnFixedUpdate: Symbol('OnFixedUpdate'),
|
|
80
|
-
|
|
81
|
-
|
|
86
|
+
OnPreFixedUpdate: Symbol('OnPreFixedUpdate'),
|
|
87
|
+
OnPrePhysicsUpdate: Symbol('OnPrePhysicsUpdate'),
|
|
88
|
+
OnPhysicsUpdate: Symbol('OnPhysicsUpdate'),
|
|
89
|
+
OnPostPhysicsUpdate: Symbol('OnPostPhysicsUpdate'),
|
|
90
|
+
onLateFixedUpdate: Symbol('onLateFixedUpdate'),
|
|
82
91
|
OnRender: Symbol('OnRender'),
|
|
83
92
|
OnPrepare: Symbol('OnPrepare'),
|
|
84
|
-
|
|
93
|
+
OnAddEntity: Symbol('OnAddEntity'),
|
|
94
|
+
OnRemoveEntity: Symbol('OnRemoveEntity'),
|
|
85
95
|
};
|