use raf's time for smoother transitions

pull/4014/head
mrkishi 5 years ago
parent 26de6eb871
commit c18f066a9b

@ -1,39 +1,42 @@
import { now, raf } from './environment'; import { raf } from './environment';
export interface Task { abort(): void; promise: Promise<void> } export interface Task { abort(): void; promise: Promise<void> }
const tasks = new Set(); type TaskCallback = (now: number) => boolean | void;
let running = false; type TaskEntry = { c: TaskCallback; f: () => void };
function run_tasks() { const tasks = new Set<TaskEntry>();
function run_tasks(now: number) {
tasks.forEach(task => { tasks.forEach(task => {
if (!task[0](now())) { if (!task.c(now)) {
tasks.delete(task); tasks.delete(task);
task[1](); task.f();
} }
}); });
running = tasks.size > 0; if (tasks.size !== 0) raf(run_tasks);
if (running) raf(run_tasks);
} }
/**
* For testing purposes only!
*/
export function clear_loops() { export function clear_loops() {
// for testing... tasks.clear();
tasks.forEach(task => tasks.delete(task));
running = false;
} }
export function loop(fn: (number) => void): Task { /**
let task; * Creates a new task that runs on each raf frame
* until it returns a falsy value or is aborted
*/
export function loop(callback: TaskCallback): Task {
let task: TaskEntry;
if (!running) { if (tasks.size === 0) raf(run_tasks);
running = true;
raf(run_tasks);
}
return { return {
promise: new Promise<void>(fulfil => { promise: new Promise(fulfill => {
tasks.add(task = [fn, fulfil]); tasks.add(task = { c: callback, f: fulfill });
}), }),
abort() { abort() {
tasks.delete(task); tasks.delete(task);

@ -107,7 +107,7 @@ describe("runtime", () => {
set_raf(cb => { set_raf(cb => {
raf.callback = () => { raf.callback = () => {
raf.callback = null; raf.callback = null;
cb(); cb(raf.time);
flush(); flush();
}; };
}); });

Loading…
Cancel
Save