From 26f17c33a503a09966c770d9b69a96e1f3914ea6 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 24 Jul 2024 19:56:48 +0200 Subject: [PATCH 1/2] [Web] Add workaround for missing export in threaded builds The offending symbol gets stripped away by wasm-dce but it's used on the JavaScript side and causes and undefined symbol which also causes the closure compiler to throw an error. --- platform/web/detect.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/web/detect.py b/platform/web/detect.py index 79485ea28a10..bf75c2f9fcf3 100644 --- a/platform/web/detect.py +++ b/platform/web/detect.py @@ -227,6 +227,11 @@ def configure(env: "SConsEnvironment"): env.Append(LINKFLAGS=["-sDEFAULT_PTHREAD_STACK_SIZE=%sKB" % env["default_pthread_stack_size"]]) env.Append(LINKFLAGS=["-sPTHREAD_POOL_SIZE=8"]) env.Append(LINKFLAGS=["-sWASM_MEM_MAX=2048MB"]) + if not env["dlink_enabled"]: + # Workaround https://github.com/emscripten-core/emscripten/issues/21844#issuecomment-2116936414. + # Not needed (and potentially dangerous) when dlink_enabled=yes, since we set EXPORT_ALL=1 in that case. + env.Append(LINKFLAGS=["-sEXPORTED_FUNCTIONS=['__emscripten_thread_crashed','_main']"]) + elif env["proxy_to_pthread"]: print_warning('"threads=no" support requires "proxy_to_pthread=no", disabling proxy to pthread.') env["proxy_to_pthread"] = False From 96feb924e8f43cc1c48870e82373541bb703f308 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Fri, 26 Jul 2024 11:52:36 +0200 Subject: [PATCH 2/2] [Web] Enable the closure compiler in CI Also fixes some JSDoc annotations in GodotAudio --- .github/workflows/web_builds.yml | 2 +- platform/web/js/libs/library_godot_audio.js | 21 ++++++++------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/.github/workflows/web_builds.yml b/.github/workflows/web_builds.yml index de8339bf1b09..add5fa815403 100644 --- a/.github/workflows/web_builds.yml +++ b/.github/workflows/web_builds.yml @@ -6,7 +6,7 @@ on: env: # Used for the cache key. Add version suffix to force clean build. GODOT_BASE_BRANCH: master - SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no + SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no use_closure_compiler=yes EM_VERSION: 3.1.59 EM_CACHE_FOLDER: "emsdk-cache" diff --git a/platform/web/js/libs/library_godot_audio.js b/platform/web/js/libs/library_godot_audio.js index 0b16b07261b2..66d0d3d79dc9 100644 --- a/platform/web/js/libs/library_godot_audio.js +++ b/platform/web/js/libs/library_godot_audio.js @@ -77,7 +77,7 @@ class Sample { * Creates a `Sample` based on the params. Will register it to the * `GodotAudio.samples` registry. * @param {SampleParams} params Base params - * @param {SampleOptions} [options={}] Optional params + * @param {SampleOptions} [options={{}}] Optional params * @returns {Sample} */ static create(params, options = {}) { @@ -98,8 +98,7 @@ class Sample { /** * `Sample` constructor. * @param {SampleParams} params Base params - * @param {SampleOptions} [options={}] Optional params - * @constructor + * @param {SampleOptions} [options={{}}] Optional params */ constructor(params, options = {}) { /** @type {string} */ @@ -154,7 +153,7 @@ class Sample { if (this._audioBuffer == null) { throw new Error('couldn\'t duplicate a null audioBuffer'); } - /** @type {Float32Array[]} */ + /** @type {Array} */ const channels = new Array(this._audioBuffer.numberOfChannels); for (let i = 0; i < this._audioBuffer.numberOfChannels; i++) { const channel = new Float32Array(this._audioBuffer.getChannelData(i)); @@ -189,7 +188,6 @@ class SampleNodeBus { /** * `SampleNodeBus` constructor. * @param {Bus} bus The bus related to the new `SampleNodeBus`. - * @constructor */ constructor(bus) { const NUMBER_OF_WEB_CHANNELS = 6; @@ -413,8 +411,7 @@ class SampleNode { /** * @param {SampleNodeParams} params Base params - * @param {SampleNodeOptions} [options={}] Optional params - * @constructor + * @param {SampleNodeOptions} [options={{}}] Optional params */ constructor(params, options = {}) { /** @type {string} */ @@ -441,7 +438,7 @@ class SampleNode { this._sampleNodeBuses = new Map(); /** @type {AudioBufferSourceNode | null} */ this._source = GodotAudio.ctx.createBufferSource(); - /** @type {AudioBufferSourceNode["onended"]} */ + this._onended = null; this.setPlaybackRate(options.playbackRate ?? 44100); @@ -558,7 +555,7 @@ class SampleNode { /** * Sets the volumes of the `SampleNode` for each buses passed in parameters. - * @param {Bus[]} buses + * @param {Array} buses * @param {Float32Array} volumes */ setVolumes(buses, volumes) { @@ -818,7 +815,6 @@ class Bus { /** * `Bus` constructor. - * @constructor */ constructor() { /** @type {Set} */ @@ -985,7 +981,6 @@ class Bus { GodotAudio.buses = GodotAudio.buses.filter((v) => v !== this); } - /** @type {Bus["prototype"]["_syncSampleNodes"]} */ _syncSampleNodes() { const sampleNodes = Array.from(this._sampleNodes); for (let i = 0; i < sampleNodes.length; i++) { @@ -1086,7 +1081,7 @@ const _GodotAudio = { // `Bus` class /** * Registry of `Bus`es. - * @type {Bus[]} + * @type {Array} */ buses: null, /** @@ -1309,7 +1304,7 @@ const _GodotAudio = { /** * Triggered when a sample node volumes need to be updated. * @param {string} playbackObjectId Id of the sample playback - * @param {number[]} busIndexes Indexes of the buses that need to be updated + * @param {Array} busIndexes Indexes of the buses that need to be updated * @param {Float32Array} volumes Array of the volumes * @returns {void} */