cancel execution on file change (#1440)

This commit is contained in:
Kurt Hutten
2024-02-19 09:23:18 +11:00
committed by GitHub
parent 0a4a517bb4
commit 66e62c6037
2 changed files with 37 additions and 2 deletions

View File

@ -228,7 +228,17 @@ class KclManager {
} }
} }
async executeAst(ast: Program = this._ast, updateCode = false) { private _cancelTokens: Map<number, boolean> = new Map()
async executeAst(
ast: Program = this._ast,
updateCode = false,
executionId?: number
) {
console.trace('executeAst')
const currentExecutionId = executionId || Date.now()
this._cancelTokens.set(currentExecutionId, false)
await this.ensureWasmInit() await this.ensureWasmInit()
this.isExecuting = true this.isExecuting = true
const { logs, errors, programMemory } = await executeAst({ const { logs, errors, programMemory } = await executeAst({
@ -236,6 +246,11 @@ class KclManager {
engineCommandManager: this.engineCommandManager, engineCommandManager: this.engineCommandManager,
}) })
this.isExecuting = false this.isExecuting = false
// Check the cancellation token for this execution before applying side effects
if (this._cancelTokens.get(currentExecutionId)) {
this._cancelTokens.delete(currentExecutionId)
return
}
this.logs = logs this.logs = logs
this.kclErrors = errors this.kclErrors = errors
this.programMemory = programMemory this.programMemory = programMemory
@ -248,6 +263,7 @@ class KclManager {
type: 'execution-done', type: 'execution-done',
data: null, data: null,
}) })
this._cancelTokens.delete(currentExecutionId)
} }
async executeAstMock( async executeAstMock(
ast: Program = this._ast, ast: Program = this._ast,
@ -295,7 +311,13 @@ class KclManager {
} }
) )
} }
async executeCode(code?: string) { async executeCode(code?: string, executionId?: number) {
const currentExecutionId = executionId || Date.now()
this._cancelTokens.set(currentExecutionId, false)
if (this._cancelTokens.get(currentExecutionId)) {
this._cancelTokens.delete(currentExecutionId)
return
}
await this.ensureWasmInit() await this.ensureWasmInit()
await this?.engineCommandManager?.waitForReady await this?.engineCommandManager?.waitForReady
const result = await executeCode({ const result = await executeCode({
@ -304,6 +326,11 @@ class KclManager {
lastAst: this._ast, lastAst: this._ast,
force: false, force: false,
}) })
// Check the cancellation token for this execution before applying side effects
if (this._cancelTokens.get(currentExecutionId)) {
this._cancelTokens.delete(currentExecutionId)
return
}
if (!result.isChange) return if (!result.isChange) return
const { logs, errors, programMemory, ast } = result const { logs, errors, programMemory, ast } = result
this.logs = logs this.logs = logs
@ -311,6 +338,12 @@ class KclManager {
this.programMemory = programMemory this.programMemory = programMemory
this.ast = ast this.ast = ast
if (code) this.code = code if (code) this.code = code
this._cancelTokens.delete(currentExecutionId)
}
cancelAllExecutions() {
this._cancelTokens.forEach((_, key) => {
this._cancelTokens.set(key, true)
})
} }
setCode(code: string, shouldWriteFile = true) { setCode(code: string, shouldWriteFile = true) {
if (shouldWriteFile) { if (shouldWriteFile) {

View File

@ -36,6 +36,7 @@ import { sep } from '@tauri-apps/api/path'
import { homeCommandBarConfig } from 'lib/commandBarConfigs/homeCommandConfig' import { homeCommandBarConfig } from 'lib/commandBarConfigs/homeCommandConfig'
import { useHotkeys } from 'react-hotkeys-hook' import { useHotkeys } from 'react-hotkeys-hook'
import { isTauri } from 'lib/isTauri' import { isTauri } from 'lib/isTauri'
import { kclManager } from 'lang/KclSingleton'
// This route only opens in the Tauri desktop context for now, // This route only opens in the Tauri desktop context for now,
// as defined in Router.tsx, so we can use the Tauri APIs and types. // as defined in Router.tsx, so we can use the Tauri APIs and types.
@ -55,6 +56,7 @@ const Home = () => {
// during the loading of the home page. This is wrapped // during the loading of the home page. This is wrapped
// in a single-use effect to avoid a potential infinite loop. // in a single-use effect to avoid a potential infinite loop.
useEffect(() => { useEffect(() => {
kclManager.cancelAllExecutions()
if (newDefaultDirectory) { if (newDefaultDirectory) {
sendToSettings({ sendToSettings({
type: 'Set Default Directory', type: 'Set Default Directory',