mirror of
https://codeberg.org/vlw/monkeydo.git
synced 2025-09-13 15:53:40 +02:00
dev21w45b
This commit is contained in:
parent
86ea8cd031
commit
675fe748e4
3 changed files with 58 additions and 20 deletions
14
Monkeydo.mjs
14
Monkeydo.mjs
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue