From 539690cbdd6186257a8d3672117bd54d919636af Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Wed, 10 Nov 2021 12:31:04 +0100 Subject: [PATCH] dev21w45c Ready for review --- Monkeydo.mjs | 10 +++------- monkey/Monkey.js | 12 +++++------- monkey/MonkeyMaster.mjs | 29 ++++++++++++++++++++--------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/Monkeydo.mjs b/Monkeydo.mjs index 8fb502d..918319a 100644 --- a/Monkeydo.mjs +++ b/Monkeydo.mjs @@ -13,12 +13,8 @@ export default class Monkeydo extends MonkeyMaster { // Execute a task do(task) { if(!task[1] in this.methods) return; - const args = task.splice(0,2); - this.methods[task[1]](...args); - } - - async debug(state = true) { - return await this.setFlag("debug",state); + const args = task.splice(2); + this.methods[task[1]]?.(...args); } // Loop playback X times or negative number for infinite @@ -28,7 +24,7 @@ export default class Monkeydo extends MonkeyMaster { } times = Math.floor(times); times = Math.min(Math.max(times,0),255); // Clamp number to 8 bits - return await this.setFlag("playing",times); + return await this.setFlag("loop",times); } // Load Monkeydo manifest diff --git a/monkey/Monkey.js b/monkey/Monkey.js index 557b068..8d0bd09 100644 --- a/monkey/Monkey.js +++ b/monkey/Monkey.js @@ -4,7 +4,7 @@ importScripts("https://unpkg.com/comlink/dist/umd/comlink.js"); class Monkey { constructor() { - this.flags = new Uint8ClampedArray(2); + this.flags = new Uint8ClampedArray(3); this.tasks = []; this.tasksLength = 0; this.i = 0; @@ -17,9 +17,8 @@ class Monkey { // Task scheduler next() { - if(this.flags[0] === 0 || this.flags[1] === 0) return; + if(this.flags[0] === 0 || this.flags[2] === 0) return this.abort(); const task = this.tasks[this.i]; - console.log(task,this.i); // Run task after delay this.queue.thisTask = setTimeout(() => { @@ -30,9 +29,8 @@ class Monkey { // Loop until flag is 0 or infinite if 255 if(this.i === this.tasksLength) { - this.i = 0; - if(this.flags[1] === 255) return; - this.flags[1]--; + this.i = -1; + if(this.flags[1] < 255) this.flags[2]--; } // Queue the next task @@ -40,11 +38,11 @@ class Monkey { } abort() { + this.flags[2] = 0; // Playing: false clearTimeout(this.queue.thisTask); clearTimeout(this.queue.nextTask); this.queue.thisTask = null; this.queue.nextTask = null; - this.flags[1] = 0; // Playing: false } // Set or get a runtime flag diff --git a/monkey/MonkeyMaster.mjs b/monkey/MonkeyMaster.mjs index d6739d1..da3ee63 100644 --- a/monkey/MonkeyMaster.mjs +++ b/monkey/MonkeyMaster.mjs @@ -41,7 +41,7 @@ export default class MonkeyMaster { const worker = new Worker(this.getWorkerPath()); worker.addEventListener("message",event => { if(event.data[0] !== "TASK") return; - this.do(event.data); + this.do(event.data[1]); // Send inner array (task) }); const Monkey = Comlink.wrap(worker); @@ -61,31 +61,32 @@ export default class MonkeyMaster { flagStringToIndex(flag) { const flags = [ "MANIFEST_LOADED", + "LOOP", "PLAYING" ]; - // Translate string to index if(typeof flag === "string" || flag < 0) { flag = flags.indexOf(flag.toUpperCase()); - if(flag < 0) return; } // Check that key is in bounds - if(flag < 0 || flags > flags.length - 1) { - throw new Error(`Array key '${flag}' out of range`); - } + if(flag < 0 || flags > flags.length - 1) return false; return flag; } async getFlag(flag) { const key = this.flagStringToIndex(flag); + if(!key) Promise.reject("Invalid flag"); return await this.comlink.flag(key); } // Set or queue worker runtime flag async setFlag(flag,value) { const key = this.flagStringToIndex(flag); + if(!key) Promise.reject("Invalid flag"); + + // Set the flag when the worker is ready if(!this.ready) { this.queue.flag = [key,value]; return; @@ -104,10 +105,13 @@ export default class MonkeyMaster { if(!this.ready) await this.init(); return await new Promise((resolve,reject) => { let load = null; + // Attempt load string as URL and fetch manifest try { const url = new URL(manifest); + // If the URL parsed but fetch failed, this promise will reject load = this.comlink.fetchManifest(url.toString()); } + // Or attempt to load string as JSON if it's not a URL catch { load = this.comlink.loadManifest(manifest); } @@ -116,11 +120,18 @@ export default class MonkeyMaster { }); } + async stop() { + return await this.comlink.abort(); + } + // 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); + const playing = await this.getFlag("playing"); + let loop = await this.getFlag("loop"); + loop = loop > 0 ? loop : 1; // Play once if loop has no value + + if(playing > 0) return; + await this.setFlag("playing",loop); return await this.comlink.next(); } } \ No newline at end of file