Skip to content

Commit

Permalink
WASM now uses IndexedDB and persistence (#1869)
Browse files Browse the repository at this point in the history
Co-authored-by: Semphris <[email protected]>
  • Loading branch information
Semphriss and Semphris authored Nov 6, 2021
1 parent dca76f5 commit dddec70
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 14 deletions.
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ if(EMSCRIPTEN)
if(CMAKE_BUILD_TYPE MATCHES Debug)
set(USE_FLAGS "${USE_FLAGS} -fsanitize=undefined -sSAFE_HEAP=1 -sASSERTIONS=1 -sDEMANGLE_SUPPORT=1")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${USE_FLAGS} -sERROR_ON_UNDEFINED_SYMBOLS=0")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${USE_FLAGS} -sERROR_ON_UNDEFINED_SYMBOLS=0")
set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} ${USE_FLAGS} -sFULL_ES2=1 -sERROR_ON_UNDEFINED_SYMBOLS=0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${USE_FLAGS} -sERROR_ON_UNDEFINED_SYMBOLS=0 -lidbfs.js")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${USE_FLAGS} -sERROR_ON_UNDEFINED_SYMBOLS=0 -lidbfs.js")
set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} ${USE_FLAGS} -sFULL_ES2=1 -sERROR_ON_UNDEFINED_SYMBOLS=0 -lidbfs.js")
endif()

# TODO: Add " OR ANDROID OR IOS" to this
Expand Down
61 changes: 51 additions & 10 deletions mk/emscripten/template.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,28 @@
document.getElementById("output").style.display = "none";
}

var data_persistent = false;
if (navigator.storage && navigator.storage.persist) {
navigator.storage.persist().then((persists) => {
if (!persists) {
alert("Your browser denied persistent storage. That means your data could be cleared next time you open the game.\n\nIf you just received a prompt asking you if you want data to persist, you may ignore this message.\n\nChrome and Chromium-based browsers (Edge, Opera, Brave...) will not ask the user; instead, the browser will choose by itself based on if it considers the site important. It detemines which sites are important based on certain data, such as how often you visit the site, what you do, etc. If you want to choose whether or not to save your progress, you may use Firefox instead.\n\nYou can read more at https://web.dev/persistent-storage/#how-is-permission-granted\n\nIf you want to choose to save your data, please use Firefox.");
} else {
data_persistent = true;
}
});
} else {
alert("Your browser does not support persistent storage!\n\nYour browser may delete your progress anytime. Make sure to backup your important files!");
}

window.supertux2_ispersistent = function() {
return data_persistent ? 1 : 0;
}

var statusElement = document.getElementById("status"),
progressElement = document.getElementById("progress"),
progressDescElement = document.getElementById("progress_desc"),
overlayElement = document.getElementById("overlay"),
spinnerElement = document.getElementById("spinner");
progressElement = document.getElementById("progress"),
progressDescElement = document.getElementById("progress_desc"),
overlayElement = document.getElementById("overlay"),
spinnerElement = document.getElementById("spinner");

var lastUpdate = Date.now() / 1000;
var lastStep = 0;
Expand Down Expand Up @@ -349,26 +366,33 @@
const root = "/home/web_user/.local/share/supertux2/";

window.supertux_loadFiles = function() {
// Loading the config file from localStorage is needed, even though the
// rest of the files are stored in IndexedDB, managed by Emscripten.
// Check the supertux_saveFiles function below for details.
for (var key of Object.keys(localStorage)) {
if (key !== "config" && !key.match("^profile[0-9]+/"))
if (key !== "supertux2_config" /*&& !key.match("^profile[0-9]+/")*/)
continue;

if (key.indexOf("/") !== -1) {
keyfilename = key.replace(/^supertux2_/, "");

if (keyfilename.indexOf("/") !== -1) {
try {
FS.mkdir(root + key.substr(0, key.indexOf("/")));
FS.mkdir(root + keyfilename.substr(0, keyfilename.indexOf("/")));
} catch {
// Folder probably already exists
}
}
FS.writeFile(root + key, localStorage.getItem(key));
FS.writeFile(root + keyfilename, localStorage.getItem(key));
}
}

window.supertux_saveFiles = function() {

FS.syncfs((err) => { console.log(err); });

function save(file) {
try {
localStorage.setItem(file, FS.readFile(root + file, { encoding: "utf8" }));
localStorage.setItem("supertux2_" + file, FS.readFile(root + file, { encoding: "utf8" }));
return true;
} catch(e) {
console.error(e);
Expand All @@ -377,8 +401,13 @@
}
}

// IndexedDB can't save fast enough to be called when the window is closed,
// so save the config file in localStorage just in case it wasn't flushed
// to disk
save("config");

// Other files use IndexedDB instead of localStorage
/*
var data_folder = FS.lookupPath(root);

for (var folder_name in data_folder.node.contents) {
Expand All @@ -389,7 +418,7 @@
save(folder_name + "/" + file_name);
}
}

*/
}

window.supertux_download = function(path) {
Expand Down Expand Up @@ -477,6 +506,18 @@
}
});

var saving = false;
window.supertux2_syncfs = function() {
if (saving) return;
saving = true;
FS.syncfs((err) => {
if (err)
console.log(err);

saving = false;
});
}

window.onresize = tryResize;
window.onunload = () => {
Module.ccall("save_config", "void", [], []);
Expand Down
11 changes: 10 additions & 1 deletion src/editor/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
#include <limits>
#include <physfs.h>

#ifdef EMSCRIPTEN
#include <emscripten.h>
#include <emscripten/html5.h>
#endif

#include "audio/sound_manager.hpp"
#include "control/input_manager.hpp"
#include "editor/button_widget.hpp"
Expand Down Expand Up @@ -542,7 +547,11 @@ Editor::quit_editor()
Tile::draw_editor_images = false;
ScreenManager::current()->pop_screen();
#ifdef __EMSCRIPTEN__
Dialog::show_message(_("Don't forget that your levels and assets\naren't saved between sessions!\nIf you want to keep your levels, download them\nfrom the \"Manage Assets\" menu."));
int persistent = EM_ASM_INT({
return supertux2_ispersistent();
});
if (!persistent)
Dialog::show_message(_("Don't forget that your levels and assets\naren't saved between sessions!\nIf you want to keep your levels, download them\nfrom the \"Manage Assets\" menu."));
#endif
};

Expand Down
11 changes: 11 additions & 0 deletions src/supertux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,23 @@ if (FileSystem::is_directory(olduserdir)) {
}
#endif

#ifdef EMSCRIPTEN
userdir = "/home/web_user/.local/share/supertux2/";
#endif

if (!FileSystem::is_directory(userdir))
{
FileSystem::mkdir(userdir);
log_info << "Created SuperTux userdir: " << userdir << std::endl;
}

#ifdef EMSCRIPTEN
EM_ASM({
FS.mount(IDBFS, {}, "/home/web_user/.local/share/supertux2/");
FS.syncfs(true, (err) => { console.log(err); });
});
#endif

if (!PHYSFS_setWriteDir(userdir.c_str()))
{
std::ostringstream msg;
Expand Down
6 changes: 6 additions & 0 deletions src/supertux/screen_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,12 @@ void ScreenManager::loop_iter()
SoundManager::current()->update();

handle_screen_switch();

#ifdef EMSCRIPTEN
EM_ASM({
supertux2_syncfs();
});
#endif
}

#ifdef __EMSCRIPTEN__
Expand Down

0 comments on commit dddec70

Please sign in to comment.