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/gles3/rasterizer_canvas_gles3.cpp4
-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/plugins/tiles/tile_atlas_view.cpp52
-rw-r--r--editor/project_manager.cpp2
-rw-r--r--editor/script_create_dialog.cpp4
-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/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/string/test_string.h8
29 files changed, 153 insertions, 114 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/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 29252c8677..b05817cd8e 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -581,7 +581,7 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
_record_item_commands(ci, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index, batch_broken);
}
- if (r_last_index >= index) {
+ if (index == 0) {
// Nothing to render, just return.
state.current_batch_index = 0;
state.canvas_instance_batches.clear();
@@ -1325,7 +1325,7 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
void RasterizerCanvasGLES3::_add_to_batch(uint32_t &r_index, bool &r_batch_broken) {
if (r_index >= data.max_instances_per_ubo - 1) {
- WARN_PRINT_ONCE("Trying to draw too many items. Please increase maximum number of items in the project settings 'rendering/gl_compatibility/item_buffer_size'");
+ ERR_PRINT_ONCE("Trying to draw too many items. Please increase maximum number of items in the project settings 'rendering/gl_compatibility/item_buffer_size'");
return;
}
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/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp
index 69104cadec..4fe7178e7e 100644
--- a/editor/plugins/tiles/tile_atlas_view.cpp
+++ b/editor/plugins/tiles/tile_atlas_view.cpp
@@ -192,6 +192,19 @@ void TileAtlasView::_draw_base_tiles() {
rect = rect.intersection(Rect2i(Vector2(), texture->get_size()));
if (rect.size.x > 0 && rect.size.y > 0) {
base_tiles_draw->draw_texture_rect_region(texture, rect, rect);
+ }
+ }
+ }
+ }
+
+ // Draw dark overlay after for performance reasons.
+ for (int x = 0; x < grid_size.x; x++) {
+ for (int y = 0; y < grid_size.y; y++) {
+ Vector2i coords = Vector2i(x, y);
+ if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) {
+ Rect2i rect = Rect2i((texture_region_size + separation) * coords + margins, texture_region_size + separation);
+ rect = rect.intersection(Rect2i(Vector2(), texture->get_size()));
+ if (rect.size.x > 0 && rect.size.y > 0) {
base_tiles_draw->draw_rect(rect, Color(0.0, 0.0, 0.0, 0.5));
}
}
@@ -242,23 +255,34 @@ void TileAtlasView::_draw_base_tiles() {
// Draw the tile.
TileMap::draw_tile(base_tiles_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, 0, frame);
+ }
+ }
- // Draw, the texture in the separation areas
- if (separation.x > 0) {
- Rect2i right_sep_rect = Rect2i(base_frame_rect.get_position() + Vector2i(base_frame_rect.size.x, 0), Vector2i(separation.x, base_frame_rect.size.y));
- right_sep_rect = right_sep_rect.intersection(Rect2i(Vector2(), texture->get_size()));
- if (right_sep_rect.size.x > 0 && right_sep_rect.size.y > 0) {
- base_tiles_draw->draw_texture_rect_region(texture, right_sep_rect, right_sep_rect);
- base_tiles_draw->draw_rect(right_sep_rect, Color(0.0, 0.0, 0.0, 0.5));
+ // Draw Dark overlay on separation in its own pass.
+ if (separation.x > 0 || separation.y > 0) {
+ for (int i = 0; i < tile_set_atlas_source->get_tiles_count(); i++) {
+ Vector2i atlas_coords = tile_set_atlas_source->get_tile_id(i);
+
+ for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(atlas_coords); frame++) {
+ // Update the y to max value.
+ Rect2i base_frame_rect = tile_set_atlas_source->get_tile_texture_region(atlas_coords, frame);
+
+ if (separation.x > 0) {
+ Rect2i right_sep_rect = Rect2i(base_frame_rect.get_position() + Vector2i(base_frame_rect.size.x, 0), Vector2i(separation.x, base_frame_rect.size.y));
+ right_sep_rect = right_sep_rect.intersection(Rect2i(Vector2(), texture->get_size()));
+ if (right_sep_rect.size.x > 0 && right_sep_rect.size.y > 0) {
+ //base_tiles_draw->draw_texture_rect_region(texture, right_sep_rect, right_sep_rect);
+ base_tiles_draw->draw_rect(right_sep_rect, Color(0.0, 0.0, 0.0, 0.5));
+ }
}
- }
- if (separation.y > 0) {
- Rect2i bottom_sep_rect = Rect2i(base_frame_rect.get_position() + Vector2i(0, base_frame_rect.size.y), Vector2i(base_frame_rect.size.x + separation.x, separation.y));
- bottom_sep_rect = bottom_sep_rect.intersection(Rect2i(Vector2(), texture->get_size()));
- if (bottom_sep_rect.size.x > 0 && bottom_sep_rect.size.y > 0) {
- base_tiles_draw->draw_texture_rect_region(texture, bottom_sep_rect, bottom_sep_rect);
- base_tiles_draw->draw_rect(bottom_sep_rect, Color(0.0, 0.0, 0.0, 0.5));
+ if (separation.y > 0) {
+ Rect2i bottom_sep_rect = Rect2i(base_frame_rect.get_position() + Vector2i(0, base_frame_rect.size.y), Vector2i(base_frame_rect.size.x + separation.x, separation.y));
+ bottom_sep_rect = bottom_sep_rect.intersection(Rect2i(Vector2(), texture->get_size()));
+ if (bottom_sep_rect.size.x > 0 && bottom_sep_rect.size.y > 0) {
+ //base_tiles_draw->draw_texture_rect_region(texture, bottom_sep_rect, bottom_sep_rect);
+ base_tiles_draw->draw_rect(bottom_sep_rect, Color(0.0, 0.0, 0.0, 0.5));
+ }
}
}
}
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/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/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/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();