refactor: improve charx loading

This commit is contained in:
kwaroran
2024-06-03 22:13:24 +09:00
parent 725b180094
commit 1e4d372f3b
2 changed files with 78 additions and 17 deletions

View File

@@ -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)

View File

@@ -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<string> {
const jszip = await import("jszip");
@@ -111,33 +113,90 @@ export class CharXReader{
}
}
async read(data:Uint8Array|File|ReadableStream<Uint8Array>){
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<Uint8Array>, 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)
}
}