Skip to content

Commit

Permalink
Refactor: Reorder the renderer setup code so that WebAudio works
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rdw-software committed Nov 17, 2021
1 parent 64cd249 commit f3949d0
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 169 deletions.
14 changes: 4 additions & 10 deletions Core/APIs/C_Rendering.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const C_Rendering = {
fogColor: Color.GREY,
meshes: [],
lightSources: [],
renderCanvas: window["WorldFrame"],
renderer: new Renderer(window["WorldFrame"]),
};

C_Rendering.loadScene = function () {};
Expand All @@ -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
Expand Down
27 changes: 24 additions & 3 deletions Core/Initialization/start-render-thread.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,45 @@
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();

const windowTitle = format("%s (%s)", WebClient.titleString, WebClient.versionString);
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");
}
31 changes: 0 additions & 31 deletions Core/WebClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -77,37 +67,16 @@ 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
DEBUG(format("SCRIPT_EXECUTION_FINISHED triggered for URL %s", URL));
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;
Expand Down
Loading

0 comments on commit f3949d0

Please sign in to comment.