diff options
25 files changed, 139 insertions, 74 deletions
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 018839b817..f6d11e2efe 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -34,6 +34,7 @@ jobs: tests: true sconsflags: use_asan=yes use_ubsan=yes proj-test: true + godot-cpp-test: true bin: "./bin/godot.linuxbsd.tools.64s" # Skip 2GiB artifact speeding up action. artifact: false @@ -126,6 +127,46 @@ jobs: VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ${{ matrix.bin }} 40 --audio-driver Dummy --path test_project 2>&1 | tee sanitizers_log.txt || true misc/scripts/check_ci_log.py sanitizers_log.txt + # Checkout godot-cpp + - name: Checkout godot-cpp + if: ${{ matrix.godot-cpp-test }} + uses: actions/checkout@v2 + with: + repository: godotengine/godot-cpp + submodules: 'recursive' + path: 'godot-cpp' + + # Check extension API + - name: Check for extension api updates + if: ${{ matrix.godot-cpp-test }} + run: | + echo "Running --dump-extension-api to create extensions api." + VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --audio-driver Dummy --dump-extension-api 2>&1 > /dev/null || true + misc/scripts/compare_extension_api.py godot-cpp/godot-headers/extension_api.json extension_api.json + + # Copy new extension API files into place + - name: Copy new extension API files into place + if: ${{ matrix.godot-cpp-test }} + run: | + cp -f extension_api.json godot-cpp/godot-headers/ + cp -f core/extension/gdnative_interface.h godot-cpp/godot-headers/godot/ + + # Build godot-cpp library + - name: Build godot-cpp library + if: ${{ matrix.godot-cpp-test }} + run: | + cd godot-cpp + scons target=${{ matrix.target }} generate_bindings=yes -j2 + cd .. + + # Build godot-cpp test extension + - name: Build godot-cpp test extension + if: ${{ matrix.godot-cpp-test }} + run: | + cd godot-cpp/test + scons target=${{ matrix.target }} -j2 + cd ../.. + - name: Prepare artifact if: ${{ matrix.artifact }} run: | diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index daeb7fbd17..b1e685651e 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -2137,7 +2137,7 @@ int64_t String::hex_to_int() const { s++; } - if (len > 2 && s[0] == '0' && s[1] == 'x') { + if (len > 2 && s[0] == '0' && lower_case(s[1]) == 'x') { s += 2; } @@ -2151,7 +2151,7 @@ int64_t String::hex_to_int() const { } else if (c >= 'a' && c <= 'f') { n = (c - 'a') + 10; } else { - return 0; + ERR_FAIL_COND_V_MSG(true, 0, "Invalid hexadecimal notation character \"" + chr(*s) + "\" in string \"" + *this + "\"."); } // Check for overflow/underflow, with special case to ensure INT64_MIN does not result in error bool overflow = ((hex > INT64_MAX / 16) && (sign == 1 || (sign == -1 && hex != (INT64_MAX >> 4) + 1))) || (sign == -1 && hex == (INT64_MAX >> 4) + 1 && c > '0'); diff --git a/doc/classes/SceneTreeTimer.xml b/doc/classes/SceneTreeTimer.xml index f97c5e42b5..b0509a322e 100644 --- a/doc/classes/SceneTreeTimer.xml +++ b/doc/classes/SceneTreeTimer.xml @@ -10,7 +10,7 @@ [gdscript] func some_function(): print("Timer started.") - yield(get_tree().create_timer(1.0), "timeout") + await get_tree().create_timer(1.0).timeout print("Timer ended.") [/gdscript] [csharp] diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 10ce03c4b2..abb68e0d05 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -56,11 +56,11 @@ Converts a string containing a binary number into an integer. Binary strings can either be prefixed with [code]0b[/code] or not, and they can also start with a [code]-[/code] before the optional prefix. [codeblocks] [gdscript] - print("0x101".bin_to_int()) # Prints "5". + print("0b101".bin_to_int()) # Prints "5". print("101".bin_to_int()) # Prints "5". [/gdscript] [csharp] - GD.Print("0x101".BinToInt()); // Prints "5". + GD.Print("0b101".BinToInt()); // Prints "5". GD.Print("101".BinToInt()); // Prints "5". [/csharp] [/codeblocks] diff --git a/main/main.cpp b/main/main.cpp index f0bc51c10f..d4a6216e35 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2072,6 +2072,8 @@ bool Main::start() { if (check_only) { if (!script_res->is_valid()) { OS::get_singleton()->set_exit_code(EXIT_FAILURE); + } else { + OS::get_singleton()->set_exit_code(EXIT_SUCCESS); } return false; } diff --git a/misc/scripts/compare_extension_api.py b/misc/scripts/compare_extension_api.py new file mode 100755 index 0000000000..f96db4278c --- /dev/null +++ b/misc/scripts/compare_extension_api.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys + +# TODO: +# Add a process that compares the original godot-cpp/godot-headers/extension_api.json with the new extension_api.json (both passed as arguments) and reports any API calls that have been removed. +# If we only have additions or no changes to the file, we pass +# For now we deem this too early because the API isn't stable enough yet. + +sys.exit(0) diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index 81b832fb42..3a2370ff31 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -116,6 +116,7 @@ void SoftBodyBullet::set_soft_mesh(RID p_mesh) { } Array arrays = RenderingServer::get_singleton()->mesh_surface_get_arrays(soft_mesh, 0); + ERR_FAIL_COND(arrays.is_empty()); bool success = set_trimesh_body_shape(arrays[RS::ARRAY_INDEX], arrays[RS::ARRAY_VERTEX]); if (!success) { diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp index bb6bc578a4..8fd3a13e1f 100644 --- a/modules/navigation/navigation_mesh_generator.cpp +++ b/modules/navigation/navigation_mesh_generator.cpp @@ -489,7 +489,7 @@ NavigationMeshGenerator::~NavigationMeshGenerator() { } void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) { - ERR_FAIL_COND(!p_nav_mesh.is_valid()); + ERR_FAIL_COND_MSG(!p_nav_mesh.is_valid(), "Invalid navigation mesh."); #ifdef TOOLS_ENABLED EditorProgress *ep(nullptr); diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index 6916f832d0..28facd09ce 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -454,7 +454,7 @@ void CollisionObject2D::shape_owner_clear_shapes(uint32_t p_owner) { } uint32_t CollisionObject2D::shape_find_owner(int p_shape_index) const { - ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, 0); + ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, UINT32_MAX); for (const KeyValue<uint32_t, ShapeData> &E : shapes) { for (int i = 0; i < E.value.shapes.size(); i++) { @@ -465,7 +465,7 @@ uint32_t CollisionObject2D::shape_find_owner(int p_shape_index) const { } //in theory it should be unreachable - return 0; + ERR_FAIL_V_MSG(UINT32_MAX, "Can't find owner for shape index " + itos(p_shape_index) + "."); } void CollisionObject2D::set_pickable(bool p_enabled) { diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 15008390b7..58bff97da9 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -96,6 +96,10 @@ Rect2 MeshInstance2D::_edit_get_rect() const { return Node2D::_edit_get_rect(); } + +bool MeshInstance2D::_edit_use_rect() const { + return mesh.is_valid(); +} #endif MeshInstance2D::MeshInstance2D() { diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h index adfda4cf7f..f94d53da7d 100644 --- a/scene/2d/mesh_instance_2d.h +++ b/scene/2d/mesh_instance_2d.h @@ -48,6 +48,7 @@ protected: public: #ifdef TOOLS_ENABLED virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; #endif void set_mesh(const Ref<Mesh> &p_mesh); diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 2f00978123..7faa964407 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -184,7 +184,7 @@ Vector2 NavigationAgent2D::get_target_location() const { Vector2 NavigationAgent2D::get_next_location() { update_navigation(); if (navigation_path.size() == 0) { - ERR_FAIL_COND_V(agent_parent == nullptr, Vector2()); + ERR_FAIL_COND_V_MSG(agent_parent == nullptr, Vector2(), "The agent has no parent."); return agent_parent->get_global_position(); } else { return navigation_path[nav_path_index]; @@ -192,7 +192,7 @@ Vector2 NavigationAgent2D::get_next_location() { } real_t NavigationAgent2D::distance_to_target() const { - ERR_FAIL_COND_V(agent_parent == nullptr, 0.0); + ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent."); return agent_parent->get_global_position().distance_to(target_location); } diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index 814ed5c2a7..fd891a5e13 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -648,7 +648,7 @@ void CollisionObject3D::shape_owner_clear_shapes(uint32_t p_owner) { } uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const { - ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, 0); + ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, UINT32_MAX); for (const KeyValue<uint32_t, ShapeData> &E : shapes) { for (int i = 0; i < E.value.shapes.size(); i++) { @@ -659,7 +659,7 @@ uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const { } //in theory it should be unreachable - return 0; + ERR_FAIL_V_MSG(UINT32_MAX, "Can't find owner for shape index " + itos(p_shape_index) + "."); } CollisionObject3D::CollisionObject3D(RID p_rid, bool p_area) { diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index c2d5c757db..1bc7d20c19 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -192,7 +192,7 @@ Vector3 NavigationAgent3D::get_target_location() const { Vector3 NavigationAgent3D::get_next_location() { update_navigation(); if (navigation_path.size() == 0) { - ERR_FAIL_COND_V(agent_parent == nullptr, Vector3()); + ERR_FAIL_COND_V_MSG(agent_parent == nullptr, Vector3(), "The agent has no parent."); return agent_parent->get_global_transform().origin; } else { return navigation_path[nav_path_index] - Vector3(0, navigation_height_offset, 0); @@ -200,7 +200,7 @@ Vector3 NavigationAgent3D::get_next_location() { } real_t NavigationAgent3D::distance_to_target() const { - ERR_FAIL_COND_V(agent_parent == nullptr, 0.0); + ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent."); return agent_parent->get_global_transform().origin.distance_to(target_location); } diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 8a51a259f7..473368cf69 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -162,7 +162,7 @@ void _bake_navigation_mesh(void *p_user_data) { } void NavigationRegion3D::bake_navigation_mesh() { - ERR_FAIL_COND(bake_thread.is_started()); + ERR_FAIL_COND_MSG(bake_thread.is_started(), "Unable to start another bake request. The navigation mesh bake thread is already baking a navigation mesh."); BakeThreadsArgs *args = memnew(BakeThreadsArgs); args->nav_region = this; diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp index 43292d42f1..903eedb58b 100644 --- a/scene/3d/soft_dynamic_body_3d.cpp +++ b/scene/3d/soft_dynamic_body_3d.cpp @@ -552,15 +552,9 @@ void SoftDynamicBody3D::set_disable_mode(DisableMode p_mode) { return; } - bool inside_tree = is_inside_tree(); - - if (inside_tree && (disable_mode == DISABLE_MODE_REMOVE)) { - _prepare_physics_server(); - } - disable_mode = p_mode; - if (inside_tree && (disable_mode == DISABLE_MODE_REMOVE)) { + if (mesh.is_valid() && is_inside_tree() && !is_enabled()) { _prepare_physics_server(); } } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 9ea98174c9..99c5e3bf0c 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -2276,33 +2276,33 @@ void LineEdit::_ensure_menu() { menu_dir = memnew(PopupMenu); menu_dir->set_name("DirMenu"); - menu_dir->add_radio_check_item(RTR("Same as layout direction"), MENU_DIR_INHERITED); - menu_dir->add_radio_check_item(RTR("Auto-detect direction"), MENU_DIR_AUTO); - menu_dir->add_radio_check_item(RTR("Left-to-right"), MENU_DIR_LTR); - menu_dir->add_radio_check_item(RTR("Right-to-left"), MENU_DIR_RTL); - menu->add_child(menu_dir); + menu_dir->add_radio_check_item(RTR("Same as Layout Direction"), MENU_DIR_INHERITED); + menu_dir->add_radio_check_item(RTR("Auto-Detect Direction"), MENU_DIR_AUTO); + menu_dir->add_radio_check_item(RTR("Left-to-Right"), MENU_DIR_LTR); + menu_dir->add_radio_check_item(RTR("Right-to-Left"), MENU_DIR_RTL); + menu->add_child(menu_dir, false, INTERNAL_MODE_FRONT); menu_ctl = memnew(PopupMenu); menu_ctl->set_name("CTLMenu"); - menu_ctl->add_item(RTR("Left-to-right mark (LRM)"), MENU_INSERT_LRM); - menu_ctl->add_item(RTR("Right-to-left mark (RLM)"), MENU_INSERT_RLM); - menu_ctl->add_item(RTR("Start of left-to-right embedding (LRE)"), MENU_INSERT_LRE); - menu_ctl->add_item(RTR("Start of right-to-left embedding (RLE)"), MENU_INSERT_RLE); - menu_ctl->add_item(RTR("Start of left-to-right override (LRO)"), MENU_INSERT_LRO); - menu_ctl->add_item(RTR("Start of right-to-left override (RLO)"), MENU_INSERT_RLO); - menu_ctl->add_item(RTR("Pop direction formatting (PDF)"), MENU_INSERT_PDF); + menu_ctl->add_item(RTR("Left-to-Right Mark (LRM)"), MENU_INSERT_LRM); + menu_ctl->add_item(RTR("Right-to-Left Mark (RLM)"), MENU_INSERT_RLM); + menu_ctl->add_item(RTR("Start of Left-to-Right Embedding (LRE)"), MENU_INSERT_LRE); + menu_ctl->add_item(RTR("Start of Right-to-Left Embedding (RLE)"), MENU_INSERT_RLE); + menu_ctl->add_item(RTR("Start of Left-to-Right Override (LRO)"), MENU_INSERT_LRO); + menu_ctl->add_item(RTR("Start of Right-to-Left Override (RLO)"), MENU_INSERT_RLO); + menu_ctl->add_item(RTR("Pop Direction Formatting (PDF)"), MENU_INSERT_PDF); menu_ctl->add_separator(); - menu_ctl->add_item(RTR("Arabic letter mark (ALM)"), MENU_INSERT_ALM); - menu_ctl->add_item(RTR("Left-to-right isolate (LRI)"), MENU_INSERT_LRI); - menu_ctl->add_item(RTR("Right-to-left isolate (RLI)"), MENU_INSERT_RLI); - menu_ctl->add_item(RTR("First strong isolate (FSI)"), MENU_INSERT_FSI); - menu_ctl->add_item(RTR("Pop direction isolate (PDI)"), MENU_INSERT_PDI); + menu_ctl->add_item(RTR("Arabic Letter Mark (ALM)"), MENU_INSERT_ALM); + menu_ctl->add_item(RTR("Left-to-Right Isolate (LRI)"), MENU_INSERT_LRI); + menu_ctl->add_item(RTR("Right-to-Left Isolate (RLI)"), MENU_INSERT_RLI); + menu_ctl->add_item(RTR("First Strong Isolate (FSI)"), MENU_INSERT_FSI); + menu_ctl->add_item(RTR("Pop Direction Isolate (PDI)"), MENU_INSERT_PDI); menu_ctl->add_separator(); - menu_ctl->add_item(RTR("Zero width joiner (ZWJ)"), MENU_INSERT_ZWJ); - menu_ctl->add_item(RTR("Zero width non-joiner (ZWNJ)"), MENU_INSERT_ZWNJ); - menu_ctl->add_item(RTR("Word joiner (WJ)"), MENU_INSERT_WJ); - menu_ctl->add_item(RTR("Soft hyphen (SHY)"), MENU_INSERT_SHY); - menu->add_child(menu_ctl); + menu_ctl->add_item(RTR("Zero-Width Joiner (ZWJ)"), MENU_INSERT_ZWJ); + menu_ctl->add_item(RTR("Zero-Width Non-Joiner (ZWNJ)"), MENU_INSERT_ZWNJ); + menu_ctl->add_item(RTR("Word Joiner (WJ)"), MENU_INSERT_WJ); + menu_ctl->add_item(RTR("Soft Hyphen (SHY)"), MENU_INSERT_SHY); + menu->add_child(menu_ctl, false, INTERNAL_MODE_FRONT); menu->connect("id_pressed", callable_mp(this, &LineEdit::menu_option)); menu_dir->connect("id_pressed", callable_mp(this, &LineEdit::menu_option)); @@ -2329,12 +2329,12 @@ void LineEdit::_ensure_menu() { menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_redo") : 0); } menu->add_separator(); - menu->add_submenu_item(RTR("Text writing direction"), "DirMenu"); + menu->add_submenu_item(RTR("Text Writing Direction"), "DirMenu"); menu->add_separator(); - menu->add_check_item(RTR("Display control characters"), MENU_DISPLAY_UCC); + menu->add_check_item(RTR("Display Control Characters"), MENU_DISPLAY_UCC); menu->set_item_checked(menu->get_item_index(MENU_DISPLAY_UCC), draw_control_chars); if (editable) { - menu->add_submenu_item(RTR("Insert control character"), "CTLMenu"); + menu->add_submenu_item(RTR("Insert Control Character"), "CTLMenu"); } menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_INHERITED), text_direction == TEXT_DIRECTION_INHERITED); menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_AUTO), text_direction == TEXT_DIRECTION_AUTO); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 9899b02dde..a1d66d8544 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -5193,32 +5193,32 @@ void TextEdit::_generate_context_menu() { menu_dir = memnew(PopupMenu); menu_dir->set_name("DirMenu"); - menu_dir->add_radio_check_item(RTR("Same as layout direction"), MENU_DIR_INHERITED); - menu_dir->add_radio_check_item(RTR("Auto-detect direction"), MENU_DIR_AUTO); - menu_dir->add_radio_check_item(RTR("Left-to-right"), MENU_DIR_LTR); - menu_dir->add_radio_check_item(RTR("Right-to-left"), MENU_DIR_RTL); + menu_dir->add_radio_check_item(RTR("Same as Layout Direction"), MENU_DIR_INHERITED); + menu_dir->add_radio_check_item(RTR("Auto-Detect Direction"), MENU_DIR_AUTO); + menu_dir->add_radio_check_item(RTR("Left-to-Right"), MENU_DIR_LTR); + menu_dir->add_radio_check_item(RTR("Right-to-Left"), MENU_DIR_RTL); menu->add_child(menu_dir, false, INTERNAL_MODE_FRONT); menu_ctl = memnew(PopupMenu); menu_ctl->set_name("CTLMenu"); - menu_ctl->add_item(RTR("Left-to-right mark (LRM)"), MENU_INSERT_LRM); - menu_ctl->add_item(RTR("Right-to-left mark (RLM)"), MENU_INSERT_RLM); - menu_ctl->add_item(RTR("Start of left-to-right embedding (LRE)"), MENU_INSERT_LRE); - menu_ctl->add_item(RTR("Start of right-to-left embedding (RLE)"), MENU_INSERT_RLE); - menu_ctl->add_item(RTR("Start of left-to-right override (LRO)"), MENU_INSERT_LRO); - menu_ctl->add_item(RTR("Start of right-to-left override (RLO)"), MENU_INSERT_RLO); - menu_ctl->add_item(RTR("Pop direction formatting (PDF)"), MENU_INSERT_PDF); + menu_ctl->add_item(RTR("Left-to-Right Mark (LRM)"), MENU_INSERT_LRM); + menu_ctl->add_item(RTR("Right-to-Left Mark (RLM)"), MENU_INSERT_RLM); + menu_ctl->add_item(RTR("Start of Left-to-Right Embedding (LRE)"), MENU_INSERT_LRE); + menu_ctl->add_item(RTR("Start of Right-to-Left Embedding (RLE)"), MENU_INSERT_RLE); + menu_ctl->add_item(RTR("Start of Left-to-Right Override (LRO)"), MENU_INSERT_LRO); + menu_ctl->add_item(RTR("Start of Right-to-Left Override (RLO)"), MENU_INSERT_RLO); + menu_ctl->add_item(RTR("Pop Direction Formatting (PDF)"), MENU_INSERT_PDF); menu_ctl->add_separator(); - menu_ctl->add_item(RTR("Arabic letter mark (ALM)"), MENU_INSERT_ALM); - menu_ctl->add_item(RTR("Left-to-right isolate (LRI)"), MENU_INSERT_LRI); - menu_ctl->add_item(RTR("Right-to-left isolate (RLI)"), MENU_INSERT_RLI); - menu_ctl->add_item(RTR("First strong isolate (FSI)"), MENU_INSERT_FSI); - menu_ctl->add_item(RTR("Pop direction isolate (PDI)"), MENU_INSERT_PDI); + menu_ctl->add_item(RTR("Arabic Letter Mark (ALM)"), MENU_INSERT_ALM); + menu_ctl->add_item(RTR("Left-to-Right Isolate (LRI)"), MENU_INSERT_LRI); + menu_ctl->add_item(RTR("Right-to-Left Isolate (RLI)"), MENU_INSERT_RLI); + menu_ctl->add_item(RTR("First Strong Isolate (FSI)"), MENU_INSERT_FSI); + menu_ctl->add_item(RTR("Pop Direction Isolate (PDI)"), MENU_INSERT_PDI); menu_ctl->add_separator(); - menu_ctl->add_item(RTR("Zero width joiner (ZWJ)"), MENU_INSERT_ZWJ); - menu_ctl->add_item(RTR("Zero width non-joiner (ZWNJ)"), MENU_INSERT_ZWNJ); - menu_ctl->add_item(RTR("Word joiner (WJ)"), MENU_INSERT_WJ); - menu_ctl->add_item(RTR("Soft hyphen (SHY)"), MENU_INSERT_SHY); + menu_ctl->add_item(RTR("Zero-Width Joiner (ZWJ)"), MENU_INSERT_ZWJ); + menu_ctl->add_item(RTR("Zero-Width Non-Joiner (ZWNJ)"), MENU_INSERT_ZWNJ); + menu_ctl->add_item(RTR("Word Joiner (WJ)"), MENU_INSERT_WJ); + menu_ctl->add_item(RTR("Soft Hyphen (SHY)"), MENU_INSERT_SHY); menu->add_child(menu_ctl, false, INTERNAL_MODE_FRONT); menu->connect("id_pressed", callable_mp(this, &TextEdit::menu_option)); @@ -5246,12 +5246,12 @@ void TextEdit::_generate_context_menu() { menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_redo") : 0); } menu->add_separator(); - menu->add_submenu_item(RTR("Text writing direction"), "DirMenu"); + menu->add_submenu_item(RTR("Text Writing Direction"), "DirMenu"); menu->add_separator(); - menu->add_check_item(RTR("Display control characters"), MENU_DISPLAY_UCC); + menu->add_check_item(RTR("Display Control Characters"), MENU_DISPLAY_UCC); menu->set_item_checked(menu->get_item_index(MENU_DISPLAY_UCC), draw_control_chars); if (editable) { - menu->add_submenu_item(RTR("Insert control character"), "CTLMenu"); + menu->add_submenu_item(RTR("Insert Control Character"), "CTLMenu"); } menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_INHERITED), text_direction == TEXT_DIRECTION_INHERITED); menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_AUTO), text_direction == TEXT_DIRECTION_AUTO); diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 4540e42b4c..26bff4494b 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -128,7 +128,7 @@ void CanvasLayer::_notification(int p_what) { } else { vp = Node::get_viewport(); } - ERR_FAIL_COND(!vp); + ERR_FAIL_NULL_MSG(vp, "Viewport is not initialized."); vp->_canvas_layer_add(this); viewport = vp->get_viewport_rid(); @@ -140,6 +140,8 @@ void CanvasLayer::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { + ERR_FAIL_NULL_MSG(vp, "Viewport is not initialized."); + vp->_canvas_layer_remove(this); RenderingServer::get_singleton()->viewport_remove_canvas(viewport, canvas); viewport = RID(); @@ -160,6 +162,8 @@ Size2 CanvasLayer::get_viewport_size() const { return Size2(1, 1); } + ERR_FAIL_NULL_V_MSG(vp, Size2(1, 1), "Viewport is not initialized."); + Rect2 r = vp->get_visible_rect(); return r.size; } @@ -169,7 +173,7 @@ RID CanvasLayer::get_viewport() const { } void CanvasLayer::set_custom_viewport(Node *p_viewport) { - ERR_FAIL_NULL(p_viewport); + ERR_FAIL_NULL_MSG(p_viewport, "Cannot set viewport to nullptr."); if (is_inside_tree()) { vp->_canvas_layer_remove(this); RenderingServer::get_singleton()->viewport_remove_canvas(viewport, canvas); diff --git a/servers/physics_2d/godot_body_2d.cpp b/servers/physics_2d/godot_body_2d.cpp index 68f114a34a..a18c748e1d 100644 --- a/servers/physics_2d/godot_body_2d.cpp +++ b/servers/physics_2d/godot_body_2d.cpp @@ -276,6 +276,7 @@ PhysicsServer2D::BodyMode GodotBody2D::get_mode() const { void GodotBody2D::_shapes_changed() { _mass_properties_changed(); + wakeup(); wakeup_neighbours(); } diff --git a/servers/physics_3d/godot_body_3d.cpp b/servers/physics_3d/godot_body_3d.cpp index 0564c4d452..02929eeaed 100644 --- a/servers/physics_3d/godot_body_3d.cpp +++ b/servers/physics_3d/godot_body_3d.cpp @@ -327,6 +327,8 @@ PhysicsServer3D::BodyMode GodotBody3D::get_mode() const { void GodotBody3D::_shapes_changed() { _mass_properties_changed(); + wakeup(); + wakeup_neighbours(); } void GodotBody3D::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) { diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp index 34b56e733e..79a2e0b0ea 100644 --- a/servers/physics_3d/godot_physics_server_3d.cpp +++ b/servers/physics_3d/godot_physics_server_3d.cpp @@ -584,7 +584,6 @@ void GodotPhysicsServer3D::body_set_collision_layer(RID p_body, uint32_t p_layer ERR_FAIL_COND(!body); body->set_collision_layer(p_layer); - body->wakeup(); } uint32_t GodotPhysicsServer3D::body_get_collision_layer(RID p_body) const { @@ -599,7 +598,6 @@ void GodotPhysicsServer3D::body_set_collision_mask(RID p_body, uint32_t p_mask) ERR_FAIL_COND(!body); body->set_collision_mask(p_mask); - body->wakeup(); } uint32_t GodotPhysicsServer3D::body_get_collision_mask(RID p_body) const { diff --git a/servers/physics_3d/godot_soft_body_3d.cpp b/servers/physics_3d/godot_soft_body_3d.cpp index d15235d27c..f214e3603a 100644 --- a/servers/physics_3d/godot_soft_body_3d.cpp +++ b/servers/physics_3d/godot_soft_body_3d.cpp @@ -139,6 +139,7 @@ void GodotSoftBody3D::set_mesh(RID p_mesh) { } Array arrays = RenderingServer::get_singleton()->mesh_surface_get_arrays(soft_mesh, 0); + ERR_FAIL_COND(arrays.is_empty()); bool success = create_from_trimesh(arrays[RenderingServer::ARRAY_INDEX], arrays[RenderingServer::ARRAY_VERTEX]); if (!success) { diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index a1c3481ed6..d05cfdc386 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -657,6 +657,10 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n"; } + actions.custom_samplers["SCREEN_TEXTURE"] = "material_samplers[3]"; // linear filter with mipmaps + actions.custom_samplers["DEPTH_TEXTURE"] = "material_samplers[3]"; + actions.custom_samplers["NORMAL_ROUGHNESS_TEXTURE"] = "material_samplers[1]"; // linear filter + actions.render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; actions.render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; actions.render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 9c38bf7606..53f2d96f52 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -2763,6 +2763,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI bool is_const = false; ConstantNode::Value value; + value.sint = -1; _find_identifier(p_block, false, p_function_info, vn->name, nullptr, nullptr, &is_const, nullptr, nullptr, &value); if (!is_const || value.sint < min || value.sint > max) { |