diff --git a/app/local/Unit.js b/app/local/Unit.js index 9214434e..641b2a3c 100644 --- a/app/local/Unit.js +++ b/app/local/Unit.js @@ -19,7 +19,8 @@ Unit.parsec = {}; // Note that, while this exact value is correct, it's larger than // Number.MAX_SAFE_INTEGER and will produce bad results in contexts where // accuracy is needed. -Unit.parsec.inMeters = BigInt('30856775814913673'); +Unit.parsec.inMetersBigInt = BigInt('30856775814913673'); +Unit.parsec.inMeters = Number(Unit.parsec.inMetersBigInt); // ^^ factors: // 1801n, 12269n, 22096469n, 1396457317n @@ -30,6 +31,7 @@ Unit.lightYear = {}; // Note that, while this exact value is correct, it's larger than // Number.MAX_SAFE_INTEGER and will produce bad results in contexts where // accuracy is needed (we're accurate up to just over 0.9ly). -Unit.lightYear.inMeters = BigInt('9460730472580800'); +Unit.lightYear.inMetersBigInt = BigInt('9460730472580800'); +Unit.lightYear.inMeters = Number(Unit.lightYear.inMetersBigInt); export default Unit; diff --git a/app/local/core.js b/app/local/core.js index c5e63857..9adef591 100644 --- a/app/local/core.js +++ b/app/local/core.js @@ -78,6 +78,7 @@ window.$game = { // TODO: determine if this has become redundant (we're implementing new positioning methods). hyperMovement: false, event: { + offscreenSkyboxReady: new ChangeTracker(), skyboxLoaded: new ChangeTracker(), } }; diff --git a/app/managedWorkers/ManagedWorker.js b/app/managedWorkers/ManagedWorker.js deleted file mode 100644 index 90226e52..00000000 --- a/app/managedWorkers/ManagedWorker.js +++ /dev/null @@ -1,32 +0,0 @@ -// Managed web worker with opt-in/out listeners. - -import CbQueue from '../local/CbQueue'; - -export default class ManagedWorker extends Worker { - constructor(url) { - super(url, { type: 'module' }); - super.onmessage = this._onInternalMessage; - this._listeners = {}; - } - - addWorkerListener(message, callback) { - if (!this._listeners[message]) { - this._listeners[message] = new CbQueue(); - } - this._listeners[message].register(callback); - } - - removeWorkerListener(message, callback) { - if (!this._listeners[message]) { - return; - } - this._listeners[message].deregister(callback); - } - - _onInternalMessage(message) { - const payload = message.data; - if (this._listeners[payload.key]) { - this._listeners[payload.key].notifyAll(payload); - } - } -} diff --git a/app/managedWorkers/OffscreenSkyboxWorker.js b/app/managedWorkers/OffscreenSkyboxWorker.js index 4d2cedc3..07589fcf 100644 --- a/app/managedWorkers/OffscreenSkyboxWorker.js +++ b/app/managedWorkers/OffscreenSkyboxWorker.js @@ -1,15 +1,20 @@ -import ManagedWorker from './ManagedWorker'; import * as THREE from 'three'; import Unit from '../local/Unit'; import { logBootInfo } from '../local/windowLoadListener'; +import ChangeTracker from '../emitters/ChangeTracker'; -export default class OffscreenSkyboxWorker extends ManagedWorker { +// TODO: maybe rename to astrometrics worker? It's become more than just a +// skybox machine. +export default class OffscreenSkyboxWorker extends Worker { constructor() { // Note: offscreenRenderer.js is made available via Webpack bundling. - super('./build/offscreenSkybox.js'); + super('./build/offscreenSkybox.js', { type: 'module' }); this.skyboxCube = null; + this.initComplete = false; // Just a tad bigger than the Milky Way. Yes, we can do that. In meters. - this.skyboxSize = Number(Unit.parsec.inMeters * BigInt(32768)); + this.skyboxSize = Number(Unit.parsec.inMetersBigInt * BigInt(32768)); + // Used to uniquely identify each web worker request. + this.ticketCount = 0; this._collectedImages = [ null, null, null, null, null, null, @@ -19,17 +24,41 @@ export default class OffscreenSkyboxWorker extends ManagedWorker { } prepListeners() { - this.addWorkerListener('init', ({ error, value }) => { + // Create worker listeners. + this.workerListener = { + init: new ChangeTracker(), + renderFace: new ChangeTracker(), + testHeavyPayload: new ChangeTracker(), + }; + + // Hook listeners into onmessage. + this.onmessage = (message) => { + const payload = message.data; + const listener = this.workerListener[payload.key]; + if (!listener) { + return console.error( + '[OffscreenSkyboxWorker] Nothing to receive', payload.key + ); + } + listener.setValue(payload); + }; + + // Define listener responses. + this.workerListener.init.getEveryChange(({ error, value }) => { + if (this.initComplete) { + return console.error('[OffscreenSkyboxWorker] Init received twice.'); + } + this.initComplete = true; if (error || !value) { console.error(error, '- got:', value); } else { - this.ready = true; this.generateSkybox(); + $game.event.offscreenSkyboxReady.setValue({ when: new Date() }); } }); - this.addWorkerListener('renderFace', ({ value }) => { + this.workerListener.renderFace.getEveryChange(({ value }) => { const { x, y, z, sideNumber, tag } = value; if (tag === 'internal cascade') { // Caution: this is request**Post**AnimationFrame, not @@ -57,7 +86,7 @@ export default class OffscreenSkyboxWorker extends ManagedWorker { } }); - this.addWorkerListener('testHeavyPayload', ({ error, value }) => { + this.workerListener.testHeavyPayload.getEveryChange(({ error, value }) => { console.log('testHeavyPayload:', value.length, 'KB transferred. Error:', error); }); }