dev21w45b

This commit is contained in:
Victor Westerlund 2021-11-09 17:23:04 +01:00
parent 86ea8cd031
commit 675fe748e4
3 changed files with 58 additions and 20 deletions

View file

@ -26,8 +26,8 @@ export default class Monkeydo extends MonkeyMaster {
if(typeof times !== "number") { if(typeof times !== "number") {
times = parseInt(times); times = parseInt(times);
} }
// Clamp number to 8 bit max times = Math.floor(times);
times = Math.min(Math.max(times,0),255); times = Math.min(Math.max(times,0),255); // Clamp number to 8 bits
return await this.setFlag("playing",times); return await this.setFlag("playing",times);
} }
@ -38,4 +38,14 @@ export default class Monkeydo extends MonkeyMaster {
} }
return await this.loadManifest(manifest); return await this.loadManifest(manifest);
} }
async play(manifest = null) {
if(!this.ready && !manifest) throw new Error("Can not start playback without a manifest");
if(manifest) {
const load = this.load(manifest)
load.then(() => this.start());
return;
}
return await this.start();
}
} }

View file

@ -6,6 +6,8 @@ class Monkey {
constructor() { constructor() {
this.flags = new Uint8ClampedArray(2); this.flags = new Uint8ClampedArray(2);
this.tasks = []; this.tasks = [];
this.tasksLength = 0;
this.i = 0;
// Runtime task queue // Runtime task queue
this.queue = { this.queue = {
thisTask: null, thisTask: null,
@ -15,21 +17,22 @@ class Monkey {
// Task scheduler // Task scheduler
next() { next() {
if(this.flags[0] === 0) return; if(this.flags[0] === 0 || this.flags[1] === 0) return;
const task = this.tasks[this.i]; const task = this.tasks[this.i];
console.log(task,this.i);
// Run task after delay // Run task after delay
this.queue.thisTask = setTimeout(() => { this.queue.thisTask = setTimeout(() => {
// Dispatch task to main thread // Dispatch task to main thread
this.postMessage(["TASK",task]); postMessage(["TASK",task]);
this.i++; this.i++;
},task[0]); },task[0]);
// Loop until flag is 0 or infinite if 255 // Loop until flag is 0 or infinite if 255
if(this.i === this.tasks.length) { if(this.i === this.tasksLength) {
this.i = 0; this.i = 0;
if(flags[1] === 255) return; if(this.flags[1] === 255) return;
flags[1]--; this.flags[1]--;
} }
// Queue the next task // Queue the next task
@ -52,6 +55,11 @@ class Monkey {
// Fetch and install manifest from URL // Fetch and install manifest from URL
async fetchManifest(url) { async fetchManifest(url) {
const manifest = await fetch(url); const manifest = await fetch(url);
if(!manifest.ok) {
console.error("Monkeydo fetch error:",manifest);
throw new Error("Server responded with an error");
};
const json = await manifest.json(); const json = await manifest.json();
return await this.loadManifest(json); return await this.loadManifest(json);
} }
@ -68,6 +76,8 @@ class Monkey {
} }
} }
this.tasks = manifest.tasks; this.tasks = 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();
}); });

View file

@ -18,8 +18,7 @@ export default class MonkeyMaster {
// Copy flags and clear queue // Copy flags and clear queue
const flags = [...this.queue._flags]; const flags = [...this.queue._flags];
this.queue._flags = []; this.queue._flags = [];
flags.forEach(flag => this.setFlag(...flag));
flags.forEach(flag => this.setFlag(flag));
} }
}; };
} }
@ -40,6 +39,11 @@ export default class MonkeyMaster {
async init() { async init() {
// Spawn and wrap dedicated worker with Comlink // Spawn and wrap dedicated worker with Comlink
const worker = new Worker(this.getWorkerPath()); const worker = new Worker(this.getWorkerPath());
worker.addEventListener("message",event => {
if(event.data[0] !== "TASK") return;
this.do(event.data);
});
const Monkey = Comlink.wrap(worker); const Monkey = Comlink.wrap(worker);
this.comlink = await new Monkey(); this.comlink = await new Monkey();
@ -60,13 +64,14 @@ export default class MonkeyMaster {
"PLAYING" "PLAYING"
]; ];
// Translate string to index // Translate string to index
if(typeof flag === "string" || flag < 0) { if(typeof flag === "string" || flag < 0) {
const key = flags.indexOf(flag.toUpperCase()); flag = flags.indexOf(flag.toUpperCase());
if(key < 0) return; if(flag < 0) return;
} }
// Check key is in bounds // Check that key is in bounds
if(flag < 0 || flags > flags.length - 1) { if(flag < 0 || flags > flags.length - 1) {
throw new Error(`Array key '${flag}' out of range`); throw new Error(`Array key '${flag}' out of range`);
} }
@ -94,15 +99,28 @@ export default class MonkeyMaster {
return update; return update;
} }
// Load a Monkeydo manifest by URL or JSON string
async loadManifest(manifest) { async loadManifest(manifest) {
if(!this.ready) await this.init(); if(!this.ready) await this.init();
try { return await new Promise((resolve,reject) => {
const url = new URL(manifest); let load = null;
this.comlink.fetchManifest(url.toString()); try {
} const url = new URL(manifest);
catch { load = this.comlink.fetchManifest(url.toString());
this.comlink.loadManifest(manifest); }
} catch {
return true; load = this.comlink.loadManifest(manifest);
}
load.then(() => resolve())
.catch(() => reject("Failed to load manifest"));
});
}
// Start playback of a loaded manifest
async start() {
// Set playstate if no value is present already
const loop = await this.getFlag("playing");
if(loop < 1) await this.setFlag("playing",1);
return await this.comlink.next();
} }
} }