diff --git a/fission/src/Synthesis.tsx b/fission/src/Synthesis.tsx index ec3352357..badb33a28 100644 --- a/fission/src/Synthesis.tsx +++ b/fission/src/Synthesis.tsx @@ -45,7 +45,6 @@ import ImportMirabufPanel from "@/ui/panels/mirabuf/ImportMirabufPanel.tsx" import Skybox from "./ui/components/Skybox.tsx" import ChooseInputSchemePanel from "./ui/panels/configuring/ChooseInputSchemePanel.tsx" import ProgressNotifications from "./ui/components/ProgressNotification.tsx" -import ConfigureRobotBrainPanel from "./ui/panels/configuring/ConfigureRobotBrainPanel.tsx" import SceneOverlay from "./ui/components/SceneOverlay.tsx" import WPILibWSWorker from "@/systems/simulation/wpilib_brain/WPILibWSWorker.ts?worker" @@ -225,12 +224,6 @@ const initialPanels: ReactElement[] = [ , , , - , , , , diff --git a/fission/src/mirabuf/MirabufLoader.ts b/fission/src/mirabuf/MirabufLoader.ts index 1355d9e38..89b61c82e 100644 --- a/fission/src/mirabuf/MirabufLoader.ts +++ b/fission/src/mirabuf/MirabufLoader.ts @@ -10,8 +10,9 @@ export type MirabufCacheID = string export interface MirabufCacheInfo { id: MirabufCacheID - cacheKey: string miraType: MiraType + cacheKey: string + buffer?: ArrayBuffer name?: string thumbnailStorageID?: string } @@ -29,10 +30,10 @@ const root = await navigator.storage.getDirectory() const robotFolderHandle = await root.getDirectoryHandle(robotsDirName, { create: true }) const fieldFolderHandle = await root.getDirectoryHandle(fieldsDirName, { create: true }) -export const backUpRobots: Map = new Map() -export const backUpFields: Map = new Map() +export let backUpRobots: MapCache = {} +export let backUpFields: MapCache = {} -const canOPFS = await (async () => { +export const canOPFS = await (async () => { try { if (robotFolderHandle.name == robotsDirName) { robotFolderHandle.entries @@ -52,6 +53,21 @@ const canOPFS = await (async () => { } } catch (e) { console.log(`No access to OPFS`) + + // Copy-pasted from RemoveAll() + for await (const key of robotFolderHandle.keys()) { + robotFolderHandle.removeEntry(key) + } + for await (const key of fieldFolderHandle.keys()) { + fieldFolderHandle.removeEntry(key) + } + + window.localStorage.setItem(robotsDirName, "{}") + window.localStorage.setItem(fieldsDirName, "{}") + + backUpRobots = {} + backUpFields = {} + return false } })() @@ -75,11 +91,10 @@ class MirabufCachingService { */ public static GetCacheMap(miraType: MiraType): MapCache { if ( - (window.localStorage.getItem(MIRABUF_LOCALSTORAGE_GENERATION_KEY) ?? "") == MIRABUF_LOCALSTORAGE_GENERATION + (window.localStorage.getItem(MIRABUF_LOCALSTORAGE_GENERATION_KEY) ?? "") != MIRABUF_LOCALSTORAGE_GENERATION ) { window.localStorage.setItem(MIRABUF_LOCALSTORAGE_GENERATION_KEY, MIRABUF_LOCALSTORAGE_GENERATION) - window.localStorage.setItem(robotsDirName, "{}") - window.localStorage.setItem(fieldsDirName, "{}") + this.RemoveAll() return {} } @@ -188,16 +203,19 @@ class MirabufCachingService { try { const map: MapCache = this.GetCacheMap(miraType) const id = map[key].id + const _buffer = miraType == MiraType.ROBOT ? backUpRobots[id].buffer : backUpFields[id].buffer const _name = map[key].name const _thumbnailStorageID = map[key].thumbnailStorageID const info: MirabufCacheInfo = { id: id, cacheKey: key, miraType: miraType, + buffer: _buffer, name: name ?? _name, thumbnailStorageID: thumbnailStorageID ?? _thumbnailStorageID, } map[key] = info + miraType == MiraType.ROBOT ? (backUpRobots[id] = info) : (backUpFields[id] = info) window.localStorage.setItem(miraType == MiraType.ROBOT ? robotsDirName : fieldsDirName, JSON.stringify(map)) return true } catch (e) { @@ -243,7 +261,7 @@ class MirabufCachingService { // Get buffer from hashMap. If not in hashMap, check OPFS. Otherwise, buff is undefined const cache = miraType == MiraType.ROBOT ? backUpRobots : backUpFields const buff = - cache.get(id) ?? + cache[id]?.buffer ?? (await (async () => { const fileHandle = canOPFS ? await (miraType == MiraType.ROBOT ? robotFolderHandle : fieldFolderHandle).getFileHandle(id, { @@ -299,7 +317,7 @@ class MirabufCachingService { const backUpCache = miraType == MiraType.ROBOT ? backUpRobots : backUpFields if (backUpCache) { - backUpCache.delete(id) + delete backUpCache[id] } World.AnalyticsSystem?.Event("Cache Remove", { @@ -318,18 +336,20 @@ class MirabufCachingService { * Removes all Mirabuf files from the caching services. Mostly for debugging purposes. */ public static async RemoveAll() { - for await (const key of robotFolderHandle.keys()) { - robotFolderHandle.removeEntry(key) - } - for await (const key of fieldFolderHandle.keys()) { - fieldFolderHandle.removeEntry(key) + if (canOPFS) { + 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) + window.localStorage.setItem(robotsDirName, "{}") + window.localStorage.setItem(fieldsDirName, "{}") - backUpRobots.clear() - backUpFields.clear() + backUpRobots = {} + backUpFields = {} } // Optional name for when assembly is being decoded anyway like in CacheAndGetLocal() @@ -339,10 +359,10 @@ class MirabufCachingService { miraType?: MiraType, name?: string ): Promise { - const backupID = Date.now().toString() try { + const backupID = Date.now().toString() if (!miraType) { - console.log("Double loading") + console.debug("Double loading") miraType = this.AssemblyFromBuffer(miraBuff).dynamic ? MiraType.ROBOT : MiraType.FIELD } @@ -350,8 +370,8 @@ class MirabufCachingService { const map: MapCache = this.GetCacheMap(miraType) const info: MirabufCacheInfo = { id: backupID, - cacheKey: key, miraType: miraType, + cacheKey: key, name: name, } map[key] = info @@ -377,7 +397,14 @@ class MirabufCachingService { // Store in hash const cache = miraType == MiraType.ROBOT ? backUpRobots : backUpFields - cache.set(backupID, miraBuff) + const mapInfo: MirabufCacheInfo = { + id: backupID, + miraType: miraType, + cacheKey: key, + buffer: miraBuff, + name: name, + } + cache[backupID] = mapInfo return info } catch (e) { diff --git a/fission/src/ui/panels/configuring/ConfigureRobotBrainPanel.tsx b/fission/src/ui/panels/configuring/ConfigureRobotBrainPanel.tsx deleted file mode 100644 index ffbd9b937..000000000 --- a/fission/src/ui/panels/configuring/ConfigureRobotBrainPanel.tsx +++ /dev/null @@ -1,247 +0,0 @@ -import { MiraType } from "@/mirabuf/MirabufLoader" -import MirabufSceneObject, { RigidNodeAssociate } from "@/mirabuf/MirabufSceneObject" -import World from "@/systems/World" -import Label, { LabelSize } from "@/ui/components/Label" -import Button from "@/ui/components/Button" -import Panel, { PanelPropsImpl } from "@/ui/components/Panel" -import { useMemo, useState } from "react" -import { FaGear } from "react-icons/fa6" -import { ToggleButton, ToggleButtonGroup } from "@/ui/components/ToggleButtonGroup" -import { Divider, styled } from "@mui/material" -import GenericElevatorBehavior from "@/systems/simulation/behavior/synthesis/GenericElevatorBehavior" -import Stack, { StackDirection } from "@/ui/components/Stack" -import { JSX } from "react/jsx-runtime" -import ArcadeDriveBehavior from "@/systems/simulation/behavior/synthesis/ArcadeDriveBehavior" -import GenericArmBehavior from "@/systems/simulation/behavior/synthesis/GenericArmBehavior" -import SynthesisBrain from "@/systems/simulation/synthesis_brain/SynthesisBrain" - -// eslint-disable-next-line react-refresh/only-export-components -export enum ConfigureRobotBrainTypes { - SYNTHESIS = 0, - WIPLIB = 1, -} - -const LabelStyled = styled(Label)({ - fontWeight: 700, - margin: "0pt", -}) - -const DividerStyled = styled(Divider)({ - borderColor: "white", -}) - -/** - * Retrieves the joints of a robot and generates JSX elements for each joint. - * @param robot The MirabufSceneObject representing the robot. - * @returns An array of JSX elements representing the joints of the robot. - */ -function GetJoints(robot: MirabufSceneObject): JSX.Element[] { - const output: JSX.Element[] = [] - let elementKey = 0 - - /* Iterate through each behavior of the robot */ - const brain = robot.brain as SynthesisBrain - brain.behaviors.forEach(behavior => { - /* Adds the joints that the wheels are associated with */ - if (behavior instanceof ArcadeDriveBehavior) { - behavior.wheels.forEach(wheel => { - const assoc = World.PhysicsSystem.GetBodyAssociation( - wheel.constraint.GetVehicleBody().GetID() - ) as RigidNodeAssociate - - if (!assoc || assoc.sceneObject !== robot) { - return - } - - output.push( - - - Wheel Node {elementKey} - - - {assoc.rigidNodeId} - - - ) - elementKey++ - }) - output.push() - } else if (behavior instanceof GenericArmBehavior) { - /* Adds the joints that the arm is associated with */ - // Get the rigid node associates for the two bodies - const assoc1 = World.PhysicsSystem.GetBodyAssociation( - behavior.hingeDriver.constraint.GetBody1().GetID() - ) as RigidNodeAssociate - const assoc2 = World.PhysicsSystem.GetBodyAssociation( - behavior.hingeDriver.constraint.GetBody2().GetID() - ) as RigidNodeAssociate - - if (!assoc1 || assoc1.sceneObject !== robot || !assoc2 || assoc2.sceneObject !== robot) { - return - } - - output.push( - - - Arm Nodes - - - {assoc1.rigidNodeId + " " + assoc2.rigidNodeId} - - - ) - elementKey++ - } else if (behavior instanceof GenericElevatorBehavior) { - /* Adds the joints that the elevator is associated with */ - // Get the rigid node associates for the two bodies - const assoc1 = World.PhysicsSystem.GetBodyAssociation( - behavior.sliderDriver.constraint.GetBody1().GetID() - ) as RigidNodeAssociate - const assoc2 = World.PhysicsSystem.GetBodyAssociation( - behavior.sliderDriver.constraint.GetBody2().GetID() - ) as RigidNodeAssociate - - if (!assoc1 || assoc1.sceneObject !== robot || !assoc2 || assoc2.sceneObject !== robot) { - return - } - - output.push( - - - Elevator Nodes - - - {assoc1.rigidNodeId + " " + assoc2.rigidNodeId} - - - ) - elementKey++ - } - }) - - return output -} - -const ConfigureRobotBrainPanel: React.FC = ({ panelId, openLocation, sidePadding }) => { - const [selectedRobot, setSelectedRobot] = useState(undefined) - const [viewType, setViewType] = useState(ConfigureRobotBrainTypes.SYNTHESIS) - const robots = useMemo(() => { - const assemblies = [...World.SceneRenderer.sceneObjects.values()].filter(x => { - if (x instanceof MirabufSceneObject) { - return x.miraType === MiraType.ROBOT - } - return false - }) as MirabufSceneObject[] - return assemblies - }, []) - - return ( - } - panelId={panelId} - openLocation={openLocation} - sidePadding={sidePadding} - onAccept={() => {}} - onCancel={() => {}} - > - {selectedRobot?.ejectorPreferences == undefined ? ( - <> - - {/** Scroll view for selecting a robot to configure */} -
- {robots.map(mirabufSceneObject => { - return ( - - ) - })} -
- {/* TODO: remove the accept button on this version */} - - ) : ( - <> -
- v != null && setViewType(v)} - sx={{ - alignSelf: "center", - }} - > - SynthesisBrain - WIPLIBBrain - - {viewType === ConfigureRobotBrainTypes.SYNTHESIS ? ( - <> - - Behaviors - - - {GetJoints(selectedRobot)} - - ) : ( - <> - - Example WIPLIB Brain - - - - - Example 2 - - - - - Example 3 - - - - - Example 4 - - - - )} -
- - )} -
- ) -} - -export default ConfigureRobotBrainPanel diff --git a/fission/src/ui/panels/mirabuf/ImportMirabufPanel.tsx b/fission/src/ui/panels/mirabuf/ImportMirabufPanel.tsx index 351b5085f..6ef68f4d7 100644 --- a/fission/src/ui/panels/mirabuf/ImportMirabufPanel.tsx +++ b/fission/src/ui/panels/mirabuf/ImportMirabufPanel.tsx @@ -8,7 +8,14 @@ import { MirabufFilesUpdateEvent, RequestMirabufFiles, } from "@/aps/APSDataManagement" -import MirabufCachingService, { MirabufCacheInfo, MirabufRemoteInfo, MiraType } from "@/mirabuf/MirabufLoader" +import MirabufCachingService, { + backUpFields, + backUpRobots, + canOPFS, + MirabufCacheInfo, + MirabufRemoteInfo, + MiraType, +} from "@/mirabuf/MirabufLoader" import World from "@/systems/World" import { useTooltipControlContext } from "@/ui/TooltipContext" import { CreateMirabuf } from "@/mirabuf/MirabufSceneObject" @@ -72,7 +79,9 @@ export type MiraManifest = { } function GetCacheInfo(miraType: MiraType): MirabufCacheInfo[] { - return Object.values(MirabufCachingService.GetCacheMap(miraType)) + return Object.values( + canOPFS ? MirabufCachingService.GetCacheMap(miraType) : miraType == MiraType.ROBOT ? backUpRobots : backUpFields + ) } function SpawnCachedMira(info: MirabufCacheInfo, type: MiraType, progressHandle?: ProgressHandle) {