aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/platforms/emscripten.cmake1
-rw-r--r--emccpost.js1
-rw-r--r--emccpre.js45
-rwxr-xr-xhtml/jspage.pl4
4 files changed, 49 insertions, 2 deletions
diff --git a/cmake/platforms/emscripten.cmake b/cmake/platforms/emscripten.cmake
index bbb0897..c7e55fe 100644
--- a/cmake/platforms/emscripten.cmake
+++ b/cmake/platforms/emscripten.cmake
@@ -43,6 +43,7 @@ endfunction()
function(set_platform_puzzle_target_properties NAME TARGET)
em_link_pre_js(${TARGET} ${CMAKE_SOURCE_DIR}/emccpre.js)
em_link_js_library(${TARGET} ${CMAKE_SOURCE_DIR}/emcclib.js)
+ em_link_post_js(${TARGET} ${CMAKE_SOURCE_DIR}/emccpost.js)
endfunction()
function(build_platform_extras)
diff --git a/emccpost.js b/emccpost.js
new file mode 100644
index 0000000..b12b0af
--- /dev/null
+++ b/emccpost.js
@@ -0,0 +1 @@
+initPuzzle();
diff --git a/emccpre.js b/emccpre.js
index 1579ead..310c465 100644
--- a/emccpre.js
+++ b/emccpre.js
@@ -35,6 +35,51 @@ var update_xmin, update_xmax, update_ymin, update_ymax;
// our own init stuff first), and that when main() returns nothing
// will get cleaned up so we remain able to call the puzzle's various
// callbacks.
+//
+//
+// Page loading order:
+//
+// 1. The browser starts reading *.html (which comes from jspage.pl)
+// 2. It finds the <script> tag. This is marked defer, so the
+// browser will start fetching and parsing it, but not execute it
+// until the page has loaded.
+//
+// Now the browser is loading *.html and *.js in parallel. The
+// html is rendered as we go, and the js is deferred.
+//
+// 3. The HTML finishes loading. The browser is about to fire the
+// `DOMContentLoaded` event (ie `onload`) but before that, it
+// actually runs the deferred JS. THis consists of
+//
+// (i) emccpre.js (this file). This sets up various JS variables
+// including the emscripten Module object.
+//
+// (ii) emscripten's JS. This starts the WASM loading.
+//
+// (iii) emccpost.js. This calls initPuzzle, which is defined here
+// in this file. initPuzzle:
+//
+// (a) finds various DOM elements and bind them to variables,
+// which depend on the HTML having loaded (it has).
+//
+// (b) makes various `cwrap` calls into the emscripten module to
+// set up hooks; this depends on the emscripten JS having been
+// loaded (it has).
+//
+// (c) Makes the call to emscripten's
+// Module.onRuntimeInitialized, which sets the callback for when
+// the WASM has finished loading and initialising. This has to
+// come before the WASM finishes loading, or we'll miss the
+// callback. We are executing synchronously here in the same JS
+// file as started the WASM loading, so that is guaranteed.
+//
+// When this JS execution is complete, the browser fires the `onload`
+// event. This is ignored. It continues loading the WASM.
+//
+// 4. The WASM loading and initialisation completes. The
+// onRuntimeInitialised callback calls into emscripten-generated
+// WASM to call the C `main`, to actually start the puzzle.
+
var Module = {
'noInitialRun': true,
'noExitRuntime': true
diff --git a/html/jspage.pl b/html/jspage.pl
index 2101030..70d7209 100755
--- a/html/jspage.pl
+++ b/html/jspage.pl
@@ -73,7 +73,7 @@ EOF
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ASCII" />
<title>${puzzlename}, ${unfinishedtitlefragment}from Simon Tatham's Portable Puzzle Collection</title>
-<script type="text/javascript" src="${jspath}${filename}.js"></script>
+<script defer type="text/javascript" src="${jspath}${filename}.js"></script>
<style class="text/css">
/* Margins and centring on the top-level div for the game menu */
#gamemenu { margin-top: 0; margin-bottom: 0.5em; text-align: center }
@@ -217,7 +217,7 @@ EOF
}
</style>
</head>
-<body onLoad="initPuzzle();">
+<body>
<h1 align=center>${puzzlename}</h1>
${unfinishedheading}
<h2 align=center>from Simon Tatham's Portable Puzzle Collection</h2>