Skip to content

Commit

Permalink
fix: [#3128] Unused scene loader locks up engine
Browse files Browse the repository at this point in the history
Closes: #3128

* Special case when no resources, consider it "loaded"
  • Loading branch information
eonarheim committed Jul 20, 2024
1 parent ef8686e commit 4a98742
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ are doing mtv adjustments during precollision.

### Fixed

- Fixed issue where `ex.Scene.onPreLoad(loader: ex.DefaultLoader)` would lock up the engine if there was an empty loader
- Fixed issue where `ex.Scene` scoped input events would preserve state and get stuck causing issues when switching back to the original scene.
- Fixed issue where not all physical keys from the spec were present in `ex.Keys` including the reported `ex.Keys.Tab`
- Fixed invalid graphics types around `ex.Graphic.tint`
Expand Down
12 changes: 12 additions & 0 deletions sandbox/tests/loader-lockup/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Loader Lockup</title>
</head>
<body>
<script src="../../lib/excalibur.js"></script>
<script src="index.js"></script>
</body>
</html>
33 changes: 33 additions & 0 deletions sandbox/tests/loader-lockup/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
class SceneX extends ex.Scene {
override backgroundColor = ex.Color.DarkGray;
override onInitialize() {
this.input.pointers.on('down', () => {
console.warn('should change scenes');
this.engine.goToScene('SceneY');
});
}
}

class SceneY extends ex.Scene {
override backgroundColor = ex.Color.Viridian;
// issue still occurs if onPreLoad is not defined or
// if we call super.onPreLoad(loader)
override onPreLoad(loader: ex.DefaultLoader) {
// un-commenting this call fixes the issue.
// loader.addResource({
// data: {},
// isLoaded: () => true,
// load: () => Promise.resolve(),
// });
}
}

var gameLoaderLockup = new ex.Engine({
scenes: {
SceneX,
SceneY: { scene: SceneY, loader: ex.Loader }
}
});

gameLoaderLockup.start();
gameLoaderLockup.goToScene('SceneX');
4 changes: 4 additions & 0 deletions src/engine/Director/DefaultLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ export class DefaultLoader implements Loadable<Loadable<any>[]> {

private _loadingFuture = new Future<void>();
public areResourcesLoaded() {
if (this._resources.length === 0) {
// special case no resources mean loaded;
return Promise.resolve();
}
return this._loadingFuture.promise;
}

Expand Down
6 changes: 6 additions & 0 deletions src/spec/DefaultLoaderSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ describe('A DefaultLoader', () => {
expect(sut).toBeDefined();
});

it('is loaded when no resources', async () => {
const loader = new ex.DefaultLoader();
expect(loader.isLoaded()).toBe(true);
await expectAsync(loader.areResourcesLoaded()).toBeResolved();
});

it('can be constructed with non-defaults', () => {
const sut = new ex.DefaultLoader({
loadables: [new ex.ImageSource('./some/image.png')]
Expand Down

0 comments on commit 4a98742

Please sign in to comment.