Compare commits
	
		
			18 Commits
		
	
	
		
			v0.25.2
			...
			franknoiro
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 977e566ae4 | |||
| 7aaf923529 | |||
| bcb05d02b4 | |||
| ef451b70b6 | |||
| c33107aa28 | |||
| 26737e055a | |||
| c01590b49b | |||
| 1d656d68c6 | |||
| e180b73c9d | |||
| 738b1a7c21 | |||
| 62aebaf523 | |||
| 2095375b37 | |||
| 7a9a33c656 | |||
| a4a393fc45 | |||
| 10884fd0b0 | |||
| bcf83dc7ee | |||
| 32f79c98f8 | |||
| c11149e909 | 
							
								
								
									
										15
									
								
								src/App.tsx
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								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
	