feat(bt): support generator leaves and delta time

Introduce support for generator functions in leaf tasks, allowing
them to yield for multi-frame execution. The `TaskRunner` now accepts
a delta time (`dt`) parameter, which is passed through to leaf
handlers.

Additionally, a `Cancel` symbol is introduced to allow leaf tasks to
explicitly cancel their subtree via a thrown error.
This commit is contained in:
2026-06-02 00:10:18 +08:00
parent ec8f668392
commit 4182bc1578
4 changed files with 107 additions and 43 deletions
+19 -16
View File
@@ -221,21 +221,24 @@ const runner = buildTree(world, {
},
{
kind: "leaf",
run: () => {
if (world.hasSingleton(GameOver) || world.hasSingleton(Paused)) {
return;
}
const timer = world.getSingleton(TickTimer);
timer.accumulator += 16;
if (timer.accumulator >= timer.interval) {
timer.accumulator -= timer.interval;
if (hasActivePiece()) {
const piece = world.getSingleton(Piece);
const board = world.getSingleton(Board);
if (!collides(board.grid, piece.shape, piece.x, piece.y + 1)) {
piece.y++;
} else {
lockAndSpawn();
*run() {
while (true) {
const dt: number = yield;
if (world.hasSingleton(GameOver) || world.hasSingleton(Paused)) {
continue;
}
const timer = world.getSingleton(TickTimer);
timer.accumulator += dt;
if (timer.accumulator >= timer.interval) {
timer.accumulator -= timer.interval;
if (hasActivePiece()) {
const piece = world.getSingleton(Piece);
const board = world.getSingleton(Board);
if (!collides(board.grid, piece.shape, piece.x, piece.y + 1)) {
piece.y++;
} else {
lockAndSpawn();
}
}
}
}
@@ -275,7 +278,7 @@ runner.schedule((runner as any).root);
const TICK_MS = 16;
const interval = setInterval(() => {
runner.tick();
runner.tick(TICK_MS);
}, TICK_MS);
// Cleanup on exit