From dd3415042cd1e5a3e72f8c0ddf949090d3595554 Mon Sep 17 00:00:00 2001 From: solvedDev Date: Sat, 10 Sep 2022 12:42:08 +0200 Subject: [PATCH] upd: make loading com.mojang projects faster --- src/components/FileSystem/FileSystem.ts | 9 ++++ .../OutputFolders/ComMojang/ProjectLoader.ts | 44 ++++++++++++------- .../Projects/ProjectChooser/ProjectChooser.ts | 4 ++ 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/components/FileSystem/FileSystem.ts b/src/components/FileSystem/FileSystem.ts index 6784b7adc..999f16a93 100644 --- a/src/components/FileSystem/FileSystem.ts +++ b/src/components/FileSystem/FileSystem.ts @@ -214,6 +214,15 @@ export class FileSystem extends Signal { throw new Error(`Invalid JSON: ${path}`) } } + async readJsonHandle(fileHandle: AnyFileHandle) { + const file = await fileHandle.getFile() + + try { + return await json5.parse(await file.text()) + } catch { + throw new Error(`Invalid JSON: ${fileHandle.name}`) + } + } writeJSON(path: string, data: any, beautify = false) { return this.writeFile( path, diff --git a/src/components/OutputFolders/ComMojang/ProjectLoader.ts b/src/components/OutputFolders/ComMojang/ProjectLoader.ts index 2532fca78..ed88c37cc 100644 --- a/src/components/OutputFolders/ComMojang/ProjectLoader.ts +++ b/src/components/OutputFolders/ComMojang/ProjectLoader.ts @@ -1,7 +1,7 @@ import { compareVersions } from 'bridge-common-utils' import { AnyDirectoryHandle } from '../../FileSystem/Types' import { App } from '/@/App' -import { loadAsDataURL } from '/@/utils/loadAsDataUrl' +import { loadAsDataURL, loadHandleAsDataURL } from '/@/utils/loadAsDataUrl' export interface IComMojangPack { type: 'behaviorPack' | 'resourcePack' @@ -34,10 +34,14 @@ export class ComMojangProjectLoader { return [] const behaviorPacks = await this.loadPacks('development_behavior_packs') + + // Fast path: No need to load resource packs if there are no behavior packs + if (behaviorPacks.size === 0) return [] const resourcePacks = await this.loadPacks('development_resource_packs') + console.log(behaviorPacks) const projects: IComMojangProject[] = [] - for (const behaviorPack of behaviorPacks) { + for (const behaviorPack of behaviorPacks.values()) { const dependencies = behaviorPack.manifest?.dependencies if (!dependencies) { projects.push({ @@ -47,11 +51,12 @@ export class ComMojangProjectLoader { continue } - const matchingRp = resourcePacks.find(({ uuid: rpUuuid }) => - dependencies.find( - ({ uuid: depUuid }: any) => !!depUuid && depUuid === rpUuuid - ) - ) + let matchingRp + for (const dep of dependencies) { + matchingRp = resourcePacks.get(dep.uuid) + if (matchingRp) break + } + if (!matchingRp) continue projects.push({ name: behaviorPack.directoryHandle.name, @@ -65,17 +70,21 @@ export class ComMojangProjectLoader { async loadPacks( folderName: 'development_behavior_packs' | 'development_resource_packs' ) { + const packs = new Map() const storePackDir = await this.fileSystem .getDirectoryHandle(folderName) .catch(() => null) - if (!storePackDir) return [] - const packs: IComMojangPack[] = [] + if (!storePackDir) return packs for await (const packHandle of storePackDir.values()) { if (packHandle.kind === 'file') continue - const manifest = await this.fileSystem - .readJSON(`${folderName}/${packHandle.name}/manifest.json`) + + const manifest = await packHandle + .getFileHandle('manifest.json') + .then((fileHandle) => + this.fileSystem.readJsonHandle(fileHandle) + ) .catch(() => null) if (!manifest) continue @@ -84,12 +93,12 @@ export class ComMojangProjectLoader { // Check whether BP/RP is part of a v2 project if (this.isV2Project(manifest)) continue - const packIcon = await loadAsDataURL( - `${folderName}/${packHandle.name}/pack_icon.png`, - this.fileSystem - ).catch(() => null) + const packIcon = await packHandle + .getFileHandle('pack_icon.png') + .then((fileHandle) => loadHandleAsDataURL(fileHandle)) + .catch(() => null) - packs.push({ + packs.set(uuid, { type: folderName === 'development_behavior_packs' ? 'behaviorPack' @@ -108,7 +117,8 @@ export class ComMojangProjectLoader { isV2Project(manifest: any) { const uuid = manifest?.header?.uuid - const bridgeVersion = manifest?.metadata?.generated_with?.bridge?.pop?.() + const bridgeVersion = + manifest?.metadata?.generated_with?.bridge?.pop?.() if (bridgeVersion && compareVersions(bridgeVersion, '2.0.0', '>=')) return true diff --git a/src/components/Projects/ProjectChooser/ProjectChooser.ts b/src/components/Projects/ProjectChooser/ProjectChooser.ts index 3db10add8..41333403b 100644 --- a/src/components/Projects/ProjectChooser/ProjectChooser.ts +++ b/src/components/Projects/ProjectChooser/ProjectChooser.ts @@ -113,6 +113,7 @@ export class ProjectChooserWindow extends NewBaseWindow { }) ) + console.time('Load com.mojang projects') const comMojangProjects = await new ComMojangProjectLoader( app ).loadProjects() @@ -143,6 +144,7 @@ export class ProjectChooserWindow extends NewBaseWindow { project: markRaw(project), }) ) + console.timeEnd('Load com.mojang projects') this.sidebar.resetSelected() if (app.isNoProjectSelected) this.sidebar.setDefaultSelected() @@ -152,7 +154,9 @@ export class ProjectChooserWindow extends NewBaseWindow { } async open() { + console.time('Load projects') this.state.currentProject = await this.loadProjects() + console.timeEnd('Load projects') super.open() } }