@antha/asset 0.3.0 → 0.4.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/README.md CHANGED
@@ -14,7 +14,12 @@ npm i @antha/asset
14
14
 
15
15
  ```TypeScript
16
16
  import {AnthaEngine, defineAnthaMod} from '@antha/engine';
17
- import {type AnthaAssetModState, createAnthaAssetMod, defineAsset} from '@antha/asset';
17
+ import {
18
+ type AnthaAssetModState,
19
+ type AssetLoader,
20
+ createAnthaAssetMod,
21
+ defineAsset,
22
+ } from '@antha/asset';
18
23
 
19
24
  type GameState = AnthaAssetModState & {
20
25
  hasLoadedTitle: boolean;
@@ -31,6 +36,25 @@ const titleAsset = defineAsset({
31
36
  };
32
37
  },
33
38
  });
39
+
40
+ async function loadTitleAsset({
41
+ assetLoader,
42
+ }: Readonly<{
43
+ assetLoader: AssetLoader;
44
+ }>) {
45
+ const loadSession = assetLoader.createLoadSession();
46
+
47
+ await assetLoader.bulkLoadAssets(
48
+ [
49
+ titleAsset,
50
+ ],
51
+ {
52
+ loadSession,
53
+ },
54
+ );
55
+ loadSession.complete();
56
+ }
57
+
34
58
  const engine = new AnthaEngine<GameState>({
35
59
  initState: {
36
60
  hasLoadedTitle: false,
@@ -39,12 +63,12 @@ const engine = new AnthaEngine<GameState>({
39
63
  createAnthaAssetMod(),
40
64
  defineAnthaMod<GameState>({
41
65
  modName: 'game-logic',
42
- async execute({state}) {
66
+ execute({state}) {
43
67
  if (state.assetLoader && !state.hasLoadedTitle) {
44
68
  state.hasLoadedTitle = true;
45
- await state.assetLoader.bulkLoadAssets([
46
- titleAsset,
47
- ]);
69
+ void loadTitleAsset({
70
+ assetLoader: state.assetLoader,
71
+ });
48
72
  }
49
73
  },
50
74
  }),
@@ -1,21 +1,5 @@
1
1
  import { type PartialWithUndefined } from '@augment-vir/common';
2
2
  import { AssetLoader } from './asset-loader.js';
3
- /**
4
- * Engine state for the Antha asset mod loading screen.
5
- *
6
- * @category Internal
7
- */
8
- export type AnthaAssetModLoadingScreenState = {
9
- /** The total number to load. Once `current` reaches this, loading is considered complete. */
10
- total: number;
11
- /**
12
- * The current number of loaded assets. Once this reaches `total`, the loading is considered
13
- * complete.
14
- */
15
- current: number;
16
- currentResourceName?: string | undefined;
17
- completedAt: DOMHighResTimeStamp | undefined;
18
- };
19
3
  /**
20
4
  * State for {@link AnthaAssetMod}.
21
5
  *
@@ -23,8 +7,6 @@ export type AnthaAssetModLoadingScreenState = {
23
7
  */
24
8
  export type AnthaAssetModState = {
25
9
  assetLoader: AssetLoader;
26
- isShowingLoadingScreen: boolean;
27
- loadingScreenState: AnthaAssetModLoadingScreenState | undefined;
28
10
  };
29
11
  /**
30
12
  * Configuration options for {@link createAnthaAssetMod}.
@@ -33,8 +15,8 @@ export type AnthaAssetModState = {
33
15
  */
34
16
  export type AnthaAssetModOptions = PartialWithUndefined<{
35
17
  /**
36
- * If set to `true`, the default loading screen is not rendered. You should probably make your
37
- * own loading screen in that case.
18
+ * If set to `true`, the default loading screen is not rendered. Loading-session state remains
19
+ * available for a custom loading screen.
38
20
  *
39
21
  * @default false
40
22
  */
@@ -2,7 +2,7 @@ import { defineAnthaMod } from '@antha/engine';
2
2
  import { addSuffix } from '@augment-vir/common';
3
3
  import { css, defineElement, html } from 'element-vir';
4
4
  import { setCssVarValue } from 'lit-css-vars';
5
- import { AssetLoader, AssetLoaderProgressUpdateEvent } from './asset-loader.js';
5
+ import { AssetLoader } from './asset-loader.js';
6
6
  /**
7
7
  * Duration in milliseconds for the loading screen fade-out animation.
8
8
  *
@@ -135,62 +135,36 @@ export function createAnthaAssetMod(options = {}) {
135
135
  modName: anthaAssetModName,
136
136
  async cleanup({ state }) {
137
137
  await state.assetLoader?.destroy();
138
- state.loadingScreenState = undefined;
139
- state.isShowingLoadingScreen = false;
140
138
  },
141
139
  execute({ state, engine }) {
142
140
  if (!state.assetLoader) {
143
141
  state.assetLoader = new AssetLoader({
144
142
  logger: engine.log,
145
143
  });
146
- if (!options.hideLoadingScreen) {
147
- state.assetLoader.listen(AssetLoaderProgressUpdateEvent, (event) => {
148
- if (event.detail.complete) {
149
- state.loadingScreenState = {
150
- current: 1,
151
- total: 1,
152
- currentResourceName: event.detail.currentResourceName ||
153
- state.loadingScreenState?.currentResourceName,
154
- completedAt: engine.totalMs,
155
- };
156
- state.isShowingLoadingScreen = false;
157
- }
158
- else {
159
- state.isShowingLoadingScreen = true;
160
- state.loadingScreenState = {
161
- current: event.detail.current,
162
- total: event.detail.total,
163
- currentResourceName: event.detail.currentResourceName,
164
- completedAt: undefined,
165
- };
166
- }
167
- });
168
- }
169
144
  }
145
+ state.assetLoader.advanceLoadState({
146
+ currentTick: engine.currentTick,
147
+ totalMs: engine.totalMs,
148
+ });
170
149
  if (options.hideLoadingScreen) {
171
150
  return;
172
151
  }
173
- const shouldShowLoadingScreen = state.loadingScreenState?.completedAt
174
- ? engine.totalMs <=
175
- state.loadingScreenState.completedAt + configuredLoadingScreenFadeMs
176
- : true;
177
- if (state.loadingScreenState && shouldShowLoadingScreen) {
178
- const progressPercent = state.loadingScreenState.total > 0
179
- ? (state.loadingScreenState.current / state.loadingScreenState.total) * 100
180
- : 0;
152
+ const loadState = state.assetLoader.loadState;
153
+ if (loadState &&
154
+ (loadState.completedAt == undefined ||
155
+ engine.totalMs <= loadState.completedAt + configuredLoadingScreenFadeMs)) {
156
+ const progressPercent = loadState.total > 0 ? (loadState.current / loadState.total) * 100 : 0;
181
157
  return html `
182
158
  <${AnthaAssetLoadingScreen.assign({
183
159
  progressPercent,
184
160
  dotCount: Math.floor(engine.totalMs / 500) % 4,
185
- completed: !!state.loadingScreenState.completedAt,
186
- currentResourceName: state.loadingScreenState.currentResourceName,
161
+ completed: loadState.completedAt != undefined,
162
+ currentResourceName: loadState.currentResourceName,
187
163
  loadingScreenFadeMs: configuredLoadingScreenFadeMs,
188
164
  })}></${AnthaAssetLoadingScreen}>
189
165
  `;
190
166
  }
191
- else {
192
- return undefined;
193
- }
167
+ return undefined;
194
168
  },
195
169
  });
196
170
  }
@@ -79,12 +79,8 @@ export type AssetBulkLoaderLoadOptions = PartialWithUndefined<{
79
79
  * @default false
80
80
  */
81
81
  doNotUnload: boolean;
82
- /**
83
- * If `true`, the loading screen events will not be emitted.
84
- *
85
- * @default false
86
- */
87
- hideLoadingScreen: boolean;
82
+ /** Receives this bulk load's progress. */
83
+ loadSession: AssetLoadSession;
88
84
  }>;
89
85
  /**
90
86
  * Options for {@link AssetLoader}.
@@ -98,75 +94,123 @@ export type AssetLoaderOptions = PartialWithUndefined<{
98
94
  */
99
95
  logger: AnthaLogger;
100
96
  }>;
101
- declare const AssetLoaderProgressUpdateEvent_base: (new (eventInitDict: {
97
+ /** Progress tracked by an {@link AssetLoadSession}. */
98
+ export type AssetLoadProgress = {
99
+ current: number;
100
+ total: number;
101
+ currentResourceName?: string | undefined;
102
+ };
103
+ /** State of the active asset load. */
104
+ export type AssetLoadState = AssetLoadProgress & {
105
+ completedAt: DOMHighResTimeStamp | undefined;
106
+ isLoading: boolean;
107
+ };
108
+ declare const AssetLoadSessionUpdateEvent_base: (new (eventInitDict: {
102
109
  bubbles?: boolean;
103
110
  cancelable?: boolean;
104
111
  composed?: boolean;
105
- detail: {
106
- current: number;
107
- total: number;
108
- currentResourceName?: string | undefined;
109
- /**
110
- * Always check this complete field first, as any misconfigured assets ma not correctly
111
- * increment `total` but complete will always reliably mark the end of loading.
112
- */
112
+ detail: AssetLoadProgress & {
113
+ /** Indicates that the caller explicitly requested load completion. */
113
114
  complete: boolean;
114
115
  };
115
- }) => import("typed-event-target").TypedCustomEvent<{
116
- current: number;
117
- total: number;
118
- currentResourceName?: string | undefined;
119
- /**
120
- * Always check this complete field first, as any misconfigured assets ma not correctly
121
- * increment `total` but complete will always reliably mark the end of loading.
122
- */
116
+ }) => import("typed-event-target").TypedCustomEvent<AssetLoadProgress & {
117
+ /** Indicates that the caller explicitly requested load completion. */
123
118
  complete: boolean;
124
- }, "antha-asset-loader-progress-update-event">) & Pick<{
119
+ }, "antha-asset-load-session-update-event">) & Pick<{
125
120
  new (type: string, eventInitDict?: EventInit): Event;
126
121
  prototype: Event;
127
122
  readonly NONE: 0;
128
123
  readonly CAPTURING_PHASE: 1;
129
124
  readonly AT_TARGET: 2;
130
125
  readonly BUBBLING_PHASE: 3;
131
- }, "prototype" | "NONE" | "CAPTURING_PHASE" | "AT_TARGET" | "BUBBLING_PHASE"> & Pick<import("typed-event-target").TypedCustomEvent<{
132
- current: number;
133
- total: number;
134
- currentResourceName?: string | undefined;
135
- /**
136
- * Always check this complete field first, as any misconfigured assets ma not correctly
137
- * increment `total` but complete will always reliably mark the end of loading.
138
- */
126
+ }, "prototype" | "NONE" | "CAPTURING_PHASE" | "AT_TARGET" | "BUBBLING_PHASE"> & Pick<import("typed-event-target").TypedCustomEvent<AssetLoadProgress & {
127
+ /** Indicates that the caller explicitly requested load completion. */
139
128
  complete: boolean;
140
- }, "antha-asset-loader-progress-update-event">, "type">;
129
+ }, "antha-asset-load-session-update-event">, "type">;
130
+ /** Event dispatched when an {@link AssetLoadSession} progresses or completes. */
131
+ export declare class AssetLoadSessionUpdateEvent extends AssetLoadSessionUpdateEvent_base {
132
+ }
133
+ /** Manages the progress and explicit completion of an asset load. */
134
+ export declare class AssetLoadSession extends ListenTarget<AssetLoadSessionUpdateEvent> {
135
+ protected currentProgress: AssetLoadProgress;
136
+ protected isComplete: boolean;
137
+ /** Reports a load-progress update without completing the session. */
138
+ reportProgress(progress: Readonly<AssetLoadProgress>): void;
139
+ /** Adds progress to the active resource. */
140
+ incrementProgress({ amount, currentResourceName, }: Readonly<{
141
+ amount?: number | undefined;
142
+ currentResourceName: string;
143
+ }>): void;
144
+ /** Marks this asset load as complete. */
145
+ complete(): void;
146
+ }
141
147
  /**
142
- * Custom event dispatched by {@link AssetLoader} whenever bulk loading progress changes. Used for
143
- * loading screen progression.
148
+ * Maintains the active asset-load session and its state.
144
149
  *
145
150
  * @category Internal
146
151
  */
147
- export declare class AssetLoaderProgressUpdateEvent extends AssetLoaderProgressUpdateEvent_base {
152
+ export declare class AssetLoadSessionController {
153
+ protected currentLoadSessionInternal: AssetLoadSession;
154
+ protected loadStateInternal: AssetLoadState | undefined;
155
+ protected completionRequestedAtTick: number | undefined;
156
+ protected latestEngineTick: number;
157
+ /** Removes the listener for the active load session. */
158
+ protected removeLoadSessionListener: (() => boolean) | undefined;
159
+ constructor();
160
+ /** The active asset-load session. */
161
+ get currentLoadSession(): AssetLoadSession;
162
+ /** The active asset-load state. */
163
+ get loadState(): AssetLoadState | undefined;
164
+ /** Creates and activates a new asset-load session. */
165
+ createLoadSession(): AssetLoadSession;
166
+ /** Advances asset-load completion after an engine render. */
167
+ advance({ currentTick, totalMs, }: Readonly<{
168
+ currentTick: number;
169
+ totalMs: DOMHighResTimeStamp;
170
+ }>): void;
171
+ /** Stops tracking the active load session. */
172
+ destroy(): void;
173
+ /** Tracks updates from the active load session. */
174
+ protected listenToLoadSession(loadSession: AssetLoadSession): void;
148
175
  }
149
176
  /**
150
177
  * Manages loading, caching, and cleanup of game assets with progress tracking.
151
178
  *
152
179
  * @category Asset
153
180
  */
154
- export declare class AssetLoader extends ListenTarget<AssetLoaderProgressUpdateEvent> {
181
+ export declare class AssetLoader {
155
182
  constructor(options?: Readonly<AssetLoaderOptions>);
156
183
  /** Logs data. This will use the user's provided logger or default to browser logs. */
157
184
  protected readonly log: AnthaLogger;
158
185
  protected readonly assetCache: Map<Readonly<Asset<any>>, Promise<AssetLoaderResult<any>>>;
186
+ protected readonly loadSessionController: AssetLoadSessionController;
187
+ /** The active asset-load session. */
188
+ get currentLoadSession(): AssetLoadSession;
189
+ /** The active asset-load state. */
190
+ get loadState(): AssetLoadState | undefined;
191
+ /** Creates and activates a new asset-load session. */
192
+ createLoadSession(): AssetLoadSession;
193
+ /** Advances asset-load completion after an engine render. */
194
+ advanceLoadState({ currentTick, totalMs, }: Readonly<{
195
+ currentTick: number;
196
+ totalMs: DOMHighResTimeStamp;
197
+ }>): void;
159
198
  /** Loads a single asset, returning its cached value if already loaded. */
160
- loadIndividualAsset<ThisAsset extends Asset>({ asset, incrementProgressCallback, }: Readonly<{
199
+ loadIndividualAsset<ThisAsset extends Asset>({ asset, incrementProgressCallback, loadSession, }: Readonly<{
161
200
  asset: Readonly<ThisAsset>;
162
201
  incrementProgressCallback?: AssetIncrementProgressCallback | undefined;
202
+ loadSession?: AssetLoadSession | undefined;
163
203
  }>): Promise<AssetValue<ThisAsset>>;
164
204
  /** Runs cleanup callbacks for the given assets and removes them from the cache. */
165
205
  unloadAssets(assets: ReadonlyArray<Asset>): Promise<void>;
206
+ /** Cleans up cached assets and stops tracking the active load session. */
166
207
  destroy(): Promise<void>;
167
208
  /** Loads multiple assets. */
168
209
  bulkLoadAssets(assets: ReadonlyArray<Readonly<Asset>>, options?: Readonly<AssetBulkLoaderLoadOptions>): Promise<ReadonlyArray<unknown>>;
169
- /** Dispatch a loading progress event for the active bulk load. */
170
- protected dispatchProgressUpdate(detail: ConstructorParameters<typeof AssetLoaderProgressUpdateEvent>[0]['detail']): void;
210
+ /** Sends load progress to the provided session. */
211
+ protected reportProgress({ loadSession, progress, }: Readonly<{
212
+ loadSession: AssetLoadSession | undefined;
213
+ progress: AssetLoadProgress;
214
+ }>): void;
171
215
  }
172
216
  export {};
@@ -9,29 +9,161 @@ import { defineTypedCustomEvent, ListenTarget } from 'typed-event-target';
9
9
  export function defineAsset(asset) {
10
10
  return asset;
11
11
  }
12
+ /** Event dispatched when an {@link AssetLoadSession} progresses or completes. */
13
+ export class AssetLoadSessionUpdateEvent extends defineTypedCustomEvent()('antha-asset-load-session-update-event') {
14
+ }
15
+ /** Manages the progress and explicit completion of an asset load. */
16
+ export class AssetLoadSession extends ListenTarget {
17
+ currentProgress = {
18
+ current: 0,
19
+ currentResourceName: undefined,
20
+ total: 0,
21
+ };
22
+ isComplete = false;
23
+ /** Reports a load-progress update without completing the session. */
24
+ reportProgress(progress) {
25
+ this.currentProgress = progress;
26
+ this.isComplete = false;
27
+ this.dispatch(new AssetLoadSessionUpdateEvent({
28
+ detail: {
29
+ ...progress,
30
+ complete: false,
31
+ },
32
+ }));
33
+ }
34
+ /** Adds progress to the active resource. */
35
+ incrementProgress({ amount, currentResourceName, }) {
36
+ this.reportProgress({
37
+ ...this.currentProgress,
38
+ current: this.currentProgress.current + (amount ?? 1),
39
+ currentResourceName,
40
+ });
41
+ }
42
+ /** Marks this asset load as complete. */
43
+ complete() {
44
+ if (this.isComplete) {
45
+ return;
46
+ }
47
+ this.isComplete = true;
48
+ this.dispatch(new AssetLoadSessionUpdateEvent({
49
+ detail: {
50
+ ...this.currentProgress,
51
+ complete: true,
52
+ },
53
+ }));
54
+ }
55
+ }
12
56
  /**
13
- * Custom event dispatched by {@link AssetLoader} whenever bulk loading progress changes. Used for
14
- * loading screen progression.
57
+ * Maintains the active asset-load session and its state.
15
58
  *
16
59
  * @category Internal
17
60
  */
18
- export class AssetLoaderProgressUpdateEvent extends defineTypedCustomEvent()('antha-asset-loader-progress-update-event') {
61
+ export class AssetLoadSessionController {
62
+ currentLoadSessionInternal;
63
+ loadStateInternal;
64
+ completionRequestedAtTick;
65
+ latestEngineTick = 0;
66
+ /** Removes the listener for the active load session. */
67
+ removeLoadSessionListener;
68
+ constructor() {
69
+ const initialLoadSession = new AssetLoadSession();
70
+ this.currentLoadSessionInternal = initialLoadSession;
71
+ this.listenToLoadSession(initialLoadSession);
72
+ }
73
+ /** The active asset-load session. */
74
+ get currentLoadSession() {
75
+ return this.currentLoadSessionInternal;
76
+ }
77
+ /** The active asset-load state. */
78
+ get loadState() {
79
+ return this.loadStateInternal;
80
+ }
81
+ /** Creates and activates a new asset-load session. */
82
+ createLoadSession() {
83
+ const loadSession = new AssetLoadSession();
84
+ this.removeLoadSessionListener?.();
85
+ this.currentLoadSessionInternal = loadSession;
86
+ this.listenToLoadSession(loadSession);
87
+ loadSession.reportProgress({
88
+ current: 0,
89
+ total: 0,
90
+ });
91
+ return loadSession;
92
+ }
93
+ /** Advances asset-load completion after an engine render. */
94
+ advance({ currentTick, totalMs, }) {
95
+ this.latestEngineTick = currentTick + 1;
96
+ if (this.completionRequestedAtTick != undefined &&
97
+ this.completionRequestedAtTick < currentTick &&
98
+ this.loadStateInternal) {
99
+ this.completionRequestedAtTick = undefined;
100
+ this.loadStateInternal = {
101
+ ...this.loadStateInternal,
102
+ completedAt: totalMs,
103
+ isLoading: false,
104
+ };
105
+ }
106
+ }
107
+ /** Stops tracking the active load session. */
108
+ destroy() {
109
+ this.removeLoadSessionListener?.();
110
+ this.currentLoadSessionInternal.destroy();
111
+ this.completionRequestedAtTick = undefined;
112
+ this.loadStateInternal = undefined;
113
+ }
114
+ /** Tracks updates from the active load session. */
115
+ listenToLoadSession(loadSession) {
116
+ this.removeLoadSessionListener = loadSession.listen(AssetLoadSessionUpdateEvent, (event) => {
117
+ if (event.detail.complete) {
118
+ this.completionRequestedAtTick = this.latestEngineTick;
119
+ }
120
+ else {
121
+ this.completionRequestedAtTick = undefined;
122
+ this.loadStateInternal = {
123
+ current: event.detail.current,
124
+ currentResourceName: event.detail.currentResourceName,
125
+ total: event.detail.total,
126
+ completedAt: undefined,
127
+ isLoading: true,
128
+ };
129
+ }
130
+ });
131
+ }
19
132
  }
20
133
  /**
21
134
  * Manages loading, caching, and cleanup of game assets with progress tracking.
22
135
  *
23
136
  * @category Asset
24
137
  */
25
- export class AssetLoader extends ListenTarget {
138
+ export class AssetLoader {
26
139
  constructor(options = {}) {
27
- super();
28
140
  this.log = options.logger || browserAnthaLogger;
29
141
  }
30
142
  /** Logs data. This will use the user's provided logger or default to browser logs. */
31
143
  log;
32
144
  assetCache = new Map();
145
+ loadSessionController = new AssetLoadSessionController();
146
+ /** The active asset-load session. */
147
+ get currentLoadSession() {
148
+ return this.loadSessionController.currentLoadSession;
149
+ }
150
+ /** The active asset-load state. */
151
+ get loadState() {
152
+ return this.loadSessionController.loadState;
153
+ }
154
+ /** Creates and activates a new asset-load session. */
155
+ createLoadSession() {
156
+ return this.loadSessionController.createLoadSession();
157
+ }
158
+ /** Advances asset-load completion after an engine render. */
159
+ advanceLoadState({ currentTick, totalMs, }) {
160
+ this.loadSessionController.advance({
161
+ currentTick,
162
+ totalMs,
163
+ });
164
+ }
33
165
  /** Loads a single asset, returning its cached value if already loaded. */
34
- async loadIndividualAsset({ asset, incrementProgressCallback, }) {
166
+ async loadIndividualAsset({ asset, incrementProgressCallback, loadSession, }) {
35
167
  const cached = this.assetCache.get(asset);
36
168
  if (cached) {
37
169
  const assetResult = await cached;
@@ -39,9 +171,18 @@ export class AssetLoader extends ListenTarget {
39
171
  }
40
172
  const deferredLoadPromise = new DeferredPromise();
41
173
  this.assetCache.set(asset, deferredLoadPromise.promise);
174
+ loadSession?.reportProgress({
175
+ current: 0,
176
+ currentResourceName: asset.name,
177
+ total: asset.maxProgress,
178
+ });
42
179
  const loadedAsset = await asset.load({
43
180
  incrementProgressCallback(progressParams) {
44
181
  incrementProgressCallback?.(progressParams);
182
+ loadSession?.incrementProgress({
183
+ amount: progressParams,
184
+ currentResourceName: asset.name,
185
+ });
45
186
  },
46
187
  });
47
188
  deferredLoadPromise.resolve(loadedAsset);
@@ -62,8 +203,9 @@ export class AssetLoader extends ListenTarget {
62
203
  this.assetCache.delete(asset);
63
204
  });
64
205
  }
206
+ /** Cleans up cached assets and stops tracking the active load session. */
65
207
  async destroy() {
66
- super.destroy();
208
+ this.loadSessionController.destroy();
67
209
  const entries = Array.from(this.assetCache.entries());
68
210
  await awaitedForEach(entries, async ([asset, result,]) => {
69
211
  await (await result).cleanup?.();
@@ -85,12 +227,14 @@ export class AssetLoader extends ListenTarget {
85
227
  return count + asset.maxProgress;
86
228
  }, 0) + cleanupCount;
87
229
  let currentProgress = 0;
88
- if (!options.hideLoadingScreen && assetsToLoad.length) {
89
- this.dispatchProgressUpdate({
90
- current: currentProgress,
91
- total: maxProgress,
92
- currentResourceName: assetsToLoad[0]?.name,
93
- complete: false,
230
+ if (assetsToLoad.length) {
231
+ this.reportProgress({
232
+ loadSession: options.loadSession,
233
+ progress: {
234
+ current: currentProgress,
235
+ total: maxProgress,
236
+ currentResourceName: assetsToLoad[0]?.name,
237
+ },
94
238
  });
95
239
  }
96
240
  await this.unloadAssets(assetsToCleanup);
@@ -98,14 +242,14 @@ export class AssetLoader extends ListenTarget {
98
242
  return assets.map((asset) => this.assetCache.get(asset));
99
243
  }
100
244
  currentProgress += cleanupCount;
101
- if (!options.hideLoadingScreen) {
102
- this.dispatchProgressUpdate({
245
+ this.reportProgress({
246
+ loadSession: options.loadSession,
247
+ progress: {
103
248
  current: currentProgress,
104
249
  total: maxProgress,
105
250
  currentResourceName: assetsToLoad[0]?.name,
106
- complete: false,
107
- });
108
- }
251
+ },
252
+ });
109
253
  const chunkedAssets = options.maxParallelism
110
254
  ? chunkArray(assets, {
111
255
  chunkSize: options.maxParallelism,
@@ -114,14 +258,14 @@ export class AssetLoader extends ListenTarget {
114
258
  const createIncrementProgressCallback = (asset) => {
115
259
  return (amount) => {
116
260
  currentProgress += amount ?? 1;
117
- if (!options.hideLoadingScreen) {
118
- this.dispatchProgressUpdate({
261
+ this.reportProgress({
262
+ loadSession: options.loadSession,
263
+ progress: {
119
264
  current: currentProgress,
120
265
  total: maxProgress,
121
266
  currentResourceName: asset.name,
122
- complete: false,
123
- });
124
- }
267
+ },
268
+ });
125
269
  };
126
270
  };
127
271
  const results = (await awaitedBlockingMap(chunkedAssets, async (assetChunk) => {
@@ -129,14 +273,14 @@ export class AssetLoader extends ListenTarget {
129
273
  if (this.assetCache.has(asset)) {
130
274
  return (await this.assetCache.get(asset))?.value;
131
275
  }
132
- if (!options.hideLoadingScreen) {
133
- this.dispatchProgressUpdate({
276
+ this.reportProgress({
277
+ loadSession: options.loadSession,
278
+ progress: {
134
279
  current: currentProgress,
135
280
  total: maxProgress,
136
281
  currentResourceName: asset.name,
137
- complete: false,
138
- });
139
- }
282
+ },
283
+ });
140
284
  return await this.loadIndividualAsset({
141
285
  incrementProgressCallback: createIncrementProgressCallback(asset),
142
286
  asset,
@@ -156,20 +300,10 @@ export class AssetLoader extends ListenTarget {
156
300
  },
157
301
  });
158
302
  }
159
- if (!options.hideLoadingScreen) {
160
- this.dispatchProgressUpdate({
161
- current: maxProgress,
162
- total: maxProgress,
163
- currentResourceName: assetsToLoad[assetsToLoad.length - 1]?.name,
164
- complete: true,
165
- });
166
- }
167
303
  return results;
168
304
  }
169
- /** Dispatch a loading progress event for the active bulk load. */
170
- dispatchProgressUpdate(detail) {
171
- this.dispatch(new AssetLoaderProgressUpdateEvent({
172
- detail,
173
- }));
305
+ /** Sends load progress to the provided session. */
306
+ reportProgress({ loadSession, progress, }) {
307
+ loadSession?.reportProgress(progress);
174
308
  }
175
309
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antha/asset",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "An Antha mod for handling asset loading.",
5
5
  "keywords": [
6
6
  "vir",
@@ -48,7 +48,7 @@
48
48
  "pixi.js": "^8.19.0"
49
49
  },
50
50
  "peerDependencies": {
51
- "@antha/engine": "^0.3.0",
51
+ "@antha/engine": "^0.4.0",
52
52
  "element-vir": ">=26"
53
53
  },
54
54
  "engines": {