From f3841d644eec2366df6d30d7ce6b942504fb2a97 Mon Sep 17 00:00:00 2001 From: Raul Santos Date: Tue, 30 Jul 2024 18:19:42 +0200 Subject: [PATCH 01/20] C#: Generate signal delegates with typed arrays Signals with typed arrays were generating C# delegates with untyped arrays. --- modules/mono/editor/bindings_generator.cpp | 26 +++++++++------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 9a76a256395b..6bd99a8f22fd 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -2934,11 +2934,6 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output) { String arguments_sig; - String delegate_type_params; - - if (!p_isignal.arguments.is_empty()) { - delegate_type_params += "<"; - } // Retrieve information from the arguments const ArgumentInterface &first = p_isignal.arguments.front()->get(); @@ -2959,18 +2954,13 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf if (&iarg != &first) { arguments_sig += ", "; - delegate_type_params += ", "; } - arguments_sig += arg_type->cs_type; + String arg_cs_type = arg_type->cs_type + _get_generic_type_parameters(*arg_type, iarg.type.generic_type_parameters); + + arguments_sig += arg_cs_type; arguments_sig += " "; arguments_sig += iarg.name; - - delegate_type_params += arg_type->cs_type; - } - - if (!p_isignal.arguments.is_empty()) { - delegate_type_params += ">"; } // Generate signal @@ -3019,8 +3009,14 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf p_output << ", "; } - p_output << sformat(arg_type->cs_variant_to_managed, - "args[" + itos(idx) + "]", arg_type->cs_type, arg_type->name); + if (arg_type->cname == name_cache.type_Array_generic || arg_type->cname == name_cache.type_Dictionary_generic) { + String arg_cs_type = arg_type->cs_type + _get_generic_type_parameters(*arg_type, iarg.type.generic_type_parameters); + + p_output << "new " << arg_cs_type << "(" << sformat(arg_type->cs_variant_to_managed, "args[" + itos(idx) + "]", arg_type->cs_type, arg_type->name) << ")"; + } else { + p_output << sformat(arg_type->cs_variant_to_managed, + "args[" + itos(idx) + "]", arg_type->cs_type, arg_type->name); + } idx++; } From df0a88b128cb24c1e0e445d5e859c4cffc4f50d2 Mon Sep 17 00:00:00 2001 From: Thaddeus Crews Date: Tue, 10 Sep 2024 13:48:53 -0500 Subject: [PATCH 02/20] SCons: Fix `clang-cl` link/ar flags --- platform/windows/detect.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 684a7c34a002..f5de6c637d8a 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -620,18 +620,16 @@ def spawn_capture(sh, escape, cmd, args, env): print("ThinLTO is only compatible with LLVM, use `use_llvm=yes` or `lto=full`.") sys.exit(255) - env.Append(CCFLAGS=["-flto=thin"]) - env.Append(LINKFLAGS=["-flto=thin"]) + env.AppendUnique(CCFLAGS=["-flto=thin"]) elif env["use_llvm"]: - env.Append(CCFLAGS=["-flto"]) - env.Append(LINKFLAGS=["-flto"]) + env.AppendUnique(CCFLAGS=["-flto"]) else: env.AppendUnique(CCFLAGS=["/GL"]) - env.AppendUnique(ARFLAGS=["/LTCG"]) - if env["progress"]: - env.AppendUnique(LINKFLAGS=["/LTCG:STATUS"]) - else: - env.AppendUnique(LINKFLAGS=["/LTCG"]) + if env["progress"]: + env.AppendUnique(LINKFLAGS=["/LTCG:STATUS"]) + else: + env.AppendUnique(LINKFLAGS=["/LTCG"]) + env.AppendUnique(ARFLAGS=["/LTCG"]) if vcvars_msvc_config: env.Prepend(CPPPATH=[p for p in str(os.getenv("INCLUDE")).split(";")]) From 504e0656bb7d530204ce7deb20075b6569846d50 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Tue, 16 Apr 2024 17:34:01 +0800 Subject: [PATCH 03/20] Add TextEdit option to prevent copying without a selection --- doc/classes/EditorSettings.xml | 3 +++ doc/classes/TextEdit.xml | 3 +++ editor/code_editor.cpp | 3 +++ editor/editor_settings.cpp | 3 +++ scene/gui/code_edit.cpp | 3 +++ scene/gui/text_edit.cpp | 20 ++++++++++++++ scene/gui/text_edit.h | 4 +++ tests/scene/test_code_edit.h | 25 ++++++++++++++++++ tests/scene/test_text_edit.h | 48 ++++++++++++++++++++++++++++++++++ 9 files changed, 112 insertions(+) diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 389d65e05a0f..441978204061 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -1199,6 +1199,9 @@ If [code]true[/code], trims trailing whitespace when saving a script. Trailing whitespace refers to tab and space characters placed at the end of lines. Since these serve no practical purpose, they can and should be removed to make version control diffs less noisy. + + If [code]true[/code], copying or cutting without a selection is performed on all lines with a caret. Otherwise, copy and cut require a selection. + If [code]true[/code], automatically indents code when pressing the [kbd]Enter[/kbd] key based on blocks above the new line. diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index 6505e48fb9a3..05184336d160 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -1299,6 +1299,9 @@ If [code]false[/code], existing text cannot be modified and new text cannot be added. + + If [code]true[/code], copying or cutting without a selection is performed on all lines with a caret. Otherwise, copy and cut require a selection. + If [code]true[/code], all occurrences of the selected text will be highlighted. diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index dd8aa523c46b..7d895ce519ac 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1068,6 +1068,9 @@ void CodeTextEditor::update_editor_settings() { text_editor->set_draw_spaces(EDITOR_GET("text_editor/appearance/whitespace/draw_spaces")); text_editor->add_theme_constant_override("line_spacing", EDITOR_GET("text_editor/appearance/whitespace/line_spacing")); + // Behavior: General + text_editor->set_empty_selection_clipboard_enabled(EDITOR_GET("text_editor/behavior/general/empty_selection_clipboard")); + // Behavior: Navigation text_editor->set_scroll_past_end_of_file_enabled(EDITOR_GET("text_editor/behavior/navigation/scroll_past_end_of_file")); text_editor->set_smooth_scroll_enabled(EDITOR_GET("text_editor/behavior/navigation/smooth_scrolling")); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 96a7700c34a5..c7d8ee32f2cf 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -657,6 +657,9 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "text_editor/appearance/whitespace/line_spacing", 4, "0,50,1") // Behavior + // Behavior: General + _initial_set("text_editor/behavior/general/empty_selection_clipboard", true); + // Behavior: Navigation _initial_set("text_editor/behavior/navigation/move_caret_on_right_click", true); _initial_set("text_editor/behavior/navigation/scroll_past_end_of_file", false); diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index c3287035ffce..635228670d08 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -831,6 +831,9 @@ void CodeEdit::_cut_internal(int p_caret) { delete_selection(p_caret); return; } + if (!is_empty_selection_clipboard_enabled()) { + return; + } if (p_caret == -1) { delete_lines(); } else { diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index d7799588ead2..16e32be26ec2 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -3366,6 +3366,14 @@ bool TextEdit::is_middle_mouse_paste_enabled() const { return middle_mouse_paste_enabled; } +void TextEdit::set_empty_selection_clipboard_enabled(bool p_enabled) { + empty_selection_clipboard_enabled = p_enabled; +} + +bool TextEdit::is_empty_selection_clipboard_enabled() const { + return empty_selection_clipboard_enabled; +} + // Text manipulation void TextEdit::clear() { setting_text = true; @@ -6568,6 +6576,9 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_middle_mouse_paste_enabled", "enabled"), &TextEdit::set_middle_mouse_paste_enabled); ClassDB::bind_method(D_METHOD("is_middle_mouse_paste_enabled"), &TextEdit::is_middle_mouse_paste_enabled); + ClassDB::bind_method(D_METHOD("set_empty_selection_clipboard_enabled", "enabled"), &TextEdit::set_empty_selection_clipboard_enabled); + ClassDB::bind_method(D_METHOD("is_empty_selection_clipboard_enabled"), &TextEdit::is_empty_selection_clipboard_enabled); + // Text manipulation ClassDB::bind_method(D_METHOD("clear"), &TextEdit::clear); @@ -6961,6 +6972,7 @@ void TextEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_and_drop_selection_enabled"), "set_drag_and_drop_selection_enabled", "is_drag_and_drop_selection_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "virtual_keyboard_enabled"), "set_virtual_keyboard_enabled", "is_virtual_keyboard_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "middle_mouse_paste_enabled"), "set_middle_mouse_paste_enabled", "is_middle_mouse_paste_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "empty_selection_clipboard_enabled"), "set_empty_selection_clipboard_enabled", "is_empty_selection_clipboard_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "wrap_mode", PROPERTY_HINT_ENUM, "None,Boundary"), "set_line_wrapping_mode", "get_line_wrapping_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Arbitrary:1,Word:2,Word (Smart):3"), "set_autowrap_mode", "get_autowrap_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "indent_wrapped_lines"), "set_indent_wrapped_lines", "is_indent_wrapped_lines"); @@ -7215,6 +7227,10 @@ void TextEdit::_cut_internal(int p_caret) { return; } + if (!empty_selection_clipboard_enabled) { + return; + } + // Remove full lines. begin_complex_operation(); begin_multicaret_edit(); @@ -7245,6 +7261,10 @@ void TextEdit::_copy_internal(int p_caret) { return; } + if (!empty_selection_clipboard_enabled) { + return; + } + // Copy full lines. StringBuilder clipboard; Vector line_ranges; diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index c5f838020bd5..94b105d48615 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -319,6 +319,7 @@ class TextEdit : public Control { bool shortcut_keys_enabled = true; bool virtual_keyboard_enabled = true; bool middle_mouse_paste_enabled = true; + bool empty_selection_clipboard_enabled = true; // Overridable actions. String cut_copy_line = ""; @@ -770,6 +771,9 @@ class TextEdit : public Control { void set_middle_mouse_paste_enabled(bool p_enabled); bool is_middle_mouse_paste_enabled() const; + void set_empty_selection_clipboard_enabled(bool p_enabled); + bool is_empty_selection_clipboard_enabled() const; + // Text manipulation void clear(); diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h index 9ec1b812dfc4..ef630ad4f79c 100644 --- a/tests/scene/test_code_edit.h +++ b/tests/scene/test_code_edit.h @@ -4779,6 +4779,31 @@ TEST_CASE("[SceneTree][CodeEdit] text manipulation") { CHECK(code_edit->get_caret_column(3) == 0); } + SUBCASE("[SceneTree][CodeEdit] cut when empty selection clipboard disabled") { + DisplayServerMock *DS = (DisplayServerMock *)(DisplayServer::get_singleton()); + code_edit->set_empty_selection_clipboard_enabled(false); + DS->clipboard_set(""); + + code_edit->set_text("this is\nsome\n"); + code_edit->set_caret_line(0); + code_edit->set_caret_column(6); + MessageQueue::get_singleton()->flush(); + SIGNAL_DISCARD("text_set"); + SIGNAL_DISCARD("text_changed"); + SIGNAL_DISCARD("lines_edited_from"); + SIGNAL_DISCARD("caret_changed"); + + code_edit->cut(); + MessageQueue::get_singleton()->flush(); + CHECK(DS->clipboard_get() == ""); + CHECK(code_edit->get_text() == "this is\nsome\n"); + CHECK(code_edit->get_caret_line() == 0); + CHECK(code_edit->get_caret_column() == 6); + SIGNAL_CHECK_FALSE("caret_changed"); + SIGNAL_CHECK_FALSE("text_changed"); + SIGNAL_CHECK_FALSE("lines_edited_from"); + } + SUBCASE("[SceneTree][CodeEdit] new line") { // Add a new line. code_edit->set_text("test new line"); diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h index 46a5046b21cc..c41eebdf3a4a 100644 --- a/tests/scene/test_text_edit.h +++ b/tests/scene/test_text_edit.h @@ -3585,6 +3585,54 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_CHECK_FALSE("lines_edited_from"); } + SUBCASE("[TextEdit] cut when empty selection clipboard disabled") { + text_edit->set_empty_selection_clipboard_enabled(false); + DS->clipboard_set(""); + + text_edit->set_text("this is\nsome\n"); + text_edit->set_caret_line(0); + text_edit->set_caret_column(6); + MessageQueue::get_singleton()->flush(); + SIGNAL_DISCARD("text_set"); + SIGNAL_DISCARD("text_changed"); + SIGNAL_DISCARD("lines_edited_from"); + SIGNAL_DISCARD("caret_changed"); + + text_edit->cut(); + MessageQueue::get_singleton()->flush(); + CHECK(DS->clipboard_get() == ""); + CHECK(text_edit->get_text() == "this is\nsome\n"); + CHECK(text_edit->get_caret_line() == 0); + CHECK(text_edit->get_caret_column() == 6); + SIGNAL_CHECK_FALSE("caret_changed"); + SIGNAL_CHECK_FALSE("text_changed"); + SIGNAL_CHECK_FALSE("lines_edited_from"); + } + + SUBCASE("[TextEdit] copy when empty selection clipboard disabled") { + text_edit->set_empty_selection_clipboard_enabled(false); + DS->clipboard_set(""); + + text_edit->set_text("this is\nsome\n"); + text_edit->set_caret_line(0); + text_edit->set_caret_column(6); + MessageQueue::get_singleton()->flush(); + SIGNAL_DISCARD("text_set"); + SIGNAL_DISCARD("text_changed"); + SIGNAL_DISCARD("lines_edited_from"); + SIGNAL_DISCARD("caret_changed"); + + text_edit->copy(); + MessageQueue::get_singleton()->flush(); + CHECK(DS->clipboard_get() == ""); + CHECK(text_edit->get_text() == "this is\nsome\n"); + CHECK(text_edit->get_caret_line() == 0); + CHECK(text_edit->get_caret_column() == 6); + SIGNAL_CHECK_FALSE("caret_changed"); + SIGNAL_CHECK_FALSE("text_changed"); + SIGNAL_CHECK_FALSE("lines_edited_from"); + } + SIGNAL_UNWATCH(text_edit, "text_set"); SIGNAL_UNWATCH(text_edit, "text_changed"); SIGNAL_UNWATCH(text_edit, "lines_edited_from"); From 4c72d599f0a171a96e47004239f42756115b723f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Wed, 18 Sep 2024 11:50:54 +0200 Subject: [PATCH 04/20] miniupnpc: Update to 2.2.8 (new major 18) Keep support for major 17 by using a version check for the changed API. Fixes #93907. --- modules/upnp/upnp.cpp | 4 + thirdparty/README.md | 2 +- thirdparty/miniupnpc/include/miniupnpc.h | 19 +++-- thirdparty/miniupnpc/src/addr_is_reserved.c | 11 ++- thirdparty/miniupnpc/src/minisoap.c | 7 +- thirdparty/miniupnpc/src/minissdpc.c | 9 +- thirdparty/miniupnpc/src/miniupnpc.c | 93 +++++++++------------ thirdparty/miniupnpc/src/miniupnpcstrings.h | 2 +- thirdparty/miniupnpc/src/miniwget.c | 44 +--------- thirdparty/miniupnpc/src/win32_snprintf.h | 4 +- 10 files changed, 79 insertions(+), 116 deletions(-) diff --git a/modules/upnp/upnp.cpp b/modules/upnp/upnp.cpp index 6bdb261b5099..4305bf842afd 100644 --- a/modules/upnp/upnp.cpp +++ b/modules/upnp/upnp.cpp @@ -131,7 +131,11 @@ void UPNP::parse_igd(Ref dev, UPNPDev *devlist) { GetUPNPUrls(&urls, &data, dev->get_description_url().utf8().get_data(), 0); char addr[16]; +#if MINIUPNPC_API_VERSION >= 18 + int i = UPNP_GetValidIGD(devlist, &urls, &data, (char *)&addr, 16, nullptr, 0); +#else int i = UPNP_GetValidIGD(devlist, &urls, &data, (char *)&addr, 16); +#endif if (i != 1) { FreeUPNPUrls(&urls); diff --git a/thirdparty/README.md b/thirdparty/README.md index a6686c539a66..4c47b91c8cd4 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -614,7 +614,7 @@ to solve some MSVC warnings. See the patches in the `patches` directory. ## miniupnpc - Upstream: https://github.com/miniupnp/miniupnp -- Version: 2.2.7 (d4d5ec7d48c093b37b2ea5d7171ede21ce9d7ff2, 2024) +- Version: 2.2.8 (b55145ec095652289a59c33603f3abafee898273, 2024) - License: BSD-3-Clause Files extracted from upstream source: diff --git a/thirdparty/miniupnpc/include/miniupnpc.h b/thirdparty/miniupnpc/include/miniupnpc.h index 808c6ad975f7..fd951a0836b7 100644 --- a/thirdparty/miniupnpc/include/miniupnpc.h +++ b/thirdparty/miniupnpc/include/miniupnpc.h @@ -1,9 +1,9 @@ -/* $Id: miniupnpc.h,v 1.63 2024/01/04 00:45:17 nanard Exp $ */ +/* $Id: miniupnpc.h,v 1.66 2024/06/08 22:13:14 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project: miniupnp * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author: Thomas Bernard - * Copyright (c) 2005-2022 Thomas Bernard + * Copyright (c) 2005-2024 Thomas Bernard * This software is subjects to the conditions detailed * in the LICENCE file provided within this distribution */ #ifndef MINIUPNPC_H_INCLUDED @@ -20,8 +20,8 @@ #define UPNPDISCOVER_MEMORY_ERROR (-102) /* versions : */ -#define MINIUPNPC_VERSION "2.2.6" -#define MINIUPNPC_API_VERSION 17 +#define MINIUPNPC_VERSION "2.2.8" +#define MINIUPNPC_API_VERSION 18 /* Source port: Using "1" as an alias for 1900 for backwards compatibility @@ -108,9 +108,11 @@ struct UPNPUrls { * return values : * 0 = NO IGD found * 1 = A valid connected IGD has been found - * 2 = A valid IGD has been found but it reported as + * 2 = A valid connected IGD has been found but its + * IP address is reserved (non routable) + * 3 = A valid IGD has been found but it reported as * not connected - * 3 = an UPnP device has been found but was not recognized as an IGD + * 4 = an UPnP device has been found but was not recognized as an IGD * * In any non zero return case, the urls and data structures * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to @@ -119,8 +121,9 @@ struct UPNPUrls { MINIUPNP_LIBSPEC int UPNP_GetValidIGD(struct UPNPDev * devlist, struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen); + struct IGDdatas * data, + char * lanaddr, int lanaddrlen, + char * wanaddr, int wanaddrlen); /* UPNP_GetIGDFromUrl() * Used when skipping the discovery process. diff --git a/thirdparty/miniupnpc/src/addr_is_reserved.c b/thirdparty/miniupnpc/src/addr_is_reserved.c index 18c64242015b..145b504823a1 100644 --- a/thirdparty/miniupnpc/src/addr_is_reserved.c +++ b/thirdparty/miniupnpc/src/addr_is_reserved.c @@ -3,7 +3,7 @@ * Project : miniupnp * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author : Thomas BERNARD - * copyright (c) 2005-2021 Thomas Bernard + * copyright (c) 2005-2024 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENSE file. */ #ifdef _WIN32 @@ -21,6 +21,9 @@ typedef unsigned long uint32_t; #include #include #endif /* _WIN32 */ +#ifdef DEBUG +#include +#endif /* List of IP address blocks which are private / reserved and therefore not suitable for public external IP addresses */ #define IP(a, b, c, d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) @@ -71,8 +74,12 @@ int addr_is_reserved(const char * addr_str) address = ntohl(addr_n); for (i = 0; i < sizeof(reserved)/sizeof(reserved[0]); ++i) { - if ((address >> reserved[i].rmask) == (reserved[i].address >> reserved[i].rmask)) + if ((address >> reserved[i].rmask) == (reserved[i].address >> reserved[i].rmask)) { +#ifdef DEBUG + printf("IP address %s is reserved\n", addr_str); +#endif return 1; + } } return 0; diff --git a/thirdparty/miniupnpc/src/minisoap.c b/thirdparty/miniupnpc/src/minisoap.c index 903ac5ffc615..5c6bf0168459 100644 --- a/thirdparty/miniupnpc/src/minisoap.c +++ b/thirdparty/miniupnpc/src/minisoap.c @@ -2,7 +2,7 @@ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005-2023 Thomas Bernard + * Copyright (c) 2005-2024 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * @@ -83,7 +83,7 @@ int soapPostSubmit(SOCKET fd, * Using HTTP/1.1 means we need to support chunked transfer-encoding : * When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked * transfer encoding. */ - /* Connection: Close is normally there only in HTTP/1.1 but who knows */ + /* Connection: close is normally there only in HTTP/1.1 but who knows */ portstr[0] = '\0'; if(port != 80) snprintf(portstr, sizeof(portstr), ":%hu", port); @@ -98,9 +98,8 @@ int soapPostSubmit(SOCKET fd, "Content-Type: text/xml; charset=\"utf-8\"\r\n" #endif "SOAPAction: \"%s\"\r\n" - "Connection: Close\r\n" + "Connection: close\r\n" "Cache-Control: no-cache\r\n" /* ??? */ - "Pragma: no-cache\r\n" "\r\n", url, httpversion, host, portstr, bodysize, action); if ((unsigned int)headerssize >= sizeof(headerbuf)) diff --git a/thirdparty/miniupnpc/src/minissdpc.c b/thirdparty/miniupnpc/src/minissdpc.c index 98c5b37463ff..57cb99962e65 100644 --- a/thirdparty/miniupnpc/src/minissdpc.c +++ b/thirdparty/miniupnpc/src/minissdpc.c @@ -1,9 +1,9 @@ -/* $Id: minissdpc.c,v 1.49 2021/05/13 11:00:36 nanard Exp $ */ +/* $Id: minissdpc.c,v 1.51 2024/05/16 00:12:05 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project : miniupnp * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author : Thomas BERNARD - * copyright (c) 2005-2021 Thomas Bernard + * copyright (c) 2005-2024 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENCE file. */ #include @@ -548,7 +548,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], #ifdef _WIN32 unsigned long _ttl = (unsigned long)ttl; #endif - int linklocal = 1; + int linklocal = 0; /* try first with site-local multicast */ int sentok; if(error) @@ -1007,9 +1007,10 @@ ssdpDiscoverDevices(const char * const deviceTypes[], /* switch linklocal flag */ if(linklocal) { linklocal = 0; - --deviceIndex; } else { + /* try again with linklocal multicast */ linklocal = 1; + --deviceIndex; } } } diff --git a/thirdparty/miniupnpc/src/miniupnpc.c b/thirdparty/miniupnpc/src/miniupnpc.c index 696af932372d..9da1496b3786 100644 --- a/thirdparty/miniupnpc/src/miniupnpc.c +++ b/thirdparty/miniupnpc/src/miniupnpc.c @@ -3,7 +3,7 @@ * Project : miniupnp * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author : Thomas BERNARD - * copyright (c) 2005-2021 Thomas Bernard + * copyright (c) 2005-2024 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENSE file. */ #include @@ -92,15 +92,15 @@ MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGD #endif } -/* simpleUPnPcommand2 : +/* simpleUPnPcommand : * not so simple ! * return values : * pointer - OK * NULL - error */ -static char * -simpleUPnPcommand2(SOCKET s, const char * url, const char * service, - const char * action, struct UPNParg * args, - int * bufsize, const char * httpversion) +char * +simpleUPnPcommand(int s, const char * url, const char * service, + const char * action, struct UPNParg * args, + int * bufsize) { char hostname[MAXHOSTNAMELEN+1]; unsigned short port = 0; @@ -197,15 +197,15 @@ simpleUPnPcommand2(SOCKET s, const char * url, const char * service, return NULL; } if(!parseURL(url, hostname, &port, &path, NULL)) return NULL; - if(ISINVALID(s)) { + if(ISINVALID((SOCKET)s)) { s = connecthostport(hostname, port, 0); - if(ISINVALID(s)) { + if(ISINVALID((SOCKET)s)) { /* failed to connect */ return NULL; } } - n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion); + n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, "1.1"); if(n<=0) { #ifdef DEBUG printf("Error sending SOAP request\n"); @@ -229,33 +229,6 @@ simpleUPnPcommand2(SOCKET s, const char * url, const char * service, return buf; } -/* simpleUPnPcommand : - * not so simple ! - * return values : - * pointer - OK - * NULL - error */ -char * -simpleUPnPcommand(int s, const char * url, const char * service, - const char * action, struct UPNParg * args, - int * bufsize) -{ - char * buf; - -#if 1 - buf = simpleUPnPcommand2((SOCKET)s, url, service, action, args, bufsize, "1.1"); -#else - buf = simpleUPnPcommand2((SOCKET)s, url, service, action, args, bufsize, "1.0"); - if (!buf || *bufsize == 0) - { -#if DEBUG - printf("Error or no result from SOAP request; retrying with HTTP/1.1\n"); -#endif - buf = simpleUPnPcommand2((SOCKET)s, url, service, action, args, bufsize, "1.1"); - } -#endif - return buf; -} - /* upnpDiscoverDevices() : * return a chained list of all devices found or NULL if * no devices was found. @@ -534,9 +507,11 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data) * -1 = Internal error * 0 = NO IGD found * 1 = A valid connected IGD has been found - * 2 = A valid IGD has been found but it reported as + * 2 = A valid connected IGD has been found but its + * IP address is reserved (non routable) + * 3 = A valid IGD has been found but it reported as * not connected - * 3 = an UPnP device has been found but was not recognized as an IGD + * 4 = an UPnP device has been found but was not recognized as an IGD * * In any positive non zero return case, the urls and data structures * passed as parameters are set. Don't forget to call FreeUPNPUrls(urls) to @@ -545,11 +520,13 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data) MINIUPNP_LIBSPEC int UPNP_GetValidIGD(struct UPNPDev * devlist, struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen) + struct IGDdatas * data, + char * lanaddr, int lanaddrlen, + char * wanaddr, int wanaddrlen) { struct xml_desc { char lanaddr[40]; + char wanaddr[40]; char * xml; int size; int is_igd; @@ -557,8 +534,8 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, struct UPNPDev * dev; int ndev = 0; int i; - int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */ - char extIpAddr[16]; + int state = -1; /* state 1 : IGD connected. State 2 : connected with reserved IP. + * State 3 : IGD. State 4 : anything */ int status_code = -1; if(!devlist) @@ -602,7 +579,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, } } /* iterate the list to find a device depending on state */ - for(state = 1; state <= 3; state++) + for(state = 1; state <= 4; state++) { for(dev = devlist, i = 0; dev; dev = dev->pNext, i++) { @@ -611,14 +588,14 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, memset(data, 0, sizeof(struct IGDdatas)); memset(urls, 0, sizeof(struct UPNPUrls)); parserootdesc(desc[i].xml, desc[i].size, data); - if(desc[i].is_igd || state >= 3 ) + if(desc[i].is_igd || state >= 4 ) { int is_connected; GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); - /* in state 2 and 3 we don't test if device is connected ! */ - if(state >= 2) + /* in state 3 and 4 we don't test if device is connected ! */ + if(state >= 3) goto free_and_return; is_connected = UPNPIGD_IsConnected(urls, data); #ifdef DEBUG @@ -626,9 +603,11 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, urls->controlURL, is_connected); #endif /* checks that status is connected AND there is a external IP address assigned */ - if(is_connected && - (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { - if(!addr_is_reserved(extIpAddr)) + if(is_connected) { + if(state >= 2) + goto free_and_return; + if(UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, desc[i].wanaddr) == 0 + && !addr_is_reserved(desc[i].wanaddr)) goto free_and_return; } FreeUPNPUrls(urls); @@ -647,9 +626,11 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, printf("UPNPIGD_IsConnected(%s) = %d\n", urls->controlURL, is_connected); #endif - if(is_connected && - (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { - if(!addr_is_reserved(extIpAddr)) + if(is_connected) { + if(state >= 2) + goto free_and_return; + if(UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, desc[i].wanaddr) == 0 + && !addr_is_reserved(desc[i].wanaddr)) goto free_and_return; } FreeUPNPUrls(urls); @@ -661,8 +642,12 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, } state = 0; free_and_return: - if (lanaddr != NULL && state >= 1 && state <= 3 && i < ndev) - strncpy(lanaddr, desc[i].lanaddr, lanaddrlen); + if (state >= 1 && state <= 4 && i < ndev) { + if (lanaddr != NULL) + strncpy(lanaddr, desc[i].lanaddr, lanaddrlen); + if (wanaddr != NULL) + strncpy(wanaddr, desc[i].wanaddr, wanaddrlen); + } for(i = 0; i < ndev; i++) free(desc[i].xml); free(desc); diff --git a/thirdparty/miniupnpc/src/miniupnpcstrings.h b/thirdparty/miniupnpc/src/miniupnpcstrings.h index f5730111af57..d40c2455ba85 100644 --- a/thirdparty/miniupnpc/src/miniupnpcstrings.h +++ b/thirdparty/miniupnpc/src/miniupnpcstrings.h @@ -2,7 +2,7 @@ #define MINIUPNPCSTRINGS_H_INCLUDED #define OS_STRING "Godot Engine/1.0" -#define MINIUPNPC_VERSION_STRING "2.2.7" +#define MINIUPNPC_VERSION_STRING "2.2.8" #if 0 /* according to "UPnP Device Architecture 1.0" */ diff --git a/thirdparty/miniupnpc/src/miniwget.c b/thirdparty/miniupnpc/src/miniwget.c index e76a5e516b47..a7a32dfdbafb 100644 --- a/thirdparty/miniupnpc/src/miniwget.c +++ b/thirdparty/miniupnpc/src/miniwget.c @@ -2,7 +2,7 @@ /* Project : miniupnp * Website : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author : Thomas Bernard - * Copyright (c) 2005-2023 Thomas Bernard + * Copyright (c) 2005-2024 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -443,9 +443,8 @@ miniwget3(const char * host, len = snprintf(buf, sizeof(buf), "GET %s HTTP/%s\r\n" "Host: %s:%d\r\n" - "Connection: Close\r\n" + "Connection: close\r\n" "User-Agent: " OS_STRING " " UPNP_VERSION_STRING " MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" - "\r\n", path, httpversion, host, port); if ((unsigned int)len >= sizeof(buf)) @@ -474,41 +473,6 @@ miniwget3(const char * host, return content; } -/* miniwget2() : - * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */ -static void * -miniwget2(const char * host, - unsigned short port, const char * path, - int * size, char * addr_str, int addr_str_len, - unsigned int scope_id, int * status_code) -{ - char * respbuffer; - -#if 1 - respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.1", - scope_id, status_code); -#else - respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.0", - scope_id, status_code); - if (*size == 0) - { -#ifdef DEBUG - printf("Retrying with HTTP/1.1\n"); -#endif - free(respbuffer); - respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.1", - scope_id, status_code); - } -#endif - return respbuffer; -} - - - - /* parseURL() * arguments : * url : source string not modified @@ -639,7 +603,7 @@ miniwget(const char * url, int * size, printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", hostname, port, path, scope_id); #endif - return miniwget2(hostname, port, path, size, 0, 0, scope_id, status_code); + return miniwget3(hostname, port, path, size, 0, 0, "1.1", scope_id, status_code); } void * @@ -660,5 +624,5 @@ miniwget_getaddr(const char * url, int * size, printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", hostname, port, path, scope_id); #endif - return miniwget2(hostname, port, path, size, addr, addrlen, scope_id, status_code); + return miniwget3(hostname, port, path, size, addr, addrlen, "1.1", scope_id, status_code); } diff --git a/thirdparty/miniupnpc/src/win32_snprintf.h b/thirdparty/miniupnpc/src/win32_snprintf.h index 1fc284ecffc2..5064df63bcbc 100644 --- a/thirdparty/miniupnpc/src/win32_snprintf.h +++ b/thirdparty/miniupnpc/src/win32_snprintf.h @@ -23,9 +23,9 @@ (defined(_MSC_VER) && _MSC_VER < 1900) /* Visual Studio older than 2015 */ || \ (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && defined(__NO_ISOCEXT)) /* mingw32 without iso c ext */ || \ (defined(__MINGW64_VERSION_MAJOR) && /* mingw-w64 not ... */ !( \ - (defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO != 0)) /* ... with ansi stdio */ || \ + (defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO != 0) /* ... with ansi stdio */ || \ (__MINGW64_VERSION_MAJOR >= 6 && defined(_UCRT)) /* ... at least 6.0.0 with ucrt */ || \ - (__MINGW64_VERSION_MAJOR >= 8 && !defined(__NO_ISOCEXT)) /* ... at least 8.0.0 with iso c ext */ || \ + (__MINGW64_VERSION_MAJOR >= 8 && !defined(__NO_ISOCEXT))) /* ... at least 8.0.0 with iso c ext */ || \ 0) || \ 0) From 714357e55cf77902cbb41f45f6d75b314b6b2993 Mon Sep 17 00:00:00 2001 From: aaronp64 Date: Mon, 5 Aug 2024 11:03:14 -0400 Subject: [PATCH 05/20] Assign return value on Variant operator failure Variant operators for String formatting and "in" could result in errors, which would return from validated_evaluate without assigning r_ret. This would cause scripts using the return value from these operators to get results from previously run code. Updated to return the original String value in the String formatting case, and false for "in" when an error occurs. --- core/variant/variant_op.h | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h index ac39a4135fca..0bd8b830e073 100644 --- a/core/variant/variant_op.h +++ b/core/variant/variant_op.h @@ -923,7 +923,10 @@ class OperatorEvaluatorStringFormat { static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { bool valid = true; String result = do_mod(*VariantGetInternalPtr::get_ptr(left), &valid); - ERR_FAIL_COND_MSG(!valid, result); + if (unlikely(!valid)) { + *VariantGetInternalPtr::get_ptr(r_ret) = *VariantGetInternalPtr::get_ptr(left); + ERR_FAIL_MSG(vformat("String formatting error: %s.", result)); + } *VariantGetInternalPtr::get_ptr(r_ret) = result; } static void ptr_evaluate(const void *left, const void *right, void *r_ret) { @@ -948,7 +951,10 @@ class OperatorEvaluatorStringFormat { static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { bool valid = true; String result = do_mod(*VariantGetInternalPtr::get_ptr(left), *VariantGetInternalPtr::get_ptr(right), &valid); - ERR_FAIL_COND_MSG(!valid, result); + if (unlikely(!valid)) { + *VariantGetInternalPtr::get_ptr(r_ret) = *VariantGetInternalPtr::get_ptr(left); + ERR_FAIL_MSG(vformat("String formatting error: %s.", result)); + } *VariantGetInternalPtr::get_ptr(r_ret) = result; } static void ptr_evaluate(const void *left, const void *right, void *r_ret) { @@ -976,7 +982,10 @@ class OperatorEvaluatorStringFormat { static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { bool valid = true; String result = do_mod(*VariantGetInternalPtr::get_ptr(left), right->get_validated_object(), &valid); - ERR_FAIL_COND_MSG(!valid, result); + if (unlikely(!valid)) { + *VariantGetInternalPtr::get_ptr(r_ret) = *VariantGetInternalPtr::get_ptr(left); + ERR_FAIL_MSG(vformat("String formatting error: %s.", result)); + } *VariantGetInternalPtr::get_ptr(r_ret) = result; } static void ptr_evaluate(const void *left, const void *right, void *r_ret) { @@ -1003,7 +1012,10 @@ class OperatorEvaluatorStringFormat { static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { bool valid = true; String result = do_mod(*VariantGetInternalPtr::get_ptr(left), *VariantGetInternalPtr::get_ptr(right), &valid); - ERR_FAIL_COND_MSG(!valid, result); + if (unlikely(!valid)) { + *VariantGetInternalPtr::get_ptr(r_ret) = *VariantGetInternalPtr::get_ptr(left); + ERR_FAIL_MSG(vformat("String formatting error: %s.", result)); + } *VariantGetInternalPtr::get_ptr(r_ret) = result; } static void ptr_evaluate(const void *left, const void *right, void *r_ret) { @@ -1492,7 +1504,10 @@ class OperatorEvaluatorObjectHasPropertyString { } static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { Object *l = right->get_validated_object(); - ERR_FAIL_NULL(l); + if (unlikely(!l)) { + *VariantGetInternalPtr::get_ptr(r_ret) = false; + ERR_FAIL_MSG("Invalid base object for 'in'."); + } const String &a = *VariantGetInternalPtr::get_ptr(left); bool valid; @@ -1526,7 +1541,10 @@ class OperatorEvaluatorObjectHasPropertyStringName { } static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { Object *l = right->get_validated_object(); - ERR_FAIL_NULL(l); + if (unlikely(!l)) { + *VariantGetInternalPtr::get_ptr(r_ret) = false; + ERR_FAIL_MSG("Invalid base object for 'in'."); + } const StringName &a = *VariantGetInternalPtr::get_ptr(left); bool valid; From f7e5e7a40053648584e1d69f25fc398a8142da8d Mon Sep 17 00:00:00 2001 From: David Snopek Date: Thu, 19 Sep 2024 16:54:05 -0500 Subject: [PATCH 06/20] OpenXR: Allow extending Android surface swapchain creation from GDExtension --- .../doc_classes/OpenXRExtensionWrapperExtension.xml | 9 +++++++++ .../openxr_composition_layer_extension.cpp | 11 +++++++++-- .../openxr/extensions/openxr_extension_wrapper.h | 3 ++- .../openxr_extension_wrapper_extension.cpp | 13 ++++++++++++- .../extensions/openxr_extension_wrapper_extension.h | 4 +++- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml b/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml index 338d63252418..813c9d582ebb 100644 --- a/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml +++ b/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml @@ -178,6 +178,15 @@ [param layer] is a pointer to an [code]XrCompositionLayerBaseHeader[/code] struct. + + + + + + Adds additional data structures to Android surface swapchains created by [OpenXRCompositionLayer]. + [param property_values] contains the values of the properties returned by [method _get_viewport_composition_layer_extension_properties]. + + diff --git a/modules/openxr/extensions/openxr_composition_layer_extension.cpp b/modules/openxr/extensions/openxr_composition_layer_extension.cpp index 83e45ffe7f3d..dc30b95b27e9 100644 --- a/modules/openxr/extensions/openxr_composition_layer_extension.cpp +++ b/modules/openxr/extensions/openxr_composition_layer_extension.cpp @@ -144,7 +144,6 @@ bool OpenXRCompositionLayerExtension::create_android_surface_swapchain(XrSwapcha OpenXRAPI *openxr_api = OpenXRAPI::get_singleton(); ERR_FAIL_NULL_V(openxr_api, false); - // @todo We need a way to add to the next pointer chain. XrResult result = xrCreateSwapchainAndroidSurfaceKHR(openxr_api->get_session(), p_info, r_swapchain, r_surface); if (XR_FAILED(result)) { print_line("OpenXR: Failed to create Android surface swapchain [", openxr_api->get_error_string(result), "]"); @@ -254,11 +253,19 @@ void OpenXRViewportCompositionLayerProvider::create_android_surface() { ERR_FAIL_COND(android_surface.swapchain != XR_NULL_HANDLE || android_surface.surface.is_valid()); ERR_FAIL_COND(!openxr_api || !openxr_api->is_running()); + void *next_pointer = nullptr; + for (OpenXRExtensionWrapper *wrapper : openxr_api->get_registered_extension_wrappers()) { + void *np = wrapper->set_android_surface_swapchain_create_info_and_get_next_pointer(extension_property_values, next_pointer); + if (np != nullptr) { + next_pointer = np; + } + } + // The XR_FB_android_surface_swapchain_create extension mandates that format, sampleCount, // faceCount, arraySize, and mipCount must be zero. XrSwapchainCreateInfo info = { XR_TYPE_SWAPCHAIN_CREATE_INFO, // type - nullptr, // next + next_pointer, // next 0, // createFlags XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, // usageFlags 0, // format diff --git a/modules/openxr/extensions/openxr_extension_wrapper.h b/modules/openxr/extensions/openxr_extension_wrapper.h index 09a9556dfa7e..95b537d1b453 100644 --- a/modules/openxr/extensions/openxr_extension_wrapper.h +++ b/modules/openxr/extensions/openxr_extension_wrapper.h @@ -97,10 +97,11 @@ class OpenXRExtensionWrapper { virtual void on_state_loss_pending() {} // `on_state_loss_pending` is called when the OpenXR session state is changed to loss pending. virtual void on_state_exiting() {} // `on_state_exiting` is called when the OpenXR session state is changed to exiting. - virtual void *set_viewport_composition_layer_and_get_next_pointer(const XrCompositionLayerBaseHeader *p_layer, Dictionary p_property_values, void *p_next_pointer) { return p_next_pointer; } // Add additional data structures to composition layers created via OpenXRCompositionLayer. + virtual void *set_viewport_composition_layer_and_get_next_pointer(const XrCompositionLayerBaseHeader *p_layer, const Dictionary &p_property_values, void *p_next_pointer) { return p_next_pointer; } // Add additional data structures to composition layers created via OpenXRCompositionLayer. virtual void on_viewport_composition_layer_destroyed(const XrCompositionLayerBaseHeader *p_layer) {} // `on_viewport_composition_layer_destroyed` is called when a composition layer created via OpenXRCompositionLayer is destroyed. virtual void get_viewport_composition_layer_extension_properties(List *p_property_list) {} // Get additional property definitions for OpenXRCompositionLayer. virtual Dictionary get_viewport_composition_layer_extension_property_defaults() { return Dictionary(); } // Get the default values for the additional property definitions for OpenXRCompositionLayer. + virtual void *set_android_surface_swapchain_create_info_and_get_next_pointer(const Dictionary &p_property_values, void *p_next_pointer) { return p_next_pointer; } // `on_event_polled` is called when there is an OpenXR event to process. // Should return true if the event was handled, false otherwise. diff --git a/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp b/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp index e09ca484d52d..07ca476421d8 100644 --- a/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp +++ b/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp @@ -65,6 +65,7 @@ void OpenXRExtensionWrapperExtension::_bind_methods() { GDVIRTUAL_BIND(_get_viewport_composition_layer_extension_properties); GDVIRTUAL_BIND(_get_viewport_composition_layer_extension_property_defaults); GDVIRTUAL_BIND(_on_viewport_composition_layer_destroyed, "layer"); + GDVIRTUAL_BIND(_set_android_surface_swapchain_create_info_and_get_next_pointer, "property_values", "next_pointer"); ClassDB::bind_method(D_METHOD("get_openxr_api"), &OpenXRExtensionWrapperExtension::get_openxr_api); ClassDB::bind_method(D_METHOD("register_extension_wrapper"), &OpenXRExtensionWrapperExtension::register_extension_wrapper); @@ -249,7 +250,7 @@ bool OpenXRExtensionWrapperExtension::on_event_polled(const XrEventDataBuffer &p return false; } -void *OpenXRExtensionWrapperExtension::set_viewport_composition_layer_and_get_next_pointer(const XrCompositionLayerBaseHeader *p_layer, Dictionary p_property_values, void *p_next_pointer) { +void *OpenXRExtensionWrapperExtension::set_viewport_composition_layer_and_get_next_pointer(const XrCompositionLayerBaseHeader *p_layer, const Dictionary &p_property_values, void *p_next_pointer) { uint64_t pointer = 0; if (GDVIRTUAL_CALL(_set_viewport_composition_layer_and_get_next_pointer, GDExtensionConstPtr(p_layer), p_property_values, GDExtensionPtr(p_next_pointer), pointer)) { @@ -279,6 +280,16 @@ Dictionary OpenXRExtensionWrapperExtension::get_viewport_composition_layer_exten return property_defaults; } +void *OpenXRExtensionWrapperExtension::set_android_surface_swapchain_create_info_and_get_next_pointer(const Dictionary &p_property_values, void *p_next_pointer) { + uint64_t pointer = 0; + + if (GDVIRTUAL_CALL(_set_android_surface_swapchain_create_info_and_get_next_pointer, p_property_values, GDExtensionPtr(p_next_pointer), pointer)) { + return reinterpret_cast(pointer); + } + + return p_next_pointer; +} + Ref OpenXRExtensionWrapperExtension::get_openxr_api() { return openxr_api; } diff --git a/modules/openxr/extensions/openxr_extension_wrapper_extension.h b/modules/openxr/extensions/openxr_extension_wrapper_extension.h index e37853903b39..5cdf288c934a 100644 --- a/modules/openxr/extensions/openxr_extension_wrapper_extension.h +++ b/modules/openxr/extensions/openxr_extension_wrapper_extension.h @@ -121,15 +121,17 @@ class OpenXRExtensionWrapperExtension : public Object, public OpenXRExtensionWra GDVIRTUAL1R(bool, _on_event_polled, GDExtensionConstPtr); - virtual void *set_viewport_composition_layer_and_get_next_pointer(const XrCompositionLayerBaseHeader *p_layer, Dictionary p_property_values, void *p_next_pointer) override; + virtual void *set_viewport_composition_layer_and_get_next_pointer(const XrCompositionLayerBaseHeader *p_layer, const Dictionary &p_property_values, void *p_next_pointer) override; virtual void on_viewport_composition_layer_destroyed(const XrCompositionLayerBaseHeader *p_layer) override; virtual void get_viewport_composition_layer_extension_properties(List *p_property_list) override; virtual Dictionary get_viewport_composition_layer_extension_property_defaults() override; + virtual void *set_android_surface_swapchain_create_info_and_get_next_pointer(const Dictionary &p_property_values, void *p_next_pointer) override; GDVIRTUAL3R(uint64_t, _set_viewport_composition_layer_and_get_next_pointer, GDExtensionConstPtr, Dictionary, GDExtensionPtr); GDVIRTUAL1(_on_viewport_composition_layer_destroyed, GDExtensionConstPtr); GDVIRTUAL0R(TypedArray, _get_viewport_composition_layer_extension_properties); GDVIRTUAL0R(Dictionary, _get_viewport_composition_layer_extension_property_defaults); + GDVIRTUAL2R(uint64_t, _set_android_surface_swapchain_create_info_and_get_next_pointer, Dictionary, GDExtensionPtr); Ref get_openxr_api(); From 267bb982319c5dbd0c5341bd85f6319b873db6d2 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Sat, 21 Sep 2024 21:11:58 +0800 Subject: [PATCH 07/20] Keep advanced toggle on when searching for settings --- editor/editor_sectioned_inspector.cpp | 33 +++++++++++++++++++++------ editor/editor_sectioned_inspector.h | 12 +++++++--- editor/editor_settings_dialog.cpp | 4 ++-- editor/import_defaults_editor.cpp | 5 +--- editor/project_settings_editor.cpp | 7 +++--- editor/shader_globals_editor.cpp | 1 + 6 files changed, 42 insertions(+), 20 deletions(-) diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index bc7bfcfa58d8..27cbb9810c78 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -30,10 +30,12 @@ #include "editor_sectioned_inspector.h" +#include "editor/editor_inspector.h" #include "editor/editor_property_name_processor.h" -#include "editor/editor_settings.h" #include "editor/editor_string_names.h" #include "editor/themes/editor_scale.h" +#include "scene/gui/check_button.h" +#include "scene/gui/tree.h" static bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) { if (p_property_path.containsn(p_filter)) { @@ -307,18 +309,35 @@ void SectionedInspector::register_search_box(LineEdit *p_box) { search_box->connect(SceneStringName(text_changed), callable_mp(this, &SectionedInspector::_search_changed)); } +void SectionedInspector::register_advanced_toggle(CheckButton *p_toggle) { + advanced_toggle = p_toggle; + advanced_toggle->connect(SceneStringName(toggled), callable_mp(this, &SectionedInspector::_advanced_toggled)); + _advanced_toggled(advanced_toggle->is_pressed()); +} + void SectionedInspector::_search_changed(const String &p_what) { + if (advanced_toggle) { + if (p_what.is_empty()) { + advanced_toggle->set_pressed_no_signal(!restrict_to_basic); + advanced_toggle->set_disabled(false); + advanced_toggle->set_tooltip_text(String()); + } else { + advanced_toggle->set_pressed_no_signal(true); + advanced_toggle->set_disabled(true); + advanced_toggle->set_tooltip_text(TTR("Advanced settings are always shown when searching.")); + } + } update_category_list(); } -EditorInspector *SectionedInspector::get_inspector() { - return inspector; +void SectionedInspector::_advanced_toggled(bool p_toggled_on) { + restrict_to_basic = !p_toggled_on; + update_category_list(); + inspector->set_restrict_to_basic_settings(restrict_to_basic); } -void SectionedInspector::set_restrict_to_basic_settings(bool p_restrict) { - restrict_to_basic = p_restrict; - update_category_list(); - inspector->set_restrict_to_basic_settings(p_restrict); +EditorInspector *SectionedInspector::get_inspector() { + return inspector; } SectionedInspector::SectionedInspector() : diff --git a/editor/editor_sectioned_inspector.h b/editor/editor_sectioned_inspector.h index 3c9eb7857118..75f1569d36b2 100644 --- a/editor/editor_sectioned_inspector.h +++ b/editor/editor_sectioned_inspector.h @@ -31,11 +31,14 @@ #ifndef EDITOR_SECTIONED_INSPECTOR_H #define EDITOR_SECTIONED_INSPECTOR_H -#include "editor/editor_inspector.h" #include "scene/gui/split_container.h" -#include "scene/gui/tree.h" +class CheckButton; +class EditorInspector; +class LineEdit; class SectionedInspectorFilter; +class Tree; +class TreeItem; class SectionedInspector : public HSplitContainer { GDCLASS(SectionedInspector, HSplitContainer); @@ -48,6 +51,7 @@ class SectionedInspector : public HSplitContainer { HashMap section_map; EditorInspector *inspector = nullptr; LineEdit *search_box = nullptr; + CheckButton *advanced_toggle = nullptr; String selected_category; @@ -57,9 +61,12 @@ class SectionedInspector : public HSplitContainer { void _section_selected(); void _search_changed(const String &p_what); + void _advanced_toggled(bool p_toggled_on); public: void register_search_box(LineEdit *p_box); + void register_advanced_toggle(CheckButton *p_toggle); + EditorInspector *get_inspector(); void edit(Object *p_object); String get_full_item_path(const String &p_item); @@ -67,7 +74,6 @@ class SectionedInspector : public HSplitContainer { void set_current_section(const String &p_section); String get_current_section() const; - void set_restrict_to_basic_settings(bool p_restrict); void update_category_list(); SectionedInspector(); diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp index b13384782347..d07608d8525b 100644 --- a/editor/editor_settings_dialog.cpp +++ b/editor/editor_settings_dialog.cpp @@ -33,6 +33,7 @@ #include "core/input/input_map.h" #include "core/os/keyboard.h" #include "editor/debugger/editor_debugger_node.h" +#include "editor/editor_inspector.h" #include "editor/editor_log.h" #include "editor/editor_node.h" #include "editor/editor_property_name_processor.h" @@ -806,7 +807,6 @@ void EditorSettingsDialog::_focus_current_search_box() { void EditorSettingsDialog::_advanced_toggled(bool p_button_pressed) { EditorSettings::get_singleton()->set("_editor_settings_advanced_mode", p_button_pressed); - inspector->set_restrict_to_basic_settings(!p_button_pressed); } void EditorSettingsDialog::_editor_restart() { @@ -860,8 +860,8 @@ EditorSettingsDialog::EditorSettingsDialog() { inspector = memnew(SectionedInspector); inspector->get_inspector()->set_use_filter(true); - inspector->set_restrict_to_basic_settings(!use_advanced); inspector->register_search_box(search_box); + inspector->register_advanced_toggle(advanced_switch); inspector->set_v_size_flags(Control::SIZE_EXPAND_FILL); tab_general->add_child(inspector); inspector->get_inspector()->connect("property_edited", callable_mp(this, &EditorSettingsDialog::_settings_property_edited)); diff --git a/editor/import_defaults_editor.cpp b/editor/import_defaults_editor.cpp index 31e3022f6b9d..23e803f722f1 100644 --- a/editor/import_defaults_editor.cpp +++ b/editor/import_defaults_editor.cpp @@ -33,11 +33,8 @@ #include "core/config/project_settings.h" #include "core/io/resource_importer.h" #include "editor/action_map_editor.h" -#include "editor/editor_autoload_settings.h" +#include "editor/editor_inspector.h" #include "editor/editor_sectioned_inspector.h" -#include "editor/localization_editor.h" -#include "editor/plugins/editor_plugin_settings.h" -#include "editor/shader_globals_editor.h" #include "scene/gui/center_container.h" class ImportDefaultsEditorSettings : public Object { diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index d00fdc212307..57672937186c 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -31,7 +31,7 @@ #include "project_settings_editor.h" #include "core/config/project_settings.h" -#include "editor/editor_log.h" +#include "editor/editor_inspector.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_string_names.h" @@ -106,7 +106,6 @@ void ProjectSettingsEditor::_update_advanced(bool p_is_advanced) { void ProjectSettingsEditor::_advanced_toggled(bool p_button_pressed) { EditorSettings::get_singleton()->set_project_metadata("project_settings", "advanced_mode", p_button_pressed); _update_advanced(p_button_pressed); - general_settings_inspector->set_restrict_to_basic_settings(!p_button_pressed); } void ProjectSettingsEditor::_setting_selected(const String &p_path) { @@ -688,6 +687,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { general_settings_inspector = memnew(SectionedInspector); general_settings_inspector->set_v_size_flags(Control::SIZE_EXPAND_FILL); general_settings_inspector->register_search_box(search_box); + general_settings_inspector->register_advanced_toggle(advanced); general_settings_inspector->get_inspector()->set_use_filter(true); general_settings_inspector->get_inspector()->connect("property_selected", callable_mp(this, &ProjectSettingsEditor::_setting_selected)); general_settings_inspector->get_inspector()->connect("property_edited", callable_mp(this, &ProjectSettingsEditor::_setting_edited)); @@ -771,11 +771,10 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { bool use_advanced = EditorSettings::get_singleton()->get_project_metadata("project_settings", "advanced_mode", false); if (use_advanced) { - advanced->set_pressed_no_signal(true); + advanced->set_pressed(true); } _update_advanced(use_advanced); - general_settings_inspector->set_restrict_to_basic_settings(!use_advanced); import_defaults_editor = memnew(ImportDefaultsEditor); import_defaults_editor->set_name(TTR("Import Defaults")); diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index c05f60545d01..85e5cd6ea064 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -31,6 +31,7 @@ #include "shader_globals_editor.h" #include "core/config/project_settings.h" +#include "editor/editor_inspector.h" #include "editor/editor_node.h" #include "editor/editor_undo_redo_manager.h" #include "servers/rendering/shader_language.h" From b7416bf6933af73c7d9dc947f9aa834db82e488c Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Sat, 21 Sep 2024 23:17:38 +0800 Subject: [PATCH 08/20] Document `OptimizedTranslation.generate()` only works in editor --- doc/classes/OptimizedTranslation.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/classes/OptimizedTranslation.xml b/doc/classes/OptimizedTranslation.xml index 124f430f1b58..bc158984d722 100644 --- a/doc/classes/OptimizedTranslation.xml +++ b/doc/classes/OptimizedTranslation.xml @@ -14,6 +14,7 @@ Generates and sets an optimized translation from the given [Translation] resource. + [b]Note:[/b] This method is intended to be used in the editor. It does nothing when called from an exported project. From 0333648cea0483edce0131722789b54d4daa7d5a Mon Sep 17 00:00:00 2001 From: Ricardo Buring Date: Wed, 7 Aug 2024 16:20:21 +0200 Subject: [PATCH 09/20] Move Godot Physics 3D into a module; add dummy 3D physics server If the module is enabled (default), 3D physics works as it did before. If the module is disabled and no other 3D physics server is registered (via a module or GDExtension), then we fall back to a dummy implementation which effectively disables 3D physics functionality (and a warning is printed). The dummy 3D physics server can also be selected explicitly, in which case no warning is printed. --- COPYRIGHT.txt | 66 +-- doc/classes/ProjectSettings.xml | 1 + main/main.cpp | 11 +- modules/godot_physics_3d/SCsub | 7 + modules/godot_physics_3d/config.py | 6 + .../godot_physics_3d}/gjk_epa.cpp | 0 .../godot_physics_3d}/gjk_epa.h | 0 .../godot_physics_3d}/godot_area_3d.cpp | 0 .../godot_physics_3d}/godot_area_3d.h | 0 .../godot_physics_3d}/godot_area_pair_3d.cpp | 0 .../godot_physics_3d}/godot_area_pair_3d.h | 0 .../godot_physics_3d}/godot_body_3d.cpp | 0 .../godot_physics_3d}/godot_body_3d.h | 0 .../godot_body_direct_state_3d.cpp | 0 .../godot_body_direct_state_3d.h | 0 .../godot_physics_3d}/godot_body_pair_3d.cpp | 0 .../godot_physics_3d}/godot_body_pair_3d.h | 0 .../godot_broad_phase_3d.cpp | 0 .../godot_physics_3d}/godot_broad_phase_3d.h | 0 .../godot_broad_phase_3d_bvh.cpp | 0 .../godot_broad_phase_3d_bvh.h | 0 .../godot_collision_object_3d.cpp | 0 .../godot_collision_object_3d.h | 0 .../godot_collision_solver_3d.cpp | 0 .../godot_collision_solver_3d.h | 0 .../godot_collision_solver_3d_sat.cpp | 0 .../godot_collision_solver_3d_sat.h | 0 .../godot_physics_3d}/godot_constraint_3d.h | 0 .../godot_physics_3d}/godot_joint_3d.h | 0 .../godot_physics_server_3d.cpp | 6 - .../godot_physics_server_3d.h | 0 .../godot_physics_3d}/godot_shape_3d.cpp | 0 .../godot_physics_3d}/godot_shape_3d.h | 0 .../godot_physics_3d}/godot_soft_body_3d.cpp | 0 .../godot_physics_3d}/godot_soft_body_3d.h | 0 .../godot_physics_3d}/godot_space_3d.cpp | 0 .../godot_physics_3d}/godot_space_3d.h | 0 .../godot_physics_3d}/godot_step_3d.cpp | 0 .../godot_physics_3d}/godot_step_3d.h | 0 modules/godot_physics_3d/joints/SCsub | 5 + .../joints/godot_cone_twist_joint_3d.cpp | 0 .../joints/godot_cone_twist_joint_3d.h | 4 +- .../joints/godot_generic_6dof_joint_3d.cpp | 0 .../joints/godot_generic_6dof_joint_3d.h | 4 +- .../joints/godot_hinge_joint_3d.cpp | 0 .../joints/godot_hinge_joint_3d.h | 4 +- .../joints/godot_jacobian_entry_3d.h | 0 .../joints/godot_pin_joint_3d.cpp | 0 .../joints/godot_pin_joint_3d.h | 4 +- .../joints/godot_slider_joint_3d.cpp | 0 .../joints/godot_slider_joint_3d.h | 4 +- modules/godot_physics_3d/register_types.cpp | 61 +++ modules/godot_physics_3d/register_types.h | 39 ++ scu_builders.py | 4 +- servers/SCsub | 1 - servers/physics_3d/SCsub | 7 - servers/physics_3d/joints/SCsub | 5 - servers/physics_server_3d.cpp | 4 +- servers/physics_server_3d_dummy.h | 436 ++++++++++++++++++ servers/register_server_types.cpp | 17 +- tests/test_main.cpp | 4 + 61 files changed, 621 insertions(+), 79 deletions(-) create mode 100644 modules/godot_physics_3d/SCsub create mode 100644 modules/godot_physics_3d/config.py rename {servers/physics_3d => modules/godot_physics_3d}/gjk_epa.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/gjk_epa.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_area_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_area_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_area_pair_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_area_pair_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_body_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_body_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_body_direct_state_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_body_direct_state_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_body_pair_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_body_pair_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_broad_phase_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_broad_phase_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_broad_phase_3d_bvh.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_broad_phase_3d_bvh.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_collision_object_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_collision_object_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_collision_solver_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_collision_solver_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_collision_solver_3d_sat.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_collision_solver_3d_sat.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_constraint_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_joint_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_physics_server_3d.cpp (99%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_physics_server_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_shape_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_shape_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_soft_body_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_soft_body_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_space_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_space_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_step_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/godot_step_3d.h (100%) create mode 100644 modules/godot_physics_3d/joints/SCsub rename {servers/physics_3d => modules/godot_physics_3d}/joints/godot_cone_twist_joint_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/joints/godot_cone_twist_joint_3d.h (98%) rename {servers/physics_3d => modules/godot_physics_3d}/joints/godot_generic_6dof_joint_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/joints/godot_generic_6dof_joint_3d.h (99%) rename {servers/physics_3d => modules/godot_physics_3d}/joints/godot_hinge_joint_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/joints/godot_hinge_joint_3d.h (97%) rename {servers/physics_3d => modules/godot_physics_3d}/joints/godot_jacobian_entry_3d.h (100%) rename {servers/physics_3d => modules/godot_physics_3d}/joints/godot_pin_joint_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/joints/godot_pin_joint_3d.h (97%) rename {servers/physics_3d => modules/godot_physics_3d}/joints/godot_slider_joint_3d.cpp (100%) rename {servers/physics_3d => modules/godot_physics_3d}/joints/godot_slider_joint_3d.h (99%) create mode 100644 modules/godot_physics_3d/register_types.cpp create mode 100644 modules/godot_physics_3d/register_types.h delete mode 100644 servers/physics_3d/SCsub delete mode 100644 servers/physics_3d/joints/SCsub create mode 100644 servers/physics_server_3d_dummy.h diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 5b6dcbb567bd..c0bb756d2e24 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -63,6 +63,39 @@ Copyright: 2011, Ole Kniemeyer, MAXON, www.maxon.net 2007-2014, Juan Linietsky, Ariel Manzur License: Expat and Zlib +Files: ./modules/godot_physics_3d/gjk_epa.cpp + ./modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp + ./modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h + ./modules/godot_physics_3d/joints/godot_hinge_joint_3d.cpp + ./modules/godot_physics_3d/joints/godot_hinge_joint_3d_sw.h + ./modules/godot_physics_3d/joints/godot_jacobian_entry_3d_sw.h + ./modules/godot_physics_3d/joints/godot_pin_joint_3d.cpp + ./modules/godot_physics_3d/joints/godot_pin_joint_3d.h + ./modules/godot_physics_3d/joints/godot_slider_joint_3d.cpp + ./modules/godot_physics_3d/joints/godot_slider_joint_3d.h + ./modules/godot_physics_3d/godot_soft_body_3d.cpp + ./modules/godot_physics_3d/godot_soft_body_3d.h + ./modules/godot_physics_3d/godot_shape_3d.cpp + ./modules/godot_physics_3d/godot_shape_3d.h +Comment: Bullet Continuous Collision Detection and Physics Library +Copyright: 2003-2008, Erwin Coumans + 2014-present, Godot Engine contributors + 2007-2014, Juan Linietsky, Ariel Manzur +License: Expat and Zlib + +Files: ./modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp +Comment: Open Dynamics Engine +Copyright: 2001-2003, Russell L. Smith, Alen Ladavac, Nguyen Binh +License: BSD-3-clause + +Files: ./modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.cpp + ./modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.h +Comment: Bullet Continuous Collision Detection and Physics Library +Copyright: 2007, Starbreeze Studios + 2014-present, Godot Engine contributors + 2007-2014, Juan Linietsky, Ariel Manzur +License: Expat and Zlib + Files: ./modules/lightmapper_rd/lm_compute.glsl Comment: Joint Non-Local Means (JNLM) denoiser Copyright: 2020, Manuel Prandini @@ -98,39 +131,6 @@ Comment: Chipmunk2D Joint Constraints Copyright: 2007, Scott Lembcke License: Expat -Files: ./servers/physics_3d/collision_solver_3d_sat.cpp -Comment: Open Dynamics Engine -Copyright: 2001-2003, Russell L. Smith, Alen Ladavac, Nguyen Binh -License: BSD-3-clause - -Files: ./servers/physics_3d/gjk_epa.cpp - ./servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp - ./servers/physics_3d/joints/generic_6dof_joint_3d_sw.h - ./servers/physics_3d/joints/hinge_joint_3d_sw.cpp - ./servers/physics_3d/joints/hinge_joint_3d_sw.h - ./servers/physics_3d/joints/jacobian_entry_3d_sw.h - ./servers/physics_3d/joints/pin_joint_3d_sw.cpp - ./servers/physics_3d/joints/pin_joint_3d_sw.h - ./servers/physics_3d/joints/slider_joint_3d_sw.cpp - ./servers/physics_3d/joints/slider_joint_3d_sw.h - ./servers/physics_3d/soft_body_3d_sw.cpp - ./servers/physics_3d/soft_body_3d_sw.h - ./servers/physics_3d/shape_3d_sw.cpp - ./servers/physics_3d/shape_3d_sw.h -Comment: Bullet Continuous Collision Detection and Physics Library -Copyright: 2003-2008, Erwin Coumans - 2014-present, Godot Engine contributors - 2007-2014, Juan Linietsky, Ariel Manzur -License: Expat and Zlib - -Files: ./servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp - ./servers/physics_3d/joints/cone_twist_joint_3d_sw.h -Comment: Bullet Continuous Collision Detection and Physics Library -Copyright: 2007, Starbreeze Studios - 2014-present, Godot Engine contributors - 2007-2014, Juan Linietsky, Ariel Manzur -License: Expat and Zlib - Files: ./servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl ./servers/rendering/renderer_rd/shaders/ssao_blur.glsl ./servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 758e98ad8577..85a25b05af83 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -2293,6 +2293,7 @@ Sets which physics engine to use for 3D physics. "DEFAULT" and "GodotPhysics3D" are the same, as there is currently no alternative 3D physics server implemented. + "Dummy" is a 3D physics server that does nothing and returns only dummy values, effectively disabling all 3D physics functionality. If [code]true[/code], the 3D physics server runs on a separate thread, making better use of multi-core CPUs. If [code]false[/code], the 3D physics server runs on the main thread. Running the physics server on a separate thread can increase performance, but restricts API access to only physics process. diff --git a/main/main.cpp b/main/main.cpp index fa50a3039f43..439cd385c028 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -83,6 +83,7 @@ #ifndef _3D_DISABLED #include "servers/physics_server_3d.h" +#include "servers/physics_server_3d_dummy.h" #include "servers/xr_server.h" #endif // _3D_DISABLED @@ -320,7 +321,15 @@ void initialize_physics() { // Physics server not found, Use the default physics physics_server_3d = PhysicsServer3DManager::get_singleton()->new_default_server(); } - ERR_FAIL_NULL(physics_server_3d); + + // Fall back to dummy if no default server has been registered. + if (!physics_server_3d) { + WARN_PRINT(vformat("Falling back to dummy PhysicsServer3D; 3D physics functionality will be disabled. If this is intended, set the %s project setting to Dummy.", PhysicsServer3DManager::setting_property_name)); + physics_server_3d = memnew(PhysicsServer3DDummy); + } + + // Should be impossible, but make sure it's not null. + ERR_FAIL_NULL_MSG(physics_server_3d, "Failed to initialize PhysicsServer3D."); physics_server_3d->init(); #endif // _3D_DISABLED diff --git a/modules/godot_physics_3d/SCsub b/modules/godot_physics_3d/SCsub new file mode 100644 index 000000000000..41a59cd24ec9 --- /dev/null +++ b/modules/godot_physics_3d/SCsub @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +Import('env') + +env.add_source_files(env.modules_sources, "*.cpp") + +SConscript("joints/SCsub") diff --git a/modules/godot_physics_3d/config.py b/modules/godot_physics_3d/config.py new file mode 100644 index 000000000000..a42f27fbe122 --- /dev/null +++ b/modules/godot_physics_3d/config.py @@ -0,0 +1,6 @@ +def can_build(env, platform): + return not env["disable_3d"] + + +def configure(env): + pass diff --git a/servers/physics_3d/gjk_epa.cpp b/modules/godot_physics_3d/gjk_epa.cpp similarity index 100% rename from servers/physics_3d/gjk_epa.cpp rename to modules/godot_physics_3d/gjk_epa.cpp diff --git a/servers/physics_3d/gjk_epa.h b/modules/godot_physics_3d/gjk_epa.h similarity index 100% rename from servers/physics_3d/gjk_epa.h rename to modules/godot_physics_3d/gjk_epa.h diff --git a/servers/physics_3d/godot_area_3d.cpp b/modules/godot_physics_3d/godot_area_3d.cpp similarity index 100% rename from servers/physics_3d/godot_area_3d.cpp rename to modules/godot_physics_3d/godot_area_3d.cpp diff --git a/servers/physics_3d/godot_area_3d.h b/modules/godot_physics_3d/godot_area_3d.h similarity index 100% rename from servers/physics_3d/godot_area_3d.h rename to modules/godot_physics_3d/godot_area_3d.h diff --git a/servers/physics_3d/godot_area_pair_3d.cpp b/modules/godot_physics_3d/godot_area_pair_3d.cpp similarity index 100% rename from servers/physics_3d/godot_area_pair_3d.cpp rename to modules/godot_physics_3d/godot_area_pair_3d.cpp diff --git a/servers/physics_3d/godot_area_pair_3d.h b/modules/godot_physics_3d/godot_area_pair_3d.h similarity index 100% rename from servers/physics_3d/godot_area_pair_3d.h rename to modules/godot_physics_3d/godot_area_pair_3d.h diff --git a/servers/physics_3d/godot_body_3d.cpp b/modules/godot_physics_3d/godot_body_3d.cpp similarity index 100% rename from servers/physics_3d/godot_body_3d.cpp rename to modules/godot_physics_3d/godot_body_3d.cpp diff --git a/servers/physics_3d/godot_body_3d.h b/modules/godot_physics_3d/godot_body_3d.h similarity index 100% rename from servers/physics_3d/godot_body_3d.h rename to modules/godot_physics_3d/godot_body_3d.h diff --git a/servers/physics_3d/godot_body_direct_state_3d.cpp b/modules/godot_physics_3d/godot_body_direct_state_3d.cpp similarity index 100% rename from servers/physics_3d/godot_body_direct_state_3d.cpp rename to modules/godot_physics_3d/godot_body_direct_state_3d.cpp diff --git a/servers/physics_3d/godot_body_direct_state_3d.h b/modules/godot_physics_3d/godot_body_direct_state_3d.h similarity index 100% rename from servers/physics_3d/godot_body_direct_state_3d.h rename to modules/godot_physics_3d/godot_body_direct_state_3d.h diff --git a/servers/physics_3d/godot_body_pair_3d.cpp b/modules/godot_physics_3d/godot_body_pair_3d.cpp similarity index 100% rename from servers/physics_3d/godot_body_pair_3d.cpp rename to modules/godot_physics_3d/godot_body_pair_3d.cpp diff --git a/servers/physics_3d/godot_body_pair_3d.h b/modules/godot_physics_3d/godot_body_pair_3d.h similarity index 100% rename from servers/physics_3d/godot_body_pair_3d.h rename to modules/godot_physics_3d/godot_body_pair_3d.h diff --git a/servers/physics_3d/godot_broad_phase_3d.cpp b/modules/godot_physics_3d/godot_broad_phase_3d.cpp similarity index 100% rename from servers/physics_3d/godot_broad_phase_3d.cpp rename to modules/godot_physics_3d/godot_broad_phase_3d.cpp diff --git a/servers/physics_3d/godot_broad_phase_3d.h b/modules/godot_physics_3d/godot_broad_phase_3d.h similarity index 100% rename from servers/physics_3d/godot_broad_phase_3d.h rename to modules/godot_physics_3d/godot_broad_phase_3d.h diff --git a/servers/physics_3d/godot_broad_phase_3d_bvh.cpp b/modules/godot_physics_3d/godot_broad_phase_3d_bvh.cpp similarity index 100% rename from servers/physics_3d/godot_broad_phase_3d_bvh.cpp rename to modules/godot_physics_3d/godot_broad_phase_3d_bvh.cpp diff --git a/servers/physics_3d/godot_broad_phase_3d_bvh.h b/modules/godot_physics_3d/godot_broad_phase_3d_bvh.h similarity index 100% rename from servers/physics_3d/godot_broad_phase_3d_bvh.h rename to modules/godot_physics_3d/godot_broad_phase_3d_bvh.h diff --git a/servers/physics_3d/godot_collision_object_3d.cpp b/modules/godot_physics_3d/godot_collision_object_3d.cpp similarity index 100% rename from servers/physics_3d/godot_collision_object_3d.cpp rename to modules/godot_physics_3d/godot_collision_object_3d.cpp diff --git a/servers/physics_3d/godot_collision_object_3d.h b/modules/godot_physics_3d/godot_collision_object_3d.h similarity index 100% rename from servers/physics_3d/godot_collision_object_3d.h rename to modules/godot_physics_3d/godot_collision_object_3d.h diff --git a/servers/physics_3d/godot_collision_solver_3d.cpp b/modules/godot_physics_3d/godot_collision_solver_3d.cpp similarity index 100% rename from servers/physics_3d/godot_collision_solver_3d.cpp rename to modules/godot_physics_3d/godot_collision_solver_3d.cpp diff --git a/servers/physics_3d/godot_collision_solver_3d.h b/modules/godot_physics_3d/godot_collision_solver_3d.h similarity index 100% rename from servers/physics_3d/godot_collision_solver_3d.h rename to modules/godot_physics_3d/godot_collision_solver_3d.h diff --git a/servers/physics_3d/godot_collision_solver_3d_sat.cpp b/modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp similarity index 100% rename from servers/physics_3d/godot_collision_solver_3d_sat.cpp rename to modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp diff --git a/servers/physics_3d/godot_collision_solver_3d_sat.h b/modules/godot_physics_3d/godot_collision_solver_3d_sat.h similarity index 100% rename from servers/physics_3d/godot_collision_solver_3d_sat.h rename to modules/godot_physics_3d/godot_collision_solver_3d_sat.h diff --git a/servers/physics_3d/godot_constraint_3d.h b/modules/godot_physics_3d/godot_constraint_3d.h similarity index 100% rename from servers/physics_3d/godot_constraint_3d.h rename to modules/godot_physics_3d/godot_constraint_3d.h diff --git a/servers/physics_3d/godot_joint_3d.h b/modules/godot_physics_3d/godot_joint_3d.h similarity index 100% rename from servers/physics_3d/godot_joint_3d.h rename to modules/godot_physics_3d/godot_joint_3d.h diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/modules/godot_physics_3d/godot_physics_server_3d.cpp similarity index 99% rename from servers/physics_3d/godot_physics_server_3d.cpp rename to modules/godot_physics_3d/godot_physics_server_3d.cpp index 8a7b4e0f07b1..6d0949acbeb8 100644 --- a/servers/physics_3d/godot_physics_server_3d.cpp +++ b/modules/godot_physics_3d/godot_physics_server_3d.cpp @@ -1629,8 +1629,6 @@ void GodotPhysicsServer3D::init() { } void GodotPhysicsServer3D::step(real_t p_step) { -#ifndef _3D_DISABLED - if (!active) { return; } @@ -1646,7 +1644,6 @@ void GodotPhysicsServer3D::step(real_t p_step) { active_objects += E->get_active_objects(); collision_pairs += E->get_collision_pairs(); } -#endif } void GodotPhysicsServer3D::sync() { @@ -1654,8 +1651,6 @@ void GodotPhysicsServer3D::sync() { } void GodotPhysicsServer3D::flush_queries() { -#ifndef _3D_DISABLED - if (!active) { return; } @@ -1703,7 +1698,6 @@ void GodotPhysicsServer3D::flush_queries() { values.push_front("physics_3d"); EngineDebugger::profiler_add_frame_data("servers", values); } -#endif } void GodotPhysicsServer3D::end_sync() { diff --git a/servers/physics_3d/godot_physics_server_3d.h b/modules/godot_physics_3d/godot_physics_server_3d.h similarity index 100% rename from servers/physics_3d/godot_physics_server_3d.h rename to modules/godot_physics_3d/godot_physics_server_3d.h diff --git a/servers/physics_3d/godot_shape_3d.cpp b/modules/godot_physics_3d/godot_shape_3d.cpp similarity index 100% rename from servers/physics_3d/godot_shape_3d.cpp rename to modules/godot_physics_3d/godot_shape_3d.cpp diff --git a/servers/physics_3d/godot_shape_3d.h b/modules/godot_physics_3d/godot_shape_3d.h similarity index 100% rename from servers/physics_3d/godot_shape_3d.h rename to modules/godot_physics_3d/godot_shape_3d.h diff --git a/servers/physics_3d/godot_soft_body_3d.cpp b/modules/godot_physics_3d/godot_soft_body_3d.cpp similarity index 100% rename from servers/physics_3d/godot_soft_body_3d.cpp rename to modules/godot_physics_3d/godot_soft_body_3d.cpp diff --git a/servers/physics_3d/godot_soft_body_3d.h b/modules/godot_physics_3d/godot_soft_body_3d.h similarity index 100% rename from servers/physics_3d/godot_soft_body_3d.h rename to modules/godot_physics_3d/godot_soft_body_3d.h diff --git a/servers/physics_3d/godot_space_3d.cpp b/modules/godot_physics_3d/godot_space_3d.cpp similarity index 100% rename from servers/physics_3d/godot_space_3d.cpp rename to modules/godot_physics_3d/godot_space_3d.cpp diff --git a/servers/physics_3d/godot_space_3d.h b/modules/godot_physics_3d/godot_space_3d.h similarity index 100% rename from servers/physics_3d/godot_space_3d.h rename to modules/godot_physics_3d/godot_space_3d.h diff --git a/servers/physics_3d/godot_step_3d.cpp b/modules/godot_physics_3d/godot_step_3d.cpp similarity index 100% rename from servers/physics_3d/godot_step_3d.cpp rename to modules/godot_physics_3d/godot_step_3d.cpp diff --git a/servers/physics_3d/godot_step_3d.h b/modules/godot_physics_3d/godot_step_3d.h similarity index 100% rename from servers/physics_3d/godot_step_3d.h rename to modules/godot_physics_3d/godot_step_3d.h diff --git a/modules/godot_physics_3d/joints/SCsub b/modules/godot_physics_3d/joints/SCsub new file mode 100644 index 000000000000..5d93da5ecf61 --- /dev/null +++ b/modules/godot_physics_3d/joints/SCsub @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +Import('env') + +env.add_source_files(env.modules_sources, "*.cpp") diff --git a/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.cpp similarity index 100% rename from servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp rename to modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.cpp diff --git a/servers/physics_3d/joints/godot_cone_twist_joint_3d.h b/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.h similarity index 98% rename from servers/physics_3d/joints/godot_cone_twist_joint_3d.h rename to modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.h index 8b749e491435..f3b683a8f38a 100644 --- a/servers/physics_3d/joints/godot_cone_twist_joint_3d.h +++ b/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.h @@ -52,8 +52,8 @@ subject to the following restrictions: Written by: Marcus Hennix */ -#include "servers/physics_3d/godot_joint_3d.h" -#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" +#include "../godot_joint_3d.h" +#include "godot_jacobian_entry_3d.h" // GodotConeTwistJoint3D can be used to simulate ragdoll joints (upper arm, leg etc). class GodotConeTwistJoint3D : public GodotJoint3D { diff --git a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp similarity index 100% rename from servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp rename to modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp diff --git a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h similarity index 99% rename from servers/physics_3d/joints/godot_generic_6dof_joint_3d.h rename to modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h index 69a52664382d..9ee6dd279176 100644 --- a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h +++ b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h @@ -35,8 +35,8 @@ Adapted to Godot from the Bullet library. */ -#include "servers/physics_3d/godot_joint_3d.h" -#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" +#include "../godot_joint_3d.h" +#include "godot_jacobian_entry_3d.h" /* Bullet Continuous Collision Detection and Physics Library diff --git a/servers/physics_3d/joints/godot_hinge_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_hinge_joint_3d.cpp similarity index 100% rename from servers/physics_3d/joints/godot_hinge_joint_3d.cpp rename to modules/godot_physics_3d/joints/godot_hinge_joint_3d.cpp diff --git a/servers/physics_3d/joints/godot_hinge_joint_3d.h b/modules/godot_physics_3d/joints/godot_hinge_joint_3d.h similarity index 97% rename from servers/physics_3d/joints/godot_hinge_joint_3d.h rename to modules/godot_physics_3d/joints/godot_hinge_joint_3d.h index eab60c19099b..7f835094684f 100644 --- a/servers/physics_3d/joints/godot_hinge_joint_3d.h +++ b/modules/godot_physics_3d/joints/godot_hinge_joint_3d.h @@ -35,8 +35,8 @@ Adapted to Godot from the Bullet library. */ -#include "servers/physics_3d/godot_joint_3d.h" -#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" +#include "../godot_joint_3d.h" +#include "godot_jacobian_entry_3d.h" /* Bullet Continuous Collision Detection and Physics Library diff --git a/servers/physics_3d/joints/godot_jacobian_entry_3d.h b/modules/godot_physics_3d/joints/godot_jacobian_entry_3d.h similarity index 100% rename from servers/physics_3d/joints/godot_jacobian_entry_3d.h rename to modules/godot_physics_3d/joints/godot_jacobian_entry_3d.h diff --git a/servers/physics_3d/joints/godot_pin_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_pin_joint_3d.cpp similarity index 100% rename from servers/physics_3d/joints/godot_pin_joint_3d.cpp rename to modules/godot_physics_3d/joints/godot_pin_joint_3d.cpp diff --git a/servers/physics_3d/joints/godot_pin_joint_3d.h b/modules/godot_physics_3d/joints/godot_pin_joint_3d.h similarity index 97% rename from servers/physics_3d/joints/godot_pin_joint_3d.h rename to modules/godot_physics_3d/joints/godot_pin_joint_3d.h index 2d19bcb6262f..62d3068e094e 100644 --- a/servers/physics_3d/joints/godot_pin_joint_3d.h +++ b/modules/godot_physics_3d/joints/godot_pin_joint_3d.h @@ -35,8 +35,8 @@ Adapted to Godot from the Bullet library. */ -#include "servers/physics_3d/godot_joint_3d.h" -#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" +#include "../godot_joint_3d.h" +#include "godot_jacobian_entry_3d.h" /* Bullet Continuous Collision Detection and Physics Library diff --git a/servers/physics_3d/joints/godot_slider_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_slider_joint_3d.cpp similarity index 100% rename from servers/physics_3d/joints/godot_slider_joint_3d.cpp rename to modules/godot_physics_3d/joints/godot_slider_joint_3d.cpp diff --git a/servers/physics_3d/joints/godot_slider_joint_3d.h b/modules/godot_physics_3d/joints/godot_slider_joint_3d.h similarity index 99% rename from servers/physics_3d/joints/godot_slider_joint_3d.h rename to modules/godot_physics_3d/joints/godot_slider_joint_3d.h index ad79fc51b00d..99fabf863840 100644 --- a/servers/physics_3d/joints/godot_slider_joint_3d.h +++ b/modules/godot_physics_3d/joints/godot_slider_joint_3d.h @@ -35,8 +35,8 @@ Adapted to Godot from the Bullet library. */ -#include "servers/physics_3d/godot_joint_3d.h" -#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" +#include "../godot_joint_3d.h" +#include "godot_jacobian_entry_3d.h" /* Bullet Continuous Collision Detection and Physics Library diff --git a/modules/godot_physics_3d/register_types.cpp b/modules/godot_physics_3d/register_types.cpp new file mode 100644 index 000000000000..1b1690cf59f7 --- /dev/null +++ b/modules/godot_physics_3d/register_types.cpp @@ -0,0 +1,61 @@ +/**************************************************************************/ +/* register_types.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "register_types.h" + +#include "godot_physics_server_3d.h" +#include "servers/physics_server_3d.h" +#include "servers/physics_server_3d_wrap_mt.h" + +static PhysicsServer3D *_createGodotPhysics3DCallback() { +#ifdef THREADS_ENABLED + bool using_threads = GLOBAL_GET("physics/3d/run_on_separate_thread"); +#else + bool using_threads = false; +#endif + + PhysicsServer3D *physics_server_3d = memnew(GodotPhysicsServer3D(using_threads)); + + return memnew(PhysicsServer3DWrapMT(physics_server_3d, using_threads)); +} + +void initialize_godot_physics_3d_module(ModuleInitializationLevel p_level) { + if (p_level != MODULE_INITIALIZATION_LEVEL_SERVERS) { + return; + } + PhysicsServer3DManager::get_singleton()->register_server("GodotPhysics3D", callable_mp_static(_createGodotPhysics3DCallback)); + PhysicsServer3DManager::get_singleton()->set_default_server("GodotPhysics3D"); +} + +void uninitialize_godot_physics_3d_module(ModuleInitializationLevel p_level) { + if (p_level != MODULE_INITIALIZATION_LEVEL_SERVERS) { + return; + } +} diff --git a/modules/godot_physics_3d/register_types.h b/modules/godot_physics_3d/register_types.h new file mode 100644 index 000000000000..998fb4a1ee1d --- /dev/null +++ b/modules/godot_physics_3d/register_types.h @@ -0,0 +1,39 @@ +/**************************************************************************/ +/* register_types.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#ifndef GODOT_PHYSICS_3D_REGISTER_TYPES_H +#define GODOT_PHYSICS_3D_REGISTER_TYPES_H + +#include "modules/register_module_types.h" + +void initialize_godot_physics_3d_module(ModuleInitializationLevel p_level); +void uninitialize_godot_physics_3d_module(ModuleInitializationLevel p_level); + +#endif // GODOT_PHYSICS_3D_REGISTER_TYPES_H diff --git a/scu_builders.py b/scu_builders.py index fc5461196f98..7fc0c15b2d05 100644 --- a/scu_builders.py +++ b/scu_builders.py @@ -322,6 +322,8 @@ def generate_scu_files(max_includes_per_scu): process_folder(["modules/openxr"], ["register_types"]) process_folder(["modules/openxr/action_map"]) process_folder(["modules/openxr/editor"]) + process_folder(["modules/godot_physics_3d"]) + process_folder(["modules/godot_physics_3d/joints"]) process_folder(["modules/csg"]) process_folder(["modules/gdscript"]) @@ -349,8 +351,6 @@ def generate_scu_files(max_includes_per_scu): process_folder(["servers/rendering/renderer_rd/environment"]) process_folder(["servers/rendering/renderer_rd/storage_rd"]) process_folder(["servers/physics_2d"]) - process_folder(["servers/physics_3d"]) - process_folder(["servers/physics_3d/joints"]) process_folder(["servers/audio"]) process_folder(["servers/audio/effects"]) diff --git a/servers/SCsub b/servers/SCsub index 736bed68ecb2..472cb096abf4 100644 --- a/servers/SCsub +++ b/servers/SCsub @@ -28,7 +28,6 @@ SConscript("text/SCsub") SConscript("physics_2d/SCsub") if not env["disable_3d"]: - SConscript("physics_3d/SCsub") env.add_source_files(env.servers_sources, "physics_server_3d.cpp") env.add_source_files(env.servers_sources, "physics_server_3d_wrap_mt.cpp") SConscript("xr/SCsub") diff --git a/servers/physics_3d/SCsub b/servers/physics_3d/SCsub deleted file mode 100644 index df7b521693bc..000000000000 --- a/servers/physics_3d/SCsub +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python - -Import("env") - -env.add_source_files(env.servers_sources, "*.cpp") - -SConscript("joints/SCsub") diff --git a/servers/physics_3d/joints/SCsub b/servers/physics_3d/joints/SCsub deleted file mode 100644 index 86681f9c74d3..000000000000 --- a/servers/physics_3d/joints/SCsub +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env python - -Import("env") - -env.add_source_files(env.servers_sources, "*.cpp") diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 698805bbddb6..ee4815186348 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -1201,7 +1201,9 @@ String PhysicsServer3DManager::get_server_name(int p_id) { } PhysicsServer3D *PhysicsServer3DManager::new_default_server() { - ERR_FAIL_COND_V(default_server_id == -1, nullptr); + if (default_server_id == -1) { + return nullptr; + } Variant ret; Callable::CallError ce; physics_servers[default_server_id].create_callback.callp(nullptr, 0, ret, ce); diff --git a/servers/physics_server_3d_dummy.h b/servers/physics_server_3d_dummy.h new file mode 100644 index 000000000000..209a541fea01 --- /dev/null +++ b/servers/physics_server_3d_dummy.h @@ -0,0 +1,436 @@ +/**************************************************************************/ +/* physics_server_3d_dummy.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#ifndef PHYSICS_SERVER_3D_DUMMY_H +#define PHYSICS_SERVER_3D_DUMMY_H + +#include "servers/physics_server_3d.h" + +class PhysicsDirectBodyState3DDummy : public PhysicsDirectBodyState3D { + GDCLASS(PhysicsDirectBodyState3DDummy, PhysicsDirectBodyState3D); + + PhysicsDirectSpaceState3D *space_state_dummy = nullptr; + +public: + virtual Vector3 get_total_gravity() const override { return Vector3(); } + virtual real_t get_total_angular_damp() const override { return 0; } + virtual real_t get_total_linear_damp() const override { return 0; } + + virtual Vector3 get_center_of_mass() const override { return Vector3(); } + virtual Vector3 get_center_of_mass_local() const override { return Vector3(); } + virtual Basis get_principal_inertia_axes() const override { return Basis(); } + virtual real_t get_inverse_mass() const override { return 0; } + virtual Vector3 get_inverse_inertia() const override { return Vector3(); } + virtual Basis get_inverse_inertia_tensor() const override { return Basis(); } + + virtual void set_linear_velocity(const Vector3 &p_velocity) override {} + virtual Vector3 get_linear_velocity() const override { return Vector3(); } + + virtual void set_angular_velocity(const Vector3 &p_velocity) override {} + virtual Vector3 get_angular_velocity() const override { return Vector3(); } + + virtual void set_transform(const Transform3D &p_transform) override {} + virtual Transform3D get_transform() const override { return Transform3D(); } + + virtual Vector3 get_velocity_at_local_position(const Vector3 &p_position) const override { return Vector3(); } + + virtual void apply_central_impulse(const Vector3 &p_impulse) override {} + virtual void apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position = Vector3()) override {} + virtual void apply_torque_impulse(const Vector3 &p_impulse) override {} + + virtual void apply_central_force(const Vector3 &p_force) override {} + virtual void apply_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) override {} + virtual void apply_torque(const Vector3 &p_torque) override {} + + virtual void add_constant_central_force(const Vector3 &p_force) override {} + virtual void add_constant_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) override {} + virtual void add_constant_torque(const Vector3 &p_torque) override {} + + virtual void set_constant_force(const Vector3 &p_force) override {} + virtual Vector3 get_constant_force() const override { return Vector3(); } + + virtual void set_constant_torque(const Vector3 &p_torque) override {} + virtual Vector3 get_constant_torque() const override { return Vector3(); } + + virtual void set_sleep_state(bool p_sleep) override {} + virtual bool is_sleeping() const override { return false; } + + virtual int get_contact_count() const override { return 0; } + + virtual Vector3 get_contact_local_position(int p_contact_idx) const override { return Vector3(); } + virtual Vector3 get_contact_local_normal(int p_contact_idx) const override { return Vector3(); } + virtual Vector3 get_contact_impulse(int p_contact_idx) const override { return Vector3(); } + virtual int get_contact_local_shape(int p_contact_idx) const override { return 0; } + virtual Vector3 get_contact_local_velocity_at_position(int p_contact_idx) const override { return Vector3(); } + + virtual RID get_contact_collider(int p_contact_idx) const override { return RID(); } + virtual Vector3 get_contact_collider_position(int p_contact_idx) const override { return Vector3(); } + virtual ObjectID get_contact_collider_id(int p_contact_idx) const override { return ObjectID(); } + virtual Object *get_contact_collider_object(int p_contact_idx) const override { return nullptr; } + virtual int get_contact_collider_shape(int p_contact_idx) const override { return 0; } + virtual Vector3 get_contact_collider_velocity_at_position(int p_contact_idx) const override { return Vector3(); } + + virtual real_t get_step() const override { return 0; } + virtual void integrate_forces() override {} + + virtual PhysicsDirectSpaceState3D *get_space_state() override { return space_state_dummy; } + + PhysicsDirectBodyState3DDummy(PhysicsDirectSpaceState3D *p_space_state_dummy) { + space_state_dummy = p_space_state_dummy; + } +}; + +class PhysicsDirectSpaceState3DDummy : public PhysicsDirectSpaceState3D { + GDCLASS(PhysicsDirectSpaceState3DDummy, PhysicsDirectSpaceState3D); + +public: + virtual bool intersect_ray(const RayParameters &p_parameters, RayResult &r_result) override { return false; } + + virtual int intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) override { return 0; } + + virtual int intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) override { return 0; } + virtual bool cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe, ShapeRestInfo *r_info = nullptr) override { return false; } + virtual bool collide_shape(const ShapeParameters &p_parameters, Vector3 *r_results, int p_result_max, int &r_result_count) override { return false; } + virtual bool rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) override { return false; } + + virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override { return Vector3(); } +}; + +class PhysicsServer3DDummy : public PhysicsServer3D { + GDCLASS(PhysicsServer3DDummy, PhysicsServer3D); + + PhysicsDirectBodyState3DDummy *body_state_dummy = nullptr; + PhysicsDirectSpaceState3DDummy *space_state_dummy = nullptr; + +public: + virtual RID world_boundary_shape_create() override { return RID(); } + virtual RID separation_ray_shape_create() override { return RID(); } + virtual RID sphere_shape_create() override { return RID(); } + virtual RID box_shape_create() override { return RID(); } + virtual RID capsule_shape_create() override { return RID(); } + virtual RID cylinder_shape_create() override { return RID(); } + virtual RID convex_polygon_shape_create() override { return RID(); } + virtual RID concave_polygon_shape_create() override { return RID(); } + virtual RID heightmap_shape_create() override { return RID(); } + virtual RID custom_shape_create() override { return RID(); } + + virtual void shape_set_data(RID p_shape, const Variant &p_data) override {} + virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias) override {} + + virtual ShapeType shape_get_type(RID p_shape) const override { return SHAPE_SPHERE; } + virtual Variant shape_get_data(RID p_shape) const override { return Variant(); } + + virtual void shape_set_margin(RID p_shape, real_t p_margin) override {} + virtual real_t shape_get_margin(RID p_shape) const override { return 0; } + + virtual real_t shape_get_custom_solver_bias(RID p_shape) const override { return 0; } + + /* SPACE API */ + + virtual RID space_create() override { return RID(); } + virtual void space_set_active(RID p_space, bool p_active) override {} + virtual bool space_is_active(RID p_space) const override { return false; } + + virtual void space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) override {} + virtual real_t space_get_param(RID p_space, SpaceParameter p_param) const override { return 0; } + + virtual PhysicsDirectSpaceState3D *space_get_direct_state(RID p_space) override { return space_state_dummy; } + + virtual void space_set_debug_contacts(RID p_space, int p_max_contacts) override {} + virtual Vector space_get_contacts(RID p_space) const override { return Vector(); } + virtual int space_get_contact_count(RID p_space) const override { return 0; } + + /* AREA API */ + + virtual RID area_create() override { return RID(); } + + virtual void area_set_space(RID p_area, RID p_space) override {} + virtual RID area_get_space(RID p_area) const override { return RID(); } + + virtual void area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false) override {} + virtual void area_set_shape(RID p_area, int p_shape_idx, RID p_shape) override {} + virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) override {} + + virtual int area_get_shape_count(RID p_area) const override { return 0; } + virtual RID area_get_shape(RID p_area, int p_shape_idx) const override { return RID(); } + virtual Transform3D area_get_shape_transform(RID p_area, int p_shape_idx) const override { return Transform3D(); } + + virtual void area_remove_shape(RID p_area, int p_shape_idx) override {} + virtual void area_clear_shapes(RID p_area) override {} + + virtual void area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) override {} + + virtual void area_attach_object_instance_id(RID p_area, ObjectID p_id) override {} + virtual ObjectID area_get_object_instance_id(RID p_area) const override { return ObjectID(); } + + virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) override {} + virtual void area_set_transform(RID p_area, const Transform3D &p_transform) override {} + + virtual Variant area_get_param(RID p_parea, AreaParameter p_param) const override { return Variant(); } + virtual Transform3D area_get_transform(RID p_area) const override { return Transform3D(); } + + virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override {} + virtual uint32_t area_get_collision_layer(RID p_area) const override { return 0; } + + virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override {} + virtual uint32_t area_get_collision_mask(RID p_area) const override { return 0; } + + virtual void area_set_monitorable(RID p_area, bool p_monitorable) override {} + + virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) override {} + virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) override {} + + virtual void area_set_ray_pickable(RID p_area, bool p_enable) override {} + + /* BODY API */ + + virtual RID body_create() override { return RID(); } + + virtual void body_set_space(RID p_body, RID p_space) override {} + virtual RID body_get_space(RID p_body) const override { return RID(); } + + virtual void body_set_mode(RID p_body, BodyMode p_mode) override {} + virtual BodyMode body_get_mode(RID p_body) const override { return BodyMode::BODY_MODE_STATIC; } + + virtual void body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false) override {} + virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape) override {} + virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) override {} + + virtual int body_get_shape_count(RID p_body) const override { return 0; } + virtual RID body_get_shape(RID p_body, int p_shape_idx) const override { return RID(); } + virtual Transform3D body_get_shape_transform(RID p_body, int p_shape_idx) const override { return Transform3D(); } + + virtual void body_remove_shape(RID p_body, int p_shape_idx) override {} + virtual void body_clear_shapes(RID p_body) override {} + + virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) override {} + + virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id) override {} + virtual ObjectID body_get_object_instance_id(RID p_body) const override { return ObjectID(); } + + virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) override {} + virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const override { return false; } + + virtual void body_set_collision_layer(RID p_body, uint32_t p_layer) override {} + virtual uint32_t body_get_collision_layer(RID p_body) const override { return 0; } + + virtual void body_set_collision_mask(RID p_body, uint32_t p_mask) override {} + virtual uint32_t body_get_collision_mask(RID p_body) const override { return 0; } + + virtual void body_set_collision_priority(RID p_body, real_t p_priority) override {} + virtual real_t body_get_collision_priority(RID p_body) const override { return 0; } + + virtual void body_set_user_flags(RID p_body, uint32_t p_flags) override {} + virtual uint32_t body_get_user_flags(RID p_body) const override { return 0; } + + virtual void body_set_param(RID p_body, BodyParameter p_param, const Variant &p_value) override {} + virtual Variant body_get_param(RID p_body, BodyParameter p_param) const override { return Variant(); } + + virtual void body_reset_mass_properties(RID p_body) override {} + + virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) override {} + virtual Variant body_get_state(RID p_body, BodyState p_state) const override { return Variant(); } + + virtual void body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) override {} + virtual void body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position = Vector3()) override {} + virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) override {} + + virtual void body_apply_central_force(RID p_body, const Vector3 &p_force) override {} + virtual void body_apply_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position = Vector3()) override {} + virtual void body_apply_torque(RID p_body, const Vector3 &p_torque) override {} + + virtual void body_add_constant_central_force(RID p_body, const Vector3 &p_force) override {} + virtual void body_add_constant_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position = Vector3()) override {} + virtual void body_add_constant_torque(RID p_body, const Vector3 &p_torque) override {} + + virtual void body_set_constant_force(RID p_body, const Vector3 &p_force) override {} + virtual Vector3 body_get_constant_force(RID p_body) const override { return Vector3(); } + + virtual void body_set_constant_torque(RID p_body, const Vector3 &p_torque) override {} + virtual Vector3 body_get_constant_torque(RID p_body) const override { return Vector3(); } + + virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) override {} + + virtual void body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) override {} + virtual bool body_is_axis_locked(RID p_body, BodyAxis p_axis) const override { return false; } + + virtual void body_add_collision_exception(RID p_body, RID p_body_b) override {} + virtual void body_remove_collision_exception(RID p_body, RID p_body_b) override {} + virtual void body_get_collision_exceptions(RID p_body, List *p_exceptions) override {} + + virtual void body_set_max_contacts_reported(RID p_body, int p_contacts) override {} + virtual int body_get_max_contacts_reported(RID p_body) const override { return 0; } + + virtual void body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) override {} + virtual real_t body_get_contacts_reported_depth_threshold(RID p_body) const override { return 0; } + + virtual void body_set_omit_force_integration(RID p_body, bool p_omit) override {} + virtual bool body_is_omitting_force_integration(RID p_body) const override { return false; } + + virtual void body_set_state_sync_callback(RID p_body, const Callable &p_callable) override {} + virtual void body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata = Variant()) override {} + + virtual void body_set_ray_pickable(RID p_body, bool p_enable) override {} + + virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override { return body_state_dummy; } + + virtual bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) override { return false; } + + /* SOFT BODY */ + + virtual RID soft_body_create() override { return RID(); } + + virtual void soft_body_update_rendering_server(RID p_body, PhysicsServer3DRenderingServerHandler *p_rendering_server_handler) override {} + + virtual void soft_body_set_space(RID p_body, RID p_space) override {} + virtual RID soft_body_get_space(RID p_body) const override { return RID(); } + + virtual void soft_body_set_mesh(RID p_body, RID p_mesh) override {} + + virtual AABB soft_body_get_bounds(RID p_body) const override { return AABB(); } + + virtual void soft_body_set_collision_layer(RID p_body, uint32_t p_layer) override {} + virtual uint32_t soft_body_get_collision_layer(RID p_body) const override { return 0; } + + virtual void soft_body_set_collision_mask(RID p_body, uint32_t p_mask) override {} + virtual uint32_t soft_body_get_collision_mask(RID p_body) const override { return 0; } + + virtual void soft_body_add_collision_exception(RID p_body, RID p_body_b) override {} + virtual void soft_body_remove_collision_exception(RID p_body, RID p_body_b) override {} + virtual void soft_body_get_collision_exceptions(RID p_body, List *p_exceptions) override {} + + virtual void soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) override {} + virtual Variant soft_body_get_state(RID p_body, BodyState p_state) const override { return Variant(); } + + virtual void soft_body_set_transform(RID p_body, const Transform3D &p_transform) override {} + + virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) override {} + + virtual void soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) override {} + virtual int soft_body_get_simulation_precision(RID p_body) const override { return 0; } + + virtual void soft_body_set_total_mass(RID p_body, real_t p_total_mass) override {} + virtual real_t soft_body_get_total_mass(RID p_body) const override { return 0; } + + virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override {} + virtual real_t soft_body_get_linear_stiffness(RID p_body) const override { return 0; } + + virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) override {} + virtual real_t soft_body_get_pressure_coefficient(RID p_body) const override { return 0; } + + virtual void soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) override {} + virtual real_t soft_body_get_damping_coefficient(RID p_body) const override { return 0; } + + virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) override {} + virtual real_t soft_body_get_drag_coefficient(RID p_body) const override { return 0; } + + virtual void soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) override {} + virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) const override { return Vector3(); } + + virtual void soft_body_remove_all_pinned_points(RID p_body) override {} + virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) override {} + virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) const override { return false; } + + /* JOINT API */ + + virtual RID joint_create() override { return RID(); } + + virtual void joint_clear(RID p_joint) override {} + + virtual JointType joint_get_type(RID p_joint) const override { return JointType::JOINT_TYPE_PIN; } + + virtual void joint_set_solver_priority(RID p_joint, int p_priority) override {} + virtual int joint_get_solver_priority(RID p_joint) const override { return 0; } + + virtual void joint_disable_collisions_between_bodies(RID p_joint, bool p_disable) override {} + virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const override { return false; } + + virtual void joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override {} + + virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override {} + virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override { return 0; } + + virtual void pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) override {} + virtual Vector3 pin_joint_get_local_a(RID p_joint) const override { return Vector3(); } + + virtual void pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) override {} + virtual Vector3 pin_joint_get_local_b(RID p_joint) const override { return Vector3(); } + + virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform3D &p_hinge_A, RID p_body_B, const Transform3D &p_hinge_B) override {} + virtual void joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override {} + + virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) override {} + virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const override { return 0; } + + virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_enabled) override {} + virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const override { return false; } + + virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override {} + + virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) override {} + virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override { return 0; } + + virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override {} + + virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) override {} + virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override { return 0; } + + virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override {} + + virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param, real_t p_value) override {} + virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) const override { return 0; } + + virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag, bool p_enable) override {} + virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) const override { return false; } + + /* MISC */ + + virtual void free(RID p_rid) override {} + + virtual void set_active(bool p_active) override {} + virtual void init() override { + space_state_dummy = memnew(PhysicsDirectSpaceState3DDummy); + body_state_dummy = memnew(PhysicsDirectBodyState3DDummy(space_state_dummy)); + } + virtual void step(real_t p_step) override {} + virtual void sync() override {} + virtual void flush_queries() override {} + virtual void end_sync() override {} + virtual void finish() override { + memdelete(body_state_dummy); + memdelete(space_state_dummy); + } + + virtual bool is_flushing_queries() const override { return false; } + + virtual int get_process_info(ProcessInfo p_info) override { return 0; } +}; + +#endif // PHYSICS_SERVER_3D_DUMMY_H diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index fc2aae10c7ab..b23c77aa0a84 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -89,8 +89,8 @@ // 3D physics and navigation (3D navigation is needed for 2D). #include "navigation_server_3d.h" #ifndef _3D_DISABLED -#include "physics_3d/godot_physics_server_3d.h" #include "physics_server_3d.h" +#include "physics_server_3d_dummy.h" #include "physics_server_3d_wrap_mt.h" #include "servers/extensions/physics_server_3d_extension.h" #include "xr/xr_body_tracker.h" @@ -106,16 +106,8 @@ ShaderTypes *shader_types = nullptr; #ifndef _3D_DISABLED -static PhysicsServer3D *_createGodotPhysics3DCallback() { -#ifdef THREADS_ENABLED - bool using_threads = GLOBAL_GET("physics/3d/run_on_separate_thread"); -#else - bool using_threads = false; -#endif - - PhysicsServer3D *physics_server_3d = memnew(GodotPhysicsServer3D(using_threads)); - - return memnew(PhysicsServer3DWrapMT(physics_server_3d, using_threads)); +static PhysicsServer3D *_create_dummy_physics_server_3d() { + return memnew(PhysicsServer3DDummy); } #endif // _3D_DISABLED @@ -323,8 +315,7 @@ void register_server_types() { GLOBAL_DEF(PropertyInfo(Variant::STRING, PhysicsServer3DManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT"), "DEFAULT"); - PhysicsServer3DManager::get_singleton()->register_server("GodotPhysics3D", callable_mp_static(_createGodotPhysics3DCallback)); - PhysicsServer3DManager::get_singleton()->set_default_server("GodotPhysics3D"); + PhysicsServer3DManager::get_singleton()->register_server("Dummy", callable_mp_static(_create_dummy_physics_server_3d)); GDREGISTER_ABSTRACT_CLASS(XRInterface); GDREGISTER_CLASS(XRVRS); diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 949e4f0b3301..3c184ccc5d61 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -176,6 +176,7 @@ #include "servers/physics_server_2d.h" #ifndef _3D_DISABLED #include "servers/physics_server_3d.h" +#include "servers/physics_server_3d_dummy.h" #endif // _3D_DISABLED #include "servers/rendering/rendering_server_default.h" @@ -290,6 +291,9 @@ struct GodotTestCaseListener : public doctest::IReporter { #ifndef _3D_DISABLED physics_server_3d = PhysicsServer3DManager::get_singleton()->new_default_server(); + if (!physics_server_3d) { + physics_server_3d = memnew(PhysicsServer3DDummy); + } physics_server_3d->init(); #endif // _3D_DISABLED From 15f344173e9ee00b6083dd1f6e6bc9897b310f90 Mon Sep 17 00:00:00 2001 From: Giganzo <158825920+Giganzo@users.noreply.github.com> Date: Sun, 22 Sep 2024 11:17:06 +0200 Subject: [PATCH 10/20] Fix Add button style in GroupsEditor --- editor/groups_editor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index ce2dbe7cb131..e0de6bbcb186 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -840,7 +840,7 @@ GroupsEditor::GroupsEditor() { add_child(hbc); add = memnew(Button); - add->set_flat(true); + add->set_theme_type_variation("FlatMenuButton"); add->set_tooltip_text(TTR("Add a new group.")); add->connect(SceneStringName(pressed), callable_mp(this, &GroupsEditor::_show_add_group_dialog)); hbc->add_child(add); From 307224927ced54943e1ce3da393c63b35160bd2e Mon Sep 17 00:00:00 2001 From: DE YU <71481700+Delsin-Yu@users.noreply.github.com> Date: Thu, 12 Sep 2024 20:24:06 +0800 Subject: [PATCH 11/20] Replace Reflection-Based implementation with Generated one Co-authored-by: Raul Santos Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> --- .../GodotTools/GodotTools/GodotSharpEditor.cs | 18 +++ modules/mono/editor/bindings_generator.cpp | 127 ++++++++++++++++++ .../Core/Bridge/ScriptManagerBridge.cs | 76 +---------- .../GodotSharp/Core/GodotObject.base.cs | 11 ++ 4 files changed, 158 insertions(+), 74 deletions(-) diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index d3899c809a2b..673f98ee1494 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -7,6 +7,7 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Reflection; using GodotTools.Build; using GodotTools.Ides; using GodotTools.Ides.Rider; @@ -700,6 +701,23 @@ public void OnAfterDeserialize() private static IntPtr InternalCreateInstance(IntPtr unmanagedCallbacks, int unmanagedCallbacksSize) { Internal.Initialize(unmanagedCallbacks, unmanagedCallbacksSize); + + var populateConstructorMethod = + AppDomain.CurrentDomain + .GetAssemblies() + .First(x => x.GetName().Name == "GodotSharpEditor") + .GetType("Godot.EditorConstructors")? + .GetMethod("AddEditorConstructors", + BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); + + if (populateConstructorMethod == null) + { + throw new MissingMethodException("Godot.EditorConstructors", + "AddEditorConstructors"); + } + + populateConstructorMethod.Invoke(null, null); + return new GodotSharpEditor().NativeInstance; } } diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 3222c58c4ed7..4b8bbc04cbed 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -77,6 +77,10 @@ StringBuilder &operator<<(StringBuilder &r_sb, const char *p_cstring) { #define BINDINGS_GLOBAL_SCOPE_CLASS "GD" #define BINDINGS_NATIVE_NAME_FIELD "NativeName" +#define BINDINGS_CLASS_CONSTRUCTOR "Constructors" +#define BINDINGS_CLASS_CONSTRUCTOR_EDITOR "EditorConstructors" +#define BINDINGS_CLASS_CONSTRUCTOR_DICTIONARY "BuiltInMethodConstructors" + #define CS_PARAM_MEMORYOWN "memoryOwn" #define CS_PARAM_METHODBIND "method" #define CS_PARAM_INSTANCE "ptr" @@ -1737,6 +1741,69 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) { compile_items.push_back(output_file); } + // Generate source file for built-in type constructor dictionary. + + { + StringBuilder cs_built_in_ctors_content; + + cs_built_in_ctors_content.append("namespace " BINDINGS_NAMESPACE ";\n\n"); + cs_built_in_ctors_content.append("using System;\n" + "using System.Collections.Generic;\n" + "\n"); + cs_built_in_ctors_content.append("internal static class " BINDINGS_CLASS_CONSTRUCTOR "\n{"); + + cs_built_in_ctors_content.append(MEMBER_BEGIN "internal static readonly Dictionary> " BINDINGS_CLASS_CONSTRUCTOR_DICTIONARY ";\n"); + + cs_built_in_ctors_content.append(MEMBER_BEGIN "public static GodotObject Invoke(string nativeTypeNameStr, IntPtr nativeObjectPtr)\n"); + cs_built_in_ctors_content.append(INDENT1 OPEN_BLOCK); + cs_built_in_ctors_content.append(INDENT2 "if (!" BINDINGS_CLASS_CONSTRUCTOR_DICTIONARY ".TryGetValue(nativeTypeNameStr, out var constructor))\n"); + cs_built_in_ctors_content.append(INDENT3 "throw new InvalidOperationException(\"Wrapper class not found for type: \" + nativeTypeNameStr);\n"); + cs_built_in_ctors_content.append(INDENT2 "return constructor(nativeObjectPtr);\n"); + cs_built_in_ctors_content.append(INDENT1 CLOSE_BLOCK); + + cs_built_in_ctors_content.append(MEMBER_BEGIN "static " BINDINGS_CLASS_CONSTRUCTOR "()\n"); + cs_built_in_ctors_content.append(INDENT1 OPEN_BLOCK); + cs_built_in_ctors_content.append(INDENT2 BINDINGS_CLASS_CONSTRUCTOR_DICTIONARY " = new();\n"); + + for (const KeyValue &E : obj_types) { + const TypeInterface &itype = E.value; + + if (itype.api_type != ClassDB::API_CORE || itype.is_singleton_instance) { + continue; + } + + if (itype.is_deprecated) { + cs_built_in_ctors_content.append("#pragma warning disable CS0618\n"); + } + + cs_built_in_ctors_content.append(INDENT2 BINDINGS_CLASS_CONSTRUCTOR_DICTIONARY ".Add(\""); + cs_built_in_ctors_content.append(itype.name); + cs_built_in_ctors_content.append("\", " CS_PARAM_INSTANCE " => new "); + cs_built_in_ctors_content.append(itype.proxy_name); + if (itype.is_singleton && !itype.is_compat_singleton) { + cs_built_in_ctors_content.append("Instance"); + } + cs_built_in_ctors_content.append("(" CS_PARAM_INSTANCE "));\n"); + + if (itype.is_deprecated) { + cs_built_in_ctors_content.append("#pragma warning restore CS0618\n"); + } + } + + cs_built_in_ctors_content.append(INDENT1 CLOSE_BLOCK); + + cs_built_in_ctors_content.append(CLOSE_BLOCK); + + String constructors_file = path::join(base_gen_dir, BINDINGS_CLASS_CONSTRUCTOR ".cs"); + Error err = _save_file(constructors_file, cs_built_in_ctors_content); + + if (err != OK) { + return err; + } + + compile_items.push_back(constructors_file); + } + // Generate native calls StringBuilder cs_icalls_content; @@ -1844,6 +1911,57 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) { compile_items.push_back(output_file); } + // Generate source file for editor type constructor dictionary. + + { + StringBuilder cs_built_in_ctors_content; + + cs_built_in_ctors_content.append("namespace " BINDINGS_NAMESPACE ";\n\n"); + cs_built_in_ctors_content.append("internal static class " BINDINGS_CLASS_CONSTRUCTOR_EDITOR "\n{"); + + cs_built_in_ctors_content.append(MEMBER_BEGIN "private static void AddEditorConstructors()\n"); + cs_built_in_ctors_content.append(INDENT1 OPEN_BLOCK); + cs_built_in_ctors_content.append(INDENT2 "var builtInMethodConstructors = " BINDINGS_CLASS_CONSTRUCTOR "." BINDINGS_CLASS_CONSTRUCTOR_DICTIONARY ";\n"); + + for (const KeyValue &E : obj_types) { + const TypeInterface &itype = E.value; + + if (itype.api_type != ClassDB::API_EDITOR || itype.is_singleton_instance) { + continue; + } + + if (itype.is_deprecated) { + cs_built_in_ctors_content.append("#pragma warning disable CS0618\n"); + } + + cs_built_in_ctors_content.append(INDENT2 "builtInMethodConstructors.Add(\""); + cs_built_in_ctors_content.append(itype.name); + cs_built_in_ctors_content.append("\", " CS_PARAM_INSTANCE " => new "); + cs_built_in_ctors_content.append(itype.proxy_name); + if (itype.is_singleton && !itype.is_compat_singleton) { + cs_built_in_ctors_content.append("Instance"); + } + cs_built_in_ctors_content.append("(" CS_PARAM_INSTANCE "));\n"); + + if (itype.is_deprecated) { + cs_built_in_ctors_content.append("#pragma warning restore CS0618\n"); + } + } + + cs_built_in_ctors_content.append(INDENT1 CLOSE_BLOCK); + + cs_built_in_ctors_content.append(CLOSE_BLOCK); + + String constructors_file = path::join(base_gen_dir, BINDINGS_CLASS_CONSTRUCTOR_EDITOR ".cs"); + Error err = _save_file(constructors_file, cs_built_in_ctors_content); + + if (err != OK) { + return err; + } + + compile_items.push_back(constructors_file); + } + // Generate native calls StringBuilder cs_icalls_content; @@ -2210,6 +2328,15 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str << CLOSE_BLOCK_L2 CLOSE_BLOCK_L1; } + output << MEMBER_BEGIN "internal " << itype.proxy_name << "(IntPtr " CS_PARAM_INSTANCE ") : this(" + << (itype.memory_own ? "true" : "false") << ")\n" OPEN_BLOCK_L1 + << INDENT2 "NativePtr = " CS_PARAM_INSTANCE ";\n" + << INDENT2 "unsafe\n" INDENT2 OPEN_BLOCK + << INDENT3 "ConstructAndInitialize(null, " + << BINDINGS_NATIVE_NAME_FIELD ", CachedType, refCounted: " + << (itype.is_ref_counted ? "true" : "false") << ");\n" + << CLOSE_BLOCK_L2 CLOSE_BLOCK_L1; + // Add.. em.. trick constructor. Sort of. output.append(MEMBER_BEGIN "internal "); output.append(itype.proxy_name); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs index 901700067dfc..1b3062c5db88 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs @@ -93,27 +93,15 @@ internal static void FrameCallback() internal static unsafe IntPtr CreateManagedForGodotObjectBinding(godot_string_name* nativeTypeName, IntPtr godotObject) { - // TODO: Optimize with source generators and delegate pointers. - try { using var stringName = StringName.CreateTakingOwnershipOfDisposableValue( NativeFuncs.godotsharp_string_name_new_copy(CustomUnsafe.AsRef(nativeTypeName))); string nativeTypeNameStr = stringName.ToString(); - Type nativeType = TypeGetProxyClass(nativeTypeNameStr) ?? throw new InvalidOperationException( - "Wrapper class not found for type: " + nativeTypeNameStr); - var obj = (GodotObject)FormatterServices.GetUninitializedObject(nativeType); - - var ctor = nativeType.GetConstructor( - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, - null, Type.EmptyTypes, null); - - obj.NativePtr = godotObject; - - _ = ctor!.Invoke(obj, null); + var instance = Constructors.Invoke(nativeTypeNameStr, godotObject); - return GCHandle.ToIntPtr(CustomGCHandle.AllocStrong(obj)); + return GCHandle.ToIntPtr(CustomGCHandle.AllocStrong(instance)); } catch (Exception e) { @@ -308,66 +296,6 @@ internal static void SetGodotObjectPtr(IntPtr gcHandlePtr, IntPtr newPtr) } } - private static Type? TypeGetProxyClass(string nativeTypeNameStr) - { - // Performance is not critical here as this will be replaced with a generated dictionary. - - if (nativeTypeNameStr[0] == '_') - nativeTypeNameStr = nativeTypeNameStr.Substring(1); - - Type? wrapperType = typeof(GodotObject).Assembly.GetType("Godot." + nativeTypeNameStr); - - if (wrapperType == null) - { - wrapperType = GetTypeByGodotClassAttr(typeof(GodotObject).Assembly, nativeTypeNameStr); - } - - if (wrapperType == null) - { - var editorAssembly = AppDomain.CurrentDomain.GetAssemblies() - .FirstOrDefault(a => a.GetName().Name == "GodotSharpEditor"); - - if (editorAssembly != null) - { - wrapperType = editorAssembly.GetType("Godot." + nativeTypeNameStr); - - if (wrapperType == null) - { - wrapperType = GetTypeByGodotClassAttr(editorAssembly, nativeTypeNameStr); - } - } - } - - static Type? GetTypeByGodotClassAttr(Assembly assembly, string nativeTypeNameStr) - { - var types = assembly.GetTypes(); - foreach (var type in types) - { - var attr = type.GetCustomAttribute(); - if (attr?.Name == nativeTypeNameStr) - { - return type; - } - } - return null; - } - - static bool IsStatic(Type type) => type.IsAbstract && type.IsSealed; - - if (wrapperType != null && IsStatic(wrapperType)) - { - // A static class means this is a Godot singleton class. Try to get the Instance proxy type. - wrapperType = TypeGetProxyClass($"{wrapperType.Name}Instance"); - if (wrapperType == null) - { - // Otherwise, fallback to GodotObject. - return typeof(GodotObject); - } - } - - return wrapperType; - } - // Called from GodotPlugins // ReSharper disable once UnusedMember.Local public static void LookupScriptsInAssembly(Assembly assembly) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs index c094eaed7787..a429931399c0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs @@ -29,6 +29,17 @@ public GodotObject() : this(false) } } + internal GodotObject(IntPtr nativePtr) : this(false) + { + // NativePtr must be non-zero before calling ConstructAndInitialize to avoid invoking the constructor NativeCtor. + // We don't want to invoke the constructor, because we already have a constructed instance in nativePtr. + NativePtr = nativePtr; + unsafe + { + ConstructAndInitialize(NativeCtor, NativeName, _cachedType, refCounted: false); + } + } + internal unsafe void ConstructAndInitialize( delegate* unmanaged nativeCtor, StringName nativeName, From d49ec39d630d63d54301389e15c9510a83766756 Mon Sep 17 00:00:00 2001 From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> Date: Sat, 20 Apr 2024 20:19:48 +0200 Subject: [PATCH 12/20] [Core] Add `Engine.print_to_stout` setting to control printing Also added notes to the related project settings pointing to the `Engine` properties. --- core/config/engine.cpp | 8 ++++++++ core/config/engine.h | 3 +++ core/core_bind.cpp | 12 ++++++++++++ core/core_bind.h | 3 +++ doc/classes/@GlobalScope.xml | 2 +- doc/classes/Engine.xml | 4 ++++ doc/classes/ProjectSettings.xml | 4 ++-- 7 files changed, 33 insertions(+), 3 deletions(-) diff --git a/core/config/engine.cpp b/core/config/engine.cpp index 9cdc21fe8e2d..d77c91331426 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -267,6 +267,14 @@ bool Engine::is_extra_gpu_memory_tracking_enabled() const { return extra_gpu_memory_tracking; } +void Engine::set_print_to_stdout(bool p_enabled) { + CoreGlobals::print_line_enabled = p_enabled; +} + +bool Engine::is_printing_to_stdout() const { + return CoreGlobals::print_line_enabled; +} + void Engine::set_print_error_messages(bool p_enabled) { CoreGlobals::print_error_enabled = p_enabled; } diff --git a/core/config/engine.h b/core/config/engine.h index f858eba32838..a0b1ffa98123 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -128,6 +128,9 @@ class Engine { void set_time_scale(double p_scale); double get_time_scale() const; + void set_print_to_stdout(bool p_enabled); + bool is_printing_to_stdout() const; + void set_print_error_messages(bool p_enabled); bool is_printing_error_messages() const; void print_header(const String &p_string) const; diff --git a/core/core_bind.cpp b/core/core_bind.cpp index bbfbb6e3cd7d..7addda508f36 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -1848,6 +1848,14 @@ String Engine::get_write_movie_path() const { return ::Engine::get_singleton()->get_write_movie_path(); } +void Engine::set_print_to_stdout(bool p_enabled) { + ::Engine::get_singleton()->set_print_to_stdout(p_enabled); +} + +bool Engine::is_printing_to_stdout() const { + return ::Engine::get_singleton()->is_printing_to_stdout(); +} + void Engine::set_print_error_messages(bool p_enabled) { ::Engine::get_singleton()->set_print_error_messages(p_enabled); } @@ -1916,10 +1924,14 @@ void Engine::_bind_methods() { ClassDB::bind_method(D_METHOD("get_write_movie_path"), &Engine::get_write_movie_path); + ClassDB::bind_method(D_METHOD("set_print_to_stdout", "enabled"), &Engine::set_print_to_stdout); + ClassDB::bind_method(D_METHOD("is_printing_to_stdout"), &Engine::is_printing_to_stdout); + ClassDB::bind_method(D_METHOD("set_print_error_messages", "enabled"), &Engine::set_print_error_messages); ClassDB::bind_method(D_METHOD("is_printing_error_messages"), &Engine::is_printing_error_messages); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "print_error_messages"), "set_print_error_messages", "is_printing_error_messages"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "print_to_stdout"), "set_print_to_stdout", "is_printing_to_stdout"); ADD_PROPERTY(PropertyInfo(Variant::INT, "physics_ticks_per_second"), "set_physics_ticks_per_second", "get_physics_ticks_per_second"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_physics_steps_per_frame"), "set_max_physics_steps_per_frame", "get_max_physics_steps_per_frame"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_fps"), "set_max_fps", "get_max_fps"); diff --git a/core/core_bind.h b/core/core_bind.h index 2a31e644255f..1af662b290f1 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -567,6 +567,9 @@ class Engine : public Object { // `set_write_movie_path()` is not exposed to the scripting API as changing it at run-time has no effect. String get_write_movie_path() const; + void set_print_to_stdout(bool p_enabled); + bool is_printing_to_stdout() const; + void set_print_error_messages(bool p_enabled); bool is_printing_error_messages() const; diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index f222cbc96953..a86f41cd9c1b 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -856,7 +856,7 @@ GD.Print("a", "b", a); // Prints ab[1, 2, 3] [/csharp] [/codeblocks] - [b]Note:[/b] Consider using [method push_error] and [method push_warning] to print error and warning messages instead of [method print] or [method print_rich]. This distinguishes them from print messages used for debugging purposes, while also displaying a stack trace when an error or warning is printed. + [b]Note:[/b] Consider using [method push_error] and [method push_warning] to print error and warning messages instead of [method print] or [method print_rich]. This distinguishes them from print messages used for debugging purposes, while also displaying a stack trace when an error or warning is printed. See also [member Engine.print_to_stdout] and [member ProjectSettings.application/run/disable_stdout]. diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index ca78054875bf..bba515705384 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -337,6 +337,10 @@ [b]Note:[/b] This property does not impact the editor's Errors tab when running a project from the editor. [b]Warning:[/b] If set to [code]false[/code] anywhere in the project, important error messages may be hidden even if they are emitted from other scripts. In a [code]@tool[/code] script, this will also impact the editor itself. Do [i]not[/i] report bugs before ensuring error messages are enabled (as they are by default). + + If [code]false[/code], stops printing messages (for example using [method @GlobalScope.print]) to the console, log files, and editor Output log. This property is equivalent to the [member ProjectSettings.application/run/disable_stdout] project setting. + [b]Note:[/b] This does not stop printing errors or warnings produced by scripts to the console or log files, for more details see [member print_error_messages]. + The speed multiplier at which the in-game clock updates, compared to real time. For example, if set to [code]2.0[/code] the game runs twice as fast, and if set to [code]0.5[/code] the game runs half as fast. This value affects [Timer], [SceneTreeTimer], and all other simulations that make use of [code]delta[/code] time (such as [method Node._process] and [method Node._physics_process]). diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 758e98ad8577..c4b2d60ca0b7 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -314,11 +314,11 @@ If [code]true[/code], disables printing to standard error. If [code]true[/code], this also hides error and warning messages printed by [method @GlobalScope.push_error] and [method @GlobalScope.push_warning]. See also [member application/run/disable_stdout]. - Changes to this setting will only be applied upon restarting the application. + Changes to this setting will only be applied upon restarting the application. To control this at runtime, use [member Engine.print_error_messages]. If [code]true[/code], disables printing to standard output. This is equivalent to starting the editor or project with the [code]--quiet[/code] [url=$DOCS_URL/tutorials/editor/command_line_tutorial.html]command line argument[/url]. See also [member application/run/disable_stderr]. - Changes to this setting will only be applied upon restarting the application. + Changes to this setting will only be applied upon restarting the application. To control this at runtime, use [member Engine.print_to_stdout]. If [code]true[/code], allows the [kbd]Alt + Space[/kbd] keys to display the window menu. This menu allows the user to perform various window management operations such as moving, resizing, or minimizing the window. From a751c05b15e75904cc949934f95061f1c0ee40e4 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Sun, 22 Sep 2024 19:31:58 +0800 Subject: [PATCH 13/20] Fix script editor wrongly replaces and quotes non-ASCII letters --- core/string/ustring.cpp | 25 ++++++++++++++++++++++++- core/string/ustring.h | 1 + editor/plugins/script_text_editor.cpp | 8 ++++---- modules/gdscript/gdscript_editor.cpp | 4 ++-- tests/core/string/test_string.h | 16 +++++++++++++++- 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 2683addd4b34..391a203d5b59 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -4626,7 +4626,7 @@ bool String::is_absolute_path() const { String String::validate_ascii_identifier() const { if (is_empty()) { - return "_"; // Empty string is not a valid identifier; + return "_"; // Empty string is not a valid identifier. } String result; @@ -4647,6 +4647,29 @@ String String::validate_ascii_identifier() const { return result; } +String String::validate_unicode_identifier() const { + if (is_empty()) { + return "_"; // Empty string is not a valid identifier. + } + + String result; + if (is_unicode_identifier_start(operator[](0))) { + result = *this; + } else { + result = "_" + *this; + } + + int len = result.length(); + char32_t *buffer = result.ptrw(); + for (int i = 0; i < len; i++) { + if (!is_unicode_identifier_continue(buffer[i])) { + buffer[i] = '_'; + } + } + + return result; +} + bool String::is_valid_ascii_identifier() const { int len = length(); diff --git a/core/string/ustring.h b/core/string/ustring.h index 11f15031f99e..5d4b209c2523 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -460,6 +460,7 @@ class String { static String get_invalid_node_name_characters(bool p_allow_internal = false); String validate_node_name() const; String validate_ascii_identifier() const; + String validate_unicode_identifier() const; String validate_filename() const; bool is_valid_ascii_identifier() const; diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 7e8fba8b9ecc..b45b30b52ec1 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1813,9 +1813,9 @@ static String _get_dropped_resource_line(const Ref &p_resource, bool p } if (is_script) { - variable_name = variable_name.to_pascal_case().validate_ascii_identifier(); + variable_name = variable_name.to_pascal_case().validate_unicode_identifier(); } else { - variable_name = variable_name.to_snake_case().to_upper().validate_ascii_identifier(); + variable_name = variable_name.to_snake_case().to_upper().validate_unicode_identifier(); } return vformat("const %s = preload(%s)", variable_name, _quote_drop_data(path)); } @@ -1927,13 +1927,13 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data path = sn->get_path_to(node); } for (const String &segment : path.split("/")) { - if (!segment.is_valid_ascii_identifier()) { + if (!segment.is_valid_unicode_identifier()) { path = _quote_drop_data(path); break; } } - String variable_name = String(node->get_name()).to_snake_case().validate_ascii_identifier(); + String variable_name = String(node->get_name()).to_snake_case().validate_unicode_identifier(); if (use_type) { StringName class_name = node->get_class_name(); Ref