Skip to content

Commit a2ce2a2

Browse files
authored
refactor(engine)!: refactor AssetManager and loaders (#246)
1 parent 1ff0c7e commit a2ce2a2

File tree

27 files changed

+646
-272
lines changed

27 files changed

+646
-272
lines changed

.changeset/hip-hoops-tell.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@jolly-pixel/engine": major
3+
"@jolly-pixel/voxel.renderer": minor
4+
"@jolly-pixel/runtime": minor
5+
---
6+
7+
Major refactor of AssetManager and loaders

packages/engine/src/audio/AudioLibrary.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
// Import Internal Dependencies
2-
import { Assets } from "../systems/index.ts";
2+
import type { AssetManager } from "../systems/index.ts";
33
import type { LazyAsset } from "../systems/asset/Base.ts";
44

55
export class AudioLibrary<
66
TKeys extends string = string
77
> {
8+
#assetManager: AssetManager;
89
#assets = new Map<TKeys, LazyAsset<AudioBuffer>>();
910

11+
constructor(
12+
assetManager: AssetManager
13+
) {
14+
this.#assetManager = assetManager;
15+
}
16+
1017
register(
1118
name: TKeys,
1219
path: string
1320
): LazyAsset<AudioBuffer> {
14-
const lazy = Assets.load<AudioBuffer>(path);
21+
const lazy = this.#assetManager.load<AudioBuffer>(path);
1522
this.#assets.set(name, lazy);
1623

1724
return lazy;

packages/engine/src/audio/AudioManager.ts

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

44
// Import Internal Dependencies
55
import {
6-
type World,
7-
Assets
6+
AssetLoader,
7+
type World
88
} from "../systems/index.ts";
99
import {
1010
type AudioListenerAdapter
@@ -18,6 +18,16 @@ import {
1818
const kDefaultVolume = 1;
1919
const kDefaultLoop = false;
2020

21+
export const AudioAssetLoader = new AssetLoader<AudioBuffer>({
22+
type: "audio",
23+
extensions: [".mp3", ".ogg", ".wav", ".aac", ".flac"],
24+
load: async(asset, context) => {
25+
const loader = new THREE.AudioLoader(context.manager);
26+
27+
return loader.loadAsync(asset.toString());
28+
}
29+
});
30+
2131
export type AudioManager = {
2232
loadAudio: (url: string, options?: AudioLoadingOptions) => Promise<THREE.Audio>;
2333
loadPositionalAudio: (url: string, options?: AudioLoadingOptions) => Promise<THREE.PositionalAudio>;
@@ -54,17 +64,7 @@ export class GlobalAudioManager implements AudioManager {
5464
listener: world.audio.listener
5565
});
5666

57-
Assets.registry.loader(
58-
{
59-
extensions: [".mp3", ".ogg", ".wav", ".aac", ".flac"],
60-
type: "audio"
61-
},
62-
async(asset, context) => {
63-
const loader = new THREE.AudioLoader(context.manager);
64-
65-
return loader.loadAsync(asset.toString());
66-
}
67-
);
67+
world.assetManager.register(AudioAssetLoader);
6868

6969
return audioManager;
7070
}

packages/engine/src/components/renderers/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ export * from "./text/TextRenderer.class.ts";
44

55
// Import Internal Dependencies
66
import {
7-
model,
7+
ModelAssetLoader,
88
type Model
99
} from "./model/loader.ts";
1010
import {
11-
font,
11+
FontAssetLoader,
1212
type Font
1313
} from "./text/loader.ts";
1414

1515
export const Loaders = {
16-
model,
17-
font
16+
model: ModelAssetLoader,
17+
font: FontAssetLoader
1818
} as const;
1919

2020
export type {

packages/engine/src/components/renderers/model/ModelRenderer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as THREE from "three";
44
// Import Internal Dependencies
55
import * as Systems from "../../../systems/index.ts";
66
import { Actor, ActorComponent } from "../../../actor/index.ts";
7-
import { model, type Model } from "./loader.ts";
7+
import { type Model } from "./loader.ts";
88

99
import {
1010
ModelAnimation,
@@ -49,7 +49,7 @@ export class ModelRenderer<
4949
typeName: "ModelRenderer"
5050
});
5151

52-
this.#asset = model(options.path);
52+
this.#asset = actor.world.assetManager.load<Model>(options.path);
5353
this.#debug = options.debug ?? false;
5454

5555
const { animations } = options;

packages/engine/src/components/renderers/model/loader.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
88
// Import Internal Dependencies
99
import {
1010
Asset,
11-
Assets,
11+
AssetLoader,
1212
type AssetLoaderContext
1313
} from "../../../systems/index.ts";
1414

@@ -17,12 +17,10 @@ export type Model = {
1717
animations: THREE.AnimationClip[];
1818
};
1919

20-
Assets.registry.loader(
21-
{
22-
extensions: [".obj", ".fbx", ".glb", ".gltf"],
23-
type: "model"
24-
},
25-
(asset, context) => {
20+
export const ModelAssetLoader = new AssetLoader<Model>({
21+
type: "model",
22+
extensions: [".obj", ".fbx", ".glb", ".gltf"],
23+
load: (asset, context) => {
2624
switch (asset.ext) {
2725
case ".obj":
2826
return safeLoad(asset, objectLoader(asset, context));
@@ -35,8 +33,7 @@ Assets.registry.loader(
3533
throw new Error(`Unsupported model type: ${asset.ext}`);
3634
}
3735
}
38-
);
39-
export const model = Assets.lazyLoad<Model>();
36+
});
4037

4138
async function objectLoader(
4239
asset: Asset,

packages/engine/src/components/renderers/text/TextRenderer.class.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
Text3D,
99
type Text3DOptions
1010
} from "./Text3D.class.ts";
11-
import { font, type Font } from "./loader.ts";
11+
import { type Font } from "./loader.ts";
1212

1313
export interface TextRendererOptions extends Omit<Text3DOptions, "font"> {
1414
path: string;
@@ -36,7 +36,7 @@ export class TextRenderer extends ActorComponent<any> {
3636
material = new THREE.MeshBasicMaterial()
3737
} = options;
3838

39-
this.#asset = font(path);
39+
this.#asset = actor.world.assetManager.load<Font>(path);
4040
this.text = new Text3D({
4141
material,
4242
textGeometryOptions

packages/engine/src/components/renderers/text/loader.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,17 @@ import {
55
} from "three/examples/jsm/loaders/FontLoader.js";
66

77
// Import Internal Dependencies
8-
import {
9-
Assets
10-
} from "../../../systems/index.ts";
8+
import { AssetLoader } from "../../../systems/index.ts";
119

12-
Assets.registry.loader(
13-
{
14-
extensions: [".typeface.json"],
15-
type: "font"
16-
},
17-
(asset, context) => {
10+
export const FontAssetLoader = new AssetLoader<Font>({
11+
type: "font",
12+
extensions: [".typeface.json"],
13+
load: (asset, context) => {
1814
const fontLoader = new FontLoader(context.manager)
1915
.setPath(asset.path);
2016

2117
return fontLoader.loadAsync(asset.name + asset.ext);
2218
}
23-
);
24-
25-
export const font = Assets.lazyLoad<Font>();
19+
});
2620

2721
export type { Font };

packages/engine/src/components/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Import Internal Dependencies
22
import { Actor } from "../actor/Actor.ts";
3+
import type { AssetManager } from "../systems/index.ts";
34

45
export type StrictComponentEnum =
56
| "ScriptBehavior"
@@ -11,11 +12,16 @@ export type StrictComponentEnum =
1112

1213
export type FreeComponentEnum = StrictComponentEnum | (string & {});
1314

15+
export interface ComponentInitializeContext {
16+
assetManager: AssetManager;
17+
}
18+
1419
export interface Component {
1520
actor: Actor<any>;
1621
typeName: FreeComponentEnum;
1722
needUpdate: boolean;
1823

24+
initialize?(context: ComponentInitializeContext): Promise<void>;
1925
awake?(): void;
2026
start?(): void;
2127
update?(deltaTime: number): void;

packages/engine/src/systems/Scene.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import { EventEmitter } from "@posva/event-emitter";
66
import type { World, WorldDefaultContext } from "./World.ts";
77
import { IntegerIncrement } from "./generators/IntegerIncrement.ts";
88
import type { Logger } from "./Logger.ts";
9+
import type { ComponentInitializeContext } from "../components/types.ts";
910

1011
export type SceneLifecycleEvents = {
12+
initialize: [];
1113
awake: [];
1214
start: [];
1315
destroy: [];
@@ -44,6 +46,13 @@ export abstract class Scene<
4446
return this.#logger;
4547
}
4648

49+
/**
50+
* Called once before awake(), asynchronously. Use this to declare asset dependencies
51+
* via context.assetManager.load(). All declared assets will be fully loaded before
52+
* awake() is called.
53+
*/
54+
async initialize(_context: ComponentInitializeContext): Promise<void> {}
55+
4756
/**
4857
* Called once when the scene is first activated (before the first start/update).
4958
* Populate actors here.

0 commit comments

Comments
 (0)