Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mirabuf Caching #992

Merged
merged 33 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e83c65c
Readwrite with OPFS after localstorage check
a-crowell Jun 18, 2024
a16e8cc
Quick save: ts update, clear opfs, robot/field dirs
a-crowell Jun 20, 2024
3458ad2
Catch for no Mira JSON in localStorage
a-crowell Jun 20, 2024
caec749
Working cache
a-crowell Jun 21, 2024
ec5dcba
Function to get json object of map
a-crowell Jun 24, 2024
dec4554
Misnomer correction and print maps prints both robots and fields
a-crowell Jun 24, 2024
f1d8891
Refactoring
a-crowell Jun 25, 2024
ba21af8
Merge remote-tracking branch 'origin/dev' into crowela/1667/mira-caching
a-crowell Jun 25, 2024
bdceed4
Merge conflicts part 2
a-crowell Jun 25, 2024
90b04e3
Update fission/src/ui/modals/spawning/SpawningModals.tsx
BrandonPacewic Jun 25, 2024
2a9730f
Merge fix
BrandonPacewic Jun 25, 2024
2093087
Merge branch 'dev' into crowela/1667/mira-caching
a-crowell Jun 27, 2024
e1d3c5e
Merge fix
a-crowell Jun 27, 2024
fc1092a
Formatting
a-crowell Jun 27, 2024
f042529
Undefined instead of null
a-crowell Jun 27, 2024
bdbcb14
Merge branch 'dev' into crowela/1667/mira-caching
a-crowell Jun 28, 2024
2500f4d
Merge fix
a-crowell Jun 28, 2024
b9b10b5
UnzipMira doc
a-crowell Jun 28, 2024
e29a989
Hashing and caching funky fetchLocations
a-crowell Jul 1, 2024
50f2d09
Code clarity and hashing bug fix
a-crowell Jul 1, 2024
53938a5
Merge remote-tracking branch 'origin/dev' into crowela/1667/mira-caching
a-crowell Jul 1, 2024
26d41ca
Refactor for readability and efficiency
a-crowell Jul 2, 2024
173d85e
Bug fixes and more testing logs
a-crowell Jul 2, 2024
8310921
Name metadata, spawning modal update, and bug fixes
a-crowell Jul 2, 2024
0e240a7
Removed extraneous prints
a-crowell Jul 2, 2024
97666bd
CacheAndGet
a-crowell Jul 3, 2024
63eb00c
Improved CacheAndGet
a-crowell Jul 3, 2024
ec19e35
Push formatting
BrandonPacewic Jul 4, 2024
1cb7af5
Little cleanups
HunterBarclay Jul 5, 2024
81c009a
That took me way too long
HunterBarclay Jul 5, 2024
3ace877
Adding a version printout of the version
HunterBarclay Jul 5, 2024
ea460d3
Manually changed line endings to CRLF on Prettier
HunterBarclay Jul 5, 2024
3923335
Changed it back
HunterBarclay Jul 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified fission/bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion fission/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion fission/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@mui/system": "^5.15.20",
"@react-three/drei": "^9.96.5",
"@react-three/fiber": "^8.15.15",
"@types/crypto-js": "^4.2.2",
"@vitest/browser": "^1.6.0",
"@vitest/coverage-v8": "^1.6.0",
"async-mutex": "^0.5.0",
Expand Down Expand Up @@ -55,6 +56,7 @@
"@vitejs/plugin-react-swc": "^3.5.0",
"autoprefixer": "^10.4.14",
"cssnano": "^6.0.1",
"crypto-js": "^4.2.0",
"eslint": "^8.56.0",
"eslint-config-prettier": "^8.8.0",
"eslint-import-resolver-alias": "^1.1.2",
Expand All @@ -68,7 +70,7 @@
"protobufjs-cli": "^1.1.2",
"tailwindcss": "^3.3.3",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.2.2",
"typescript": "^5.4.5",
"vite": "^5.1.4",
"vite-plugin-singlefile": "^0.13.5",
"vitest": "^1.5.3"
Expand Down
6 changes: 3 additions & 3 deletions fission/src/Synthesis.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Scene from "@/components/Scene.tsx"
import MirabufSceneObject from "./mirabuf/MirabufSceneObject.ts"
import { LoadMirabufRemote } from "./mirabuf/MirabufLoader.ts"
import { LoadMirabufRemote, MiraType } from "./mirabuf/MirabufLoader.ts"
import { mirabuf } from "./proto/mirabuf"
import MirabufParser, { ParseErrorSeverity } from "./mirabuf/MirabufParser.ts"
import MirabufInstance from "./mirabuf/MirabufInstance.ts"
Expand Down Expand Up @@ -92,8 +92,8 @@ function Synthesis() {
console.log(urlParams)

const setup = async () => {
const miraAssembly = await LoadMirabufRemote(mira_path)
.catch(_ => LoadMirabufRemote(DEFAULT_MIRA_PATH))
const miraAssembly = await LoadMirabufRemote(mira_path, MiraType.ROBOT)
.catch(_ => LoadMirabufRemote(DEFAULT_MIRA_PATH, MiraType.ROBOT))
.catch(console.error)

await (async () => {
Expand Down
126 changes: 115 additions & 11 deletions fission/src/mirabuf/MirabufLoader.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,130 @@
import { mirabuf } from "../proto/mirabuf"
import { mirabuf } from "@/proto/mirabuf"
import Pako from "pako"
// import * as fs from "fs"

type MiraCache = { [id: string] : string}

const robotsDirName = "Robots"
const fieldsDirName = "Fields"
const root = await navigator.storage.getDirectory()
const robotFolderHandle = await root.getDirectoryHandle(robotsDirName, { create: true })
const fieldFolderHandle = await root.getDirectoryHandle(fieldsDirName, { create: true })

export function UnzipMira(buff: Uint8Array): Uint8Array {
// Check if file is gzipped via magic gzip numbers 31 139
if (buff[0] == 31 && buff[1] == 139) {
return Pako.ungzip(buff)
} else {
return buff
}
}

export async function LoadMirabufRemote(
fetchLocation: string,
useCache: boolean = true
): Promise<mirabuf.Assembly | undefined> {
const miraBuff = await fetch(encodeURI(fetchLocation), useCache ? undefined : { cache: "no-store" })
.then(x => x.blob())
.then(x => x.arrayBuffer())
const byteBuffer = UnzipMira(new Uint8Array(miraBuff))
return mirabuf.Assembly.decode(byteBuffer)
export async function LoadMirabufRemote(fetchLocation: string, type: MiraType, blobHashID?: string): Promise<mirabuf.Assembly | undefined> {
const map = GetMiraCacheMap(type)

// blobHashID for ImportLocalMira
const targetID = map ? ( blobHashID ? map[blobHashID] : map[fetchLocation]) : undefined

if (targetID != undefined && map != undefined) {
console.log("Loading mira from cache")
return (await LoadMirabufCache(fetchLocation, targetID, type, map)) ?? LoadAndCacheMira(fetchLocation, type, blobHashID)
} else {
console.log("Loading and caching new mira")
return await LoadAndCacheMira(fetchLocation, type, blobHashID)
}
}

// export function LoadMirabufLocal(fileLocation: string): mirabuf.Assembly {
// return mirabuf.Assembly.decode(UnzipMira(new Uint8Array(fs.readFileSync(fileLocation))))
// }

export async function ClearMira() {
for await (const key of robotFolderHandle.keys()) {
robotFolderHandle.removeEntry(key)
}
for await (const key of fieldFolderHandle.keys()) {
fieldFolderHandle.removeEntry(key)
}

window.localStorage.removeItem(robotsDirName)
window.localStorage.removeItem(fieldsDirName)
}

export function GetMiraCacheMap(type: MiraType): MiraCache | undefined {
const miraJSON = window.localStorage.getItem(type == MiraType.ROBOT ? robotsDirName : fieldsDirName)

if (miraJSON != undefined) {
console.log("mirabuf JSON found")
console.log(miraJSON)
return JSON.parse(miraJSON)
} else {
console.log("mirabuf JSON not found")
return undefined
}
}

async function LoadAndCacheMira(fetchLocation: string, type: MiraType, blobHashID?: string): Promise<mirabuf.Assembly | undefined> {
try {
// Grab file remote
const miraBuff = await fetch(encodeURI(fetchLocation), import.meta.env.DEV ? { cache: "no-store" } : undefined)
.then(x => x.blob())
.then(x => x.arrayBuffer())
const byteBuffer = UnzipMira(new Uint8Array(miraBuff))
const assembly = mirabuf.Assembly.decode(byteBuffer)

// Store in OPFS
const backupID = Date.now().toString()
const fileHandle = await (type == MiraType.ROBOT ? robotFolderHandle : fieldFolderHandle).getFileHandle(
backupID,
{ create: true }
)
const writable = await fileHandle.createWritable()
await writable.write(miraBuff)
await writable.close()

// Local cache map
const map: MiraCache = GetMiraCacheMap(type) ?? {}
map[blobHashID ?? fetchLocation] = backupID
window.localStorage.setItem(type == MiraType.ROBOT ? robotsDirName : fieldsDirName, JSON.stringify(map))

console.log(assembly)
return assembly
} catch (e) {
console.error("Failed to load and cache mira " + e)
return undefined
}
}

async function LoadMirabufCache(
fetchLocation: string,
targetID: string,
type: MiraType,
map: MiraCache
): Promise<mirabuf.Assembly | undefined> {
try {
const fileHandle =
(await (type == MiraType.ROBOT ? robotFolderHandle : fieldFolderHandle).getFileHandle(targetID, {
create: false,
})) ?? undefined

// Get assembly from file
if (fileHandle != undefined) {
const buff = await fileHandle.getFile().then(x => x.arrayBuffer())
const assembly = mirabuf.Assembly.decode(UnzipMira(new Uint8Array(buff)))
console.log(assembly)
return assembly
}
} catch (e) {
console.error("Failed to find file from OPFS" + e)

// Remove from localStorage list
delete map[fetchLocation]
window.localStorage.setItem(type == MiraType.ROBOT ? robotsDirName : fieldsDirName, JSON.stringify(map))

return undefined
}
}

export enum MiraType {
ROBOT,
FIELD,
}
4 changes: 2 additions & 2 deletions fission/src/mirabuf/MirabufParser.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as THREE from "three"
import { mirabuf } from "../proto/mirabuf"
import { MirabufTransform_ThreeMatrix4 } from "../util/TypeConversions"
import { mirabuf } from "@/proto/mirabuf"
import { MirabufTransform_ThreeMatrix4 } from "@/util/TypeConversions"

export enum ParseErrorSeverity {
Unimportable = 10,
Expand Down
10 changes: 7 additions & 3 deletions fission/src/mirabuf/MirabufSceneObject.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { mirabuf } from "@/proto/mirabuf"
import SceneObject from "../systems/scene/SceneObject"
import MirabufInstance from "./MirabufInstance"
import { LoadMirabufRemote } from "./MirabufLoader"
import { LoadMirabufRemote, MiraType } from "./MirabufLoader"
import MirabufParser, { ParseErrorSeverity } from "./MirabufParser"
import World from "@/systems/World"
import Jolt from "@barclah/jolt-physics"
Expand Down Expand Up @@ -157,8 +157,12 @@ class MirabufSceneObject extends SceneObject {
}
}

export async function CreateMirabufFromUrl(path: string): Promise<MirabufSceneObject | null | undefined> {
const miraAssembly = await LoadMirabufRemote(path).catch(console.error)
export async function CreateMirabufFromUrl(
path: string,
miraType: MiraType,
hashID?: string
): Promise<MirabufSceneObject | null | undefined> {
const miraAssembly = await LoadMirabufRemote(path, miraType, hashID).catch(console.error)

if (!miraAssembly || !(miraAssembly instanceof mirabuf.Assembly)) {
return
Expand Down
Loading