Files
endorphin-tessera-gui/examples/cooperative-tasks.endor
T

98 lines
4.5 KiB
Plaintext

// 协作任务示例:两个 ui.spawn 各自保留执行帧,worker 按指令量子轮转推进。
// 这里刻意重复增量语句,方便看到暂停点;取消不回滚已经发生的 steps 写入,单个原生调用仍是原子边界。
// 每个实例有独立 steps 状态,两个任务不会把局部帧或计数存储混在一起。
class CooperativeWork {
// 保存 ui.state 返回的原生可变计数,每个 CooperativeWork 构造传入不同对象。
steps: Object
// 普通零参数方法被 spawn 调度后可跨量子继续;每条 increment 更新同一实例的计数。
// 连续语句无需手工 yield,VM 按累计预算暂停,恢复时不会从第一条重放。
function run(self: CooperativeWork): Unit {
// 第 1 至 16 次增量:由 spawn 的调用续体依次执行,每次原生 increment 完成后才进入下一条。
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
// 第 17 至 32 次增量:若此前在 VM 指令量子处让出,恢复后从保存的位置继续,不重跑前面的增量。
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
// 第 33 至 48 次增量:依然修改当前实例的 steps,另一个 owner 的 run 有独立调用帧与计数。
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
// 第 49 至 64 次增量:正常走完才结束任务;中途取消保留已发生修改,不把计数回滚为零。
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
self.steps.increment()
}
}
// 创建两个独立 owner,虽然 key 都叫 work,也不会相互替换;owner/key 组合才是任务身份。
left = CooperativeWork(ui.state(0))
// 左右实例共享类和方法定义,但这里分别分配 state,不能仅凭相同 work key 判断会相互取消。
right = CooperativeWork(ui.state(0))
// owner 是 left,方法是绑定 left 的 run;Task 句柄只用于状态/取消/结果查询,不是第二个业务计数对象。
leftTask = ui.spawn(left,"work",left.run)
// 同 key 配不同 owner 构成不同任务身份,worker 可以在两个续体之间按量子交替推进。
rightTask = ui.spawn(right,"work",right.run)
// 状态文字绑定到 Task.status,业务进度可在 Console 查询 left/right 的 steps.value。
leftStatus = TextBlock("")
// 两份文字控件分别绑定各自 Task.status,完成时间和状态不会通过同一字段覆盖彼此。
rightStatus = TextBlock("")
leftStatus.bind("text",leftTask.status)
rightStatus.bind("text",rightTask.status)
// 仅展示任务状态,任务 owner 不是 Page;关闭页面不会仅因内容消失就撤掉这两个普通业务 owner 的任务。
page = Page()
page.title = "独立暂停调用"
page.render(Column(24,16,TextBlock("两个任务分别保存执行帧;在 REPL 查看 left.steps.value / right.steps.value",2),leftStatus,rightStatus))