diff --git a/src/App.tsx b/src/App.tsx index cbd75e0ac..10fd4f39a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,8 +1,8 @@ -import { useRef, useState, useEffect, useMemo } from 'react' +import { useRef, useState, useEffect } from 'react' import { Canvas } from '@react-three/fiber' import { Allotment } from 'allotment' import { OrbitControls, OrthographicCamera } from '@react-three/drei' -import { lexer } from './lang/tokeniser' +import { asyncLexer } from './lang/tokeniser' import { abstractSyntaxTree } from './lang/abstractSyntaxTree' import { executor, ExtrudeGroup, SketchGroup } from './lang/executor' import { recast } from './lang/recast' @@ -40,8 +40,6 @@ function App() { code, setCode, setAst, - // formatCode, - ast, setError, errorState, setProgramMemory, @@ -56,10 +54,8 @@ function App() { addLog: s.addLog, code: s.code, setCode: s.setCode, - ast: s.ast, setAst: s.setAst, lastGuiMode: s.lastGuiMode, - // formatCode: s.formatCode, setError: s.setError, errorState: s.errorState, setProgramMemory: s.setProgramMemory, @@ -89,61 +85,60 @@ function App() { } const [geoArray, setGeoArray] = useState<(ExtrudeGroup | SketchGroup)[]>([]) useEffect(() => { - try { - if (!code) { - setGeoArray([]) - setAst(null) - return - } - const tokens = lexer(code) - const _ast = abstractSyntaxTree(tokens) - setAst(_ast) - resetLogs() - const programMemory = executor(_ast, { - root: { - log: { - type: 'userVal', - value: (a: any) => { - addLog(a) - }, - __meta: [ - { - pathToNode: [], - sourceRange: [0, 0], + const asyncWrap = async () => { + try { + if (!code) { + setGeoArray([]) + setAst(null) + return + } + const tokens = await asyncLexer(code) + const _ast = abstractSyntaxTree(tokens) + console.log('setting ast') + setAst(_ast) + resetLogs() + const programMemory = executor(_ast, { + root: { + log: { + type: 'userVal', + value: (a: any) => { + addLog(a) }, - ], + __meta: [ + { + pathToNode: [], + sourceRange: [0, 0], + }, + ], + }, }, - }, - _sketch: [], - }) - setProgramMemory(programMemory) - const geos = programMemory?.return - ?.map(({ name }: { name: string }) => { - const artifact = programMemory?.root?.[name] - if ( - artifact.type === 'extrudeGroup' || - artifact.type === 'sketchGroup' - ) { - return artifact - } - return null + _sketch: [], }) - .filter((a) => a) as (ExtrudeGroup | SketchGroup)[] + setProgramMemory(programMemory) + const geos = programMemory?.return + ?.map(({ name }: { name: string }) => { + const artifact = programMemory?.root?.[name] + if ( + artifact.type === 'extrudeGroup' || + artifact.type === 'sketchGroup' + ) { + return artifact + } + return null + }) + .filter((a) => a) as (ExtrudeGroup | SketchGroup)[] - setGeoArray(geos) - console.log(programMemory) - setError() - } catch (e: any) { - setError('problem') - console.log(e) - addLog(e) + setGeoArray(geos) + console.log(programMemory) + setError() + } catch (e: any) { + setError('problem') + console.log(e) + addLog(e) + } } + asyncWrap() }, [code]) - // const shouldFormat = useMemo(() => { - // if (!ast) return false - // const recastedCode = recast(ast) - // return recastedCode !== code - // }, [code, ast]) return (
diff --git a/src/useStore.ts b/src/useStore.ts index 08fc5ec24..93718b328 100644 --- a/src/useStore.ts +++ b/src/useStore.ts @@ -1,4 +1,5 @@ import create from 'zustand' +import { persist } from 'zustand/middleware' import { addLineHighlight, EditorView } from './editor/highlightextension' import { Program, @@ -107,87 +108,100 @@ interface StoreState { setIsShiftDown: (isShiftDown: boolean) => void } -export const useStore = create()((set, get) => ({ - editorView: null, - setEditorView: (editorView) => { - set({ editorView }) - }, - highlightRange: [0, 0], - setHighlightRange: (highlightRange) => { - set({ highlightRange }) - const editorView = get().editorView - if (editorView) { - editorView.dispatch({ effects: addLineHighlight.of(highlightRange) }) - } - }, - setCursor: (ranges: Ranges) => { - const { editorView } = get() - if (!editorView) return - editorView.dispatch({ - selection: EditorSelection.create( - [...ranges.map(([start, end]) => EditorSelection.cursor(end))], - ranges.length - 1 - ), - }) - }, - selectionRanges: [[0, 0]], - setSelectionRanges: (selectionRanges) => { - set({ selectionRanges }) - }, - guiMode: { mode: 'default' }, - lastGuiMode: { mode: 'default' }, - setGuiMode: (guiMode) => { - set({ guiMode }) - }, - logs: [], - addLog: (log) => { - if (Array.isArray(log)) { - const cleanLog: any = log.map(({ __geoMeta, ...rest }) => rest) - set((state) => ({ logs: [...state.logs, cleanLog] })) - } else { - set((state) => ({ logs: [...state.logs, log] })) - } - }, - resetLogs: () => { - set({ logs: [] }) - }, - ast: null, - setAst: (ast) => { - set({ ast }) - }, - updateAst: async (ast, focusPath) => { - const newCode = recast(ast) - const astWithUpdatedSource = abstractSyntaxTree(await asyncLexer(newCode)) +export const useStore = create()( + persist( + (set, get) => ({ + editorView: null, + setEditorView: (editorView) => { + set({ editorView }) + }, + highlightRange: [0, 0], + setHighlightRange: (highlightRange) => { + set({ highlightRange }) + const editorView = get().editorView + if (editorView) { + editorView.dispatch({ effects: addLineHighlight.of(highlightRange) }) + } + }, + setCursor: (ranges: Ranges) => { + const { editorView } = get() + if (!editorView) return + editorView.dispatch({ + selection: EditorSelection.create( + [...ranges.map(([start, end]) => EditorSelection.cursor(end))], + ranges.length - 1 + ), + }) + }, + selectionRanges: [[0, 0]], + setSelectionRanges: (selectionRanges) => { + set({ selectionRanges }) + }, + guiMode: { mode: 'default' }, + lastGuiMode: { mode: 'default' }, + setGuiMode: (guiMode) => { + set({ guiMode }) + }, + logs: [], + addLog: (log) => { + if (Array.isArray(log)) { + const cleanLog: any = log.map(({ __geoMeta, ...rest }) => rest) + set((state) => ({ logs: [...state.logs, cleanLog] })) + } else { + set((state) => ({ logs: [...state.logs, log] })) + } + }, + resetLogs: () => { + set({ logs: [] }) + }, + ast: null, + setAst: (ast) => { + set({ ast }) + }, + updateAst: async (ast, focusPath) => { + const newCode = recast(ast) + const astWithUpdatedSource = abstractSyntaxTree( + await asyncLexer(newCode) + ) - set({ ast: astWithUpdatedSource, code: newCode }) - if (focusPath) { - const { node } = getNodeFromPath(astWithUpdatedSource, focusPath) - const { start, end } = node - if (!start || !end) return - setTimeout(() => { - get().setCursor([[start, end]]) - }) + set({ ast: astWithUpdatedSource, code: newCode }) + if (focusPath) { + const { node } = getNodeFromPath(astWithUpdatedSource, focusPath) + const { start, end } = node + if (!start || !end) return + setTimeout(() => { + get().setCursor([[start, end]]) + }) + } + }, + code: '', + setCode: (code) => { + set({ code }) + }, + formatCode: async () => { + const code = get().code + const ast = abstractSyntaxTree(await asyncLexer(code)) + const newCode = recast(ast) + set({ code: newCode, ast }) + }, + errorState: { + isError: false, + error: '', + }, + setError: (error = '') => { + set({ errorState: { isError: !!error, error } }) + }, + programMemory: { root: {}, _sketch: [] }, + setProgramMemory: (programMemory) => set({ programMemory }), + isShiftDown: false, + setIsShiftDown: (isShiftDown) => set({ isShiftDown }), + }), + { + name: 'store', + partialize: (state) => + Object.fromEntries( + Object.entries(state).filter(([key]) => ['code'].includes(key)) + ), } - }, - code: '', - setCode: (code) => { - set({ code }) - }, - formatCode: async () => { - const code = get().code - const ast = abstractSyntaxTree(await asyncLexer(code)) - const newCode = recast(ast) - set({ code: newCode, ast }) - }, - errorState: { - isError: false, - error: '', - }, - setError: (error = '') => { - set({ errorState: { isError: !!error, error } }) - }, - programMemory: { root: {}, _sketch: [] }, - setProgramMemory: (programMemory) => set({ programMemory }), - isShiftDown: false, - setIsShiftDown: (isShiftDown) => set({ isShiftDown }), -})) + ) +)