mirror of
https://codeberg.org/vlw/monkeydo.git
synced 2025-09-13 23:53:41 +02:00
Implement requestAnimationFrame
This commit replaces setTimeout with a working example of requestAnimationFrame. Some further testing will have to be done
This commit is contained in:
parent
fc25c3ccba
commit
7ca095a0d7
3 changed files with 34 additions and 40 deletions
|
@ -37,11 +37,7 @@ export default class Monkeydo extends MonkeyMaster {
|
||||||
|
|
||||||
async play(manifest = null) {
|
async play(manifest = null) {
|
||||||
if(!this.ready && !manifest) throw new Error("Can not start playback without a manifest");
|
if(!this.ready && !manifest) throw new Error("Can not start playback without a manifest");
|
||||||
if(manifest) {
|
if(manifest) await this.load(manifest);
|
||||||
const load = this.load(manifest)
|
|
||||||
load.then(() => this.start());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return await this.start();
|
return await this.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,40 +5,39 @@ importScripts("https://unpkg.com/comlink/dist/umd/comlink.js");
|
||||||
class Monkey {
|
class Monkey {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.flags = new Uint8ClampedArray(3);
|
this.flags = new Uint8ClampedArray(3);
|
||||||
this.tasks = [];
|
|
||||||
this.tasksLength = 0;
|
this.tasks = {
|
||||||
this.i = 0;
|
tasks: [],
|
||||||
// Runtime task queue
|
length: 0,
|
||||||
this.queue = {
|
target: 0,
|
||||||
thisTask: null,
|
_i: 0,
|
||||||
nextTask: null
|
set manifest(manifest) {
|
||||||
|
this.tasks = manifest;
|
||||||
|
this.length = this.tasks.length - 1;
|
||||||
|
},
|
||||||
|
get task() {
|
||||||
|
return this.tasks[this._i];
|
||||||
|
},
|
||||||
|
step: () => {
|
||||||
|
this.tasks._i++;
|
||||||
|
const nextTask = this.tasks.task;
|
||||||
|
this.tasks.target = performance.now() + nextTask[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Task scheduler
|
// Main event loop, runs on every frame
|
||||||
next() {
|
tick() {
|
||||||
const start = performance.now();
|
if(this === undefined) return false;
|
||||||
const self = this;
|
if(this.flags[0] === 0 || this.flags[2] === 0) return this.abort();
|
||||||
let task = null;
|
|
||||||
|
const frame = Math.min(performance.now(),this.tasks.target);
|
||||||
// Run task after delay
|
if(frame == this.tasks.target) {
|
||||||
function frame() {
|
postMessage(["TASK",this.tasks.task]);
|
||||||
if(self.flags[0] === 0 || self.flags[2] === 0) return self.abort();
|
this.tasks.step();
|
||||||
postMessage(["TASK",task]);
|
|
||||||
self.i++;
|
|
||||||
scheduleFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queue the next task
|
|
||||||
function scheduleFrame() {
|
|
||||||
task = self.tasks[self.i];
|
|
||||||
//const elapsed = Math.round(performance.now() - start);
|
|
||||||
const wait = task[0] + start;
|
|
||||||
console.log(wait);
|
|
||||||
setTimeout(() => requestAnimationFrame(frame),wait);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduleFrame(start);
|
requestAnimationFrame(this.tick.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
abort() {
|
abort() {
|
||||||
|
@ -73,9 +72,7 @@ class Monkey {
|
||||||
reject("Failed to load manifest");
|
reject("Failed to load manifest");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.tasks = manifest.tasks;
|
this.tasks.manifest = manifest.tasks;
|
||||||
// Store length as property so we don't have to calculate the offset each iteration of next()
|
|
||||||
this.tasksLength = manifest.tasks.length - 1;
|
|
||||||
this.flags[0] = 1; // Manifest loaded: true
|
this.flags[0] = 1; // Manifest loaded: true
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
|
|
@ -47,11 +47,12 @@ export default class MonkeyMaster {
|
||||||
const Monkey = Comlink.wrap(worker);
|
const Monkey = Comlink.wrap(worker);
|
||||||
this.comlink = await new Monkey();
|
this.comlink = await new Monkey();
|
||||||
|
|
||||||
// Wait for comlink to initialize proxy and send queued flags
|
// Wait for comlink to spin up
|
||||||
return await new Promise((resolve,reject) => {
|
return await new Promise((resolve,reject) => {
|
||||||
if(!this.comlink) reject("Failed to open proxy to worker");
|
if(!this.comlink) reject("Failed to establish Comlink with worker");
|
||||||
|
|
||||||
this.ready = true;
|
this.ready = true;
|
||||||
|
// Send queued flags when worker is ready
|
||||||
this.queue.sendAllFlags();
|
this.queue.sendAllFlags();
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
@ -132,6 +133,6 @@ export default class MonkeyMaster {
|
||||||
|
|
||||||
if(playing > 0) return;
|
if(playing > 0) return;
|
||||||
await this.setFlag("playing",loop);
|
await this.setFlag("playing",loop);
|
||||||
return await this.comlink.next();
|
return await this.comlink.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue