From e1144a8ea4b2c185b597ea38f68412b080d00c8e Mon Sep 17 00:00:00 2001 From: Christopher Serr Date: Sun, 8 Mar 2020 17:33:55 +0100 Subject: [PATCH] Store the splits as a byte array From now on we never serialize the splits to a string and instead directly slice the WebAssembly memory and directly export, upload, and save the splits from there. Additionally this does another optimization where livesplit-core now provides a way to directly query the length of the returned buffer instead of having to manually search of the nul-terminator. --- livesplit-core | 2 +- src/ui/LiveSplit.tsx | 19 +++++++++---------- src/util/FileUtil.ts | 2 +- src/util/SplitsIO.ts | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/livesplit-core b/livesplit-core index 7c30023..b66a7ab 160000 --- a/livesplit-core +++ b/livesplit-core @@ -1 +1 @@ -Subproject commit 7c300236dd338206946d43837f7c27ccd5ca1b84 +Subproject commit b66a7ab5273f68961d278b75490aaa0861c8a3c4 diff --git a/src/ui/LiveSplit.tsx b/src/ui/LiveSplit.tsx index dd80882..e41dbf4 100644 --- a/src/ui/LiveSplit.tsx +++ b/src/ui/LiveSplit.tsx @@ -41,7 +41,7 @@ type Menu = { kind: MenuKind.About }; export interface Props { - splits: string, + splits: Int8Array, layout: any, settings: any, layoutWidth: number, @@ -63,7 +63,7 @@ const DEFAULT_LAYOUT_WIDTH = 300; export class LiveSplit extends React.Component { public static async loadStoredData() { - const splits = await localforage.getItem("splits") as string; + const splits = await localforage.getItem("splits") as Int8Array ?? new Int8Array(); const layout = await localforage.getItem("layout"); const settings = await localforage.getItem("settings"); const layoutWidth = await localforage.getItem("layoutWidth") as number; @@ -119,8 +119,8 @@ export class LiveSplit extends React.Component { "The Default Loading Run should be a valid Run", ); this.loadFromSplitsIO(window.location.hash.substr("#/splits-io/".length)); - } else { - const result = Run.parseString(props.splits, "", false); + } else if (props.splits.length > 0) { + const result = Run.parseArray(props.splits, "", false); if (result.parsedSuccessfully()) { result.unwrap().with((r) => timer.writeWith((t) => t.setRun(r)))?.dispose(); } @@ -377,10 +377,10 @@ export class LiveSplit extends React.Component { } public async uploadToSplitsIO(): Promise> { - const lss = this.readWith((t) => t.saveAsLss()); + const lss = this.readWith((t) => t.saveAsLssBytes()); try { - const claimUri = await SplitsIO.uploadLss(lss); + const claimUri = await SplitsIO.uploadLss(new Blob([lss])); return window.open(claimUri); } catch (_) { toast.error("Failed to upload the splits."); @@ -390,9 +390,9 @@ export class LiveSplit extends React.Component { public exportSplits() { const [lss, name] = this.writeWith((t) => { - const lss = t.saveAsLss(); - const name = t.getRun().extendedFileName(true); t.markAsUnmodified(); + const name = t.getRun().extendedFileName(true); + const lss = t.saveAsLssBytes(); return [lss, name]; }); try { @@ -404,9 +404,8 @@ export class LiveSplit extends React.Component { public async saveSplits() { const lss = this.writeWith((t) => { - const lss = t.saveAsLss(); t.markAsUnmodified(); - return lss; + return t.saveAsLssBytes(); }); try { await localforage.setItem("splits", lss); diff --git a/src/util/FileUtil.ts b/src/util/FileUtil.ts index d702828..7b08692 100644 --- a/src/util/FileUtil.ts +++ b/src/util/FileUtil.ts @@ -58,7 +58,7 @@ export async function openFileAsString(): Promise<[string, File]> { return convertFileToString(file); } -export function exportFile(filename: string, data: any) { +export function exportFile(filename: string, data: BlobPart) { const url = URL.createObjectURL(new Blob([data], { type: "application/octet-stream" })); try { const element = document.createElement("a"); diff --git a/src/util/SplitsIO.ts b/src/util/SplitsIO.ts index cb67e3e..449aa0c 100644 --- a/src/util/SplitsIO.ts +++ b/src/util/SplitsIO.ts @@ -28,7 +28,7 @@ export enum UploadError { UploadRequestErrored, } -export async function uploadLss(lss: string): Promise { +export async function uploadLss(lss: string | Blob): Promise { const response = await validatedFetch( "https://splits.io/api/v4/runs", {