@gg-web-engine/core 0.0.38 → 0.0.40

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 (53) hide show
  1. package/dist/2d/components/physics/i-rigid-body-2d.component.d.ts +3 -0
  2. package/dist/2d/components/physics/i-trigger-2d.component.d.ts +3 -0
  3. package/dist/2d/components/rendering/i-visual-scene-2d.component.d.ts +1 -1
  4. package/dist/2d/entities/i-renderable-2d.entity.d.ts +3 -1
  5. package/dist/2d/entities/i-renderable-2d.entity.js +7 -0
  6. package/dist/2d/gg-2d-world.d.ts +1 -0
  7. package/dist/2d/models/body-options.d.ts +5 -1
  8. package/dist/3d/components/physics/i-physics-world-3d.component.d.ts +7 -0
  9. package/dist/3d/components/physics/i-rigid-body-3d.component.d.ts +3 -0
  10. package/dist/3d/components/physics/i-trigger-3d.component.d.ts +3 -0
  11. package/dist/3d/components/rendering/i-visual-scene-3d.component.d.ts +1 -1
  12. package/dist/3d/entities/controllers/input/car-keyboard-handling.controller.js +2 -2
  13. package/dist/3d/entities/controllers/input/gg-car-keyboard-handling.controller.js +3 -3
  14. package/dist/3d/entities/i-renderable-3d.entity.d.ts +3 -1
  15. package/dist/3d/entities/i-renderable-3d.entity.js +7 -0
  16. package/dist/3d/entities/map-graph-3d.entity.d.ts +2 -3
  17. package/dist/3d/entities/map-graph-3d.entity.js +10 -7
  18. package/dist/3d/entities/raycast-vehicle-3d.entity.d.ts +2 -0
  19. package/dist/3d/entities/raycast-vehicle-3d.entity.js +15 -1
  20. package/dist/3d/factories.d.ts +3 -3
  21. package/dist/3d/gg-3d-world.d.ts +1 -0
  22. package/dist/3d/models/body-options.d.ts +5 -1
  23. package/dist/3d/models/shapes.d.ts +41 -1
  24. package/dist/base/clock/pausable-clock.d.ts +62 -1
  25. package/dist/base/clock/pausable-clock.js +102 -8
  26. package/dist/base/components/physics/i-body.component.d.ts +3 -1
  27. package/dist/base/components/physics/i-physics-world.component.d.ts +8 -6
  28. package/dist/base/components/rendering/i-renderer.component.d.ts +6 -2
  29. package/dist/base/components/rendering/i-visual-scene.component.d.ts +0 -4
  30. package/dist/base/entities/controllers/inline-controller.d.ts +1 -1
  31. package/dist/base/entities/controllers/inline-controller.js +4 -1
  32. package/dist/base/entities/i-entity.d.ts +1 -1
  33. package/dist/base/entities/i-entity.js +3 -3
  34. package/dist/base/entities/i-renderer.entity.d.ts +4 -0
  35. package/dist/base/entities/i-renderer.entity.js +8 -0
  36. package/dist/base/gg-world.d.ts +8 -5
  37. package/dist/base/gg-world.js +81 -39
  38. package/dist/base/index.d.ts +0 -1
  39. package/dist/base/index.js +0 -1
  40. package/dist/base/inputs/mouse.input.js +9 -4
  41. package/dist/base/models/body-options.d.ts +9 -0
  42. package/dist/dev/gg-console.ui.js +16 -8
  43. package/dist/dev/gg-debugger.ui.d.ts +9 -0
  44. package/dist/dev/gg-debugger.ui.js +206 -34
  45. package/dist/dev/gg-static.d.ts +0 -1
  46. package/dist/dev/gg-static.js +15 -8
  47. package/dist/dev/index.d.ts +1 -0
  48. package/dist/dev/index.js +1 -0
  49. package/dist/dev/performance-meter.entity.d.ts +21 -0
  50. package/dist/dev/performance-meter.entity.js +120 -0
  51. package/package.json +1 -1
  52. package/dist/base/interfaces/i-debug-physics-drawer.d.ts +0 -8
  53. package/dist/base/interfaces/i-debug-physics-drawer.js +0 -1
@@ -1,12 +1,16 @@
1
- import { GgWorld, PhysicsTypeDocRepo } from '../../gg-world';
2
- import { IDebugPhysicsDrawer } from '../../interfaces/i-debug-physics-drawer';
1
+ import { PhysicsTypeDocRepo } from '../../gg-world';
3
2
  import { IComponent } from '../i-component';
4
3
  import { CollisionGroup } from '../../models/body-options';
4
+ import { Subject } from 'rxjs';
5
5
  export interface IPhysicsWorldComponent<D, R, TypeDoc extends PhysicsTypeDocRepo<D, R> = PhysicsTypeDocRepo<D, R>> extends IComponent {
6
6
  readonly factory: TypeDoc['factory'];
7
7
  gravity: D;
8
- timeScale: number;
9
- get physicsDebugViewActive(): boolean;
8
+ /** event emitter, emits newly added physics components */
9
+ readonly added$: Subject<TypeDoc['rigidBody'] | TypeDoc['trigger'] | any>;
10
+ /** event emitter, emits just removed physics components */
11
+ readonly removed$: Subject<TypeDoc['rigidBody'] | TypeDoc['trigger'] | any>;
12
+ /** list of currently added to world physics components */
13
+ readonly children: (TypeDoc['rigidBody'] | TypeDoc['trigger'] | any)[];
10
14
  init(): Promise<void>;
11
15
  /**
12
16
  * Runs simulation of the physics world.
@@ -16,6 +20,4 @@ export interface IPhysicsWorldComponent<D, R, TypeDoc extends PhysicsTypeDocRepo
16
20
  simulate(delta: number): void;
17
21
  registerCollisionGroup(): CollisionGroup;
18
22
  deregisterCollisionGroup(group: CollisionGroup): void;
19
- startDebugger(world: GgWorld<D, R>, drawer: IDebugPhysicsDrawer<D, R>): void;
20
- stopDebugger(world: GgWorld<D, R>): void;
21
23
  }
@@ -25,8 +25,12 @@ export declare abstract class IRendererComponent<D, R, VTypeDoc extends VisualTy
25
25
  readonly canvas?: HTMLCanvasElement | undefined;
26
26
  entity: IEntity | null;
27
27
  /** Specifies the options for the renderer. */
28
- readonly rendererOptions: RendererOptions;
29
- protected constructor(scene: IVisualSceneComponent<D, R, VTypeDoc>, canvas?: HTMLCanvasElement | undefined, options?: Partial<RendererOptions>);
28
+ readonly rendererOptions: RendererOptions & Partial<VTypeDoc['rendererExtraOpts']>;
29
+ /** get flag whether renderer shows physics debugger view */
30
+ abstract get physicsDebugViewActive(): boolean;
31
+ /** turns on/off physics debugger view for this renderer */
32
+ abstract set physicsDebugViewActive(value: boolean);
33
+ protected constructor(scene: IVisualSceneComponent<D, R, VTypeDoc>, canvas?: HTMLCanvasElement | undefined, options?: Partial<RendererOptions & VTypeDoc['rendererExtraOpts']>);
30
34
  /**
31
35
  * Renders the scene.
32
36
  */
@@ -1,10 +1,6 @@
1
- import { IDebugPhysicsDrawer } from '../../interfaces/i-debug-physics-drawer';
2
1
  import { IComponent } from '../i-component';
3
2
  import { VisualTypeDocRepo } from '../../gg-world';
4
3
  export interface IVisualSceneComponent<D, R, TypeDoc extends VisualTypeDocRepo<D, R> = VisualTypeDocRepo<D, R>> extends IComponent {
5
4
  readonly factory: TypeDoc['factory'];
6
- readonly debugPhysicsDrawerClass?: {
7
- new (): IDebugPhysicsDrawer<D, R, TypeDoc>;
8
- };
9
5
  init(): Promise<void>;
10
6
  }
@@ -1,3 +1,3 @@
1
1
  import { GgWorld } from '../../gg-world';
2
2
  import { Observable } from 'rxjs';
3
- export declare function createInlineTickController(world: GgWorld<any, any>, tickOrder?: number): Observable<[number, number]>;
3
+ export declare function createInlineTickController(world: GgWorld<any, any>, tickOrder?: number, name?: string): Observable<[number, number]>;
@@ -6,8 +6,11 @@ class InlineTickController extends IEntity {
6
6
  this.tickOrder = tickOrder;
7
7
  }
8
8
  }
9
- export function createInlineTickController(world, tickOrder = TickOrder.CONTROLLERS) {
9
+ export function createInlineTickController(world, tickOrder = TickOrder.CONTROLLERS, name) {
10
10
  const controller = new InlineTickController(tickOrder);
11
+ if (name) {
12
+ controller.name = name;
13
+ }
11
14
  world.addEntity(controller);
12
15
  return controller.tick$.pipe(finalize(() => {
13
16
  world.removeEntity(controller, true);
@@ -34,7 +34,7 @@ export declare abstract class IEntity<D = any, R = any, VTypeDoc extends VisualT
34
34
  /**
35
35
  * The flag whether entity should listen to ticks. If set to false, ticks will not be propagated to this entity
36
36
  * */
37
- protected _active: boolean;
37
+ protected _selfActive: boolean;
38
38
  get active(): boolean;
39
39
  set active(value: boolean);
40
40
  parent: IEntity | null;
@@ -26,7 +26,7 @@ export class IEntity {
26
26
  /**
27
27
  * The flag whether entity should listen to ticks. If set to false, ticks will not be propagated to this entity
28
28
  * */
29
- this._active = true;
29
+ this._selfActive = true;
30
30
  this.parent = null;
31
31
  this._children = [];
32
32
  this._components = [];
@@ -43,10 +43,10 @@ export class IEntity {
43
43
  this._name = value;
44
44
  }
45
45
  get active() {
46
- return this._active;
46
+ return this._selfActive && (!this.parent || this.parent.active);
47
47
  }
48
48
  set active(value) {
49
- this._active = value;
49
+ this._selfActive = value;
50
50
  }
51
51
  get children() {
52
52
  return [...this._children];
@@ -23,6 +23,10 @@ export declare abstract class IRendererEntity<D, R, TypeDoc extends VisualTypeDo
23
23
  */
24
24
  get rendererSize(): Point2 | null;
25
25
  get rendererOptions(): RendererOptions;
26
+ /** get flag whether renderer shows physics debugger view */
27
+ get physicsDebugViewActive(): boolean;
28
+ /** turns on/off physics debugger view for this renderer */
29
+ set physicsDebugViewActive(value: boolean);
26
30
  /**
27
31
  Initializes a new instance of the BaseGgRenderer class.
28
32
  * @param renderer
@@ -38,6 +38,14 @@ export class IRendererEntity extends IEntity {
38
38
  get rendererOptions() {
39
39
  return this.renderer.rendererOptions;
40
40
  }
41
+ /** get flag whether renderer shows physics debugger view */
42
+ get physicsDebugViewActive() {
43
+ return this.renderer.physicsDebugViewActive;
44
+ }
45
+ /** turns on/off physics debugger view for this renderer */
46
+ set physicsDebugViewActive(value) {
47
+ this.renderer.physicsDebugViewActive = value;
48
+ }
41
49
  onSpawned(world) {
42
50
  this._rendererSize$.next(null);
43
51
  if (this.rendererOptions.size == 'fullscreen' || typeof this.rendererOptions.size === 'function') {
@@ -1,8 +1,10 @@
1
1
  import { IDisplayObjectComponent, IEntity, IPhysicsWorldComponent, IPositionable, IRenderableEntity, IRendererComponent, IRigidBodyComponent, ITriggerComponent, IVisualSceneComponent, KeyboardInput, PausableClock } from '../base';
2
+ import { Subject } from 'rxjs';
2
3
  export declare type VisualTypeDocRepo<D, R> = {
3
4
  factory: unknown;
4
5
  displayObject: IDisplayObjectComponent<D, R>;
5
6
  renderer: IRendererComponent<D, R>;
7
+ rendererExtraOpts: {};
6
8
  };
7
9
  export declare type PhysicsTypeDocRepo<D, R> = {
8
10
  factory: unknown;
@@ -12,14 +14,17 @@ export declare type PhysicsTypeDocRepo<D, R> = {
12
14
  export declare abstract class GgWorld<D, R, VTypeDoc extends VisualTypeDocRepo<D, R> = VisualTypeDocRepo<D, R>, PTypeDoc extends PhysicsTypeDocRepo<D, R> = PhysicsTypeDocRepo<D, R>, VS extends IVisualSceneComponent<D, R, VTypeDoc> = IVisualSceneComponent<D, R, VTypeDoc>, PW extends IPhysicsWorldComponent<D, R, PTypeDoc> = IPhysicsWorldComponent<D, R, PTypeDoc>> {
13
15
  readonly visualScene: VS;
14
16
  readonly physicsWorld: PW;
17
+ private static default_name_counter;
18
+ private static _documentWorlds;
19
+ static get documentWorlds(): GgWorld<any, any>[];
15
20
  readonly worldClock: PausableClock;
16
21
  readonly keyboardInput: KeyboardInput;
17
- private static default_name_counter;
18
22
  name: string;
19
23
  readonly children: IEntity[];
20
24
  protected readonly tickListeners: IEntity[];
21
- private static _documentWorlds;
22
- static get documentWorlds(): GgWorld<any, any>[];
25
+ readonly tickStarted$: Subject<void>;
26
+ readonly tickForwardTo$: Subject<IEntity | 'PHYSICS_WORLD'>;
27
+ readonly tickForwardedTo$: Subject<IEntity | 'PHYSICS_WORLD'>;
23
28
  protected constructor(visualScene: VS, physicsWorld: PW);
24
29
  init(): Promise<void>;
25
30
  start(): void;
@@ -34,6 +39,4 @@ export declare abstract class GgWorld<D, R, VTypeDoc extends VisualTypeDocRepo<D
34
39
  position?: D, rotation?: R, material?: unknown): IPositionable<D, R> & IRenderableEntity<D, R, VTypeDoc>;
35
40
  addEntity(entity: IEntity): void;
36
41
  removeEntity(entity: IEntity, dispose?: boolean): void;
37
- get physicsDebugViewActive(): boolean;
38
- set physicsDebugViewActive(value: boolean);
39
42
  }
@@ -7,7 +7,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { GgGlobalClock, KeyboardInput, TickOrder, } from '../base';
10
+ import { GgGlobalClock, IRendererEntity, KeyboardInput, TickOrder, } from '../base';
11
+ import { lastValueFrom, Subject, take } from 'rxjs';
12
+ import { PerformanceMeterEntity } from '../dev';
11
13
  export class GgWorld {
12
14
  constructor(visualScene, physicsWorld) {
13
15
  this.visualScene = visualScene;
@@ -18,25 +20,74 @@ export class GgWorld {
18
20
  this.children = [];
19
21
  // the same as children, but sorted by tick order
20
22
  this.tickListeners = [];
23
+ // events
24
+ this.tickStarted$ = new Subject();
25
+ this.tickForwardTo$ = new Subject();
26
+ this.tickForwardedTo$ = new Subject();
21
27
  GgWorld._documentWorlds.push(this);
22
28
  this.keyboardInput.start();
23
29
  if (window.ggstatic) {
24
- window.ggstatic.registerConsoleCommand(this, 'show_debugger', (...args) => __awaiter(this, void 0, void 0, function* () {
25
- window.ggstatic.showDebugControls = ['1', 'true', '+'].includes(args[0]);
26
- return '' + window.ggstatic.showDebugControls;
27
- }), 'args: [0 or 1]; turn on/off debug panel. Default value is 0');
28
- window.ggstatic.registerConsoleCommand(this, 'show_stats', (...args) => __awaiter(this, void 0, void 0, function* () {
29
- window.ggstatic.showStats = ['1', 'true', '+'].includes(args[0]);
30
- return '' + window.ggstatic.showStats;
31
- }), 'args: [0 or 1]; turn on/off stats. Default value is 0');
32
30
  window.ggstatic.registerConsoleCommand(this, 'ph_timescale', (...args) => __awaiter(this, void 0, void 0, function* () {
33
- this.physicsWorld.timeScale = +args[0];
34
- return JSON.stringify(this.physicsWorld.timeScale);
31
+ this.worldClock.timeScale = +args[0];
32
+ return JSON.stringify(this.worldClock.timeScale);
35
33
  }), 'args: [float]; change time scale of physics engine. Default value is 1.0');
34
+ window.ggstatic.registerConsoleCommand(this, 'ls_renderers', () => __awaiter(this, void 0, void 0, function* () {
35
+ return this.children
36
+ .filter(e => e instanceof IRendererEntity)
37
+ .map(r => r.name)
38
+ .join('\n');
39
+ }), 'no args; print all renderers in selected world');
36
40
  window.ggstatic.registerConsoleCommand(this, 'dr_drawphysics', (...args) => __awaiter(this, void 0, void 0, function* () {
37
- this.physicsDebugViewActive = ['1', 'true', '+'].includes(args[0]);
38
- return '' + this.physicsWorld.physicsDebugViewActive;
39
- }), 'args: [0 or 1]; turn on/off physics debug view. Default value is 0');
41
+ const value = ['1', 'true', '+'].includes(args[0]);
42
+ const rendererName = args[1];
43
+ let renderer;
44
+ if (rendererName) {
45
+ renderer = this.children.find(x => x instanceof IRendererEntity && x.name === rendererName);
46
+ }
47
+ else {
48
+ renderer = this.children.find(x => x instanceof IRendererEntity);
49
+ }
50
+ if (renderer) {
51
+ renderer.physicsDebugViewActive = value;
52
+ return '' + value;
53
+ }
54
+ return 'false';
55
+ }), 'args: [0 or 1] or [0 or 1, string]; turn on/off physics debug view. Second argument expects renderer ' +
56
+ 'name, if not provided first renderer will be picked. Look up for renderer names using command "ls_renderers"');
57
+ window.ggstatic.registerConsoleCommand(this, 'performance_report', (...args) => __awaiter(this, void 0, void 0, function* () {
58
+ let mode = 'avg';
59
+ let samples = 20;
60
+ for (let i = 0; i < 2; i++) {
61
+ if (['avg', 'peak'].includes(args[i])) {
62
+ mode = args[i];
63
+ }
64
+ else if (!isNaN(+args[i])) {
65
+ samples = +args[i];
66
+ }
67
+ }
68
+ const meter = new PerformanceMeterEntity(samples, 250);
69
+ this.addEntity(meter);
70
+ yield lastValueFrom(this.worldClock.tick$.pipe(take(samples)));
71
+ const report = mode === 'avg' ? meter.avgReport : meter.peakReport;
72
+ this.removeEntity(meter);
73
+ const renderItems = report.entries.map(([name, value]) => `<span style='color:lightgray;'>${name}:</span>` +
74
+ new Array(Math.max(0, 26 - name.length)).join('&nbsp;') +
75
+ `${value.toFixed(2)} ms` +
76
+ (mode === 'avg' ? ` (${((value * 100) / report.totalTime).toFixed(2)}%)` : ''));
77
+ let totalColor = 'lightgreen';
78
+ if (report.totalTime > 12) {
79
+ totalColor = report.totalTime < 16 ? 'yellow' : 'red';
80
+ }
81
+ const title = `${mode === 'avg' ? 'Average' : 'Peak'} Frame time`;
82
+ renderItems.unshift(title +
83
+ ':' +
84
+ new Array(Math.max(0, 26 - title.length)).join('&nbsp;') +
85
+ `<span style='color:${totalColor};'>${report.totalTime.toFixed(2)} ms</span>`);
86
+ renderItems.unshift(`Performance report (${samples} samples)`);
87
+ return renderItems.join('\n');
88
+ }), 'args: [int, avg|peak]; [avg|peak, int]; [avg|peak]; [int] or []; measure how much time was spent per ' +
89
+ 'entity in world. Arguments are samples amount (20 by default) and "peak" or "avg" choice, both arguments are ' +
90
+ 'optional. "avg" report sorts entities by average time consumed, "peak" records highest value for each entity');
40
91
  }
41
92
  }
42
93
  static get documentWorlds() {
@@ -45,24 +96,30 @@ export class GgWorld {
45
96
  init() {
46
97
  return __awaiter(this, void 0, void 0, function* () {
47
98
  yield Promise.all([this.physicsWorld.init(), this.visualScene.init()]);
99
+ const forwardTick = (listener, elapsed, delta) => {
100
+ if (listener.active) {
101
+ this.tickForwardTo$.next(listener);
102
+ listener.tick$.next([elapsed, delta]);
103
+ this.tickForwardedTo$.next(listener);
104
+ }
105
+ };
48
106
  this.worldClock.tick$.subscribe(([elapsed, delta]) => {
107
+ this.tickStarted$.next();
49
108
  let i = 0;
50
109
  // emit tick to all entities with tick order < GGTickOrder.PHYSICS_SIMULATION
51
110
  for (i; i < this.tickListeners.length; i++) {
52
111
  if (this.tickListeners[i].tickOrder >= TickOrder.PHYSICS_SIMULATION) {
53
112
  break;
54
113
  }
55
- if (this.tickListeners[i].active) {
56
- this.tickListeners[i].tick$.next([elapsed, delta]);
57
- }
114
+ forwardTick(this.tickListeners[i], elapsed, delta);
58
115
  }
59
- // run phycics simulation
116
+ // run physics simulation
117
+ this.tickForwardTo$.next('PHYSICS_WORLD');
60
118
  this.physicsWorld.simulate(delta);
119
+ this.tickForwardedTo$.next('PHYSICS_WORLD');
61
120
  // emit tick to all remained entities
62
121
  for (i; i < this.tickListeners.length; i++) {
63
- if (this.tickListeners[i].active) {
64
- this.tickListeners[i].tick$.next([elapsed, delta]);
65
- }
122
+ forwardTick(this.tickListeners[i], elapsed, delta);
66
123
  }
67
124
  });
68
125
  });
@@ -94,6 +151,9 @@ export class GgWorld {
94
151
  }
95
152
  this.worldClock.stop();
96
153
  this.keyboardInput.stop();
154
+ this.tickStarted$.complete();
155
+ this.tickForwardTo$.complete();
156
+ this.tickForwardedTo$.complete();
97
157
  for (let i = 0; i < this.children.length; i++) {
98
158
  this.children[i].onRemoved();
99
159
  this.children[i].dispose();
@@ -126,24 +186,6 @@ export class GgWorld {
126
186
  entity.dispose();
127
187
  }
128
188
  }
129
- get physicsDebugViewActive() {
130
- return this.physicsWorld.physicsDebugViewActive;
131
- }
132
- set physicsDebugViewActive(value) {
133
- if (this.physicsDebugViewActive === value) {
134
- return;
135
- }
136
- if (value) {
137
- const cls = this.visualScene.debugPhysicsDrawerClass;
138
- if (!cls) {
139
- throw new Error('Debug drawer is not available');
140
- }
141
- this.physicsWorld.startDebugger(this, new cls());
142
- }
143
- else {
144
- this.physicsWorld.stopDebugger(this);
145
- }
146
- }
147
189
  }
148
190
  GgWorld.default_name_counter = 0;
149
191
  GgWorld._documentWorlds = [];
@@ -21,7 +21,6 @@ export * from './inputs/direction.keyboard.input';
21
21
  export * from './inputs/i-input';
22
22
  export * from './inputs/keyboard.input';
23
23
  export * from './inputs/mouse.input';
24
- export * from './interfaces/i-debug-physics-drawer';
25
24
  export * from './interfaces/i-positionable';
26
25
  export * from './models/axis-directions';
27
26
  export * from './models/body-options';
@@ -21,7 +21,6 @@ export * from './inputs/direction.keyboard.input';
21
21
  export * from './inputs/i-input';
22
22
  export * from './inputs/keyboard.input';
23
23
  export * from './inputs/mouse.input';
24
- export * from './interfaces/i-debug-physics-drawer';
25
24
  export * from './interfaces/i-positionable';
26
25
  export * from './models/axis-directions';
27
26
  export * from './models/body-options';
@@ -162,11 +162,16 @@ export class MouseInput extends IInput {
162
162
  .pipe(takeUntil(this.stopped$))
163
163
  .subscribe((event) => {
164
164
  if (pointers.length === 0) {
165
- if (this.options.canvas) {
166
- this.options.canvas.setPointerCapture(event.pointerId);
165
+ try {
166
+ if (this.options.canvas) {
167
+ this.options.canvas.setPointerCapture(event.pointerId);
168
+ }
169
+ this._element.addEventListener('pointerup', onPointerUp);
170
+ this._element.addEventListener('pointercancel', onPointerUp);
171
+ }
172
+ catch (err) {
173
+ console.error(err);
167
174
  }
168
- this._element.addEventListener('pointerup', onPointerUp);
169
- this._element.addEventListener('pointercancel', onPointerUp);
170
175
  }
171
176
  pointers.push(event);
172
177
  if (event.pointerType === 'touch') {
@@ -7,3 +7,12 @@ export interface BodyOptions {
7
7
  ownCollisionGroups: CollisionGroup[] | 'all';
8
8
  interactWithCollisionGroups: CollisionGroup[] | 'all';
9
9
  }
10
+ export declare type DebugBodySettings = {
11
+ shape: any;
12
+ ignoreTransform?: boolean;
13
+ } & ({
14
+ type: 'RIGID_STATIC' | 'TRIGGER';
15
+ } | {
16
+ type: 'RIGID_DYNAMIC';
17
+ sleeping: boolean;
18
+ });
@@ -67,31 +67,39 @@ List of available commands: `.replace(/ /g, '&nbsp;') + `<span style="color:yell
67
67
  };
68
68
  document.getElementById('gg-console-close-icon').onmousedown = () => this.destroyUI();
69
69
  this.elements.input.onkeydown = event => {
70
- if ((event === null || event === void 0 ? void 0 : event.keyCode) === 13) {
70
+ var _a;
71
+ if ((event === null || event === void 0 ? void 0 : event.code) === 'Enter') {
71
72
  event.preventDefault();
72
73
  this.onInput().then();
73
74
  }
74
- else if ((event === null || event === void 0 ? void 0 : event.keyCode) === 38) {
75
+ else if ((event === null || event === void 0 ? void 0 : event.code) === 'ArrowUp') {
75
76
  event.preventDefault();
76
77
  this.onUsePreviousCommand();
77
78
  }
78
- else if ((event === null || event === void 0 ? void 0 : event.keyCode) === 40) {
79
+ else if ((event === null || event === void 0 ? void 0 : event.code) === 'ArrowDown') {
79
80
  event.preventDefault();
80
81
  this.onUseNextCommand();
81
82
  }
83
+ else if ((event === null || event === void 0 ? void 0 : event.code) === 'Backspace') {
84
+ let input = (_a = this.elements) === null || _a === void 0 ? void 0 : _a.input;
85
+ if (input) {
86
+ let value = input.value || '';
87
+ // backspace pressed while input had completion selected.
88
+ // Native logic will remove selected text (completion part), we remove one additional character
89
+ if ((input.selectionStart || value.length) < value.length && input.selectionEnd == value.length) {
90
+ this.elements.input.value = value.substring(0, input.selectionStart || value.length - 1);
91
+ }
92
+ }
93
+ }
82
94
  };
83
95
  this.elements.input.oninput = event => {
84
96
  var _a;
85
97
  let value = ((_a = this.elements) === null || _a === void 0 ? void 0 : _a.input.value) || '';
86
- // backspace
87
- if (value.length > 0 && event.data === null) {
88
- value = value.substring(0, value.length - 1);
89
- }
90
98
  if (value.trim() === '') {
91
99
  return;
92
100
  }
93
101
  let autocompletion = window.ggstatic.availableCommands.find((c) => c[0].startsWith(value));
94
- if (autocompletion) {
102
+ if (autocompletion && autocompletion[0].length > value.length) {
95
103
  this.elements.input.value = autocompletion[0];
96
104
  this.elements.input.setSelectionRange(value.length, this.elements.input.value.length);
97
105
  }
@@ -6,6 +6,15 @@ export declare class GgDebuggerUI {
6
6
  private currentWorld;
7
7
  setShowStats(selectedWorld: GgWorld<any, any>, value: boolean): void;
8
8
  private debugControlsRemoved$;
9
+ private viewUpdated$;
9
10
  get showDebugControls(): boolean;
10
11
  setShowDebugControls(selectedWorld: GgWorld<any, any>, value: boolean): void;
12
+ private snapshot;
13
+ perfStatsMode: 'AVG' | 'PEAK';
14
+ private performanceStatsSnapshot;
15
+ private makeSnapshot;
16
+ private makePerformanceStatsSnapshot;
17
+ css: string;
18
+ private renderControls;
19
+ private renderPerformanceStats;
11
20
  }