Skip to content

Commit

Permalink
use localstorage for wasm imgui persistency instead of indexeddb
Browse files Browse the repository at this point in the history
  • Loading branch information
floooh committed Dec 12, 2024
1 parent a65a2da commit 5a84734
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 190 deletions.
49 changes: 8 additions & 41 deletions src/ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,6 @@ static const ui_tracelog_column_t ui_tracelog_columns[UI_TRACELOG_NUM_COLUMNS] =

static struct {
bool valid;
bool ini_save_in_progress;
bool ini_load_in_progress;
bool ini_load_completed;
ui_memedit_t memedit;
ui_memedit_t memedit_integrated;
#if defined(CHIP_Z80)
Expand Down Expand Up @@ -414,10 +411,7 @@ void ui_init() {
md_conf.linkIcon = ICON_FA_LINK;

ui.menu.layer_slider = MAX_LAYERS;

// start load the persistent Dear ImGui ini settings
ui_load_settings();

ui.valid = true;
}

Expand Down Expand Up @@ -647,9 +641,6 @@ bool ui_handle_input(const sapp_event* ev) {
void ui_frame() {
assert(ui.valid);
ui.link_hovered = false;
if (!ui.ini_load_completed) {
return;
}
simgui_new_frame({ sapp_width(), sapp_height(), sapp_frame_duration(), sapp_dpi_scale() });
ui_handle_docking();
ui_menu();
Expand Down Expand Up @@ -679,9 +670,6 @@ void ui_frame() {

void ui_draw() {
assert(ui.valid);
if (!ui.ini_load_completed) {
return;
}
sgimgui_draw(&ui.sgimgui);
simgui_render();
}
Expand Down Expand Up @@ -2496,38 +2484,17 @@ static const char* ui_save_key(void) {
#endif
}

static void ui_save_completed(bool succeeded, void* userdata) {
(void)succeeded; (void)userdata;
ImGui::GetIO().WantSaveIniSettings = false;
ui.ini_save_in_progress = false;
}

static void ui_handle_save_settings(void) {
if (ImGui::GetIO().WantSaveIniSettings && !ui.ini_save_in_progress) {
ui.ini_save_in_progress = true;
util_save_t save = {};
save.key = ui_save_key();
save.bytes = ImGui::SaveIniSettingsToMemory(&save.num_bytes);
save.completed = ui_save_completed;
save.userdata = 0;
util_save_async(save);
}
}

static void ui_load_completed(bool succeeded, const void* data, uint32_t num_bytes, void* userdata) {
(void)userdata;
if (succeeded && data && num_bytes > 0) {
ImGui::LoadIniSettingsFromMemory((const char*)data, num_bytes);
if (ImGui::GetIO().WantSaveIniSettings) {
ImGui::GetIO().WantSaveIniSettings = false;
util_save_string(ui_save_key(), ImGui::SaveIniSettingsToMemory());
}
ui.ini_load_in_progress = false;
ui.ini_load_completed = true;
}

static void ui_load_settings(void) {
util_load_t load = {};
load.key = ui_save_key();
load.completed = ui_load_completed;
load.userdata = 0;
util_load_async(load);
ui.ini_load_in_progress = true;
const char* payload = util_load_string(ui_save_key());
if (payload) {
ImGui::LoadIniSettingsFromMemory(payload);
util_free_loaded_string(payload);
}
}
157 changes: 27 additions & 130 deletions src/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
#endif
#include "ui_asm.h"
#include "util.h"
#include <stdlib.h> // free()

static struct {
bool valid;
bool is_osx;
} util;

#if defined(__EMSCRIPTEN__)
EM_JS_DEPS(v6502r, "$ccall");
EM_JS_DEPS(v6502r, "$ccall,$UTF8ToString,$stringToNewUTF8");

EM_JS(void, emsc_js_init, (void), {
Module['emsc_js_onload'] = emsc_js_onload;
Expand Down Expand Up @@ -108,126 +109,21 @@ EMSCRIPTEN_KEEPALIVE int util_emsc_loadfile(const char* name, uint8_t* data, int
return 1;
}

EM_JS(void, emsc_js_save_async, (const char* c_key, const void* bytes, uint32_t num_bytes, util_save_callback_t completed, void* userdata), {
console.log('emsc_js_save_async called');
const db_name = UTF8ToString(c_key);
const db_store_name = 'store';
let open_request;
try {
open_request = window.indexedDB.open(db_name);
} catch (err) {
console.warn('emsc_js_save_async: failed to open IndexedDB with: ', err);
_util_emsc_save_callback(false, completed, userdata);
return;
}
open_request.onupgradeneeded = () => {
console.log('emsc_js_save_async: onupgradeneeded');
const db = open_request.result;
db.createObjectStore(db_store_name);
};
open_request.onsuccess = () => {
console.log('emsc_js_save_async: onsuccess');
const db = open_request.result;
let transaction;
try {
transaction = db.transaction([db_store_name], 'readwrite');
} catch (err) {
console.warn('emsc_js_save_async: db.transaction failed with: ', err);
_util_emsc_save_callback(false, completed, userdata);
return;
}
const file = transaction.objectStore(db_store_name);
const blob = HEAPU8.subarray(bytes, bytes + num_bytes);
const put_request = file.put(blob, 'imgui.ini');
put_request.onsuccess = () => {
console.log('emsc_js_save_async: put success');
_util_emsc_save_callback(true, completed, userdata);
};
put_request.onerror = () => {
console.warn('emsc_js_save_async: put failure');
_util_emsc_save_callback(false, completed, userdata);
};
transaction.onerror = () => {
console.warn('emsc_js_save_async: transaction failure');
_util_emsc_save_callback(false, completed, userdata);
};
};
open_request.onerror = () => {
console.warn('emsc_js_save_async: open request failure');
_util_emsc_save_callback(false, completed, userdata);
};
EM_JS(void, emsc_js_save_string, (const char* c_key, const char* c_payload), {
const key = UTF8ToString(c_key);
const payload = UTF8ToString(c_payload);
window.localStorage.setItem(key, payload);
});

EMSCRIPTEN_KEEPALIVE void util_emsc_save_callback(bool succeeded, util_save_callback_t completed, void* userdata) {
completed(succeeded, userdata);
}

EM_JS(void, emsc_js_load_async, (const char* c_key, util_load_callback_t completed, void* userdata), {
console.log('emsc_js_load_async called');
const db_name = UTF8ToString(c_key);
const db_store_name = 'store';
let open_request;
try {
open_request = window.indexedDB.open(db_name);
} catch (err) {
console.warn('emsc_js_load_async: failed to open IndexedDB with: ', err);
_util_emsc_load_callback(false, completed, 0, 0, userdata);
return;
}
open_request.onupgradeneeded = () => {
console.log('emsc_js_load_async: onupgradeneeded');
const db = open_request.result;
db.createObjectStore(db_store_name);
};
open_request.onsuccess = () => {
console.log('emsc_js_load_async: open_request onsuccess');
let db = open_request.result;
let transaction;
try {
transaction = db.transaction([db_store_name], 'readwrite');
} catch (err) {
console.warn('emsc_js_load_async: db.transaction failed with: ', err);
_util_emsc_load_callback(false, completed, 0, 0, userdata);
return;
}
const file = transaction.objectStore(db_store_name);
const get_request = file.get('imgui.ini');
get_request.onsuccess = () => {
console.log('emsc_js_load_async: get_request onsuccess');
if (get_request.result !== undefined) {
const num_bytes = get_request.result.length;
console.log(`emsc_js_load_async: successfully loaded ${num_bytes} bytes`);
const ptr = _util_emsc_alloc(num_bytes);
HEAPU8.set(get_request.result, ptr);
_util_emsc_load_callback(true, completed, ptr, num_bytes, userdata);
} else {
console.warn('emsc_js_load_async: get_request.result is undefined');
_util_emsc_load_callback(false, completed, 0, 0, userdata);
}
};
get_request.onerror = () => {
console.warn('emsc_js_load_async: get_request onerror');
_util_emsc_load_callback(false, completed, 0, 0, userdata);
};
transaction.onerror = () => {
console.warn('emsc_js_load_async: transaction onerror');
_util_emsc_load_callback(false, completed, 0, 0, userdata);
};
};
open_request.onerror = () => {
console.log('emsc_js_load_async: open_request onerror');
_util_emsc_load_callback(false, completed, 0, 0, userdata);
EM_JS(const char*, emsc_js_load_string, (const char* c_key), {
const key = UTF8ToString(c_key);
const payload = window.localStorage.getItem(key);
if (payload) {
return stringToNewUTF8(payload);
} else {
return 0;
}
});

EMSCRIPTEN_KEEPALIVE void* util_emsc_alloc(uint32_t num_bytes) {
return malloc(num_bytes);
}

EMSCRIPTEN_KEEPALIVE void util_emsc_load_callback(bool succeeded, util_load_callback_t completed, void* bytes, uint32_t num_bytes, void* userdata) {
completed(succeeded, bytes, num_bytes, userdata);
free(bytes);
}
#endif // EMSCRIPTEN

void util_init(void) {
Expand Down Expand Up @@ -287,24 +183,25 @@ bool util_is_osx(void) {
return util.is_osx;
}

void util_save_async(util_save_t args) {
assert(args.key);
assert(args.bytes);
assert(args.num_bytes > 0);
assert(args.completed);
void util_save_string(const char* key, const char* payload) {
assert(key && payload);
#if defined(__EMSCRIPTEN__)
emsc_js_save_async(args.key, args.bytes, args.num_bytes, args.completed, args.userdata);
#else
args.completed(false, args.userdata);
emsc_js_save_string(key, payload);
#endif
}

void util_load_async(util_load_t args) {
assert(args.key);
assert(args.completed);
// NOTE: may return 0
const char* util_load_string(const char* key) {
assert(key);
#if defined(__EMSCRIPTEN__)
emsc_js_load_async(args.key, args.completed, args.userdata);
return emsc_js_load_string(key);
#else
args.completed(false, 0, 0, args.userdata);
return 0;
#endif
}

void util_free_loaded_string(const char* payload) {
if (payload) {
free((void*)payload);
}
}
22 changes: 3 additions & 19 deletions src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,16 @@
extern "C" {
#endif

typedef void (*util_load_callback_t)(bool succeeded, const void* data, uint32_t num_bytes, void* userdata);
typedef void (*util_save_callback_t)(bool succeeded, void* userdata);

typedef struct {
const char* key;
util_load_callback_t completed;
void* userdata;
} util_load_t;

typedef struct {
const char* key;
const void* bytes;
size_t num_bytes;
util_save_callback_t completed;
void* userdata;
} util_save_t;

void util_init(void);
void util_shutdown(void);
void util_html5_download_string(const char* filename, const char* content);
void util_html5_download_binary(const char* filename, range_t bytes);
void util_html5_load(void);
void util_html5_open_link(const char* url);
bool util_is_osx(void);
void util_save_async(util_save_t args);
void util_load_async(util_load_t args);
void util_save_string(const char* key, const char* payload);
const char* util_load_string(const char* key);
void util_free_loaded_string(const char* payload);

#if defined(__cplusplus)
} // extern "C"
Expand Down

0 comments on commit 5a84734

Please sign in to comment.