From 6aebc9129820c0f080ff1626ff60507bf63de6a5 Mon Sep 17 00:00:00 2001 From: kobewi Date: Sat, 2 Dec 2023 18:29:23 +0100 Subject: [PATCH 01/86] Flush delete queue after process frame timers --- scene/main/scene_tree.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index ced6d9aaa63..e11560456a7 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -492,11 +492,11 @@ bool SceneTree::physics_process(double p_time) { MessageQueue::get_singleton()->flush(); //small little hack process_timers(p_time, true); //go through timers - process_tweens(p_time, true); flush_transform_notifications(); + // This should happen last because any processing that deletes something beforehand might expect the object to be removed in the same frame. _flush_delete_queue(); _call_idle_callbacks(); @@ -529,17 +529,17 @@ bool SceneTree::process(double p_time) { MessageQueue::get_singleton()->flush(); //small little hack flush_transform_notifications(); //transforms after world update, to avoid unnecessary enter/exit notifications - _flush_delete_queue(); - if (unlikely(pending_new_scene)) { _flush_scene_change(); } process_timers(p_time, false); //go through timers - process_tweens(p_time, false); - flush_transform_notifications(); //additional transforms after timers update + flush_transform_notifications(); // Additional transforms after timers update. + + // This should happen last because any processing that deletes something beforehand might expect the object to be removed in the same frame. + _flush_delete_queue(); _call_idle_callbacks(); From 2e8c94181232b42c3b62140e1f9f3a81d425ac89 Mon Sep 17 00:00:00 2001 From: Lane Barnes Date: Sat, 23 Nov 2024 15:36:03 -0700 Subject: [PATCH 02/86] Fix example code snippet in AudioStreamGenerator.xml I was playing around with C# code snippet but I kept hearing a clipping sound. I think this is because the phase variable is being set to 0 in the wrong spot. The phase at the end of the FillBuffer() method is some non zero number. When FillBuffer is called again, the phase is suddenly changed back to zero. This causes the end of one sin wave segment to be out of sync with the next sin wave segment. The sin wave needs to be continuous between FillBuffer calls so no clipping sound occurs. Moving the phase variable out of FillBuffer and putting it in a scope above makes it retain its value between FillBuffer calls, making the sin wave continuous, and the clipping sound is gone. For further proof, the demo project "Audio Generator Demo" has the phase variable be one scope above FillBuffer and it does not set phase=0 inside of FillBuffer. If anything, I'm fixing this documentation to match the working demo --- doc/classes/AudioStreamGenerator.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/classes/AudioStreamGenerator.xml b/doc/classes/AudioStreamGenerator.xml index f618e69631e..6fce5a8af15 100644 --- a/doc/classes/AudioStreamGenerator.xml +++ b/doc/classes/AudioStreamGenerator.xml @@ -11,6 +11,7 @@ var playback # Will hold the AudioStreamGeneratorPlayback. @onready var sample_hz = $AudioStreamPlayer.stream.mix_rate var pulse_hz = 440.0 # The frequency of the sound wave. + var phase = 0.0 func _ready(): $AudioStreamPlayer.play() @@ -18,7 +19,6 @@ fill_buffer() func fill_buffer(): - var phase = 0.0 var increment = pulse_hz / sample_hz var frames_available = playback.get_frames_available() @@ -32,6 +32,7 @@ private AudioStreamGeneratorPlayback _playback; // Will hold the AudioStreamGeneratorPlayback. private float _sampleHz; private float _pulseHz = 440.0f; // The frequency of the sound wave. + private double phase = 0.0; public override void _Ready() { @@ -46,7 +47,6 @@ public void FillBuffer() { - double phase = 0.0; float increment = _pulseHz / _sampleHz; int framesAvailable = _playback.GetFramesAvailable(); From 8a544bf07c2755a2ab0eed8c4cb23ad835c9a13e Mon Sep 17 00:00:00 2001 From: Allen Pestaluky Date: Thu, 5 Dec 2024 15:15:35 -0500 Subject: [PATCH 03/86] Fix undo behavior on `EditorSettingsDialog::_update_builtin_action`. Fixes #100068. Co-authored-by: Tomek --- editor/editor_settings_dialog.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp index 8989b9cf9b9..2f7dfe16072 100644 --- a/editor/editor_settings_dialog.cpp +++ b/editor/editor_settings_dialog.cpp @@ -314,6 +314,10 @@ void EditorSettingsDialog::_event_config_confirmed() { void EditorSettingsDialog::_update_builtin_action(const String &p_name, const Array &p_events) { Array old_input_array = EditorSettings::get_singleton()->get_builtin_action_overrides(p_name); + if (old_input_array.is_empty()) { + List> defaults = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied()[current_edited_identifier]; + old_input_array = _event_list_to_array_helper(defaults); + } EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); undo_redo->create_action(vformat(TTR("Edit Built-in Action: %s"), p_name)); @@ -321,11 +325,11 @@ void EditorSettingsDialog::_update_builtin_action(const String &p_name, const Ar undo_redo->add_undo_method(EditorSettings::get_singleton(), "mark_setting_changed", "builtin_action_overrides"); undo_redo->add_do_method(EditorSettings::get_singleton(), "set_builtin_action_override", p_name, p_events); undo_redo->add_undo_method(EditorSettings::get_singleton(), "set_builtin_action_override", p_name, old_input_array); + undo_redo->add_do_method(this, "_update_shortcuts"); + undo_redo->add_undo_method(this, "_update_shortcuts"); undo_redo->add_do_method(this, "_settings_changed"); undo_redo->add_undo_method(this, "_settings_changed"); undo_redo->commit_action(); - - _update_shortcuts(); } void EditorSettingsDialog::_update_shortcut_events(const String &p_path, const Array &p_events) { From 636a132e45cc8799ef1a5208859ed7307f8c28f2 Mon Sep 17 00:00:00 2001 From: BlueCube3310 <53150244+BlueCube3310@users.noreply.github.com> Date: Mon, 23 Dec 2024 23:16:46 +0100 Subject: [PATCH 04/86] Compatibility: Avoid converting to compressed formats when retrieving image data --- drivers/gles3/storage/texture_storage.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index 0a864b56923..01869c26ac7 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -1072,7 +1072,7 @@ Ref TextureStorage::texture_2d_get(RID p_texture) const { // It also allows for reading compressed textures, mipmaps, and more formats. Vector data; - int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->real_format, texture->mipmaps > 1); + int64_t data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->real_format, texture->mipmaps > 1); data.resize(data_size * 2); // Add some memory at the end, just in case for buggy drivers. uint8_t *w = data.ptrw(); @@ -1084,7 +1084,7 @@ Ref TextureStorage::texture_2d_get(RID p_texture) const { glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); for (int i = 0; i < texture->mipmaps; i++) { - int ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, texture->real_format, i); + int64_t ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, texture->real_format, i); if (texture->compressed) { glPixelStorei(GL_PACK_ALIGNMENT, 4); @@ -1104,7 +1104,7 @@ Ref TextureStorage::texture_2d_get(RID p_texture) const { ERR_FAIL_V_MSG(Ref(), vformat("Texture %s has no data.", path_str)); } - if (texture->format != texture->real_format) { + if (texture->format != texture->real_format && !Image::is_format_compressed(texture->real_format)) { image->convert(texture->format); } } @@ -1114,7 +1114,7 @@ Ref TextureStorage::texture_2d_get(RID p_texture) const { Vector data; // On web and mobile we always read an RGBA8 image with no mipmaps. - int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false); + int64_t data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false); data.resize(data_size * 2); // Add some memory at the end, just in case for buggy drivers. uint8_t *w = data.ptrw(); @@ -1164,7 +1164,7 @@ Ref TextureStorage::texture_2d_get(RID p_texture) const { ERR_FAIL_V_MSG(Ref(), vformat("Texture %s has no data.", path_str)); } - if (texture->format != Image::FORMAT_RGBA8) { + if (texture->format != Image::FORMAT_RGBA8 && !Image::is_format_compressed(texture->format)) { image->convert(texture->format); } @@ -1189,7 +1189,7 @@ Ref TextureStorage::texture_2d_layer_get(RID p_texture, int p_layer) cons Vector data; - int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false); + int64_t data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false); data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers uint8_t *w = data.ptrw(); @@ -1239,7 +1239,7 @@ Ref TextureStorage::texture_2d_layer_get(RID p_texture, int p_layer) cons ERR_FAIL_V_MSG(Ref(), vformat("Texture %s has no data.", path_str)); } - if (texture->format != Image::FORMAT_RGBA8) { + if (texture->format != Image::FORMAT_RGBA8 && !Image::is_format_compressed(texture->format)) { image->convert(texture->format); } @@ -1261,7 +1261,7 @@ Vector> TextureStorage::_texture_3d_read_framebuffer(GLES3::Texture * int depth = p_texture->depth; for (int mipmap_level = 0; mipmap_level < p_texture->mipmaps; mipmap_level++) { - int data_size = Image::get_image_data_size(width, height, Image::FORMAT_RGBA8, false); + int64_t data_size = Image::get_image_data_size(width, height, Image::FORMAT_RGBA8, false); glViewport(0, 0, width, height); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); @@ -1280,7 +1280,7 @@ Vector> TextureStorage::_texture_3d_read_framebuffer(GLES3::Texture * Ref img = Image::create_from_data(width, height, false, Image::FORMAT_RGBA8, data); ERR_FAIL_COND_V(img->is_empty(), Vector>()); - if (p_texture->format != Image::FORMAT_RGBA8) { + if (p_texture->format != Image::FORMAT_RGBA8 && !Image::is_format_compressed(p_texture->format)) { img->convert(p_texture->format); } From df66ea74d7ab575b03ce48c358e9cdf89370dd31 Mon Sep 17 00:00:00 2001 From: Jan Haller Date: Mon, 30 Dec 2024 21:22:26 +0100 Subject: [PATCH 05/86] Fix `NodePath::slice()` incorrect behavior for subname indexing Adjust slice boundaries in `NodePath` logic to correctly handle subnames. Update test cases to reflect these changes. --- core/string/node_path.cpp | 2 +- tests/core/string/test_node_path.h | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp index b32bed5ee45..3ab8eb860de 100644 --- a/core/string/node_path.cpp +++ b/core/string/node_path.cpp @@ -255,7 +255,7 @@ NodePath NodePath::slice(int p_begin, int p_end) const { if (end < 0) { end += total_count; } - const int sub_begin = MAX(begin - name_count - 1, 0); + const int sub_begin = MAX(begin - name_count, 0); const int sub_end = MAX(end - name_count, 0); const Vector names = get_names().slice(begin, end); diff --git a/tests/core/string/test_node_path.h b/tests/core/string/test_node_path.h index bdbc578e850..3e7d4de4001 100644 --- a/tests/core/string/test_node_path.h +++ b/tests/core/string/test_node_path.h @@ -169,28 +169,31 @@ TEST_CASE("[NodePath] Empty path") { } TEST_CASE("[NodePath] Slice") { - const NodePath node_path_relative = NodePath("Parent/Child:prop"); + const NodePath node_path_relative = NodePath("Parent/Child:prop:subprop"); const NodePath node_path_absolute = NodePath("/root/Parent/Child:prop"); CHECK_MESSAGE( node_path_relative.slice(0, 2) == NodePath("Parent/Child"), "The slice lower bound should be inclusive and the slice upper bound should be exclusive."); CHECK_MESSAGE( - node_path_relative.slice(3) == NodePath(":prop"), - "Slicing on the length of the path should return the last entry."); + node_path_relative.slice(3) == NodePath(":subprop"), + "Slicing on the last index (length - 1) should return the last entry."); + CHECK_MESSAGE( + node_path_relative.slice(1) == NodePath("Child:prop:subprop"), + "Slicing without upper bound should return remaining entries after index."); CHECK_MESSAGE( node_path_relative.slice(1, 3) == NodePath("Child:prop"), "Slicing should include names and subnames."); CHECK_MESSAGE( - node_path_relative.slice(-1) == NodePath(":prop"), + node_path_relative.slice(-1) == NodePath(":subprop"), "Slicing on -1 should return the last entry."); CHECK_MESSAGE( - node_path_relative.slice(0, -1) == NodePath("Parent/Child"), + node_path_relative.slice(0, -1) == NodePath("Parent/Child:prop"), "Slicing up to -1 should include the second-to-last entry."); CHECK_MESSAGE( - node_path_relative.slice(-2, -1) == NodePath("Child"), + node_path_relative.slice(-2, -1) == NodePath(":prop"), "Slicing from negative to negative should treat lower bound as inclusive and upper bound as exclusive."); CHECK_MESSAGE( - node_path_relative.slice(0, 10) == NodePath("Parent/Child:prop"), + node_path_relative.slice(0, 10) == NodePath("Parent/Child:prop:subprop"), "Slicing past the length of the path should work like slicing up to the last entry."); CHECK_MESSAGE( node_path_relative.slice(-10, 2) == NodePath("Parent/Child"), From 176e5f42b26595256f62d88227261a197b76293e Mon Sep 17 00:00:00 2001 From: Kiro Date: Thu, 2 Jan 2025 09:02:43 +0100 Subject: [PATCH 06/86] add Static assert checks --- core/variant/variant.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index f092905a3ab..76657db78a9 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -2518,66 +2518,79 @@ Variant::Variant(const ObjectID &p_id) : Variant::Variant(const StringName &p_string) : type(STRING_NAME) { memnew_placement(_data._mem, StringName(p_string)); + static_assert(sizeof(StringName) <= sizeof(_data._mem)); } Variant::Variant(const String &p_string) : type(STRING) { memnew_placement(_data._mem, String(p_string)); + static_assert(sizeof(String) <= sizeof(_data._mem)); } Variant::Variant(const char *const p_cstring) : type(STRING) { memnew_placement(_data._mem, String((const char *)p_cstring)); + static_assert(sizeof(String) <= sizeof(_data._mem)); } Variant::Variant(const char32_t *p_wstring) : type(STRING) { memnew_placement(_data._mem, String(p_wstring)); + static_assert(sizeof(String) <= sizeof(_data._mem)); } Variant::Variant(const Vector3 &p_vector3) : type(VECTOR3) { memnew_placement(_data._mem, Vector3(p_vector3)); + static_assert(sizeof(Vector3) <= sizeof(_data._mem)); } Variant::Variant(const Vector3i &p_vector3i) : type(VECTOR3I) { memnew_placement(_data._mem, Vector3i(p_vector3i)); + static_assert(sizeof(Vector3i) <= sizeof(_data._mem)); } Variant::Variant(const Vector4 &p_vector4) : type(VECTOR4) { memnew_placement(_data._mem, Vector4(p_vector4)); + static_assert(sizeof(Vector4) <= sizeof(_data._mem)); } Variant::Variant(const Vector4i &p_vector4i) : type(VECTOR4I) { memnew_placement(_data._mem, Vector4i(p_vector4i)); + static_assert(sizeof(Vector4i) <= sizeof(_data._mem)); } Variant::Variant(const Vector2 &p_vector2) : type(VECTOR2) { memnew_placement(_data._mem, Vector2(p_vector2)); + static_assert(sizeof(Vector2) <= sizeof(_data._mem)); } Variant::Variant(const Vector2i &p_vector2i) : type(VECTOR2I) { memnew_placement(_data._mem, Vector2i(p_vector2i)); + static_assert(sizeof(Vector2i) <= sizeof(_data._mem)); } Variant::Variant(const Rect2 &p_rect2) : type(RECT2) { memnew_placement(_data._mem, Rect2(p_rect2)); + static_assert(sizeof(Rect2) <= sizeof(_data._mem)); } Variant::Variant(const Rect2i &p_rect2i) : type(RECT2I) { memnew_placement(_data._mem, Rect2i(p_rect2i)); + static_assert(sizeof(Rect2i) <= sizeof(_data._mem)); } Variant::Variant(const Plane &p_plane) : type(PLANE) { memnew_placement(_data._mem, Plane(p_plane)); + static_assert(sizeof(Plane) <= sizeof(_data._mem)); } Variant::Variant(const ::AABB &p_aabb) : @@ -2595,6 +2608,7 @@ Variant::Variant(const Basis &p_matrix) : Variant::Variant(const Quaternion &p_quaternion) : type(QUATERNION) { memnew_placement(_data._mem, Quaternion(p_quaternion)); + static_assert(sizeof(Quaternion) <= sizeof(_data._mem)); } Variant::Variant(const Transform3D &p_transform) : @@ -2618,16 +2632,19 @@ Variant::Variant(const Transform2D &p_transform) : Variant::Variant(const Color &p_color) : type(COLOR) { memnew_placement(_data._mem, Color(p_color)); + static_assert(sizeof(Color) <= sizeof(_data._mem)); } Variant::Variant(const NodePath &p_node_path) : type(NODE_PATH) { memnew_placement(_data._mem, NodePath(p_node_path)); + static_assert(sizeof(NodePath) <= sizeof(_data._mem)); } Variant::Variant(const ::RID &p_rid) : type(RID) { memnew_placement(_data._mem, ::RID(p_rid)); + static_assert(sizeof(::RID) <= sizeof(_data._mem)); } Variant::Variant(const Object *p_object) : @@ -2639,21 +2656,25 @@ Variant::Variant(const Object *p_object) : Variant::Variant(const Callable &p_callable) : type(CALLABLE) { memnew_placement(_data._mem, Callable(p_callable)); + static_assert(sizeof(Callable) <= sizeof(_data._mem)); } Variant::Variant(const Signal &p_callable) : type(SIGNAL) { memnew_placement(_data._mem, Signal(p_callable)); + static_assert(sizeof(Signal) <= sizeof(_data._mem)); } Variant::Variant(const Dictionary &p_dictionary) : type(DICTIONARY) { memnew_placement(_data._mem, Dictionary(p_dictionary)); + static_assert(sizeof(Dictionary) <= sizeof(_data._mem)); } Variant::Variant(const Array &p_array) : type(ARRAY) { memnew_placement(_data._mem, Array(p_array)); + static_assert(sizeof(Array) <= sizeof(_data._mem)); } Variant::Variant(const PackedByteArray &p_byte_array) : From b2d881a73a369e361482719fd4f7d8f1da602ad9 Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Thu, 2 Jan 2025 18:16:06 +0100 Subject: [PATCH 07/86] Optimize `_count` by replacing a full copy with a CoW copy for the full-string count case. --- core/string/ustring.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index be50b0b4e91..48d900d1969 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -3707,8 +3707,7 @@ int String::_count(const String &p_string, int p_from, int p_to, bool p_case_ins return 0; } if (p_from == 0 && p_to == len) { - str = String(); - str.copy_from_unchecked(&get_data()[0], len); + str = *this; } else { str = substr(p_from, p_to - p_from); } @@ -3744,8 +3743,7 @@ int String::_count(const char *p_string, int p_from, int p_to, bool p_case_insen return 0; } if (p_from == 0 && search_limit == source_length) { - str = String(); - str.copy_from_unchecked(&get_data()[0], source_length); + str = *this; } else { str = substr(p_from, search_limit - p_from); } From 96ce5c00014e2f52691ed7c308529dbd140d8f9c Mon Sep 17 00:00:00 2001 From: clayjohn Date: Fri, 3 Jan 2025 17:11:02 -0800 Subject: [PATCH 08/86] Ensure Sky with custom fov has correction matrix applied to it in RD renderers --- .../rendering/renderer_rd/environment/sky.cpp | 33 +++++++------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 6aa6f4d7ef6..1ffac1d687b 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -1187,6 +1187,17 @@ void SkyRD::setup_sky(const RenderDataRD *p_render_data, const Size2i p_screen_s projection[2].y = -projection[2].y; } + float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_render_data->environment); + + if (custom_fov && sky_scene_state.view_count == 1) { + // With custom fov we don't support stereo... + float near_plane = projection.get_z_near(); + float far_plane = projection.get_z_far(); + float aspect = projection.get_aspect(); + + projection.set_perspective(custom_fov, aspect, near_plane, far_plane); + } + sky_scene_state.cam_projection = correction * projection; // Our info in our UBO is only used if we're rendering stereo. @@ -1450,20 +1461,9 @@ void SkyRD::update_res_buffers(Ref p_render_buffers, RID p Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); - float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); - // Camera Projection projection = sky_scene_state.cam_projection; - if (custom_fov && sky_scene_state.view_count == 1) { - // With custom fov we don't support stereo... - float near_plane = projection.get_z_near(); - float far_plane = projection.get_z_far(); - float aspect = projection.get_aspect(); - - projection.set_perspective(custom_fov, aspect, near_plane, far_plane); - } - sky_transform = sky_transform * sky_scene_state.cam_transform.basis; if (shader_data->uses_quarter_res) { @@ -1551,20 +1551,9 @@ void SkyRD::draw_sky(RD::DrawListID p_draw_list, Ref p_ren Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); - float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); - // Camera Projection projection = sky_scene_state.cam_projection; - if (custom_fov && sky_scene_state.view_count == 1) { - // With custom fov we don't support stereo... - float near_plane = projection.get_z_near(); - float far_plane = projection.get_z_far(); - float aspect = projection.get_aspect(); - - projection.set_perspective(custom_fov, aspect, near_plane, far_plane); - } - sky_transform = sky_transform * sky_scene_state.cam_transform.basis; PipelineCacheRD *pipeline = &shader_data->pipelines[sky_scene_state.view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND]; From 32ef7306f4fe79430ee1325f9a92bff092d5dadf Mon Sep 17 00:00:00 2001 From: HP van Braam Date: Sat, 21 Dec 2024 21:45:06 +0100 Subject: [PATCH 09/86] Handle changing ItemLists from signals We make sure we don't touch the ItemList's items array after signals are emitted as a signal handler might change the item list, causing the index we had to be invalid. This fixes #100663 --- scene/gui/item_list.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index e114aa0452a..302bd0b8d63 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -746,7 +746,19 @@ void ItemList::gui_input(const Ref &p_event) { return; } - if (items[i].selectable && (!items[i].selected || allow_reselect) && select_mode != SELECT_TOGGLE) { + if (select_mode == SELECT_TOGGLE) { + if (items[i].selectable) { + if (items[i].selected) { + deselect(i); + current = i; + emit_signal(SNAME("multi_selected"), i, false); + } else { + select(i, false); + current = i; + emit_signal(SNAME("multi_selected"), i, true); + } + } + } else if (items[i].selectable && (!items[i].selected || allow_reselect)) { select(i, select_mode == SELECT_SINGLE || !mb->is_command_or_control_pressed()); if (select_mode == SELECT_SINGLE) { @@ -756,18 +768,6 @@ void ItemList::gui_input(const Ref &p_event) { } } - if (items[i].selectable && select_mode == SELECT_TOGGLE) { - if (items[i].selected) { - deselect(i); - current = i; - emit_signal(SNAME("multi_selected"), i, false); - } else { - select(i, false); - current = i; - emit_signal(SNAME("multi_selected"), i, true); - } - } - emit_signal(SNAME("item_clicked"), i, get_local_mouse_position(), mb->get_button_index()); if (mb->get_button_index() == MouseButton::LEFT && mb->is_double_click()) { From 84e6ac9ecdfdc280520cbb6c217c15447f1cbb6c Mon Sep 17 00:00:00 2001 From: BlueCube3310 <53150244+BlueCube3310@users.noreply.github.com> Date: Mon, 6 Jan 2025 12:31:22 +0100 Subject: [PATCH 10/86] Web: Export ASTC/BPTC compressed textures --- platform/web/doc_classes/EditorExportPlatformWeb.xml | 4 ++-- platform/web/export/export_plugin.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/web/doc_classes/EditorExportPlatformWeb.xml b/platform/web/doc_classes/EditorExportPlatformWeb.xml index 955e3a0232e..08632392beb 100644 --- a/platform/web/doc_classes/EditorExportPlatformWeb.xml +++ b/platform/web/doc_classes/EditorExportPlatformWeb.xml @@ -87,10 +87,10 @@ If [code]false[/code], the exported game will not support threads. As a result, it is more prone to performance and audio issues, but will only require to be run on an HTTPS website. - If [code]true[/code], allows textures to be optimized for desktop through the S3TC algorithm. + If [code]true[/code], allows textures to be optimized for desktop through the S3TC/BPTC algorithm. - If [code]true[/code] allows textures to be optimized for mobile through the ETC2 algorithm. + If [code]true[/code] allows textures to be optimized for mobile through the ETC2/ASTC algorithm. diff --git a/platform/web/export/export_plugin.cpp b/platform/web/export/export_plugin.cpp index 142a8deb86d..177493d5005 100644 --- a/platform/web/export/export_plugin.cpp +++ b/platform/web/export/export_plugin.cpp @@ -334,9 +334,11 @@ Error EditorExportPlatformWeb::_build_pwa(const Ref &p_prese void EditorExportPlatformWeb::get_preset_features(const Ref &p_preset, List *r_features) const { if (p_preset->get("vram_texture_compression/for_desktop")) { r_features->push_back("s3tc"); + r_features->push_back("bptc"); } if (p_preset->get("vram_texture_compression/for_mobile")) { r_features->push_back("etc2"); + r_features->push_back("astc"); } if (p_preset->get("variant/thread_support").operator bool()) { r_features->push_back("threads"); From f70acb03084a5b8b041b600acd79a576da3ce63d Mon Sep 17 00:00:00 2001 From: Kiro Date: Tue, 7 Jan 2025 13:40:17 +0100 Subject: [PATCH 11/86] shift the polygon heap only if index is in range --- modules/navigation/3d/nav_mesh_queries_3d.cpp | 2 +- modules/navigation/nav_utils.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/navigation/3d/nav_mesh_queries_3d.cpp b/modules/navigation/3d/nav_mesh_queries_3d.cpp index 7596ec84a6a..1e82de34f37 100644 --- a/modules/navigation/3d/nav_mesh_queries_3d.cpp +++ b/modules/navigation/3d/nav_mesh_queries_3d.cpp @@ -314,7 +314,7 @@ void NavMeshQueries3D::_query_task_build_path_corridor(NavMeshPathQueryTask3D &p owner->get_travel_cost(); neighbor_poly.entry = new_entry; - if (neighbor_poly.poly != nullptr) { + if (neighbor_poly.traversable_poly_index != traversable_polys.INVALID_INDEX) { traversable_polys.shift(neighbor_poly.traversable_poly_index); } else { neighbor_poly.poly = connection.polygon; diff --git a/modules/navigation/nav_utils.h b/modules/navigation/nav_utils.h index 6aa208f1d33..a068689704a 100644 --- a/modules/navigation/nav_utils.h +++ b/modules/navigation/nav_utils.h @@ -201,6 +201,7 @@ class Heap { Indexer _indexer; public: + static constexpr uint32_t INVALID_INDEX = UINT32_MAX; void reserve(uint32_t p_size) { _buffer.reserve(p_size); } @@ -222,7 +223,7 @@ class Heap { T pop() { ERR_FAIL_COND_V_MSG(_buffer.is_empty(), T(), "Can't pop an empty heap."); T value = _buffer[0]; - _indexer(value, UINT32_MAX); + _indexer(value, INVALID_INDEX); if (_buffer.size() > 1) { _buffer[0] = _buffer[_buffer.size() - 1]; _indexer(_buffer[0], 0); @@ -246,7 +247,7 @@ class Heap { void clear() { for (const T &value : _buffer) { - _indexer(value, UINT32_MAX); + _indexer(value, INVALID_INDEX); } _buffer.clear(); } From 174a2b6593f87f61d192f23c1a5d1e16d37a4082 Mon Sep 17 00:00:00 2001 From: Mikael Hermansson Date: Tue, 7 Jan 2025 17:16:59 +0100 Subject: [PATCH 12/86] Fix debug contact count not being initialized when using Jolt Physics --- modules/jolt_physics/spaces/jolt_contact_listener_3d.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/jolt_physics/spaces/jolt_contact_listener_3d.h b/modules/jolt_physics/spaces/jolt_contact_listener_3d.h index 41b3c9ef3bb..e18a8a9bf1a 100644 --- a/modules/jolt_physics/spaces/jolt_contact_listener_3d.h +++ b/modules/jolt_physics/spaces/jolt_contact_listener_3d.h @@ -93,7 +93,7 @@ class JoltContactListener3D final #ifdef DEBUG_ENABLED PackedVector3Array debug_contacts; - std::atomic_int debug_contact_count; + std::atomic_int debug_contact_count = 0; #endif virtual void OnContactAdded(const JPH::Body &p_body1, const JPH::Body &p_body2, const JPH::ContactManifold &p_manifold, JPH::ContactSettings &p_settings) override; From 0fddf6a82423d67a93a6e2f2e5264fcc863b4322 Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Tue, 7 Jan 2025 17:24:21 +0100 Subject: [PATCH 13/86] Optimize calls of `utf8` in a few spots to avoid calling it more than once. --- drivers/unix/file_access_unix.cpp | 8 +++----- drivers/unix/file_access_unix_pipe.cpp | 8 +++++--- editor/export/editor_export_platform.cpp | 4 ++-- modules/mbedtls/crypto_mbedtls.cpp | 5 +++-- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 048d4252902..7fe88887191 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -311,18 +311,16 @@ bool FileAccessUnix::store_buffer(const uint8_t *p_src, uint64_t p_length) { } bool FileAccessUnix::file_exists(const String &p_path) { - int err; struct stat st = {}; - String filename = fix_path(p_path); + const CharString filename_utf8 = fix_path(p_path).utf8(); // Does the name exist at all? - err = stat(filename.utf8().get_data(), &st); - if (err) { + if (stat(filename_utf8.get_data(), &st)) { return false; } // See if we have access to the file - if (access(filename.utf8().get_data(), F_OK)) { + if (access(filename_utf8.get_data(), F_OK)) { return false; } diff --git a/drivers/unix/file_access_unix_pipe.cpp b/drivers/unix/file_access_unix_pipe.cpp index 325cca08158..775d3f7d867 100644 --- a/drivers/unix/file_access_unix_pipe.cpp +++ b/drivers/unix/file_access_unix_pipe.cpp @@ -67,10 +67,12 @@ Error FileAccessUnixPipe::open_internal(const String &p_path, int p_mode_flags) ERR_FAIL_COND_V_MSG(fd[0] >= 0 || fd[1] >= 0, ERR_ALREADY_IN_USE, "Pipe is already in use."); path = String("/tmp/") + p_path.replace("pipe://", "").replace("/", "_"); + const CharString path_utf8 = path.utf8(); + struct stat st = {}; - int err = stat(path.utf8().get_data(), &st); + int err = stat(path_utf8.get_data(), &st); if (err) { - if (mkfifo(path.utf8().get_data(), 0600) != 0) { + if (mkfifo(path_utf8.get_data(), 0600) != 0) { last_error = ERR_FILE_CANT_OPEN; return last_error; } @@ -79,7 +81,7 @@ Error FileAccessUnixPipe::open_internal(const String &p_path, int p_mode_flags) ERR_FAIL_COND_V_MSG(!S_ISFIFO(st.st_mode), ERR_ALREADY_IN_USE, "Pipe name is already used by file."); } - int f = ::open(path.utf8().get_data(), O_RDWR | O_CLOEXEC | O_NONBLOCK); + int f = ::open(path_utf8.get_data(), O_RDWR | O_CLOEXEC | O_NONBLOCK); if (f < 0) { switch (errno) { case ENOENT: { diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp index f5723ed6cb3..8abfd8d62de 100644 --- a/editor/export/editor_export_platform.cpp +++ b/editor/export/editor_export_platform.cpp @@ -1685,8 +1685,8 @@ void EditorExportPlatform::zip_folder_recursive(zipFile &p_zip, const String &p_ 0x0314, // "version made by", 0x03 - Unix, 0x14 - ZIP specification version 2.0, required to store Unix file permissions 1 << 11); // Bit 11 is the language encoding flag. When set, filename and comment fields must be encoded using UTF-8. - String target = da->read_link(f); - zipWriteInFileInZip(p_zip, target.utf8().get_data(), target.utf8().size()); + const CharString target_utf8 = da->read_link(f).utf8(); + zipWriteInFileInZip(p_zip, target_utf8.get_data(), target_utf8.size()); zipCloseFileInZip(p_zip); } else if (da->current_is_dir()) { zip_folder_recursive(p_zip, p_root_path, p_folder.path_join(f), p_pkg_name); diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp index f827a593fe2..3aa5fdd27ac 100644 --- a/modules/mbedtls/crypto_mbedtls.cpp +++ b/modules/mbedtls/crypto_mbedtls.cpp @@ -99,10 +99,11 @@ Error CryptoKeyMbedTLS::save(const String &p_path, bool p_public_only) { Error CryptoKeyMbedTLS::load_from_string(const String &p_string_key, bool p_public_only) { int ret = 0; + const CharString string_key_utf8 = p_string_key.utf8(); if (p_public_only) { - ret = mbedtls_pk_parse_public_key(&pkey, (unsigned char *)p_string_key.utf8().get_data(), p_string_key.utf8().size()); + ret = mbedtls_pk_parse_public_key(&pkey, (const unsigned char *)string_key_utf8.get_data(), string_key_utf8.size()); } else { - ret = _parse_key((unsigned char *)p_string_key.utf8().get_data(), p_string_key.utf8().size()); + ret = _parse_key((const unsigned char *)string_key_utf8.get_data(), string_key_utf8.size()); } ERR_FAIL_COND_V_MSG(ret, FAILED, "Error parsing key '" + itos(ret) + "'."); From 8d911b25542a76da1b81dfe8f0d464e39df2aed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:11:45 +0200 Subject: [PATCH 14/86] [Window] Expose `start_drag` and `start_resize` methods (for both native and embedded windows). --- doc/classes/Window.xml | 13 +++++ platform/linuxbsd/x11/display_server_x11.cpp | 8 +++ platform/windows/display_server_windows.cpp | 8 +++ scene/main/viewport.cpp | 41 ++++++++++++++++ scene/main/viewport.h | 3 ++ scene/main/window.cpp | 51 ++++++++++++++++++++ scene/main/window.h | 3 ++ 7 files changed, 127 insertions(+) diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index 193dbe6a107..90eba0bdea8 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -557,6 +557,19 @@ Makes the [Window] appear. This enables interactions with the [Window] and doesn't change any of its property other than visibility (unlike e.g. [method popup]). + + + + Starts an interactive drag operation on the window, using the current mouse position. Call this method when handling a mouse button being pressed to simulate a pressed event on the window's title bar. Using this method allows the window to participate in space switching, tiling, and other system features. + + + + + + + Starts an interactive resize operation on the window, using the current mouse position. Call this method when handling a mouse button being pressed to simulate a pressed event on the window's edge. + + diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 8a33e10cbe2..77f08095b1c 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -5496,6 +5496,10 @@ void DisplayServerX11::window_start_drag(WindowID p_window) { ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; + if (wd.embed_parent) { + return; // Embedded window. + } + XClientMessageEvent m; memset(&m, 0, sizeof(m)); @@ -5532,6 +5536,10 @@ void DisplayServerX11::window_start_resize(WindowResizeEdge p_edge, WindowID p_w ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; + if (wd.embed_parent) { + return; // Embedded window. + } + XClientMessageEvent m; memset(&m, 0, sizeof(m)); diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index c053408ed4c..0c331725bdc 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -3990,6 +3990,10 @@ void DisplayServerWindows::window_start_drag(WindowID p_window) { ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; + if (wd.parent_hwnd) { + return; // Embedded window. + } + ReleaseCapture(); POINT coords; @@ -4006,6 +4010,10 @@ void DisplayServerWindows::window_start_resize(WindowResizeEdge p_edge, WindowID ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; + if (wd.parent_hwnd) { + return; // Embedded window. + } + ReleaseCapture(); POINT coords; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 6a898bd5ca2..6043006786b 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2956,6 +2956,47 @@ bool Viewport::_sub_windows_forward_input(const Ref &p_event) { return true; } +void Viewport::_window_start_drag(Window *p_window) { + int index = _sub_window_find(p_window); + ERR_FAIL_COND(index == -1); + + SubWindow sw = gui.sub_windows.write[index]; + + if (gui.subwindow_focused != sw.window) { + // Refocus. + _sub_window_grab_focus(sw.window); + } + + gui.subwindow_drag = SUB_WINDOW_DRAG_MOVE; + gui.subwindow_drag_from = get_mouse_position(); + gui.subwindow_drag_pos = sw.window->get_position(); + gui.currently_dragged_subwindow = sw.window; + + _sub_window_update(sw.window); +} + +void Viewport::_window_start_resize(SubWindowResize p_edge, Window *p_window) { + int index = _sub_window_find(p_window); + ERR_FAIL_COND(index == -1); + + SubWindow sw = gui.sub_windows.write[index]; + Rect2i r = Rect2i(sw.window->get_position(), sw.window->get_size()); + + if (gui.subwindow_focused != sw.window) { + // Refocus. + _sub_window_grab_focus(sw.window); + } + + gui.subwindow_drag = SUB_WINDOW_DRAG_RESIZE; + gui.subwindow_resize_mode = p_edge; + gui.subwindow_resize_from_rect = r; + gui.subwindow_drag_from = get_mouse_position(); + gui.subwindow_drag_pos = sw.window->get_position(); + gui.currently_dragged_subwindow = sw.window; + + _sub_window_update(sw.window); +} + void Viewport::_update_mouse_over() { // Update gui.mouse_over and gui.subwindow_over in all Viewports. // Send necessary mouse_enter/mouse_exit signals and the MOUSE_ENTER/MOUSE_EXIT notifications for every Viewport in the SceneTree. diff --git a/scene/main/viewport.h b/scene/main/viewport.h index a6a6e8ed446..63bec5b01c3 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -488,6 +488,9 @@ class Viewport : public Node { void _process_dirty_canvas_parent_orders(); void _propagate_world_2d_changed(Node *p_node); + void _window_start_drag(Window *p_window); + void _window_start_resize(SubWindowResize p_edge, Window *p_window); + protected: bool _set_size(const Size2i &p_size, const Size2i &p_size_2d_override, bool p_allocated); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 0d374478927..3476cb4cdc5 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -1998,6 +1998,54 @@ bool Window::has_focus() const { return focused; } +void Window::start_drag() { + ERR_MAIN_THREAD_GUARD; + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + DisplayServer::get_singleton()->window_start_drag(window_id); + } else if (embedder) { + embedder->_window_start_drag(this); + } +} + +void Window::start_resize(DisplayServer::WindowResizeEdge p_edge) { + ERR_MAIN_THREAD_GUARD; + if (get_flag(FLAG_RESIZE_DISABLED)) { + return; + } + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + DisplayServer::get_singleton()->window_start_resize(p_edge, window_id); + } else if (embedder) { + switch (p_edge) { + case DisplayServer::WINDOW_EDGE_TOP_LEFT: { + embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_TOP_LEFT, this); + } break; + case DisplayServer::WINDOW_EDGE_TOP: { + embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_TOP, this); + } break; + case DisplayServer::WINDOW_EDGE_TOP_RIGHT: { + embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_TOP_RIGHT, this); + } break; + case DisplayServer::WINDOW_EDGE_LEFT: { + embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_LEFT, this); + } break; + case DisplayServer::WINDOW_EDGE_RIGHT: { + embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_RIGHT, this); + } break; + case DisplayServer::WINDOW_EDGE_BOTTOM_LEFT: { + embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_BOTTOM_LEFT, this); + } break; + case DisplayServer::WINDOW_EDGE_BOTTOM: { + embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_BOTTOM, this); + } break; + case DisplayServer::WINDOW_EDGE_BOTTOM_RIGHT: { + embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_BOTTOM_RIGHT, this); + } break; + default: + break; + } + } +} + Rect2i Window::get_usable_parent_rect() const { ERR_READ_THREAD_GUARD_V(Rect2i()); ERR_FAIL_COND_V(!is_inside_tree(), Rect2()); @@ -2888,6 +2936,9 @@ void Window::_bind_methods() { ClassDB::bind_method(D_METHOD("has_focus"), &Window::has_focus); ClassDB::bind_method(D_METHOD("grab_focus"), &Window::grab_focus); + ClassDB::bind_method(D_METHOD("start_drag"), &Window::start_drag); + ClassDB::bind_method(D_METHOD("start_resize", "edge"), &Window::start_resize); + ClassDB::bind_method(D_METHOD("set_ime_active", "active"), &Window::set_ime_active); ClassDB::bind_method(D_METHOD("set_ime_position", "position"), &Window::set_ime_position); diff --git a/scene/main/window.h b/scene/main/window.h index 86b1d7c71ac..ce5489e96b1 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -401,6 +401,9 @@ class Window : public Viewport { void grab_focus(); bool has_focus() const; + void start_drag(); + void start_resize(DisplayServer::WindowResizeEdge p_edge); + Rect2i get_usable_parent_rect() const; // Internationalization. From a705962d736d879801c289c21272661b24190266 Mon Sep 17 00:00:00 2001 From: kobewi Date: Fri, 3 Jan 2025 21:53:41 +0100 Subject: [PATCH 15/86] Simplify scene tabs option disabling --- editor/gui/editor_scene_tabs.cpp | 35 ++++++++++++++++---------------- editor/gui/editor_scene_tabs.h | 1 - 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/editor/gui/editor_scene_tabs.cpp b/editor/gui/editor_scene_tabs.cpp index 748903a2d46..91a7598bfba 100644 --- a/editor/gui/editor_scene_tabs.cpp +++ b/editor/gui/editor_scene_tabs.cpp @@ -164,6 +164,11 @@ void EditorSceneTabs::_reposition_active_tab(int p_to_index) { } void EditorSceneTabs::_update_context_menu() { +#define DISABLE_LAST_OPTION_IF(m_condition) \ + if (m_condition) { \ + scene_tabs_context_menu->set_item_disabled(-1, true); \ + } + scene_tabs_context_menu->clear(); scene_tabs_context_menu->reset_size(); @@ -173,12 +178,11 @@ void EditorSceneTabs::_update_context_menu() { scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/new_scene"), EditorNode::FILE_NEW_SCENE); if (tab_id >= 0) { scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_scene"), EditorNode::FILE_SAVE_SCENE); - _disable_menu_option_if(EditorNode::FILE_SAVE_SCENE, no_root_node); + DISABLE_LAST_OPTION_IF(no_root_node); scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_scene_as"), EditorNode::FILE_SAVE_AS_SCENE); - _disable_menu_option_if(EditorNode::FILE_SAVE_AS_SCENE, no_root_node); + DISABLE_LAST_OPTION_IF(no_root_node); } - scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_all_scenes"), EditorNode::FILE_SAVE_ALL_SCENES); bool can_save_all_scenes = false; for (int i = 0; i < EditorNode::get_editor_data().get_edited_scene_count(); i++) { if (!EditorNode::get_editor_data().get_scene_path(i).is_empty() && EditorNode::get_editor_data().get_edited_scene_root(i)) { @@ -186,25 +190,26 @@ void EditorSceneTabs::_update_context_menu() { break; } } - _disable_menu_option_if(EditorNode::FILE_SAVE_ALL_SCENES, !can_save_all_scenes); + scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_all_scenes"), EditorNode::FILE_SAVE_ALL_SCENES); + DISABLE_LAST_OPTION_IF(!can_save_all_scenes); if (tab_id >= 0) { scene_tabs_context_menu->add_separator(); scene_tabs_context_menu->add_item(TTR("Show in FileSystem"), EditorNode::FILE_SHOW_IN_FILESYSTEM); - _disable_menu_option_if(EditorNode::FILE_SHOW_IN_FILESYSTEM, !ResourceLoader::exists(EditorNode::get_editor_data().get_scene_path(tab_id))); + DISABLE_LAST_OPTION_IF(!ResourceLoader::exists(EditorNode::get_editor_data().get_scene_path(tab_id))); scene_tabs_context_menu->add_item(TTR("Play This Scene"), EditorNode::FILE_RUN_SCENE); - _disable_menu_option_if(EditorNode::FILE_RUN_SCENE, no_root_node); + DISABLE_LAST_OPTION_IF(no_root_node); scene_tabs_context_menu->add_separator(); scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/close_scene"), EditorNode::FILE_CLOSE); - scene_tabs_context_menu->set_item_text(scene_tabs_context_menu->get_item_index(EditorNode::FILE_CLOSE), TTR("Close Tab")); + scene_tabs_context_menu->set_item_text(-1, TTR("Close Tab")); scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/reopen_closed_scene"), EditorNode::FILE_OPEN_PREV); - scene_tabs_context_menu->set_item_text(scene_tabs_context_menu->get_item_index(EditorNode::FILE_OPEN_PREV), TTR("Undo Close Tab")); - _disable_menu_option_if(EditorNode::FILE_OPEN_PREV, !EditorNode::get_singleton()->has_previous_scenes()); + scene_tabs_context_menu->set_item_text(-1, TTR("Undo Close Tab")); + DISABLE_LAST_OPTION_IF(!EditorNode::get_singleton()->has_previous_scenes()); scene_tabs_context_menu->add_item(TTR("Close Other Tabs"), EditorNode::FILE_CLOSE_OTHERS); - _disable_menu_option_if(EditorNode::FILE_CLOSE_OTHERS, EditorNode::get_editor_data().get_edited_scene_count() <= 1); + DISABLE_LAST_OPTION_IF(EditorNode::get_editor_data().get_edited_scene_count() <= 1); scene_tabs_context_menu->add_item(TTR("Close Tabs to the Right"), EditorNode::FILE_CLOSE_RIGHT); - _disable_menu_option_if(EditorNode::FILE_CLOSE_RIGHT, EditorNode::get_editor_data().get_edited_scene_count() == tab_id + 1); + DISABLE_LAST_OPTION_IF(EditorNode::get_editor_data().get_edited_scene_count() == tab_id + 1); scene_tabs_context_menu->add_item(TTR("Close All Tabs"), EditorNode::FILE_CLOSE_ALL); const PackedStringArray paths = { EditorNode::get_editor_data().get_scene_path(tab_id) }; @@ -212,13 +217,9 @@ void EditorSceneTabs::_update_context_menu() { } else { EditorContextMenuPluginManager::get_singleton()->add_options_from_plugins(scene_tabs_context_menu, EditorContextMenuPlugin::CONTEXT_SLOT_SCENE_TABS, {}); } - last_hovered_tab = tab_id; -} +#undef DISABLE_LAST_OPTION_IF -void EditorSceneTabs::_disable_menu_option_if(int p_option, bool p_condition) { - if (p_condition) { - scene_tabs_context_menu->set_item_disabled(scene_tabs_context_menu->get_item_index(p_option), true); - } + last_hovered_tab = tab_id; } void EditorSceneTabs::_custom_menu_option(int p_option) { diff --git a/editor/gui/editor_scene_tabs.h b/editor/gui/editor_scene_tabs.h index f9b94f34102..296c7fe548e 100644 --- a/editor/gui/editor_scene_tabs.h +++ b/editor/gui/editor_scene_tabs.h @@ -70,7 +70,6 @@ class EditorSceneTabs : public MarginContainer { void _update_tab_titles(); void _reposition_active_tab(int p_to_index); void _update_context_menu(); - void _disable_menu_option_if(int p_option, bool p_condition); void _custom_menu_option(int p_option); void _tab_preview_done(const String &p_path, const Ref &p_preview, const Ref &p_small_preview, const Variant &p_udata); From 4f1c956f25272c01a7a586627506b8fdd1c4e931 Mon Sep 17 00:00:00 2001 From: Nazarii Date: Tue, 7 Jan 2025 23:11:50 +0200 Subject: [PATCH 16/86] Use AHashMap for SurfaceTool --- scene/resources/surface_tool.cpp | 41 +++++++++++++++----------------- scene/resources/surface_tool.h | 14 +++++++---- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index c230cf1b704..ce17cf8799a 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -30,6 +30,8 @@ #include "surface_tool.h" +#include "core/templates/a_hash_map.h" + #define EQ_VERTEX_DIST 0.00001 SurfaceTool::OptimizeVertexCacheFunc SurfaceTool::optimize_vertex_cache_func = nullptr; @@ -51,7 +53,7 @@ void SurfaceTool::strip_mesh_arrays(PackedVector3Array &r_vertices, PackedInt32A r_vertices.resize(new_vertex_count); remap_index_func((unsigned int *)r_indices.ptrw(), (unsigned int *)r_indices.ptr(), r_indices.size(), remap.ptr()); - HashMap found_triangles; + AHashMap found_triangles; int *idx_ptr = r_indices.ptrw(); int filtered_indices_count = 0; @@ -70,7 +72,7 @@ void SurfaceTool::strip_mesh_arrays(PackedVector3Array &r_vertices, PackedInt32A memcpy(idx_ptr + (filtered_indices_count * 3), tri, sizeof(int) * 3); } - found_triangles[tri] = true; + found_triangles.insert_new(tri, true); filtered_indices_count++; } r_indices.resize(filtered_indices_count * 3); @@ -135,18 +137,12 @@ bool SurfaceTool::Vertex::operator==(const Vertex &p_vertex) const { } uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) { - uint32_t h = hash_djb2_buffer((const uint8_t *)&p_vtx.vertex, sizeof(real_t) * 3); - h = hash_djb2_buffer((const uint8_t *)&p_vtx.normal, sizeof(real_t) * 3, h); - h = hash_djb2_buffer((const uint8_t *)&p_vtx.binormal, sizeof(real_t) * 3, h); - h = hash_djb2_buffer((const uint8_t *)&p_vtx.tangent, sizeof(real_t) * 3, h); - h = hash_djb2_buffer((const uint8_t *)&p_vtx.uv, sizeof(real_t) * 2, h); - h = hash_djb2_buffer((const uint8_t *)&p_vtx.uv2, sizeof(real_t) * 2, h); - h = hash_djb2_buffer((const uint8_t *)&p_vtx.color, sizeof(real_t) * 4, h); - h = hash_djb2_buffer((const uint8_t *)p_vtx.bones.ptr(), p_vtx.bones.size() * sizeof(int), h); + uint32_t h = hash_djb2_buffer((const uint8_t *)p_vtx.bones.ptr(), p_vtx.bones.size() * sizeof(int)); h = hash_djb2_buffer((const uint8_t *)p_vtx.weights.ptr(), p_vtx.weights.size() * sizeof(float), h); - h = hash_djb2_buffer((const uint8_t *)&p_vtx.custom[0], sizeof(Color) * RS::ARRAY_CUSTOM_COUNT, h); - h = hash_murmur3_one_32(p_vtx.smooth_group, h); - h = hash_fmix32(h); + + const int64_t length = (int64_t)&p_vtx.vertex - (int64_t)&p_vtx.smooth_group + sizeof(p_vtx.vertex); + const void *key = &p_vtx.smooth_group; + h = hash_murmur3_buffer(key, length, h); return h; } @@ -163,7 +159,7 @@ bool SurfaceTool::SmoothGroupVertex::operator==(const SmoothGroupVertex &p_verte } uint32_t SurfaceTool::SmoothGroupVertexHasher::hash(const SmoothGroupVertex &p_vtx) { - uint32_t h = hash_djb2_buffer((const uint8_t *)&p_vtx.vertex, sizeof(real_t) * 3); + uint32_t h = HashMapHasherDefault::hash(p_vtx.vertex); h = hash_murmur3_one_32(p_vtx.smooth_group, h); h = hash_fmix32(h); return h; @@ -755,17 +751,17 @@ void SurfaceTool::index() { return; //already indexed } - HashMap indices; - LocalVector old_vertex_array = vertex_array; - vertex_array.clear(); + AHashMap indices = vertex_array.size(); - for (const Vertex &vertex : old_vertex_array) { + uint32_t new_size = 0; + for (Vertex &vertex : vertex_array) { int *idxptr = indices.getptr(vertex); int idx; if (!idxptr) { idx = indices.size(); - vertex_array.push_back(vertex); - indices[vertex] = idx; + vertex_array[new_size] = vertex; + indices.insert_new(vertex_array[new_size], idx); + new_size++; } else { idx = *idxptr; } @@ -773,6 +769,7 @@ void SurfaceTool::index() { index_array.push_back(idx); } + vertex_array.resize(new_size); format |= Mesh::ARRAY_FORMAT_INDEX; } @@ -1197,7 +1194,7 @@ void SurfaceTool::generate_normals(bool p_flip) { ERR_FAIL_COND((vertex_array.size() % 3) != 0); - HashMap smooth_hash; + AHashMap smooth_hash = vertex_array.size(); for (uint32_t vi = 0; vi < vertex_array.size(); vi += 3) { Vertex *v = &vertex_array[vi]; @@ -1214,7 +1211,7 @@ void SurfaceTool::generate_normals(bool p_flip) { if (v[i].smooth_group != UINT32_MAX) { Vector3 *lv = smooth_hash.getptr(v[i]); if (!lv) { - smooth_hash.insert(v[i], normal); + smooth_hash.insert_new(v[i], normal); } else { (*lv) += normal; } diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index 68dc9e71987..a8f7e5c72cd 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -43,17 +43,23 @@ class SurfaceTool : public RefCounted { public: struct Vertex { - Vector3 vertex; + // Trivial data for which the hash is computed using hash_buffer. + // ---------------------------------------------------------------- + uint32_t smooth_group = 0; // Must be first. + Color color; - Vector3 normal; // normal, binormal, tangent + Vector3 normal; // normal, binormal, tangent. Vector3 binormal; Vector3 tangent; Vector2 uv; Vector2 uv2; + Color custom[RS::ARRAY_CUSTOM_COUNT]; + + Vector3 vertex; // Must be last. + // ---------------------------------------------------------------- + Vector bones; Vector weights; - Color custom[RS::ARRAY_CUSTOM_COUNT]; - uint32_t smooth_group = 0; bool operator==(const Vertex &p_vertex) const; From a29294fddc3d55c8c9e57332aff205e7630dcfe8 Mon Sep 17 00:00:00 2001 From: Thaddeus Crews Date: Tue, 7 Jan 2025 15:55:17 -0600 Subject: [PATCH 17/86] SCons: Refactor color output implementation --- SConstruct | 44 ++---- doc/tools/doc_status.py | 7 +- doc/tools/make_rst.py | 5 +- methods.py | 144 ++++-------------- misc/scripts/install_d3d12_sdk_windows.py | 2 +- misc/utility/color.py | 130 ++++++++++++++++ .../gdextension_build/SConstruct | 29 +--- .../gdextension_build/methods.py | 53 ++----- .../gdextension_build/SConstruct | 29 +--- .../gdextension_build/methods.py | 69 ++------- platform/windows/detect.py | 3 - 11 files changed, 211 insertions(+), 304 deletions(-) create mode 100644 misc/utility/color.py diff --git a/SConstruct b/SConstruct index 470830d8eb7..442daea6d97 100644 --- a/SConstruct +++ b/SConstruct @@ -5,12 +5,10 @@ EnsureSConsVersion(4, 0) EnsurePythonVersion(3, 8) # System -import atexit import glob import os import pickle import sys -import time from collections import OrderedDict from importlib.util import module_from_spec, spec_from_file_location from types import ModuleType @@ -52,13 +50,14 @@ _helper_module("platform_methods", "platform_methods.py") _helper_module("version", "version.py") _helper_module("core.core_builders", "core/core_builders.py") _helper_module("main.main_builders", "main/main_builders.py") +_helper_module("misc.utility.color", "misc/utility/color.py") # Local import gles3_builders import glsl_builders import methods import scu_builders -from methods import Ansi, print_error, print_info, print_warning +from misc.utility.color import STDERR_COLOR, print_error, print_info, print_warning from platform_methods import architecture_aliases, architectures, compatibility_platform_aliases if ARGUMENTS.get("target", "editor") == "editor": @@ -74,8 +73,6 @@ platform_doc_class_path = {} platform_exporters = [] platform_apis = [] -time_at_start = time.time() - for x in sorted(glob.glob("platform/*")): if not os.path.isdir(x) or not os.path.exists(x + "/detect.py"): continue @@ -702,6 +699,14 @@ if env["arch"] == "x86_32": else: env.Append(CCFLAGS=["-msse2"]) +# Explicitly specify colored output. +if methods.using_gcc(env): + env.AppendUnique(CCFLAGS=["-fdiagnostics-color" if STDERR_COLOR else "-fno-diagnostics-color"]) +elif methods.using_clang(env) or methods.using_emcc(env): + env.AppendUnique(CCFLAGS=["-fcolor-diagnostics" if STDERR_COLOR else "-fno-color-diagnostics"]) + if sys.platform == "win32": + env.AppendUnique(CCFLAGS=["-fansi-escape-codes"]) + # Set optimize and debug_symbols flags. # "custom" means do nothing and let users set their own optimization flags. # Needs to happen after configure to have `env.msvc` defined. @@ -1086,30 +1091,5 @@ methods.show_progress(env) # TODO: replace this with `env.Dump(format="json")` # once we start requiring SCons 4.0 as min version. methods.dump(env) - - -def print_elapsed_time(): - elapsed_time_sec = round(time.time() - time_at_start, 2) - time_centiseconds = round((elapsed_time_sec % 1) * 100) - print( - "{}[Time elapsed: {}.{:02}]{}".format( - Ansi.GRAY, - time.strftime("%H:%M:%S", time.gmtime(elapsed_time_sec)), - time_centiseconds, - Ansi.RESET, - ) - ) - - -atexit.register(print_elapsed_time) - - -def purge_flaky_files(): - paths_to_keep = [env["ninja_file"]] - for build_failure in GetBuildFailures(): - path = build_failure.node.path - if os.path.isfile(path) and path not in paths_to_keep: - os.remove(path) - - -atexit.register(purge_flaky_files) +methods.prepare_purge(env) +methods.prepare_timer() diff --git a/doc/tools/doc_status.py b/doc/tools/doc_status.py index dc52a38bddd..db2b19447b5 100755 --- a/doc/tools/doc_status.py +++ b/doc/tools/doc_status.py @@ -10,14 +10,14 @@ sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../")) -from methods import COLOR_SUPPORTED, Ansi, toggle_color +from misc.utility.color import STDOUT_COLOR, Ansi, toggle_color ################################################################################ # Config # ################################################################################ flags = { - "c": COLOR_SUPPORTED, + "c": STDOUT_COLOR, "b": False, "g": False, "s": False, @@ -330,7 +330,8 @@ def generate_for_class(c: ET.Element): table_column_names.append("Docs URL") table_columns.append("url") -toggle_color(flags["c"]) +if flags["c"]: + toggle_color(True) ################################################################################ # Help # diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py index a10b5d6e782..adb7500528b 100755 --- a/doc/tools/make_rst.py +++ b/doc/tools/make_rst.py @@ -13,7 +13,7 @@ sys.path.insert(0, root_directory := os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../")) import version -from methods import Ansi, toggle_color +from misc.utility.color import Ansi, toggle_color # $DOCS_URL/path/to/page.html(#fragment-tag) GODOT_DOCS_PATTERN = re.compile(r"^\$DOCS_URL/(.*)\.html(#.*)?$") @@ -697,7 +697,8 @@ def main() -> None: ) args = parser.parse_args() - toggle_color(args.color) + if args.color: + toggle_color(True) # Retrieve heading translations for the given language. if not args.dry_run and args.lang != "en": diff --git a/methods.py b/methods.py index 4351584c6b6..fee268609d7 100644 --- a/methods.py +++ b/methods.py @@ -7,125 +7,16 @@ import subprocess import sys from collections import OrderedDict -from enum import Enum from io import StringIO, TextIOWrapper from pathlib import Path -from typing import Final, Generator, List, Optional, Union, cast +from typing import Generator, List, Optional, Union, cast + +from misc.utility.color import print_error, print_info, print_warning # Get the "Godot" folder name ahead of time base_folder_path = str(os.path.abspath(Path(__file__).parent)) + "/" base_folder_only = os.path.basename(os.path.normpath(base_folder_path)) -################################################################################ -# COLORIZE -################################################################################ - -IS_CI: Final[bool] = bool(os.environ.get("CI")) -IS_TTY: Final[bool] = bool(sys.stdout.isatty()) - - -def _color_supported() -> bool: - """ - Enables ANSI escape code support on Windows 10 and later (for colored console output). - See here: https://github.com/python/cpython/issues/73245 - """ - if sys.platform == "win32" and IS_TTY: - try: - from ctypes import WinError, byref, windll # type: ignore - from ctypes.wintypes import DWORD # type: ignore - - stdout_handle = windll.kernel32.GetStdHandle(DWORD(-11)) - mode = DWORD(0) - if not windll.kernel32.GetConsoleMode(stdout_handle, byref(mode)): - raise WinError() - mode = DWORD(mode.value | 4) - if not windll.kernel32.SetConsoleMode(stdout_handle, mode): - raise WinError() - except (TypeError, OSError) as e: - print(f"Failed to enable ANSI escape code support, disabling color output.\n{e}", file=sys.stderr) - return False - - return IS_TTY or IS_CI - - -# Colors are disabled in non-TTY environments such as pipes. This means -# that if output is redirected to a file, it won't contain color codes. -# Colors are always enabled on continuous integration. -COLOR_SUPPORTED: Final[bool] = _color_supported() -_can_color: bool = COLOR_SUPPORTED - - -def toggle_color(value: Optional[bool] = None) -> None: - """ - Explicitly toggle color codes, regardless of support. - - - `value`: An optional boolean to explicitly set the color - state instead of toggling. - """ - global _can_color - _can_color = value if value is not None else not _can_color - - -class Ansi(Enum): - """ - Enum class for adding ansi colorcodes directly into strings. - Automatically converts values to strings representing their - internal value, or an empty string in a non-colorized scope. - """ - - RESET = "\x1b[0m" - - BOLD = "\x1b[1m" - DIM = "\x1b[2m" - ITALIC = "\x1b[3m" - UNDERLINE = "\x1b[4m" - STRIKETHROUGH = "\x1b[9m" - REGULAR = "\x1b[22;23;24;29m" - - BLACK = "\x1b[30m" - RED = "\x1b[31m" - GREEN = "\x1b[32m" - YELLOW = "\x1b[33m" - BLUE = "\x1b[34m" - MAGENTA = "\x1b[35m" - CYAN = "\x1b[36m" - WHITE = "\x1b[37m" - - LIGHT_BLACK = "\x1b[90m" - LIGHT_RED = "\x1b[91m" - LIGHT_GREEN = "\x1b[92m" - LIGHT_YELLOW = "\x1b[93m" - LIGHT_BLUE = "\x1b[94m" - LIGHT_MAGENTA = "\x1b[95m" - LIGHT_CYAN = "\x1b[96m" - LIGHT_WHITE = "\x1b[97m" - - GRAY = LIGHT_BLACK if IS_CI else BLACK - """ - Special case. GitHub Actions doesn't convert `BLACK` to gray as expected, but does convert `LIGHT_BLACK`. - By implementing `GRAY`, we handle both cases dynamically, while still allowing for explicit values if desired. - """ - - def __str__(self) -> str: - global _can_color - return str(self.value) if _can_color else "" - - -def print_info(*values: object) -> None: - """Prints a informational message with formatting.""" - print(f"{Ansi.GRAY}{Ansi.BOLD}INFO:{Ansi.REGULAR}", *values, Ansi.RESET) - - -def print_warning(*values: object) -> None: - """Prints a warning message with formatting.""" - print(f"{Ansi.YELLOW}{Ansi.BOLD}WARNING:{Ansi.REGULAR}", *values, Ansi.RESET, file=sys.stderr) - - -def print_error(*values: object) -> None: - """Prints an error message with formatting.""" - print(f"{Ansi.RED}{Ansi.BOLD}ERROR:{Ansi.REGULAR}", *values, Ansi.RESET, file=sys.stderr) - - # Listing all the folders we have converted # for SCU in scu_builders.py _scu_folders = set() @@ -505,6 +396,8 @@ def mySpawn(sh, escape, cmd, args, env): def no_verbose(env): + from misc.utility.color import Ansi + colors = [Ansi.BLUE, Ansi.BOLD, Ansi.REGULAR, Ansi.RESET] # There is a space before "..." to ensure that source file names can be @@ -875,7 +768,7 @@ def __init__(self): # Progress reporting is not available in non-TTY environments since it # messes with the output (for example, when writing to a file). - self.display = cast(bool, self.max and env["progress"] and IS_TTY) + self.display = cast(bool, self.max and env["progress"] and sys.stdout.isatty()) if self.display and not self.max: print_info("Performing initial build, progress percentage unavailable!") @@ -1019,6 +912,31 @@ def prepare_cache(env) -> None: atexit.register(clean_cache, cache_path, cache_limit, env["verbose"]) +def prepare_purge(env): + from SCons.Script.Main import GetBuildFailures + + def purge_flaky_files(): + paths_to_keep = [env["ninja_file"]] + for build_failure in GetBuildFailures(): + path = build_failure.node.path + if os.path.isfile(path) and path not in paths_to_keep: + os.remove(path) + + atexit.register(purge_flaky_files) + + +def prepare_timer(): + import time + + def print_elapsed_time(time_at_start: float): + time_elapsed = time.time() - time_at_start + time_formatted = time.strftime("%H:%M:%S", time.gmtime(time_elapsed)) + time_centiseconds = round((time_elapsed % 1) * 100) + print_info(f"Time elapsed: {time_formatted}.{time_centiseconds}") + + atexit.register(print_elapsed_time, time.time()) + + def dump(env): # Dumps latest build information for debugging purposes and external tools. from json import dump diff --git a/misc/scripts/install_d3d12_sdk_windows.py b/misc/scripts/install_d3d12_sdk_windows.py index fa9ce780513..26e5181d9a0 100644 --- a/misc/scripts/install_d3d12_sdk_windows.py +++ b/misc/scripts/install_d3d12_sdk_windows.py @@ -8,7 +8,7 @@ sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../")) -from methods import Ansi +from misc.utility.color import Ansi # Base Godot dependencies path # If cross-compiling (no LOCALAPPDATA), we install in `bin` diff --git a/misc/utility/color.py b/misc/utility/color.py new file mode 100644 index 00000000000..ae392dd8470 --- /dev/null +++ b/misc/utility/color.py @@ -0,0 +1,130 @@ +from __future__ import annotations + +import os +import sys +from enum import Enum +from typing import Final + +# Colors are disabled in non-TTY environments such as pipes. This means if output is redirected +# to a file, it won't contain color codes. Colors are always enabled on continuous integration. + +IS_CI: Final[bool] = bool(os.environ.get("CI")) +STDOUT_TTY: Final[bool] = bool(sys.stdout.isatty()) +STDERR_TTY: Final[bool] = bool(sys.stderr.isatty()) + + +def _color_supported(stdout: bool) -> bool: + """ + Validates if the current environment supports colored output. Attempts to enable ANSI escape + code support on Windows 10 and later. + """ + if IS_CI: + return True + + if sys.platform != "win32": + return STDOUT_TTY if stdout else STDERR_TTY + else: + from ctypes import POINTER, WINFUNCTYPE, WinError, windll + from ctypes.wintypes import BOOL, DWORD, HANDLE + + STD_HANDLE = -11 if stdout else -12 + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4 + + def err_handler(result, func, args): + if not result: + raise WinError() + return args + + GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(("GetStdHandle", windll.kernel32), ((1, "nStdHandle"),)) + GetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))( + ("GetConsoleMode", windll.kernel32), + ((1, "hConsoleHandle"), (2, "lpMode")), + ) + GetConsoleMode.errcheck = err_handler + SetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, DWORD)( + ("SetConsoleMode", windll.kernel32), + ((1, "hConsoleHandle"), (1, "dwMode")), + ) + SetConsoleMode.errcheck = err_handler + + try: + handle = GetStdHandle(STD_HANDLE) + flags = GetConsoleMode(handle) + SetConsoleMode(handle, flags | ENABLE_VIRTUAL_TERMINAL_PROCESSING) + return True + except OSError: + return False + + +STDOUT_COLOR: Final[bool] = _color_supported(True) +STDERR_COLOR: Final[bool] = _color_supported(False) +_stdout_override: bool = STDOUT_COLOR +_stderr_override: bool = STDERR_COLOR + + +def toggle_color(stdout: bool, value: bool | None = None) -> None: + """ + Explicitly toggle color codes, regardless of support. + + - `stdout`: A boolean to choose the output stream. `True` for stdout, `False` for stderr. + - `value`: An optional boolean to explicitly set the color state instead of toggling. + """ + if stdout: + global _stdout_override + _stdout_override = value if value is not None else not _stdout_override + else: + global _stderr_override + _stderr_override = value if value is not None else not _stderr_override + + +class Ansi(Enum): + """ + Enum class for adding ansi codepoints directly into strings. Automatically converts values to + strings representing their internal value. + """ + + RESET = "\x1b[0m" + + BOLD = "\x1b[1m" + DIM = "\x1b[2m" + ITALIC = "\x1b[3m" + UNDERLINE = "\x1b[4m" + STRIKETHROUGH = "\x1b[9m" + REGULAR = "\x1b[22;23;24;29m" + + BLACK = "\x1b[30m" + RED = "\x1b[31m" + GREEN = "\x1b[32m" + YELLOW = "\x1b[33m" + BLUE = "\x1b[34m" + MAGENTA = "\x1b[35m" + CYAN = "\x1b[36m" + WHITE = "\x1b[37m" + GRAY = "\x1b[90m" + + def __str__(self) -> str: + return self.value + + +def print_info(*values: object) -> None: + """Prints a informational message with formatting.""" + if _stdout_override: + print(f"{Ansi.GRAY}{Ansi.BOLD}INFO:{Ansi.REGULAR}", *values, Ansi.RESET) + else: + print(*values) + + +def print_warning(*values: object) -> None: + """Prints a warning message with formatting.""" + if _stderr_override: + print(f"{Ansi.YELLOW}{Ansi.BOLD}WARNING:{Ansi.REGULAR}", *values, Ansi.RESET, file=sys.stderr) + else: + print(*values, file=sys.stderr) + + +def print_error(*values: object) -> None: + """Prints an error message with formatting.""" + if _stderr_override: + print(f"{Ansi.RED}{Ansi.BOLD}ERROR:{Ansi.REGULAR}", *values, Ansi.RESET, file=sys.stderr) + else: + print(*values, file=sys.stderr) diff --git a/modules/text_server_adv/gdextension_build/SConstruct b/modules/text_server_adv/gdextension_build/SConstruct index 51caa4e6e55..39573aebde5 100644 --- a/modules/text_server_adv/gdextension_build/SConstruct +++ b/modules/text_server_adv/gdextension_build/SConstruct @@ -1,14 +1,8 @@ #!/usr/bin/env python - -import atexit -import time -from typing import TYPE_CHECKING +# ruff: noqa: F821 import methods -if TYPE_CHECKING: - from misc.utility.scons_hints import * - # For the reference: # - CCFLAGS are compilation flags shared between C and C++ # - CFLAGS are for C-specific compilation flags @@ -17,8 +11,6 @@ if TYPE_CHECKING: # - CPPDEFINES are for pre-processor defines # - LINKFLAGS are for linking flags -time_at_start = time.time() - env = SConscript("./godot-cpp/SConstruct") env.__class__.disable_warnings = methods.disable_warnings @@ -33,9 +25,6 @@ opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", Fa opts.Update(env) -if not env["verbose"]: - methods.no_verbose(env) - if env["platform"] == "windows" and not env["use_mingw"]: env.AppendUnique(CCFLAGS=["/utf-8"]) # Force to use Unicode encoding. @@ -767,18 +756,4 @@ else: Default(library) - -def print_elapsed_time(): - elapsed_time_sec = round(time.time() - time_at_start, 2) - time_centiseconds = round((elapsed_time_sec % 1) * 100) - print( - "{}[Time elapsed: {}.{:02}]{}".format( - methods.Ansi.GRAY, - time.strftime("%H:%M:%S", time.gmtime(elapsed_time_sec)), - time_centiseconds, - methods.Ansi.RESET, - ) - ) - - -atexit.register(print_elapsed_time) +methods.prepare_timer() diff --git a/modules/text_server_adv/gdextension_build/methods.py b/modules/text_server_adv/gdextension_build/methods.py index d029e428558..c12b8c8a397 100644 --- a/modules/text_server_adv/gdextension_build/methods.py +++ b/modules/text_server_adv/gdextension_build/methods.py @@ -1,41 +1,3 @@ -import os -import sys - -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../../")) - -from methods import Ansi - - -def no_verbose(env): - colors = [Ansi.BLUE, Ansi.BOLD, Ansi.REGULAR, Ansi.RESET] - - # There is a space before "..." to ensure that source file names can be - # Ctrl + clicked in the VS Code terminal. - compile_source_message = "{}Compiling {}$SOURCE{} ...{}".format(*colors) - java_compile_source_message = "{}Compiling {}$SOURCE{} ...{}".format(*colors) - compile_shared_source_message = "{}Compiling shared {}$SOURCE{} ...{}".format(*colors) - link_program_message = "{}Linking Program {}$TARGET{} ...{}".format(*colors) - link_library_message = "{}Linking Static Library {}$TARGET{} ...{}".format(*colors) - ranlib_library_message = "{}Ranlib Library {}$TARGET{} ...{}".format(*colors) - link_shared_library_message = "{}Linking Shared Library {}$TARGET{} ...{}".format(*colors) - java_library_message = "{}Creating Java Archive {}$TARGET{} ...{}".format(*colors) - compiled_resource_message = "{}Creating Compiled Resource {}$TARGET{} ...{}".format(*colors) - generated_file_message = "{}Generating {}$TARGET{} ...{}".format(*colors) - - env["CXXCOMSTR"] = compile_source_message - env["CCCOMSTR"] = compile_source_message - env["SHCCCOMSTR"] = compile_shared_source_message - env["SHCXXCOMSTR"] = compile_shared_source_message - env["ARCOMSTR"] = link_library_message - env["RANLIBCOMSTR"] = ranlib_library_message - env["SHLINKCOMSTR"] = link_shared_library_message - env["LINKCOMSTR"] = link_program_message - env["JARCOMSTR"] = java_library_message - env["JAVACCOMSTR"] = java_compile_source_message - env["RCCOMSTR"] = compiled_resource_message - env["GENCOMSTR"] = generated_file_message - - def disable_warnings(self): # 'self' is the environment if self["platform"] == "windows" and not self["use_mingw"]: @@ -50,6 +12,19 @@ def disable_warnings(self): self.AppendUnique(CCFLAGS=["-w"]) +def prepare_timer(): + import atexit + import time + + def print_elapsed_time(time_at_start: float): + time_elapsed = time.time() - time_at_start + time_formatted = time.strftime("%H:%M:%S", time.gmtime(time_elapsed)) + time_centiseconds = round((time_elapsed % 1) * 100) + print(f"[Time elapsed: {time_formatted}.{time_centiseconds}]") + + atexit.register(print_elapsed_time, time.time()) + + def make_icu_data(target, source, env): dst = target[0].srcnode().abspath with open(dst, "w", encoding="utf-8", newline="\n") as g: @@ -75,6 +50,8 @@ def make_icu_data(target, source, env): def write_macos_plist(target, binary_name, identifier, name): + import os + os.makedirs(f"{target}/Resource/", exist_ok=True) with open(f"{target}/Resource/Info.plist", "w", encoding="utf-8", newline="\n") as f: f.write(f"""\ diff --git a/modules/text_server_fb/gdextension_build/SConstruct b/modules/text_server_fb/gdextension_build/SConstruct index 72606760dff..ac1dc6d4e4a 100644 --- a/modules/text_server_fb/gdextension_build/SConstruct +++ b/modules/text_server_fb/gdextension_build/SConstruct @@ -1,14 +1,8 @@ #!/usr/bin/env python - -import atexit -import time -from typing import TYPE_CHECKING +# ruff: noqa: F821 import methods -if TYPE_CHECKING: - from misc.utility.scons_hints import * - # For the reference: # - CCFLAGS are compilation flags shared between C and C++ # - CFLAGS are for C-specific compilation flags @@ -17,8 +11,6 @@ if TYPE_CHECKING: # - CPPDEFINES are for pre-processor defines # - LINKFLAGS are for linking flags -time_at_start = time.time() - env = SConscript("./godot-cpp/SConstruct") env.__class__.disable_warnings = methods.disable_warnings @@ -31,9 +23,6 @@ opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", Fa opts.Update(env) -if not env["verbose"]: - methods.no_verbose(env) - # ThorVG if env["thorvg_enabled"] and env["freetype_enabled"]: env_tvg = env.Clone() @@ -313,18 +302,4 @@ else: Default(library) - -def print_elapsed_time(): - elapsed_time_sec = round(time.time() - time_at_start, 2) - time_centiseconds = round((elapsed_time_sec % 1) * 100) - print( - "{}[Time elapsed: {}.{:02}]{}".format( - methods.Ansi.GRAY, - time.strftime("%H:%M:%S", time.gmtime(elapsed_time_sec)), - time_centiseconds, - methods.Ansi.RESET, - ) - ) - - -atexit.register(print_elapsed_time) +methods.prepare_timer() diff --git a/modules/text_server_fb/gdextension_build/methods.py b/modules/text_server_fb/gdextension_build/methods.py index d029e428558..f39c1c4689b 100644 --- a/modules/text_server_fb/gdextension_build/methods.py +++ b/modules/text_server_fb/gdextension_build/methods.py @@ -1,41 +1,3 @@ -import os -import sys - -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../../")) - -from methods import Ansi - - -def no_verbose(env): - colors = [Ansi.BLUE, Ansi.BOLD, Ansi.REGULAR, Ansi.RESET] - - # There is a space before "..." to ensure that source file names can be - # Ctrl + clicked in the VS Code terminal. - compile_source_message = "{}Compiling {}$SOURCE{} ...{}".format(*colors) - java_compile_source_message = "{}Compiling {}$SOURCE{} ...{}".format(*colors) - compile_shared_source_message = "{}Compiling shared {}$SOURCE{} ...{}".format(*colors) - link_program_message = "{}Linking Program {}$TARGET{} ...{}".format(*colors) - link_library_message = "{}Linking Static Library {}$TARGET{} ...{}".format(*colors) - ranlib_library_message = "{}Ranlib Library {}$TARGET{} ...{}".format(*colors) - link_shared_library_message = "{}Linking Shared Library {}$TARGET{} ...{}".format(*colors) - java_library_message = "{}Creating Java Archive {}$TARGET{} ...{}".format(*colors) - compiled_resource_message = "{}Creating Compiled Resource {}$TARGET{} ...{}".format(*colors) - generated_file_message = "{}Generating {}$TARGET{} ...{}".format(*colors) - - env["CXXCOMSTR"] = compile_source_message - env["CCCOMSTR"] = compile_source_message - env["SHCCCOMSTR"] = compile_shared_source_message - env["SHCXXCOMSTR"] = compile_shared_source_message - env["ARCOMSTR"] = link_library_message - env["RANLIBCOMSTR"] = ranlib_library_message - env["SHLINKCOMSTR"] = link_shared_library_message - env["LINKCOMSTR"] = link_program_message - env["JARCOMSTR"] = java_library_message - env["JAVACCOMSTR"] = java_compile_source_message - env["RCCOMSTR"] = compiled_resource_message - env["GENCOMSTR"] = generated_file_message - - def disable_warnings(self): # 'self' is the environment if self["platform"] == "windows" and not self["use_mingw"]: @@ -50,31 +12,22 @@ def disable_warnings(self): self.AppendUnique(CCFLAGS=["-w"]) -def make_icu_data(target, source, env): - dst = target[0].srcnode().abspath - with open(dst, "w", encoding="utf-8", newline="\n") as g: - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("/* (C) 2016 and later: Unicode, Inc. and others. */\n") - g.write("/* License & terms of use: https://www.unicode.org/copyright.html */\n") - g.write("#ifndef _ICU_DATA_H\n") - g.write("#define _ICU_DATA_H\n") - g.write('#include "unicode/utypes.h"\n') - g.write('#include "unicode/udata.h"\n') - g.write('#include "unicode/uversion.h"\n') +def prepare_timer(): + import atexit + import time - with open(source[0].srcnode().abspath, "rb") as f: - buf = f.read() + def print_elapsed_time(time_at_start: float): + time_elapsed = time.time() - time_at_start + time_formatted = time.strftime("%H:%M:%S", time.gmtime(time_elapsed)) + time_centiseconds = round((time_elapsed % 1) * 100) + print(f"[Time elapsed: {time_formatted}.{time_centiseconds}]") - g.write('extern "C" U_EXPORT const size_t U_ICUDATA_SIZE = ' + str(len(buf)) + ";\n") - g.write('extern "C" U_EXPORT const unsigned char U_ICUDATA_ENTRY_POINT[] = {\n') - for i in range(len(buf)): - g.write("\t" + str(buf[i]) + ",\n") - - g.write("};\n") - g.write("#endif") + atexit.register(print_elapsed_time, time.time()) def write_macos_plist(target, binary_name, identifier, name): + import os + os.makedirs(f"{target}/Resource/", exist_ok=True) with open(f"{target}/Resource/Info.plist", "w", encoding="utf-8", newline="\n") as f: f.write(f"""\ diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 8e567a2cd60..5893858dd9e 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -812,9 +812,6 @@ def configure_mingw(env: "SConsEnvironment"): env.Append(CCFLAGS=san_flags) env.Append(LINKFLAGS=san_flags) - if env["use_llvm"] and os.name == "nt" and methods._can_color: - env.Append(CCFLAGS=["$(-fansi-escape-codes$)", "$(-fcolor-diagnostics$)"]) - if get_is_ar_thin_supported(env): env.Append(ARFLAGS=["--thin"]) From 7cedf99ddc0cb4b6dd3c6d97d5adf987882da500 Mon Sep 17 00:00:00 2001 From: Steffen Blake Date: Tue, 7 Jan 2025 18:37:43 -0700 Subject: [PATCH 18/86] Update Windows Export Script to work on Battery Power --- platform/windows/export/export_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp index d82ca35b437..1944d26217b 100644 --- a/platform/windows/export/export_plugin.cpp +++ b/platform/windows/export/export_plugin.cpp @@ -440,7 +440,7 @@ void EditorExportPlatformWindows::get_export_options(List *r_optio String run_script = "Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'\n" "$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'\n" "$trigger = New-ScheduledTaskTrigger -Once -At 00:00\n" - "$settings = New-ScheduledTaskSettingsSet\n" + "$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries\n" "$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings\n" "Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true\n" "Start-ScheduledTask -TaskName godot_remote_debug\n" From a8377d0f22410b140701d6884b1a2115dfe36adb Mon Sep 17 00:00:00 2001 From: Summersay415 Date: Wed, 8 Jan 2025 12:09:35 +0700 Subject: [PATCH 19/86] Fix ANGLE and D3D12 libraries inclusion in .zip export --- platform/windows/export/export_plugin.cpp | 78 +++++++++++------------ 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp index d82ca35b437..93f6d405953 100644 --- a/platform/windows/export/export_plugin.cpp +++ b/platform/windows/export/export_plugin.cpp @@ -192,6 +192,36 @@ Error EditorExportPlatformWindows::export_project(const Ref } } + bool export_as_zip = p_path.ends_with("zip"); + bool embedded = p_preset->get("binary_format/embed_pck"); + + String pkg_name; + if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") { + pkg_name = String(ProjectSettings::get_singleton()->get("application/config/name")); + } else { + pkg_name = "Unnamed"; + } + + pkg_name = OS::get_singleton()->get_safe_dir_name(pkg_name); + + // Setup temp folder. + String path = p_path; + String tmp_dir_path = EditorPaths::get_singleton()->get_temp_dir().path_join(pkg_name); + Ref tmp_app_dir = DirAccess::create_for_path(tmp_dir_path); + if (export_as_zip) { + if (tmp_app_dir.is_null()) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Could not create and open the directory: \"%s\""), tmp_dir_path)); + return ERR_CANT_CREATE; + } + if (DirAccess::exists(tmp_dir_path)) { + if (tmp_app_dir->change_dir(tmp_dir_path) == OK) { + tmp_app_dir->erase_contents_recursive(); + } + } + tmp_app_dir->make_dir_recursive(tmp_dir_path); + path = tmp_dir_path.path_join(p_path.get_file().get_basename() + ".exe"); + } + int export_angle = p_preset->get("application/export_angle"); bool include_angle_libs = false; if (export_angle == 0) { @@ -202,10 +232,10 @@ Error EditorExportPlatformWindows::export_project(const Ref if (include_angle_libs) { Ref da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); if (da->file_exists(template_path.get_base_dir().path_join("libEGL." + arch + ".dll"))) { - da->copy(template_path.get_base_dir().path_join("libEGL." + arch + ".dll"), p_path.get_base_dir().path_join("libEGL.dll"), get_chmod_flags()); + da->copy(template_path.get_base_dir().path_join("libEGL." + arch + ".dll"), path.get_base_dir().path_join("libEGL.dll"), get_chmod_flags()); } if (da->file_exists(template_path.get_base_dir().path_join("libGLESv2." + arch + ".dll"))) { - da->copy(template_path.get_base_dir().path_join("libGLESv2." + arch + ".dll"), p_path.get_base_dir().path_join("libGLESv2.dll"), get_chmod_flags()); + da->copy(template_path.get_base_dir().path_join("libGLESv2." + arch + ".dll"), path.get_base_dir().path_join("libGLESv2.dll"), get_chmod_flags()); } } @@ -221,55 +251,25 @@ Error EditorExportPlatformWindows::export_project(const Ref Ref da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); if (da->file_exists(template_path.get_base_dir().path_join("D3D12Core." + arch + ".dll"))) { if (agility_sdk_multiarch) { - da->make_dir_recursive(p_path.get_base_dir().path_join(arch)); - da->copy(template_path.get_base_dir().path_join("D3D12Core." + arch + ".dll"), p_path.get_base_dir().path_join(arch).path_join("D3D12Core.dll"), get_chmod_flags()); + da->make_dir_recursive(path.get_base_dir().path_join(arch)); + da->copy(template_path.get_base_dir().path_join("D3D12Core." + arch + ".dll"), path.get_base_dir().path_join(arch).path_join("D3D12Core.dll"), get_chmod_flags()); } else { - da->copy(template_path.get_base_dir().path_join("D3D12Core." + arch + ".dll"), p_path.get_base_dir().path_join("D3D12Core.dll"), get_chmod_flags()); + da->copy(template_path.get_base_dir().path_join("D3D12Core." + arch + ".dll"), path.get_base_dir().path_join("D3D12Core.dll"), get_chmod_flags()); } } if (da->file_exists(template_path.get_base_dir().path_join("d3d12SDKLayers." + arch + ".dll"))) { if (agility_sdk_multiarch) { - da->make_dir_recursive(p_path.get_base_dir().path_join(arch)); - da->copy(template_path.get_base_dir().path_join("d3d12SDKLayers." + arch + ".dll"), p_path.get_base_dir().path_join(arch).path_join("d3d12SDKLayers.dll"), get_chmod_flags()); + da->make_dir_recursive(path.get_base_dir().path_join(arch)); + da->copy(template_path.get_base_dir().path_join("d3d12SDKLayers." + arch + ".dll"), path.get_base_dir().path_join(arch).path_join("d3d12SDKLayers.dll"), get_chmod_flags()); } else { - da->copy(template_path.get_base_dir().path_join("d3d12SDKLayers." + arch + ".dll"), p_path.get_base_dir().path_join("d3d12SDKLayers.dll"), get_chmod_flags()); + da->copy(template_path.get_base_dir().path_join("d3d12SDKLayers." + arch + ".dll"), path.get_base_dir().path_join("d3d12SDKLayers.dll"), get_chmod_flags()); } } if (da->file_exists(template_path.get_base_dir().path_join("WinPixEventRuntime." + arch + ".dll"))) { - da->copy(template_path.get_base_dir().path_join("WinPixEventRuntime." + arch + ".dll"), p_path.get_base_dir().path_join("WinPixEventRuntime.dll"), get_chmod_flags()); + da->copy(template_path.get_base_dir().path_join("WinPixEventRuntime." + arch + ".dll"), path.get_base_dir().path_join("WinPixEventRuntime.dll"), get_chmod_flags()); } } - bool export_as_zip = p_path.ends_with("zip"); - bool embedded = p_preset->get("binary_format/embed_pck"); - - String pkg_name; - if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") { - pkg_name = String(ProjectSettings::get_singleton()->get("application/config/name")); - } else { - pkg_name = "Unnamed"; - } - - pkg_name = OS::get_singleton()->get_safe_dir_name(pkg_name); - - // Setup temp folder. - String path = p_path; - String tmp_dir_path = EditorPaths::get_singleton()->get_temp_dir().path_join(pkg_name); - Ref tmp_app_dir = DirAccess::create_for_path(tmp_dir_path); - if (export_as_zip) { - if (tmp_app_dir.is_null()) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Could not create and open the directory: \"%s\""), tmp_dir_path)); - return ERR_CANT_CREATE; - } - if (DirAccess::exists(tmp_dir_path)) { - if (tmp_app_dir->change_dir(tmp_dir_path) == OK) { - tmp_app_dir->erase_contents_recursive(); - } - } - tmp_app_dir->make_dir_recursive(tmp_dir_path); - path = tmp_dir_path.path_join(p_path.get_file().get_basename() + ".exe"); - } - // Export project. String pck_path = path; if (embedded) { From 50b90604afa43e73fae09cf6f4fbf7d153c13f89 Mon Sep 17 00:00:00 2001 From: axunes Date: Sat, 4 Jan 2025 04:08:44 -0500 Subject: [PATCH 20/86] macOS: search for project file in .app resources --- core/config/project_settings.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index e90f81d0852..eb8e80a31d8 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -648,6 +648,28 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b return err; } +#ifdef MACOS_ENABLED + // Attempt to load project file from macOS .app bundle resources. + resource_path = OS::get_singleton()->get_bundle_resource_dir(); + if (!resource_path.is_empty()) { + if (resource_path[resource_path.length() - 1] == '/') { + resource_path = resource_path.substr(0, resource_path.length() - 1); // Chop end. + } + Ref d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + ERR_FAIL_COND_V_MSG(d.is_null(), ERR_CANT_CREATE, vformat("Cannot create DirAccess for path '%s'.", resource_path)); + d->change_dir(resource_path); + + Error err; + + err = _load_settings_text_or_binary(resource_path.path_join("project.godot"), resource_path.path_join("project.binary")); + if (err == OK && !p_ignore_override) { + // Optional, we don't mind if it fails. + _load_settings_text(resource_path.path_join("override.cfg")); + return err; + } + } +#endif + // Nothing was found, try to find a project file in provided path (`p_path`) // or, if requested (`p_upwards`) in parent directories. From 989161e117587733d6302b5191d14362f0e7f257 Mon Sep 17 00:00:00 2001 From: WhalesState Date: Wed, 8 Jan 2025 10:32:25 +0200 Subject: [PATCH 21/86] Fix color picking on linux. --- platform/macos/display_server_macos.mm | 1 + platform/windows/display_server_windows.cpp | 1 + scene/gui/color_picker.cpp | 75 ++++++++++++++------- 3 files changed, 54 insertions(+), 23 deletions(-) diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index f4935437552..2e1326ae4f6 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -788,6 +788,7 @@ case FEATURE_STATUS_INDICATOR: case FEATURE_NATIVE_HELP: case FEATURE_WINDOW_DRAG: + case FEATURE_SCREEN_EXCLUDE_FROM_CAPTURE: return true; default: { } diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index c053408ed4c..6a0ab3d4c6b 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -138,6 +138,7 @@ bool DisplayServerWindows::has_feature(Feature p_feature) const { case FEATURE_SCREEN_CAPTURE: case FEATURE_STATUS_INDICATOR: case FEATURE_WINDOW_EMBEDDING: + case FEATURE_SCREEN_EXCLUDE_FROM_CAPTURE: return true; default: return false; diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index c4a9ce8c3b0..08634f100bd 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -161,13 +161,19 @@ void ColorPicker::_notification(int p_what) { Vector2 ofs = ds->mouse_get_position(); picker_window->set_position(ofs - Vector2(28, 28)); - Color c = DisplayServer::get_singleton()->screen_get_pixel(DisplayServer::get_singleton()->mouse_get_position()); + Color c = DisplayServer::get_singleton()->screen_get_pixel(ofs); picker_preview_style_box_color->set_bg_color(c); picker_preview_style_box->set_bg_color(c.get_luminance() < 0.5 ? Color(1.0f, 1.0f, 1.0f) : Color(0.0f, 0.0f, 0.0f)); - Ref zoom_preview_img = ds->screen_get_image_rect(Rect2i(ofs.x - 8, ofs.y - 8, 17, 17)); - picker_texture_zoom->set_texture(ImageTexture::create_from_image(zoom_preview_img)); + if (ds->has_feature(DisplayServer::FEATURE_SCREEN_EXCLUDE_FROM_CAPTURE)) { + Ref zoom_preview_img = ds->screen_get_image_rect(Rect2i(ofs.x - 8, ofs.y - 8, 17, 17)); + picker_window->set_position(ofs - Vector2(28, 28)); + picker_texture_zoom->set_texture(ImageTexture::create_from_image(zoom_preview_img)); + } else { + Size2i screen_size = ds->screen_get_size(); + picker_window->set_position(ofs + Vector2(ofs.x < screen_size.width / 2 ? 8 : -36, ofs.y < screen_size.height / 2 ? 8 : -36)); + } set_pick_color(c); } @@ -1708,12 +1714,16 @@ void ColorPicker::_pick_button_pressed() { if (!picker_window) { picker_window = memnew(Popup); - picker_window->set_size(Vector2i(55, 72)); + bool has_feature_exclude_from_capture = DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_SCREEN_EXCLUDE_FROM_CAPTURE); + if (!has_feature_exclude_from_capture) { + picker_window->set_size(Vector2i(28, 28)); + } else { + picker_window->set_size(Vector2i(55, 72)); + picker_window->set_flag(Window::FLAG_EXCLUDE_FROM_CAPTURE, true); // Only supported on MacOS and Windows. + } picker_window->connect(SceneStringName(visibility_changed), callable_mp(this, &ColorPicker::_pick_finished)); picker_window->connect(SceneStringName(window_input), callable_mp(this, &ColorPicker::_target_gui_input)); - picker_window->set_flag(Window::FLAG_EXCLUDE_FROM_CAPTURE, true); - picker_preview = memnew(Panel); picker_preview->set_mouse_filter(MOUSE_FILTER_IGNORE); picker_preview->set_size(Vector2i(55, 72)); @@ -1721,16 +1731,23 @@ void ColorPicker::_pick_button_pressed() { picker_preview_color = memnew(Panel); picker_preview_color->set_mouse_filter(MOUSE_FILTER_IGNORE); - picker_preview_color->set_size(Vector2i(51, 15)); - picker_preview_color->set_position(Vector2i(2, 55)); + if (!has_feature_exclude_from_capture) { + picker_preview_color->set_size(Vector2i(24, 24)); + picker_preview_color->set_position(Vector2i(2, 2)); + } else { + picker_preview_color->set_size(Vector2i(51, 15)); + picker_preview_color->set_position(Vector2i(2, 55)); + } picker_preview->add_child(picker_preview_color); - picker_texture_zoom = memnew(TextureRect); - picker_texture_zoom->set_mouse_filter(MOUSE_FILTER_IGNORE); - picker_texture_zoom->set_custom_minimum_size(Vector2i(51, 51)); - picker_texture_zoom->set_position(Vector2i(2, 2)); - picker_texture_zoom->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); - picker_preview->add_child(picker_texture_zoom); + if (has_feature_exclude_from_capture) { + picker_texture_zoom = memnew(TextureRect); + picker_texture_zoom->set_mouse_filter(MOUSE_FILTER_IGNORE); + picker_texture_zoom->set_custom_minimum_size(Vector2i(51, 51)); + picker_texture_zoom->set_position(Vector2i(2, 2)); + picker_texture_zoom->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); + picker_preview->add_child(picker_texture_zoom); + } picker_preview_style_box.instantiate(); picker_preview->add_theme_style_override(SceneStringName(panel), picker_preview_style_box); @@ -1886,23 +1903,35 @@ void ColorPicker::_pick_button_pressed_legacy() { picker_window->add_child(picker_texture_rect); picker_texture_rect->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_picker_texture_input)); + bool has_feature_exclude_from_capture = DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_SCREEN_EXCLUDE_FROM_CAPTURE); picker_preview = memnew(Panel); picker_preview->set_mouse_filter(MOUSE_FILTER_IGNORE); - picker_preview->set_size(Vector2i(55, 72)); + if (!has_feature_exclude_from_capture) { + picker_preview->set_size(Vector2i(28, 28)); + } else { + picker_preview->set_size(Vector2i(55, 72)); + } picker_window->add_child(picker_preview); picker_preview_color = memnew(Panel); picker_preview_color->set_mouse_filter(MOUSE_FILTER_IGNORE); - picker_preview_color->set_size(Vector2i(51, 15)); - picker_preview_color->set_position(Vector2i(2, 55)); + if (!has_feature_exclude_from_capture) { + picker_preview_color->set_size(Vector2i(24, 24)); + picker_preview_color->set_position(Vector2i(2, 2)); + } else { + picker_preview_color->set_size(Vector2i(51, 15)); + picker_preview_color->set_position(Vector2i(2, 55)); + } picker_preview->add_child(picker_preview_color); - picker_texture_zoom = memnew(TextureRect); - picker_texture_zoom->set_mouse_filter(MOUSE_FILTER_IGNORE); - picker_texture_zoom->set_custom_minimum_size(Vector2i(51, 51)); - picker_texture_zoom->set_position(Vector2i(2, 2)); - picker_texture_zoom->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); - picker_preview->add_child(picker_texture_zoom); + if (has_feature_exclude_from_capture) { + picker_texture_zoom = memnew(TextureRect); + picker_texture_zoom->set_mouse_filter(MOUSE_FILTER_IGNORE); + picker_texture_zoom->set_custom_minimum_size(Vector2i(51, 51)); + picker_texture_zoom->set_position(Vector2i(2, 2)); + picker_texture_zoom->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); + picker_preview->add_child(picker_texture_zoom); + } picker_preview_style_box.instantiate(); picker_preview->add_theme_style_override(SceneStringName(panel), picker_preview_style_box); From 6f4089fa55dd07edcc003f8ecba612e968c96102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Wed, 8 Jan 2025 10:40:17 +0100 Subject: [PATCH 22/86] Fix GCC warning about potential stringop-overflow in AudioEffectPitchShift Fixes #101236. --- servers/audio/effects/audio_effect_pitch_shift.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers/audio/effects/audio_effect_pitch_shift.h b/servers/audio/effects/audio_effect_pitch_shift.h index 949ce960579..381833c24ae 100644 --- a/servers/audio/effects/audio_effect_pitch_shift.h +++ b/servers/audio/effects/audio_effect_pitch_shift.h @@ -77,7 +77,7 @@ class AudioEffectPitchShift : public AudioEffect { public: friend class AudioEffectPitchShiftInstance; - enum FFTSize { + enum FFTSize : unsigned int { FFT_SIZE_256, FFT_SIZE_512, FFT_SIZE_1024, From 8a810dd55abc79de826b54f3a8d2a8c927ec08ff Mon Sep 17 00:00:00 2001 From: Mateus Elias Date: Wed, 8 Jan 2025 09:45:59 -0300 Subject: [PATCH 23/86] Fix incorrect string escaping in OS.shell_open() method Windows path example Corrected improper string escaping in the OS.shell_open() Windows path example. Backslashes are now properly escaped to prevent string parsing errors. Also, added a new alternative example of how to mount a Windows path with OS.shell_open(). --- doc/classes/OS.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 48e18f4a319..72857bae318 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -809,7 +809,8 @@ Requests the OS to open a resource identified by [param uri] with the most appropriate program. For example: - - [code]OS.shell_open("C:\\Users\name\Downloads")[/code] on Windows opens the file explorer at the user's Downloads folder. + - [code]OS.shell_open("C:\\Users\\name\\Downloads")[/code] on Windows opens the file explorer at the user's Downloads folder. + - [code]OS.shell_open("C:/Users/name/Downloads")[/code] also works on Windows and opens the file explorer at the user's Downloads folder. - [code]OS.shell_open("https://godotengine.org")[/code] opens the default web browser on the official Godot website. - [code]OS.shell_open("mailto:example@example.com")[/code] opens the default email client with the "To" field set to [code]example@example.com[/code]. See [url=https://datatracker.ietf.org/doc/html/rfc2368]RFC 2368 - The [code]mailto[/code] URL scheme[/url] for a list of fields that can be added. Use [method ProjectSettings.globalize_path] to convert a [code]res://[/code] or [code]user://[/code] project path into a system path for use with this method. From f134769506d8ac2e3a9f676a10f5be81da1ded8b Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Wed, 8 Jan 2025 11:56:49 +0200 Subject: [PATCH 24/86] Fix various typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add TODO notes for typos that should be fixed for 5.0 Co-authored-by: Rémi Verschelde --- SConstruct | 2 +- core/math/delaunay_3d.h | 12 +- core/templates/rid_owner.h | 12 +- core/variant/variant_setget.cpp | 30 +-- doc/Doxyfile | 2 +- doc/classes/RenderingServer.xml | 2 +- .../d3d12/rendering_device_driver_d3d12.cpp | 14 +- drivers/gles3/storage/light_storage.h | 4 +- drivers/metal/pixel_formats.h | 2 +- drivers/metal/pixel_formats.mm | 4 +- editor/animation_track_editor_plugins.cpp | 8 +- editor/doc_tools.cpp | 2 +- editor/export/codesign.h | 2 +- editor/filesystem_dock.cpp | 10 +- editor/filesystem_dock.h | 2 +- ...post_import_plugin_skeleton_rest_fixer.cpp | 10 +- editor/import/3d/resource_importer_scene.cpp | 6 +- .../resource_importer_layered_texture.cpp | 2 +- editor/plugins/node_3d_editor_plugin.cpp | 4 +- editor/plugins/script_editor_plugin.cpp | 4 +- editor/plugins/script_editor_plugin.h | 2 +- editor/plugins/tiles/atlas_merging_dialog.cpp | 8 +- editor/plugins/tiles/atlas_merging_dialog.h | 2 +- .../tiles/tile_proxies_manager_dialog.cpp | 10 +- .../tiles/tile_proxies_manager_dialog.h | 2 +- .../tiles/tile_set_atlas_source_editor.cpp | 4 +- .../tiles/tile_set_atlas_source_editor.h | 2 +- ...tile_set_scenes_collection_source_editor.h | 2 +- editor/template_builders.py | 4 +- main/steam_tracker.cpp | 6 +- main/steam_tracker.h | 2 +- misc/dist/html/service-worker.js | 12 +- modules/gdscript/gdscript_analyzer.cpp | 16 +- modules/gdscript/gdscript_editor.cpp | 2 +- .../language_server/gdscript_extend_parser.h | 6 +- .../gdscript_text_document.cpp | 2 +- modules/gltf/gltf_document.cpp | 2 +- modules/gltf/gltf_document.h | 2 +- modules/godot_physics_2d/godot_joints_2d.cpp | 2 +- .../extensions/openxr_extension_wrapper.h | 2 +- modules/text_server_adv/text_server_adv.cpp | 8 +- platform/ios/os_ios.mm | 6 +- platform/macos/export/export_plugin.cpp | 8 +- platform/windows/export/export_plugin.cpp | 6 +- scene/2d/cpu_particles_2d.cpp | 8 +- scene/2d/gpu_particles_2d.cpp | 8 +- scene/2d/navigation_region_2d.cpp | 10 +- scene/2d/navigation_region_2d.h | 2 +- scene/animation/animation_blend_space_2d.cpp | 10 +- scene/animation/animation_blend_space_2d.h | 2 +- scene/animation/animation_blend_tree.cpp | 4 +- scene/animation/animation_blend_tree.h | 2 +- scene/animation/animation_mixer.cpp | 36 +-- scene/animation/animation_mixer.h | 6 +- .../animation_node_state_machine.cpp | 4 +- scene/gui/graph_edit_arranger.cpp | 4 +- scene/gui/text_edit.cpp | 22 +- scene/gui/text_edit.h | 2 +- scene/gui/tree.cpp | 14 +- scene/gui/tree.h | 2 +- scene/resources/3d/primitive_meshes.cpp | 14 +- scene/resources/animation.h | 4 +- scene/resources/font.cpp | 26 +-- scene/resources/font.h | 2 +- .../audio_effect_spectrum_analyzer.cpp | 4 +- servers/display_server.cpp | 6 +- servers/display_server.h | 2 +- .../rendering/dummy/storage/light_storage.h | 4 +- .../rendering/renderer_rd/environment/gi.cpp | 4 +- .../renderer_rd/renderer_canvas_render_rd.cpp | 2 +- .../shaders/effects/bokeh_dof_raster.glsl | 8 +- .../shaders/scene_forward_lights_inc.glsl | 6 +- .../renderer_rd/storage_rd/light_storage.cpp | 4 +- servers/rendering/renderer_scene_cull.h | 2 +- servers/rendering/renderer_scene_render.cpp | 2 +- servers/rendering/rendering_device_commons.h | 2 +- servers/rendering/storage/light_storage.h | 4 +- servers/rendering_server.cpp | 2 +- servers/rendering_server.h | 2 +- servers/text_server.h | 2 +- tests/core/math/test_plane.h | 2 +- tests/display_server_mock.h | 2 +- tests/scene/test_code_edit.h | 210 +++++++++--------- tests/scene/test_gltf_document.h | 4 +- tests/servers/test_navigation_server_3d.h | 2 +- tests/test_macros.h | 86 +++---- 86 files changed, 398 insertions(+), 398 deletions(-) diff --git a/SConstruct b/SConstruct index 470830d8eb7..87f51f74a9f 100644 --- a/SConstruct +++ b/SConstruct @@ -198,7 +198,7 @@ opts.Add(BoolVariable("threads", "Enable threading support", True)) opts.Add(BoolVariable("deprecated", "Enable compatibility code for deprecated and removed features", True)) opts.Add(EnumVariable("precision", "Set the floating-point precision level", "single", ("single", "double"))) opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", True)) -opts.Add(BoolVariable("brotli", "Enable Brotli for decompresson and WOFF2 fonts support", True)) +opts.Add(BoolVariable("brotli", "Enable Brotli for decompression and WOFF2 fonts support", True)) opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver on supported platforms", False)) opts.Add(BoolVariable("vulkan", "Enable the vulkan rendering driver", True)) opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 rendering driver", True)) diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h index 4f21a665de7..5bbdcc093e9 100644 --- a/core/math/delaunay_3d.h +++ b/core/math/delaunay_3d.h @@ -135,9 +135,9 @@ class Delaunay3D { R128 row3_y = v3_y - v0_y; R128 row3_z = v3_z - v0_z; - R128 sq_lenght1 = row1_x * row1_x + row1_y * row1_y + row1_z * row1_z; - R128 sq_lenght2 = row2_x * row2_x + row2_y * row2_y + row2_z * row2_z; - R128 sq_lenght3 = row3_x * row3_x + row3_y * row3_y + row3_z * row3_z; + R128 sq_length1 = row1_x * row1_x + row1_y * row1_y + row1_z * row1_z; + R128 sq_length2 = row2_x * row2_x + row2_y * row2_y + row2_z * row2_z; + R128 sq_length3 = row3_x * row3_x + row3_y * row3_y + row3_z * row3_z; // Compute the determinant of said matrix. R128 determinant = row1_x * (row2_y * row3_z - row3_y * row2_z) - row2_x * (row1_y * row3_z - row3_y * row1_z) + row3_x * (row1_y * row2_z - row2_y * row1_z); @@ -146,9 +146,9 @@ class Delaunay3D { R128 volume = determinant / R128(6.f); R128 i12volume = R128(1.f) / (volume * R128(12.f)); - R128 center_x = v0_x + i12volume * ((row2_y * row3_z - row3_y * row2_z) * sq_lenght1 - (row1_y * row3_z - row3_y * row1_z) * sq_lenght2 + (row1_y * row2_z - row2_y * row1_z) * sq_lenght3); - R128 center_y = v0_y + i12volume * (-(row2_x * row3_z - row3_x * row2_z) * sq_lenght1 + (row1_x * row3_z - row3_x * row1_z) * sq_lenght2 - (row1_x * row2_z - row2_x * row1_z) * sq_lenght3); - R128 center_z = v0_z + i12volume * ((row2_x * row3_y - row3_x * row2_y) * sq_lenght1 - (row1_x * row3_y - row3_x * row1_y) * sq_lenght2 + (row1_x * row2_y - row2_x * row1_y) * sq_lenght3); + R128 center_x = v0_x + i12volume * ((row2_y * row3_z - row3_y * row2_z) * sq_length1 - (row1_y * row3_z - row3_y * row1_z) * sq_length2 + (row1_y * row2_z - row2_y * row1_z) * sq_length3); + R128 center_y = v0_y + i12volume * (-(row2_x * row3_z - row3_x * row2_z) * sq_length1 + (row1_x * row3_z - row3_x * row1_z) * sq_length2 - (row1_x * row2_z - row2_x * row1_z) * sq_length3); + R128 center_z = v0_z + i12volume * ((row2_x * row3_y - row3_x * row2_y) * sq_length1 - (row1_x * row3_y - row3_x * row1_y) * sq_length2 + (row1_x * row2_y - row2_x * row1_y) * sq_length3); // Once we know the center, the radius is clearly the distance to any vertex. R128 rel1_x = center_x - v0_x; diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h index 3ee70a092fe..149ac0dbd9a 100644 --- a/core/templates/rid_owner.h +++ b/core/templates/rid_owner.h @@ -417,8 +417,8 @@ class RID_Alloc : public RID_AllocBase { } } - void set_description(const char *p_descrption) { - description = p_descrption; + void set_description(const char *p_description) { + description = p_description; } RID_Alloc(uint32_t p_target_chunk_byte_size = 65536, uint32_t p_maximum_number_of_elements = 262144) { @@ -515,8 +515,8 @@ class RID_PtrOwner { alloc.fill_owned_buffer(p_rid_buffer); } - void set_description(const char *p_descrption) { - alloc.set_description(p_descrption); + void set_description(const char *p_description) { + alloc.set_description(p_description); } RID_PtrOwner(uint32_t p_target_chunk_byte_size = 65536, uint32_t p_maximum_number_of_elements = 262144) : @@ -570,8 +570,8 @@ class RID_Owner { alloc.fill_owned_buffer(p_rid_buffer); } - void set_description(const char *p_descrption) { - alloc.set_description(p_descrption); + void set_description(const char *p_description) { + alloc.set_description(p_description); } RID_Owner(uint32_t p_target_chunk_byte_size = 65536, uint32_t p_maximum_number_of_elements = 262144) : alloc(p_target_chunk_byte_size, p_maximum_number_of_elements) {} diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index 21fd12d2464..a50f213bc5d 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -479,7 +479,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { } \ }; -#define INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(m_base_type, m_elem_type, m_assign_type, m_max) \ +#define INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(m_base_type, m_elem_type, m_assign_type, m_max) \ struct VariantIndexedSetGet_##m_base_type { \ static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \ if (index < 0 || index >= m_max) { \ @@ -541,7 +541,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { } \ }; -#define INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(m_base_type, m_elem_type, m_accessor, m_max) \ +#define INDEXED_SETGET_STRUCT_BUILTIN_ACCESSOR(m_base_type, m_elem_type, m_accessor, m_max) \ struct VariantIndexedSetGet_##m_base_type { \ static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \ if (index < 0 || index >= m_max) { \ @@ -597,7 +597,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { } \ }; -#define INDEXED_SETGET_STRUCT_BULTIN_FUNC(m_base_type, m_elem_type, m_set, m_get, m_max) \ +#define INDEXED_SETGET_STRUCT_BUILTIN_FUNC(m_base_type, m_elem_type, m_set, m_get, m_max) \ struct VariantIndexedSetGet_##m_base_type { \ static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \ if (index < 0 || index >= m_max) { \ @@ -844,18 +844,18 @@ struct VariantIndexedSetGet_String { static uint64_t get_indexed_size(const Variant *base) { return VariantInternal::get_string(base)->length(); } }; -INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2, double, real_t, 2) -INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2i, int64_t, int32_t, 2) -INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3, double, real_t, 3) -INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3i, int64_t, int32_t, 3) -INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector4, double, real_t, 4) -INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector4i, int64_t, int32_t, 4) -INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Quaternion, double, real_t, 4) -INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Color, double, float, 4) - -INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Transform2D, Vector2, .columns, 3) -INDEXED_SETGET_STRUCT_BULTIN_FUNC(Basis, Vector3, set_column, get_column, 3) -INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Projection, Vector4, .columns, 4) +INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Vector2, double, real_t, 2) +INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Vector2i, int64_t, int32_t, 2) +INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Vector3, double, real_t, 3) +INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Vector3i, int64_t, int32_t, 3) +INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Vector4, double, real_t, 4) +INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Vector4i, int64_t, int32_t, 4) +INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Quaternion, double, real_t, 4) +INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Color, double, float, 4) + +INDEXED_SETGET_STRUCT_BUILTIN_ACCESSOR(Transform2D, Vector2, .columns, 3) +INDEXED_SETGET_STRUCT_BUILTIN_FUNC(Basis, Vector3, set_column, get_column, 3) +INDEXED_SETGET_STRUCT_BUILTIN_ACCESSOR(Projection, Vector4, .columns, 4) INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedByteArray, int64_t, uint8_t) INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedInt32Array, int64_t, int32_t) diff --git a/doc/Doxyfile b/doc/Doxyfile index 26d86cb1272..bd1c940ba7b 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1475,7 +1475,7 @@ EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index f05f431dcf3..14cfb4b9f43 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1280,7 +1280,7 @@ - + Sets the values to be used for ambient light rendering. See [Environment] for more details. diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index cd5df56fbb9..0e92d830574 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -1660,7 +1660,7 @@ bool RenderingDeviceDriverD3D12::texture_can_make_shared_with_format(TextureID p /**** SAMPLER ****/ /*****************/ -static const D3D12_TEXTURE_ADDRESS_MODE RD_REPEAT_MODE_TO_D3D12_ADDRES_MODE[RDD::SAMPLER_REPEAT_MODE_MAX] = { +static const D3D12_TEXTURE_ADDRESS_MODE RD_REPEAT_MODE_TO_D3D12_ADDRESS_MODE[RDD::SAMPLER_REPEAT_MODE_MAX] = { D3D12_TEXTURE_ADDRESS_MODE_WRAP, D3D12_TEXTURE_ADDRESS_MODE_MIRROR, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, @@ -1715,9 +1715,9 @@ RDD::SamplerID RenderingDeviceDriverD3D12::sampler_create(const SamplerState &p_ p_state.enable_compare ? D3D12_FILTER_REDUCTION_TYPE_COMPARISON : D3D12_FILTER_REDUCTION_TYPE_STANDARD); } - sampler_desc.AddressU = RD_REPEAT_MODE_TO_D3D12_ADDRES_MODE[p_state.repeat_u]; - sampler_desc.AddressV = RD_REPEAT_MODE_TO_D3D12_ADDRES_MODE[p_state.repeat_v]; - sampler_desc.AddressW = RD_REPEAT_MODE_TO_D3D12_ADDRES_MODE[p_state.repeat_w]; + sampler_desc.AddressU = RD_REPEAT_MODE_TO_D3D12_ADDRESS_MODE[p_state.repeat_u]; + sampler_desc.AddressV = RD_REPEAT_MODE_TO_D3D12_ADDRESS_MODE[p_state.repeat_v]; + sampler_desc.AddressW = RD_REPEAT_MODE_TO_D3D12_ADDRESS_MODE[p_state.repeat_w]; for (int i = 0; i < 4; i++) { sampler_desc.BorderColor[i] = RD_TO_D3D12_SAMPLER_BORDER_COLOR[p_state.border_color][i]; @@ -3811,7 +3811,7 @@ void RenderingDeviceDriverD3D12::shader_destroy_modules(ShaderID p_shader) { /**** UNIFORM SET ****/ /*********************/ -static void _add_descriptor_count_for_uniform(RenderingDevice::UniformType p_type, uint32_t p_binding_length, bool p_dobule_srv_uav_ambiguous, uint32_t &r_num_resources, uint32_t &r_num_samplers, bool &r_srv_uav_ambiguity) { +static void _add_descriptor_count_for_uniform(RenderingDevice::UniformType p_type, uint32_t p_binding_length, bool p_double_srv_uav_ambiguous, uint32_t &r_num_resources, uint32_t &r_num_samplers, bool &r_srv_uav_ambiguity) { r_srv_uav_ambiguity = false; // Some resource types can be SRV or UAV, depending on what NIR-DXIL decided for a specific shader variant. @@ -3832,11 +3832,11 @@ static void _add_descriptor_count_for_uniform(RenderingDevice::UniformType p_typ r_num_resources += 1; } break; case RenderingDevice::UNIFORM_TYPE_STORAGE_BUFFER: { - r_num_resources += p_dobule_srv_uav_ambiguous ? 2 : 1; + r_num_resources += p_double_srv_uav_ambiguous ? 2 : 1; r_srv_uav_ambiguity = true; } break; case RenderingDevice::UNIFORM_TYPE_IMAGE: { - r_num_resources += p_binding_length * (p_dobule_srv_uav_ambiguous ? 2 : 1); + r_num_resources += p_binding_length * (p_double_srv_uav_ambiguous ? 2 : 1); r_srv_uav_ambiguity = true; } break; default: { diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h index c1d23deb4df..ddd1d79783d 100644 --- a/drivers/gles3/storage/light_storage.h +++ b/drivers/gles3/storage/light_storage.h @@ -757,7 +757,7 @@ class LightStorage : public RendererLightStorage { virtual void shadow_atlas_free(RID p_atlas) override; virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) override; virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override; - virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override; + virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_instance, float p_coverage, uint64_t p_light_version) override; _FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_instance) { ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas); @@ -883,7 +883,7 @@ class LightStorage : public RendererLightStorage { virtual void shadow_atlas_update(RID p_atlas) override; virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) override; - virtual int get_directional_light_shadow_size(RID p_light_intance) override; + virtual int get_directional_light_shadow_size(RID p_light_instance) override; virtual void set_directional_shadow_count(int p_count) override; Rect2i get_directional_shadow_rect(); diff --git a/drivers/metal/pixel_formats.h b/drivers/metal/pixel_formats.h index 167c3d56009..40189ed8a6f 100644 --- a/drivers/metal/pixel_formats.h +++ b/drivers/metal/pixel_formats.h @@ -274,7 +274,7 @@ class API_AVAILABLE(macos(11.0), ios(14.0)) PixelFormats { MTLFormatType getFormatType(DataFormat p_format); /** Returns the format type corresponding to the specified Metal MTLPixelFormat, */ - MTLFormatType getFormatType(MTLPixelFormat p_formt); + MTLFormatType getFormatType(MTLPixelFormat p_format); /** * Returns the Metal MTLPixelFormat corresponding to the specified Godot pixel diff --git a/drivers/metal/pixel_formats.mm b/drivers/metal/pixel_formats.mm index 36edbab99aa..97452656a08 100644 --- a/drivers/metal/pixel_formats.mm +++ b/drivers/metal/pixel_formats.mm @@ -144,8 +144,8 @@ void clear(T *p_val, size_t p_count = 1) { return getDataFormatDesc(p_format).formatType; } -MTLFormatType PixelFormats::getFormatType(MTLPixelFormat p_formt) { - return getDataFormatDesc(p_formt).formatType; +MTLFormatType PixelFormats::getFormatType(MTLPixelFormat p_format) { + return getDataFormatDesc(p_format).formatType; } MTLPixelFormat PixelFormats::getMTLPixelFormat(DataFormat p_format) { diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp index 9c30f156267..cad4a975279 100644 --- a/editor/animation_track_editor_plugins.cpp +++ b/editor/animation_track_editor_plugins.cpp @@ -417,8 +417,8 @@ Rect2 AnimationTrackEditSpriteFrame::get_key_rect(int p_index, float p_pixels_se animation_path = animation_path.replace(":frame", ":animation"); int animation_track = get_animation()->find_track(animation_path, get_animation()->track_get_type(get_track())); float track_time = get_animation()->track_get_key_time(get_track(), p_index); - int animaiton_index = get_animation()->track_find_key(animation_track, track_time); - animation_name = get_animation()->track_get_key_value(animation_track, animaiton_index); + int animation_index = get_animation()->track_find_key(animation_track, track_time); + animation_name = get_animation()->track_get_key_value(animation_track, animation_index); } Ref texture = sf->get_frame_texture(animation_name, frame); @@ -509,8 +509,8 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in animation_path = animation_path.replace(":frame", ":animation"); int animation_track = get_animation()->find_track(animation_path, get_animation()->track_get_type(get_track())); float track_time = get_animation()->track_get_key_time(get_track(), p_index); - int animaiton_index = get_animation()->track_find_key(animation_track, track_time); - animation_name = get_animation()->track_get_key_value(animation_track, animaiton_index); + int animation_index = get_animation()->track_find_key(animation_track, track_time); + animation_name = get_animation()->track_get_key_value(animation_track, animation_index); } texture = sf->get_frame_texture(animation_name, frame); diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index bf9b531605b..02babe6a068 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -75,7 +75,7 @@ static String _translate_doc_string(const String &p_text) { return translated.indent(indent); } -// Comparator for constructors, based on `MetodDoc` operator. +// Comparator for constructors, based on `MethodDoc` operator. struct ConstructorCompare { _FORCE_INLINE_ bool operator()(const DocData::MethodDoc &p_lhs, const DocData::MethodDoc &p_rhs) const { // Must be a constructor (i.e. assume named for the class) diff --git a/editor/export/codesign.h b/editor/export/codesign.h index 9659cc1a6a5..0e0635dff89 100644 --- a/editor/export/codesign.h +++ b/editor/export/codesign.h @@ -275,7 +275,7 @@ class CodeSignCodeDirectory : public CodeSignBlob { uint32_t spare3; // Not used. uint64_t code_limit_64; // Set to 0 and ignore. // Version 0x20400 - uint64_t exec_seg_base; // Start of the signed code segmet. + uint64_t exec_seg_base; // Start of the signed code segment. uint64_t exec_seg_limit; // Code segment (__TEXT) vmsize. uint64_t exec_seg_flags; // Executable segment flags. // Version 0x20500 diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index aed3d7bb5ad..f626891bd8e 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -82,7 +82,7 @@ Control *FileSystemList::make_custom_tooltip(const String &p_text) const { } void FileSystemList::_line_editor_submit(const String &p_text) { - if (popup_edit_commited) { + if (popup_edit_committed) { return; // Already processed by _text_editor_popup_modal_close } @@ -90,7 +90,7 @@ void FileSystemList::_line_editor_submit(const String &p_text) { return; // ESC pressed, app focus lost, or forced close from code. } - popup_edit_commited = true; // End edit popup processing. + popup_edit_committed = true; // End edit popup processing. popup_editor->hide(); emit_signal(SNAME("item_edited")); @@ -139,7 +139,7 @@ bool FileSystemList::edit_selected() { line_editor->set_text(name); line_editor->select(0, name.rfind_char('.')); - popup_edit_commited = false; // Start edit popup processing. + popup_edit_committed = false; // Start edit popup processing. popup_editor->popup(); popup_editor->child_controls_changed(); line_editor->grab_focus(); @@ -151,7 +151,7 @@ String FileSystemList::get_edit_text() { } void FileSystemList::_text_editor_popup_modal_close() { - if (popup_edit_commited) { + if (popup_edit_committed) { return; // Already processed by _text_editor_popup_modal_close } @@ -1184,7 +1184,7 @@ HashSet FileSystemDock::_get_valid_conversions_for_file_paths(const Vect return HashSet(); } - // Get a list of all potentional conversion-to targets. + // Get a list of all potential conversion-to targets. HashSet current_valid_conversion_to_targets; for (const Ref &E : conversions) { const String what = E->converts_to(); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index b177f8a3cc6..0ed0de3d59e 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -60,7 +60,7 @@ class FileSystemTree : public Tree { class FileSystemList : public ItemList { GDCLASS(FileSystemList, ItemList); - bool popup_edit_commited = true; + bool popup_edit_committed = true; VBoxContainer *popup_editor_vb = nullptr; Popup *popup_editor = nullptr; LineEdit *line_editor = nullptr; diff --git a/editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp b/editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp index c1e64325148..21b60743d83 100644 --- a/editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp +++ b/editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp @@ -645,13 +645,13 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory // Scan descendants for mapped bones. bool found_mapped = false; - Vector decendants_to_process = src_skeleton->get_bone_children(src_idx); - while (decendants_to_process.size() > 0) { - int desc_idx = decendants_to_process[0]; - decendants_to_process.erase(desc_idx); + Vector descendants_to_process = src_skeleton->get_bone_children(src_idx); + while (descendants_to_process.size() > 0) { + int desc_idx = descendants_to_process[0]; + descendants_to_process.erase(desc_idx); Vector desc_children = src_skeleton->get_bone_children(desc_idx); for (const int &desc_child : desc_children) { - decendants_to_process.push_back(desc_child); + descendants_to_process.push_back(desc_child); } StringName desc_bone_name = is_renamed ? StringName(src_skeleton->get_bone_name(desc_idx)) : bone_map->find_profile_bone_name(src_skeleton->get_bone_name(desc_idx)); diff --git a/editor/import/3d/resource_importer_scene.cpp b/editor/import/3d/resource_importer_scene.cpp index 4b5c1011059..4a8837ce5b0 100644 --- a/editor/import/3d/resource_importer_scene.cpp +++ b/editor/import/3d/resource_importer_scene.cpp @@ -2363,12 +2363,12 @@ void ResourceImporterScene::get_import_options(const String &p_path, Listpush_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_type", PROPERTY_HINT_TYPE_STRING, "Node"), "")); r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_name"), "")); - List script_extentions; - ResourceLoader::get_recognized_extensions_for_type("Script", &script_extentions); + List script_extensions; + ResourceLoader::get_recognized_extensions_for_type("Script", &script_extensions); String script_ext_hint; - for (const String &E : script_extentions) { + for (const String &E : script_extensions) { if (!script_ext_hint.is_empty()) { script_ext_hint += ","; } diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index b10c681816b..33186bc42c2 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -489,7 +489,7 @@ void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source _save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + extension, r_texture_import->compress_mode, r_texture_import->lossy, Image::COMPRESS_S3TC /* IGNORED */, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, false); return; } - // Must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc). + // Must import in all formats, in order of priority (so platform chooses the best supported one. IE, etc2 over etc). // Android, GLES 2.x const bool can_s3tc_bptc = ResourceImporterTextureSettings::should_import_s3tc_bptc(); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index b803d2e5d82..062fa01758a 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2072,8 +2072,8 @@ void Node3DEditorViewport::_sinput(const Ref &p_event) { } bool current_hover_handle_secondary = false; - int curreny_hover_handle = spatial_editor->get_current_hover_gizmo_handle(current_hover_handle_secondary); - if (found_gizmo != spatial_editor->get_current_hover_gizmo() || found_handle != curreny_hover_handle || found_handle_secondary != current_hover_handle_secondary) { + int current_hover_handle = spatial_editor->get_current_hover_gizmo_handle(current_hover_handle_secondary); + if (found_gizmo != spatial_editor->get_current_hover_gizmo() || found_handle != current_hover_handle || found_handle_secondary != current_hover_handle_secondary) { spatial_editor->set_current_hover_gizmo(found_gizmo); spatial_editor->set_current_hover_gizmo_handle(found_handle, found_handle_secondary); spatial_editor->get_single_selected_node()->update_gizmos(); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index c11b107ee38..8c6c02f8548 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1277,8 +1277,8 @@ Ref