Fix not saving to IndexedDB

This commit is contained in:
UnknownShadow200 2021-06-08 08:15:04 +10:00
parent 7bf24f4016
commit edd15233ca
2 changed files with 56 additions and 57 deletions

View File

@ -96,6 +96,7 @@ cc_uint64 Stopwatch_Measure(void) {
/*########################################################################################################################* /*########################################################################################################################*
*-----------------------------------------------------Directory/File------------------------------------------------------* *-----------------------------------------------------Directory/File------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
extern void interop_InitFilesystem(void);
extern int interop_DirectoryCreate(const char* path, int perms); extern int interop_DirectoryCreate(const char* path, int perms);
cc_result Directory_Create(const cc_string* path) { cc_result Directory_Create(const cc_string* path) {
char str[NATIVE_STR_LEN]; char str[NATIVE_STR_LEN];
@ -427,19 +428,11 @@ EMSCRIPTEN_KEEPALIVE void Platform_LogError(const char* msg) {
} }
extern void interop_InitModule(void); extern void interop_InitModule(void);
extern void interop_GetIndexedDBError(char* buffer);
void Platform_Init(void) { void Platform_Init(void) {
char tmp[64+1] = { 0 }; interop_InitFilesystem();
interop_InitModule(); interop_InitModule();
interop_InitSockets(); interop_InitSockets();
/* Check if an error occurred when pre-loading IndexedDB */
interop_GetIndexedDBError(tmp);
if (!tmp[0]) return;
Chat_Add1("&cError preloading IndexedDB: %c", tmp);
Chat_AddRaw("&cPreviously saved settings/maps will be lost");
/* NOTE: You must pre-load IndexedDB before main() */ /* NOTE: You must pre-load IndexedDB before main() */
/* (because pre-loading only works asynchronously) */ /* (because pre-loading only works asynchronously) */
/* If you don't, you'll get errors later trying to sync local to remote */ /* If you don't, you'll get errors later trying to sync local to remote */

View File

@ -126,52 +126,58 @@ mergeInto(LibraryManager.library, {
//######################################################################################################################## //########################################################################################################################
//--------------------------------------------------------Filesystem------------------------------------------------------ //--------------------------------------------------------Filesystem------------------------------------------------------
//######################################################################################################################## //########################################################################################################################
interop_GetIndexedDBError: function(buffer) { interop_InitFilesystem: function(buffer) {
if (window.cc_idbErr) stringToUTF8(window.cc_idbErr, buffer, 64); // if interop_SaveNode is directly defined as a function, it is wrongly optimised
}, // out when compilingas the function is not directly referenced by any C code
interop_SaveNode: function (path) { Module.saveNode = function(path) {
var callback = function(err) { var callback = function(err) {
if (!err) return; if (!err) return;
console.log(err); console.log(err);
ccall('Platform_LogError', 'void', ['string'], ['&cError saving ' + path]); ccall('Platform_LogError', 'void', ['string'], ['&cError saving ' + path]);
ccall('Platform_LogError', 'void', ['string'], [' &c' + err]); ccall('Platform_LogError', 'void', ['string'], [' &c' + err]);
}; };
var stat, node, entry;
try {
var lookup = FS.lookupPath(path);
path = lookup.path;
node = lookup.node;
stat = node.node_ops.getattr(node);
} catch (err) {
return callback(err);
}
if (FS.isDir(stat.mode)) {
entry = { timestamp: stat.mtime, mode: stat.mode };
} else {
// Performance consideration: storing a normal JavaScript array to a IndexedDB is much slower than storing a typed array.
// Therefore always convert the file contents to a typed array first before writing the data to IndexedDB.
node.contents = MEMFS.getFileDataAsTypedArray(node);
entry = { timestamp: stat.mtime, mode: stat.mode, contents: node.contents };
}
IDBFS.getDB('/classicube', function(err, db) {
if (err) return callback(err);
var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
transaction.onerror = function(e) {
callback(this.error);
e.preventDefault();
};
var req = store.put(entry, path);
req.onsuccess = function() { callback(null); };
req.onerror = function(e) {
callback(this.error);
e.preventDefault();
};
});
};
var stat, node, entry; if (!window.cc_idbErr) return;
try { ccall('Platform_LogError', 'void', ['string'], ['&cError preloading IndexedDB:' + window.cc_idbErr]);
var lookup = FS.lookupPath(path); ccall('Platform_LogError', 'void', ['string'], ['&cPreviously saved settings/maps will be lost']);
node = lookup.node;
stat = FS.stat(path);
} catch (err) {
return callback(err);
}
if (FS.isDir(stat.mode)) {
entry = { timestamp: stat.mtime, mode: stat.mode };
} else {
// Performance consideration: storing a normal JavaScript array to a IndexedDB is much slower than storing a typed array.
// Therefore always convert the file contents to a typed array first before writing the data to IndexedDB.
node.contents = MEMFS.getFileDataAsTypedArray(node);
entry = { timestamp: stat.mtime, mode: stat.mode, contents: node.contents };
}
IDBFS.getDB('/classicube', function(err, db) {
if (err) return callback(err);
var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
transaction.onerror = function(e) {
callback(this.error);
e.preventDefault();
};
var req = store.put(entry, node.path);
req.onsuccess = function() { callback(null); };
req.onerror = function(e) {
callback(this.error);
e.preventDefault();
};
});
}, },
interop_DirectorySetWorking: function (raw) { interop_DirectorySetWorking: function (raw) {
var path = UTF8ToString(raw); var path = UTF8ToString(raw);
@ -187,7 +193,7 @@ mergeInto(LibraryManager.library, {
var path = UTF8ToString(raw); var path = UTF8ToString(raw);
try { try {
FS.mkdir(path, mode, 0); FS.mkdir(path, mode, 0);
interop_SaveNode(path); Module.saveNode(path);
return 0; return 0;
} catch (e) { } catch (e) {
if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e); if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
@ -269,8 +275,8 @@ mergeInto(LibraryManager.library, {
try { try {
var stream = FS.getStream(fd); var stream = FS.getStream(fd);
FS.close(stream); FS.close(stream);
// save writable files to IndexedDB // save writable files to IndexedDB (check for O_RDWR)
if (stream.isWrite.get()) interop_SaveNode(stream.path); if ((stream.flags & 3) == 2) Module.saveNode(stream.path);
return 0; return 0;
} catch (e) { } catch (e) {
if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e); if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);