[Optimization] Destroy LoadingScene when done (after beta rebase) (#3215)
* destroy loading-scene when done - unused event listeners are shut off - children are removed - `loading_bg` will be removed after transition is finished - Added some simple types for `rex` plugins * fix tests * fix pokemonSprite.test.ts on local runs it would include hidden dirs like `.DS_store`. Any files starting with `.` is now excluded * add `mockGameObjectCreator` and use in `gameWrapper` * add battle-scene.test.ts add test to verify that LoadingScene is being removed on `BatleScene.create()` call * update types usage for phaser3-rex-plugins * remove phaser-extensions.d.ts fk you typedoc...
This commit is contained in:
parent
e9c48ef865
commit
29aa1a68e7
|
@ -69,6 +69,7 @@ import { TimedEventManager } from "#app/timed-event-manager.js";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import {TrainerType} from "#enums/trainer-type";
|
import {TrainerType} from "#enums/trainer-type";
|
||||||
import { battleSpecDialogue } from "./data/dialogue";
|
import { battleSpecDialogue } from "./data/dialogue";
|
||||||
|
import { LoadingScene } from "./loading-scene";
|
||||||
|
|
||||||
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
||||||
|
|
||||||
|
@ -320,6 +321,7 @@ export default class BattleScene extends SceneBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
|
this.scene.remove(LoadingScene.KEY);
|
||||||
initGameSpeed.apply(this);
|
initGameSpeed.apply(this);
|
||||||
this.inputController = new InputsController(this);
|
this.inputController = new InputsController(this);
|
||||||
this.uiInputs = new UiInputs(this, this.inputController);
|
this.uiInputs = new UiInputs(this, this.inputController);
|
||||||
|
@ -370,7 +372,7 @@ export default class BattleScene extends SceneBase {
|
||||||
|
|
||||||
this.fieldUI = fieldUI;
|
this.fieldUI = fieldUI;
|
||||||
|
|
||||||
const transition = (this.make as any).rexTransitionImagePack({
|
const transition = this.make.rexTransitionImagePack({
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
scale: 6,
|
scale: 6,
|
||||||
|
@ -378,11 +380,15 @@ export default class BattleScene extends SceneBase {
|
||||||
origin: { x: 0, y: 0 }
|
origin: { x: 0, y: 0 }
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
//@ts-ignore (the defined types in the package are incromplete...)
|
||||||
transition.transit({
|
transition.transit({
|
||||||
mode: "blinds",
|
mode: "blinds",
|
||||||
ease: "Cubic.easeInOut",
|
ease: "Cubic.easeInOut",
|
||||||
duration: 1250,
|
duration: 1250,
|
||||||
oncomplete: () => transition.destroy()
|
});
|
||||||
|
transition.once("complete", () => {
|
||||||
|
this.textures.remove("loading_bg");
|
||||||
|
transition.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.add.existing(transition);
|
this.add.existing(transition);
|
||||||
|
|
|
@ -24,10 +24,12 @@ import { Biome } from "#enums/biome";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
|
|
||||||
export class LoadingScene extends SceneBase {
|
export class LoadingScene extends SceneBase {
|
||||||
|
public static readonly KEY = "loading";
|
||||||
|
|
||||||
readonly LOAD_EVENTS = Phaser.Loader.Events;
|
readonly LOAD_EVENTS = Phaser.Loader.Events;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super("loading");
|
super(LoadingScene.KEY);
|
||||||
|
|
||||||
Phaser.Plugins.PluginCache.register("Loader", CacheBustedLoaderPlugin, "load");
|
Phaser.Plugins.PluginCache.register("Loader", CacheBustedLoaderPlugin, "load");
|
||||||
initI18n();
|
initI18n();
|
||||||
|
@ -434,7 +436,7 @@ export class LoadingScene extends SceneBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
const intro = this.add.video(0, 0);
|
const intro = this.add.video(0, 0);
|
||||||
intro.on(Phaser.GameObjects.Events.VIDEO_COMPLETE, (video: Phaser.GameObjects.Video) => {
|
intro.once(Phaser.GameObjects.Events.VIDEO_COMPLETE, (video: Phaser.GameObjects.Video) => {
|
||||||
this.tweens.add({
|
this.tweens.add({
|
||||||
targets: intro,
|
targets: intro,
|
||||||
duration: 500,
|
duration: 500,
|
||||||
|
@ -482,7 +484,10 @@ export class LoadingScene extends SceneBase {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.load.on(this.LOAD_EVENTS.COMPLETE, () => loadingGraphics.forEach(go => go.destroy()));
|
this.load.on(this.LOAD_EVENTS.COMPLETE, () => {
|
||||||
|
loadingGraphics.forEach(go => go.destroy());
|
||||||
|
intro.destroy();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get gameHeight() {
|
get gameHeight() {
|
||||||
|
@ -494,6 +499,17 @@ export class LoadingScene extends SceneBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
async create() {
|
async create() {
|
||||||
|
this.events.once(Phaser.Scenes.Events.DESTROY, () => this.handleDestroy());
|
||||||
this.scene.start("battle");
|
this.scene.start("battle");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleDestroy() {
|
||||||
|
console.debug(`Destroying ${LoadingScene.KEY} scene`);
|
||||||
|
this.load.off(this.LOAD_EVENTS.PROGRESS);
|
||||||
|
this.load.off(this.LOAD_EVENTS.FILE_COMPLETE);
|
||||||
|
this.load.off(this.LOAD_EVENTS.COMPLETE);
|
||||||
|
// this.textures.remove("loading_bg"); is removed in BattleScene.launchBattle()
|
||||||
|
this.children.removeAll(true);
|
||||||
|
console.debug(`Destroyed ${LoadingScene.KEY} scene`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { LoadingScene } from "#app/loading-scene.js";
|
||||||
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
import GameManager from "./utils/gameManager";
|
||||||
|
|
||||||
|
describe("BattleScene", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should remove LoadingScene on create", () => {
|
||||||
|
// `BattleScene.create()` is called during the `new GameManager()` call
|
||||||
|
expect(game.scene.scene.remove).toHaveBeenCalledWith(LoadingScene.KEY);
|
||||||
|
});
|
||||||
|
});
|
|
@ -4,17 +4,18 @@ import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { getAppRootDir } from "#app/test/sprites/spritesUtils";
|
import { getAppRootDir } from "#app/test/sprites/spritesUtils";
|
||||||
|
|
||||||
const deepCopy = (data) => {
|
type PokemonVariantMasterlist = typeof _masterlist;
|
||||||
|
|
||||||
|
const deepCopy = (data: any) => {
|
||||||
return JSON.parse(JSON.stringify(data));
|
return JSON.parse(JSON.stringify(data));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
describe("check if every variant's sprite are correctly set", () => {
|
describe("check if every variant's sprite are correctly set", () => {
|
||||||
let masterlist;
|
let masterlist: PokemonVariantMasterlist;
|
||||||
let expVariant;
|
let expVariant: PokemonVariantMasterlist["exp"];
|
||||||
let femaleVariant;
|
let femaleVariant: PokemonVariantMasterlist["female"];
|
||||||
let backVariant;
|
let backVariant: PokemonVariantMasterlist["back"];
|
||||||
let rootDir;
|
let rootDir: string;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
rootDir = `${getAppRootDir()}${path.sep}public${path.sep}images${path.sep}pokemon${path.sep}variant${path.sep}`;
|
rootDir = `${getAppRootDir()}${path.sep}public${path.sep}images${path.sep}pokemon${path.sep}variant${path.sep}`;
|
||||||
|
@ -34,11 +35,11 @@ describe("check if every variant's sprite are correctly set", () => {
|
||||||
expect(backVariant).not.toBeUndefined();
|
expect(backVariant).not.toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
function getMissingMasterlist(mlist, dirpath, excludes = []) {
|
function getMissingMasterlist(mlist: any, dirpath: string, excludes: string[] = []): string[] {
|
||||||
const errors = [];
|
const errors: string[] = [];
|
||||||
const trimmedDirpath = `variant${path.sep}${dirpath.split(rootDir)[1]}`;
|
const trimmedDirpath = `variant${path.sep}${dirpath.split(rootDir)[1]}`;
|
||||||
if (fs.existsSync(dirpath)) {
|
if (fs.existsSync(dirpath)) {
|
||||||
const files = fs.readdirSync(dirpath).filter(filename => !filename.startsWith("."));
|
const files = fs.readdirSync(dirpath).filter((filename) => !/^\..*/.test(filename));
|
||||||
for (const filename of files) {
|
for (const filename of files) {
|
||||||
const filePath = `${dirpath}${filename}`;
|
const filePath = `${dirpath}${filename}`;
|
||||||
const trimmedFilePath = `${trimmedDirpath}${filename}`;
|
const trimmedFilePath = `${trimmedDirpath}${filename}`;
|
||||||
|
@ -101,12 +102,12 @@ describe("check if every variant's sprite are correctly set", () => {
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMissingFiles(keys, dirPath) {
|
function getMissingFiles(keys: Record<string, any>, dirPath: string): string[] {
|
||||||
const errors = [];
|
const errors = [];
|
||||||
for (const key of Object.keys(keys)) {
|
for (const key of Object.keys(keys)) {
|
||||||
const row = keys[key];
|
const row = keys[key];
|
||||||
for (const [index, elm] of row.entries()) {
|
for (const [index, elm] of row.entries()) {
|
||||||
let url;
|
let url: string;
|
||||||
if (elm === 0) {
|
if (elm === 0) {
|
||||||
continue;
|
continue;
|
||||||
} else if (elm === 1) {
|
} else if (elm === 1) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import {MoveAnim} from "#app/data/battle-anims";
|
||||||
import Pokemon from "#app/field/pokemon";
|
import Pokemon from "#app/field/pokemon";
|
||||||
import * as battleScene from "#app/battle-scene";
|
import * as battleScene from "#app/battle-scene";
|
||||||
import MockImage from "#app/test/utils/mocks/mocksContainer/mockImage.js";
|
import MockImage from "#app/test/utils/mocks/mocksContainer/mockImage.js";
|
||||||
|
import { MockGameObjectCreator } from "./mocks/mockGameObjectCreator";
|
||||||
|
|
||||||
Object.defineProperty(window, "localStorage", {
|
Object.defineProperty(window, "localStorage", {
|
||||||
value: mockLocalStorage(),
|
value: mockLocalStorage(),
|
||||||
|
@ -223,13 +224,9 @@ export default class GameWrapper {
|
||||||
return resolve(response);
|
return resolve(response);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
this.scene.make = {
|
this.scene.make = new MockGameObjectCreator(mockTextureManager);
|
||||||
graphics: (config) => new MockGraphics(mockTextureManager, config),
|
|
||||||
rexTransitionImagePack: () => ({
|
|
||||||
transit: () => null,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
this.scene.time = new MockClock(this.scene);
|
this.scene.time = new MockClock(this.scene);
|
||||||
|
this.scene.remove = vi.fn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { vi } from "vitest";
|
||||||
|
import MockGraphics from "./mocksContainer/mockGraphics";
|
||||||
|
import MockTextureManager from "./mockTextureManager";
|
||||||
|
|
||||||
|
export class MockGameObjectCreator {
|
||||||
|
private readonly textureManager: MockTextureManager;
|
||||||
|
|
||||||
|
constructor(textureManager: MockTextureManager) {
|
||||||
|
console.log("Mocking Phaser.GameObjects.GameObjectCreator;");
|
||||||
|
this.textureManager = textureManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics(config: any) {
|
||||||
|
return new MockGraphics(this.textureManager, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
rexTransitionImagePack() {
|
||||||
|
return {
|
||||||
|
transit: vi.fn(),
|
||||||
|
once: vi.fn(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue