From ff0ed25a3bf928aa8bef4d6dc0d7acbd43f71467 Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Sun, 7 Nov 2021 13:36:26 +0100 Subject: [PATCH] dev21w44b --- Monkeydo.mjs | 10 +--- monkey/Monkey.js | 20 +++++--- monkey/MonkeyMaster.mjs | 101 +++++++++++++++++++++++----------------- 3 files changed, 71 insertions(+), 60 deletions(-) diff --git a/Monkeydo.mjs b/Monkeydo.mjs index cbd83aa..4975232 100644 --- a/Monkeydo.mjs +++ b/Monkeydo.mjs @@ -20,14 +20,6 @@ export default class Monkeydo extends MonkeyMaster { } async load(manifest) { - let data = ""; - if(typeof manifest === "object") { - data = JSON.stringify(manifest); - } - const load = await this.transaction("LOAD_MANIFEST",manifest); - if(!load) { - throw new Error("Failed to load manifest"); - } - return true; + } } \ No newline at end of file diff --git a/monkey/Monkey.js b/monkey/Monkey.js index c3fc1e1..f7efb0e 100644 --- a/monkey/Monkey.js +++ b/monkey/Monkey.js @@ -1,14 +1,25 @@ -// Dedicated worker (monkey) which executes tasks from a Monkeydo manifest +// Dedicated worker (monkey) that executes tasks from a Monkeydo manifest + +importScripts("https://unpkg.com/comlink/dist/umd/comlink.js"); class Monkey { constructor() { this.manifest = {}; + + // Runtime flags + this.flags = new Uint8ClampedArray(2); + } + + // Set or get a runtime flag + flag(index,value = null) { + return value ? this.flags[index] = value : this.flags[index]; } async loadManifest(manifest) { try { const data = JSON.parse(manifest); this.manifest = data; + this.flags[0] = 1; } catch { const url = new URL(manifest); @@ -16,9 +27,4 @@ class Monkey { } } -const monkey = new Monkey(); - -// Event handler for messages received from initiator -onmessage = (message) => { - console.log(message); -} \ No newline at end of file +Comlink.expose(Monkey); \ No newline at end of file diff --git a/monkey/MonkeyMaster.mjs b/monkey/MonkeyMaster.mjs index 90f3193..e75dfcc 100644 --- a/monkey/MonkeyMaster.mjs +++ b/monkey/MonkeyMaster.mjs @@ -1,55 +1,68 @@ // Task manager for Monkeydo dedicated workers (monkeys) -class WorkerTransactions { +import * as Comlink from "https://unpkg.com/comlink/dist/esm/comlink.mjs"; + +export default class MonkeyMaster { constructor() { - this.txn = { - _open: [], // Open transations - prefix: "TXN", - timeout: 2000, - // Close a transaction - set close(name) { - this._open[name].resolve(); - }, - // Open a new transaction - set open(name) { - name = [this.prefix,name]; - name = name.join("_").toUpperCase(); - this._open[name] = new Promise(); - }, - get status(name) { - return this._open[name]; + this.comlink = null; + + this.ready = false; + this.flagQueue = []; + this.init(); + } + + // Import worker relative to this module + getWorkerPath() { + const name = "Monkey.js"; + const url = new URL(import.meta.url); + + const path = url.pathname.split("/"); + path[path.length - 1] = name; + + url.pathname = path.join("/"); + return url.toString(); + } + + async init() { + // Spawn and wrap dedicated worker with Comlink + const worker = new Worker(this.getWorkerPath()); + const Monkey = Comlink.wrap(worker); + + this.comlink = await new Monkey(); + } + + // Return a flag array index by name + flagStringToIndex(flag) { + const flags = [ + "MANIFEST_LOADED", + "PLAYING", + "LOOP" + ]; + // Translate string to index + if(typeof flag === "string" || flag < 0) { + const key = flags.indexOf(flag.toUpperCase()); + if(key < 0) { + return false; } } - } -} - -export default class MonkeyMaster extends WorkerTransactions { - constructor() { - super(); - // Spawn dedicated worker - this.monkey = new Worker("Monkey.js"); - this.monkey.addEventListener("message",message => this.receive(message.data)); - - if(this?.crossOriginIsolateds === true) { - // TODO; SharedArrayBuffer goes here + // Check key is in bounds + if(flag < 0 || flags > flags.length - 1) { + throw new Error(`Array key '${flag}' out of range`); } + return flag; } - send(data) { - this.monkey.postMessage(data); + async getFlag(flag) { + const key = this.flagStringToIndex(flag); + return await this.comlink.flag(key); + } + + async setFlag(flag,value) { + const key = this.flagStringToIndex(flag); + const update = await this.comlink.flag(0,12); + if(!update) { + this.flagQueue.push([key,value]); + } return true; } - - async receive(data) { - if(data[0] === "TASK") { - this.do(data[1]); - return; - } - this.txn.close = data[1]; - } - - async transaction(name,data) { - this.txn.open = name; - const send = this.send([this.txn.prefix,name,data]); - } } \ No newline at end of file