diff --git a/e2e/playwright/flow-tests.spec.ts b/e2e/playwright/flow-tests.spec.ts index eea3105e9..349f6a83c 100644 --- a/e2e/playwright/flow-tests.spec.ts +++ b/e2e/playwright/flow-tests.spec.ts @@ -661,10 +661,7 @@ test('Can extrude from the command bar', async ({ page, context }) => { await expect(page.getByRole('button', { name: 'selection' })).toBeDisabled() // Click to select face and set distance - await u.openAndClearDebugPanel() await page.getByText('|> startProfileAt([-6.95, 4.98], %)').click() - await u.waitForCmdReceive('select_add') - await u.closeDebugPanel() await page.getByRole('button', { name: 'Continue' }).click() await expect(page.getByRole('button', { name: 'distance' })).toBeDisabled() await page.keyboard.press('Enter') diff --git a/src/clientSideScene/setup.tsx b/src/clientSideScene/setup.tsx index 3eaa2f957..64e95c0f9 100644 --- a/src/clientSideScene/setup.tsx +++ b/src/clientSideScene/setup.tsx @@ -481,6 +481,7 @@ class SetupSingleton { const targetFov = 4 const fovAnimationStep = (currentFov - targetFov) / FRAMES_TO_ANIMATE_IN + let frameWaitOnFinish = 5 const animateFovChange = () => { if (this.camera instanceof PerspectiveCamera) { @@ -490,14 +491,15 @@ class SetupSingleton { this.camera.updateProjectionMatrix() this.dollyZoom(currentFov) requestAnimationFrame(animateFovChange) // Continue the animation + } else if (frameWaitOnFinish > 0) { + frameWaitOnFinish-- + requestAnimationFrame(animateFovChange) // Continue the animation } else { - setTimeout(() => { - // Once the target FOV is reached, switch to the orthographic camera - // Needs to wait a couple frames after the FOV animation is complete - this.useOrthographicCamera() - this.isFovAnimationInProgress = false - resolve(true) - }, 100) + // Once the target FOV is reached, switch to the orthographic camera + // Needs to wait a couple frames after the FOV animation is complete + this.useOrthographicCamera() + this.isFovAnimationInProgress = false + resolve(true) } } } diff --git a/src/lang/std/engineConnection.ts b/src/lang/std/engineConnection.ts index 92b39cdad..8d5530072 100644 --- a/src/lang/std/engineConnection.ts +++ b/src/lang/std/engineConnection.ts @@ -915,6 +915,7 @@ export type CommandLog = export class EngineCommandManager { artifactMap: ArtifactMap = {} lastArtifactMap: ArtifactMap = {} + sceneCommandArtifacts: ArtifactMap = {} private getAst: () => Program = () => ({ start: 0, end: 0, body: [] } as any) outSequence = 1 inSequence = 1 @@ -1118,6 +1119,7 @@ export class EngineCommandManager { } const modelingResponse = message.data.modeling_response const command = this.artifactMap[id] + const sceneCommand = this.sceneCommandArtifacts[id] this.addCommandLog({ type: 'receive-reliable', data: message, @@ -1153,7 +1155,25 @@ export class EngineCommandManager { data: modelingResponse, raw: message, }) - } else { + } else if (sceneCommand && sceneCommand.type === 'pending') { + const resolve = sceneCommand.resolve + const artifact = { + type: 'result', + range: sceneCommand.range, + pathToNode: sceneCommand.pathToNode, + commandType: sceneCommand.commandType, + parentId: sceneCommand.parentId ? sceneCommand.parentId : undefined, + data: modelingResponse, + raw: message, + } as const + this.sceneCommandArtifacts[id] = artifact + resolve({ + id, + commandType: sceneCommand.commandType, + range: sceneCommand.range, + data: modelingResponse, + }) + } else if (command) { this.artifactMap[id] = { type: 'result', commandType: command?.commandType, @@ -1162,6 +1182,15 @@ export class EngineCommandManager { data: modelingResponse, raw: message, } + } else { + this.sceneCommandArtifacts[id] = { + type: 'result', + commandType: sceneCommand?.commandType, + range: sceneCommand?.range, + pathToNode: sceneCommand?.pathToNode, + data: modelingResponse, + raw: message, + } } } handleFailedModelingCommand({ @@ -1373,7 +1402,7 @@ export class EngineCommandManager { } // since it's not mouse drag or highlighting send over TCP and keep track of the command this.engineConnection?.send(command) - return this.handlePendingCommand(command.cmd_id, command.cmd) + return this.handlePendingSceneCommand(command.cmd_id, command.cmd) } sendModelingCommand({ id, @@ -1414,6 +1443,36 @@ export class EngineCommandManager { } throw Error('shouldnt reach here') } + handlePendingSceneCommand( + id: string, + command: Models['ModelingCmd_type'], + ast?: Program, + range?: SourceRange + ) { + let resolve: (val: any) => void = () => {} + const promise = new Promise((_resolve, reject) => { + resolve = _resolve + }) + const getParentId = (): string | undefined => { + if (command.type === 'extend_path') { + return command.path + } + // TODO handle other commands that have a parent + } + const pathToNode = ast + ? getNodePathFromSourceRange(ast, range || [0, 0]) + : [] + this.sceneCommandArtifacts[id] = { + range: range || [0, 0], + pathToNode, + type: 'pending', + commandType: command.type, + parentId: getParentId(), + promise, + resolve, + } + return promise + } handlePendingCommand( id: string, command: Models['ModelingCmd_type'],