实验页:程序运行时改了代码或设计器,停手 1.5 秒后自动重新运行,不用再按 F5。重启前先用边写边检查的接口检查整个工程,有错误就不重启,原来的程序接着运行,工具栏提示"代码有错误,改好后自动重新运行";检查期间又改了、程序已停或换了工程时作废;停止后改动不会自动启动程序。使用说明、设计方案同步
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6a18bdf2e4
commit
9ed446f95a
3 files changed
+52
No files matched your search
@@ -91,6 +91,7 @@ onBeforeUnmount(() => window.removeEventListener('keydown', onKey))
|
||||
<h3>4. 写代码、运行</h3>
|
||||
<ul>
|
||||
<li><b>F5</b> 或 <b>▶ 运行</b>:编译并运行,窗体显示在右边的运行区;<b>Shift+F5</b> 或 <b>■ 停止</b> 结束程序。</li>
|
||||
<li>程序运行时改了代码或窗体,停手 1.5 秒后自动重新运行,不用再按 F5;代码有错误时原来的程序接着运行,改好后再自动重新运行。</li>
|
||||
<li>编译错误显示在窗体下面,点它跳到出错的代码;常见错误会给出中文<b>提示</b>。</li>
|
||||
<li>程序运行时出错(比如文本框是空的就转换成数字),窗体下面显示中文说明和出错的文件、行号,点它跳到那一行。</li>
|
||||
<li><code>Console.WriteLine</code> 的输出、程序保存的图片(项目 4 的拍照)也显示在窗体下面。</li>
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
startupForm,
|
||||
} from '../designer/templates'
|
||||
import CodeEditor from '../editor/CodeEditor.vue'
|
||||
import { checkProject } from '../editor/language'
|
||||
import { api } from '../api'
|
||||
import { currentUser, logout } from '../auth'
|
||||
import { deleteWork, loadWork, sampleWorkKey, saveWork } from '../editor/works'
|
||||
@@ -136,6 +137,8 @@ onMounted(async () => {
|
||||
/** 打开一个工程:服务器上有保存的作品就用作品,没有就用原始代码;discardWork 表示丢弃作品恢复原始代码 */
|
||||
async function openProject(key: string, original: () => Promise<SourceFile[]>, discardWork: boolean) {
|
||||
await flushSave()
|
||||
// 换了工程:之前安排的自动重新运行作废
|
||||
clearTimeout(rerunTimer)
|
||||
workKey.value = key
|
||||
designerHistory.clear()
|
||||
if (discardWork) await deleteWork(key).catch(() => {})
|
||||
@@ -331,6 +334,7 @@ function updateFile(path: string, content: string) {
|
||||
|
||||
function filesChanged() {
|
||||
modified.value = true
|
||||
scheduleRerun()
|
||||
// 老师试运行学生的提交时没有保存位置,不保存
|
||||
if (workKey.value) scheduleSave()
|
||||
}
|
||||
@@ -501,11 +505,50 @@ function toggleRunArea(collapsed = !runCollapsed.value) {
|
||||
function run() {
|
||||
if (running.value) return
|
||||
toggleRunArea(false)
|
||||
start()
|
||||
}
|
||||
|
||||
function start() {
|
||||
clearTimeout(rerunTimer)
|
||||
rerunBlocked.value = false
|
||||
session.run(
|
||||
files.value.map((f) => ({ ...f })),
|
||||
props.assignmentId ? assignment.value?.sampleId : sampleId.value,
|
||||
)
|
||||
}
|
||||
|
||||
// ---------- 运行中改了代码或窗体:自动重新运行,不用再按 F5 ----------
|
||||
/** 停止修改多久后重新运行 */
|
||||
const RERUN_DELAY_MS = 1500
|
||||
let rerunTimer: ReturnType<typeof setTimeout> | undefined
|
||||
/** 每次修改都递增,用来判断检查期间是否又改了 */
|
||||
let editCount = 0
|
||||
/** 改出了编译错误:原来的程序继续运行,改好后再重新运行 */
|
||||
const rerunBlocked = ref(false)
|
||||
|
||||
function scheduleRerun() {
|
||||
editCount++
|
||||
if (!running.value) return
|
||||
clearTimeout(rerunTimer)
|
||||
rerunTimer = setTimeout(() => void rerun(), RERUN_DELAY_MS)
|
||||
}
|
||||
|
||||
async function rerun() {
|
||||
// 上一次还在编译:等它运行起来再说
|
||||
if (state.status === 'compiling') {
|
||||
rerunTimer = setTimeout(() => void rerun(), RERUN_DELAY_MS)
|
||||
return
|
||||
}
|
||||
if (state.status !== 'running') return
|
||||
const edit = editCount
|
||||
// 先检查一遍:有错误就不重启,免得正在运行的程序被换成一堆报错(错误照常用波浪线标在代码里)
|
||||
const diagnostics = await checkProject()
|
||||
// 检查期间又改了(会再安排一次)、程序已经停了,或者检查失败:这次不重新运行
|
||||
if (edit !== editCount || state.status !== 'running' || !diagnostics) return
|
||||
rerunBlocked.value = diagnostics.some((d) => d.severity === 'error')
|
||||
if (!rerunBlocked.value) start()
|
||||
}
|
||||
onBeforeUnmount(() => clearTimeout(rerunTimer))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -561,6 +604,7 @@ function run() {
|
||||
</NPopconfirm>
|
||||
<span v-if="!viewing" class="save-state" :class="saveState">{{ SAVE_TEXT[saveState] }}</span>
|
||||
<NTag :type="statusType">{{ STATUS_TEXT[state.status] }}</NTag>
|
||||
<span v-if="rerunBlocked && state.status === 'running'" class="rerun-blocked">代码有错误,改好后自动重新运行</span>
|
||||
<span v-if="!assignmentId && !viewing && currentUser?.role === 'teacher'" class="metrics">
|
||||
编译 {{ state.metrics.compileMs }} ms · 启动 {{ state.metrics.startMs }} ms · 最近一次操作往返 {{ state.metrics.lastRoundTripMs }} ms
|
||||
</span>
|
||||
@@ -746,6 +790,12 @@ function run() {
|
||||
color: #dc2626;
|
||||
}
|
||||
|
||||
.rerun-blocked {
|
||||
color: #b45309;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.user {
|
||||
font-size: 13px;
|
||||
white-space: nowrap;
|
||||
|
||||
Reference in new issue
Block a user