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')){ if(f.name.endsWith('charx')){
console.log('reading charx') console.log('reading charx')
const reader = new CharXReader()
alertStore.set({ alertStore.set({
type: 'wait', type: 'wait',
msg: 'Loading... (Reading)' msg: 'Loading... (Reading)'
}) })
await reader.read(f.data) const reader = new CharXReader()
await reader.read(f.data, {
alertInfo: true
})
const cardData = reader.cardData const cardData = reader.cardData
if(!cardData){ if(!cardData){
alertError(language.errors.noData) 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 * as fflate from "fflate";
import { sleep } from "../util"; import { sleep } from "../util";
import { alertStore } from "../alert";
import { Capacitor } from "@capacitor/core";
export async function processZip(dataArray: Uint8Array): Promise<string> { export async function processZip(dataArray: Uint8Array): Promise<string> {
const jszip = await import("jszip"); const jszip = await import("jszip");
@@ -111,33 +113,90 @@ export class CharXReader{
} }
} }
async read(data:Uint8Array|File|ReadableStream<Uint8Array>){ async push(data:Uint8Array, final:boolean = false){
if(data instanceof Uint8Array){
this.unzip.push(data, true) if(data.byteLength > 1024 * 1024){
} let pointer = 0
if(data instanceof File){
const reader = data.stream().getReader()
while(true){ while(true){
const {done, value} = await reader.read() const chunk = data.slice(pointer, pointer + 1024 * 1024)
if(done){ 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 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){ if(data instanceof ReadableStream){
const reader = data.getReader() const reader = data.getReader()
while(true){ while(true){
const {done, value} = await reader.read() const {done, value} = await reader.read()
if(value){
await this.push(value, false)
}
if(done){ if(done){
await this.push(new Uint8Array(0), true)
break 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)
} }
} }