From 55beb433f3eece394cdc1078c3a994bfa5d40449 Mon Sep 17 00:00:00 2001 From: j433866 Date: Wed, 1 May 2019 14:12:36 +0100 Subject: [PATCH] Go back to sending messages via the main thread. A MessageChannel is faster on Chrome, but causes issues in Firefox. Bake button now says "Loading..." when the inputWorker is gathering inputs for baking --- src/web/ControlsWaiter.mjs | 17 +++++++--- src/web/InputWaiter.mjs | 66 ++++++++++++++++++++++++++------------ src/web/InputWorker.mjs | 45 +++++++++++++------------- 3 files changed, 80 insertions(+), 48 deletions(-) diff --git a/src/web/ControlsWaiter.mjs b/src/web/ControlsWaiter.mjs index 52c156de..70214bd6 100755 --- a/src/web/ControlsWaiter.mjs +++ b/src/web/ControlsWaiter.mjs @@ -57,9 +57,10 @@ class ControlsWaiter { * Handler to trigger baking. */ bakeClick() { - if (document.getElementById("bake").textContent.indexOf("Bake") > 0) { + const btnBake = document.getElementById("bake"); + if (btnBake.textContent.indexOf("Bake") > 0) { this.app.manager.input.getAll(); - } else { + } else if (btnBake.textContent.indexOf("Cancel") > 0) { this.manager.worker.cancelBake(); } } @@ -370,11 +371,12 @@ ${navigator.userAgent} /** - * Switches the Bake button between 'Bake' and 'Cancel' functions. + * Switches the Bake button between 'Bake', 'Cancel' and 'Loading' functions. * * @param {boolean} cancel - Whether to change to cancel or not + * @param {boolean} loading - Whether to change to loading or not */ - toggleBakeButtonFunction(cancel) { + toggleBakeButtonFunction(cancel, loading) { const bakeButton = document.getElementById("bake"), btnText = bakeButton.querySelector("span"); @@ -383,10 +385,17 @@ ${navigator.userAgent} if (cancel) { btnText.innerText = "Cancel"; bakeButton.classList.remove("btn-success"); + bakeButton.classList.remove("btn-warning"); bakeButton.classList.add("btn-danger"); + } else if (loading) { + btnText.innerText = "Loading..."; + bakeButton.classList.remove("btn-success"); + bakeButton.classList.remove("btn-danger"); + bakeButton.classList.add("btn-warning"); } else { btnText.innerText = "Bake!"; bakeButton.classList.remove("btn-danger"); + bakeButton.classList.remove("btn-warning"); bakeButton.classList.add("btn-success"); } } diff --git a/src/web/InputWaiter.mjs b/src/web/InputWaiter.mjs index da1bb71e..aa0d6f25 100644 --- a/src/web/InputWaiter.mjs +++ b/src/web/InputWaiter.mjs @@ -105,10 +105,9 @@ class InputWaiter { this.inputWorker.postMessage({ action: "loaderWorkerReady", data: { - id: workerObj.id, - port: workerObj.port + id: workerObj.id } - }, [workerObj.port]); + }); } /** @@ -122,17 +121,12 @@ class InputWaiter { } log.debug("Adding new LoaderWorker."); const newWorker = new LoaderWorker(); - const messageChannel = new MessageChannel(); const workerId = this.workerId++; - // newWorker.addEventListener("message", this.handleLoaderMessage.bind(this)); - newWorker.postMessage({ - port: messageChannel.port1, - id: workerId - }, [messageChannel.port1]); + newWorker.addEventListener("message", this.handleLoaderMessage.bind(this)); + newWorker.postMessage({id: workerId}); const newWorkerObj = { worker: newWorker, - id: workerId, - port: messageChannel.port2 + id: workerId }; this.loaderWorkers.push(newWorkerObj); return this.loaderWorkers.indexOf(newWorkerObj); @@ -151,10 +145,6 @@ class InputWaiter { log.debug(`Terminating worker ${this.loaderWorkers[idx].id}`); this.loaderWorkers[idx].worker.terminate(); this.loaderWorkers.splice(idx, 1); - if (this.loaderWorkers.length === 0) { - // There should always be 1 loaderworker loaded - this.addLoaderWorker(); - } } /** @@ -182,6 +172,44 @@ class InputWaiter { return -1; } + /** + * Sends an input to be loaded to the loaderWorker + * + * @param {object} inputData + * @param {File} inputData.file + * @param {number} inputData.inputNum + * @param {number} inputData.workerId + */ + loadInput(inputData) { + const idx = this.getLoaderWorkerIndex(inputData.workerId); + if (idx === -1) return; + this.loaderWorkers[idx].worker.postMessage({ + file: inputData.file, + inputNum: inputData.inputNum + }); + } + + /** + * Handler for messages sent back by the loaderWorker + * + * @param {MessageEvent} e + */ + handleLoaderMessage(e) { + const r = e.data; + + if (r.hasOwnProperty("fileBuffer")) { + this.inputWorker.postMessage({ + action: "loaderWorkerMessage", + data: r + }, [r.fileBuffer]); + } else { + this.inputWorker.postMessage({ + action: "loaderWorkerMessage", + data: r + }); + } + } + /** * Handler for messages sent back by the inputWorker @@ -203,12 +231,7 @@ class InputWaiter { this.activateLoaderWorker(); break; case "loadInput": - this.loaderWorkers[r.data.workerIdx].worker.postMessage({ - file: r.data.file, - inputNum: r.data.inputNum - }); - this.loaderWorkers[r.data.workerIdx].inputNum = r.data.inputNum; - this.loaderWorkers[r.data.workerIdx].active = true; + this.loadInput(r.data); break; case "terminateLoaderWorker": this.removeLoaderWorker(this.getLoaderWorker(r.data)); @@ -271,6 +294,7 @@ class InputWaiter { * Gets the input for all tabs */ getAll() { + this.manager.controls.toggleBakeButtonFunction(false, true); this.inputWorker.postMessage({ action: "getAll" }); diff --git a/src/web/InputWorker.mjs b/src/web/InputWorker.mjs index 37df4de0..945dcef6 100644 --- a/src/web/InputWorker.mjs +++ b/src/web/InputWorker.mjs @@ -12,7 +12,7 @@ self.maxWorkers = 4; self.maxTabs = 1; self.pendingFiles = []; self.inputs = {}; -self.loaderWorkerPorts = []; +self.loaderWorkers = []; self.currentInputNum = 1; self.numInputs = 0; self.pendingInputs = 0; @@ -83,6 +83,9 @@ self.addEventListener("message", function(e) { case "filterTabs": self.filterTabs(r.data); break; + case "loaderWorkerMessage": + self.handleLoaderMessage(r.data); + break; default: log.error(`Unknown action '${r.action}'.`); } @@ -390,8 +393,8 @@ self.updateInputValue = function(inputData) { }; self.getLoaderWorkerIdx = function(workerId) { - for (let i = 0; i < self.loaderWorkerPorts.length; i++) { - if (self.loaderWorkerPorts[i].id === workerId) { + for (let i = 0; i < self.loaderWorkers.length; i++) { + if (self.loaderWorkers[i].id === workerId) { return i; } } @@ -401,19 +404,14 @@ self.getLoaderWorkerIdx = function(workerId) { self.loaderWorkerReady = function(workerData) { const newWorkerObj = { id: workerData.id, - port: workerData.port, inputNum: -1, active: true }; - newWorkerObj.port.onmessage = function (e) { - self.handleLoaderMessage(e); - }; - self.loaderWorkerPorts.push(newWorkerObj); - self.loadNextFile(self.loaderWorkerPorts.indexOf(newWorkerObj)); + self.loaderWorkers.push(newWorkerObj); + self.loadNextFile(self.loaderWorkers.indexOf(newWorkerObj)); }; -self.handleLoaderMessage = function(e) { - const r = e.data; +self.handleLoaderMessage = function(r) { let inputNum = 0; if (r.hasOwnProperty("inputNum")) { @@ -451,30 +449,31 @@ self.handleLoaderMessage = function(e) { }; self.loadNextFile = function(workerIdx) { - if (workerIdx === -1) return; // No more workers can be created - const port = self.loaderWorkerPorts[workerIdx].port; + if (workerIdx === -1) return; + const id = self.loaderWorkers[workerIdx].id; if (self.pendingFiles.length === 0) { - const workerObj = self.loaderWorkerPorts.splice(workerIdx, 1)[0]; + const workerObj = self.loaderWorkers.splice(workerIdx, 1)[0]; self.terminateLoaderWorker(workerObj.id); return; } const nextFile = self.pendingFiles.splice(0, 1)[0]; - self.loaderWorkerPorts[workerIdx].inputNum = nextFile.inputNum; + self.loaderWorkers[workerIdx].inputNum = nextFile.inputNum; self.loadingInputs++; - port.postMessage({ + self.postMessage({ action: "loadInput", data: { file: nextFile.file, - inputNum: nextFile.inputNum + inputNum: nextFile.inputNum, + workerId: id } }); }; self.activateLoaderWorker = function() { - for (let i = 0; i < self.loaderWorkerPorts.length; i++) { - if (!self.loaderWorkerPorts[i].active) { - self.loaderWorkerPorts[i].active = true; + for (let i = 0; i < self.loaderWorkers.length; i++) { + if (!self.loaderWorkers[i].active) { + self.loaderWorkers[i].active = true; self.loadNextFile(i); return; } @@ -603,10 +602,10 @@ self.removeInput = function(removeInputData) { delete self.inputs[inputNum]; - for (let i = 0; i < self.loaderWorkerPorts.length; i++) { - if (self.loaderWorkerPorts[i].inputNum === inputNum) { + for (let i = 0; i < self.loaderWorkers.length; i++) { + if (self.loaderWorkers[i].inputNum === inputNum) { self.loadingInputs--; - self.terminateLoaderWorker(self.loaderWorkerPorts[i].id); + self.terminateLoaderWorker(self.loaderWorkers[i].id); } }