diff options
Diffstat (limited to 'platform/javascript')
| -rw-r--r-- | platform/javascript/api/api.cpp | 6 | ||||
| -rw-r--r-- | platform/javascript/audio_driver_javascript.cpp | 13 | ||||
| -rw-r--r-- | platform/javascript/audio_driver_javascript.h | 1 | ||||
| -rw-r--r-- | platform/javascript/display_server_javascript.cpp | 81 | ||||
| -rw-r--r-- | platform/javascript/display_server_javascript.h | 1 | ||||
| -rw-r--r-- | platform/javascript/dom_keys.inc | 1 | ||||
| -rw-r--r-- | platform/javascript/export/export.cpp | 65 | ||||
| -rw-r--r-- | platform/javascript/http_client.h.inc | 16 | ||||
| -rw-r--r-- | platform/javascript/http_client_javascript.cpp | 32 | ||||
| -rw-r--r-- | platform/javascript/javascript_eval.cpp | 2 | ||||
| -rw-r--r-- | platform/javascript/javascript_main.cpp | 3 | ||||
| -rw-r--r-- | platform/javascript/os_javascript.cpp | 38 | ||||
| -rw-r--r-- | platform/javascript/os_javascript.h | 1 | 
13 files changed, 79 insertions, 181 deletions
| diff --git a/platform/javascript/api/api.cpp b/platform/javascript/api/api.cpp index 45cb82b351..9c73e5c4c4 100644 --- a/platform/javascript/api/api.cpp +++ b/platform/javascript/api/api.cpp @@ -35,26 +35,22 @@  static JavaScript *javascript_eval;  void register_javascript_api() { -  	ClassDB::register_virtual_class<JavaScript>();  	javascript_eval = memnew(JavaScript);  	Engine::get_singleton()->add_singleton(Engine::Singleton("JavaScript", javascript_eval));  }  void unregister_javascript_api() { -  	memdelete(javascript_eval);  }  JavaScript *JavaScript::singleton = nullptr;  JavaScript *JavaScript::get_singleton() { -  	return singleton;  }  JavaScript::JavaScript() { -  	ERR_FAIL_COND_MSG(singleton != nullptr, "JavaScript singleton already exist.");  	singleton = this;  } @@ -62,13 +58,11 @@ JavaScript::JavaScript() {  JavaScript::~JavaScript() {}  void JavaScript::_bind_methods() { -  	ClassDB::bind_method(D_METHOD("eval", "code", "use_global_execution_context"), &JavaScript::eval, DEFVAL(false));  }  #if !defined(JAVASCRIPT_ENABLED) || !defined(JAVASCRIPT_EVAL_ENABLED)  Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { -  	return Variant();  }  #endif diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp index 690ce5ba47..03ca5f78d1 100644 --- a/platform/javascript/audio_driver_javascript.cpp +++ b/platform/javascript/audio_driver_javascript.cpp @@ -35,22 +35,18 @@  AudioDriverJavaScript *AudioDriverJavaScript::singleton = nullptr;  const char *AudioDriverJavaScript::get_name() const { -  	return "JavaScript";  }  extern "C" EMSCRIPTEN_KEEPALIVE void audio_driver_js_mix() { -  	AudioDriverJavaScript::singleton->mix_to_js();  }  extern "C" EMSCRIPTEN_KEEPALIVE void audio_driver_process_capture(float sample) { -  	AudioDriverJavaScript::singleton->process_capture(sample);  }  void AudioDriverJavaScript::mix_to_js() { -  	int channel_count = get_total_channels_by_speaker_mode(get_speaker_mode());  	int sample_count = memarr_len(internal_buffer) / channel_count;  	int32_t *stream_buffer = reinterpret_cast<int32_t *>(internal_buffer); @@ -61,13 +57,11 @@ void AudioDriverJavaScript::mix_to_js() {  }  void AudioDriverJavaScript::process_capture(float sample) { -  	int32_t sample32 = int32_t(sample * 32768.f) * (1U << 16);  	input_buffer_write(sample32);  }  Error AudioDriverJavaScript::init() { -  	/* clang-format off */  	_driver_id = EM_ASM_INT({  		return Module.IDHandler.add({ @@ -115,7 +109,6 @@ Error AudioDriverJavaScript::init() {  }  void AudioDriverJavaScript::start() { -  	/* clang-format off */  	EM_ASM({  		const ref = Module.IDHandler.get($0); @@ -164,7 +157,6 @@ void AudioDriverJavaScript::resume() {  }  int AudioDriverJavaScript::get_mix_rate() const { -  	/* clang-format off */  	return EM_ASM_INT({  		const ref = Module.IDHandler.get($0); @@ -174,7 +166,6 @@ int AudioDriverJavaScript::get_mix_rate() const {  }  AudioDriver::SpeakerMode AudioDriverJavaScript::get_speaker_mode() const { -  	/* clang-format off */  	return get_speaker_mode_by_total_channels(EM_ASM_INT({  		const ref = Module.IDHandler.get($0); @@ -191,7 +182,6 @@ void AudioDriverJavaScript::unlock() {  }  void AudioDriverJavaScript::finish_async() { -  	// Close the context, add the operation to the async_finish list in module.  	int id = _driver_id;  	_driver_id = 0; @@ -230,7 +220,6 @@ void AudioDriverJavaScript::finish() {  }  Error AudioDriverJavaScript::capture_start() { -  	input_buffer_init(buffer_length);  	/* clang-format off */ @@ -260,7 +249,6 @@ Error AudioDriverJavaScript::capture_start() {  }  Error AudioDriverJavaScript::capture_stop() { -  	/* clang-format off */  	EM_ASM({  		var ref = Module.IDHandler.get($0); @@ -286,7 +274,6 @@ Error AudioDriverJavaScript::capture_stop() {  }  AudioDriverJavaScript::AudioDriverJavaScript() { -  	_driver_id = 0;  	internal_buffer = nullptr;  	buffer_length = 0; diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h index 4a44f4683f..7d5237998a 100644 --- a/platform/javascript/audio_driver_javascript.h +++ b/platform/javascript/audio_driver_javascript.h @@ -34,7 +34,6 @@  #include "servers/audio_server.h"  class AudioDriverJavaScript : public AudioDriver { -  	float *internal_buffer;  	int _driver_id; diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index 060e446fca..b95674efc3 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -1,3 +1,33 @@ +/*************************************************************************/ +/*  display_server_javascript.cpp                                        */ +/*************************************************************************/ +/*                       This file is part of:                           */ +/*                           GODOT ENGINE                                */ +/*                      https://godotengine.org                          */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */ +/*                                                                       */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the       */ +/* "Software"), to deal in the Software without restriction, including   */ +/* without limitation the rights to use, copy, modify, merge, publish,   */ +/* distribute, sublicense, and/or sell copies of the Software, and to    */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions:                                             */ +/*                                                                       */ +/* The above copyright notice and this permission notice shall be        */ +/* included in all copies or substantial portions of the Software.       */ +/*                                                                       */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ +/*************************************************************************/ +  #include "platform/javascript/display_server_javascript.h"  #include "drivers/dummy/rasterizer_dummy.h" @@ -26,7 +56,6 @@ extern "C" EMSCRIPTEN_KEEPALIVE void _set_canvas_id(uint8_t *p_data, int p_data_  }  static void focus_canvas() { -  	/* clang-format off */  	EM_ASM(  		Module['canvas'].focus(); @@ -35,7 +64,6 @@ static void focus_canvas() {  }  static bool is_canvas_focused() { -  	/* clang-format off */  	return EM_ASM_INT_V(  		return document.activeElement == Module['canvas']; @@ -66,7 +94,6 @@ static Point2 compute_position_in_canvas(int x, int y) {  static bool cursor_inside_canvas = true;  EM_BOOL DisplayServerJavaScript::fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data) { -  	DisplayServerJavaScript *display = get_singleton();  	// Empty ID is canvas.  	String target_id = String::utf8(p_event->id); @@ -105,7 +132,6 @@ extern "C" EMSCRIPTEN_KEEPALIVE void _drop_files_callback(char *p_filev[], int p  template <typename T>  static void dom2godot_mod(T *emscripten_event_ptr, Ref<InputEventWithModifiers> godot_event) { -  	godot_event->set_shift(emscripten_event_ptr->shiftKey);  	godot_event->set_alt(emscripten_event_ptr->altKey);  	godot_event->set_control(emscripten_event_ptr->ctrlKey); @@ -113,7 +139,6 @@ static void dom2godot_mod(T *emscripten_event_ptr, Ref<InputEventWithModifiers>  }  static Ref<InputEventKey> setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) { -  	Ref<InputEventKey> ev;  	ev.instance();  	ev->set_echo(emscripten_event->repeat); @@ -135,7 +160,6 @@ static Ref<InputEventKey> setup_key_event(const EmscriptenKeyboardEvent *emscrip  }  EM_BOOL DisplayServerJavaScript::keydown_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) { -  	DisplayServerJavaScript *display = get_singleton();  	Ref<InputEventKey> ev = setup_key_event(p_event);  	ev->set_pressed(true); @@ -150,7 +174,6 @@ EM_BOOL DisplayServerJavaScript::keydown_callback(int p_event_type, const Emscri  }  EM_BOOL DisplayServerJavaScript::keypress_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) { -  	DisplayServerJavaScript *display = get_singleton();  	display->deferred_key_event->set_unicode(p_event->charCode);  	Input::get_singleton()->parse_input_event(display->deferred_key_event); @@ -158,7 +181,6 @@ EM_BOOL DisplayServerJavaScript::keypress_callback(int p_event_type, const Emscr  }  EM_BOOL DisplayServerJavaScript::keyup_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) { -  	Ref<InputEventKey> ev = setup_key_event(p_event);  	ev->set_pressed(false);  	Input::get_singleton()->parse_input_event(ev); @@ -168,7 +190,6 @@ EM_BOOL DisplayServerJavaScript::keyup_callback(int p_event_type, const Emscript  // Mouse  EM_BOOL DisplayServerJavaScript::mouse_button_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data) { -  	DisplayServerJavaScript *display = get_singleton();  	Ref<InputEventMouseButton> ev; @@ -199,13 +220,10 @@ EM_BOOL DisplayServerJavaScript::mouse_button_callback(int p_event_type, const E  	}  	if (ev->is_pressed()) { -  		double diff = emscripten_get_now() - display->last_click_ms;  		if (ev->get_button_index() == display->last_click_button_index) { -  			if (diff < 400 && Point2(display->last_click_pos).distance_to(ev->get_position()) < 5) { -  				display->last_click_ms = 0;  				display->last_click_pos = Point2(-100, -100);  				display->last_click_button_index = -1; @@ -245,7 +263,6 @@ EM_BOOL DisplayServerJavaScript::mouse_button_callback(int p_event_type, const E  }  EM_BOOL DisplayServerJavaScript::mousemove_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data) { -  	Input *input = Input::get_singleton();  	int input_mask = input->get_mouse_button_mask();  	Point2 pos = compute_position_in_canvas(p_event->clientX, p_event->clientY); @@ -273,7 +290,6 @@ EM_BOOL DisplayServerJavaScript::mousemove_callback(int p_event_type, const Emsc  // Cursor  static const char *godot2dom_cursor(DisplayServer::CursorShape p_shape) { -  	switch (p_shape) {  		case DisplayServer::CURSOR_ARROW:  			return "auto"; @@ -315,7 +331,6 @@ static const char *godot2dom_cursor(DisplayServer::CursorShape p_shape) {  }  static void set_css_cursor(const char *p_cursor) { -  	/* clang-format off */  	EM_ASM_({  		Module['canvas'].style.cursor = UTF8ToString($0); @@ -324,7 +339,6 @@ static void set_css_cursor(const char *p_cursor) {  }  static bool is_css_cursor_hidden() { -  	/* clang-format off */  	return EM_ASM_INT({  		return Module['canvas'].style.cursor === 'none'; @@ -333,7 +347,6 @@ static bool is_css_cursor_hidden() {  }  void DisplayServerJavaScript::cursor_set_shape(CursorShape p_shape) { -  	ERR_FAIL_INDEX(p_shape, CURSOR_MAX);  	if (mouse_get_mode() == MOUSE_MODE_VISIBLE) { @@ -353,9 +366,7 @@ DisplayServer::CursorShape DisplayServerJavaScript::cursor_get_shape() const {  }  void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { -  	if (p_cursor.is_valid()) { -  		Map<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape);  		if (cursor_c) { @@ -483,25 +494,21 @@ void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, Curso  // Mouse mode  void DisplayServerJavaScript::mouse_set_mode(MouseMode p_mode) { -  	ERR_FAIL_COND_MSG(p_mode == MOUSE_MODE_CONFINED, "MOUSE_MODE_CONFINED is not supported for the HTML5 platform.");  	if (p_mode == mouse_get_mode())  		return;  	if (p_mode == MOUSE_MODE_VISIBLE) { -  		// set_css_cursor must be called before set_cursor_shape to make the cursor visible  		set_css_cursor(godot2dom_cursor(cursor_shape));  		cursor_set_shape(cursor_shape);  		emscripten_exit_pointerlock();  	} else if (p_mode == MOUSE_MODE_HIDDEN) { -  		set_css_cursor("none");  		emscripten_exit_pointerlock();  	} else if (p_mode == MOUSE_MODE_CAPTURED) { -  		EMSCRIPTEN_RESULT result = emscripten_request_pointerlock("canvas", false);  		ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback.");  		ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback."); @@ -512,7 +519,6 @@ void DisplayServerJavaScript::mouse_set_mode(MouseMode p_mode) {  }  DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const { -  	if (is_css_cursor_hidden())  		return MOUSE_MODE_HIDDEN; @@ -524,7 +530,6 @@ DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const {  // Wheel  EM_BOOL DisplayServerJavaScript::wheel_callback(int p_event_type, const EmscriptenWheelEvent *p_event, void *p_user_data) { -  	ERR_FAIL_COND_V(p_event_type != EMSCRIPTEN_EVENT_WHEEL, false);  	if (!is_canvas_focused()) {  		if (cursor_inside_canvas) { @@ -574,13 +579,11 @@ EM_BOOL DisplayServerJavaScript::wheel_callback(int p_event_type, const Emscript  // Touch  EM_BOOL DisplayServerJavaScript::touch_press_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data) { -  	DisplayServerJavaScript *display = get_singleton();  	Ref<InputEventScreenTouch> ev;  	ev.instance();  	int lowest_id_index = -1;  	for (int i = 0; i < p_event->numTouches; ++i) { -  		const EmscriptenTouchPoint &touch = p_event->touches[i];  		if (lowest_id_index == -1 || touch.identifier < p_event->touches[lowest_id_index].identifier)  			lowest_id_index = i; @@ -598,13 +601,11 @@ EM_BOOL DisplayServerJavaScript::touch_press_callback(int p_event_type, const Em  }  EM_BOOL DisplayServerJavaScript::touchmove_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data) { -  	DisplayServerJavaScript *display = get_singleton();  	Ref<InputEventScreenDrag> ev;  	ev.instance();  	int lowest_id_index = -1;  	for (int i = 0; i < p_event->numTouches; ++i) { -  		const EmscriptenTouchPoint &touch = p_event->touches[i];  		if (lowest_id_index == -1 || touch.identifier < p_event->touches[lowest_id_index].identifier)  			lowest_id_index = i; @@ -628,10 +629,8 @@ bool DisplayServerJavaScript::screen_is_touchscreen(int p_screen) const {  // Gamepad  EM_BOOL DisplayServerJavaScript::gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data) { -  	Input *input = Input::get_singleton();  	if (p_event_type == EMSCRIPTEN_EVENT_GAMEPADCONNECTED) { -  		String guid = "";  		if (String::utf8(p_event->mapping) == "standard")  			guid = "Default HTML5 Gamepad"; @@ -643,7 +642,6 @@ EM_BOOL DisplayServerJavaScript::gamepad_change_callback(int p_event_type, const  }  void DisplayServerJavaScript::process_joypads() { -  	int joypad_count = emscripten_get_num_gamepads();  	Input *input = Input::get_singleton();  	for (int joypad = 0; joypad < joypad_count; joypad++) { @@ -653,23 +651,13 @@ void DisplayServerJavaScript::process_joypads() {  		ERR_CONTINUE(query_result != EMSCRIPTEN_RESULT_SUCCESS &&  					 query_result != EMSCRIPTEN_RESULT_NO_DATA);  		if (query_result == EMSCRIPTEN_RESULT_SUCCESS && state.connected) { -  			int button_count = MIN(state.numButtons, 18);  			int axis_count = MIN(state.numAxes, 8);  			for (int button = 0; button < button_count; button++) { -  				float value = state.analogButton[button]; -				if (String::utf8(state.mapping) == "standard" && (button == JOY_ANALOG_L2 || button == JOY_ANALOG_R2)) { -					Input::JoyAxis joy_axis; -					joy_axis.min = 0; -					joy_axis.value = value; -					input->joy_axis(joypad, button, joy_axis); -				} else { -					input->joy_button(joypad, button, value); -				} +				input->joy_button(joypad, button, value);  			}  			for (int axis = 0; axis < axis_count; axis++) { -  				Input::JoyAxis joy_axis;  				joy_axis.min = -1;  				joy_axis.value = state.axis[axis]; @@ -685,6 +673,7 @@ bool DisplayServerJavaScript::is_joy_known(int p_device) {  	return Input::get_singleton()->is_joy_mapped(p_device);  } +  String DisplayServerJavaScript::get_joy_guid(int p_device) const {  	return Input::get_singleton()->get_joy_guid_remapped(p_device); @@ -737,7 +726,6 @@ String DisplayServerJavaScript::clipboard_get() const {  }  extern "C" EMSCRIPTEN_KEEPALIVE void send_window_event(int p_notification) { -  	if (p_notification == DisplayServer::WINDOW_EVENT_MOUSE_ENTER || p_notification == DisplayServer::WINDOW_EVENT_MOUSE_EXIT) {  		cursor_inside_canvas = p_notification == DisplayServer::WINDOW_EVENT_MOUSE_ENTER;  	} @@ -755,7 +743,6 @@ extern "C" EMSCRIPTEN_KEEPALIVE void send_window_event(int p_notification) {  }  void DisplayServerJavaScript::alert(const String &p_alert, const String &p_title) { -  	/* clang-format off */  	EM_ASM_({  		window.alert(UTF8ToString($0)); @@ -764,7 +751,6 @@ void DisplayServerJavaScript::alert(const String &p_alert, const String &p_title  }  void DisplayServerJavaScript::set_icon(const Ref<Image> &p_icon) { -  	ERR_FAIL_COND(p_icon.is_null());  	Ref<Image> icon = p_icon;  	if (icon->is_compressed()) { @@ -834,7 +820,6 @@ DisplayServer *DisplayServerJavaScript::create_func(const String &p_rendering_dr  }  DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { -  	/* clang-format off */  	EM_ASM({  		const canvas = Module['canvas']; @@ -1019,7 +1004,6 @@ Point2i DisplayServerJavaScript::screen_get_position(int p_screen) const {  }  Size2i DisplayServerJavaScript::screen_get_size(int p_screen) const { -  	EmscriptenFullscreenChangeEvent ev;  	EMSCRIPTEN_RESULT result = emscripten_get_fullscreen_status(&ev);  	ERR_FAIL_COND_V(result != EMSCRIPTEN_RESULT_SUCCESS, Size2i()); @@ -1093,6 +1077,7 @@ void DisplayServerJavaScript::window_set_current_screen(int p_screen, WindowID p  Point2i DisplayServerJavaScript::window_get_position(WindowID p_window) const {  	return Point2i(); // TODO Does this need implementation?  } +  void DisplayServerJavaScript::window_set_position(const Point2i &p_position, WindowID p_window) {  	// Not supported.  } diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h index 73a7b017e6..9860ecdf98 100644 --- a/platform/javascript/display_server_javascript.h +++ b/platform/javascript/display_server_javascript.h @@ -37,7 +37,6 @@  #include <emscripten/html5.h>  class DisplayServerJavaScript : public DisplayServer { -  	//int video_driver_index;  	Vector2 windowed_size; diff --git a/platform/javascript/dom_keys.inc b/platform/javascript/dom_keys.inc index 42d394fd4f..882e943471 100644 --- a/platform/javascript/dom_keys.inc +++ b/platform/javascript/dom_keys.inc @@ -219,7 +219,6 @@  #define DOM_VK_WIN_OEM_CLEAR 0xFE  int dom2godot_keycode(int dom_keycode) { -  	if (DOM_VK_0 <= dom_keycode && dom_keycode <= DOM_VK_Z) {  		// ASCII intersection  		return dom_keycode; diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 36076a2af9..3573ddac95 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -28,6 +28,7 @@  /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */  /*************************************************************************/ +#include "core/io/json.h"  #include "core/io/tcp_server.h"  #include "core/io/zip_io.h"  #include "editor/editor_export.h" @@ -40,7 +41,6 @@  #define EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG "webassembly_debug.zip"  class EditorHTTPServer : public Reference { -  private:  	Ref<TCP_Server> server;  	Ref<StreamPeerTCP> connection; @@ -148,11 +148,13 @@ public:  	}  	void poll() { -		if (!server->is_listening()) +		if (!server->is_listening()) {  			return; +		}  		if (connection.is_null()) { -			if (!server->is_connection_available()) +			if (!server->is_connection_available()) {  				return; +			}  			connection = server->take_connection();  			time = OS::get_singleton()->get_ticks_usec();  		} @@ -160,11 +162,11 @@ public:  			_clear_client();  			return;  		} -		if (connection->get_status() != StreamPeerTCP::STATUS_CONNECTED) +		if (connection->get_status() != StreamPeerTCP::STATUS_CONNECTED) {  			return; +		}  		while (true) { -  			char *r = (char *)req_buf;  			int l = req_pos - 1;  			if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') { @@ -190,7 +192,6 @@ public:  };  class EditorExportPlatformJavaScript : public EditorExportPlatform { -  	GDCLASS(EditorExportPlatformJavaScript, EditorExportPlatform);  	Ref<ImageTexture> logo; @@ -198,7 +199,7 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {  	Ref<ImageTexture> stop_icon;  	int menu_options; -	void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug); +	void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags);  private:  	Ref<EditorHTTPServer> server; @@ -230,7 +231,6 @@ public:  	virtual Ref<Texture2D> get_run_icon() const;  	virtual void get_platform_features(List<String> *r_features) { -  		r_features->push_back("web");  		r_features->push_back(get_os_name());  	} @@ -238,23 +238,28 @@ public:  	virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, Set<String> &p_features) {  	} +	String get_debug_protocol() const { return "ws://"; } +  	EditorExportPlatformJavaScript();  	~EditorExportPlatformJavaScript();  }; -void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug) { - +void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags) {  	String str_template = String::utf8(reinterpret_cast<const char *>(p_html.ptr()), p_html.size());  	String str_export;  	Vector<String> lines = str_template.split("\n"); +	Vector<String> flags; +	String flags_json; +	gen_export_flags(flags, p_flags); +	flags_json = JSON::print(flags);  	for (int i = 0; i < lines.size(); i++) { -  		String current_line = lines[i];  		current_line = current_line.replace("$GODOT_BASENAME", p_name);  		current_line = current_line.replace("$GODOT_PROJECT_NAME", ProjectSettings::get_singleton()->get_setting("application/config/name"));  		current_line = current_line.replace("$GODOT_HEAD_INCLUDE", p_preset->get("html/head_include"));  		current_line = current_line.replace("$GODOT_DEBUG_ENABLED", p_debug ? "true" : "false"); +		current_line = current_line.replace("$GODOT_ARGS", flags_json);  		str_export += current_line + "\n";  	} @@ -266,7 +271,6 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re  }  void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { -  	if (p_preset->get("vram_texture_compression/for_desktop")) {  		r_features->push_back("s3tc");  	} @@ -283,7 +287,6 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP  }  void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_options) { -  	r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_desktop"), true)); // S3TC  	r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_mobile"), false)); // ETC or ETC2, depending on renderer  	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_FILE, "*.html"), "")); @@ -293,22 +296,18 @@ void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_op  }  String EditorExportPlatformJavaScript::get_name() const { -  	return "HTML5";  }  String EditorExportPlatformJavaScript::get_os_name() const { -  	return "HTML5";  }  Ref<Texture2D> EditorExportPlatformJavaScript::get_logo() const { -  	return logo;  }  bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { -  	String err;  	bool valid = false; @@ -343,14 +342,14 @@ bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p  		}  	} -	if (!err.empty()) +	if (!err.empty()) {  		r_error = err; +	}  	return valid;  }  List<String> EditorExportPlatformJavaScript::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { -  	List<String> list;  	list.push_back("html");  	return list; @@ -368,11 +367,11 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese  	template_path = template_path.strip_edges();  	if (template_path == String()) { - -		if (p_debug) +		if (p_debug) {  			template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG); -		else +		} else {  			template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE); +		}  	}  	if (!DirAccess::exists(p_path.get_base_dir())) { @@ -396,7 +395,6 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese  	unzFile pkg = unzOpen2(template_path.utf8().get_data(), &io);  	if (!pkg) { -  		EditorNode::get_singleton()->show_warning(TTR("Could not open template for export:") + "\n" + template_path);  		return ERR_FILE_NOT_FOUND;  	} @@ -426,22 +424,18 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese  		//write  		if (file == "godot.html") { -  			if (!custom_html.empty()) {  				continue;  			} -			_fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug); +			_fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug, p_flags);  			file = p_path.get_file();  		} else if (file == "godot.js") { -  			file = p_path.get_file().get_basename() + ".js";  		} else if (file == "godot.worker.js") { -  			file = p_path.get_file().get_basename() + ".worker.js";  		} else if (file == "godot.wasm") { -  			file = p_path.get_file().get_basename() + ".wasm";  		} @@ -459,7 +453,6 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese  	unzClose(pkg);  	if (!custom_html.empty()) { -  		FileAccess *f = FileAccess::open(custom_html, FileAccess::READ);  		if (!f) {  			EditorNode::get_singleton()->show_warning(TTR("Could not read custom HTML shell:") + "\n" + custom_html); @@ -469,7 +462,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese  		buf.resize(f->get_len());  		f->get_buffer(buf.ptrw(), buf.size());  		memdelete(f); -		_fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug); +		_fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug, p_flags);  		f = FileAccess::open(p_path, FileAccess::WRITE);  		if (!f) { @@ -523,11 +516,9 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese  }  bool EditorExportPlatformJavaScript::poll_export() { -  	Ref<EditorExportPreset> preset;  	for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) { -  		Ref<EditorExportPreset> ep = EditorExport::get_singleton()->get_export_preset(i);  		if (ep->is_runnable() && ep->get_platform() == this) {  			preset = ep; @@ -553,12 +544,10 @@ Ref<ImageTexture> EditorExportPlatformJavaScript::get_option_icon(int p_index) c  }  int EditorExportPlatformJavaScript::get_options_count() const { -  	return menu_options;  }  Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) { -  	if (p_option == 1) {  		MutexLock lock(server_lock);  		server->stop(); @@ -606,7 +595,6 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese  }  Ref<Texture2D> EditorExportPlatformJavaScript::get_run_icon() const { -  	return run_icon;  } @@ -622,7 +610,6 @@ void EditorExportPlatformJavaScript::_server_thread_poll(void *data) {  }  EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() { -  	server.instance();  	server_quit = false;  	server_thread = Thread::create(_server_thread_poll, this); @@ -636,10 +623,11 @@ EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {  	run_icon->create_from_image(img);  	Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme(); -	if (theme.is_valid()) +	if (theme.is_valid()) {  		stop_icon = theme->get_icon("Stop", "EditorIcons"); -	else +	} else {  		stop_icon.instance(); +	}  	menu_options = 0;  } @@ -652,7 +640,6 @@ EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() {  }  void register_javascript_exporter() { -  	EDITOR_DEF("export/web/http_host", "localhost");  	EDITOR_DEF("export/web/http_port", 8060);  	EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "export/web/http_port", PROPERTY_HINT_RANGE, "1,65535,1")); diff --git a/platform/javascript/http_client.h.inc b/platform/javascript/http_client.h.inc index ac275aadbc..4d5ff88bdd 100644 --- a/platform/javascript/http_client.h.inc +++ b/platform/javascript/http_client.h.inc @@ -33,21 +33,21 @@  Error prepare_request(Method p_method, const String &p_url, const Vector<String> &p_headers);  int xhr_id; -int read_limit; -int response_read_offset; -Status status; +int read_limit = 4096; +int response_read_offset = 0; +Status status = STATUS_DISCONNECTED;  String host; -int port; -bool use_tls; +int port = -1; +bool use_tls = false;  String username;  String password; -int polled_response_code; +int polled_response_code = 0;  String polled_response_header;  PackedByteArray polled_response;  #ifdef DEBUG_ENABLED -bool has_polled; -uint64_t last_polling_frame; +bool has_polled = false; +uint64_t last_polling_frame = 0;  #endif diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp index 863c207896..cb0e48b8a9 100644 --- a/platform/javascript/http_client_javascript.cpp +++ b/platform/javascript/http_client_javascript.cpp @@ -29,10 +29,10 @@  /*************************************************************************/  #include "core/io/http_client.h" +  #include "http_request.h"  Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl, bool p_verify_host) { -  	close();  	if (p_ssl && !p_verify_host) {  		WARN_PRINT("Disabling HTTPClient's host verification is not supported for the HTML5 platform, host will be verified"); @@ -67,17 +67,14 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl,  }  void HTTPClient::set_connection(const Ref<StreamPeer> &p_connection) { -  	ERR_FAIL_MSG("Accessing an HTTPClient's StreamPeer is not supported for the HTML5 platform.");  }  Ref<StreamPeer> HTTPClient::get_connection() const { -  	ERR_FAIL_V_MSG(REF(), "Accessing an HTTPClient's StreamPeer is not supported for the HTML5 platform.");  }  Error HTTPClient::prepare_request(Method p_method, const String &p_url, const Vector<String> &p_headers) { -  	ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER);  	ERR_FAIL_COND_V_MSG(p_method == METHOD_TRACE || p_method == METHOD_CONNECT, ERR_UNAVAILABLE, "HTTP methods TRACE and CONNECT are not supported for the HTML5 platform.");  	ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER); @@ -104,7 +101,6 @@ Error HTTPClient::prepare_request(Method p_method, const String &p_url, const Ve  }  Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) { -  	Error err = prepare_request(p_method, p_url, p_headers);  	if (err != OK)  		return err; @@ -113,7 +109,6 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector  }  Error HTTPClient::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body) { -  	Error err = prepare_request(p_method, p_url, p_headers);  	if (err != OK)  		return err; @@ -122,7 +117,6 @@ Error HTTPClient::request(Method p_method, const String &p_url, const Vector<Str  }  void HTTPClient::close() { -  	host = "";  	port = -1;  	use_tls = false; @@ -134,28 +128,23 @@ void HTTPClient::close() {  }  HTTPClient::Status HTTPClient::get_status() const { -  	return status;  }  bool HTTPClient::has_response() const { -  	return !polled_response_header.empty();  }  bool HTTPClient::is_response_chunked() const { -  	// TODO evaluate using moz-chunked-arraybuffer, fetch & ReadableStream  	return false;  }  int HTTPClient::get_response_code() const { -  	return polled_response_code;  }  Error HTTPClient::get_response_headers(List<String> *r_response) { -  	if (polled_response_header.empty())  		return ERR_INVALID_PARAMETER; @@ -168,12 +157,10 @@ Error HTTPClient::get_response_headers(List<String> *r_response) {  }  int HTTPClient::get_response_body_length() const { -  	return polled_response.size();  }  PackedByteArray HTTPClient::read_response_body_chunk() { -  	ERR_FAIL_COND_V(status != STATUS_BODY, PackedByteArray());  	int to_read = MIN(read_limit, polled_response.size() - response_read_offset); @@ -192,17 +179,14 @@ PackedByteArray HTTPClient::read_response_body_chunk() {  }  void HTTPClient::set_blocking_mode(bool p_enable) { -  	ERR_FAIL_COND_MSG(p_enable, "HTTPClient blocking mode is not supported for the HTML5 platform.");  }  bool HTTPClient::is_blocking_mode_enabled() const { -  	return false;  }  void HTTPClient::set_read_chunk_size(int p_size) { -  	read_limit = p_size;  } @@ -211,9 +195,7 @@ int HTTPClient::get_read_chunk_size() const {  }  Error HTTPClient::poll() { -  	switch (status) { -  		case STATUS_DISCONNECTED:  			return ERR_UNCONFIGURED; @@ -233,7 +215,6 @@ Error HTTPClient::poll() {  			return ERR_CONNECTION_ERROR;  		case STATUS_REQUESTING: { -  #ifdef DEBUG_ENABLED  			if (!has_polled) {  				has_polled = true; @@ -279,20 +260,9 @@ Error HTTPClient::poll() {  }  HTTPClient::HTTPClient() { -  	xhr_id = godot_xhr_new(); -	read_limit = 4096; -	status = STATUS_DISCONNECTED; -	port = -1; -	use_tls = false; -	polled_response_code = 0; -#ifdef DEBUG_ENABLED -	has_polled = false; -	last_polling_frame = 0; -#endif  }  HTTPClient::~HTTPClient() { -  	godot_xhr_free(xhr_id);  } diff --git a/platform/javascript/javascript_eval.cpp b/platform/javascript/javascript_eval.cpp index db8050b90e..3a72b10dd4 100644 --- a/platform/javascript/javascript_eval.cpp +++ b/platform/javascript/javascript_eval.cpp @@ -34,14 +34,12 @@  #include "emscripten.h"  extern "C" EMSCRIPTEN_KEEPALIVE uint8_t *resize_PackedByteArray_and_open_write(PackedByteArray *p_arr, VectorWriteProxy<uint8_t> *r_write, int p_len) { -  	p_arr->resize(p_len);  	*r_write = p_arr->write;  	return p_arr->ptrw();  }  Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { -  	union {  		bool b;  		double d; diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp index 854383aeee..740a72fafa 100644 --- a/platform/javascript/javascript_main.cpp +++ b/platform/javascript/javascript_main.cpp @@ -46,7 +46,6 @@ void exit_callback() {  }  void main_loop_callback() { -  	if (os->main_loop_iterate()) {  		emscripten_cancel_main_loop(); // Cancel current loop and wait for finalize_async.  		EM_ASM({ @@ -69,7 +68,6 @@ extern "C" EMSCRIPTEN_KEEPALIVE void cleanup_after_sync() {  }  extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) { -  	String idbfs_err = String::utf8(p_idbfs_err);  	if (!idbfs_err.empty()) {  		print_line("IndexedDB not available: " + idbfs_err); @@ -85,7 +83,6 @@ extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) {  }  int main(int argc, char *argv[]) { -  	os = new OS_JavaScript();  	Main::setup(argv[0], argc - 1, &argv[1], false);  	emscripten_set_main_loop(main_loop_callback, -1, false); diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 205644ce51..ad4b5a5afa 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -30,18 +30,23 @@  #include "os_javascript.h" +#include "core/debugger/engine_debugger.h"  #include "core/io/file_access_buffered_fa.h"  #include "core/io/json.h"  #include "drivers/unix/dir_access_unix.h"  #include "drivers/unix/file_access_unix.h"  #include "main/main.h" +#include "modules/modules_enabled.gen.h"  #include "platform/javascript/display_server_javascript.h" +#ifdef MODULE_WEBSOCKET_ENABLED +#include "modules/websocket/remote_debugger_peer_websocket.h" +#endif +  #include <emscripten.h>  #include <stdlib.h>  bool OS_JavaScript::has_touchscreen_ui_hint() const { -  	/* clang-format off */  	return EM_ASM_INT_V(  		return 'ontouchstart' in window; @@ -52,22 +57,24 @@ bool OS_JavaScript::has_touchscreen_ui_hint() const {  // Audio  int OS_JavaScript::get_audio_driver_count() const { -  	return 1;  }  const char *OS_JavaScript::get_audio_driver_name(int p_driver) const { -  	return "JavaScript";  }  // Lifecycle  void OS_JavaScript::initialize() { -  	OS_Unix::initialize_core();  	FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix>>(FileAccess::ACCESS_RESOURCES);  	DisplayServerJavaScript::register_javascript_driver(); +#ifdef MODULE_WEBSOCKET_ENABLED +	EngineDebugger::register_uri_handler("ws://", RemoteDebuggerPeerWebSocket::create); +	EngineDebugger::register_uri_handler("wss://", RemoteDebuggerPeerWebSocket::create); +#endif +  	char locale_ptr[16];  	/* clang-format off */  	EM_ASM({ @@ -82,22 +89,18 @@ void OS_JavaScript::resume_audio() {  }  void OS_JavaScript::set_main_loop(MainLoop *p_main_loop) { -  	main_loop = p_main_loop;  }  MainLoop *OS_JavaScript::get_main_loop() const { -  	return main_loop;  }  void OS_JavaScript::main_loop_callback() { -  	get_singleton()->main_loop_iterate();  }  bool OS_JavaScript::main_loop_iterate() { -  	if (is_userfs_persistent() && sync_wait_time >= 0) {  		int64_t current_time = get_ticks_msec();  		int64_t elapsed_time = current_time - last_sync_check_time; @@ -122,7 +125,6 @@ bool OS_JavaScript::main_loop_iterate() {  }  void OS_JavaScript::delete_main_loop() { -  	if (main_loop) {  		memdelete(main_loop);  	} @@ -135,14 +137,12 @@ void OS_JavaScript::finalize_async() {  }  void OS_JavaScript::finalize() { -  	delete_main_loop();  }  // Miscellaneous  Error OS_JavaScript::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { -  	Array args;  	for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {  		args.push_back(E->get()); @@ -164,17 +164,14 @@ Error OS_JavaScript::execute(const String &p_path, const List<String> &p_argumen  }  Error OS_JavaScript::kill(const ProcessID &p_pid) { -  	ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "OS::kill() is not available on the HTML5 platform.");  }  int OS_JavaScript::get_process_id() const { -  	ERR_FAIL_V_MSG(0, "OS::get_process_id() is not available on the HTML5 platform.");  }  bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) { -  	if (p_feature == "HTML5" || p_feature == "web")  		return true; @@ -187,12 +184,10 @@ bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) {  }  String OS_JavaScript::get_executable_path() const { -  	return OS::get_executable_path();  }  Error OS_JavaScript::shell_open(String p_uri) { -  	// Open URI in a new tab, browser will deal with it by protocol.  	/* clang-format off */  	EM_ASM_({ @@ -203,37 +198,30 @@ Error OS_JavaScript::shell_open(String p_uri) {  }  String OS_JavaScript::get_name() const { -  	return "HTML5";  }  bool OS_JavaScript::can_draw() const { -  	return true; // Always?  }  String OS_JavaScript::get_user_data_dir() const { -  	return "/userfs";  };  String OS_JavaScript::get_cache_path() const { -  	return "/home/web_user/.cache";  }  String OS_JavaScript::get_config_path() const { -  	return "/home/web_user/.config";  }  String OS_JavaScript::get_data_path() const { -  	return "/home/web_user/.local/share";  }  void OS_JavaScript::file_access_close_callback(const String &p_file, int p_flags) { -  	OS_JavaScript *os = get_singleton();  	if (os->is_userfs_persistent() && p_file.begins_with("/userfs") && p_flags & FileAccess::WRITE) {  		os->last_sync_check_time = OS::get_singleton()->get_ticks_msec(); @@ -243,17 +231,14 @@ void OS_JavaScript::file_access_close_callback(const String &p_file, int p_flags  }  void OS_JavaScript::set_idb_available(bool p_idb_available) { -  	idb_available = p_idb_available;  }  bool OS_JavaScript::is_userfs_persistent() const { -  	return idb_available;  }  OS_JavaScript *OS_JavaScript::get_singleton() { -  	return static_cast<OS_JavaScript *>(OS::get_singleton());  } @@ -261,7 +246,6 @@ void OS_JavaScript::initialize_joypads() {  }  OS_JavaScript::OS_JavaScript() { -  	AudioDriverManager::add_driver(&audio_driver_javascript);  	Vector<Logger *> loggers; diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 0a81a4a5b3..f0f18b44f8 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -39,7 +39,6 @@  #include <emscripten/html5.h>  class OS_JavaScript : public OS_Unix { -  	MainLoop *main_loop = nullptr;  	AudioDriverJavaScript audio_driver_javascript; |