diff --git a/src/reader/cif/text/parser.ts b/src/reader/cif/text/parser.ts index 22191b0c5b14490e5148053a6f47a5b6dc8da6f1..7647125796ce818c2c7dbaa959f60f657c59a687 100644 --- a/src/reader/cif/text/parser.ts +++ b/src/reader/cif/text/parser.ts @@ -456,7 +456,6 @@ interface LoopReadState { } function readLoopChunk(state: LoopReadState, chunkSize: number) { - //console.log(chunkSize); const { tokenizer, tokens, fieldCount } = state; let tokenCount = state.tokenCount; let counter = 0; @@ -466,20 +465,13 @@ function readLoopChunk(state: LoopReadState, chunkSize: number) { counter++; } state.tokenCount = tokenCount; - return counter; //tokenizer.currentTokenType === CifTokenType.Value; + return counter; } function readLoopChunks(state: LoopReadState) { - const { chunker } = state.tokenizer; - // while (readLoopChunk(state, computation.chunkSize)) { - // if (computation.requiresUpdate) { - // await computation.updateProgress('Parsing...', void 0, state.tokenizer.position, state.tokenizer.data.length); - // } - // } - - return chunker.process( + return state.tokenizer.chunker.process( chunkSize => readLoopChunk(state, chunkSize), - update => update('Parsing...', void 0, state.tokenizer.position, state.tokenizer.data.length)); + update => update({ message: 'Parsing...', current: state.tokenizer.position, max: state.tokenizer.data.length })); } /** @@ -509,12 +501,6 @@ async function handleLoop(tokenizer: TokenizerState, categories: { [name: string tokens }; - // let tokenCount = 0; - // while (tokenizer.currentTokenType === CifTokenType.Value) { - // TokenBuilder.add(tokens[(tokenCount++) % fieldCount], tokenizer.currentTokenStart, tokenizer.currentTokenEnd); - // moveNext(tokenizer); - // } - await readLoopChunks(state); if (state.tokenCount % fieldCount !== 0) { @@ -569,7 +555,7 @@ async function parseInternal(data: string, ctx: Computation.Context) { //inSaveFrame = false, //blockSaveFrames: any; - ctx.updateProgress('Parsing...'); + ctx.updateProgress({ message: 'Parsing...' }); moveNext(tokenizer); while (tokenizer.currentTokenType !== CifTokenType.End) { diff --git a/src/reader/common/text/tokenizer.ts b/src/reader/common/text/tokenizer.ts index 314b4ff42453066774d791db0a9141e9a4ddfef4..d84705a43db0b67f159f15c158d2edc842b7c69e 100644 --- a/src/reader/common/text/tokenizer.ts +++ b/src/reader/common/text/tokenizer.ts @@ -112,7 +112,7 @@ export namespace Tokenizer { readLinesChunk(state, linesToRead, lineTokens); linesAlreadyRead += linesToRead; return linesToRead; - }, update => update('Parsing...', void 0, state.position, length)); + }, update => update({ message: 'Parsing...', current: state.position, max: length })); return lineTokens; } diff --git a/src/script.ts b/src/script.ts index 671f9f374e1a26c4390b4ea3a1856791ec416bbe..8612e3bc5d60cb213fb8adfa6a4845e5e4c16c80 100644 --- a/src/script.ts +++ b/src/script.ts @@ -19,7 +19,7 @@ const file = 'md_1u19_trj.gro' async function runGro(input: string) { console.time('parseGro'); const comp = Gro(input); - const running = comp.runObservable(Computation.observableContext({ updateRateMs: 150 })); + const running = comp.runObservable(Computation.observable({ updateRateMs: 150 })); running.subscribe(p => console.log(`[Gro] ${(p.current / p.max * 100).toFixed(2)} (${p.elapsedMs | 0}ms)`)); const parsed = await running.result; console.timeEnd('parseGro'); @@ -85,8 +85,8 @@ async function runCIF(input: string | Uint8Array) { console.time('parseCIF'); const comp = typeof input === 'string' ? CIF.parseText(input) : CIF.parseBinary(input); - const running = comp.runObservable(Computation.observableContext({ updateRateMs: 250 })); - running.subscribe(p => console.log(`[CIF] ${(p.current / p.max * 100).toFixed(2)} (${p.elapsedMs | 0}ms)`)); + const running = comp.runObservable(Computation.observable({ updateRateMs: 250 })); // Computation.synchronous + running.subscribe(p => console.log(`[CIF] ${p.message} ${(p.current / p.max * 100).toFixed(2)}% (${p.elapsedMs | 0}ms)`)); const parsed = await running.result; console.timeEnd('parseCIF'); if (parsed.isError) { @@ -137,7 +137,7 @@ import Computation from './utils/computation' const comp = Computation.create(async ctx => { for (let i = 0; i < 0; i++) { await new Promise(res => setTimeout(res, 500)); - if (ctx.requiresUpdate) await ctx.updateProgress('working', void 0, i, 2); + if (ctx.requiresUpdate) await ctx.updateProgress({ message: 'working', current: i, max: 2 }); } return 42; }); diff --git a/src/utils/computation.ts b/src/utils/computation.ts index 9619abd2feb20203d7779d2f742f059d20622609..565752b13940ae9477c5c01695c0b0581a775e8e 100644 --- a/src/utils/computation.ts +++ b/src/utils/computation.ts @@ -42,13 +42,20 @@ namespace Computation { requestAbort?: () => void } + export interface ProgressUpdate { + message?: string, + abort?: boolean | (() => void), + current?: number, + max?: number + } + export interface Context { readonly isSynchronous: boolean, /** Also checks if the computation was aborted. If so, throws. */ readonly requiresUpdate: boolean, requestAbort(): void, /** Also checks if the computation was aborted. If so, throws. */ - updateProgress(msg: string, abort?: boolean | (() => void), current?: number, max?: number): Promise<void> | void + updateProgress(info: ProgressUpdate): Promise<void> | void } export type ProgressObserver = (progress: Readonly<Progress>) => void; @@ -59,14 +66,14 @@ namespace Computation { } /** A context without updates. */ - export const synchronousContext: Context = { + export const synchronous: Context = { isSynchronous: true, requiresUpdate: false, requestAbort() { }, - updateProgress(msg, abort, current, max) { } + updateProgress(info) { } } - export function observableContext(params?: Partial<Params>) { + export function observable(params?: Partial<Params>) { return new ObservableContext(params); } @@ -163,7 +170,7 @@ class ObservableContext implements Computation.Context { } catch (e) { } } - updateProgress(msg: string, abort?: boolean | (() => void), current?: number, max?: number): Promise<void> | void { + updateProgress({ message, abort, current, max }: Computation.ProgressUpdate): Promise<void> | void { this.checkAborted(); const time = Computation.now(); @@ -175,14 +182,14 @@ class ObservableContext implements Computation.Context { this.progress.requestAbort = abort ? this.abortRequester : void 0; } - this.progress.message = msg; + if (typeof message !== 'undefined') this.progress.message = message; this.progress.elapsedMs = time - this.startedTime; - if (isNaN(current!) || isNaN(max!)) { + if (isNaN(current!)) { this.progress.isIndeterminate = true; } else { this.progress.isIndeterminate = false; this.progress.current = current!; - this.progress.max = max!; + if (!isNaN(max!)) this.progress.max = max!; } if (this.observers) {