2022-11-26 05:13:07 +11:00
|
|
|
import create from 'zustand'
|
2022-11-26 08:34:23 +11:00
|
|
|
import { addLineHighlight, EditorView } from './editor/highlightextension'
|
2022-11-28 19:43:20 +11:00
|
|
|
import { Program, abstractSyntaxTree } from './lang/abstractSyntaxTree'
|
2022-11-28 09:37:46 +11:00
|
|
|
import { recast } from './lang/recast'
|
2022-11-28 19:43:20 +11:00
|
|
|
import { lexer } from './lang/tokeniser'
|
2022-11-26 05:13:07 +11:00
|
|
|
|
|
|
|
export type Range = [number, number]
|
|
|
|
|
2022-11-27 14:06:33 +11:00
|
|
|
type GuiModes =
|
|
|
|
| {
|
|
|
|
mode: 'default'
|
|
|
|
}
|
|
|
|
| {
|
|
|
|
mode: 'sketch'
|
|
|
|
sketchMode: 'points'
|
|
|
|
axis: 'xy' | 'xz' | 'yz'
|
2022-11-28 09:37:46 +11:00
|
|
|
id: string
|
2022-11-27 14:06:33 +11:00
|
|
|
}
|
|
|
|
| {
|
|
|
|
mode: 'sketch'
|
|
|
|
sketchMode: 'selectFace'
|
|
|
|
}
|
|
|
|
| {
|
|
|
|
mode: 'codeError'
|
|
|
|
}
|
|
|
|
|
2022-11-26 05:13:07 +11:00
|
|
|
interface StoreState {
|
2022-11-26 08:34:23 +11:00
|
|
|
editorView: EditorView | null
|
|
|
|
setEditorView: (editorView: EditorView) => void
|
|
|
|
highlightRange: [number, number]
|
|
|
|
setHighlightRange: (range: Range) => void
|
|
|
|
selectionRange: [number, number]
|
|
|
|
setSelectionRange: (range: Range) => void
|
2022-11-27 14:06:33 +11:00
|
|
|
guiMode: GuiModes
|
|
|
|
lastGuiMode: GuiModes
|
|
|
|
setGuiMode: (guiMode: GuiModes) => void
|
|
|
|
removeError: () => void
|
|
|
|
logs: string[]
|
|
|
|
addLog: (log: string) => void
|
|
|
|
resetLogs: () => void
|
2022-11-28 09:37:46 +11:00
|
|
|
ast: Program | null
|
|
|
|
setAst: (ast: Program | null) => void
|
|
|
|
updateAst: (ast: Program) => void
|
|
|
|
code: string
|
|
|
|
setCode: (code: string) => void
|
2022-11-28 19:43:20 +11:00
|
|
|
formatCode: () => void
|
2022-11-26 05:13:07 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
export const useStore = create<StoreState>()((set, get) => ({
|
2022-11-26 08:34:23 +11:00
|
|
|
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) })
|
|
|
|
}
|
|
|
|
},
|
|
|
|
selectionRange: [0, 0],
|
|
|
|
setSelectionRange: (selectionRange) => {
|
|
|
|
set({ selectionRange })
|
|
|
|
},
|
2022-11-27 14:06:33 +11:00
|
|
|
guiMode: { mode: 'default' },
|
|
|
|
lastGuiMode: { mode: 'default' },
|
|
|
|
setGuiMode: (guiMode) => {
|
|
|
|
const lastGuiMode = get().guiMode
|
|
|
|
set({ guiMode })
|
2022-11-28 19:43:20 +11:00
|
|
|
if (guiMode.mode !== 'codeError') {
|
2022-11-28 09:37:46 +11:00
|
|
|
// don't set lastGuiMode to and error state
|
|
|
|
// as the point fo lastGuiMode is to restore the last healthy state
|
|
|
|
// todo maybe rename to lastHealthyGuiMode and remove this comment
|
|
|
|
set({ lastGuiMode })
|
|
|
|
}
|
2022-11-27 14:06:33 +11:00
|
|
|
},
|
|
|
|
removeError: () => {
|
|
|
|
const lastGuiMode = get().lastGuiMode
|
|
|
|
const currentGuiMode = get().guiMode
|
|
|
|
if (currentGuiMode.mode === 'codeError') {
|
|
|
|
set({ guiMode: lastGuiMode })
|
|
|
|
}
|
|
|
|
},
|
|
|
|
logs: [],
|
|
|
|
addLog: (log) => {
|
|
|
|
set((state) => ({ logs: [...state.logs, log] }))
|
|
|
|
},
|
|
|
|
resetLogs: () => {
|
|
|
|
set({ logs: [] })
|
|
|
|
},
|
2022-11-28 09:37:46 +11:00
|
|
|
ast: null,
|
|
|
|
setAst: (ast) => {
|
|
|
|
set({ ast })
|
|
|
|
},
|
|
|
|
updateAst: (ast) => {
|
|
|
|
const newCode = recast(ast)
|
|
|
|
set({ ast, code: newCode })
|
|
|
|
},
|
|
|
|
code: '',
|
|
|
|
setCode: (code) => {
|
|
|
|
set({ code })
|
2022-11-28 19:43:20 +11:00
|
|
|
},
|
|
|
|
formatCode: () => {
|
|
|
|
const code = get().code
|
|
|
|
const ast = abstractSyntaxTree(lexer(code))
|
|
|
|
const newCode = recast(ast)
|
|
|
|
set({ code: newCode, ast })
|
|
|
|
},
|
2022-11-26 05:13:07 +11:00
|
|
|
}))
|