diff --git a/src/clientSideScene/ClientSideSceneComp.tsx b/src/clientSideScene/ClientSideSceneComp.tsx index b935e6f56..ff8898727 100644 --- a/src/clientSideScene/ClientSideSceneComp.tsx +++ b/src/clientSideScene/ClientSideSceneComp.tsx @@ -656,10 +656,17 @@ const ConstraintSymbol = ({ kclManager.ast, kclManager.programMemory ) + if (!transform) return const { modifiedAst } = transform + // eslint-disable-next-line @typescript-eslint/no-floating-promises - kclManager.updateAst(modifiedAst, true) + await kclManager.updateAst(modifiedAst, true) + + // Code editor will be updated in the modelingMachine. + const newCode = recast(modifiedAst) + if (err(newCode)) return + await codeManager.updateCodeEditor(newCode) } catch (e) { console.log('error', e) } diff --git a/src/clientSideScene/sceneEntities.ts b/src/clientSideScene/sceneEntities.ts index 17225d083..20de78889 100644 --- a/src/clientSideScene/sceneEntities.ts +++ b/src/clientSideScene/sceneEntities.ts @@ -846,6 +846,10 @@ export class SceneEntities { segmentName ) } + + const newCode = recast(modifiedAst) + if (err(newCode)) return + codeManager.updateCodeEditor(newCode) }, onMove: (args) => { this.onDragSegment({ @@ -970,43 +974,49 @@ export class SceneEntities { if (trap(_node)) return const sketchInit = _node.node?.declarations?.[0]?.init - if (sketchInit.type === 'PipeExpression') { - updateRectangleSketch(sketchInit, x, y, tags[0]) - - let _recastAst = parse(recast(_ast)) - if (trap(_recastAst)) return - _ast = _recastAst - - // Update the primary AST and unequip the rectangle tool - await kclManager.executeAstMock(_ast) - sceneInfra.modelingSend({ type: 'Finish rectangle' }) - - const { execState } = await executeAst({ - ast: _ast, - useFakeExecutor: true, - engineCommandManager: this.engineCommandManager, - programMemoryOverride, - idGenerator: kclManager.execState.idGenerator, - }) - const programMemory = execState.memory - - // Prepare to update the THREEjs scene - this.sceneProgramMemory = programMemory - const sketch = sketchFromKclValue( - programMemory.get(variableDeclarationName), - variableDeclarationName - ) - if (err(sketch)) return - const sgPaths = sketch.paths - const orthoFactor = orthoScale(sceneInfra.camControls.camera) - - // Update the starting segment of the THREEjs scene - this.updateSegment(sketch.start, 0, 0, _ast, orthoFactor, sketch) - // Update the rest of the segments of the THREEjs scene - sgPaths.forEach((seg, index) => - this.updateSegment(seg, index, 0, _ast, orthoFactor, sketch) - ) + if (sketchInit.type !== 'PipeExpression') { + return } + + updateRectangleSketch(sketchInit, x, y, tags[0]) + + const newCode = recast(_ast) + let _recastAst = parse(newCode) + if (trap(_recastAst)) return + _ast = _recastAst + + // Update the primary AST and unequip the rectangle tool + await kclManager.executeAstMock(_ast) + sceneInfra.modelingSend({ type: 'Finish rectangle' }) + + const { execState } = await executeAst({ + ast: _ast, + useFakeExecutor: true, + engineCommandManager: this.engineCommandManager, + programMemoryOverride, + idGenerator: kclManager.execState.idGenerator, + }) + const programMemory = execState.memory + + // Prepare to update the THREEjs scene + this.sceneProgramMemory = programMemory + const sketch = sketchFromKclValue( + programMemory.get(variableDeclarationName), + variableDeclarationName + ) + if (err(sketch)) return + const sgPaths = sketch.paths + const orthoFactor = orthoScale(sceneInfra.camControls.camera) + + // Update the starting segment of the THREEjs scene + this.updateSegment(sketch.start, 0, 0, _ast, orthoFactor, sketch) + // Update the rest of the segments of the THREEjs scene + sgPaths.forEach((seg, index) => + this.updateSegment(seg, index, 0, _ast, orthoFactor, sketch) + ) + + if (err(newCode)) return + codeManager.updateCodeEditor(newCode) }, }) } @@ -1166,13 +1176,17 @@ export class SceneEntities { if (err(moddedResult)) return modded = moddedResult.modifiedAst - let _recastAst = parse(recast(modded)) + const newCode = recast(modded) + if (err(newCode)) return + let _recastAst = parse(newCode) if (trap(_recastAst)) return Promise.reject(_recastAst) _ast = _recastAst // Update the primary AST and unequip the rectangle tool await kclManager.executeAstMock(_ast) sceneInfra.modelingSend({ type: 'Finish circle' }) + + codeManager.updateCodeEditor(newCode) } }, }) @@ -1208,6 +1222,7 @@ export class SceneEntities { forward, position, }) + await codeManager.writeToFile() } }, onDrag: async ({ diff --git a/src/hooks/useToolbarGuards.ts b/src/hooks/useToolbarGuards.ts index bfcb5eb80..8d8ae9678 100644 --- a/src/hooks/useToolbarGuards.ts +++ b/src/hooks/useToolbarGuards.ts @@ -2,13 +2,13 @@ import { SetVarNameModal, createSetVarNameModal, } from 'components/SetVarNameModal' -import { editorManager, kclManager } from 'lib/singletons' -import { reportRejection, trap } from 'lib/trap' +import { editorManager, kclManager, codeManager } from 'lib/singletons' +import { reportRejection, trap, err } from 'lib/trap' import { moveValueIntoNewVariable } from 'lang/modifyAst' import { isNodeSafeToReplace } from 'lang/queryAst' import { useEffect, useState } from 'react' import { useModelingContext } from './useModelingContext' -import { PathToNode, SourceRange } from 'lang/wasm' +import { PathToNode, SourceRange, recast } from 'lang/wasm' import { useKclContext } from 'lang/KclProvider' import { toSync } from 'lib/utils' @@ -57,6 +57,11 @@ export function useConvertToVariable(range?: SourceRange) { ) await kclManager.updateAst(_modifiedAst, true) + + const newCode = recast(_modifiedAst) + if (err(newCode)) return + codeManager.updateCodeEditor(newCode) + return pathToReplacedNode } catch (e) { console.log('error', e) diff --git a/src/lang/KclSingleton.ts b/src/lang/KclSingleton.ts index c164e9fcd..8074cc568 100644 --- a/src/lang/KclSingleton.ts +++ b/src/lang/KclSingleton.ts @@ -351,9 +351,6 @@ export class KclManager { this.clearAst() return } - codeManager.updateCodeEditor(newCode) - // Write the file to disk. - await codeManager.writeToFile() this._ast = { ...newAst } const { logs, errors, execState } = await executeAst({ @@ -491,11 +488,6 @@ export class KclManager { } if (execute) { - // Call execute on the set ast. - // Update the code state and editor. - codeManager.updateCodeEditor(newCode) - // Write the file to disk. - await codeManager.writeToFile() await this.executeAst({ ast: astWithUpdatedSource, zoomToFit: optionalParams?.zoomToFit, diff --git a/src/lang/modifyAst/addFillet.ts b/src/lang/modifyAst/addFillet.ts index e8a5ec0de..f79e88e82 100644 --- a/src/lang/modifyAst/addFillet.ts +++ b/src/lang/modifyAst/addFillet.ts @@ -8,6 +8,7 @@ import { VariableDeclaration, VariableDeclarator, sketchFromKclValue, + recast, } from '../wasm' import { createCallExpressionStdLib, @@ -35,7 +36,12 @@ import { ArtifactGraph, getSweepFromSuspectedPath, } from 'lang/std/artifactGraph' -import { kclManager, engineCommandManager, editorManager } from 'lib/singletons' +import { + kclManager, + engineCommandManager, + editorManager, + codeManager, +} from 'lib/singletons' import { Node } from 'wasm-lib/kcl/bindings/Node' // Apply Fillet To Selection @@ -253,6 +259,11 @@ async function updateAstAndFocus( const updatedAst = await kclManager.updateAst(modifiedAst, true, { focusPath: pathToFilletNode, }) + + const newCode = recast(updatedAst.newAst) + if (err(newCode)) return + await codeManager.updateCodeEditor(newCode) + if (updatedAst?.selections) { editorManager.selectRange(updatedAst?.selections) } diff --git a/src/machines/modelingMachine.ts b/src/machines/modelingMachine.ts index 0d573c724..27cf6d342 100644 --- a/src/machines/modelingMachine.ts +++ b/src/machines/modelingMachine.ts @@ -18,6 +18,7 @@ import { sceneEntitiesManager, engineCommandManager, editorManager, + codeManager, } from 'lib/singletons' import { horzVertInfo, @@ -512,6 +513,13 @@ export const modelingMachine = setup({ }, // end guards actions: { + // eslint-disable-next-line @typescript-eslint/no-misused-promises + 'update code editor and write to file': async () => { + const newCode = recast(kclManager.ast) + if (err(newCode)) return + await codeManager.updateCodeEditor(newCode) + await codeManager.writeToFile() + }, 'assign tool in context': assign({ currentTool: ({ event }) => 'data' in event && event.data && 'tool' in event.data @@ -599,7 +607,6 @@ export const modelingMachine = setup({ if (trap(extrudeSketchRes)) return const { modifiedAst, pathToExtrudeArg } = extrudeSketchRes - store.videoElement?.pause() const updatedAst = await kclManager.updateAst(modifiedAst, true, { focusPath: [pathToExtrudeArg], zoomToFit: true, @@ -608,11 +615,11 @@ export const modelingMachine = setup({ type: 'path', }, }) - if (!engineCommandManager.engineConnection?.idleMode) { - store.videoElement?.play().catch((e) => { - console.warn('Video playing was prevented', e) - }) - } + + const newCode = recast(updatedAst.newAst) + if (err(newCode)) return + await codeManager.updateCodeEditor(newCode) + if (updatedAst?.selections) { editorManager.selectRange(updatedAst?.selections) } @@ -646,7 +653,6 @@ export const modelingMachine = setup({ if (trap(revolveSketchRes)) return const { modifiedAst, pathToRevolveArg } = revolveSketchRes - store.videoElement?.pause() const updatedAst = await kclManager.updateAst(modifiedAst, true, { focusPath: [pathToRevolveArg], zoomToFit: true, @@ -655,11 +661,11 @@ export const modelingMachine = setup({ type: 'path', }, }) - if (!engineCommandManager.engineConnection?.idleMode) { - store.videoElement?.play().catch((e) => { - console.warn('Video playing was prevented', e) - }) - } + + const newCode = recast(updatedAst.newAst) + if (err(newCode)) return + await codeManager.updateCodeEditor(newCode) + if (updatedAst?.selections) { editorManager.selectRange(updatedAst?.selections) } @@ -689,6 +695,10 @@ export const modelingMachine = setup({ } await kclManager.updateAst(modifiedAst, true) + + const newCode = recast(modifiedAst) + if (err(newCode)) return + await codeManager.updateCodeEditor(newCode) })().catch(reportRejection) }, 'AST fillet': ({ event }) => { @@ -1560,7 +1570,10 @@ export const modelingMachine = setup({ }, }, - entry: 'setup client side sketch segments', + entry: [ + 'setup client side sketch segments', + 'update code editor and write to file', + ], }, 'Await horizontal distance info': {