Skip to content

Commit c8405ca

Browse files
authored
fix: mistake with new GameInstance TContext generic (#155)
1 parent 775590f commit c8405ca

File tree

15 files changed

+115
-47
lines changed

15 files changed

+115
-47
lines changed

.changeset/humble-hats-poke.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@jolly-pixel/runtime": patch
3+
"@jolly-pixel/engine": patch
4+
---
5+
6+
Fix some mistake with newest GameInstance TContext generic and add a type GameInstanceDefaultContext to avoid repeting the default type everywhere

packages/engine/src/actor/Actor.ts

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
import * as THREE from "three";
33

44
// Import Internal Dependencies
5-
import { type GameInstance } from "../systems/GameInstance.ts";
6-
import type { ActorComponent } from "./ActorComponent.ts";
75
import { ActorTree } from "./ActorTree.ts";
86
import { Transform } from "./Transform.ts";
7+
import type { GameInstance, GameInstanceDefaultContext } from "../systems/GameInstance.ts";
8+
import type { ActorComponent } from "./ActorComponent.ts";
99
import type { Behavior } from "../components/script/Behavior.ts";
1010
import type {
1111
Component
@@ -18,14 +18,18 @@ type RequiresOptions<T extends ComponentConstructor> =
1818
? undefined extends O ? false : true
1919
: false;
2020

21-
export interface ActorOptions<TContext = Record<string, unknown>> {
21+
export interface ActorOptions<
22+
TContext = GameInstanceDefaultContext
23+
> {
2224
name: string;
2325
parent?: Actor<TContext> | null;
2426
visible?: boolean;
2527
layer?: number | number[];
2628
}
2729

28-
export class Actor<TContext = Record<string, unknown>> extends ActorTree<TContext> {
30+
export class Actor<
31+
TContext = GameInstanceDefaultContext
32+
> extends ActorTree<TContext> {
2933
gameInstance: GameInstance<any, TContext>;
3034

3135
name: string;
@@ -39,13 +43,16 @@ export class Actor<TContext = Record<string, unknown>> extends ActorTree<TContex
3943
threeObject = new THREE.Group();
4044

4145
constructor(
42-
gameInstance: GameInstance<any, any>,
46+
gameInstance: GameInstance<any, TContext>,
4347
options: ActorOptions<TContext>
4448
) {
4549
super();
4650
const { name, parent = null, visible = true, layer } = options;
4751

48-
if (parent !== null && parent.pendingForDestruction) {
52+
if (
53+
parent !== null &&
54+
parent.pendingForDestruction
55+
) {
4956
throw new Error("Cannot add actor to a parent that is pending for destruction.");
5057
}
5158

@@ -111,14 +118,13 @@ export class Actor<TContext = Record<string, unknown>> extends ActorTree<TContex
111118
}
112119

113120
getComponentByName<T extends ActorComponent<TContext>>(
114-
actor: Actor<TContext>,
115-
componentName: string
121+
componentTypeName: string
116122
): T {
117-
const component = actor.components.find(
118-
(comp) => comp.typeName === componentName
123+
const component = this.components.find(
124+
(comp) => comp.typeName === componentTypeName
119125
);
120126
if (!component) {
121-
throw new Error(`Component with typeName "${componentName}" not found on actor "${actor.name}"`);
127+
throw new Error(`Component with typeName "${componentTypeName}" not found on actor "${this.name}"`);
122128
}
123129

124130
return component as T;

packages/engine/src/actor/ActorComponent.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@ import { EventEmitter } from "@posva/event-emitter";
44
// Import Internal Dependencies
55
import { Actor } from "./Actor.ts";
66
import { getSignalMetadata, SignalEvent } from "./Signal.ts";
7+
import type {
8+
GameInstanceDefaultContext
9+
} from "../systems/GameInstance.ts";
710
import type {
811
Component,
912
FreeComponentEnum
1013
} from "../components/types.ts";
1114

12-
export interface ActorComponentOptions<TContext = Record<string, unknown>> {
15+
export interface ActorComponentOptions<
16+
TContext = GameInstanceDefaultContext
17+
> {
1318
actor: Actor<TContext>;
1419
typeName: FreeComponentEnum;
1520
}
@@ -18,7 +23,9 @@ export type ActorComponentEvents = {
1823
metadataInitialized: [];
1924
};
2025

21-
export class ActorComponent<TContext = Record<string, unknown>> extends EventEmitter<ActorComponentEvents> implements Component {
26+
export class ActorComponent<
27+
TContext = GameInstanceDefaultContext
28+
> extends EventEmitter<ActorComponentEvents> implements Component {
2229
protected static Id = 0;
2330

2431
static generateNextId() {

packages/engine/src/actor/ActorTree.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,28 @@
22
import pm from "picomatch";
33

44
// Import Internal Dependencies
5+
import type {
6+
GameInstanceDefaultContext
7+
} from "../systems/GameInstance.ts";
58
import { Actor } from "./Actor.ts";
69

7-
export type ActorTreeNode<TContext = Record<string, unknown>> = {
10+
export type ActorTreeNode<
11+
TContext = GameInstanceDefaultContext
12+
> = {
813
actor: Actor<TContext>;
914
parent?: Actor<TContext>;
1015
};
1116

12-
export interface ActorTreeOptions<TContext = Record<string, unknown>> {
17+
export interface ActorTreeOptions<
18+
TContext = GameInstanceDefaultContext
19+
> {
1320
addCallback?: (actor: Actor<TContext>) => void;
1421
removeCallback?: (actor: Actor<TContext>) => void;
1522
}
1623

17-
export class ActorTree<TContext = Record<string, unknown>> {
24+
export class ActorTree<
25+
TContext = GameInstanceDefaultContext
26+
> {
1827
#addCallback?: (actor: Actor<TContext>) => void;
1928
#removeCallback?: (actor: Actor<TContext>) => void;
2029

packages/engine/src/audio/AudioManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export class GlobalAudioManager implements AudioManager {
4343
#audioService: AudioFactory;
4444

4545
static fromGameInstance(
46-
gameInstance: GameInstance
46+
gameInstance: GameInstance<any, any>
4747
): GlobalAudioManager {
4848
return new GlobalAudioManager({
4949
listener: gameInstance.audio.listener

packages/engine/src/components/script/Behavior.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
import * as THREE from "three";
33

44
// Import Internal Dependencies
5+
import type {
6+
GameInstanceDefaultContext
7+
} from "../../systems/GameInstance.ts";
58
import {
69
Actor,
710
ActorComponent
@@ -25,7 +28,7 @@ export interface BehaviorOptions {
2528

2629
export class Behavior<
2730
T extends BehaviorProperties = Record<string, BehaviorPropertiesValue>,
28-
TContext = Record<string, unknown>
31+
TContext = GameInstanceDefaultContext
2932
> extends ActorComponent<TContext> {
3033
#properties: T = Object.create(null);
3134

packages/engine/src/systems/GameInstance.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ import {
2323
BrowserGlobalsAdapter
2424
} from "../adapters/global.ts";
2525

26-
export interface GameInstanceOptions<TContext = Record<string, unknown>> {
26+
export interface GameInstanceOptions<
27+
TContext = GameInstanceDefaultContext
28+
> {
2729
enableOnExit?: boolean;
2830

2931
scene: Scene;
@@ -35,7 +37,14 @@ export interface GameInstanceOptions<TContext = Record<string, unknown>> {
3537
globalsAdapter?: GlobalsAdapter;
3638
}
3739

38-
export class GameInstance<T = THREE.WebGLRenderer, TContext = Record<string, unknown>> {
40+
export interface GameInstanceDefaultContext {
41+
[key: string]: unknown;
42+
}
43+
44+
export class GameInstance<
45+
T = THREE.WebGLRenderer,
46+
TContext = GameInstanceDefaultContext
47+
> {
3948
renderer: Renderer<T>;
4049
input: Input;
4150
loadingManager: THREE.LoadingManager = new THREE.LoadingManager();
@@ -53,7 +62,7 @@ export class GameInstance<T = THREE.WebGLRenderer, TContext = Record<string, unk
5362
scene,
5463
input = new Input(renderer.canvas, { enableOnExit: options.enableOnExit ?? false }),
5564
audio = new GlobalAudio(),
56-
context = {} as TContext,
65+
context = Object.create(null),
5766
windowAdapter = new BrowserWindowAdapter(),
5867
globalsAdapter = new BrowserGlobalsAdapter()
5968
} = options;

packages/engine/src/ui/UINode.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
import * as THREE from "three";
33

44
// Import Internal Dependencies
5-
import { type Actor, ActorComponent } from "../actor/index.ts";
5+
import type { GameInstanceDefaultContext } from "../systems/GameInstance.ts";
66
import type { UIRenderer } from "./UIRenderer.ts";
7+
import { type Actor, ActorComponent } from "../actor/index.ts";
8+
import { UIRendererID } from "./common.ts";
79

810
export type UIAnchorX = "left" | "center" | "right";
911
export type UIAnchorY = "top" | "center" | "bottom";
@@ -56,17 +58,19 @@ export interface UINodeOptions extends UINodePositionalOptions {
5658
};
5759
}
5860

59-
export class UINode extends ActorComponent<any> {
61+
export class UINode<TContext = GameInstanceDefaultContext> extends ActorComponent<TContext> {
6062
#options: UINodeOptions;
6163

6264
constructor(
63-
actor: Actor<any>,
65+
actor: Actor<TContext>,
6466
options: UINodeOptions = {}
6567
) {
6668
super({ actor, typeName: "UINode" });
6769
this.#options = options;
6870

69-
const uiRenderer = this.actor.gameInstance[Symbol.for("UIRenderer")] as UIRenderer;
71+
const uiRenderer = this.actor.gameInstance[
72+
UIRendererID
73+
] as UIRenderer<TContext> | undefined;
7074
if (uiRenderer) {
7175
uiRenderer.addChildren(this);
7276
}

packages/engine/src/ui/UIRenderer.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import * as THREE from "three";
33
import { CSS2DRenderer as ThreeCSS2DRenderer } from "three/addons/renderers/CSS2DRenderer.js";
44

55
// Import Internal Dependencies
6-
import { type Actor, ActorComponent } from "../actor/index.ts";
6+
import type { GameInstanceDefaultContext } from "../systems/GameInstance.ts";
77
import type { UINode } from "./UINode.ts";
8+
import { type Actor, ActorComponent } from "../actor/index.ts";
9+
import { UIRendererID } from "./common.ts";
810

911
// CONSTANTS
1012
const kOrthographicCameraZIndex = 10;
@@ -15,18 +17,18 @@ export interface UIRendererOptions {
1517
zIndex?: number;
1618
}
1719

18-
export class UIRenderer extends ActorComponent<any> {
19-
static ID = Symbol.for("UIRenderer");
20-
20+
export class UIRenderer<
21+
TContext = GameInstanceDefaultContext
22+
> extends ActorComponent<TContext> {
2123
camera: THREE.OrthographicCamera;
22-
nodes: UINode[] = [];
24+
nodes: UINode<TContext>[] = [];
2325

2426
#cssRenderer: ThreeCSS2DRenderer;
2527
#boundDraw: () => void;
2628
#boundResize: () => void;
2729

2830
constructor(
29-
actor: Actor<any>,
31+
actor: Actor<TContext>,
3032
options: UIRendererOptions = {}
3133
) {
3234
super({ actor, typeName: "UIRenderer" });
@@ -70,13 +72,15 @@ export class UIRenderer extends ActorComponent<any> {
7072
gameInstance.renderer.on("resize", this.#boundResize);
7173
gameInstance.renderer.on("draw", this.#boundDraw);
7274

73-
Object.defineProperty(gameInstance, UIRenderer.ID, {
75+
Object.defineProperty(gameInstance, UIRendererID, {
7476
value: this,
7577
enumerable: false
7678
});
7779
}
7880

79-
addChildren(node: UINode): void {
81+
addChildren(
82+
node: UINode<TContext>
83+
): void {
8084
const nodeIndex = this.nodes.indexOf(node);
8185
if (nodeIndex !== -1) {
8286
return;
@@ -118,6 +122,6 @@ export class UIRenderer extends ActorComponent<any> {
118122

119123
this.#cssRenderer.domElement.remove();
120124

121-
gameInstance[UIRenderer.ID] = undefined;
125+
gameInstance[UIRendererID] = undefined;
122126
}
123127
}

packages/engine/src/ui/UISprite.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
import * as THREE from "three";
33

44
// Import Internal Dependencies
5+
import type {
6+
GameInstanceDefaultContext
7+
} from "../systems/GameInstance.ts";
58
import {
69
Actor,
710
SignalEvent
@@ -30,14 +33,16 @@ export interface UISpriteOptions extends UINodeOptions {
3033
styleOnHover?: UISpriteStyle;
3134
}
3235

33-
export class UISprite extends UINode {
36+
export class UISprite<
37+
TContext = GameInstanceDefaultContext
38+
> extends UINode<TContext> {
3439
mesh: THREE.Mesh;
3540

3641
#isHovered = false;
3742
#isPressed = false;
3843
#style: UISpriteStyle;
3944
#styleOnHover: UISpriteStyle | null;
40-
#text: UIText | undefined;
45+
#text: UIText<TContext> | undefined;
4146

4247
#lastClickTime = 0;
4348

@@ -51,7 +56,7 @@ export class UISprite extends UINode {
5156
onHover = new SignalEvent();
5257

5358
constructor(
54-
actor: Actor<any>,
59+
actor: Actor<TContext>,
5560
options: UISpriteOptions = {}
5661
) {
5762
super(actor, options);

0 commit comments

Comments
 (0)