Compare commits
18 Commits
jtran/sequ
...
franknoiro
Author | SHA1 | Date | |
---|---|---|---|
977e566ae4 | |||
7aaf923529 | |||
bcb05d02b4 | |||
ef451b70b6 | |||
c33107aa28 | |||
26737e055a | |||
c01590b49b | |||
1d656d68c6 | |||
e180b73c9d | |||
738b1a7c21 | |||
62aebaf523 | |||
2095375b37 | |||
7a9a33c656 | |||
a4a393fc45 | |||
10884fd0b0 | |||
bcf83dc7ee | |||
32f79c98f8 | |||
c11149e909 |
17
src/App.tsx
17
src/App.tsx
@ -1,7 +1,6 @@
|
||||
import { useRef, useEffect, useCallback, MouseEventHandler } from 'react'
|
||||
import { useEffect, useCallback, MouseEventHandler } from 'react'
|
||||
import { DebugPanel } from './components/DebugPanel'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { _executor } from './lang/executor'
|
||||
import { PaneType, useStore } from './useStore'
|
||||
import { Logs, KCLErrors } from './components/Logs'
|
||||
import { CollapsiblePanel } from './components/CollapsiblePanel'
|
||||
@ -30,13 +29,10 @@ import { CameraDragInteractionType_type } from '@kittycad/lib/dist/types/src/mod
|
||||
import { CodeMenu } from 'components/CodeMenu'
|
||||
import { TextEditor } from 'components/TextEditor'
|
||||
import { Themes, getSystemTheme } from 'lib/theme'
|
||||
import { useSetupEngineManager } from 'hooks/useSetupEngineManager'
|
||||
import { useCodeEval } from 'hooks/useCodeEval'
|
||||
|
||||
|
||||
export function App() {
|
||||
const { code: loadedCode, project } = useLoaderData() as IndexLoaderData
|
||||
|
||||
const streamRef = useRef<HTMLDivElement>(null)
|
||||
useHotKeyListener()
|
||||
const {
|
||||
setCode,
|
||||
@ -59,9 +55,6 @@ export function App() {
|
||||
}))
|
||||
|
||||
const {
|
||||
auth: {
|
||||
context: { token },
|
||||
},
|
||||
settings: {
|
||||
context: { showDebugPanel, onboardingStatus, cameraControls, theme },
|
||||
},
|
||||
@ -104,9 +97,6 @@ export function App() {
|
||||
}
|
||||
}, [loadedCode, setCode])
|
||||
|
||||
useSetupEngineManager(streamRef, token)
|
||||
useCodeEval()
|
||||
|
||||
const debounceSocketSend = throttle<EngineCommand>((message) => {
|
||||
engineCommandManager?.sendSceneCommand(message)
|
||||
}, 16)
|
||||
@ -186,9 +176,8 @@ export function App() {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="h-screen overflow-hidden relative flex flex-col cursor-pointer select-none"
|
||||
className="relative h-full flex flex-col"
|
||||
onMouseMove={handleMouseMove}
|
||||
ref={streamRef}
|
||||
>
|
||||
<AppHeader
|
||||
className={
|
||||
|
@ -40,6 +40,7 @@ import { ContextFrom } from 'xstate'
|
||||
import CommandBarProvider from 'components/CommandBar'
|
||||
import { TEST, VITE_KC_SENTRY_DSN } from './env'
|
||||
import * as Sentry from '@sentry/react'
|
||||
import ModelingMachineProvider from 'components/ModelingMachineProvider'
|
||||
|
||||
if (VITE_KC_SENTRY_DSN && !TEST) {
|
||||
Sentry.init({
|
||||
@ -136,7 +137,9 @@ const router = createBrowserRouter(
|
||||
element: (
|
||||
<Auth>
|
||||
<Outlet />
|
||||
<App />
|
||||
<ModelingMachineProvider>
|
||||
<App />
|
||||
</ModelingMachineProvider>
|
||||
{!isTauri() && import.meta.env.PROD && <DownloadAppBanner />}
|
||||
</Auth>
|
||||
),
|
||||
|
106
src/components/ModelingMachineProvider.tsx
Normal file
106
src/components/ModelingMachineProvider.tsx
Normal file
@ -0,0 +1,106 @@
|
||||
import { useMachine } from '@xstate/react'
|
||||
import React, { createContext, useRef } from 'react'
|
||||
import {
|
||||
AnyStateMachine,
|
||||
ContextFrom,
|
||||
InterpreterFrom,
|
||||
Prop,
|
||||
StateFrom,
|
||||
} from 'xstate'
|
||||
import { modelingMachine } from 'machines/modelingMachine'
|
||||
import { useSetupEngineManager } from 'hooks/useSetupEngineManager'
|
||||
import { useCodeEval } from 'hooks/useCodeEval'
|
||||
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
|
||||
|
||||
type MachineContext<T extends AnyStateMachine> = {
|
||||
state: StateFrom<T>
|
||||
context: ContextFrom<T>
|
||||
send: Prop<InterpreterFrom<T>, 'send'>
|
||||
}
|
||||
|
||||
export const ModelingMachineContext = createContext(
|
||||
{} as MachineContext<typeof modelingMachine>
|
||||
)
|
||||
|
||||
export const ModelingMachineProvider = ({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) => {
|
||||
const {
|
||||
auth: {
|
||||
context: { token },
|
||||
},
|
||||
} = useGlobalStateContext()
|
||||
const streamRef = useRef<HTMLDivElement>(null)
|
||||
useSetupEngineManager(streamRef, token)
|
||||
useCodeEval()
|
||||
|
||||
// const { commands } = useCommandsContext()
|
||||
|
||||
// Settings machine setup
|
||||
// const retrievedSettings = useRef(
|
||||
// localStorage?.getItem(MODELING_PERSIST_KEY) || '{}'
|
||||
// )
|
||||
|
||||
// What should we persist from modeling state? Nothing?
|
||||
// const persistedSettings = Object.assign(
|
||||
// settingsMachine.initialState.context,
|
||||
// JSON.parse(retrievedSettings.current) as Partial<
|
||||
// (typeof settingsMachine)['context']
|
||||
// >
|
||||
// )
|
||||
|
||||
const [modelingState, modelingSend] = useMachine(modelingMachine, {
|
||||
// context: persistedSettings,
|
||||
actions: {
|
||||
'Modify AST': () => {},
|
||||
'Make selection horizontal': () => {},
|
||||
'Make selection vertical': () => {},
|
||||
'Update code selection cursors': () => {},
|
||||
},
|
||||
guards: {
|
||||
'Can make selection horizontal': () => true,
|
||||
'Can make selection vertical': () => true,
|
||||
'Selection contains axis': () => true,
|
||||
'Selection contains edge': () => true,
|
||||
'Selection contains face': () => true,
|
||||
'Selection contains line': () => true,
|
||||
'Selection contains point': () => true,
|
||||
'Selection is empty': () => true,
|
||||
'Selection is not empty': () => true,
|
||||
'Selection is one face': () => true,
|
||||
'Selection is one or more edges': () => true,
|
||||
},
|
||||
services: {
|
||||
createSketch: async () => {},
|
||||
createLine: async () => {},
|
||||
createExtrude: async () => {},
|
||||
createFillet: async () => {},
|
||||
},
|
||||
})
|
||||
|
||||
// useStateMachineCommands({
|
||||
// state: settingsState,
|
||||
// send: settingsSend,
|
||||
// commands,
|
||||
// owner: 'settings',
|
||||
// commandBarMeta: settingsCommandBarMeta,
|
||||
// })
|
||||
|
||||
return (
|
||||
<ModelingMachineContext.Provider
|
||||
value={{
|
||||
state: modelingState,
|
||||
context: modelingState.context,
|
||||
send: modelingSend,
|
||||
}}
|
||||
>
|
||||
<div className="h-screen overflow-hidden select-none" ref={streamRef}>
|
||||
{children}
|
||||
</div>
|
||||
</ModelingMachineContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export default ModelingMachineProvider
|
@ -333,7 +333,7 @@ export const Stream = ({ className = '' }) => {
|
||||
onWheel={handleScroll}
|
||||
onPlay={() => setIsLoading(false)}
|
||||
onMouseMoveCapture={handleMouseMove}
|
||||
className={`w-full h-full ${isExecuting && 'blur-md'}`}
|
||||
className={`w-full cursor-pointer h-full ${isExecuting && 'blur-md'}`}
|
||||
style={{ transitionDuration: '200ms', transitionProperty: 'filter' }}
|
||||
/>
|
||||
{isLoading && (
|
||||
|
@ -29,6 +29,7 @@ import {
|
||||
import { isOverlap, roundOff } from 'lib/utils'
|
||||
import { kclErrToDiagnostic } from 'lang/errors'
|
||||
import { CSSRuleObject } from 'tailwindcss/types/config'
|
||||
import { useModelingContext } from 'hooks/useModelingContext'
|
||||
import interact from '@replit/codemirror-interact'
|
||||
|
||||
export const editorShortcutMeta = {
|
||||
@ -76,6 +77,11 @@ export const TextEditor = ({
|
||||
sourceRangeMap: s.sourceRangeMap,
|
||||
}))
|
||||
|
||||
const {
|
||||
context: { selectionRanges: machineSelectionRanges },
|
||||
send,
|
||||
} = useModelingContext()
|
||||
|
||||
const {
|
||||
settings: {
|
||||
context: { textWrapping },
|
||||
@ -197,6 +203,14 @@ export const TextEditor = ({
|
||||
otherSelections: [],
|
||||
codeBasedSelections,
|
||||
})
|
||||
|
||||
send({
|
||||
type: 'Set selection',
|
||||
data: {
|
||||
...machineSelectionRanges,
|
||||
codeBasedSelections,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const editorExtensions = useMemo(() => {
|
||||
|
6
src/hooks/useModelingContext.ts
Normal file
6
src/hooks/useModelingContext.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { ModelingMachineContext } from 'components/ModelingMachineProvider'
|
||||
import { useContext } from 'react'
|
||||
|
||||
export const useModelingContext = () => {
|
||||
return useContext(ModelingMachineContext)
|
||||
}
|
466
src/machines/modelingMachine.ts
Normal file
466
src/machines/modelingMachine.ts
Normal file
@ -0,0 +1,466 @@
|
||||
import { Program } from 'lang/abstractSyntaxTreeTypes'
|
||||
import { ProgramMemory } from 'lang/executor'
|
||||
import { Axis, Selection, Selections } from 'useStore'
|
||||
import { assign, createMachine } from 'xstate'
|
||||
|
||||
export const MODELING_PERSIST_KEY = 'MODELING_PERSIST_KEY'
|
||||
|
||||
export const modelingMachine = createMachine(
|
||||
{
|
||||
/** @xstate-layout N4IgpgJg5mDOIC5QFkD2EwBsCWA7KAxAMICGuAxlgNoAMAuoqAA6qzYAu2qujIAHogC0AFgCMAOgBMogOwyAzAE5hNABw0ZAVlGKANCACeQyQDZh4zTMWj5GmqfnDN8gL4v9aDDnzjsETGAEAMpg7AAEsFhg5JzctAxIICxssTyJAgiimuZOkqqSMjRqipKKcvpGCIKiqibiwrVqkjSiwpJiCm4e6Fh4UL7+gQAicFExYSx47PG8yRxcaaAZgvKqivUaJquywtYyohWIojbiqqr7NZprps2u7iCevT5+AQQjkQHjkDAziXOpvGWSnkUk0JhMVkkmmkbRMmkOVWE5mkighNHk7WaZzu3S8fQGr3eY3CJD42Fgv2YrHm3EBQhkpVBpm0q2EMi2qgRImROjRGLaahkqi6Dx63n6L0CIU+4UmuGm9Fm1IB6SE8kK4hku1MilUlgh4JkCNWIJMzQhThKiiukhFj3FBKlxLC3zAlKSyoWdKq8hMqnEinRtgaohoELB8MMiE0zikpUkpnR1sDijtYvxkuCztJ5Pd-y9qqq4PWKgjZ2yUJ0COcdXRNEUvvyMYxqfu9ozgyzMrCADMSJQ857aYWVpp1udRAVA1kTMckQiGTRxGHWtaYyYaA1NGm8c9OwBReVgABOEQA1qFyAALQcpAtLRBagNOIW7RuqRxcmz+hob-ItNoOhxUVdwlA8j1PWAL3Ya8qFEBIqTvYcHwQBll1sDRdhMZRRD9eQuTWKQVDkK5Wm0GMZB3J4wNefcAEcAFdsCYF0+HYY8GIwW8aUWfhEATGQ42tWRClwxRUWrfJ6jkK1hHkMckyoh1M3opiWLANiOK4+ClSQ3iMmkCRagxGpZDWdQJKjBAtiXBtBTBUw2VKJSO0JUZuz7AdFT+Id9LVBtxHBMQwTKLUCjZL8ynEWx1CFPYrEott0z3V5pWiElMEwbiVRQlZwWXMMxBKVZ1FKBE1kEqEtm0JxWlKEwXJS4Z3PSsISEy7L7z4n0oq0JErmyXZWiNKzRyXHQ1AafYqukRqaMCVTmN7bBMtCTrkO6yRHGi0ydAaTc1xGyprHWXVQ0sesdVtJLQMdAhFpYnsVoCaYdJ8vTvT204N1kbCajEYyEXE00NFw2dVDEDdEtxajxCCaDrwICBuDAXxcAAN1QC9xCIY8wBIdgwHPS8b28xCeO9VZBODaxVCyPIIS1BE5zjFQij9cSamUOa4YRq9iDISgsrJj0PsLSczlBeRhuaY5wq5K46jKetCnkdUIfOHn4ZJ8QAEkD0YpbvCJ9hUFQYWENFinxehSRxEnMR1QxZ2si5dVTvky65FacF0S1vm9c7NLxjlBVLfzDaMkDEEwS50plAKNQv0IrZarMaWkTphqbth7WYKvQPUudSIoAAWzAeV1r8hBrAkTc5JoaFZFaedRr9TVoRjc4rgaNpRH9nX9bcj5WtDqvvUaCxxLhfrrSFTlRvd6LwTNVY4V5LUB-zwvmpH8YS-LyuRYj6u9QkEo5F9JxG9WSQFZOaXShaWxZG3HOHTz68d4IZASAvCIwBlwruEdGJ5ODkHauPG2Y56hTk3CFRw+ErJWFOI3doatSiOH1FvL+Q9Ai-3-gfYBYQryoGPNgAAXtwdgkDj6+U+hWU4VwGxOA3C0D8bsQRq3TuqS4vpZw4ILgAGTwETAAKmbTASMUZo0xtjXG+NCZhGNlAlCWRcKBWUNfMGrJIyVBEFCAMZxlAtD9LOZwgjxAiNwOIyR4gAByqAwgAAVUBTFgAQAAghACAEw3FH3DvQ8W1ochrAbCvNQSgFb1ntrYEJF97BIksdY2x5txCuKmGEbxGAIBeJ8X4qYqjNrMgDFCa0RQtS1AhNE9YNh6zZASe0YQyTRFhAkWkkIQD5RZJ8ZAPJvix50LFihMpMdLDtE0PUjmR0hCTNqXEhpicmktJsW0uxnTD7hGyX0ogqBS5MBekTFRQzrYjPZBILIYZnDqA1iYN2ux7YxiuEUQMqdubv3xPuTSnFAjIxsbIrGqMFEEyJhpdiPyikZFZMua0pRmxjlREzKyvoQR6gSscBkvpSjQxArDL54KMD3UNupb5XETk5W6rqU6BRsiCg-HLBEEIJBQjkpMhQ0htDXRhg6fFWkFrEtYgSt0b1yYUoyAaU4id0QzgTGCRl+xQRyTkAUdodNgLth8Lyn539g7hE8m6clXUMh6lqZYMc3sFnCAXLUAMjgwZlPREkj5mrSWo11QsMIAAlfGEADBZnCBAckNCKAGsCcM7qDsQStD1LKjc8ZrW1gcHqX09ZsI4o1f0T+V4wi4CcfqrsrV9WQsQMIDcy5WiCmOM3TcMyfR232B0P6ZwV5gh5gAMWeqEaR-y8ByKBXjEFy1Vph10qcza4l6hjkcNYByeorVWVDDaxcJRSoRi0O2zt7AiVqSHS9YtNchSBQGkKWcWCWjMw0OOcxg0-RFG0Bu4d26lpPWHXBMNY7xU2taMNV8H5rB3wXZe76WQb3qBrQ+l6OrnSun3RVIizaDQlHBAvSoxwIbluOGGBkepNbOv6B24dcNiQeu9SQX1-qwjHjI9gBiFJDWRyOAUJWkylA2CxUiO5C7-oYdDBCPIVx03JXw5uojMoSM+r9bql00BQ2jrFUcWQ6wlCTOkJifYKHGPWlteoEySg41v3uLmjA8BEgZrk0a+kcgmTr1ZOyVYBEzCaj2uEtNuE37ctcmAczDGqiMh0BhSZ0IPxyHOAiUoyImVaPULbZpeHeYk286fdEpTL5mEC7fLkchqaomqhoLUVLLF4MS59DCUh9jTrEKWyw879EsvqBx9klgdCJlix5nwWarGtPaZgYr4sY322tKsRu6nKxcnTlIDkpRJzsmTCs1JmAHFOIyfKEzoqLOZEDONQb0WRvaDdicJwEZS2Z2lrhObay0lDBRr1kZ1glynYcE0PYSD9FIkEuoNoDIk1FDO3FjrKSLsLeW1s3pEAbubVwiCVE0tVjTlMXotUB31zZDMA0U72c2uZoDgD7rRGukg5yeDgypaJBqzDGY15DYEc+iR0d1H9LfuY-EFqjARPEBmn9PkQo0qHJVWrOqe20hwZ5AxB+VruKeWup3mz1CCrxnZGcFaW21rNCBXOHZ3CawbAY4l58qX7ruBeokzL0MGotSTjNGYD88kauPhQSasMRQ0dFHVUJ5nUvSO+pN0VJzWRxLZFwgoPQyC9Rq7kFsTX1hfSCJzXm-sXn3ofv4jGKeZQ0tyXMuUReII0EMjKPyBO7ndc+AIy9GXHJ7aVZC2j-9QMnCajyPkWWUfsIQdCNLxP8nULYSIsoYLNVsLU+OMoJhlopqlqhEXjN4hS-t4N7gI3ZHKhrZ86buodMGwYjy6nIf3G71olkO0FWbf2DiE98vq2XfWhKCkDUDEWosIJlt5kPfjcD8MhUGUNwbggA */
|
||||
id: 'Modeling',
|
||||
|
||||
tsTypes: {} as import('./modelingMachine.typegen').Typegen0,
|
||||
predictableActionArguments: true,
|
||||
|
||||
context: {
|
||||
guiMode: 'default',
|
||||
selection: [] as string[],
|
||||
ast: null as Program | null,
|
||||
selectionRanges: {
|
||||
otherSelections: [],
|
||||
codeBasedSelections: [],
|
||||
} as Selections,
|
||||
programMemory: { root: {}, pendingMemory: {} } as ProgramMemory,
|
||||
// TODO: migrate engineCommandManager from useStore
|
||||
// engineCommandManager?: EngineCommandManager
|
||||
},
|
||||
|
||||
schema: {
|
||||
events: {} as
|
||||
| { type: 'Deselect all' }
|
||||
| { type: 'Deselect edge'; data: Selection & { type: 'edge' } }
|
||||
| { type: 'Deselect axis'; data: Axis }
|
||||
| {
|
||||
type: 'Deselect segment'
|
||||
data: Selection & { type: 'line' | 'arc' }
|
||||
}
|
||||
| { type: 'Deselect face'; data: Selection & { type: 'face' } }
|
||||
| {
|
||||
type: 'Deselect point'
|
||||
data: Selection & { type: 'point' | 'line-end' | 'line-mid' }
|
||||
}
|
||||
| { type: 'Equip extrude' }
|
||||
| { type: 'Equip fillet' }
|
||||
| { type: 'Enter sketch' }
|
||||
| { type: 'Select all'; data: Selection & { type: 'all ' } }
|
||||
| { type: 'Select edge'; data: Selection & { type: 'edge' } }
|
||||
| { type: 'Select axis'; data: Axis }
|
||||
| { type: 'Select segment'; data: Selection & { type: 'line' | 'arc' } }
|
||||
| { type: 'Select face'; data: Selection & { type: 'face' } }
|
||||
| { type: 'Set selection'; data: Selections }
|
||||
| {
|
||||
type: 'Select point'
|
||||
data: Selection & { type: 'point' | 'line-end' | 'line-mid' }
|
||||
}
|
||||
| { type: 'Sketch no face' }
|
||||
| { type: 'Toggle gui mode' }
|
||||
| { type: 'Cancel' }
|
||||
| { type: 'Add point' }
|
||||
| { type: 'Equip line tool' }
|
||||
| { type: 'Set radius' }
|
||||
| { type: 'Make segment horizontal' }
|
||||
| { type: 'Make segment vertical' }
|
||||
| { type: 'Complete line' }
|
||||
| { type: 'Set distance' },
|
||||
},
|
||||
|
||||
states: {
|
||||
idle: {
|
||||
on: {
|
||||
'Set selection': {
|
||||
target: 'idle',
|
||||
internal: true,
|
||||
actions: 'Set selection',
|
||||
},
|
||||
'Deselect point': {
|
||||
target: 'idle',
|
||||
internal: true,
|
||||
actions: [
|
||||
'Remove from code-based selection',
|
||||
'Update code selection cursors',
|
||||
// 'Engine: remove highlight',
|
||||
],
|
||||
cond: 'Selection contains point',
|
||||
},
|
||||
|
||||
'Deselect edge': {
|
||||
target: 'idle',
|
||||
internal: true,
|
||||
actions: [
|
||||
'Remove from code-based selection',
|
||||
'Update code selection cursors',
|
||||
// 'Engine: remove highlight',
|
||||
],
|
||||
cond: 'Selection contains edge',
|
||||
},
|
||||
|
||||
'Deselect axis': {
|
||||
target: 'idle',
|
||||
internal: true,
|
||||
actions: [
|
||||
'Remove from other selection',
|
||||
'Update code selection cursors',
|
||||
// 'Engine: remove highlight',
|
||||
],
|
||||
cond: 'Selection contains axis',
|
||||
},
|
||||
|
||||
'Select point': {
|
||||
target: 'idle',
|
||||
internal: true,
|
||||
actions: [
|
||||
'Add to code-based selection',
|
||||
'Update code selection cursors',
|
||||
// 'Engine: add highlight',
|
||||
],
|
||||
},
|
||||
|
||||
'Select edge': {
|
||||
target: 'idle',
|
||||
internal: true,
|
||||
actions: [
|
||||
'Add to code-based selection',
|
||||
'Update code selection cursors',
|
||||
// 'Engine: add highlight',
|
||||
],
|
||||
},
|
||||
|
||||
'Select axis': {
|
||||
target: 'idle',
|
||||
internal: true,
|
||||
actions: [
|
||||
'Add to other selection',
|
||||
// 'Engine: add highlight',
|
||||
],
|
||||
},
|
||||
|
||||
'Select face': {
|
||||
target: 'idle',
|
||||
internal: true,
|
||||
actions: [
|
||||
'Add to code-based selection',
|
||||
'Update code selection cursors',
|
||||
// 'Engine: add highlight',
|
||||
],
|
||||
},
|
||||
|
||||
'Enter sketch': [
|
||||
{
|
||||
target: 'Sketch',
|
||||
cond: 'Selection is one face',
|
||||
},
|
||||
'Sketch no face',
|
||||
],
|
||||
|
||||
'Equip extrude': [
|
||||
{
|
||||
target: 'Extrude',
|
||||
cond: 'Selection is empty',
|
||||
},
|
||||
{
|
||||
target: 'Extrude',
|
||||
cond: 'Selection is one face',
|
||||
},
|
||||
],
|
||||
|
||||
'Deselect face': {
|
||||
target: 'idle',
|
||||
internal: true,
|
||||
actions: [
|
||||
'Remove from code-based selection',
|
||||
'Update code selection cursors',
|
||||
// 'Engine: remove highlight',
|
||||
],
|
||||
cond: 'Selection contains face',
|
||||
},
|
||||
|
||||
'Select all': {
|
||||
target: 'idle',
|
||||
internal: true,
|
||||
actions: 'Add to code-based selection',
|
||||
},
|
||||
|
||||
'Deselect all': {
|
||||
target: 'idle',
|
||||
internal: true,
|
||||
actions: [
|
||||
'Clear selection',
|
||||
'Update code selection cursors',
|
||||
// 'Engine: remove highlight',
|
||||
],
|
||||
cond: 'Selection is not empty',
|
||||
},
|
||||
|
||||
'Equip fillet': [
|
||||
{
|
||||
target: 'Fillet',
|
||||
cond: 'Selection is empty',
|
||||
},
|
||||
{
|
||||
target: 'Fillet',
|
||||
cond: 'Selection is one or more edges',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
Sketch: {
|
||||
states: {
|
||||
Idle: {
|
||||
on: {
|
||||
'Equip line tool': 'Line Tool',
|
||||
|
||||
'Select point': {
|
||||
target: 'Idle',
|
||||
internal: true,
|
||||
actions: [
|
||||
'Update code selection cursors',
|
||||
'Add to code-based selection',
|
||||
],
|
||||
},
|
||||
|
||||
'Select segment': {
|
||||
target: 'Idle',
|
||||
internal: true,
|
||||
actions: [
|
||||
'Update code selection cursors',
|
||||
'Add to code-based selection',
|
||||
],
|
||||
},
|
||||
|
||||
'Deselect point': {
|
||||
target: 'Idle',
|
||||
internal: true,
|
||||
cond: 'Selection contains point',
|
||||
actions: [
|
||||
'Update code selection cursors',
|
||||
'Add to code-based selection',
|
||||
],
|
||||
},
|
||||
|
||||
'Deselect segment': {
|
||||
target: 'Idle',
|
||||
internal: true,
|
||||
cond: 'Selection contains line',
|
||||
actions: [
|
||||
'Update code selection cursors',
|
||||
'Add to code-based selection',
|
||||
],
|
||||
},
|
||||
|
||||
'Make segment vertical': {
|
||||
cond: 'Can make selection vertical',
|
||||
target: 'Idle',
|
||||
internal: true,
|
||||
actions: ['Make selection vertical'],
|
||||
},
|
||||
|
||||
'Make segment horizontal': {
|
||||
target: 'Idle',
|
||||
internal: true,
|
||||
cond: 'Can make selection horizontal',
|
||||
actions: ['Make selection horizontal'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
'Line Tool': {
|
||||
states: {
|
||||
'No Points': {
|
||||
on: {
|
||||
'Add point': {
|
||||
target: 'Point Added',
|
||||
actions: ['Modify AST', 'Update code selection cursors'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Done: {
|
||||
type: 'final',
|
||||
},
|
||||
|
||||
'Point Added': {
|
||||
on: {
|
||||
'Add point': {
|
||||
target: 'Segment Added',
|
||||
actions: ['Modify AST', 'Update code selection cursors'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
'Segment Added': {
|
||||
on: {
|
||||
'Add point': {
|
||||
target: 'Segment Added',
|
||||
internal: true,
|
||||
actions: ['Modify AST', 'Update code selection cursors'],
|
||||
},
|
||||
|
||||
'Complete line': {
|
||||
target: 'Done',
|
||||
actions: ['Modify AST', 'Update code selection cursors'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
initial: 'No Points',
|
||||
|
||||
invoke: {
|
||||
src: 'createLine',
|
||||
id: 'Create line',
|
||||
onDone: 'Idle',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
initial: 'Idle',
|
||||
|
||||
on: {
|
||||
Cancel: '.Idle',
|
||||
},
|
||||
|
||||
invoke: {
|
||||
src: 'createSketch',
|
||||
id: 'Create sketch',
|
||||
onDone: 'idle',
|
||||
},
|
||||
},
|
||||
|
||||
Extrude: {
|
||||
states: {
|
||||
Idle: {
|
||||
on: {
|
||||
'Select face': 'Selection Ready',
|
||||
},
|
||||
},
|
||||
'Selection Ready': {
|
||||
on: {
|
||||
'Set distance': 'Ready',
|
||||
},
|
||||
},
|
||||
Ready: {},
|
||||
},
|
||||
|
||||
initial: 'Idle',
|
||||
|
||||
on: {
|
||||
'Equip extrude': [
|
||||
{
|
||||
target: '.Selection Ready',
|
||||
cond: 'Selection is one face',
|
||||
},
|
||||
'.Idle',
|
||||
],
|
||||
},
|
||||
|
||||
invoke: {
|
||||
src: 'createExtrude',
|
||||
id: 'Create extrude',
|
||||
onDone: {
|
||||
target: 'idle',
|
||||
actions: ['Modify AST', 'Clear selection'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
'Sketch no face': {
|
||||
on: {
|
||||
'Select face': 'Sketch',
|
||||
},
|
||||
},
|
||||
|
||||
Fillet: {
|
||||
states: {
|
||||
Idle: {
|
||||
on: {
|
||||
'Select edge': 'Selection Ready',
|
||||
},
|
||||
},
|
||||
'Selection Ready': {
|
||||
on: {
|
||||
'Set radius': 'Ready',
|
||||
|
||||
'Select edge': {
|
||||
target: 'Selection Ready',
|
||||
internal: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
Ready: {},
|
||||
},
|
||||
|
||||
initial: 'Ready',
|
||||
|
||||
on: {
|
||||
'Equip fillet': [
|
||||
{
|
||||
target: '.Selection Ready',
|
||||
cond: 'Selection is one or more edges',
|
||||
},
|
||||
'.Idle',
|
||||
],
|
||||
},
|
||||
|
||||
invoke: {
|
||||
src: 'createFillet',
|
||||
id: 'Create fillet',
|
||||
onDone: {
|
||||
target: 'idle',
|
||||
actions: ['Modify AST', 'Clear selection'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
initial: 'idle',
|
||||
|
||||
on: {
|
||||
Cancel: '.idle',
|
||||
},
|
||||
},
|
||||
{
|
||||
actions: {
|
||||
'Set selection': assign({
|
||||
selectionRanges: (_, event) => event.data,
|
||||
}),
|
||||
'Add to code-based selection': assign({
|
||||
selectionRanges: ({ selectionRanges }, event) => ({
|
||||
...selectionRanges,
|
||||
codeBasedSelections: [
|
||||
...selectionRanges.codeBasedSelections,
|
||||
event.data,
|
||||
],
|
||||
}),
|
||||
}),
|
||||
'Add to other selection': assign({
|
||||
selectionRanges: ({ selectionRanges }, event) => ({
|
||||
...selectionRanges,
|
||||
otherSelections: [...selectionRanges.otherSelections, event.data],
|
||||
}),
|
||||
}),
|
||||
'Remove from code-based selection': assign({
|
||||
selectionRanges: ({ selectionRanges }, event) => ({
|
||||
...selectionRanges,
|
||||
codeBasedSelections: [
|
||||
...selectionRanges.codeBasedSelections,
|
||||
event.data,
|
||||
],
|
||||
}),
|
||||
}),
|
||||
'Remove from other selection': assign({
|
||||
selectionRanges: ({ selectionRanges }, event) => ({
|
||||
...selectionRanges,
|
||||
otherSelections: [...selectionRanges.otherSelections, event.data],
|
||||
}),
|
||||
}),
|
||||
'Clear selection': assign({
|
||||
selectionRanges: () => ({
|
||||
otherSelections: [],
|
||||
codeBasedSelections: [],
|
||||
}),
|
||||
}),
|
||||
},
|
||||
}
|
||||
)
|
165
src/machines/modelingMachine.typegen.ts
Normal file
165
src/machines/modelingMachine.typegen.ts
Normal file
@ -0,0 +1,165 @@
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true
|
||||
internalEvents: {
|
||||
'done.invoke.Create extrude': {
|
||||
type: 'done.invoke.Create extrude'
|
||||
data: unknown
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.'
|
||||
}
|
||||
'done.invoke.Create fillet': {
|
||||
type: 'done.invoke.Create fillet'
|
||||
data: unknown
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.'
|
||||
}
|
||||
'done.invoke.Create line': {
|
||||
type: 'done.invoke.Create line'
|
||||
data: unknown
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.'
|
||||
}
|
||||
'done.invoke.Create sketch': {
|
||||
type: 'done.invoke.Create sketch'
|
||||
data: unknown
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.'
|
||||
}
|
||||
'error.platform.Create extrude': {
|
||||
type: 'error.platform.Create extrude'
|
||||
data: unknown
|
||||
}
|
||||
'error.platform.Create fillet': {
|
||||
type: 'error.platform.Create fillet'
|
||||
data: unknown
|
||||
}
|
||||
'error.platform.Create line': {
|
||||
type: 'error.platform.Create line'
|
||||
data: unknown
|
||||
}
|
||||
'error.platform.Create sketch': {
|
||||
type: 'error.platform.Create sketch'
|
||||
data: unknown
|
||||
}
|
||||
'xstate.init': { type: 'xstate.init' }
|
||||
}
|
||||
invokeSrcNameMap: {
|
||||
createExtrude: 'done.invoke.Create extrude'
|
||||
createFillet: 'done.invoke.Create fillet'
|
||||
createLine: 'done.invoke.Create line'
|
||||
createSketch: 'done.invoke.Create sketch'
|
||||
}
|
||||
missingImplementations: {
|
||||
actions:
|
||||
| 'Make selection horizontal'
|
||||
| 'Make selection vertical'
|
||||
| 'Modify AST'
|
||||
| 'Update code selection cursors'
|
||||
delays: never
|
||||
guards:
|
||||
| 'Can make selection horizontal'
|
||||
| 'Can make selection vertical'
|
||||
| 'Selection contains axis'
|
||||
| 'Selection contains edge'
|
||||
| 'Selection contains face'
|
||||
| 'Selection contains line'
|
||||
| 'Selection contains point'
|
||||
| 'Selection is empty'
|
||||
| 'Selection is not empty'
|
||||
| 'Selection is one face'
|
||||
| 'Selection is one or more edges'
|
||||
services: 'createExtrude' | 'createFillet' | 'createLine' | 'createSketch'
|
||||
}
|
||||
eventsCausingActions: {
|
||||
'Add to code-based selection':
|
||||
| 'Deselect point'
|
||||
| 'Deselect segment'
|
||||
| 'Select all'
|
||||
| 'Select edge'
|
||||
| 'Select face'
|
||||
| 'Select point'
|
||||
| 'Select segment'
|
||||
'Add to other selection': 'Select axis'
|
||||
'Clear selection':
|
||||
| 'Deselect all'
|
||||
| 'done.invoke.Create extrude'
|
||||
| 'done.invoke.Create fillet'
|
||||
'Make selection horizontal': 'Make segment horizontal'
|
||||
'Make selection vertical': 'Make segment vertical'
|
||||
'Modify AST':
|
||||
| 'Add point'
|
||||
| 'Complete line'
|
||||
| 'done.invoke.Create extrude'
|
||||
| 'done.invoke.Create fillet'
|
||||
'Remove from code-based selection':
|
||||
| 'Deselect edge'
|
||||
| 'Deselect face'
|
||||
| 'Deselect point'
|
||||
'Remove from other selection': 'Deselect axis'
|
||||
'Set selection': 'Set selection'
|
||||
'Update code selection cursors':
|
||||
| 'Add point'
|
||||
| 'Complete line'
|
||||
| 'Deselect all'
|
||||
| 'Deselect axis'
|
||||
| 'Deselect edge'
|
||||
| 'Deselect face'
|
||||
| 'Deselect point'
|
||||
| 'Deselect segment'
|
||||
| 'Select edge'
|
||||
| 'Select face'
|
||||
| 'Select point'
|
||||
| 'Select segment'
|
||||
}
|
||||
eventsCausingDelays: {}
|
||||
eventsCausingGuards: {
|
||||
'Can make selection horizontal': 'Make segment horizontal'
|
||||
'Can make selection vertical': 'Make segment vertical'
|
||||
'Selection contains axis': 'Deselect axis'
|
||||
'Selection contains edge': 'Deselect edge'
|
||||
'Selection contains face': 'Deselect face'
|
||||
'Selection contains line': 'Deselect segment'
|
||||
'Selection contains point': 'Deselect point'
|
||||
'Selection is empty': 'Equip extrude' | 'Equip fillet'
|
||||
'Selection is not empty': 'Deselect all'
|
||||
'Selection is one face': 'Enter sketch' | 'Equip extrude'
|
||||
'Selection is one or more edges': 'Equip fillet'
|
||||
}
|
||||
eventsCausingServices: {
|
||||
createExtrude: 'Equip extrude'
|
||||
createFillet: 'Equip fillet'
|
||||
createLine: 'Equip line tool'
|
||||
createSketch: 'Enter sketch' | 'Select face'
|
||||
}
|
||||
matchesStates:
|
||||
| 'Extrude'
|
||||
| 'Extrude.Idle'
|
||||
| 'Extrude.Ready'
|
||||
| 'Extrude.Selection Ready'
|
||||
| 'Fillet'
|
||||
| 'Fillet.Idle'
|
||||
| 'Fillet.Ready'
|
||||
| 'Fillet.Selection Ready'
|
||||
| 'Sketch'
|
||||
| 'Sketch no face'
|
||||
| 'Sketch.Idle'
|
||||
| 'Sketch.Line Tool'
|
||||
| 'Sketch.Line Tool.Done'
|
||||
| 'Sketch.Line Tool.No Points'
|
||||
| 'Sketch.Line Tool.Point Added'
|
||||
| 'Sketch.Line Tool.Segment Added'
|
||||
| 'idle'
|
||||
| {
|
||||
Extrude?: 'Idle' | 'Ready' | 'Selection Ready'
|
||||
Fillet?: 'Idle' | 'Ready' | 'Selection Ready'
|
||||
Sketch?:
|
||||
| 'Idle'
|
||||
| 'Line Tool'
|
||||
| {
|
||||
'Line Tool'?:
|
||||
| 'Done'
|
||||
| 'No Points'
|
||||
| 'Point Added'
|
||||
| 'Segment Added'
|
||||
}
|
||||
}
|
||||
tags: never
|
||||
}
|
@ -21,12 +21,23 @@ import {
|
||||
import { KCLError } from './lang/errors'
|
||||
import { defferExecution } from 'lib/utils'
|
||||
|
||||
export type Axis = 'y-axis' | 'x-axis' | 'z-axis'
|
||||
|
||||
export type Selection = {
|
||||
type: 'default' | 'line-end' | 'line-mid'
|
||||
type:
|
||||
| 'default'
|
||||
| 'line-end'
|
||||
| 'line-mid'
|
||||
| 'face'
|
||||
| 'point'
|
||||
| 'edge'
|
||||
| 'line'
|
||||
| 'arc'
|
||||
| 'all'
|
||||
range: SourceRange
|
||||
}
|
||||
export type Selections = {
|
||||
otherSelections: ('y-axis' | 'x-axis' | 'z-axis')[]
|
||||
otherSelections: Axis[]
|
||||
codeBasedSelections: Selection[]
|
||||
}
|
||||
export type TooTip =
|
||||
|
Reference in New Issue
Block a user