From 1e4d372f3b29f3d4539a6760eea6f074ac2e229d Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 3 Jun 2024 22:13:24 +0900 Subject: [PATCH] refactor: improve charx loading --- src/ts/characterCards.ts | 6 ++- src/ts/process/processzip.ts | 89 ++++++++++++++++++++++++++++++------ 2 files changed, 78 insertions(+), 17 deletions(-) diff --git a/src/ts/characterCards.ts b/src/ts/characterCards.ts index 0caba74b..13bf17ad 100644 --- a/src/ts/characterCards.ts +++ b/src/ts/characterCards.ts @@ -66,12 +66,14 @@ async function importCharacterProcess(f:{ if(f.name.endsWith('charx')){ console.log('reading charx') - const reader = new CharXReader() alertStore.set({ type: 'wait', msg: 'Loading... (Reading)' }) - await reader.read(f.data) + const reader = new CharXReader() + await reader.read(f.data, { + alertInfo: true + }) const cardData = reader.cardData if(!cardData){ alertError(language.errors.noData) diff --git a/src/ts/process/processzip.ts b/src/ts/process/processzip.ts index 8e5e0982..95a3471b 100644 --- a/src/ts/process/processzip.ts +++ b/src/ts/process/processzip.ts @@ -1,6 +1,8 @@ -import { AppendableBuffer, saveAsset, type LocalWriter, type VirtualWriter } from "../storage/globalApi"; +import { AppendableBuffer, isTauri, saveAsset, type LocalWriter, type VirtualWriter } from "../storage/globalApi"; import * as fflate from "fflate"; import { sleep } from "../util"; +import { alertStore } from "../alert"; +import { Capacitor } from "@capacitor/core"; export async function processZip(dataArray: Uint8Array): Promise { const jszip = await import("jszip"); @@ -111,33 +113,90 @@ export class CharXReader{ } } - async read(data:Uint8Array|File|ReadableStream){ - if(data instanceof Uint8Array){ - this.unzip.push(data, true) - } - if(data instanceof File){ - const reader = data.stream().getReader() + async push(data:Uint8Array, final:boolean = false){ + + if(data.byteLength > 1024 * 1024){ + let pointer = 0 while(true){ - const {done, value} = await reader.read() - if(done){ + const chunk = data.slice(pointer, pointer + 1024 * 1024) + this.unzip.push(chunk, false) + await Promise.all(this.assetPromises) + if(pointer + 1024 * 1024 >= data.byteLength){ + if(final){ + this.unzip.push(new Uint8Array(0), final) + } break } - this.unzip.push(value, false) + pointer += 1024 * 1024 } - this.unzip.push(new Uint8Array(0), true) + return } + + this.unzip.push(data, final) + await Promise.all(this.assetPromises) + } + + async read(data:Uint8Array|File|ReadableStream, arg:{ + alertInfo?:boolean + } = {}){ + if(data instanceof ReadableStream){ const reader = data.getReader() while(true){ const {done, value} = await reader.read() + if(value){ + await this.push(value, false) + } if(done){ + await this.push(new Uint8Array(0), true) break } - this.unzip.push(value, false) } - this.unzip.push(new Uint8Array(0), true) + await this.push(new Uint8Array(0), true) + return } - await sleep(500) - await Promise.all(this.assetPromises) + + const getSlice = async (start:number, end:number) => { + if(data instanceof Uint8Array){ + return data.slice(start, end) + } + if(data instanceof File){ + return new Uint8Array(await data.slice(start, end).arrayBuffer()) + } + } + + const getLength = () => { + if(data instanceof Uint8Array){ + return data.byteLength + } + if(data instanceof File){ + return data.size + } + } + + const alertInfo = () => { + if(arg.alertInfo){ + alertStore.set({ + type: 'wait', + msg: `Loading... (Getting Data: ${Math.floor(pointer / getLength() * 100)}%)` + }) + } + } + + let pointer = 0 + while(true){ + const chunk = await getSlice(pointer, pointer + 1024 * 1024) + await this.push(chunk, false) + alertInfo() + if(pointer + 1024 * 1024 >= getLength()){ + await this.push(new Uint8Array(0), true) + break + } + pointer += 1024 * 1024 + if(!isTauri && !Capacitor.isNativePlatform()){ + await sleep(1000) + } + } + await sleep(100) } } \ No newline at end of file