@hkdigital/lib-core 0.4.77 → 0.4.78
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.
|
@@ -380,31 +380,43 @@ export default class SceneBase {
|
|
|
380
380
|
return;
|
|
381
381
|
}
|
|
382
382
|
|
|
383
|
-
|
|
383
|
+
let completedCount = 0;
|
|
384
|
+
const totalLoaders = this.sources.length;
|
|
385
|
+
|
|
386
|
+
// Start all loaders with completion callbacks
|
|
384
387
|
for (let i = 0; i < this.sources.length; i++) {
|
|
385
388
|
const source = this.sources[i];
|
|
386
389
|
const loader = this.getLoaderFromSource(source);
|
|
387
|
-
loader.load();
|
|
388
|
-
}
|
|
389
390
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
allLoaded = false;
|
|
398
|
-
break;
|
|
399
|
-
}
|
|
391
|
+
loader.load((completedLoader, finalState) => {
|
|
392
|
+
console.debug(`SceneBase:loader-finished [${completedLoader._url}] ${finalState}`);
|
|
393
|
+
|
|
394
|
+
// Check for errors
|
|
395
|
+
if (finalState === STATE_ERROR) {
|
|
396
|
+
this.#state.send(ERROR, completedLoader.error || new Error('Loader failed'));
|
|
397
|
+
return;
|
|
400
398
|
}
|
|
401
399
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
400
|
+
// Check for abort - don't count aborted loaders as completed
|
|
401
|
+
if (finalState === STATE_ABORTED) {
|
|
402
|
+
// Aborted loaders are handled by SceneBase's own abort logic
|
|
403
|
+
console.debug(`SceneBase:loader-aborted [${completedLoader._url}] - not counting toward completion`);
|
|
404
|
+
return;
|
|
405
405
|
}
|
|
406
|
-
|
|
407
|
-
|
|
406
|
+
|
|
407
|
+
// Only count successfully loaded loaders
|
|
408
|
+
if (finalState === STATE_LOADED) {
|
|
409
|
+
completedCount++;
|
|
410
|
+
console.debug(`SceneBase:loader-completed [${completedLoader._url}] (${completedCount}/${totalLoaders})`);
|
|
411
|
+
|
|
412
|
+
// Check for completion
|
|
413
|
+
if (completedCount === totalLoaders) {
|
|
414
|
+
console.debug('SceneBase:all-loaders-completed-via-callback');
|
|
415
|
+
this.#state.send(LOADED);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
}
|
|
408
420
|
}
|
|
409
421
|
|
|
410
422
|
#startAbort() {
|
|
@@ -35,8 +35,11 @@ export default class NetworkLoader {
|
|
|
35
35
|
_abortLoading: null | (() => void);
|
|
36
36
|
/**
|
|
37
37
|
* Start loading all network data
|
|
38
|
+
*
|
|
39
|
+
* @param {null|((loader: NetworkLoader, finalState: string) => void)} [onCompletion]
|
|
40
|
+
* Optional callback called when loader reaches a terminal state (loaded/error/aborted)
|
|
38
41
|
*/
|
|
39
|
-
load(): void;
|
|
42
|
+
load(onCompletion?: null | ((loader: NetworkLoader, finalState: string) => void)): void;
|
|
40
43
|
/**
|
|
41
44
|
* Unoad all network data
|
|
42
45
|
*/
|
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
STATE_UNLOADING,
|
|
9
9
|
STATE_LOADED,
|
|
10
10
|
STATE_ABORTING,
|
|
11
|
+
STATE_ABORTED,
|
|
12
|
+
STATE_ERROR,
|
|
11
13
|
LOAD,
|
|
12
14
|
ERROR,
|
|
13
15
|
LOADED,
|
|
@@ -89,6 +91,9 @@ export default class NetworkLoader {
|
|
|
89
91
|
/** @type {null|(()=>void)} */
|
|
90
92
|
_abortLoading = null;
|
|
91
93
|
|
|
94
|
+
/** @type {null|((loader: NetworkLoader, finalState: string) => void)} */
|
|
95
|
+
#completionCallback = null;
|
|
96
|
+
|
|
92
97
|
/**
|
|
93
98
|
* Construct NetworkLoader
|
|
94
99
|
*
|
|
@@ -104,6 +109,17 @@ export default class NetworkLoader {
|
|
|
104
109
|
console.debug(`loader:onenter [${this._url}] ${currentState}`);
|
|
105
110
|
this.state = currentState;
|
|
106
111
|
|
|
112
|
+
// Check if we've reached a terminal state
|
|
113
|
+
const isTerminalState = currentState === STATE_LOADED ||
|
|
114
|
+
currentState === STATE_ERROR ||
|
|
115
|
+
currentState === STATE_ABORTED;
|
|
116
|
+
|
|
117
|
+
if (isTerminalState && this.#completionCallback) {
|
|
118
|
+
const callback = this.#completionCallback;
|
|
119
|
+
this.#completionCallback = null; // Clean up immediately
|
|
120
|
+
callback(this, currentState); // Call with loader and final state
|
|
121
|
+
}
|
|
122
|
+
|
|
107
123
|
switch (currentState) {
|
|
108
124
|
case STATE_LOADING:
|
|
109
125
|
{
|
|
@@ -155,8 +171,12 @@ export default class NetworkLoader {
|
|
|
155
171
|
|
|
156
172
|
/**
|
|
157
173
|
* Start loading all network data
|
|
174
|
+
*
|
|
175
|
+
* @param {null|((loader: NetworkLoader, finalState: string) => void)} [onCompletion]
|
|
176
|
+
* Optional callback called when loader reaches a terminal state (loaded/error/aborted)
|
|
158
177
|
*/
|
|
159
|
-
load() {
|
|
178
|
+
load(onCompletion = null) {
|
|
179
|
+
this.#completionCallback = onCompletion;
|
|
160
180
|
this.#state.send(LOAD);
|
|
161
181
|
}
|
|
162
182
|
|
|
@@ -327,6 +347,12 @@ export default class NetworkLoader {
|
|
|
327
347
|
// this._size = this._buffer.byteLength;
|
|
328
348
|
// }
|
|
329
349
|
|
|
350
|
+
// Check if we've been aborted before sending LOADED
|
|
351
|
+
if (this.#state.current === STATE_ABORTING || this.#state.current === STATE_ABORTED) {
|
|
352
|
+
console.debug(`loader:already-aborted [${this._url}] - not sending LOADED`);
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
|
|
330
356
|
console.debug(`loader:sending-LOADED [${this._url}]`);
|
|
331
357
|
this.#state.send(LOADED);
|
|
332
358
|
} catch (e) {
|