From b165a84821012c2bc1189aaf8a7e1a90ce9b4b87 Mon Sep 17 00:00:00 2001 From: Adam Scott Date: Thu, 20 Jul 2023 09:42:03 -0400 Subject: [PATCH] Add `do_not_block_main_thread` option to `platform=web` --- modules/webrtc/library_godot_webrtc.js | 20 ++ modules/websocket/library_godot_websocket.js | 5 + platform/web/detect.py | 12 ++ platform/web/display_server_web.cpp | 185 +++++++++++++++--- platform/web/display_server_web.h | 16 +- platform/web/godot_js.h | 3 +- platform/web/js/libs/library_godot_audio.js | 9 + platform/web/js/libs/library_godot_display.js | 40 ++++ platform/web/js/libs/library_godot_fetch.js | 8 + platform/web/js/libs/library_godot_input.js | 12 ++ .../library_godot_javascript_singleton.js | 10 + platform/web/js/libs/library_godot_os.js | 13 ++ 12 files changed, 304 insertions(+), 29 deletions(-) diff --git a/modules/webrtc/library_godot_webrtc.js b/modules/webrtc/library_godot_webrtc.js index 7ece4aa87235..eae41207415a 100644 --- a/modules/webrtc/library_godot_webrtc.js +++ b/modules/webrtc/library_godot_webrtc.js @@ -90,6 +90,7 @@ const GodotRTCDataChannel = { }, }, + godot_js_rtc_datachannel_ready_state_get__proxy: 'sync', godot_js_rtc_datachannel_ready_state_get__sig: 'ii', godot_js_rtc_datachannel_ready_state_get: function (p_id) { const ref = IDHandler.get(p_id); @@ -110,6 +111,7 @@ const GodotRTCDataChannel = { } }, + godot_js_rtc_datachannel_send__proxy: 'sync', godot_js_rtc_datachannel_send__sig: 'iiiii', godot_js_rtc_datachannel_send: function (p_id, p_buffer, p_length, p_raw) { const ref = IDHandler.get(p_id); @@ -131,16 +133,19 @@ const GodotRTCDataChannel = { return 0; }, + godot_js_rtc_datachannel_is_ordered__proxy: 'sync', godot_js_rtc_datachannel_is_ordered__sig: 'ii', godot_js_rtc_datachannel_is_ordered: function (p_id) { return GodotRTCDataChannel.get_prop(p_id, 'ordered', true); }, + godot_js_rtc_datachannel_id_get__proxy: 'sync', godot_js_rtc_datachannel_id_get__sig: 'ii', godot_js_rtc_datachannel_id_get: function (p_id) { return GodotRTCDataChannel.get_prop(p_id, 'id', 65535); }, + godot_js_rtc_datachannel_max_packet_lifetime_get__proxy: 'sync', godot_js_rtc_datachannel_max_packet_lifetime_get__sig: 'ii', godot_js_rtc_datachannel_max_packet_lifetime_get: function (p_id) { const ref = IDHandler.get(p_id); @@ -156,21 +161,25 @@ const GodotRTCDataChannel = { return 65535; }, + godot_js_rtc_datachannel_max_retransmits_get__proxy: 'sync', godot_js_rtc_datachannel_max_retransmits_get__sig: 'ii', godot_js_rtc_datachannel_max_retransmits_get: function (p_id) { return GodotRTCDataChannel.get_prop(p_id, 'maxRetransmits', 65535); }, + godot_js_rtc_datachannel_is_negotiated__proxy: 'sync', godot_js_rtc_datachannel_is_negotiated__sig: 'ii', godot_js_rtc_datachannel_is_negotiated: function (p_id) { return GodotRTCDataChannel.get_prop(p_id, 'negotiated', 65535); }, + godot_js_rtc_datachannel_get_buffered_amount__proxy: 'sync', godot_js_rtc_datachannel_get_buffered_amount__sig: 'ii', godot_js_rtc_datachannel_get_buffered_amount: function (p_id) { return GodotRTCDataChannel.get_prop(p_id, 'bufferedAmount', 0); }, + godot_js_rtc_datachannel_label_get__proxy: 'sync', godot_js_rtc_datachannel_label_get__sig: 'ii', godot_js_rtc_datachannel_label_get: function (p_id) { const ref = IDHandler.get(p_id); @@ -189,12 +198,14 @@ const GodotRTCDataChannel = { return GodotRuntime.allocString(ref.protocol); }, + godot_js_rtc_datachannel_destroy__proxy: 'sync', godot_js_rtc_datachannel_destroy__sig: 'vi', godot_js_rtc_datachannel_destroy: function (p_id) { GodotRTCDataChannel.close(p_id); IDHandler.remove(p_id); }, + godot_js_rtc_datachannel_connect__proxy: 'sync', godot_js_rtc_datachannel_connect__sig: 'viiiiii', godot_js_rtc_datachannel_connect: function (p_id, p_ref, p_on_open, p_on_message, p_on_error, p_on_close) { const onopen = GodotRuntime.get_func(p_on_open).bind(null, p_ref); @@ -204,6 +215,7 @@ const GodotRTCDataChannel = { GodotRTCDataChannel.connect(p_id, onopen, onmessage, onerror, onclose); }, + godot_js_rtc_datachannel_close__proxy: 'sync', godot_js_rtc_datachannel_close__sig: 'vi', godot_js_rtc_datachannel_close: function (p_id) { const ref = IDHandler.get(p_id); @@ -356,6 +368,7 @@ const GodotRTCPeerConnection = { }, }, + godot_js_rtc_pc_create__proxy: 'sync', godot_js_rtc_pc_create__sig: 'iiiiiiii', godot_js_rtc_pc_create: function (p_config, p_ref, p_on_connection_state_change, p_on_ice_gathering_state_change, p_on_signaling_state_change, p_on_ice_candidate, p_on_datachannel) { const wrap = function (p_func) { @@ -371,6 +384,7 @@ const GodotRTCPeerConnection = { ); }, + godot_js_rtc_pc_close__proxy: 'sync', godot_js_rtc_pc_close__sig: 'vi', godot_js_rtc_pc_close: function (p_id) { const ref = IDHandler.get(p_id); @@ -380,11 +394,13 @@ const GodotRTCPeerConnection = { ref.close(); }, + godot_js_rtc_pc_destroy__proxy: 'sync', godot_js_rtc_pc_destroy__sig: 'vi', godot_js_rtc_pc_destroy: function (p_id) { GodotRTCPeerConnection.destroy(p_id); }, + godot_js_rtc_pc_offer_create__proxy: 'sync', godot_js_rtc_pc_offer_create__sig: 'viiii', godot_js_rtc_pc_offer_create: function (p_id, p_obj, p_on_session, p_on_error) { const ref = IDHandler.get(p_id); @@ -400,6 +416,7 @@ const GodotRTCPeerConnection = { }); }, + godot_js_rtc_pc_local_description_set__proxy: 'sync', godot_js_rtc_pc_local_description_set__sig: 'viiiii', godot_js_rtc_pc_local_description_set: function (p_id, p_type, p_sdp, p_obj, p_on_error) { const ref = IDHandler.get(p_id); @@ -417,6 +434,7 @@ const GodotRTCPeerConnection = { }); }, + godot_js_rtc_pc_remote_description_set__proxy: 'sync', godot_js_rtc_pc_remote_description_set__sig: 'viiiiii', godot_js_rtc_pc_remote_description_set: function (p_id, p_type, p_sdp, p_obj, p_session_created, p_on_error) { const ref = IDHandler.get(p_id); @@ -442,6 +460,7 @@ const GodotRTCPeerConnection = { }); }, + godot_js_rtc_pc_ice_candidate_add__proxy: 'sync', godot_js_rtc_pc_ice_candidate_add__sig: 'viiii', godot_js_rtc_pc_ice_candidate_add: function (p_id, p_mid_name, p_mline_idx, p_sdp) { const ref = IDHandler.get(p_id); @@ -458,6 +477,7 @@ const GodotRTCPeerConnection = { }, godot_js_rtc_pc_datachannel_create__deps: ['$GodotRTCDataChannel'], + godot_js_rtc_pc_datachannel_create__proxy: 'sync', godot_js_rtc_pc_datachannel_create__sig: 'iiii', godot_js_rtc_pc_datachannel_create: function (p_id, p_label, p_config) { try { diff --git a/modules/websocket/library_godot_websocket.js b/modules/websocket/library_godot_websocket.js index ed01c69725bc..5e0c6fc57613 100644 --- a/modules/websocket/library_godot_websocket.js +++ b/modules/websocket/library_godot_websocket.js @@ -144,6 +144,7 @@ const GodotWebSocket = { }, }, + godot_js_websocket_create__proxy: 'sync', godot_js_websocket_create__sig: 'iiiiiiii', godot_js_websocket_create: function (p_ref, p_url, p_proto, p_on_open, p_on_message, p_on_error, p_on_close) { const on_open = GodotRuntime.get_func(p_on_open).bind(null, p_ref); @@ -166,6 +167,7 @@ const GodotWebSocket = { return GodotWebSocket.create(socket, on_open, on_message, on_error, on_close); }, + godot_js_websocket_send__proxy: 'sync', godot_js_websocket_send__sig: 'iiiii', godot_js_websocket_send: function (p_id, p_buf, p_buf_len, p_raw) { const bytes_array = new Uint8Array(p_buf_len); @@ -180,11 +182,13 @@ const GodotWebSocket = { return GodotWebSocket.send(p_id, out); }, + godot_js_websocket_buffered_amount__proxy: 'sync', godot_js_websocket_buffered_amount__sig: 'ii', godot_js_websocket_buffered_amount: function (p_id) { return GodotWebSocket.bufferedAmount(p_id); }, + godot_js_websocket_close__proxy: 'sync', godot_js_websocket_close__sig: 'viii', godot_js_websocket_close: function (p_id, p_code, p_reason) { const code = p_code; @@ -192,6 +196,7 @@ const GodotWebSocket = { GodotWebSocket.close(p_id, code, reason); }, + godot_js_websocket_destroy__proxy: 'sync', godot_js_websocket_destroy__sig: 'vi', godot_js_websocket_destroy: function (p_id) { GodotWebSocket.destroy(p_id); diff --git a/platform/web/detect.py b/platform/web/detect.py index 2685cbcd63ef..0b547ddb967d 100644 --- a/platform/web/detect.py +++ b/platform/web/detect.py @@ -41,6 +41,11 @@ def get_opts(): "dlink_enabled", "Enable WebAssembly dynamic linking (GDExtension support). Produces bigger binaries", False ), BoolVariable("use_closure_compiler", "Use closure compiler to minimize JavaScript code", False), + BoolVariable( + "do_not_block_main_thread", + "Use Emscripten PROXY_TO_PTHREAD option to run the main application code to a separate thread", + False, + ), ] @@ -213,6 +218,13 @@ def configure(env: "Environment"): env.Append(LINKFLAGS=["-s", "SIDE_MODULE=2"]) env.extra_suffix = ".dlink" + env.extra_suffix + # Run the main application in a web worker + if env["do_not_block_main_thread"]: + env.Append(LINKFLAGS=["-s", "PROXY_TO_PTHREAD=1"]) + env.Append(CPPDEFINES=["PROXY_TO_PTHREAD_ENABLED"]) + # https://github.com/emscripten-core/emscripten/issues/18034#issuecomment-1277561925 + env.Append(LINKFLAGS=["-s", "TEXTDECODER=0"]) + # Reduce code size by generating less support code (e.g. skip NodeJS support). env.Append(LINKFLAGS=["-s", "ENVIRONMENT=web,worker"]) diff --git a/platform/web/display_server_web.cpp b/platform/web/display_server_web.cpp index 93b0496d7467..d947c6e1b14f 100644 --- a/platform/web/display_server_web.cpp +++ b/platform/web/display_server_web.cpp @@ -35,6 +35,7 @@ #include "os_web.h" #include "core/config/project_settings.h" +#include "core/object/callable_method_pointer.h" #include "scene/resources/atlas_texture.h" #include "servers/rendering/dummy/rasterizer_dummy.h" @@ -69,6 +70,13 @@ bool DisplayServerWeb::check_size_force_redraw() { } void DisplayServerWeb::fullscreen_change_callback(int p_fullscreen) { +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::fullscreen_change_callback).bind(p_fullscreen).call_deferred(); + return; + } +#endif + DisplayServerWeb *display = get_singleton(); if (p_fullscreen) { display->window_mode = WINDOW_MODE_FULLSCREEN; @@ -78,7 +86,23 @@ void DisplayServerWeb::fullscreen_change_callback(int p_fullscreen) { } // Drag and drop callback. -void DisplayServerWeb::drop_files_js_callback(char **p_filev, int p_filec) { +void DisplayServerWeb::_drop_files_js_callback(const char **p_filev, int p_filec) { + Vector files; + for (int i = 0; i < p_filec; i++) { + files.push_back(String::utf8(p_filev[i])); + } + +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::drop_files_js_callback).bind(files).call_deferred(); + return; + } +#endif + + drop_files_js_callback(files); +} + +void DisplayServerWeb::drop_files_js_callback(const Vector p_files) { DisplayServerWeb *ds = get_singleton(); if (!ds) { ERR_FAIL_MSG("Unable to drop files because the DisplayServer is not active"); @@ -86,11 +110,7 @@ void DisplayServerWeb::drop_files_js_callback(char **p_filev, int p_filec) { if (ds->drop_files_callback.is_null()) { return; } - Vector files; - for (int i = 0; i < p_filec; i++) { - files.push_back(String::utf8(p_filev[i])); - } - Variant v = files; + Variant v = p_files; Variant *vp = &v; Variant ret; Callable::CallError ce; @@ -99,6 +119,13 @@ void DisplayServerWeb::drop_files_js_callback(char **p_filev, int p_filec) { // Web quit request callback. void DisplayServerWeb::request_quit_callback() { +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::request_quit_callback).call_deferred(); + return; + } +#endif + DisplayServerWeb *ds = get_singleton(); if (ds && !ds->window_event_callback.is_null()) { Variant event = int(DisplayServer::WINDOW_EVENT_CLOSE_REQUEST); @@ -127,6 +154,13 @@ void DisplayServerWeb::dom2godot_mod(Ref ev, int p_mod, } void DisplayServerWeb::key_callback(int p_pressed, int p_repeat, int p_modifiers) { +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::key_callback).bind(p_pressed, p_repeat, p_modifiers).call_deferred(); + return; + } +#endif + DisplayServerWeb *ds = get_singleton(); JSKeyEvent &key_event = ds->key_event; // Resume audio context after input in case autoplay was denied. @@ -160,6 +194,13 @@ void DisplayServerWeb::key_callback(int p_pressed, int p_repeat, int p_modifiers // Mouse int DisplayServerWeb::mouse_button_callback(int p_pressed, int p_button, double p_x, double p_y, int p_modifiers) { +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::mouse_button_callback).bind(p_pressed, p_button, p_x, p_y, p_modifiers).call_deferred(); + return true; + } +#endif + DisplayServerWeb *ds = get_singleton(); Point2 pos(p_x, p_y); @@ -236,6 +277,13 @@ int DisplayServerWeb::mouse_button_callback(int p_pressed, int p_button, double } void DisplayServerWeb::mouse_move_callback(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers) { +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::mouse_move_callback).bind(p_x, p_y, p_rel_x, p_rel_y, p_modifiers).call_deferred(); + return; + } +#endif + BitField input_mask = Input::get_singleton()->get_mouse_button_mask(); // For motion outside the canvas, only read mouse movement if dragging // started inside the canvas; imitating desktop app behavior. @@ -310,10 +358,26 @@ bool DisplayServerWeb::tts_is_paused() const { return godot_js_tts_is_paused(); } -void DisplayServerWeb::update_voices_callback(int p_size, const char **p_voice) { - get_singleton()->voices.clear(); +void DisplayServerWeb::_update_voices_callback(int p_size, const char **p_voice) { + Vector voices; for (int i = 0; i < p_size; i++) { - Vector tokens = String::utf8(p_voice[i]).split(";", true, 2); + voices.append(String::utf8(p_voice[i])); + } + +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::update_voices_callback).bind(voices).call_deferred(); + return; + } +#endif + + update_voices_callback(voices); +} + +void DisplayServerWeb::update_voices_callback(const Vector p_voices) { + get_singleton()->voices.clear(); + for (int i = 0; i < p_voices.size(); i++) { + Vector tokens = p_voices[i].split(";", true, 2); if (tokens.size() == 2) { Dictionary voice_d; voice_d["name"] = tokens[1]; @@ -326,7 +390,7 @@ void DisplayServerWeb::update_voices_callback(int p_size, const char **p_voice) TypedArray DisplayServerWeb::tts_get_voices() const { ERR_FAIL_COND_V_MSG(!tts, TypedArray(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); - godot_js_tts_get_voices(update_voices_callback); + godot_js_tts_get_voices(_update_voices_callback); return voices; } @@ -367,6 +431,13 @@ void DisplayServerWeb::tts_stop() { } void DisplayServerWeb::_js_utterance_callback(int p_event, int p_id, int p_pos) { +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::_js_utterance_callback).bind(p_event, p_id, p_pos).call_deferred(); + return; + } +#endif + DisplayServerWeb *ds = (DisplayServerWeb *)DisplayServer::get_singleton(); if (ds->utterance_ids.has(p_id)) { int pos = 0; @@ -517,6 +588,13 @@ Point2i DisplayServerWeb::mouse_get_position() const { // Wheel int DisplayServerWeb::mouse_wheel_callback(double p_delta_x, double p_delta_y) { +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::mouse_wheel_callback).bind(p_delta_x, p_delta_y).call_deferred(); + return true; + } +#endif + if (!godot_js_display_canvas_is_focused()) { if (get_singleton()->cursor_inside_canvas) { godot_js_display_canvas_focus(); @@ -569,6 +647,13 @@ int DisplayServerWeb::mouse_wheel_callback(double p_delta_x, double p_delta_y) { // Touch void DisplayServerWeb::touch_callback(int p_type, int p_count) { +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::touch_callback).bind(p_type, p_count).call_deferred(); + return; + } +#endif + DisplayServerWeb *ds = get_singleton(); const JSTouchEvent &touch_event = ds->touch_event; @@ -612,13 +697,26 @@ bool DisplayServerWeb::is_touchscreen_available() const { } // Virtual Keyboard -void DisplayServerWeb::vk_input_text_callback(const char *p_text, int p_cursor) { +void DisplayServerWeb::_vk_input_text_callback(const char *p_text, int p_cursor) { + String text = p_text; + +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::vk_input_text_callback).bind(text, p_cursor).call_deferred(); + return; + } +#endif + + vk_input_text_callback(text, p_cursor); +} + +void DisplayServerWeb::vk_input_text_callback(String p_text, int p_cursor) { DisplayServerWeb *ds = DisplayServerWeb::get_singleton(); if (!ds || ds->input_text_callback.is_null()) { return; } // Call input_text - Variant event = String::utf8(p_text); + Variant event = p_text; Variant *eventp = &event; Variant ret; Callable::CallError ce; @@ -649,14 +747,35 @@ void DisplayServerWeb::virtual_keyboard_hide() { } void DisplayServerWeb::window_blur_callback() { +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::window_blur_callback).call_deferred(); + return; + } +#endif + Input::get_singleton()->release_pressed_events(); } // Gamepad -void DisplayServerWeb::gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid) { +void DisplayServerWeb::_gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid) { + String id = p_id; + String guid = p_guid; + +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::gamepad_callback).bind(p_index, p_connected, id, guid).call_deferred(); + return; + } +#endif + + gamepad_callback(p_index, p_connected, id, guid); +} + +void DisplayServerWeb::gamepad_callback(int p_index, int p_connected, const String p_id, const String p_guid) { Input *input = Input::get_singleton(); if (p_connected) { - input->joy_connection_changed(p_index, true, String::utf8(p_id), String::utf8(p_guid)); + input->joy_connection_changed(p_index, true, p_id, p_guid); } else { input->joy_connection_changed(p_index, false, ""); } @@ -699,8 +818,21 @@ Vector DisplayServerWeb::get_rendering_drivers_func() { } // Clipboard -void DisplayServerWeb::update_clipboard_callback(const char *p_text) { - get_singleton()->clipboard = String::utf8(p_text); +void DisplayServerWeb::_update_clipboard_callback(const char *p_text) { + String text = p_text; + +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::update_clipboard_callback).bind(text).call_deferred(); + return; + } +#endif + + update_clipboard_callback(text); +} + +void DisplayServerWeb::update_clipboard_callback(const String p_text) { + get_singleton()->clipboard = p_text; } void DisplayServerWeb::clipboard_set(const String &p_text) { @@ -710,11 +842,18 @@ void DisplayServerWeb::clipboard_set(const String &p_text) { } String DisplayServerWeb::clipboard_get() const { - godot_js_display_clipboard_get(update_clipboard_callback); + godot_js_display_clipboard_get(_update_clipboard_callback); return clipboard; } void DisplayServerWeb::send_window_event_callback(int p_notification) { +#ifdef PROXY_TO_PTHREAD_ENABLED + if (!Thread::is_main_thread()) { + callable_mp_static(DisplayServerWeb::send_window_event_callback).bind(p_notification).call_deferred(); + return; + } +#endif + DisplayServerWeb *ds = get_singleton(); if (!ds) { return; @@ -836,19 +975,19 @@ DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode godot_js_input_mouse_wheel_cb(&DisplayServerWeb::mouse_wheel_callback); godot_js_input_touch_cb(&DisplayServerWeb::touch_callback, touch_event.identifier, touch_event.coords); godot_js_input_key_cb(&DisplayServerWeb::key_callback, key_event.code, key_event.key); - godot_js_input_paste_cb(update_clipboard_callback); - godot_js_input_drop_files_cb(drop_files_js_callback); - godot_js_input_gamepad_cb(&DisplayServerWeb::gamepad_callback); + godot_js_input_paste_cb(&DisplayServerWeb::_update_clipboard_callback); + godot_js_input_drop_files_cb(&DisplayServerWeb::_drop_files_js_callback); + godot_js_input_gamepad_cb(&DisplayServerWeb::_gamepad_callback); // JS Display interface (js/libs/library_godot_display.js) godot_js_display_fullscreen_cb(&DisplayServerWeb::fullscreen_change_callback); - godot_js_display_window_blur_cb(&window_blur_callback); - godot_js_display_notification_cb(&send_window_event_callback, + godot_js_display_window_blur_cb(&DisplayServerWeb::window_blur_callback); + godot_js_display_notification_cb(&DisplayServerWeb::send_window_event_callback, WINDOW_EVENT_MOUSE_ENTER, WINDOW_EVENT_MOUSE_EXIT, WINDOW_EVENT_FOCUS_IN, WINDOW_EVENT_FOCUS_OUT); - godot_js_display_vk_cb(&vk_input_text_callback); + godot_js_display_vk_cb(&DisplayServerWeb::_vk_input_text_callback); Input::get_singleton()->set_event_dispatch_function(_dispatch_input_event); } diff --git a/platform/web/display_server_web.h b/platform/web/display_server_web.h index a4fd75f33b30..c6ff6db40ae6 100644 --- a/platform/web/display_server_web.h +++ b/platform/web/display_server_web.h @@ -88,14 +88,17 @@ class DisplayServerWeb : public DisplayServer { static const char *godot2dom_cursor(DisplayServer::CursorShape p_shape); // events + static void _fullscreen_change_callback(int p_fullscreen); static void fullscreen_change_callback(int p_fullscreen); static int mouse_button_callback(int p_pressed, int p_button, double p_x, double p_y, int p_modifiers); static void mouse_move_callback(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers); static int mouse_wheel_callback(double p_delta_x, double p_delta_y); static void touch_callback(int p_type, int p_count); static void key_callback(int p_pressed, int p_repeat, int p_modifiers); - static void vk_input_text_callback(const char *p_text, int p_cursor); - static void gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid); + static void _vk_input_text_callback(const char *p_text, int p_cursor); + static void vk_input_text_callback(const String p_text, int p_cursor); + static void _gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid); + static void gamepad_callback(int p_index, int p_connected, const String p_id, const String p_guid); void process_joypads(); static void _js_utterance_callback(int p_event, int p_id, int p_pos); @@ -106,10 +109,13 @@ class DisplayServerWeb : public DisplayServer { static void request_quit_callback(); static void window_blur_callback(); - static void update_voices_callback(int p_size, const char **p_voice); - static void update_clipboard_callback(const char *p_text); + static void _update_voices_callback(int p_size, const char **p_voice); + static void update_voices_callback(const Vector p_voices); + static void _update_clipboard_callback(const char *p_text); + static void update_clipboard_callback(String p_text); static void send_window_event_callback(int p_notification); - static void drop_files_js_callback(char **p_filev, int p_filec); + static void _drop_files_js_callback(const char **p_filev, int p_filec); + static void drop_files_js_callback(const Vector p_files); protected: int get_current_video_driver() const; diff --git a/platform/web/godot_js.h b/platform/web/godot_js.h index 3341cf8a6726..0ea1f24f1244 100644 --- a/platform/web/godot_js.h +++ b/platform/web/godot_js.h @@ -36,6 +36,7 @@ extern "C" { #endif #include +#include // Config extern void godot_js_config_locale_get(char *p_ptr, int p_ptr_max); @@ -67,7 +68,7 @@ extern int godot_js_input_gamepad_sample(); extern int godot_js_input_gamepad_sample_count(); extern int godot_js_input_gamepad_sample_get(int p_idx, float r_btns[16], int32_t *r_btns_num, float r_axes[10], int32_t *r_axes_num, int32_t *r_standard); extern void godot_js_input_paste_cb(void (*p_callback)(const char *p_text)); -extern void godot_js_input_drop_files_cb(void (*p_callback)(char **p_filev, int p_filec)); +extern void godot_js_input_drop_files_cb(void (*p_callback)(const char **p_filev, int p_filec)); // TTS extern int godot_js_tts_is_speaking(); diff --git a/platform/web/js/libs/library_godot_audio.js b/platform/web/js/libs/library_godot_audio.js index 1993d66310f8..53105893981b 100644 --- a/platform/web/js/libs/library_godot_audio.js +++ b/platform/web/js/libs/library_godot_audio.js @@ -159,16 +159,19 @@ const GodotAudio = { return 1; }, + godot_audio_has_worklet__proxy: 'sync', godot_audio_has_worklet__sig: 'i', godot_audio_has_worklet: function () { return (GodotAudio.ctx && GodotAudio.ctx.audioWorklet) ? 1 : 0; }, + godot_audio_has_script_processor__proxy: 'sync', godot_audio_has_script_processor__sig: 'i', godot_audio_has_script_processor: function () { return (GodotAudio.ctx && GodotAudio.ctx.createScriptProcessor) ? 1 : 0; }, + godot_audio_init__proxy: 'sync', godot_audio_init__sig: 'iiiii', godot_audio_init: function (p_mix_rate, p_latency, p_state_change, p_latency_update) { const statechange = GodotRuntime.get_func(p_state_change); @@ -179,6 +182,7 @@ const GodotAudio = { return channels; }, + godot_audio_resume__proxy: 'sync', godot_audio_resume__sig: 'v', godot_audio_resume: function () { if (GodotAudio.ctx && GodotAudio.ctx.state !== 'running') { @@ -358,6 +362,7 @@ const GodotAudioWorklet = { }, }, + godot_audio_worklet_create__proxy: 'sync', godot_audio_worklet_create__sig: 'ii', godot_audio_worklet_create: function (channels) { try { @@ -369,6 +374,7 @@ const GodotAudioWorklet = { return 0; }, + godot_audio_worklet_start__proxy: 'sync', godot_audio_worklet_start__sig: 'viiiii', godot_audio_worklet_start: function (p_in_buf, p_in_size, p_out_buf, p_out_size, p_state) { const out_buffer = GodotRuntime.heapSub(HEAPF32, p_out_buf, p_out_size); @@ -377,6 +383,7 @@ const GodotAudioWorklet = { GodotAudioWorklet.start(in_buffer, out_buffer, state); }, + godot_audio_worklet_start_no_threads__proxy: 'sync', godot_audio_worklet_start_no_threads__sig: 'viiiiii', godot_audio_worklet_start_no_threads: function (p_out_buf, p_out_size, p_out_callback, p_in_buf, p_in_size, p_in_callback) { const out_callback = GodotRuntime.get_func(p_out_callback); @@ -465,6 +472,7 @@ const GodotAudioScript = { }, }, + godot_audio_script_create__proxy: 'sync', godot_audio_script_create__sig: 'iii', godot_audio_script_create: function (buffer_length, channel_count) { const buf_len = GodotRuntime.getHeapValue(buffer_length, 'i32'); @@ -478,6 +486,7 @@ const GodotAudioScript = { return 0; }, + godot_audio_script_start__proxy: 'sync', godot_audio_script_start__sig: 'viiiii', godot_audio_script_start: function (p_in_buf, p_in_size, p_out_buf, p_out_size, p_cb) { const onprocess = GodotRuntime.get_func(p_cb); diff --git a/platform/web/js/libs/library_godot_display.js b/platform/web/js/libs/library_godot_display.js index 746f858923ca..eae07e4d3013 100644 --- a/platform/web/js/libs/library_godot_display.js +++ b/platform/web/js/libs/library_godot_display.js @@ -345,6 +345,7 @@ const GodotDisplay = { }, }, + godot_js_display_is_swap_ok_cancel__proxy: 'sync', godot_js_display_is_swap_ok_cancel__sig: 'i', godot_js_display_is_swap_ok_cancel: function () { const win = (['Windows', 'Win64', 'Win32', 'WinCE']); @@ -355,16 +356,19 @@ const GodotDisplay = { return 0; }, + godot_js_tts_is_speaking__proxy: 'sync', godot_js_tts_is_speaking__sig: 'i', godot_js_tts_is_speaking: function () { return window.speechSynthesis.speaking; }, + godot_js_tts_is_paused__proxy: 'sync', godot_js_tts_is_paused__sig: 'i', godot_js_tts_is_paused: function () { return window.speechSynthesis.paused; }, + godot_js_tts_get_voices__proxy: 'sync', godot_js_tts_get_voices__sig: 'vi', godot_js_tts_get_voices: function (p_callback) { const func = GodotRuntime.get_func(p_callback); @@ -382,6 +386,7 @@ const GodotDisplay = { } }, + godot_js_tts_speak__proxy: 'sync', godot_js_tts_speak__sig: 'viiiffii', godot_js_tts_speak: function (p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_callback) { const func = GodotRuntime.get_func(p_callback); @@ -424,53 +429,63 @@ const GodotDisplay = { window.speechSynthesis.speak(utterance); }, + godot_js_tts_pause__proxy: 'sync', godot_js_tts_pause__sig: 'v', godot_js_tts_pause: function () { window.speechSynthesis.pause(); }, + godot_js_tts_resume__proxy: 'sync', godot_js_tts_resume__sig: 'v', godot_js_tts_resume: function () { window.speechSynthesis.resume(); }, + godot_js_tts_stop__proxy: 'sync', godot_js_tts_stop__sig: 'v', godot_js_tts_stop: function () { window.speechSynthesis.cancel(); window.speechSynthesis.resume(); }, + godot_js_display_alert__proxy: 'sync', godot_js_display_alert__sig: 'vi', godot_js_display_alert: function (p_text) { window.alert(GodotRuntime.parseString(p_text)); // eslint-disable-line no-alert }, + godot_js_display_screen_dpi_get__proxy: 'sync', godot_js_display_screen_dpi_get__sig: 'i', godot_js_display_screen_dpi_get: function () { return GodotDisplay.getDPI(); }, + godot_js_display_pixel_ratio_get__proxy: 'sync', godot_js_display_pixel_ratio_get__sig: 'f', godot_js_display_pixel_ratio_get: function () { return GodotDisplayScreen.getPixelRatio(); }, + godot_js_display_fullscreen_request__proxy: 'sync', godot_js_display_fullscreen_request__sig: 'i', godot_js_display_fullscreen_request: function () { return GodotDisplayScreen.requestFullscreen(); }, + godot_js_display_fullscreen_exit__proxy: 'sync', godot_js_display_fullscreen_exit__sig: 'i', godot_js_display_fullscreen_exit: function () { return GodotDisplayScreen.exitFullscreen(); }, + godot_js_display_desired_size_set__proxy: 'sync', godot_js_display_desired_size_set__sig: 'vii', godot_js_display_desired_size_set: function (width, height) { GodotDisplayScreen.desired_size = [width, height]; GodotDisplayScreen.updateSize(); }, + godot_js_display_size_update__proxy: 'sync', godot_js_display_size_update__sig: 'i', godot_js_display_size_update: function () { const updated = GodotDisplayScreen.updateSize(); @@ -480,6 +495,7 @@ const GodotDisplay = { return updated; }, + godot_js_display_screen_size_get__proxy: 'sync', godot_js_display_screen_size_get__sig: 'vii', godot_js_display_screen_size_get: function (width, height) { const scale = GodotDisplayScreen.getPixelRatio(); @@ -487,12 +503,14 @@ const GodotDisplay = { GodotRuntime.setHeapValue(height, window.screen.height * scale, 'i32'); }, + godot_js_display_window_size_get__proxy: 'sync', godot_js_display_window_size_get__sig: 'vii', godot_js_display_window_size_get: function (p_width, p_height) { GodotRuntime.setHeapValue(p_width, GodotConfig.canvas.width, 'i32'); GodotRuntime.setHeapValue(p_height, GodotConfig.canvas.height, 'i32'); }, + godot_js_display_has_webgl__proxy: 'sync', godot_js_display_has_webgl__sig: 'ii', godot_js_display_has_webgl: function (p_version) { if (p_version !== 1 && p_version !== 2) { @@ -507,11 +525,13 @@ const GodotDisplay = { /* * Canvas */ + godot_js_display_canvas_focus__proxy: 'sync', godot_js_display_canvas_focus__sig: 'v', godot_js_display_canvas_focus: function () { GodotConfig.canvas.focus(); }, + godot_js_display_canvas_is_focused__proxy: 'sync', godot_js_display_canvas_is_focused__sig: 'i', godot_js_display_canvas_is_focused: function () { return document.activeElement === GodotConfig.canvas; @@ -520,6 +540,7 @@ const GodotDisplay = { /* * Touchscreen */ + godot_js_display_touchscreen_is_available__proxy: 'sync', godot_js_display_touchscreen_is_available__sig: 'i', godot_js_display_touchscreen_is_available: function () { return 'ontouchstart' in window; @@ -528,6 +549,7 @@ const GodotDisplay = { /* * Clipboard */ + godot_js_display_clipboard_set__proxy: 'sync', godot_js_display_clipboard_set__sig: 'ii', godot_js_display_clipboard_set: function (p_text) { const text = GodotRuntime.parseString(p_text); @@ -541,6 +563,7 @@ const GodotDisplay = { return 0; }, + godot_js_display_clipboard_get__proxy: 'sync', godot_js_display_clipboard_get__sig: 'ii', godot_js_display_clipboard_get: function (callback) { const func = GodotRuntime.get_func(callback); @@ -560,11 +583,13 @@ const GodotDisplay = { /* * Window */ + godot_js_display_window_title_set__proxy: 'sync', godot_js_display_window_title_set__sig: 'vi', godot_js_display_window_title_set: function (p_data) { document.title = GodotRuntime.parseString(p_data); }, + godot_js_display_window_icon_set__proxy: 'sync', godot_js_display_window_icon_set__sig: 'vii', godot_js_display_window_icon_set: function (p_ptr, p_len) { let link = document.getElementById('-gd-engine-icon'); @@ -593,6 +618,7 @@ const GodotDisplay = { /* * Cursor */ + godot_js_display_cursor_set_visible__proxy: 'sync', godot_js_display_cursor_set_visible__sig: 'vi', godot_js_display_cursor_set_visible: function (p_visible) { const visible = p_visible !== 0; @@ -607,16 +633,19 @@ const GodotDisplay = { } }, + godot_js_display_cursor_is_hidden__proxy: 'sync', godot_js_display_cursor_is_hidden__sig: 'i', godot_js_display_cursor_is_hidden: function () { return !GodotDisplayCursor.visible; }, + godot_js_display_cursor_set_shape__proxy: 'sync', godot_js_display_cursor_set_shape__sig: 'vi', godot_js_display_cursor_set_shape: function (p_string) { GodotDisplayCursor.set_shape(GodotRuntime.parseString(p_string)); }, + godot_js_display_cursor_set_custom_shape__proxy: 'sync', godot_js_display_cursor_set_custom_shape__sig: 'viiiii', godot_js_display_cursor_set_custom_shape: function (p_shape, p_ptr, p_len, p_hotspot_x, p_hotspot_y) { const shape = GodotRuntime.parseString(p_shape); @@ -640,6 +669,7 @@ const GodotDisplay = { } }, + godot_js_display_cursor_lock_set__proxy: 'sync', godot_js_display_cursor_lock_set__sig: 'vi', godot_js_display_cursor_lock_set: function (p_lock) { if (p_lock) { @@ -649,6 +679,7 @@ const GodotDisplay = { } }, + godot_js_display_cursor_is_locked__proxy: 'sync', godot_js_display_cursor_is_locked__sig: 'i', godot_js_display_cursor_is_locked: function () { return GodotDisplayCursor.isPointerLocked() ? 1 : 0; @@ -657,6 +688,7 @@ const GodotDisplay = { /* * Listeners */ + godot_js_display_fullscreen_cb__proxy: 'sync', godot_js_display_fullscreen_cb__sig: 'vi', godot_js_display_fullscreen_cb: function (callback) { const canvas = GodotConfig.canvas; @@ -671,6 +703,7 @@ const GodotDisplay = { GodotEventListeners.add(document, 'webkitfullscreenchange', change_cb, false); }, + godot_js_display_window_blur_cb__proxy: 'sync', godot_js_display_window_blur_cb__sig: 'vi', godot_js_display_window_blur_cb: function (callback) { const func = GodotRuntime.get_func(callback); @@ -679,6 +712,7 @@ const GodotDisplay = { }, false); }, + godot_js_display_notification_cb__proxy: 'sync', godot_js_display_notification_cb__sig: 'viiiii', godot_js_display_notification_cb: function (callback, p_enter, p_exit, p_in, p_out) { const canvas = GodotConfig.canvas; @@ -691,6 +725,7 @@ const GodotDisplay = { }); }, + godot_js_display_setup_canvas__proxy: 'sync', godot_js_display_setup_canvas__sig: 'viiii', godot_js_display_setup_canvas: function (p_width, p_height, p_fullscreen, p_hidpi) { const canvas = GodotConfig.canvas; @@ -725,6 +760,7 @@ const GodotDisplay = { /* * Virtual Keyboard */ + godot_js_display_vk_show__proxy: 'sync', godot_js_display_vk_show__sig: 'viiii', godot_js_display_vk_show: function (p_text, p_type, p_start, p_end) { const text = GodotRuntime.parseString(p_text); @@ -733,21 +769,25 @@ const GodotDisplay = { GodotDisplayVK.show(text, p_type, start, end); }, + godot_js_display_vk_hide__proxy: 'sync', godot_js_display_vk_hide__sig: 'v', godot_js_display_vk_hide: function () { GodotDisplayVK.hide(); }, + godot_js_display_vk_available__proxy: 'sync', godot_js_display_vk_available__sig: 'i', godot_js_display_vk_available: function () { return GodotDisplayVK.available(); }, + godot_js_display_tts_available__proxy: 'sync', godot_js_display_tts_available__sig: 'i', godot_js_display_tts_available: function () { return 'speechSynthesis' in window; }, + godot_js_display_vk_cb__proxy: 'sync', godot_js_display_vk_cb__sig: 'vi', godot_js_display_vk_cb: function (p_input_cb) { const input_cb = GodotRuntime.get_func(p_input_cb); diff --git a/platform/web/js/libs/library_godot_fetch.js b/platform/web/js/libs/library_godot_fetch.js index 1bb48bfd6a33..ea08ff88cb2c 100644 --- a/platform/web/js/libs/library_godot_fetch.js +++ b/platform/web/js/libs/library_godot_fetch.js @@ -131,6 +131,7 @@ const GodotFetch = { }, }, + godot_js_fetch_create__proxy: 'sync', godot_js_fetch_create__sig: 'iiiiiii', godot_js_fetch_create: function (p_method, p_url, p_headers, p_headers_size, p_body, p_body_size) { const method = GodotRuntime.parseString(p_method); @@ -151,6 +152,7 @@ const GodotFetch = { }), body); }, + godot_js_fetch_state_get__proxy: 'sync', godot_js_fetch_state_get__sig: 'ii', godot_js_fetch_state_get: function (p_id) { const obj = IDHandler.get(p_id); @@ -172,6 +174,7 @@ const GodotFetch = { return -1; }, + godot_js_fetch_http_status_get__proxy: 'sync', godot_js_fetch_http_status_get__sig: 'ii', godot_js_fetch_http_status_get: function (p_id) { const obj = IDHandler.get(p_id); @@ -181,6 +184,7 @@ const GodotFetch = { return obj.status; }, + godot_js_fetch_read_headers__proxy: 'sync', godot_js_fetch_read_headers__sig: 'iiii', godot_js_fetch_read_headers: function (p_id, p_parse_cb, p_ref) { const obj = IDHandler.get(p_id); @@ -198,6 +202,7 @@ const GodotFetch = { return 0; }, + godot_js_fetch_read_chunk__proxy: 'sync', godot_js_fetch_read_chunk__sig: 'iiii', godot_js_fetch_read_chunk: function (p_id, p_buf, p_buf_size) { const obj = IDHandler.get(p_id); @@ -224,6 +229,7 @@ const GodotFetch = { return p_buf_size - to_read; }, + godot_js_fetch_body_length_get__proxy: 'sync', godot_js_fetch_body_length_get__sig: 'ii', godot_js_fetch_body_length_get: function (p_id) { const obj = IDHandler.get(p_id); @@ -233,6 +239,7 @@ const GodotFetch = { return obj.bodySize; }, + godot_js_fetch_is_chunked__proxy: 'sync', godot_js_fetch_is_chunked__sig: 'ii', godot_js_fetch_is_chunked: function (p_id) { const obj = IDHandler.get(p_id); @@ -242,6 +249,7 @@ const GodotFetch = { return obj.chunked ? 1 : 0; }, + godot_js_fetch_free__proxy: 'sync', godot_js_fetch_free__sig: 'vi', godot_js_fetch_free: function (id) { GodotFetch.free(id); diff --git a/platform/web/js/libs/library_godot_input.js b/platform/web/js/libs/library_godot_input.js index 1b221e78b371..92113e85c916 100644 --- a/platform/web/js/libs/library_godot_input.js +++ b/platform/web/js/libs/library_godot_input.js @@ -356,6 +356,7 @@ const GodotInput = { /* * Mouse API */ + godot_js_input_mouse_move_cb__proxy: 'sync', godot_js_input_mouse_move_cb__sig: 'vi', godot_js_input_mouse_move_cb: function (callback) { const func = GodotRuntime.get_func(callback); @@ -374,6 +375,7 @@ const GodotInput = { GodotEventListeners.add(window, 'mousemove', move_cb, false); }, + godot_js_input_mouse_wheel_cb__proxy: 'sync', godot_js_input_mouse_wheel_cb__sig: 'vi', godot_js_input_mouse_wheel_cb: function (callback) { const func = GodotRuntime.get_func(callback); @@ -385,6 +387,7 @@ const GodotInput = { GodotEventListeners.add(GodotConfig.canvas, 'wheel', wheel_cb, false); }, + godot_js_input_mouse_button_cb__proxy: 'sync', godot_js_input_mouse_button_cb__sig: 'vi', godot_js_input_mouse_button_cb: function (callback) { const func = GodotRuntime.get_func(callback); @@ -409,6 +412,7 @@ const GodotInput = { /* * Touch API */ + godot_js_input_touch_cb__proxy: 'sync', godot_js_input_touch_cb__sig: 'viii', godot_js_input_touch_cb: function (callback, ids, coords) { const func = GodotRuntime.get_func(callback); @@ -442,6 +446,7 @@ const GodotInput = { /* * Key API */ + godot_js_input_key_cb__proxy: 'sync', godot_js_input_key_cb__sig: 'viii', godot_js_input_key_cb: function (callback, code, key) { const func = GodotRuntime.get_func(callback); @@ -459,23 +464,27 @@ const GodotInput = { /* * Gamepad API */ + godot_js_input_gamepad_cb__proxy: 'sync', godot_js_input_gamepad_cb__sig: 'vi', godot_js_input_gamepad_cb: function (change_cb) { const onchange = GodotRuntime.get_func(change_cb); GodotInputGamepads.init(onchange); }, + godot_js_input_gamepad_sample_count__proxy: 'sync', godot_js_input_gamepad_sample_count__sig: 'i', godot_js_input_gamepad_sample_count: function () { return GodotInputGamepads.get_samples().length; }, + godot_js_input_gamepad_sample__proxy: 'sync', godot_js_input_gamepad_sample__sig: 'i', godot_js_input_gamepad_sample: function () { GodotInputGamepads.sample(); return 0; }, + godot_js_input_gamepad_sample_get__proxy: 'sync', godot_js_input_gamepad_sample_get__sig: 'iiiiiii', godot_js_input_gamepad_sample_get: function (p_index, r_btns, r_btns_num, r_axes, r_axes_num, r_standard) { const sample = GodotInputGamepads.get_sample(p_index); @@ -502,6 +511,7 @@ const GodotInput = { /* * Drag/Drop API */ + godot_js_input_drop_files_cb__proxy: 'sync', godot_js_input_drop_files_cb__sig: 'vi', godot_js_input_drop_files_cb: function (callback) { const func = GodotRuntime.get_func(callback); @@ -524,6 +534,7 @@ const GodotInput = { }, /* Paste API */ + godot_js_input_paste_cb__proxy: 'sync', godot_js_input_paste_cb__sig: 'vi', godot_js_input_paste_cb: function (callback) { const func = GodotRuntime.get_func(callback); @@ -535,6 +546,7 @@ const GodotInput = { }, false); }, + godot_js_input_vibrate_handheld__proxy: 'sync', godot_js_input_vibrate_handheld__sig: 'vi', godot_js_input_vibrate_handheld: function (p_duration_ms) { if (typeof navigator.vibrate !== 'function') { diff --git a/platform/web/js/libs/library_godot_javascript_singleton.js b/platform/web/js/libs/library_godot_javascript_singleton.js index dafc01a1fdf5..0b3705220cce 100644 --- a/platform/web/js/libs/library_godot_javascript_singleton.js +++ b/platform/web/js/libs/library_godot_javascript_singleton.js @@ -121,6 +121,7 @@ const GodotJSWrapper = { }, }, + godot_js_wrapper_interface_get__proxy: 'sync', godot_js_wrapper_interface_get__sig: 'ii', godot_js_wrapper_interface_get: function (p_name) { const name = GodotRuntime.parseString(p_name); @@ -130,6 +131,7 @@ const GodotJSWrapper = { return 0; }, + godot_js_wrapper_object_get__proxy: 'sync', godot_js_wrapper_object_get__sig: 'iiii', godot_js_wrapper_object_get: function (p_id, p_exchange, p_prop) { const obj = GodotJSWrapper.get_proxied_value(p_id); @@ -148,6 +150,7 @@ const GodotJSWrapper = { return GodotJSWrapper.js2variant(obj, p_exchange); }, + godot_js_wrapper_object_set__proxy: 'sync', godot_js_wrapper_object_set__sig: 'viiii', godot_js_wrapper_object_set: function (p_id, p_name, p_type, p_exchange) { const obj = GodotJSWrapper.get_proxied_value(p_id); @@ -162,6 +165,7 @@ const GodotJSWrapper = { } }, + godot_js_wrapper_object_call__proxy: 'sync', godot_js_wrapper_object_call__sig: 'iiiiiiiii', godot_js_wrapper_object_call: function (p_id, p_method, p_args, p_argc, p_convert_callback, p_exchange, p_lock, p_free_lock_callback) { const obj = GodotJSWrapper.get_proxied_value(p_id); @@ -189,6 +193,7 @@ const GodotJSWrapper = { } }, + godot_js_wrapper_object_unref__proxy: 'sync', godot_js_wrapper_object_unref__sig: 'vi', godot_js_wrapper_object_unref: function (p_id) { const proxy = IDHandler.get(p_id); @@ -197,6 +202,7 @@ const GodotJSWrapper = { } }, + godot_js_wrapper_create_cb__proxy: 'sync', godot_js_wrapper_create_cb__sig: 'iii', godot_js_wrapper_create_cb: function (p_ref, p_func) { const func = GodotRuntime.get_func(p_func); @@ -219,11 +225,13 @@ const GodotJSWrapper = { return id; }, + godot_js_wrapper_object_set_cb_ret__proxy: 'sync', godot_js_wrapper_object_set_cb_ret__sig: 'vii', godot_js_wrapper_object_set_cb_ret: function (p_val_type, p_val_ex) { GodotJSWrapper.cb_ret = GodotJSWrapper.variant2js(p_val_type, p_val_ex); }, + godot_js_wrapper_object_getvar__proxy: 'sync', godot_js_wrapper_object_getvar__sig: 'iiii', godot_js_wrapper_object_getvar: function (p_id, p_type, p_exchange) { const obj = GodotJSWrapper.get_proxied_value(p_id); @@ -242,6 +250,7 @@ const GodotJSWrapper = { } }, + godot_js_wrapper_object_setvar__proxy: 'sync', godot_js_wrapper_object_setvar__sig: 'iiiiii', godot_js_wrapper_object_setvar: function (p_id, p_key_type, p_key_ex, p_val_type, p_val_ex) { const obj = GodotJSWrapper.get_proxied_value(p_id); @@ -258,6 +267,7 @@ const GodotJSWrapper = { } }, + godot_js_wrapper_create_object__proxy: 'sync', godot_js_wrapper_create_object__sig: 'iiiiiiii', godot_js_wrapper_create_object: function (p_object, p_args, p_argc, p_convert_callback, p_exchange, p_lock, p_free_lock_callback) { const name = GodotRuntime.parseString(p_object); diff --git a/platform/web/js/libs/library_godot_os.js b/platform/web/js/libs/library_godot_os.js index 00ae3995831f..92635cb6ae87 100644 --- a/platform/web/js/libs/library_godot_os.js +++ b/platform/web/js/libs/library_godot_os.js @@ -91,11 +91,13 @@ const GodotConfig = { }, }, + godot_js_config_canvas_id_get__proxy: 'sync', godot_js_config_canvas_id_get__sig: 'vii', godot_js_config_canvas_id_get: function (p_ptr, p_ptr_max) { GodotRuntime.stringToHeap(`#${GodotConfig.canvas.id}`, p_ptr, p_ptr_max); }, + godot_js_config_locale_get__proxy: 'sync', godot_js_config_locale_get__sig: 'vii', godot_js_config_locale_get: function (p_ptr, p_ptr_max) { GodotRuntime.stringToHeap(GodotConfig.locale, p_ptr, p_ptr_max); @@ -266,22 +268,26 @@ const GodotOS = { }, }, + godot_js_os_finish_async__proxy: 'sync', godot_js_os_finish_async__sig: 'vi', godot_js_os_finish_async: function (p_callback) { const func = GodotRuntime.get_func(p_callback); GodotOS.finish_async(func); }, + godot_js_os_request_quit_cb__proxy: 'sync', godot_js_os_request_quit_cb__sig: 'vi', godot_js_os_request_quit_cb: function (p_callback) { GodotOS.request_quit = GodotRuntime.get_func(p_callback); }, + godot_js_os_fs_is_persistent__proxy: 'sync', godot_js_os_fs_is_persistent__sig: 'i', godot_js_os_fs_is_persistent: function () { return GodotFS.is_persistent(); }, + godot_js_os_fs_sync__proxy: 'sync', godot_js_os_fs_sync__sig: 'vi', godot_js_os_fs_sync: function (callback) { const func = GodotRuntime.get_func(callback); @@ -291,6 +297,7 @@ const GodotOS = { }); }, + godot_js_os_has_feature__proxy: 'sync', godot_js_os_has_feature__sig: 'ii', godot_js_os_has_feature: function (p_ftr) { const ftr = GodotRuntime.parseString(p_ftr); @@ -313,6 +320,7 @@ const GodotOS = { return 0; }, + godot_js_os_execute__proxy: 'sync', godot_js_os_execute__sig: 'ii', godot_js_os_execute: function (p_json) { const json_args = GodotRuntime.parseString(p_json); @@ -324,11 +332,13 @@ const GodotOS = { return 1; }, + godot_js_os_shell_open__proxy: 'sync', godot_js_os_shell_open__sig: 'vi', godot_js_os_shell_open: function (p_uri) { window.open(GodotRuntime.parseString(p_uri), '_blank'); }, + godot_js_os_hw_concurrency_get__proxy: 'sync', godot_js_os_hw_concurrency_get__sig: 'i', godot_js_os_hw_concurrency_get: function () { // TODO Godot core needs fixing to avoid spawning too many threads (> 24). @@ -336,6 +346,7 @@ const GodotOS = { return concurrency < 2 ? concurrency : 2; }, + godot_js_os_download_buffer__proxy: 'sync', godot_js_os_download_buffer__sig: 'viiii', godot_js_os_download_buffer: function (p_ptr, p_size, p_name, p_mime) { const buf = GodotRuntime.heapSlice(HEAP8, p_ptr, p_size); @@ -426,6 +437,7 @@ const GodotPWA = { }, }, + godot_js_pwa_cb__proxy: 'sync', godot_js_pwa_cb__sig: 'vi', godot_js_pwa_cb: function (p_update_cb) { if ('serviceWorker' in navigator) { @@ -434,6 +446,7 @@ const GodotPWA = { } }, + godot_js_pwa_update__proxy: 'sync', godot_js_pwa_update__sig: 'i', godot_js_pwa_update: function () { if ('serviceWorker' in navigator && GodotPWA.hasUpdate) {