From f3949d0065729460b805496284af8b66a0f7bc3e Mon Sep 17 00:00:00 2001 From: RDW Date: Wed, 17 Nov 2021 17:26:22 +0100 Subject: [PATCH] Refactor: Reorder the renderer setup code so that WebAudio works Since BJS provides the facilities for both WebGL and WebAudio, the C_WebAudio API relies on it being available when it is loaded. This wasn't the case with the original design, since the UI is loaded asynchronously and only then was the render loop started. Since there's no reason or even benefit to doing so, this should change the render loop to start immediately and allow the WebAudio initialization to create its SoundTracks via BJS' API. --- Core/APIs/C_Rendering.js | 14 +- Core/Initialization/start-render-thread.js | 27 ++- Core/WebClient.js | 31 --- index.html | 266 +++++++++++---------- 4 files changed, 169 insertions(+), 169 deletions(-) diff --git a/Core/APIs/C_Rendering.js b/Core/APIs/C_Rendering.js index 56e36ec..5456c0e 100644 --- a/Core/APIs/C_Rendering.js +++ b/Core/APIs/C_Rendering.js @@ -13,6 +13,8 @@ const C_Rendering = { fogColor: Color.GREY, meshes: [], lightSources: [], + renderCanvas: window["WorldFrame"], + renderer: new Renderer(window["WorldFrame"]), }; C_Rendering.loadScene = function () {}; @@ -38,18 +40,10 @@ C_Rendering.isSwitchingScenes = function () {}; // Creates a new renderer for the WorldFrame canvas and immediately renders the active scene. // Note: Only one renderer/scene/canvas is currently supported. C_Rendering.startRenderLoop = function () { - if (this.renderer) { - NOTICE("Failed to start render loop (renderer already exists and only one scene is currently supported)"); - return; - } - const renderCanvas = window["WorldFrame"]; - const renderer = new Renderer(renderCanvas); - this.renderer = renderer; - function onCurrentFrameFinishedRendering() { - const deltaTime = renderer.deltaTime; + const deltaTime = C_Rendering.renderer.deltaTime; C_EventSystem.triggerEvent("RENDER_LOOP_UPDATE", deltaTime); - renderer.renderNextFrame(); + C_Rendering.renderer.renderNextFrame(); } this.switchScene(); this.createDefaultLightSource(); // for easier debugging diff --git a/Core/Initialization/start-render-thread.js b/Core/Initialization/start-render-thread.js index e79e83e..98e4957 100644 --- a/Core/Initialization/start-render-thread.js +++ b/Core/Initialization/start-render-thread.js @@ -1,19 +1,25 @@ var format = require("util").format; -// Shorthand because I'm lazy (must be set after the localization tables have been read) -let L = {}; function StartWebClient() { C_Profiling.startTimer("StartWebClient"); C_Settings.loadSettingsCache(); + // WebAudio Setup: Requires settings to be loaded + // We can do this here as long as the C_Decoding API was loaded first + C_Decoding.addDecoder(new BuiltinAudioDecoder()); + // Ensure stored settings are applied to any new audio source right away + C_WebAudio.setMusicVolume(C_Settings.getValue("musicVolume")); + C_WebAudio.setEffectsVolume(C_Settings.getValue("sfxVolume")); + C_WebAudio.setAmbienceVolume(C_Settings.getValue("ambienceVolume")); + C_WebAudio.setGlobalVolume(C_Settings.getValue("globalVolume")); + WebClient.initializeLocalizationTables(); L = C_Locales.getLocalizationTable(C_Settings.getValue("activeLocale")); WebClient.setWindowTitle(L["Loading..."]); C_Macro.restoreMacroCache(); // Needs to be done before addons are loaded, as they may want to interact with the cache? - WebClient.createUserInterface(); C_Addons.loadAddonCache(); C_Addons.loadEnabledAddons(); @@ -21,4 +27,19 @@ function StartWebClient() { WebClient.setWindowTitle(windowTitle); C_EventSystem.registerEvent("SCRIPT_EXECUTION_FINISHED", "WebClient", WebClient.onScriptExecutionFinished); + + window.onbeforeunload = function () { + C_EventSystem.triggerEvent("APPLICATION_SHUTDOWN"); + }; + + C_EventSystem.registerEvent("APPLICATION_SHUTDOWN", "WebClient", function () { + DEBUG("Application shutting down; performing cleanup tasks"); + C_Addons.saveAddonCache(); + C_Macro.saveMacroCache(); + C_Settings.saveSettingsCache(); + }); + + WebClient.run(); + + C_Profiling.endTimer("StartWebClient"); } diff --git a/Core/WebClient.js b/Core/WebClient.js index 1345599..00a972a 100644 --- a/Core/WebClient.js +++ b/Core/WebClient.js @@ -5,16 +5,6 @@ class WebClient { static titleString = "Revival WebClient"; static versionString = "v" + require("./package.json").version; - static defaultFrames = [ - "ViewportContainer", - "WorldFrame", - "UIParent", - "FpsCounterFrame", - "KeyboardInputFrame", - "GameMenuFrame", - "AddonOptionsFrame", - "SystemOptionsFrame", - ]; static settings = {}; static nextAvailableGUID = 1; // Sets the window title of the application window @@ -77,13 +67,6 @@ class WebClient { DEBUG("Loading application manifest from " + filePath); this.metadata = C_FileSystem.readJSON(filePath); } - // Load basic interface - static createUserInterface() { - for (const fileName of this.defaultFrames) { - DEBUG(format("Creating default interface component %s", fileName)); - this.loadScript(format(WEBCLIENT_INTERFACE_DIR + "/Frames/" + fileName + ".js")); - } - } // Defer render loop until the WorldFrame (canvas) exists static onScriptExecutionFinished(event, URL) { // Kinda ugly, but alas. It's better than entering callback hell and sync loading doesn't work at all for this @@ -91,23 +74,9 @@ class WebClient { if (URL !== WEBCLIENT_INTERFACE_DIR + "/Frames/WorldFrame.js") return; // process.on("exit", function () { - window.onbeforeunload = function () { - C_EventSystem.triggerEvent("APPLICATION_SHUTDOWN"); - }; - - C_EventSystem.registerEvent("APPLICATION_SHUTDOWN", "WebClient", function () { - DEBUG("Application shutting down; performing cleanup tasks"); - C_Addons.saveAddonCache(); - C_Macro.saveMacroCache(); - C_Settings.saveSettingsCache(); - }); - - WebClient.run(); } // Starts the client application static run() { - C_Profiling.endTimer("StartWebClient"); - function processMessageQueue() { let numProcessedMessages = 0; let nextMessage = null; diff --git a/index.html b/index.html index ec3cf8f..211befd 100644 --- a/index.html +++ b/index.html @@ -9,143 +9,159 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +