summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/object/class_db.cpp8
-rw-r--r--core/string/ustring.cpp21
-rw-r--r--core/string/ustring.h4
-rw-r--r--core/variant/callable.h10
-rw-r--r--core/variant/variant_call.cpp4
-rw-r--r--doc/classes/String.xml8
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp2
-rw-r--r--editor/action_map_editor.cpp7
-rw-r--r--editor/create_dialog.cpp8
-rw-r--r--editor/editor_command_palette.cpp2
-rw-r--r--editor/editor_properties.cpp3
-rw-r--r--editor/editor_resource_picker.cpp16
-rw-r--r--editor/editor_run.cpp7
-rw-r--r--editor/find_in_files.cpp3
-rw-r--r--editor/import/resource_importer_scene.cpp2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp6
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp2
-rw-r--r--editor/project_manager.cpp2
-rw-r--r--editor/script_create_dialog.cpp4
-rw-r--r--platform/android/android_keys_utils.h6
-rw-r--r--platform/web/display_server_web.cpp25
-rw-r--r--platform/web/js/engine/config.js2
-rw-r--r--platform/web/web_main.cpp36
-rw-r--r--scene/3d/collision_object_3d.cpp2
-rw-r--r--scene/3d/xr_nodes.cpp6
-rw-r--r--scene/gui/code_edit.cpp4
-rw-r--r--scene/gui/option_button.cpp2
-rw-r--r--servers/display_server.cpp11
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp4
-rw-r--r--servers/rendering/renderer_rd/storage_rd/utilities.cpp4
-rw-r--r--tests/core/io/test_json.h2
-rw-r--r--tests/core/math/test_aabb.h8
-rw-r--r--tests/core/math/test_basis.h10
-rw-r--r--tests/core/math/test_color.h6
-rw-r--r--tests/core/math/test_expression.h20
-rw-r--r--tests/core/math/test_geometry_2d.h24
-rw-r--r--tests/core/math/test_rect2.h8
-rw-r--r--tests/core/math/test_vector2.h28
-rw-r--r--tests/core/math/test_vector2i.h6
-rw-r--r--tests/core/math/test_vector3.h28
-rw-r--r--tests/core/math/test_vector3i.h4
-rw-r--r--tests/core/math/test_vector4.h10
-rw-r--r--tests/core/math/test_vector4i.h4
-rw-r--r--tests/core/string/test_string.h8
-rw-r--r--tests/scene/test_animation.h82
-rw-r--r--tests/scene/test_audio_stream_wav.h2
-rw-r--r--tests/scene/test_curve.h54
-rw-r--r--tests/scene/test_primitives.h40
-rw-r--r--tests/scene/test_text_edit.h34
49 files changed, 326 insertions, 273 deletions
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index 41585943b3..0863dea053 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -31,6 +31,7 @@
#include "class_db.h"
#include "core/config/engine.h"
+#include "core/object/script_language.h"
#include "core/os/mutex.h"
#include "core/version.h"
@@ -376,7 +377,12 @@ bool ClassDB::is_virtual(const StringName &p_class) {
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
- ERR_FAIL_COND_V_MSG(!ti, false, "Cannot get class '" + String(p_class) + "'.");
+ if (!ti) {
+ if (!ScriptServer::is_global_class(p_class)) {
+ ERR_FAIL_V_MSG(false, "Cannot get class '" + String(p_class) + "'.");
+ }
+ return false;
+ }
#ifdef TOOLS_ENABLED
if (ti->api == API_EDITOR && !Engine::get_singleton()->is_editor_hint()) {
return false;
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index c86c8316fe..c6cc4cc4ac 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -1180,9 +1180,14 @@ Vector<String> String::split(const String &p_splitter, bool p_allow_empty, int p
int len = length();
while (true) {
- int end = find(p_splitter, from);
- if (end < 0) {
- end = len;
+ int end;
+ if (p_splitter.is_empty()) {
+ end = from + 1;
+ } else {
+ end = find(p_splitter, from);
+ if (end < 0) {
+ end = len;
+ }
}
if (p_allow_empty || (end > from)) {
if (p_maxsplit <= 0) {
@@ -1223,7 +1228,15 @@ Vector<String> String::rsplit(const String &p_splitter, bool p_allow_empty, int
break;
}
- int left_edge = rfind(p_splitter, remaining_len - p_splitter.length());
+ int left_edge;
+ if (p_splitter.is_empty()) {
+ left_edge = remaining_len - 1;
+ if (left_edge == 0) {
+ left_edge--; // Skip to the < 0 condition.
+ }
+ } else {
+ left_edge = rfind(p_splitter, remaining_len - p_splitter.length());
+ }
if (left_edge < 0) {
// no more splitters, we're done
diff --git a/core/string/ustring.h b/core/string/ustring.h
index 4b6568a502..8af74584f3 100644
--- a/core/string/ustring.h
+++ b/core/string/ustring.h
@@ -345,8 +345,8 @@ public:
String get_slice(String p_splitter, int p_slice) const;
String get_slicec(char32_t p_splitter, int p_slice) const;
- Vector<String> split(const String &p_splitter, bool p_allow_empty = true, int p_maxsplit = 0) const;
- Vector<String> rsplit(const String &p_splitter, bool p_allow_empty = true, int p_maxsplit = 0) const;
+ Vector<String> split(const String &p_splitter = "", bool p_allow_empty = true, int p_maxsplit = 0) const;
+ Vector<String> rsplit(const String &p_splitter = "", bool p_allow_empty = true, int p_maxsplit = 0) const;
Vector<String> split_spaces() const;
Vector<float> split_floats(const String &p_splitter, bool p_allow_empty = true) const;
Vector<float> split_floats_mk(const Vector<String> &p_splitters, bool p_allow_empty = true) const;
diff --git a/core/variant/callable.h b/core/variant/callable.h
index 0305dc55c3..32770bd663 100644
--- a/core/variant/callable.h
+++ b/core/variant/callable.h
@@ -73,6 +73,16 @@ public:
void call_deferredp(const Variant **p_arguments, int p_argcount) const;
Variant callv(const Array &p_arguments) const;
+ template <typename... VarArgs>
+ void call_deferred(VarArgs... p_args) const {
+ Variant args[sizeof...(p_args) + 1] = { p_args..., 0 }; // +1 makes sure zero sized arrays are also supported.
+ const Variant *argptrs[sizeof...(p_args) + 1];
+ for (uint32_t i = 0; i < sizeof...(p_args); i++) {
+ argptrs[i] = &args[i];
+ }
+ return call_deferredp(sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
+ }
+
Error rpcp(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const;
_FORCE_INLINE_ bool is_null() const {
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 7da46a2d05..91af2bab85 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1509,8 +1509,8 @@ static void _register_variant_builtin_methods() {
bind_method(String, to_camel_case, sarray(), varray());
bind_method(String, to_pascal_case, sarray(), varray());
bind_method(String, to_snake_case, sarray(), varray());
- bind_method(String, split, sarray("delimiter", "allow_empty", "maxsplit"), varray(true, 0));
- bind_method(String, rsplit, sarray("delimiter", "allow_empty", "maxsplit"), varray(true, 0));
+ bind_method(String, split, sarray("delimiter", "allow_empty", "maxsplit"), varray("", true, 0));
+ bind_method(String, rsplit, sarray("delimiter", "allow_empty", "maxsplit"), varray("", true, 0));
bind_method(String, split_floats, sarray("delimiter", "allow_empty"), varray(true));
bind_method(String, join, sarray("parts"), varray());
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index 1ee91b91d2..b0b4f74b46 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -634,11 +634,11 @@
</method>
<method name="rsplit" qualifiers="const">
<return type="PackedStringArray" />
- <param index="0" name="delimiter" type="String" />
+ <param index="0" name="delimiter" type="String" default="&quot;&quot;" />
<param index="1" name="allow_empty" type="bool" default="true" />
<param index="2" name="maxsplit" type="int" default="0" />
<description>
- Splits the string by a [param delimiter] string and returns an array of the substrings, starting from right.
+ Splits the string by a [param delimiter] string and returns an array of the substrings, starting from right. If [param delimiter] is an empty string, each substring will be a single character.
The splits in the returned array are sorted in the same order as the original string, from left to right.
If [param allow_empty] is [code]true[/code], and there are two adjacent delimiters in the string, it will add an empty string to the array of substrings at this position.
If [param maxsplit] is specified, it defines the number of splits to do from the right up to [param maxsplit]. The default value of 0 means that all items are split, thus giving the same result as [method split].
@@ -710,11 +710,11 @@
</method>
<method name="split" qualifiers="const">
<return type="PackedStringArray" />
- <param index="0" name="delimiter" type="String" />
+ <param index="0" name="delimiter" type="String" default="&quot;&quot;" />
<param index="1" name="allow_empty" type="bool" default="true" />
<param index="2" name="maxsplit" type="int" default="0" />
<description>
- Splits the string by a [param delimiter] string and returns an array of the substrings. The [param delimiter] can be of any length.
+ Splits the string by a [param delimiter] string and returns an array of the substrings. The [param delimiter] can be of any length. If [param delimiter] is an empty string, each substring will be a single character.
If [param allow_empty] is [code]true[/code], and there are two adjacent delimiters in the string, it will add an empty string to the array of substrings at this position.
If [param maxsplit] is specified, it defines the number of splits to do from the left up to [param maxsplit]. The default value of [code]0[/code] means that all items are split.
If you need only one element from the array at a specific index, [method get_slice] is a more performant option.
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 1fe31a3c47..66754932ad 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -7751,7 +7751,7 @@ void RenderingDeviceVulkan::draw_list_bind_index_array(DrawListID p_list, RID p_
dl->validation.index_array_size = index_array->indices;
dl->validation.index_array_offset = index_array->offset;
- vkCmdBindIndexBuffer(dl->command_buffer, index_array->buffer, index_array->offset, index_array->index_type);
+ vkCmdBindIndexBuffer(dl->command_buffer, index_array->buffer, 0, index_array->index_type);
}
void RenderingDeviceVulkan::draw_list_set_line_width(DrawListID p_list, float p_width) {
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
index 9b1ff78727..3b9d6c18eb 100644
--- a/editor/action_map_editor.cpp
+++ b/editor/action_map_editor.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "editor/action_map_editor.h"
+
#include "editor/editor_scale.h"
#include "editor/event_listener_line_edit.h"
#include "editor/input_event_configuration_dialog.h"
@@ -395,15 +396,9 @@ void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_info
action_tree->clear();
TreeItem *root = action_tree->create_item();
- int uneditable_count = 0;
-
for (int i = 0; i < actions_cache.size(); i++) {
ActionInfo action_info = actions_cache[i];
- if (!action_info.editable) {
- uneditable_count++;
- }
-
const Array events = action_info.action["events"];
if (!_should_display_action(action_info.name, events)) {
continue;
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 6142856f75..545b0895b0 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -284,12 +284,12 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String
bool can_instantiate = (p_type_category == TypeCategory::CPP_TYPE && ClassDB::can_instantiate(p_type)) ||
p_type_category == TypeCategory::OTHER_TYPE;
- if (!can_instantiate) {
- r_item->set_custom_color(0, search_options->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ if (can_instantiate && !ClassDB::is_virtual(p_type)) {
+ r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback));
+ } else {
r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, "NodeDisabled"));
+ r_item->set_custom_color(0, search_options->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
r_item->set_selectable(0, false);
- } else {
- r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback));
}
bool is_deprecated = EditorHelp::get_doc_data()->class_list[p_type].is_deprecated;
diff --git a/editor/editor_command_palette.cpp b/editor/editor_command_palette.cpp
index a0913265eb..3f93fa1f41 100644
--- a/editor/editor_command_palette.cpp
+++ b/editor/editor_command_palette.cpp
@@ -226,7 +226,7 @@ void EditorCommandPalette::_add_command(String p_command_name, String p_key_name
void EditorCommandPalette::execute_command(String &p_command_key) {
ERR_FAIL_COND_MSG(!commands.has(p_command_key), p_command_key + " not found.");
commands[p_command_key].last_used = OS::get_singleton()->get_unix_time();
- commands[p_command_key].callable.call_deferredp(nullptr, 0);
+ commands[p_command_key].callable.call_deferred();
_save_history();
}
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index d76dce0c1d..d71976a1af 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -1045,7 +1045,6 @@ void EditorPropertyLayersGrid::_notification(int p_what) {
const int vofs = (grid_size.height - h) / 2;
int layer_index = 0;
- int block_index = 0;
Point2 arrow_pos;
@@ -1112,8 +1111,6 @@ void EditorPropertyLayersGrid::_notification(int p_what) {
break;
}
}
-
- ++block_index;
}
if ((expansion_rows != prev_expansion_rows) && expanded) {
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index 7c1e3e63ef..0b38996b2d 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -570,13 +570,17 @@ void EditorResourcePicker::_get_allowed_types(bool p_with_convert, HashSet<Strin
for (int i = 0; i < size; i++) {
String base = allowed_types[i].strip_edges();
- p_vector->insert(base);
+ if (!ClassDB::is_virtual(base)) {
+ p_vector->insert(base);
+ }
// If we hit a familiar base type, take all the data from cache.
if (allowed_types_cache.has(base)) {
List<StringName> allowed_subtypes = allowed_types_cache[base];
for (const StringName &subtype_name : allowed_subtypes) {
- p_vector->insert(subtype_name);
+ if (!ClassDB::is_virtual(subtype_name)) {
+ p_vector->insert(subtype_name);
+ }
}
} else {
List<StringName> allowed_subtypes;
@@ -586,13 +590,17 @@ void EditorResourcePicker::_get_allowed_types(bool p_with_convert, HashSet<Strin
ClassDB::get_inheriters_from_class(base, &inheriters);
}
for (const StringName &subtype_name : inheriters) {
- p_vector->insert(subtype_name);
+ if (!ClassDB::is_virtual(subtype_name)) {
+ p_vector->insert(subtype_name);
+ }
allowed_subtypes.push_back(subtype_name);
}
for (const StringName &subtype_name : global_classes) {
if (EditorNode::get_editor_data().script_class_is_parent(subtype_name, base)) {
- p_vector->insert(subtype_name);
+ if (!ClassDB::is_virtual(subtype_name)) {
+ p_vector->insert(subtype_name);
+ }
allowed_subtypes.push_back(subtype_name);
}
}
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index 599df12bd3..41d5d1b0d2 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -57,8 +57,11 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
args.push_back(resource_path.replace(" ", "%20"));
}
- args.push_back("--remote-debug");
- args.push_back(EditorDebuggerNode::get_singleton()->get_server_uri());
+ const String debug_uri = EditorDebuggerNode::get_singleton()->get_server_uri();
+ if (debug_uri.size()) {
+ args.push_back("--remote-debug");
+ args.push_back(debug_uri);
+ }
args.push_back("--editor-pid");
args.push_back(itos(OS::get_singleton()->get_process_id()));
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index a2bd1223a9..b7605d8e2b 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -422,8 +422,7 @@ void FindInFilesDialog::set_find_in_files_mode(FindInFilesMode p_mode) {
}
String FindInFilesDialog::get_search_text() const {
- String text = _search_text_line_edit->get_text();
- return text.strip_edges();
+ return _search_text_line_edit->get_text();
}
String FindInFilesDialog::get_replace_text() const {
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 8ede88a888..a6a0eef11b 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -1276,14 +1276,12 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
} break;
}
- int idx = 0;
for (const Ref<Shape3D> &E : shapes) {
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E);
base->add_child(cshape, true);
cshape->set_owner(base->get_owner());
- idx++;
}
}
}
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 1d6f41d4c4..e6e32f882f 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -2068,12 +2068,9 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
}
}
- int index = 0;
for (CanvasItem *ci : drag_selection) {
Transform2D xform = ci->get_global_transform_with_canvas().affine_inverse() * ci->get_transform();
-
ci->_edit_set_position(ci->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos));
- index++;
}
return true;
}
@@ -2191,12 +2188,9 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
new_pos = previous_pos + (drag_to - drag_from);
}
- int index = 0;
for (CanvasItem *ci : drag_selection) {
Transform2D xform = ci->get_global_transform_with_canvas().affine_inverse() * ci->get_transform();
-
ci->_edit_set_position(ci->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos));
- index++;
}
}
return true;
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index a7a8d526d0..b0c8597adf 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -242,7 +242,7 @@ void TextureRegionEditor::_region_draw() {
hscroll->set_value((hscroll->get_min() + hscroll->get_max() - hscroll->get_page()) / 2);
vscroll->set_value((vscroll->get_min() + vscroll->get_max() - vscroll->get_page()) / 2);
// This ensures that the view is updated correctly.
- callable_mp(this, &TextureRegionEditor::_pan_callback).bind(Vector2(1, 0)).call_deferredp(nullptr, 0);
+ callable_mp(this, &TextureRegionEditor::_pan_callback).bind(Vector2(1, 0)).call_deferred();
request_center = false;
}
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 588746bf64..b2a2566ad4 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -546,7 +546,6 @@ private:
Vector<String> failed_files;
- int idx = 0;
while (ret == UNZ_OK) {
//get filename
unz_file_info info;
@@ -585,7 +584,6 @@ private:
}
}
- idx++;
ret = unzGoToNextFile(pkg);
}
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index cc09c3a432..08c0f0f708 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -275,7 +275,6 @@ String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must
bool found = false;
bool match = false;
- int index = 0;
for (const String &E : extensions) {
if (E.nocasecmp_to(extension) == 0) {
found = true;
@@ -284,7 +283,6 @@ String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must
}
break;
}
- index++;
}
if (!found) {
@@ -373,7 +371,7 @@ void ScriptCreateDialog::_create_new() {
const ScriptLanguage::ScriptTemplate sinfo = _get_current_template();
String parent_class = parent_name->get_text();
- if (!ClassDB::class_exists(parent_class) && !ScriptServer::is_global_class(parent_class)) {
+ if (!parent_name->get_text().is_quoted() && !ClassDB::class_exists(parent_class) && !ScriptServer::is_global_class(parent_class)) {
// If base is a custom type, replace with script path instead.
const EditorData::CustomType *type = EditorNode::get_editor_data().get_custom_type_by_name(parent_class);
ERR_FAIL_NULL(type);
diff --git a/platform/android/android_keys_utils.h b/platform/android/android_keys_utils.h
index 5ec3ee17aa..bc633aeade 100644
--- a/platform/android/android_keys_utils.h
+++ b/platform/android/android_keys_utils.h
@@ -43,7 +43,6 @@ struct AndroidGodotCodePair {
static AndroidGodotCodePair android_godot_code_pairs[] = {
{ AKEYCODE_UNKNOWN, Key::UNKNOWN }, // (0) Unknown key code.
- { AKEYCODE_HOME, Key::HOME }, // (3) Home key.
{ AKEYCODE_BACK, Key::BACK }, // (4) Back key.
{ AKEYCODE_0, Key::KEY_0 }, // (7) '0' key.
{ AKEYCODE_1, Key::KEY_1 }, // (8) '1' key.
@@ -63,6 +62,7 @@ static AndroidGodotCodePair android_godot_code_pairs[] = {
{ AKEYCODE_DPAD_RIGHT, Key::RIGHT }, // (22) Directional Pad Right key.
{ AKEYCODE_VOLUME_UP, Key::VOLUMEUP }, // (24) Volume Up key.
{ AKEYCODE_VOLUME_DOWN, Key::VOLUMEDOWN }, // (25) Volume Down key.
+ { AKEYCODE_POWER, Key::STANDBY }, // (26) Power key.
{ AKEYCODE_CLEAR, Key::CLEAR }, // (28) Clear key.
{ AKEYCODE_A, Key::A }, // (29) 'A' key.
{ AKEYCODE_B, Key::B }, // (30) 'B' key.
@@ -98,6 +98,7 @@ static AndroidGodotCodePair android_godot_code_pairs[] = {
{ AKEYCODE_SHIFT_RIGHT, Key::SHIFT }, // (60) Right Shift modifier key.
{ AKEYCODE_TAB, Key::TAB }, // (61) Tab key.
{ AKEYCODE_SPACE, Key::SPACE }, // (62) Space key.
+ { AKEYCODE_ENVELOPE, Key::LAUNCHMAIL }, // (65) Envelope special function key.
{ AKEYCODE_ENTER, Key::ENTER }, // (66) Enter key.
{ AKEYCODE_DEL, Key::BACKSPACE }, // (67) Backspace key.
{ AKEYCODE_GRAVE, Key::QUOTELEFT }, // (68) '`' (backtick) key.
@@ -114,6 +115,7 @@ static AndroidGodotCodePair android_godot_code_pairs[] = {
{ AKEYCODE_MENU, Key::MENU }, // (82) Menu key.
{ AKEYCODE_SEARCH, Key::SEARCH }, // (84) Search key.
{ AKEYCODE_MEDIA_STOP, Key::MEDIASTOP }, // (86) Stop media key.
+ { AKEYCODE_MEDIA_NEXT, Key::MEDIANEXT }, // (87) Play Next media key.
{ AKEYCODE_MEDIA_PREVIOUS, Key::MEDIAPREVIOUS }, // (88) Play Previous media key.
{ AKEYCODE_PAGE_UP, Key::PAGEUP }, // (92) Page Up key.
{ AKEYCODE_PAGE_DOWN, Key::PAGEDOWN }, // (93) Page Down key.
@@ -127,6 +129,8 @@ static AndroidGodotCodePair android_godot_code_pairs[] = {
{ AKEYCODE_META_RIGHT, Key::META }, // (118) Right Meta modifier key.
{ AKEYCODE_SYSRQ, Key::PRINT }, // (120) System Request / Print Screen key.
{ AKEYCODE_BREAK, Key::PAUSE }, // (121) Break / Pause key.
+ { AKEYCODE_MOVE_HOME, Key::HOME }, // (122) Home Movement key.
+ { AKEYCODE_MOVE_END, Key::END }, // (123) End Movement key.
{ AKEYCODE_INSERT, Key::INSERT }, // (124) Insert key.
{ AKEYCODE_FORWARD, Key::FORWARD }, // (125) Forward key.
{ AKEYCODE_MEDIA_PLAY, Key::MEDIAPLAY }, // (126) Play media key.
diff --git a/platform/web/display_server_web.cpp b/platform/web/display_server_web.cpp
index 2c1e87e663..5a1a56b9da 100644
--- a/platform/web/display_server_web.cpp
+++ b/platform/web/display_server_web.cpp
@@ -758,10 +758,8 @@ DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode
godot_js_os_request_quit_cb(request_quit_callback);
#ifdef GLES3_ENABLED
- // TODO "vulkan" defaults to webgl2 for now.
- bool wants_webgl2 = p_rendering_driver == "opengl3" || p_rendering_driver == "vulkan";
- bool webgl2_init_failed = wants_webgl2 && !godot_js_display_has_webgl(2);
- if (wants_webgl2 && !webgl2_init_failed) {
+ bool webgl2_inited = false;
+ if (godot_js_display_has_webgl(2)) {
EmscriptenWebGLContextAttributes attributes;
emscripten_webgl_init_context_attributes(&attributes);
attributes.alpha = OS::get_singleton()->is_layered_allowed();
@@ -770,20 +768,17 @@ DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode
attributes.explicitSwapControl = true;
webgl_ctx = emscripten_webgl_create_context(canvas_id, &attributes);
- if (emscripten_webgl_make_context_current(webgl_ctx) != EMSCRIPTEN_RESULT_SUCCESS) {
- webgl2_init_failed = true;
- } else {
- if (!emscripten_webgl_enable_extension(webgl_ctx, "OVR_multiview2")) {
- // @todo Should we log this?
- }
- RasterizerGLES3::make_current();
- }
+ webgl2_inited = webgl_ctx && emscripten_webgl_make_context_current(webgl_ctx) == EMSCRIPTEN_RESULT_SUCCESS;
}
- if (webgl2_init_failed) {
+ if (webgl2_inited) {
+ if (!emscripten_webgl_enable_extension(webgl_ctx, "OVR_multiview2")) {
+ print_verbose("Failed to enable WebXR extension.");
+ }
+ RasterizerGLES3::make_current();
+
+ } else {
OS::get_singleton()->alert("Your browser does not seem to support WebGL2. Please update your browser version.",
"Unable to initialize video driver");
- }
- if (!wants_webgl2 || webgl2_init_failed) {
RasterizerDummy::make_current();
}
#else
diff --git a/platform/web/js/engine/config.js b/platform/web/js/engine/config.js
index 41be7b2512..4560f12b49 100644
--- a/platform/web/js/engine/config.js
+++ b/platform/web/js/engine/config.js
@@ -275,7 +275,7 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
'print': this.onPrint,
'printErr': this.onPrintError,
'thisProgram': this.executable,
- 'noExitRuntime': true,
+ 'noExitRuntime': false,
'dynamicLibraries': [`${loadPath}.side.wasm`],
'instantiateWasm': function (imports, onSuccess) {
function done(result) {
diff --git a/platform/web/web_main.cpp b/platform/web/web_main.cpp
index a76b98f4e9..fce782b546 100644
--- a/platform/web/web_main.cpp
+++ b/platform/web/web_main.cpp
@@ -41,30 +41,25 @@
static OS_Web *os = nullptr;
static uint64_t target_ticks = 0;
+static bool main_started = false;
+static bool shutdown_complete = false;
void exit_callback() {
- emscripten_cancel_main_loop(); // After this, we can exit!
- Main::cleanup();
+ if (!shutdown_complete) {
+ return; // Still waiting.
+ }
+ if (main_started) {
+ Main::cleanup();
+ main_started = false;
+ }
int exit_code = OS_Web::get_singleton()->get_exit_code();
memdelete(os);
os = nullptr;
- emscripten_force_exit(exit_code); // No matter that we call cancel_main_loop, regular "exit" will not work, forcing.
+ emscripten_force_exit(exit_code); // Exit runtime.
}
void cleanup_after_sync() {
- emscripten_set_main_loop(exit_callback, -1, false);
-}
-
-void early_cleanup() {
- emscripten_cancel_main_loop(); // After this, we can exit!
- int exit_code = OS_Web::get_singleton()->get_exit_code();
- memdelete(os);
- os = nullptr;
- emscripten_force_exit(exit_code); // No matter that we call cancel_main_loop, regular "exit" will not work, forcing.
-}
-
-void early_cleanup_sync() {
- emscripten_set_main_loop(early_cleanup, -1, false);
+ shutdown_complete = true;
}
void main_loop_callback() {
@@ -87,7 +82,8 @@ void main_loop_callback() {
target_ticks += (uint64_t)(1000000 / max_fps);
}
if (os->main_loop_iterate()) {
- emscripten_cancel_main_loop(); // Cancel current loop and wait for cleanup_after_sync.
+ emscripten_cancel_main_loop(); // Cancel current loop and set the cleanup one.
+ emscripten_set_main_loop(exit_callback, -1, false);
godot_js_os_finish_async(cleanup_after_sync);
}
}
@@ -109,10 +105,14 @@ extern EMSCRIPTEN_KEEPALIVE int godot_web_main(int argc, char *argv[]) {
}
os->set_exit_code(exit_code);
// Will only exit after sync.
- godot_js_os_finish_async(early_cleanup_sync);
+ emscripten_set_main_loop(exit_callback, -1, false);
+ godot_js_os_finish_async(cleanup_after_sync);
return exit_code;
}
+ os->set_exit_code(0);
+ main_started = true;
+
// Ease up compatibility.
ResourceLoader::set_abort_on_missing_resources(false);
diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp
index a98be62dfa..ca23fe03a2 100644
--- a/scene/3d/collision_object_3d.cpp
+++ b/scene/3d/collision_object_3d.cpp
@@ -330,7 +330,7 @@ bool CollisionObject3D::_are_collision_shapes_visible() {
void CollisionObject3D::_update_shape_data(uint32_t p_owner) {
if (_are_collision_shapes_visible()) {
if (debug_shapes_to_update.is_empty()) {
- callable_mp(this, &CollisionObject3D::_update_debug_shapes).call_deferredp({}, 0);
+ callable_mp(this, &CollisionObject3D::_update_debug_shapes).call_deferred();
}
debug_shapes_to_update.insert(p_owner);
}
diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp
index f5d30c584f..ca7d1dfc1d 100644
--- a/scene/3d/xr_nodes.cpp
+++ b/scene/3d/xr_nodes.cpp
@@ -644,6 +644,12 @@ void XROrigin3D::set_current(bool p_enabled) {
origin_nodes[i]->set_current(false);
}
}
+
+ // update XRServer with our current position
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ xr_server->set_world_origin(get_global_transform());
} else {
bool found = false;
// We no longer have a current origin so find the first one we can make current
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 5f8f25154c..ea310f5a12 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -694,8 +694,8 @@ void CodeEdit::_backspace_internal(int p_caret) {
return;
}
- if (has_selection()) {
- delete_selection();
+ if (has_selection(p_caret)) {
+ delete_selection(p_caret);
return;
}
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 2cbece69f2..0940b4c07b 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -451,7 +451,7 @@ void OptionButton::_queue_refresh_cache() {
}
cache_refresh_pending = true;
- callable_mp(this, &OptionButton::_refresh_size_cache).call_deferredp(nullptr, 0);
+ callable_mp(this, &OptionButton::_refresh_size_cache).call_deferred();
}
void OptionButton::select(int p_idx) {
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index 07cb59aaee..1897612562 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -302,19 +302,12 @@ void DisplayServer::tts_post_utterance_event(TTSUtteranceEvent p_event, int p_id
case DisplayServer::TTS_UTTERANCE_ENDED:
case DisplayServer::TTS_UTTERANCE_CANCELED: {
if (utterance_callback[p_event].is_valid()) {
- Variant args[1];
- args[0] = p_id;
- const Variant *argp[] = { &args[0] };
- utterance_callback[p_event].call_deferredp(argp, 1); // Should be deferred, on some platforms utterance events can be called from different threads in a rapid succession.
+ utterance_callback[p_event].call_deferred(p_id); // Should be deferred, on some platforms utterance events can be called from different threads in a rapid succession.
}
} break;
case DisplayServer::TTS_UTTERANCE_BOUNDARY: {
if (utterance_callback[p_event].is_valid()) {
- Variant args[2];
- args[0] = p_pos;
- args[1] = p_id;
- const Variant *argp[] = { &args[0], &args[1] };
- utterance_callback[p_event].call_deferredp(argp, 2); // Should be deferred, on some platforms utterance events can be called from different threads in a rapid succession.
+ utterance_callback[p_event].call_deferred(p_pos, p_id); // Should be deferred, on some platforms utterance events can be called from different threads in a rapid succession.
}
} break;
default:
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index 41d4ca8d5e..16d382a5f3 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -1964,7 +1964,7 @@ void RendererCanvasCull::update_visibility_notifiers() {
if (!visibility_notifier->enter_callable.is_null()) {
if (RSG::threaded) {
- visibility_notifier->enter_callable.call_deferredp(nullptr, 0);
+ visibility_notifier->enter_callable.call_deferred();
} else {
Callable::CallError ce;
Variant ret;
@@ -1977,7 +1977,7 @@ void RendererCanvasCull::update_visibility_notifiers() {
if (!visibility_notifier->exit_callable.is_null()) {
if (RSG::threaded) {
- visibility_notifier->exit_callable.call_deferredp(nullptr, 0);
+ visibility_notifier->exit_callable.call_deferred();
} else {
Callable::CallError ce;
Variant ret;
diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.cpp b/servers/rendering/renderer_rd/storage_rd/utilities.cpp
index 4048c46d28..625f089f66 100644
--- a/servers/rendering/renderer_rd/storage_rd/utilities.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/utilities.cpp
@@ -200,7 +200,7 @@ void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_de
if (p_enter) {
if (!vn->enter_callback.is_null()) {
if (p_deferred) {
- vn->enter_callback.call_deferredp(nullptr, 0);
+ vn->enter_callback.call_deferred();
} else {
Variant r;
Callable::CallError ce;
@@ -210,7 +210,7 @@ void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_de
} else {
if (!vn->exit_callback.is_null()) {
if (p_deferred) {
- vn->exit_callback.call_deferredp(nullptr, 0);
+ vn->exit_callback.call_deferred();
} else {
Variant r;
Callable::CallError ce;
diff --git a/tests/core/io/test_json.h b/tests/core/io/test_json.h
index 478cf1766e..af450da3b8 100644
--- a/tests/core/io/test_json.h
+++ b/tests/core/io/test_json.h
@@ -83,7 +83,7 @@ TEST_CASE("[JSON] Parsing single data types") {
json.get_error_line() == 0,
"Parsing a floating-point number as JSON should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(json.get_data()), 0.123456),
+ double(json.get_data()) == doctest::Approx(0.123456),
"Parsing a floating-point number as JSON should return the expected value.");
json.parse("\"hello\"");
diff --git a/tests/core/math/test_aabb.h b/tests/core/math/test_aabb.h
index ebaf441abf..23969556be 100644
--- a/tests/core/math/test_aabb.h
+++ b/tests/core/math/test_aabb.h
@@ -91,7 +91,7 @@ TEST_CASE("[AABB] Basic setters") {
TEST_CASE("[AABB] Volume getters") {
AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
CHECK_MESSAGE(
- Math::is_equal_approx(aabb.get_volume(), 120),
+ aabb.get_volume() == doctest::Approx(120),
"get_volume() should return the expected value with positive size.");
CHECK_MESSAGE(
aabb.has_volume(),
@@ -99,17 +99,17 @@ TEST_CASE("[AABB] Volume getters") {
aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(-4, 5, 6));
CHECK_MESSAGE(
- Math::is_equal_approx(aabb.get_volume(), -120),
+ aabb.get_volume() == doctest::Approx(-120),
"get_volume() should return the expected value with negative size (1 component).");
aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(-4, -5, 6));
CHECK_MESSAGE(
- Math::is_equal_approx(aabb.get_volume(), 120),
+ aabb.get_volume() == doctest::Approx(120),
"get_volume() should return the expected value with negative size (2 components).");
aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(-4, -5, -6));
CHECK_MESSAGE(
- Math::is_equal_approx(aabb.get_volume(), -120),
+ aabb.get_volume() == doctest::Approx(-120),
"get_volume() should return the expected value with negative size (3 components).");
aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 0, 6));
diff --git a/tests/core/math/test_basis.h b/tests/core/math/test_basis.h
index a4099ebf7d..dce9d5cec3 100644
--- a/tests/core/math/test_basis.h
+++ b/tests/core/math/test_basis.h
@@ -223,7 +223,7 @@ TEST_CASE("[Basis] Set axis angle") {
// Testing the singularity when the angle is 180°.
Basis singularityPi(-1, 0, 0, 0, 1, 0, 0, 0, -1);
singularityPi.get_axis_angle(axis, angle);
- CHECK(Math::is_equal_approx(angle, pi));
+ CHECK(angle == doctest::Approx(pi));
// Testing reversing the an axis (of an 30° angle).
float cos30deg = Math::cos(Math::deg_to_rad((real_t)30.0));
@@ -231,17 +231,17 @@ TEST_CASE("[Basis] Set axis angle") {
Basis z_negative(cos30deg, 0.5, 0, -0.5, cos30deg, 0, 0, 0, 1);
z_positive.get_axis_angle(axis, angle);
- CHECK(Math::is_equal_approx(angle, Math::deg_to_rad((real_t)30.0)));
+ CHECK(angle == doctest::Approx(Math::deg_to_rad((real_t)30.0)));
CHECK(axis == Vector3(0, 0, 1));
z_negative.get_axis_angle(axis, angle);
- CHECK(Math::is_equal_approx(angle, Math::deg_to_rad((real_t)30.0)));
+ CHECK(angle == doctest::Approx(Math::deg_to_rad((real_t)30.0)));
CHECK(axis == Vector3(0, 0, -1));
// Testing a rotation of 90° on x-y-z.
Basis x90deg(1, 0, 0, 0, 0, -1, 0, 1, 0);
x90deg.get_axis_angle(axis, angle);
- CHECK(Math::is_equal_approx(angle, pi / (real_t)2));
+ CHECK(angle == doctest::Approx(pi / (real_t)2));
CHECK(axis == Vector3(1, 0, 0));
Basis y90deg(0, 0, 1, 0, 1, 0, -1, 0, 0);
@@ -255,7 +255,7 @@ TEST_CASE("[Basis] Set axis angle") {
// Regression test: checks that the method returns a small angle (not 0).
Basis tiny(1, 0, 0, 0, 0.9999995, -0.001, 0, 001, 0.9999995); // The min angle possible with float is 0.001rad.
tiny.get_axis_angle(axis, angle);
- CHECK(Math::is_equal_approx(angle, (real_t)0.001, (real_t)0.0001));
+ CHECK(angle == doctest::Approx(0.001).epsilon(0.0001));
// Regression test: checks that the method returns an angle which is a number (not NaN)
Basis bugNan(1.00000024, 0, 0.000100001693, 0, 1, 0, -0.000100009143, 0, 1.00000024);
diff --git a/tests/core/math/test_color.h b/tests/core/math/test_color.h
index 51c3bc8bdc..c6550778e8 100644
--- a/tests/core/math/test_color.h
+++ b/tests/core/math/test_color.h
@@ -101,13 +101,13 @@ TEST_CASE("[Color] Reading methods") {
const Color dark_blue = Color(0, 0, 0.5, 0.4);
CHECK_MESSAGE(
- Math::is_equal_approx(dark_blue.get_h(), 240.0f / 360.0f),
+ dark_blue.get_h() == doctest::Approx(240.0f / 360.0f),
"The returned HSV hue should match the expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(dark_blue.get_s(), 1.0f),
+ dark_blue.get_s() == doctest::Approx(1.0f),
"The returned HSV saturation should match the expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(dark_blue.get_v(), 0.5f),
+ dark_blue.get_v() == doctest::Approx(0.5f),
"The returned HSV value should match the expected value.");
}
diff --git a/tests/core/math/test_expression.h b/tests/core/math/test_expression.h
index 6e3be541b0..9734fd9f36 100644
--- a/tests/core/math/test_expression.h
+++ b/tests/core/math/test_expression.h
@@ -83,42 +83,42 @@ TEST_CASE("[Expression] Floating-point arithmetic") {
expression.parse("-123.456") == OK,
"Float identity should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), -123.456),
+ double(expression.execute()) == doctest::Approx(-123.456),
"Float identity should return the expected result.");
CHECK_MESSAGE(
expression.parse("2.0 + 3.0") == OK,
"Float addition should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 5),
+ double(expression.execute()) == doctest::Approx(5),
"Float addition should return the expected result.");
CHECK_MESSAGE(
expression.parse("3.0 / 10") == OK,
"Float / integer division should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 0.3),
+ double(expression.execute()) == doctest::Approx(0.3),
"Float / integer division should return the expected result.");
CHECK_MESSAGE(
expression.parse("3 / 10.0") == OK,
"Basic integer / float division should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 0.3),
+ double(expression.execute()) == doctest::Approx(0.3),
"Basic integer / float division should return the expected result.");
CHECK_MESSAGE(
expression.parse("3.0 / 10.0") == OK,
"Float / float division should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 0.3),
+ double(expression.execute()) == doctest::Approx(0.3),
"Float / float division should return the expected result.");
CHECK_MESSAGE(
expression.parse("2.5 * (6.0 + 14.25) / 2.0 - 5.12345") == OK,
"Float multiplication-addition-subtraction-division should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 20.18905),
+ double(expression.execute()) == doctest::Approx(20.18905),
"Float multiplication-addition-subtraction-division should return the expected result.");
}
@@ -129,7 +129,7 @@ TEST_CASE("[Expression] Scientific notation") {
expression.parse("2.e5") == OK,
"The expression should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 200'000),
+ double(expression.execute()) == doctest::Approx(200'000),
"The expression should return the expected result.");
// The middle "e" is ignored here.
@@ -137,14 +137,14 @@ TEST_CASE("[Expression] Scientific notation") {
expression.parse("2e5") == OK,
"The expression should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 2e5),
+ double(expression.execute()) == doctest::Approx(2e5),
"The expression should return the expected result.");
CHECK_MESSAGE(
expression.parse("2e.5") == OK,
"The expression should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 2),
+ double(expression.execute()) == doctest::Approx(2),
"The expression should return the expected result.");
}
@@ -176,7 +176,7 @@ TEST_CASE("[Expression] Built-in functions") {
expression.parse("snapped(sin(0.5), 0.01)") == OK,
"The expression should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 0.48),
+ double(expression.execute()) == doctest::Approx(0.48),
"`snapped(sin(0.5), 0.01)` should return the expected result.");
CHECK_MESSAGE(
diff --git a/tests/core/math/test_geometry_2d.h b/tests/core/math/test_geometry_2d.h
index 54893a0b87..27c9e7f58b 100644
--- a/tests/core/math/test_geometry_2d.h
+++ b/tests/core/math/test_geometry_2d.h
@@ -171,43 +171,43 @@ TEST_CASE("[Geometry2D] Segment intersection with circle") {
real_t one = 1.0;
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(0, 0), Vector2(4, 0), Vector2(0, 0), 1.0), one_quarter),
+ Geometry2D::segment_intersects_circle(Vector2(0, 0), Vector2(4, 0), Vector2(0, 0), 1.0) == doctest::Approx(one_quarter),
"Segment from inside to outside of circle should intersect it.");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(4, 0), Vector2(0, 0), Vector2(0, 0), 1.0), three_quarters),
+ Geometry2D::segment_intersects_circle(Vector2(4, 0), Vector2(0, 0), Vector2(0, 0), 1.0) == doctest::Approx(three_quarters),
"Segment from outside to inside of circle should intersect it.");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(-2, 0), Vector2(2, 0), Vector2(0, 0), 1.0), one_quarter),
+ Geometry2D::segment_intersects_circle(Vector2(-2, 0), Vector2(2, 0), Vector2(0, 0), 1.0) == doctest::Approx(one_quarter),
"Segment running through circle should intersect it.");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(2, 0), Vector2(-2, 0), Vector2(0, 0), 1.0), one_quarter),
+ Geometry2D::segment_intersects_circle(Vector2(2, 0), Vector2(-2, 0), Vector2(0, 0), 1.0) == doctest::Approx(one_quarter),
"Segment running through circle should intersect it.");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(0, 0), Vector2(1, 0), Vector2(0, 0), 1.0), one),
+ Geometry2D::segment_intersects_circle(Vector2(0, 0), Vector2(1, 0), Vector2(0, 0), 1.0) == doctest::Approx(one),
"Segment starting inside the circle and ending on the circle should intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(1, 0), Vector2(0, 0), Vector2(0, 0), 1.0), zero),
+ Geometry2D::segment_intersects_circle(Vector2(1, 0), Vector2(0, 0), Vector2(0, 0), 1.0) == doctest::Approx(zero),
"Segment starting on the circle and going inwards should intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(1, 0), Vector2(2, 0), Vector2(0, 0), 1.0), zero),
+ Geometry2D::segment_intersects_circle(Vector2(1, 0), Vector2(2, 0), Vector2(0, 0), 1.0) == doctest::Approx(zero),
"Segment starting on the circle and going outwards should intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(2, 0), Vector2(1, 0), Vector2(0, 0), 1.0), one),
+ Geometry2D::segment_intersects_circle(Vector2(2, 0), Vector2(1, 0), Vector2(0, 0), 1.0) == doctest::Approx(one),
"Segment starting outside the circle and ending on the circle intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(-1, 0), Vector2(1, 0), Vector2(0, 0), 2.0), minus_one),
+ Geometry2D::segment_intersects_circle(Vector2(-1, 0), Vector2(1, 0), Vector2(0, 0), 2.0) == doctest::Approx(minus_one),
"Segment completely within the circle should not intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(1, 0), Vector2(-1, 0), Vector2(0, 0), 2.0), minus_one),
+ Geometry2D::segment_intersects_circle(Vector2(1, 0), Vector2(-1, 0), Vector2(0, 0), 2.0) == doctest::Approx(minus_one),
"Segment completely within the circle should not intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(2, 0), Vector2(3, 0), Vector2(0, 0), 1.0), minus_one),
+ Geometry2D::segment_intersects_circle(Vector2(2, 0), Vector2(3, 0), Vector2(0, 0), 1.0) == doctest::Approx(minus_one),
"Segment completely outside the circle should not intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(3, 0), Vector2(2, 0), Vector2(0, 0), 1.0), minus_one),
+ Geometry2D::segment_intersects_circle(Vector2(3, 0), Vector2(2, 0), Vector2(0, 0), 1.0) == doctest::Approx(minus_one),
"Segment completely outside the circle should not intersect it");
}
diff --git a/tests/core/math/test_rect2.h b/tests/core/math/test_rect2.h
index d784875c1c..9984823331 100644
--- a/tests/core/math/test_rect2.h
+++ b/tests/core/math/test_rect2.h
@@ -102,16 +102,16 @@ TEST_CASE("[Rect2] Basic setters") {
TEST_CASE("[Rect2] Area getters") {
CHECK_MESSAGE(
- Math::is_equal_approx(Rect2(0, 100, 1280, 720).get_area(), 921'600),
+ Rect2(0, 100, 1280, 720).get_area() == doctest::Approx(921'600),
"get_area() should return the expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(Rect2(0, 100, -1280, -720).get_area(), 921'600),
+ Rect2(0, 100, -1280, -720).get_area() == doctest::Approx(921'600),
"get_area() should return the expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(Rect2(0, 100, 1280, -720).get_area(), -921'600),
+ Rect2(0, 100, 1280, -720).get_area() == doctest::Approx(-921'600),
"get_area() should return the expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(Rect2(0, 100, -1280, 720).get_area(), -921'600),
+ Rect2(0, 100, -1280, 720).get_area() == doctest::Approx(-921'600),
"get_area() should return the expected value.");
CHECK_MESSAGE(
Math::is_zero_approx(Rect2(0, 100, 0, 720).get_area()),
diff --git a/tests/core/math/test_vector2.h b/tests/core/math/test_vector2.h
index f7e9259329..8f8fccd717 100644
--- a/tests/core/math/test_vector2.h
+++ b/tests/core/math/test_vector2.h
@@ -49,16 +49,16 @@ TEST_CASE("[Vector2] Angle methods") {
const Vector2 vector_x = Vector2(1, 0);
const Vector2 vector_y = Vector2(0, 1);
CHECK_MESSAGE(
- Math::is_equal_approx(vector_x.angle_to(vector_y), (real_t)Math_TAU / 4),
+ vector_x.angle_to(vector_y) == doctest::Approx((real_t)Math_TAU / 4),
"Vector2 angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_y.angle_to(vector_x), (real_t)-Math_TAU / 4),
+ vector_y.angle_to(vector_x) == doctest::Approx((real_t)-Math_TAU / 4),
"Vector2 angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_x.angle_to_point(vector_y), (real_t)Math_TAU * 3 / 8),
+ vector_x.angle_to_point(vector_y) == doctest::Approx((real_t)Math_TAU * 3 / 8),
"Vector2 angle_to_point should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_y.angle_to_point(vector_x), (real_t)-Math_TAU / 8),
+ vector_y.angle_to_point(vector_x) == doctest::Approx((real_t)-Math_TAU / 8),
"Vector2 angle_to_point should work as expected.");
}
@@ -113,10 +113,10 @@ TEST_CASE("[Vector2] Interpolation methods") {
Vector2(4, 6).slerp(Vector2(8, 10), 0.5).is_equal_approx(Vector2(5.9076470794008017626, 8.07918879020090480697)),
"Vector2 slerp should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.slerp(vector2, 0.5).length(), (real_t)4.31959610746631919),
+ vector1.slerp(vector2, 0.5).length() == doctest::Approx((real_t)4.31959610746631919),
"Vector2 slerp with different length input should return a vector with an interpolated length.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.angle_to(vector1.slerp(vector2, 0.5)) * 2, vector1.angle_to(vector2)),
+ vector1.angle_to(vector1.slerp(vector2, 0.5)) * 2 == doctest::Approx(vector1.angle_to(vector2)),
"Vector2 slerp with different length input should return a vector with an interpolated angle.");
CHECK_MESSAGE(
vector1.cubic_interpolate(vector2, Vector2(), Vector2(7, 7), 0.5) == Vector2(2.375, 3.5),
@@ -136,19 +136,19 @@ TEST_CASE("[Vector2] Length methods") {
vector1.length_squared() == 200,
"Vector2 length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.length(), 10 * (real_t)Math_SQRT2),
+ vector1.length() == doctest::Approx(10 * (real_t)Math_SQRT2),
"Vector2 length should work as expected.");
CHECK_MESSAGE(
vector2.length_squared() == 1300,
"Vector2 length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector2.length(), (real_t)36.05551275463989293119),
+ vector2.length() == doctest::Approx((real_t)36.05551275463989293119),
"Vector2 length should work as expected.");
CHECK_MESSAGE(
vector1.distance_squared_to(vector2) == 500,
"Vector2 distance_squared_to should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.distance_to(vector2), (real_t)22.36067977499789696409),
+ vector1.distance_to(vector2) == doctest::Approx((real_t)22.36067977499789696409),
"Vector2 distance_to should work as expected.");
}
@@ -294,7 +294,7 @@ TEST_CASE("[Vector2] Operators") {
TEST_CASE("[Vector2] Other methods") {
const Vector2 vector = Vector2(1.2, 3.4);
CHECK_MESSAGE(
- Math::is_equal_approx(vector.aspect(), (real_t)1.2 / (real_t)3.4),
+ vector.aspect() == doctest::Approx((real_t)1.2 / (real_t)3.4),
"Vector2 aspect should work as expected.");
CHECK_MESSAGE(
@@ -443,10 +443,10 @@ TEST_CASE("[Vector2] Linear algebra methods") {
vector_y.cross(vector_x) == -1,
"Vector2 cross product of Y and X should give negative 1.");
CHECK_MESSAGE(
- Math::is_equal_approx(a.cross(b), (real_t)-28.1),
+ a.cross(b) == doctest::Approx((real_t)-28.1),
"Vector2 cross should return expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(Vector2(-a.x, a.y).cross(Vector2(b.x, -b.y)), (real_t)-28.1),
+ Vector2(-a.x, a.y).cross(Vector2(b.x, -b.y)) == doctest::Approx((real_t)-28.1),
"Vector2 cross should return expected value.");
CHECK_MESSAGE(
@@ -459,10 +459,10 @@ TEST_CASE("[Vector2] Linear algebra methods") {
(vector_x * 10).dot(vector_x * 10) == 100.0,
"Vector2 dot product of same direction vectors should behave as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(a.dot(b), (real_t)57.3),
+ a.dot(b) == doctest::Approx((real_t)57.3),
"Vector2 dot should return expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(Vector2(-a.x, a.y).dot(Vector2(b.x, -b.y)), (real_t)-57.3),
+ Vector2(-a.x, a.y).dot(Vector2(b.x, -b.y)) == doctest::Approx((real_t)-57.3),
"Vector2 dot should return expected value.");
}
diff --git a/tests/core/math/test_vector2i.h b/tests/core/math/test_vector2i.h
index 49b0632e3c..c7a0dccdcc 100644
--- a/tests/core/math/test_vector2i.h
+++ b/tests/core/math/test_vector2i.h
@@ -79,13 +79,13 @@ TEST_CASE("[Vector2i] Length methods") {
vector1.length_squared() == 200,
"Vector2i length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.length(), 10 * Math_SQRT2),
+ vector1.length() == doctest::Approx(10 * Math_SQRT2),
"Vector2i length should work as expected.");
CHECK_MESSAGE(
vector2.length_squared() == 1300,
"Vector2i length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector2.length(), 36.05551275463989293119),
+ vector2.length() == doctest::Approx(36.05551275463989293119),
"Vector2i length should work as expected.");
}
@@ -127,7 +127,7 @@ TEST_CASE("[Vector2i] Operators") {
TEST_CASE("[Vector2i] Other methods") {
const Vector2i vector = Vector2i(1, 3);
CHECK_MESSAGE(
- Math::is_equal_approx(vector.aspect(), (real_t)1.0 / (real_t)3.0),
+ vector.aspect() == doctest::Approx((real_t)1.0 / (real_t)3.0),
"Vector2i aspect should work as expected.");
CHECK_MESSAGE(
diff --git a/tests/core/math/test_vector3.h b/tests/core/math/test_vector3.h
index 77d3a9d93c..89d73ee6de 100644
--- a/tests/core/math/test_vector3.h
+++ b/tests/core/math/test_vector3.h
@@ -52,26 +52,26 @@ TEST_CASE("[Vector3] Angle methods") {
const Vector3 vector_y = Vector3(0, 1, 0);
const Vector3 vector_yz = Vector3(0, 1, 1);
CHECK_MESSAGE(
- Math::is_equal_approx(vector_x.angle_to(vector_y), (real_t)Math_TAU / 4),
+ vector_x.angle_to(vector_y) == doctest::Approx((real_t)Math_TAU / 4),
"Vector3 angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_x.angle_to(vector_yz), (real_t)Math_TAU / 4),
+ vector_x.angle_to(vector_yz) == doctest::Approx((real_t)Math_TAU / 4),
"Vector3 angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_yz.angle_to(vector_x), (real_t)Math_TAU / 4),
+ vector_yz.angle_to(vector_x) == doctest::Approx((real_t)Math_TAU / 4),
"Vector3 angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_y.angle_to(vector_yz), (real_t)Math_TAU / 8),
+ vector_y.angle_to(vector_yz) == doctest::Approx((real_t)Math_TAU / 8),
"Vector3 angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_x.signed_angle_to(vector_y, vector_y), (real_t)Math_TAU / 4),
+ vector_x.signed_angle_to(vector_y, vector_y) == doctest::Approx((real_t)Math_TAU / 4),
"Vector3 signed_angle_to edge case should be positive.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_x.signed_angle_to(vector_yz, vector_y), (real_t)Math_TAU / -4),
+ vector_x.signed_angle_to(vector_yz, vector_y) == doctest::Approx((real_t)Math_TAU / -4),
"Vector3 signed_angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_yz.signed_angle_to(vector_x, vector_y), (real_t)Math_TAU / 4),
+ vector_yz.signed_angle_to(vector_x, vector_y) == doctest::Approx((real_t)Math_TAU / 4),
"Vector3 signed_angle_to should work as expected.");
}
@@ -130,10 +130,10 @@ TEST_CASE("[Vector3] Interpolation methods") {
Vector3(4, 6, 2).slerp(Vector3(8, 10, 3), 0.5).is_equal_approx(Vector3(5.90194219811429941053, 8.06758688849378394534, 2.558307894718317120038)),
"Vector3 slerp should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.slerp(vector2, 0.5).length(), (real_t)6.25831088708303172),
+ vector1.slerp(vector2, 0.5).length() == doctest::Approx((real_t)6.25831088708303172),
"Vector3 slerp with different length input should return a vector with an interpolated length.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.angle_to(vector1.slerp(vector2, 0.5)) * 2, vector1.angle_to(vector2)),
+ vector1.angle_to(vector1.slerp(vector2, 0.5)) * 2 == doctest::Approx(vector1.angle_to(vector2)),
"Vector3 slerp with different length input should return a vector with an interpolated angle.");
CHECK_MESSAGE(
vector1.cubic_interpolate(vector2, Vector3(), Vector3(7, 7, 7), 0.5) == Vector3(2.375, 3.5, 4.625),
@@ -153,19 +153,19 @@ TEST_CASE("[Vector3] Length methods") {
vector1.length_squared() == 300,
"Vector3 length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.length(), 10 * (real_t)Math_SQRT3),
+ vector1.length() == doctest::Approx(10 * (real_t)Math_SQRT3),
"Vector3 length should work as expected.");
CHECK_MESSAGE(
vector2.length_squared() == 2900,
"Vector3 length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector2.length(), (real_t)53.8516480713450403125),
+ vector2.length() == doctest::Approx((real_t)53.8516480713450403125),
"Vector3 length should work as expected.");
CHECK_MESSAGE(
vector1.distance_squared_to(vector2) == 1400,
"Vector3 distance_squared_to should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.distance_to(vector2), (real_t)37.41657386773941385584),
+ vector1.distance_to(vector2) == doctest::Approx((real_t)37.41657386773941385584),
"Vector3 distance_to should work as expected.");
}
@@ -473,10 +473,10 @@ TEST_CASE("[Vector3] Linear algebra methods") {
(vector_x * 10).dot(vector_x * 10) == 100.0,
"Vector3 dot product of same direction vectors should behave as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(a.dot(b), (real_t)75.24),
+ a.dot(b) == doctest::Approx((real_t)75.24),
"Vector3 dot should return expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(Vector3(-a.x, a.y, -a.z).dot(Vector3(b.x, -b.y, b.z)), (real_t)-75.24),
+ Vector3(-a.x, a.y, -a.z).dot(Vector3(b.x, -b.y, b.z)) == doctest::Approx((real_t)-75.24),
"Vector3 dot should return expected value.");
}
diff --git a/tests/core/math/test_vector3i.h b/tests/core/math/test_vector3i.h
index 2050b222d0..56578f99eb 100644
--- a/tests/core/math/test_vector3i.h
+++ b/tests/core/math/test_vector3i.h
@@ -82,13 +82,13 @@ TEST_CASE("[Vector3i] Length methods") {
vector1.length_squared() == 300,
"Vector3i length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.length(), 10 * Math_SQRT3),
+ vector1.length() == doctest::Approx(10 * Math_SQRT3),
"Vector3i length should work as expected.");
CHECK_MESSAGE(
vector2.length_squared() == 2900,
"Vector3i length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector2.length(), 53.8516480713450403125),
+ vector2.length() == doctest::Approx(53.8516480713450403125),
"Vector3i length should work as expected.");
}
diff --git a/tests/core/math/test_vector4.h b/tests/core/math/test_vector4.h
index b31db56f67..6ed85661cb 100644
--- a/tests/core/math/test_vector4.h
+++ b/tests/core/math/test_vector4.h
@@ -91,19 +91,19 @@ TEST_CASE("[Vector4] Length methods") {
vector1.length_squared() == 400,
"Vector4 length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.length(), 20),
+ vector1.length() == doctest::Approx(20),
"Vector4 length should work as expected.");
CHECK_MESSAGE(
vector2.length_squared() == 5400,
"Vector4 length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector2.length(), (real_t)73.484692283495),
+ vector2.length() == doctest::Approx((real_t)73.484692283495),
"Vector4 length should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.distance_to(vector2), (real_t)54.772255750517),
+ vector1.distance_to(vector2) == doctest::Approx((real_t)54.772255750517),
"Vector4 distance_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.distance_squared_to(vector2), 3000),
+ vector1.distance_squared_to(vector2) == doctest::Approx(3000),
"Vector4 distance_squared_to should work as expected.");
}
@@ -311,7 +311,7 @@ TEST_CASE("[Vector4] Linear algebra methods") {
(vector_x * 10).dot(vector_x * 10) == 100.0,
"Vector4 dot product of same direction vectors should behave as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx((vector1 * 2).dot(vector2 * 4), (real_t)-25.9 * 8),
+ (vector1 * 2).dot(vector2 * 4) == doctest::Approx((real_t)-25.9 * 8),
"Vector4 dot product should work as expected.");
}
diff --git a/tests/core/math/test_vector4i.h b/tests/core/math/test_vector4i.h
index 309162c3f7..30d38607dd 100644
--- a/tests/core/math/test_vector4i.h
+++ b/tests/core/math/test_vector4i.h
@@ -82,13 +82,13 @@ TEST_CASE("[Vector4i] Length methods") {
vector1.length_squared() == 400,
"Vector4i length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.length(), 20),
+ vector1.length() == doctest::Approx(20),
"Vector4i length should work as expected.");
CHECK_MESSAGE(
vector2.length_squared() == 5400,
"Vector4i length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector2.length(), 73.4846922835),
+ vector2.length() == doctest::Approx(73.4846922835),
"Vector4i length should work as expected.");
}
diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h
index cd1b421ce8..7e4e3aa9f0 100644
--- a/tests/core/string/test_string.h
+++ b/tests/core/string/test_string.h
@@ -485,6 +485,7 @@ TEST_CASE("[String] Splitting") {
const char *slices_l[3] = { "Mars", "Jupiter", "Saturn,Uranus" };
const char *slices_r[3] = { "Mars,Jupiter", "Saturn", "Uranus" };
+ const char *slices_3[4] = { "t", "e", "s", "t" };
l = s.split(",", true, 2);
CHECK(l.size() == 3);
@@ -498,6 +499,13 @@ TEST_CASE("[String] Splitting") {
CHECK(l[i] == slices_r[i]);
}
+ s = "test";
+ l = s.split();
+ CHECK(l.size() == 4);
+ for (int i = 0; i < l.size(); i++) {
+ CHECK(l[i] == slices_3[i]);
+ }
+
s = "Mars Jupiter Saturn Uranus";
const char *slices_s[4] = { "Mars", "Jupiter", "Saturn", "Uranus" };
l = s.split_spaces();
diff --git a/tests/scene/test_animation.h b/tests/scene/test_animation.h
index ca80f0ecab..e921779c23 100644
--- a/tests/scene/test_animation.h
+++ b/tests/scene/test_animation.h
@@ -40,8 +40,8 @@ namespace TestAnimation {
TEST_CASE("[Animation] Empty animation getters") {
const Ref<Animation> animation = memnew(Animation);
- CHECK(Math::is_equal_approx(animation->get_length(), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->get_step(), real_t(0.1)));
+ CHECK(animation->get_length() == doctest::Approx(real_t(1.0)));
+ CHECK(animation->get_step() == doctest::Approx(real_t(0.1)));
}
TEST_CASE("[Animation] Create value track") {
@@ -59,33 +59,33 @@ TEST_CASE("[Animation] Create value track") {
CHECK(int(animation->track_get_key_value(0, 0)) == 0);
CHECK(int(animation->track_get_key_value(0, 1)) == 100);
- CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, -0.2), 0.0));
- CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.0), 0.0));
- CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.2), 40.0));
- CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.4), 80.0));
- CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.5), 100.0));
- CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.6), 100.0));
+ CHECK(animation->value_track_interpolate(0, -0.2) == doctest::Approx(0.0));
+ CHECK(animation->value_track_interpolate(0, 0.0) == doctest::Approx(0.0));
+ CHECK(animation->value_track_interpolate(0, 0.2) == doctest::Approx(40.0));
+ CHECK(animation->value_track_interpolate(0, 0.4) == doctest::Approx(80.0));
+ CHECK(animation->value_track_interpolate(0, 0.5) == doctest::Approx(100.0));
+ CHECK(animation->value_track_interpolate(0, 0.6) == doctest::Approx(100.0));
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 0) == doctest::Approx(real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 1) == doctest::Approx(real_t(1.0)));
ERR_PRINT_OFF;
// Nonexistent keys.
CHECK(animation->track_get_key_value(0, 2).is_null());
CHECK(animation->track_get_key_value(0, -1).is_null());
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 2), real_t(-1.0)));
+ CHECK(animation->track_get_key_transition(0, 2) == doctest::Approx(real_t(-1.0)));
// Nonexistent track (and keys).
CHECK(animation->track_get_key_value(1, 0).is_null());
CHECK(animation->track_get_key_value(1, 1).is_null());
CHECK(animation->track_get_key_value(1, 2).is_null());
CHECK(animation->track_get_key_value(1, -1).is_null());
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(1, 0), real_t(-1.0)));
+ CHECK(animation->track_get_key_transition(1, 0) == doctest::Approx(real_t(-1.0)));
// This is a value track, so the methods below should return errors.
CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
- CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.0) == doctest::Approx(0.0));
CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
ERR_PRINT_ON;
}
@@ -123,15 +123,15 @@ TEST_CASE("[Animation] Create 3D position track") {
CHECK(r_interpolation.is_equal_approx(Vector3(3.5, 4, 5)));
// 3D position tracks always use linear interpolation for performance reasons.
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 0) == doctest::Approx(real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 1) == doctest::Approx(real_t(1.0)));
// This is a 3D position track, so the methods below should return errors.
ERR_PRINT_OFF;
CHECK(animation->value_track_interpolate(0, 0.0).is_null());
CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
- CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.0) == doctest::Approx(0.0));
CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
ERR_PRINT_ON;
}
@@ -169,15 +169,15 @@ TEST_CASE("[Animation] Create 3D rotation track") {
CHECK(r_interpolation.is_equal_approx(Quaternion(0.231055, 0.374912, 0.761204, 0.476048)));
// 3D rotation tracks always use linear interpolation for performance reasons.
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 0) == doctest::Approx(real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 1) == doctest::Approx(real_t(1.0)));
// This is a 3D rotation track, so the methods below should return errors.
ERR_PRINT_OFF;
CHECK(animation->value_track_interpolate(0, 0.0).is_null());
CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
- CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.0) == doctest::Approx(real_t(0.0)));
CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
ERR_PRINT_ON;
}
@@ -215,15 +215,15 @@ TEST_CASE("[Animation] Create 3D scale track") {
CHECK(r_interpolation.is_equal_approx(Vector3(3.5, 4, 5)));
// 3D scale tracks always use linear interpolation for performance reasons.
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 0) == doctest::Approx(1.0));
+ CHECK(animation->track_get_key_transition(0, 1) == doctest::Approx(1.0));
// This is a 3D scale track, so the methods below should return errors.
ERR_PRINT_OFF;
CHECK(animation->value_track_interpolate(0, 0.0).is_null());
CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
- CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.0) == doctest::Approx(0.0));
CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
ERR_PRINT_ON;
}
@@ -242,32 +242,32 @@ TEST_CASE("[Animation] Create blend shape track") {
float r_blend = 0.0f;
CHECK(animation->blend_shape_track_get_key(0, 0, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, -1.0f));
+ CHECK(r_blend == doctest::Approx(-1.0f));
CHECK(animation->blend_shape_track_get_key(0, 1, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, 1.0f));
+ CHECK(r_blend == doctest::Approx(1.0f));
CHECK(animation->blend_shape_track_interpolate(0, -0.2, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, -1.0f));
+ CHECK(r_blend == doctest::Approx(-1.0f));
CHECK(animation->blend_shape_track_interpolate(0, 0.0, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, -1.0f));
+ CHECK(r_blend == doctest::Approx(-1.0f));
CHECK(animation->blend_shape_track_interpolate(0, 0.2, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, -0.2f));
+ CHECK(r_blend == doctest::Approx(-0.2f));
CHECK(animation->blend_shape_track_interpolate(0, 0.4, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, 0.6f));
+ CHECK(r_blend == doctest::Approx(0.6f));
CHECK(animation->blend_shape_track_interpolate(0, 0.5, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, 1.0f));
+ CHECK(r_blend == doctest::Approx(1.0f));
CHECK(animation->blend_shape_track_interpolate(0, 0.6, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, 1.0f));
+ CHECK(r_blend == doctest::Approx(1.0f));
// Blend shape tracks always use linear interpolation for performance reasons.
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 0) == doctest::Approx(real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 1) == doctest::Approx(real_t(1.0)));
// This is a blend shape track, so the methods below should return errors.
ERR_PRINT_OFF;
@@ -275,7 +275,7 @@ TEST_CASE("[Animation] Create blend shape track") {
CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
- CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.0) == doctest::Approx(0.0));
ERR_PRINT_ON;
}
@@ -289,15 +289,15 @@ TEST_CASE("[Animation] Create Bezier track") {
CHECK(animation->get_track_count() == 1);
CHECK(!animation->track_is_compressed(0));
- CHECK(Math::is_equal_approx(animation->bezier_track_get_key_value(0, 0), real_t(-1.0)));
- CHECK(Math::is_equal_approx(animation->bezier_track_get_key_value(0, 1), real_t(1.0)));
+ CHECK(animation->bezier_track_get_key_value(0, 0) == doctest::Approx(real_t(-1.0)));
+ CHECK(animation->bezier_track_get_key_value(0, 1) == doctest::Approx(real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, -0.2), real_t(-1.0)));
- CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.0), real_t(-1.0)));
- CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.2), real_t(-0.76057207584381)));
- CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.4), real_t(-0.39975279569626)));
- CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.5), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.6), real_t(1.0)));
+ CHECK(animation->bezier_track_interpolate(0, -0.2) == doctest::Approx(real_t(-1.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.0) == doctest::Approx(real_t(-1.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.2) == doctest::Approx(real_t(-0.76057207584381)));
+ CHECK(animation->bezier_track_interpolate(0, 0.4) == doctest::Approx(real_t(-0.39975279569626)));
+ CHECK(animation->bezier_track_interpolate(0, 0.5) == doctest::Approx(real_t(1.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.6) == doctest::Approx(real_t(1.0)));
// This is a bezier track, so the methods below should return errors.
ERR_PRINT_OFF;
diff --git a/tests/scene/test_audio_stream_wav.h b/tests/scene/test_audio_stream_wav.h
index 4ba431dfc2..c84c66b0e6 100644
--- a/tests/scene/test_audio_stream_wav.h
+++ b/tests/scene/test_audio_stream_wav.h
@@ -138,7 +138,7 @@ void run_test(String file_name, AudioStreamWAV::Format data_format, bool stereo,
CHECK(stream->get_data() == test_data);
SUBCASE("Stream length is computed properly") {
- CHECK(Math::is_equal_approx(stream->get_length(), double(wav_count / wav_rate)));
+ CHECK(stream->get_length() == doctest::Approx(double(wav_count / wav_rate)));
}
SUBCASE("Stream can be saved as .wav") {
diff --git a/tests/scene/test_curve.h b/tests/scene/test_curve.h
index ad7625ddc5..36ec0c0a4d 100644
--- a/tests/scene/test_curve.h
+++ b/tests/scene/test_curve.h
@@ -83,54 +83,54 @@ TEST_CASE("[Curve] Custom curve with free tangents") {
Math::is_zero_approx(curve->sample(-0.1)),
"Custom free curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.1), (real_t)0.352),
+ curve->sample(0.1) == doctest::Approx((real_t)0.352),
"Custom free curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.4), (real_t)0.352),
+ curve->sample(0.4) == doctest::Approx((real_t)0.352),
"Custom free curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.7), (real_t)0.896),
+ curve->sample(0.7) == doctest::Approx((real_t)0.896),
"Custom free curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(1), 1),
+ curve->sample(1) == doctest::Approx(1),
"Custom free curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(2), 1),
+ curve->sample(2) == doctest::Approx(1),
"Custom free curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
Math::is_zero_approx(curve->sample_baked(-0.1)),
"Custom free curve should return the expected baked value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.1), (real_t)0.352),
+ curve->sample_baked(0.1) == doctest::Approx((real_t)0.352),
"Custom free curve should return the expected baked value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.4), (real_t)0.352),
+ curve->sample_baked(0.4) == doctest::Approx((real_t)0.352),
"Custom free curve should return the expected baked value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.7), (real_t)0.896),
+ curve->sample_baked(0.7) == doctest::Approx((real_t)0.896),
"Custom free curve should return the expected baked value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(1), 1),
+ curve->sample_baked(1) == doctest::Approx(1),
"Custom free curve should return the expected baked value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(2), 1),
+ curve->sample_baked(2) == doctest::Approx(1),
"Custom free curve should return the expected baked value at offset 0.1.");
curve->remove_point(1);
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.1), 0),
+ curve->sample(0.1) == doctest::Approx(0),
"Custom free curve should return the expected value at offset 0.1 after removing point at index 1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.1), 0),
+ curve->sample_baked(0.1) == doctest::Approx(0),
"Custom free curve should return the expected baked value at offset 0.1 after removing point at index 1.");
curve->clear_points();
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.6), 0),
+ curve->sample(0.6) == doctest::Approx(0),
"Custom free curve should return the expected value at offset 0.6 after clearing all points.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.6), 0),
+ curve->sample_baked(0.6) == doctest::Approx(0),
"Custom free curve should return the expected baked value at offset 0.6 after clearing all points.");
}
@@ -143,7 +143,7 @@ TEST_CASE("[Curve] Custom curve with linear tangents") {
curve->add_point(Vector2(0.75, 1), 0, 0, Curve::TangentMode::TANGENT_LINEAR, Curve::TangentMode::TANGENT_LINEAR);
CHECK_MESSAGE(
- Math::is_equal_approx(curve->get_point_left_tangent(3), 4),
+ curve->get_point_left_tangent(3) == doctest::Approx(4),
"get_point_left_tangent() should return the expected value for point index 3.");
CHECK_MESSAGE(
Math::is_zero_approx(curve->get_point_right_tangent(3)),
@@ -172,48 +172,48 @@ TEST_CASE("[Curve] Custom curve with linear tangents") {
Math::is_zero_approx(curve->sample(-0.1)),
"Custom linear curve should return the expected value at offset -0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.1), (real_t)0.4),
+ curve->sample(0.1) == doctest::Approx((real_t)0.4),
"Custom linear curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.4), (real_t)0.4),
+ curve->sample(0.4) == doctest::Approx((real_t)0.4),
"Custom linear curve should return the expected value at offset 0.4.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.7), (real_t)0.8),
+ curve->sample(0.7) == doctest::Approx((real_t)0.8),
"Custom linear curve should return the expected value at offset 0.7.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(1), 1),
+ curve->sample(1) == doctest::Approx(1),
"Custom linear curve should return the expected value at offset 1.0.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(2), 1),
+ curve->sample(2) == doctest::Approx(1),
"Custom linear curve should return the expected value at offset 2.0.");
CHECK_MESSAGE(
Math::is_zero_approx(curve->sample_baked(-0.1)),
"Custom linear curve should return the expected baked value at offset -0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.1), (real_t)0.4),
+ curve->sample_baked(0.1) == doctest::Approx((real_t)0.4),
"Custom linear curve should return the expected baked value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.4), (real_t)0.4),
+ curve->sample_baked(0.4) == doctest::Approx((real_t)0.4),
"Custom linear curve should return the expected baked value at offset 0.4.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.7), (real_t)0.8),
+ curve->sample_baked(0.7) == doctest::Approx((real_t)0.8),
"Custom linear curve should return the expected baked value at offset 0.7.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(1), 1),
+ curve->sample_baked(1) == doctest::Approx(1),
"Custom linear curve should return the expected baked value at offset 1.0.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(2), 1),
+ curve->sample_baked(2) == doctest::Approx(1),
"Custom linear curve should return the expected baked value at offset 2.0.");
ERR_PRINT_OFF;
curve->remove_point(10);
ERR_PRINT_ON;
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.7), (real_t)0.8),
+ curve->sample(0.7) == doctest::Approx((real_t)0.8),
"Custom free curve should return the expected value at offset 0.7 after removing point at invalid index 10.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.7), (real_t)0.8),
+ curve->sample_baked(0.7) == doctest::Approx((real_t)0.8),
"Custom free curve should return the expected baked value at offset 0.7 after removing point at invalid index 10.");
}
diff --git a/tests/scene/test_primitives.h b/tests/scene/test_primitives.h
index ceec117700..8bac903d93 100644
--- a/tests/scene/test_primitives.h
+++ b/tests/scene/test_primitives.h
@@ -57,9 +57,9 @@ TEST_CASE("[SceneTree][Primitive][Capsule] Capsule Primitive") {
capsule->set_radial_segments(16);
capsule->set_rings(32);
- CHECK_MESSAGE(Math::is_equal_approx(capsule->get_radius(), 1.3f),
+ CHECK_MESSAGE(capsule->get_radius() == doctest::Approx(1.3f),
"Get/Set radius work with one set.");
- CHECK_MESSAGE(Math::is_equal_approx(capsule->get_height(), 7.1f),
+ CHECK_MESSAGE(capsule->get_height() == doctest::Approx(7.1f),
"Get/Set radius work with one set.");
CHECK_MESSAGE(capsule->get_radial_segments() == 16,
"Get/Set radius work with one set.");
@@ -129,7 +129,7 @@ TEST_CASE("[SceneTree][Primitive][Capsule] Capsule Primitive") {
if (normals[ii].y == 0.f) {
float mag_of_normal = Math::sqrt(normals[ii].x * normals[ii].x + normals[ii].z * normals[ii].z);
Vector3 normalized_normal = normals[ii] / mag_of_normal;
- CHECK_MESSAGE(Math::is_equal_approx(point_dist_from_yaxis, radius),
+ CHECK_MESSAGE(point_dist_from_yaxis == doctest::Approx(radius),
"Points on the tube of the capsule are radius away from y-axis.");
CHECK_MESSAGE(normalized_normal.is_equal_approx(yaxis_to_point),
"Normal points orthogonal from mid cylinder.");
@@ -244,9 +244,9 @@ TEST_CASE("[SceneTree][Primitive][Cylinder] Cylinder Primitive") {
cylinder->set_cap_top(false);
cylinder->set_cap_bottom(false);
- CHECK(Math::is_equal_approx(cylinder->get_top_radius(), 4.3f));
- CHECK(Math::is_equal_approx(cylinder->get_bottom_radius(), 1.2f));
- CHECK(Math::is_equal_approx(cylinder->get_height(), 9.77f));
+ CHECK(cylinder->get_top_radius() == doctest::Approx(4.3f));
+ CHECK(cylinder->get_bottom_radius() == doctest::Approx(1.2f));
+ CHECK(cylinder->get_height() == doctest::Approx(9.77f));
CHECK(cylinder->get_radial_segments() == 12);
CHECK(cylinder->get_rings() == 16);
CHECK(!cylinder->is_cap_top());
@@ -478,7 +478,7 @@ TEST_CASE("[SceneTree][Primitive][Prism] Prism Primitive") {
prism->set_subdivide_height(5);
prism->set_subdivide_depth(64);
- CHECK(Math::is_equal_approx(prism->get_left_to_right(), 3.4f));
+ CHECK(prism->get_left_to_right() == doctest::Approx(3.4f));
CHECK(prism->get_size().is_equal_approx(size));
CHECK(prism->get_subdivide_width() == 36);
CHECK(prism->get_subdivide_height() == 5);
@@ -513,8 +513,8 @@ TEST_CASE("[SceneTree][Primitive][Sphere] Sphere Primitive") {
sphere->set_rings(5);
sphere->set_is_hemisphere(true);
- CHECK(Math::is_equal_approx(sphere->get_radius(), 3.4f));
- CHECK(Math::is_equal_approx(sphere->get_height(), 2.2f));
+ CHECK(sphere->get_radius() == doctest::Approx(3.4f));
+ CHECK(sphere->get_height() == doctest::Approx(2.2f));
CHECK(sphere->get_radial_segments() == 36);
CHECK(sphere->get_rings() == 5);
CHECK(sphere->get_is_hemisphere());
@@ -581,8 +581,8 @@ TEST_CASE("[SceneTree][Primitive][Torus] Torus Primitive") {
torus->set_rings(19);
torus->set_ring_segments(43);
- CHECK(Math::is_equal_approx(torus->get_inner_radius(), 3.2f));
- CHECK(Math::is_equal_approx(torus->get_outer_radius(), 9.5f));
+ CHECK(torus->get_inner_radius() == doctest::Approx(3.2f));
+ CHECK(torus->get_outer_radius() == doctest::Approx(9.5f));
CHECK(torus->get_rings() == 19);
CHECK(torus->get_ring_segments() == 43);
}
@@ -610,8 +610,8 @@ TEST_CASE("[SceneTree][Primitive][TubeTrail] TubeTrail Primitive") {
Ref<Curve> curve = memnew(Curve);
tube->set_curve(curve);
- CHECK(Math::is_equal_approx(tube->get_radius(), 7.2f));
- CHECK(Math::is_equal_approx(tube->get_section_length(), 5.5f));
+ CHECK(tube->get_radius() == doctest::Approx(7.2f));
+ CHECK(tube->get_section_length() == doctest::Approx(5.5f));
CHECK(tube->get_radial_steps() == 9);
CHECK(tube->get_sections() == 33);
CHECK(tube->get_section_rings() == 12);
@@ -670,8 +670,8 @@ TEST_CASE("[SceneTree][Primitive][RibbonTrail] RibbonTrail Primitive") {
ribbon->set_section_segments(9);
ribbon->set_curve(curve);
- CHECK(Math::is_equal_approx(ribbon->get_size(), 4.3f));
- CHECK(Math::is_equal_approx(ribbon->get_section_length(), 1.3f));
+ CHECK(ribbon->get_size() == doctest::Approx(4.3f));
+ CHECK(ribbon->get_section_length() == doctest::Approx(1.3f));
CHECK(ribbon->get_sections() == 16);
CHECK(ribbon->get_section_segments() == 9);
CHECK(ribbon->get_curve() == curve);
@@ -781,11 +781,11 @@ TEST_CASE("[SceneTree][Primitive][Text] Text Primitive") {
CHECK(text->get_structured_text_bidi_override_options() == options);
CHECK(text->is_uppercase() == true);
CHECK(text->get_offset() == offset);
- CHECK(Math::is_equal_approx(text->get_line_spacing(), 1.7f));
- CHECK(Math::is_equal_approx(text->get_width(), width));
- CHECK(Math::is_equal_approx(text->get_depth(), depth));
- CHECK(Math::is_equal_approx(text->get_curve_step(), curve_step));
- CHECK(Math::is_equal_approx(text->get_pixel_size(), pixel_size));
+ CHECK(text->get_line_spacing() == doctest::Approx(1.7f));
+ CHECK(text->get_width() == doctest::Approx(width));
+ CHECK(text->get_depth() == doctest::Approx(depth));
+ CHECK(text->get_curve_step() == doctest::Approx(curve_step));
+ CHECK(text->get_pixel_size() == doctest::Approx(pixel_size));
}
SUBCASE("[Primitive][Text] Set objects multiple times.") {
diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h
index e34f2970d4..5dad7d06e1 100644
--- a/tests/scene/test_text_edit.h
+++ b/tests/scene/test_text_edit.h
@@ -734,13 +734,20 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
}
SUBCASE("[TextEdit] add selection for next occurrence") {
- text_edit->set_text("\ntest other_test\nrandom test\nword test word");
+ text_edit->set_text("\ntest other_test\nrandom test\nword test word nonrandom");
text_edit->set_caret_column(0);
text_edit->set_caret_line(1);
- text_edit->select_word_under_caret();
- CHECK(text_edit->has_selection(0));
+ // First selection made by the implicit select_word_under_caret call
+ text_edit->add_selection_for_next_occurrence();
+ CHECK(text_edit->get_caret_count() == 1);
CHECK(text_edit->get_selected_text(0) == "test");
+ CHECK(text_edit->get_selection_from_line(0) == 1);
+ CHECK(text_edit->get_selection_from_column(0) == 0);
+ CHECK(text_edit->get_selection_to_line(0) == 1);
+ CHECK(text_edit->get_selection_to_column(0) == 4);
+ CHECK(text_edit->get_caret_line(0) == 1);
+ CHECK(text_edit->get_caret_column(0) == 4);
text_edit->add_selection_for_next_occurrence();
CHECK(text_edit->get_caret_count() == 2);
@@ -771,6 +778,27 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
CHECK(text_edit->get_selection_to_column(3) == 9);
CHECK(text_edit->get_caret_line(3) == 3);
CHECK(text_edit->get_caret_column(3) == 9);
+
+ // A different word with a new manually added caret
+ text_edit->add_caret(2, 1);
+ text_edit->select(2, 0, 2, 4, 4);
+ CHECK(text_edit->get_selected_text(4) == "rand");
+
+ text_edit->add_selection_for_next_occurrence();
+ CHECK(text_edit->get_caret_count() == 6);
+ CHECK(text_edit->get_selected_text(5) == "rand");
+ CHECK(text_edit->get_selection_from_line(5) == 3);
+ CHECK(text_edit->get_selection_from_column(5) == 18);
+ CHECK(text_edit->get_selection_to_line(5) == 3);
+ CHECK(text_edit->get_selection_to_column(5) == 22);
+ CHECK(text_edit->get_caret_line(5) == 3);
+ CHECK(text_edit->get_caret_column(5) == 22);
+
+ // Make sure the previous selections are still active
+ CHECK(text_edit->get_selected_text(0) == "test");
+ CHECK(text_edit->get_selected_text(1) == "test");
+ CHECK(text_edit->get_selected_text(2) == "test");
+ CHECK(text_edit->get_selected_text(3) == "test");
}
SUBCASE("[TextEdit] deselect on focus loss") {