Merge pull request #91369 from adamscott/web-remote-debug
Add more Remote Debug options to the web platform
This commit is contained in:
commit
378b7c76f4
|
@ -585,32 +585,176 @@ bool EditorExportPlatformWeb::poll_export() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int prev = menu_options;
|
HTTPServerState prev_server_state = server_state;
|
||||||
menu_options = preset.is_valid();
|
server_state = HTTP_SERVER_STATE_OFF;
|
||||||
if (server->is_listening()) {
|
if (server->is_listening()) {
|
||||||
if (menu_options == 0) {
|
if (preset.is_null()) {
|
||||||
server->stop();
|
server->stop();
|
||||||
} else {
|
} else {
|
||||||
menu_options += 1;
|
server_state = HTTP_SERVER_STATE_ON;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return menu_options != prev;
|
|
||||||
|
return server_state != prev_server_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<ImageTexture> EditorExportPlatformWeb::get_option_icon(int p_index) const {
|
Ref<ImageTexture> EditorExportPlatformWeb::get_option_icon(int p_index) const {
|
||||||
return p_index == 1 ? stop_icon : EditorExportPlatform::get_option_icon(p_index);
|
Ref<ImageTexture> play_icon = EditorExportPlatform::get_option_icon(p_index);
|
||||||
|
|
||||||
|
switch (server_state) {
|
||||||
|
case HTTP_SERVER_STATE_OFF: {
|
||||||
|
switch (p_index) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
return play_icon;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case HTTP_SERVER_STATE_ON: {
|
||||||
|
switch (p_index) {
|
||||||
|
case 0:
|
||||||
|
return play_icon;
|
||||||
|
case 1:
|
||||||
|
return restart_icon;
|
||||||
|
case 2:
|
||||||
|
return stop_icon;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ERR_FAIL_V_MSG(nullptr, vformat(R"(EditorExportPlatformWeb option icon index "%s" is invalid.)", p_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
int EditorExportPlatformWeb::get_options_count() const {
|
int EditorExportPlatformWeb::get_options_count() const {
|
||||||
return menu_options;
|
if (server_state == HTTP_SERVER_STATE_ON) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
String EditorExportPlatformWeb::get_option_label(int p_index) const {
|
||||||
|
String run_in_browser = TTR("Run in Browser");
|
||||||
|
String start_http_server = TTR("Start HTTP Server");
|
||||||
|
String reexport_project = TTR("Re-export Project");
|
||||||
|
String stop_http_server = TTR("Stop HTTP Server");
|
||||||
|
|
||||||
|
switch (server_state) {
|
||||||
|
case HTTP_SERVER_STATE_OFF: {
|
||||||
|
switch (p_index) {
|
||||||
|
case 0:
|
||||||
|
return run_in_browser;
|
||||||
|
case 1:
|
||||||
|
return start_http_server;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case HTTP_SERVER_STATE_ON: {
|
||||||
|
switch (p_index) {
|
||||||
|
case 0:
|
||||||
|
return run_in_browser;
|
||||||
|
case 1:
|
||||||
|
return reexport_project;
|
||||||
|
case 2:
|
||||||
|
return stop_http_server;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ERR_FAIL_V_MSG("", vformat(R"(EditorExportPlatformWeb option label index "%s" is invalid.)", p_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
String EditorExportPlatformWeb::get_option_tooltip(int p_index) const {
|
||||||
|
String run_in_browser = TTR("Run exported HTML in the system's default browser.");
|
||||||
|
String start_http_server = TTR("Start the HTTP server.");
|
||||||
|
String reexport_project = TTR("Export project again to account for updates.");
|
||||||
|
String stop_http_server = TTR("Stop the HTTP server.");
|
||||||
|
|
||||||
|
switch (server_state) {
|
||||||
|
case HTTP_SERVER_STATE_OFF: {
|
||||||
|
switch (p_index) {
|
||||||
|
case 0:
|
||||||
|
return run_in_browser;
|
||||||
|
case 1:
|
||||||
|
return start_http_server;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case HTTP_SERVER_STATE_ON: {
|
||||||
|
switch (p_index) {
|
||||||
|
case 0:
|
||||||
|
return run_in_browser;
|
||||||
|
case 1:
|
||||||
|
return reexport_project;
|
||||||
|
case 2:
|
||||||
|
return stop_http_server;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ERR_FAIL_V_MSG("", vformat(R"(EditorExportPlatformWeb option tooltip index "%s" is invalid.)", p_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
Error EditorExportPlatformWeb::run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) {
|
Error EditorExportPlatformWeb::run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) {
|
||||||
if (p_option == 1) {
|
const uint16_t bind_port = EDITOR_GET("export/web/http_port");
|
||||||
server->stop();
|
// Resolve host if needed.
|
||||||
return OK;
|
const String bind_host = EDITOR_GET("export/web/http_host");
|
||||||
|
const bool use_tls = EDITOR_GET("export/web/use_tls");
|
||||||
|
|
||||||
|
switch (server_state) {
|
||||||
|
case HTTP_SERVER_STATE_OFF: {
|
||||||
|
switch (p_option) {
|
||||||
|
// Run in Browser.
|
||||||
|
case 0: {
|
||||||
|
Error err = _export_project(p_preset, p_debug_flags);
|
||||||
|
if (err != OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
err = _start_server(bind_host, bind_port, use_tls);
|
||||||
|
if (err != OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return _launch_browser(bind_host, bind_port, use_tls);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
// Start HTTP Server.
|
||||||
|
case 1: {
|
||||||
|
Error err = _export_project(p_preset, p_debug_flags);
|
||||||
|
if (err != OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return _start_server(bind_host, bind_port, use_tls);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case HTTP_SERVER_STATE_ON: {
|
||||||
|
switch (p_option) {
|
||||||
|
// Run in Browser.
|
||||||
|
case 0: {
|
||||||
|
Error err = _export_project(p_preset, p_debug_flags);
|
||||||
|
if (err != OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return _launch_browser(bind_host, bind_port, use_tls);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
// Re-export Project.
|
||||||
|
case 1: {
|
||||||
|
return _export_project(p_preset, p_debug_flags);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
// Stop HTTP Server.
|
||||||
|
case 2: {
|
||||||
|
return _stop_server();
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, vformat(R"(Trying to run EditorExportPlatformWeb, but option "%s" isn't known.)", p_option));
|
||||||
|
}
|
||||||
|
|
||||||
|
Error EditorExportPlatformWeb::_export_project(const Ref<EditorExportPreset> &p_preset, int p_debug_flags) {
|
||||||
const String dest = EditorPaths::get_singleton()->get_cache_dir().path_join("web");
|
const String dest = EditorPaths::get_singleton()->get_cache_dir().path_join("web");
|
||||||
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||||
if (!da->dir_exists(dest)) {
|
if (!da->dir_exists(dest)) {
|
||||||
|
@ -637,35 +781,40 @@ Error EditorExportPlatformWeb::run(const Ref<EditorExportPreset> &p_preset, int
|
||||||
DirAccess::remove_file_or_error(basepath + ".wasm");
|
DirAccess::remove_file_or_error(basepath + ".wasm");
|
||||||
DirAccess::remove_file_or_error(basepath + ".icon.png");
|
DirAccess::remove_file_or_error(basepath + ".icon.png");
|
||||||
DirAccess::remove_file_or_error(basepath + ".apple-touch-icon.png");
|
DirAccess::remove_file_or_error(basepath + ".apple-touch-icon.png");
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
const uint16_t bind_port = EDITOR_GET("export/web/http_port");
|
Error EditorExportPlatformWeb::_launch_browser(const String &p_bind_host, const uint16_t p_bind_port, const bool p_use_tls) {
|
||||||
// Resolve host if needed.
|
OS::get_singleton()->shell_open(String((p_use_tls ? "https://" : "http://") + p_bind_host + ":" + itos(p_bind_port) + "/tmp_js_export.html"));
|
||||||
const String bind_host = EDITOR_GET("export/web/http_host");
|
// FIXME: Find out how to clean up export files after running the successfully
|
||||||
|
// exported game. Might not be trivial.
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error EditorExportPlatformWeb::_start_server(const String &p_bind_host, const uint16_t p_bind_port, const bool p_use_tls) {
|
||||||
IPAddress bind_ip;
|
IPAddress bind_ip;
|
||||||
if (bind_host.is_valid_ip_address()) {
|
if (p_bind_host.is_valid_ip_address()) {
|
||||||
bind_ip = bind_host;
|
bind_ip = p_bind_host;
|
||||||
} else {
|
} else {
|
||||||
bind_ip = IP::get_singleton()->resolve_hostname(bind_host);
|
bind_ip = IP::get_singleton()->resolve_hostname(p_bind_host);
|
||||||
}
|
}
|
||||||
ERR_FAIL_COND_V_MSG(!bind_ip.is_valid(), ERR_INVALID_PARAMETER, "Invalid editor setting 'export/web/http_host': '" + bind_host + "'. Try using '127.0.0.1'.");
|
ERR_FAIL_COND_V_MSG(!bind_ip.is_valid(), ERR_INVALID_PARAMETER, "Invalid editor setting 'export/web/http_host': '" + p_bind_host + "'. Try using '127.0.0.1'.");
|
||||||
|
|
||||||
const bool use_tls = EDITOR_GET("export/web/use_tls");
|
|
||||||
const String tls_key = EDITOR_GET("export/web/tls_key");
|
const String tls_key = EDITOR_GET("export/web/tls_key");
|
||||||
const String tls_cert = EDITOR_GET("export/web/tls_certificate");
|
const String tls_cert = EDITOR_GET("export/web/tls_certificate");
|
||||||
|
|
||||||
// Restart server.
|
// Restart server.
|
||||||
server->stop();
|
server->stop();
|
||||||
err = server->listen(bind_port, bind_ip, use_tls, tls_key, tls_cert);
|
Error err = server->listen(p_bind_port, bind_ip, p_use_tls, tls_key, tls_cert);
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Run"), vformat(TTR("Error starting HTTP server: %d."), err));
|
add_message(EXPORT_MESSAGE_ERROR, TTR("Run"), vformat(TTR("Error starting HTTP server: %d."), err));
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
OS::get_singleton()->shell_open(String((use_tls ? "https://" : "http://") + bind_host + ":" + itos(bind_port) + "/tmp_js_export.html"));
|
Error EditorExportPlatformWeb::_stop_server() {
|
||||||
// FIXME: Find out how to clean up export files after running the successfully
|
server->stop();
|
||||||
// exported game. Might not be trivial.
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,8 +840,10 @@ EditorExportPlatformWeb::EditorExportPlatformWeb() {
|
||||||
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
|
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
|
||||||
if (theme.is_valid()) {
|
if (theme.is_valid()) {
|
||||||
stop_icon = theme->get_icon(SNAME("Stop"), EditorStringName(EditorIcons));
|
stop_icon = theme->get_icon(SNAME("Stop"), EditorStringName(EditorIcons));
|
||||||
|
restart_icon = theme->get_icon(SNAME("Reload"), EditorStringName(EditorIcons));
|
||||||
} else {
|
} else {
|
||||||
stop_icon.instantiate();
|
stop_icon.instantiate();
|
||||||
|
restart_icon.instantiate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,10 +46,16 @@
|
||||||
class EditorExportPlatformWeb : public EditorExportPlatform {
|
class EditorExportPlatformWeb : public EditorExportPlatform {
|
||||||
GDCLASS(EditorExportPlatformWeb, EditorExportPlatform);
|
GDCLASS(EditorExportPlatformWeb, EditorExportPlatform);
|
||||||
|
|
||||||
|
enum HTTPServerState {
|
||||||
|
HTTP_SERVER_STATE_OFF,
|
||||||
|
HTTP_SERVER_STATE_ON,
|
||||||
|
};
|
||||||
|
|
||||||
Ref<ImageTexture> logo;
|
Ref<ImageTexture> logo;
|
||||||
Ref<ImageTexture> run_icon;
|
Ref<ImageTexture> run_icon;
|
||||||
Ref<ImageTexture> stop_icon;
|
Ref<ImageTexture> stop_icon;
|
||||||
int menu_options = 0;
|
Ref<ImageTexture> restart_icon;
|
||||||
|
HTTPServerState server_state = HTTP_SERVER_STATE_OFF;
|
||||||
|
|
||||||
Ref<EditorHTTPServer> server;
|
Ref<EditorHTTPServer> server;
|
||||||
|
|
||||||
|
@ -96,6 +102,11 @@ class EditorExportPlatformWeb : public EditorExportPlatform {
|
||||||
Error _build_pwa(const Ref<EditorExportPreset> &p_preset, const String p_path, const Vector<SharedObject> &p_shared_objects);
|
Error _build_pwa(const Ref<EditorExportPreset> &p_preset, const String p_path, const Vector<SharedObject> &p_shared_objects);
|
||||||
Error _write_or_error(const uint8_t *p_content, int p_len, String p_path);
|
Error _write_or_error(const uint8_t *p_content, int p_len, String p_path);
|
||||||
|
|
||||||
|
Error _export_project(const Ref<EditorExportPreset> &p_preset, int p_debug_flags);
|
||||||
|
Error _launch_browser(const String &p_bind_host, uint16_t p_bind_port, bool p_use_tls);
|
||||||
|
Error _start_server(const String &p_bind_host, uint16_t p_bind_port, bool p_use_tls);
|
||||||
|
Error _stop_server();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override;
|
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override;
|
||||||
|
|
||||||
|
@ -112,8 +123,8 @@ public:
|
||||||
|
|
||||||
virtual bool poll_export() override;
|
virtual bool poll_export() override;
|
||||||
virtual int get_options_count() const override;
|
virtual int get_options_count() const override;
|
||||||
virtual String get_option_label(int p_index) const override { return p_index ? TTR("Stop HTTP Server") : TTR("Run in Browser"); }
|
virtual String get_option_label(int p_index) const override;
|
||||||
virtual String get_option_tooltip(int p_index) const override { return p_index ? TTR("Stop HTTP Server") : TTR("Run exported HTML in the system's default browser."); }
|
virtual String get_option_tooltip(int p_index) const override;
|
||||||
virtual Ref<ImageTexture> get_option_icon(int p_index) const override;
|
virtual Ref<ImageTexture> get_option_icon(int p_index) const override;
|
||||||
virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) override;
|
virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) override;
|
||||||
virtual Ref<Texture2D> get_run_icon() const override;
|
virtual Ref<Texture2D> get_run_icon() const override;
|
||||||
|
|
Loading…
Reference in New Issue