Skip to content

Commit

Permalink
Add sync_fs_done callback event
Browse files Browse the repository at this point in the history
  • Loading branch information
JiepengTan committed Nov 8, 2024
1 parent 4240ad0 commit 8c10664
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 58 deletions.
2 changes: 2 additions & 0 deletions platform/web/godot_js.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ extern void godot_js_config_canvas_id_get(char *p_ptr, int p_ptr_max);

// OS
extern void godot_js_os_refresh_fs();
extern void godot_js_os_on_fs_sync_done();
extern void godot_js_os_on_main_iterater(uint32_t p_frame_num);
extern void godot_js_os_finish_async(void (*p_callback)());
extern void godot_js_os_request_quit_cb(void (*p_callback)());
extern int godot_js_os_fs_is_persistent();
Expand Down
126 changes: 68 additions & 58 deletions platform/web/js/libs/library_godot_input.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,19 +329,25 @@ const GodotInputDragDrop = {
return function (ev) {
GodotInputDragDrop._process_event(ev, callback);
};
},
},
},
};
mergeInto(LibraryManager.library, GodotInputDragDrop);

const GodotEditorEventHandler = {
$GodotEditorEventHandler__deps: ['$FS', '$GodotFS', '$GodotEventListeners', '$GodotInputDragDrop'],
$GodotEditorEventHandler: {
addOrUpdateFilesCB: {},
deleteFilesCB: {},

_process_add_files_event: function (ev, callback) {
infos = ev.detail
add_or_update_files: function (infos) {
const drops = [];
const files = [];
const DROP = `/tmp/add-file-${parseInt(Math.random() * (1 << 30), 10)}/`;
FS.mkdir(DROP.slice(0, -1)); // Without trailing slash
for (let i = 0; i < infos.length; i++) {
const elem = infos[i];
const path = elem['path'];
console.log("_process_add_files_event ", path)
GodotFS.copy_to_fs(DROP + path, new Uint8Array(elem['data']));
let idx = path.indexOf('/');
if (idx === -1) {
Expand All @@ -357,7 +363,7 @@ const GodotInputDragDrop = {
}
files.push(DROP + path);
}
callback(drops);
GodotEditorEventHandler.addOrUpdateFilesCB(drops);
if (GodotConfig.persistent_drops) {
// Delay removal at exit.
GodotOS.atexit(function (resolve, reject) {
Expand All @@ -369,20 +375,69 @@ const GodotInputDragDrop = {
}
},

handler_add_files: function (callback) {
return function (ev) {
GodotInputDragDrop._process_add_files_event(ev, callback);
};
handler_update_project: async function (ev) {
let infos = ev.detail
// 1. handle delete files
GodotEditorEventHandler.deleteFilesCB(infos.deletedInfos);
// 2. add or update files
GodotEditorEventHandler.add_or_update_files(infos.dirtyInfos)
// 3. callback
let start_frame = GodotOS.frame_num
await GodotOS.get_sync_done_promise()
if(GodotOS.frame_num - start_frame < 2 ) {
await GodotOS.get_sync_done_promise()
}
if (infos.resolve) {
infos.resolve()
}
},
},
};
mergeInto(LibraryManager.library, GodotInputDragDrop);
godot_js_delete_files_cb__proxy: 'sync',
godot_js_delete_files_cb__sig: 'vi',
godot_js_delete_files_cb: function (callback) {
const func = GodotRuntime.get_func(callback);
const delete_files = function (files) {
const args = files || [];
if (!args.length) {
return;
}
const argc = args.length;
const argv = GodotRuntime.allocStringArray(args);
func(argv, argc);
GodotRuntime.freeStringArray(argv, argc);
};
const canvas = GodotConfig.canvas;
GodotEditorEventHandler.deleteFilesCB = delete_files;
GodotEventListeners.add(canvas, 'update_project', GodotEditorEventHandler.handler_update_project);
},

godot_js_update_files_cb__proxy: 'sync',
godot_js_update_files_cb__sig: 'vi',
godot_js_update_files_cb: function (callback) {
const func = GodotRuntime.get_func(callback);
const update_files = function (ev) {
const files = ev.detail;
const args = files || [];
if (!args.length) {
return;
}
const argc = args.length;
const argv = GodotRuntime.allocStringArray(args);
func(argv, argc);
GodotRuntime.freeStringArray(argv, argc);
};
const canvas = GodotConfig.canvas;
GodotEventListeners.add(canvas, "update_files", update_files);
},


};
mergeInto(LibraryManager.library, GodotEditorEventHandler);
/*
* Godot exposed input functions.
*/
const GodotInput = {
$GodotInput__deps: ['$GodotRuntime', '$GodotConfig', '$GodotEventListeners', '$GodotInputGamepads', '$GodotInputDragDrop'],
$GodotInput__deps: ['$GodotRuntime', '$GodotConfig', '$GodotEventListeners', '$GodotInputGamepads', '$GodotInputDragDrop', '$GodotEditorEventHandler'],
$GodotInput: {
getModifiers: function (evt) {
return (evt.shiftKey + 0) + ((evt.altKey + 0) << 1) + ((evt.ctrlKey + 0) << 2) + ((evt.metaKey + 0) << 3);
Expand Down Expand Up @@ -551,51 +606,6 @@ const GodotInput = {
GodotRuntime.setHeapValue(r_standard, is_standard, 'i32');
return 0;
},


godot_js_update_files_cb__proxy: 'sync',
godot_js_update_files_cb__sig: 'vi',
godot_js_update_files_cb: function (callback) {
const func = GodotRuntime.get_func(callback);
const update_files = function (ev) {
const files = ev.detail;
const args = files || [];
if (!args.length) {
return;
}
const argc = args.length;
const argv = GodotRuntime.allocStringArray(args);
func(argv, argc);
GodotRuntime.freeStringArray(argv, argc);
};
const canvas = GodotConfig.canvas;
GodotEventListeners.add(canvas, "update_files", update_files);

const refresh_fs = function (evt) {
console.log("refresh_fs called");
GodotFS.refresh_fs()
}
GodotEventListeners.add(canvas, 'refresh_fs', refresh_fs);
},

godot_js_delete_files_cb__proxy: 'sync',
godot_js_delete_files_cb__sig: 'vi',
godot_js_delete_files_cb: function (callback) {
const func = GodotRuntime.get_func(callback);
const delete_files = function (ev) {
const files = ev.detail;
const args = files || [];
if (!args.length) {
return;
}
const argc = args.length;
const argv = GodotRuntime.allocStringArray(args);
func(argv, argc);
GodotRuntime.freeStringArray(argv, argc);
};
const canvas = GodotConfig.canvas;
GodotEventListeners.add(canvas, "delete_files", delete_files);
},
/*
* Drag/Drop API
*/
Expand All @@ -619,8 +629,8 @@ const GodotInput = {
ev.preventDefault();
}, false);

GodotEditorEventHandler.addOrUpdateFilesCB = dropFiles;
GodotEventListeners.add(canvas, 'drop', GodotInputDragDrop.handler(dropFiles));
GodotEventListeners.add(canvas, 'add_files', GodotInputDragDrop.handler_add_files(dropFiles));
},

/* Paste API */
Expand Down
29 changes: 29 additions & 0 deletions platform/web/js/libs/library_godot_os.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,18 @@ const GodotOS = {
request_quit: function () {},
_async_cbs: [],
_fs_sync_promise: null,
frame_num: 0,
_fs_sync_done_promise: null,
_fs_sync_done_resove: null,

get_sync_done_promise: async function () {
if(GodotOS._fs_sync_done_promise == null) {
GodotOS._fs_sync_done_promise = new Promise((resolve, reject) => {
GodotOS._fs_sync_done_resove = resolve;
});
}
return GodotOS._fs_sync_done_promise;
},

atexit: function (p_promise_cb) {
GodotOS._async_cbs.push(p_promise_cb);
Expand Down Expand Up @@ -309,6 +321,23 @@ const GodotOS = {
GodotFS.refresh_fs();
},

godot_js_os_on_fs_sync_done__proxy: 'sync',
godot_js_os_on_fs_sync_done__sig: 'v',
godot_js_os_on_fs_sync_done: async function () {
if(GodotOS._fs_sync_done_resove){
GodotOS._fs_sync_done_resove(GodotOS.frame_num)
}
GodotOS._fs_sync_done_promise = new Promise(async (resolve, reject) => {
GodotOS._fs_sync_done_resove = resolve;
})
},

godot_js_os_on_main_iterater__proxy: 'sync',
godot_js_os_on_main_iterater__sig: 'vi',
godot_js_os_on_main_iterater: function (p_frame_num) {
GodotOS.frame_num = p_frame_num;
},

godot_js_os_has_feature__proxy: 'sync',
godot_js_os_has_feature__sig: 'ii',
godot_js_os_has_feature: function (p_ftr) {
Expand Down
6 changes: 6 additions & 0 deletions platform/web/os_web.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,16 @@ void OS_Web::fs_sync_callback() {
}

bool OS_Web::main_loop_iterate() {
uint64_t current_frames_drawn = Engine::get_singleton()->get_frames_drawn();
if (is_userfs_persistent() && idb_needs_sync && !idb_is_syncing) {
idb_is_syncing = true;
idb_needs_sync = false;
godot_js_os_fs_sync(&fs_sync_callback);
last_dirty_frame = current_frames_drawn;
}
godot_js_os_on_main_iterater((uint32_t)current_frames_drawn);
if (current_frames_drawn == (last_dirty_frame + 10)) {
godot_js_os_on_fs_sync_done();
}

DisplayServer::get_singleton()->process_events();
Expand Down
1 change: 1 addition & 0 deletions platform/web/os_web.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class OS_Web : public OS_Unix {
bool idb_available = false;
bool idb_needs_sync = false;
bool pwa_is_waiting = false;
int64_t last_dirty_frame = 0;

WASM_EXPORT static void main_loop_callback();

Expand Down
1 change: 1 addition & 0 deletions test
Submodule test added at 7edb84

0 comments on commit 8c10664

Please sign in to comment.