From 828be28653a70bd241f0b190a91e96085ab0d9cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Mon, 28 Mar 2022 14:02:35 +0200 Subject: [PATCH] [REF] component: introduce RootFiber.setCounter and update scheduler The goal is to be able to execute code whenever a root fiber is ready, and before the next animation frame --- src/app/app.ts | 1 + src/component/component_node.ts | 3 +- src/component/error_handling.ts | 3 +- src/component/fibers.ts | 11 +++++- src/component/scheduler.ts | 69 +++++++++++++-------------------- 5 files changed, 40 insertions(+), 47 deletions(-) diff --git a/src/app/app.ts b/src/app/app.ts index 61de942d..ce7fd846 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -101,6 +101,7 @@ export class App< destroy() { if (this.root) { + this.scheduler.flush(); this.root.destroy(); } } diff --git a/src/component/component_node.ts b/src/component/component_node.ts index fd3749fd..17a0af39 100644 --- a/src/component/component_node.ts +++ b/src/component/component_node.ts @@ -245,7 +245,8 @@ export class ComponentNode

implements VNode = new Set(); - isRunning: boolean = false; requestAnimationFrame: Window["requestAnimationFrame"]; + frame: number = 0; constructor() { this.requestAnimationFrame = Scheduler.requestAnimationFrame; } - start() { - this.isRunning = true; - this.scheduleTasks(); - } - - stop() { - this.isRunning = false; - } - addFiber(fiber: Fiber) { this.tasks.add(fiber.root!); - if (!this.isRunning) { - this.start(); - } } /** @@ -39,39 +27,34 @@ export class Scheduler { * Other tasks are left unchanged. */ flush() { - this.tasks.forEach((fiber) => { - if (fiber.root !== fiber) { - this.tasks.delete(fiber); - return; - } - const hasError = fibersInError.has(fiber); - if (hasError && fiber.counter !== 0) { - this.tasks.delete(fiber); - return; - } - if (fiber.node.status === STATUS.DESTROYED) { - this.tasks.delete(fiber); - return; - } - - if (fiber.counter === 0) { - if (!hasError) { - fiber.complete(); - } - this.tasks.delete(fiber); - } - }); - if (this.tasks.size === 0) { - this.stop(); + if (this.frame === 0) { + this.frame = this.requestAnimationFrame(() => { + this.frame = 0; + this.tasks.forEach((fiber) => this.processFiber(fiber)); + }); } } - scheduleTasks() { - this.requestAnimationFrame(() => { - this.flush(); - if (this.isRunning) { - this.scheduleTasks(); + processFiber(fiber: RootFiber) { + if (fiber.root !== fiber) { + this.tasks.delete(fiber); + return; + } + const hasError = fibersInError.has(fiber); + if (hasError && fiber.counter !== 0) { + this.tasks.delete(fiber); + return; + } + if (fiber.node.status === STATUS.DESTROYED) { + this.tasks.delete(fiber); + return; + } + + if (fiber.counter === 0) { + if (!hasError) { + fiber.complete(); } - }); + this.tasks.delete(fiber); + } } }