summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/DisplayServer.xml5
-rw-r--r--doc/classes/EditorInspector.xml5
-rw-r--r--doc/classes/Window.xml4
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp6
-rw-r--r--editor/animation_track_editor.cpp10
-rw-r--r--editor/editor_inspector.cpp2
-rw-r--r--editor/editor_node.cpp1
-rw-r--r--editor/editor_node.h1
-rw-r--r--editor/editor_themes.cpp5
-rw-r--r--editor/filesystem_dock.cpp6
-rw-r--r--editor/inspector_dock.cpp34
-rw-r--r--editor/inspector_dock.h4
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp30
-rw-r--r--editor/plugins/animation_player_editor_plugin.h4
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp74
-rw-r--r--editor/plugins/asset_library_editor_plugin.h14
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp10
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp1
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp3
-rw-r--r--platform/linuxbsd/display_server_x11.cpp15
-rw-r--r--platform/linuxbsd/display_server_x11.h1
-rw-r--r--platform/osx/display_server_osx.h3
-rw-r--r--platform/osx/display_server_osx.mm63
-rw-r--r--platform/windows/display_server_windows.cpp16
-rw-r--r--scene/2d/tile_map.cpp4
-rw-r--r--scene/main/window.cpp6
-rw-r--r--servers/display_server.cpp5
-rw-r--r--servers/display_server.h1
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp1
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h1
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp1
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h1
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp9
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h1
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp1
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h1
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp1
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.h1
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp20
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h5
-rw-r--r--servers/rendering/rendering_device.h2
-rw-r--r--servers/rendering/shader_language.cpp647
-rw-r--r--servers/rendering/shader_language.h20
-rw-r--r--servers/rendering/shader_warnings.cpp16
44 files changed, 550 insertions, 511 deletions
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index f34b8c342f..c527922cd5 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -321,11 +321,6 @@
[b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
- <method name="mouse_get_absolute_position" qualifiers="const">
- <return type="Vector2i" />
- <description>
- </description>
- </method>
<method name="mouse_get_button_state" qualifiers="const">
<return type="int" enum="MouseButton" />
<description>
diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml
index 39589138fa..27dab3d422 100644
--- a/doc/classes/EditorInspector.xml
+++ b/doc/classes/EditorInspector.xml
@@ -13,6 +13,11 @@
<member name="horizontal_scroll_mode" type="int" setter="set_horizontal_scroll_mode" getter="get_horizontal_scroll_mode" overrides="ScrollContainer" enum="ScrollContainer.ScrollMode" default="0" />
</members>
<signals>
+ <signal name="edited_object_changed">
+ <description>
+ Emitted when the object being edited by the inspector has changed.
+ </description>
+ </signal>
<signal name="object_id_selected">
<argument index="0" name="id" type="int" />
<description>
diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml
index 75161d3c5b..0e4e3a65f8 100644
--- a/doc/classes/Window.xml
+++ b/doc/classes/Window.xml
@@ -368,6 +368,10 @@
<description>
</description>
</signal>
+ <signal name="theme_changed">
+ <description>
+ </description>
+ </signal>
<signal name="visibility_changed">
<description>
</description>
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 4d742a36d9..c6592b300b 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -8372,11 +8372,11 @@ void RenderingDeviceVulkan::_free_internal(RID p_id) {
} else if (uniform_set_owner.owns(p_id)) {
UniformSet *uniform_set = uniform_set_owner.get_or_null(p_id);
frames[frame].uniform_sets_to_dispose_of.push_back(*uniform_set);
+ uniform_set_owner.free(p_id);
+
if (uniform_set->invalidated_callback != nullptr) {
- uniform_set->invalidated_callback(p_id, uniform_set->invalidated_callback_userdata);
+ uniform_set->invalidated_callback(uniform_set->invalidated_callback_userdata);
}
-
- uniform_set_owner.free(p_id);
} else if (render_pipeline_owner.owns(p_id)) {
RenderPipeline *pipeline = render_pipeline_owner.get_or_null(p_id);
frames[frame].render_pipelines_to_dispose_of.push_back(*pipeline);
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 13e9d58744..973f74d6cc 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -3375,7 +3375,13 @@ Node *AnimationTrackEditor::get_root() const {
}
void AnimationTrackEditor::update_keying() {
- bool keying_enabled = is_visible_in_tree() && animation.is_valid();
+ bool keying_enabled = false;
+
+ EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history();
+ if (is_visible_in_tree() && animation.is_valid() && editor_history->get_path_size() > 0) {
+ Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0));
+ keying_enabled = Object::cast_to<Node>(obj) != nullptr;
+ }
if (keying_enabled == keying) {
return;
@@ -4525,8 +4531,6 @@ void AnimationTrackEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
update_keying();
- EditorNode::get_singleton()->update_keying();
- emit_signal(SNAME("keying_changed"));
}
}
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 75e518e050..1e1f25b6d1 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -2905,6 +2905,7 @@ void EditorInspector::edit(Object *p_object) {
object->connect("property_list_changed", callable_mp(this, &EditorInspector::_changed_callback));
update_tree();
}
+ emit_signal("edited_object_changed");
}
void EditorInspector::set_keying(bool p_active) {
@@ -3543,6 +3544,7 @@ void EditorInspector::_bind_methods() {
ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("property_edited", PropertyInfo(Variant::STRING, "property")));
ADD_SIGNAL(MethodInfo("property_toggled", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::BOOL, "checked")));
+ ADD_SIGNAL(MethodInfo("edited_object_changed"));
ADD_SIGNAL(MethodInfo("restart_requested"));
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index cc92d391d9..e64f60c58d 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -2307,7 +2307,6 @@ void EditorNode::_edit_current(bool p_skip_foreign) {
}
inspector_dock->update(current_obj);
- inspector_dock->update_keying();
}
void EditorNode::_run(bool p_current, const String &p_custom) {
diff --git a/editor/editor_node.h b/editor/editor_node.h
index ff56040297..487bde3cb4 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -884,7 +884,6 @@ public:
void edit_current() { _edit_current(); };
- void update_keying() const { inspector_dock->update_keying(); };
bool has_scenes_in_session();
int execute_and_show_output(const String &p_title, const String &p_path, const List<String> &p_arguments, bool p_close_on_ok = true, bool p_close_on_errors = false);
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 35aad36db5..8e87ddee80 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -1442,6 +1442,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
style_info_3d_viewport->set_border_width_all(0);
theme->set_stylebox("Information3dViewport", "EditorStyles", style_info_3d_viewport);
+ // Asset Library.
+ theme->set_stylebox("panel", "AssetLib", style_content_panel);
+ theme->set_color("status_color", "AssetLib", Color(0.5, 0.5, 0.5));
+ theme->set_icon("dismiss", "AssetLib", theme->get_icon("Close", "EditorIcons"));
+
// Theme editor.
theme->set_color("preview_picker_overlay_color", "ThemeEditor", Color(0.1, 0.1, 0.1, 0.25));
Color theme_preview_picker_bg_color = accent_color;
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index d71861e72d..3f15b3f206 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -2506,6 +2506,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
String fpath = p_paths[0];
String item_text = fpath.ends_with("/") ? TTR("Open in File Manager") : TTR("Show in File Manager");
p_popup->add_icon_item(get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), item_text, FILE_SHOW_IN_EXPLORER);
+ path = fpath;
}
}
@@ -2542,6 +2543,9 @@ void FileSystemDock::_tree_rmb_empty(const Vector2 &p_pos) {
tree_popup->add_icon_item(get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), TTR("New Script..."), FILE_NEW_SCRIPT);
tree_popup->add_icon_item(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")), TTR("New Resource..."), FILE_NEW_RESOURCE);
tree_popup->add_icon_item(get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")), TTR("New TextFile..."), FILE_NEW_TEXTFILE);
+ tree_popup->add_separator();
+ tree_popup->add_icon_item(get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), TTR("Open in File Manager"), FILE_SHOW_IN_EXPLORER);
+
tree_popup->set_position(tree->get_screen_position() + p_pos);
tree_popup->reset_size();
tree_popup->popup();
@@ -2581,6 +2585,8 @@ void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) {
return;
}
+ path = current_path->get_text();
+
file_list_popup->clear();
file_list_popup->reset_size();
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index f56e868286..ce4e51e54c 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -382,20 +382,6 @@ void InspectorDock::_menu_expandall() {
inspector->expand_all_folding();
}
-void InspectorDock::_property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance) {
- AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_value_key(p_keyed, p_value, p_advance);
-}
-
-void InspectorDock::_transform_keyed(Object *sp, const String &p_sub, const Transform3D &p_key) {
- Node3D *s = Object::cast_to<Node3D>(sp);
- if (!s) {
- return;
- }
- AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_transform_key(s, p_sub, Animation::TYPE_POSITION_3D, p_key.origin);
- AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_transform_key(s, p_sub, Animation::TYPE_ROTATION_3D, p_key.basis.get_rotation_quaternion());
- AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_transform_key(s, p_sub, Animation::TYPE_SCALE_3D, p_key.basis.get_scale());
-}
-
void InspectorDock::_warning_pressed() {
warning_dialog->popup_centered();
}
@@ -440,9 +426,6 @@ void InspectorDock::_notification(int p_what) {
}
void InspectorDock::_bind_methods() {
- ClassDB::bind_method("update_keying", &InspectorDock::update_keying);
- ClassDB::bind_method("_transform_keyed", &InspectorDock::_transform_keyed); // Still used by some connect_compat.
-
ClassDB::bind_method("_unref_resource", &InspectorDock::_unref_resource);
ClassDB::bind_method("_paste_resource", &InspectorDock::_paste_resource);
ClassDB::bind_method("_copy_resource", &InspectorDock::_copy_resource);
@@ -547,22 +530,6 @@ void InspectorDock::go_back() {
_edit_back();
}
-void InspectorDock::update_keying() {
- bool valid = false;
-
- if (AnimationPlayerEditor::get_singleton()->get_track_editor()->has_keying()) {
- EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history();
- if (editor_history->get_path_size() >= 1) {
- Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0));
- if (Object::cast_to<Node>(obj)) {
- valid = true;
- }
- }
- }
-
- inspector->set_keying(valid);
-}
-
InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
set_name("Inspector");
@@ -716,7 +683,6 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
inspector->set_use_filter(true); // TODO: check me
inspector->connect("resource_selected", callable_mp(this, &InspectorDock::_resource_selected));
- inspector->connect("property_keyed", callable_mp(this, &InspectorDock::_property_keyed));
}
InspectorDock::~InspectorDock() {
diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h
index 94e4f67348..2f120c93b4 100644
--- a/editor/inspector_dock.h
+++ b/editor/inspector_dock.h
@@ -117,16 +117,12 @@ class InspectorDock : public VBoxContainer {
void _select_history(int p_idx);
void _prepare_history();
- void _property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance);
- void _transform_keyed(Object *sp, const String &p_sub, const Transform3D &p_key);
-
protected:
static void _bind_methods();
void _notification(int p_what);
public:
void go_back();
- void update_keying();
void edit_resource(const Ref<Resource> &p_resource);
void open_resource(const String &p_type);
void clear();
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index d7c0ba7540..dcc549ec2a 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -301,7 +301,6 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
autoplay->set_pressed(current == player->get_autoplay());
AnimationPlayerEditor::get_singleton()->get_track_editor()->update_keying();
- EditorNode::get_singleton()->update_keying();
_animation_key_editor_seek(timeline_position, false);
}
@@ -829,7 +828,6 @@ void AnimationPlayerEditor::_update_player() {
if (!player) {
AnimationPlayerEditor::get_singleton()->get_track_editor()->update_keying();
- EditorNode::get_singleton()->update_keying();
return;
}
@@ -1795,11 +1793,39 @@ AnimationPlayerEditor::~AnimationPlayerEditor() {
void AnimationPlayerEditorPlugin::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
+ Node3DEditor::get_singleton()->connect("transform_key_request", callable_mp(this, &AnimationPlayerEditorPlugin::_transform_key_request));
+ editor->get_inspector()->connect("property_keyed", callable_mp(this, &AnimationPlayerEditorPlugin::_property_keyed));
+ anim_editor->get_track_editor()->connect("keying_changed", callable_mp(this, &AnimationPlayerEditorPlugin::_update_keying));
+ editor->get_inspector()->connect("edited_object_changed", callable_mp(anim_editor->get_track_editor(), &AnimationTrackEditor::update_keying));
set_force_draw_over_forwarding_enabled();
} break;
}
}
+void AnimationPlayerEditorPlugin::_property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance) {
+ if (!anim_editor->get_track_editor()->has_keying()) {
+ return;
+ }
+ anim_editor->get_track_editor()->insert_value_key(p_keyed, p_value, p_advance);
+}
+
+void AnimationPlayerEditorPlugin::_transform_key_request(Object *sp, const String &p_sub, const Transform3D &p_key) {
+ if (!anim_editor->get_track_editor()->has_keying()) {
+ return;
+ }
+ Node3D *s = Object::cast_to<Node3D>(sp);
+ if (!s) {
+ return;
+ }
+ anim_editor->get_track_editor()->insert_transform_key(s, p_sub, Animation::TYPE_POSITION_3D, p_key.origin);
+ anim_editor->get_track_editor()->insert_transform_key(s, p_sub, Animation::TYPE_ROTATION_3D, p_key.basis.get_rotation_quaternion());
+ anim_editor->get_track_editor()->insert_transform_key(s, p_sub, Animation::TYPE_SCALE_3D, p_key.basis.get_scale());
+}
+
+void AnimationPlayerEditorPlugin::_update_keying() {
+ editor->get_inspector()->set_keying(anim_editor->get_track_editor()->has_keying());
+}
+
void AnimationPlayerEditorPlugin::edit(Object *p_object) {
anim_editor->set_undo_redo(&get_undo_redo());
if (!p_object) {
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 626d31f439..06dca11aff 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -255,6 +255,10 @@ class AnimationPlayerEditorPlugin : public EditorPlugin {
protected:
void _notification(int p_what);
+ void _property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance);
+ void _transform_key_request(Object *sp, const String &p_sub, const Transform3D &p_key);
+ void _update_keying();
+
public:
virtual Dictionary get_state() const override { return anim_editor->get_state(); }
virtual void set_state(const Dictionary &p_state) override { anim_editor->set_state(p_state); }
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 31ef13a2eb..5fb3040b75 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -369,11 +369,11 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
download_error->set_text(TTR("Asset Download Error:") + "\n" + error_text);
download_error->popup_centered();
// Let the user retry the download.
- retry->show();
+ retry_button->show();
return;
}
- install->set_disabled(false);
+ install_button->set_disabled(false);
status->set_text(TTR("Success!"));
// Make the progress bar invisible but don't reflow other Controls around it.
progress->set_modulate(Color(0, 0, 0, 0));
@@ -381,7 +381,7 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
set_process(false);
// Automatically prompt for installation once the download is completed.
- _install();
+ install();
}
void EditorAssetLibraryItemDownload::configure(const String &p_title, int p_asset_id, const Ref<Texture2D> &p_preview, const String &p_download_url, const String &p_sha256_hash) {
@@ -400,8 +400,9 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TabContainer")));
- dismiss->set_normal_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
+ panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("AssetLib")));
+ status->add_theme_color_override("font_color", get_theme_color(SNAME("status_color"), SNAME("AssetLib")));
+ dismiss_button->set_normal_texture(get_theme_icon(SNAME("dismiss"), SNAME("AssetLib")));
} break;
case NOTIFICATION_PROCESS: {
// Make the progress bar visible again when retrying the download.
@@ -461,7 +462,7 @@ void EditorAssetLibraryItemDownload::_close() {
queue_delete();
}
-void EditorAssetLibraryItemDownload::_install() {
+void EditorAssetLibraryItemDownload::install() {
String file = download->get_download_file();
if (external_install) {
@@ -475,7 +476,7 @@ void EditorAssetLibraryItemDownload::_install() {
void EditorAssetLibraryItemDownload::_make_request() {
// Hide the Retry button if we've just pressed it.
- retry->hide();
+ retry_button->hide();
download->cancel_request();
download->set_download_file(EditorPaths::get_singleton()->get_cache_dir().plus_file("tmp_asset_" + itos(asset_id)) + ".zip");
@@ -499,6 +500,8 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
HBoxContainer *hb = memnew(HBoxContainer);
panel->add_child(hb);
icon = memnew(TextureRect);
+ icon->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
+ icon->set_v_size_flags(0);
hb->add_child(icon);
VBoxContainer *vb = memnew(VBoxContainer);
@@ -511,9 +514,9 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
title_hb->add_child(title);
title->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- dismiss = memnew(TextureButton);
- dismiss->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDownload::_close));
- title_hb->add_child(dismiss);
+ dismiss_button = memnew(TextureButton);
+ dismiss_button->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDownload::_close));
+ title_hb->add_child(dismiss_button);
title->set_clip_text(true);
@@ -521,7 +524,6 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
status = memnew(Label(TTR("Idle")));
vb->add_child(status);
- status->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5));
progress = memnew(ProgressBar);
vb->add_child(progress);
@@ -529,19 +531,19 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
vb->add_child(hb2);
hb2->add_spacer();
- install = memnew(Button);
- install->set_text(TTR("Install..."));
- install->set_disabled(true);
- install->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDownload::_install));
+ install_button = memnew(Button);
+ install_button->set_text(TTR("Install..."));
+ install_button->set_disabled(true);
+ install_button->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDownload::install));
- retry = memnew(Button);
- retry->set_text(TTR("Retry"));
- retry->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDownload::_make_request));
+ retry_button = memnew(Button);
+ retry_button->set_text(TTR("Retry"));
+ retry_button->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDownload::_make_request));
// Only show the Retry button in case of a failure.
- retry->hide();
+ retry_button->hide();
- hb2->add_child(retry);
- hb2->add_child(install);
+ hb2->add_child(retry_button);
+ hb2->add_child(install_button);
set_custom_minimum_size(Size2(310, 0) * EDSCALE);
download = memnew(HTTPRequest);
@@ -640,14 +642,10 @@ void EditorAssetLibrary::unhandled_key_input(const Ref<InputEvent> &p_event) {
void EditorAssetLibrary::_install_asset() {
ERR_FAIL_COND(!description);
- for (int i = 0; i < downloads_hb->get_child_count(); i++) {
- EditorAssetLibraryItemDownload *d = Object::cast_to<EditorAssetLibraryItemDownload>(downloads_hb->get_child(i));
- if (d && d->get_asset_id() == description->get_asset_id()) {
- if (EditorNode::get_singleton() != nullptr) {
- EditorNode::get_singleton()->show_warning(TTR("Download for this asset is already in progress!"));
- }
- return;
- }
+ EditorAssetLibraryItemDownload *d = _get_asset_in_progress(description->get_asset_id());
+ if (d) {
+ d->install();
+ return;
}
EditorAssetLibraryItemDownload *download = memnew(EditorAssetLibraryItemDownload);
@@ -1265,6 +1263,13 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
description->configure(r["title"], r["asset_id"], category_map[r["category_id"]], r["category_id"], r["author"], r["author_id"], r["cost"], r["version"], r["version_string"], r["description"], r["download_url"], r["browse_url"], r["download_hash"]);
+ EditorAssetLibraryItemDownload *download_item = _get_asset_in_progress(description->get_asset_id());
+ if (download_item) {
+ description->get_ok_button()->set_text(TTR("Install"));
+ } else {
+ description->get_ok_button()->set_text(TTR("Download"));
+ }
+
if (r.has("icon_url") && !r["icon_url"].operator String().is_empty()) {
_request_image(description->get_instance_id(), r["icon_url"], IMAGE_QUEUE_ICON, 0);
}
@@ -1322,6 +1327,17 @@ void EditorAssetLibrary::_manage_plugins() {
ProjectSettingsEditor::get_singleton()->set_plugins_page();
}
+EditorAssetLibraryItemDownload *EditorAssetLibrary::_get_asset_in_progress(int p_asset_id) const {
+ for (int i = 0; i < downloads_hb->get_child_count(); i++) {
+ EditorAssetLibraryItemDownload *d = Object::cast_to<EditorAssetLibraryItemDownload>(downloads_hb->get_child(i));
+ if (d && d->get_asset_id() == p_asset_id) {
+ return d;
+ }
+ }
+
+ return nullptr;
+}
+
void EditorAssetLibrary::_install_external_asset(String p_zip_path, String p_title) {
emit_signal(SNAME("install_asset"), p_zip_path, p_title);
}
diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h
index 8d6c0eb76e..058aafc221 100644
--- a/editor/plugins/asset_library_editor_plugin.h
+++ b/editor/plugins/asset_library_editor_plugin.h
@@ -39,6 +39,7 @@
#include "scene/gui/grid_container.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/link_button.h"
+#include "scene/gui/margin_container.h"
#include "scene/gui/option_button.h"
#include "scene/gui/panel_container.h"
#include "scene/gui/progress_bar.h"
@@ -126,16 +127,16 @@ public:
EditorAssetLibraryItemDescription();
};
-class EditorAssetLibraryItemDownload : public Control {
- GDCLASS(EditorAssetLibraryItemDownload, Control);
+class EditorAssetLibraryItemDownload : public MarginContainer {
+ GDCLASS(EditorAssetLibraryItemDownload, MarginContainer);
PanelContainer *panel;
TextureRect *icon;
Label *title;
ProgressBar *progress;
- Button *install;
- Button *retry;
- TextureButton *dismiss;
+ Button *install_button;
+ Button *retry_button;
+ TextureButton *dismiss_button;
AcceptDialog *download_error;
HTTPRequest *download;
@@ -152,7 +153,6 @@ class EditorAssetLibraryItemDownload : public Control {
EditorAssetInstaller *asset_installer;
void _close();
- void _install();
void _make_request();
void _http_download_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data);
@@ -164,6 +164,7 @@ public:
void set_external_install(bool p_enable) { external_install = p_enable; }
int get_asset_id() { return asset_id; }
void configure(const String &p_title, int p_asset_id, const Ref<Texture2D> &p_preview, const String &p_download_url, const String &p_sha256_hash);
+ void install();
EditorAssetLibraryItemDownload();
};
@@ -287,6 +288,7 @@ class EditorAssetLibrary : public PanelContainer {
void _api_request(const String &p_request, RequestType p_request_type, const String &p_arguments = "");
void _http_request_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data);
void _filter_debounce_timer_timeout();
+ EditorAssetLibraryItemDownload *_get_asset_in_progress(int p_asset_id) const;
void _repository_changed(int p_repository_id);
void _support_toggled(int p_support);
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index d82d0c6ffc..95786176ee 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -136,9 +136,11 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
continue;
}
- //Transform3D shape_transform = sb->shape_owner_get_transform(E);
-
- //shape_transform.set_origin(shape_transform.get_origin() - phys_offset);
+ Transform3D shape_transform;
+ if (p_apply_xforms) {
+ shape_transform = mi->get_transform();
+ }
+ shape_transform *= sb->get_transform() * sb->shape_owner_get_transform(E);
for (int k = 0; k < sb->shape_owner_get_shape_count(E); k++) {
Ref<Shape3D> collision = sb->shape_owner_get_shape(E, k);
@@ -147,7 +149,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
}
MeshLibrary::ShapeData shape_data;
shape_data.shape = collision;
- shape_data.local_transform = sb->get_transform() * sb->shape_owner_get_transform(E);
+ shape_data.local_transform = shape_transform;
collisions.push_back(shape_data);
}
}
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 20f86c6a81..44f8d1a2bb 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -8043,7 +8043,6 @@ Node3DEditorPlugin::Node3DEditorPlugin(EditorNode *p_node) {
editor->get_main_control()->add_child(spatial_editor);
spatial_editor->hide();
- spatial_editor->connect("transform_key_request", Callable(editor->get_inspector_dock(), "_transform_keyed"));
}
Node3DEditorPlugin::~Node3DEditorPlugin() {
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index e1b27cb045..169ce29438 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -149,6 +149,9 @@ void BoneTransformEditor::set_target(const String &p_prop) {
void BoneTransformEditor::_property_keyed(const String &p_path, bool p_advance) {
AnimationTrackEditor *te = AnimationPlayerEditor::get_singleton()->get_track_editor();
+ if (!te->has_keying()) {
+ return;
+ }
PackedStringArray split = p_path.split("/");
if (split.size() == 3 && split[0] == "bones") {
int bone_idx = split[1].to_int();
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index c4f7a3a646..318d014ee5 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -365,21 +365,6 @@ void DisplayServerX11::mouse_warp_to_position(const Point2i &p_to) {
}
Point2i DisplayServerX11::mouse_get_position() const {
- int root_x, root_y;
- int win_x, win_y;
- unsigned int mask_return;
- Window window_returned;
-
- Bool result = XQueryPointer(x11_display, RootWindow(x11_display, DefaultScreen(x11_display)), &window_returned,
- &window_returned, &root_x, &root_y, &win_x, &win_y,
- &mask_return);
- if (result == True) {
- return Point2i(root_x, root_y);
- }
- return Point2i();
-}
-
-Point2i DisplayServerX11::mouse_get_absolute_position() const {
int number_of_screens = XScreenCount(x11_display);
for (int i = 0; i < number_of_screens; i++) {
Window root, child;
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 1dcedabb1a..8929f528d6 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -289,7 +289,6 @@ public:
virtual void mouse_warp_to_position(const Point2i &p_to) override;
virtual Point2i mouse_get_position() const override;
- virtual Point2i mouse_get_absolute_position() const override;
virtual MouseButton mouse_get_button_state() const override;
virtual void clipboard_set(const String &p_text) override;
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index afc2754b0e..d609a84e50 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -98,6 +98,8 @@ public:
NSTimeInterval last_warp = 0;
bool ignore_warp = false;
+ float display_max_scale = 1.f;
+
Vector<KeyEvent> key_event_buffer;
int key_event_pos;
@@ -214,7 +216,6 @@ public:
virtual void mouse_warp_to_position(const Point2i &p_to) override;
virtual Point2i mouse_get_position() const override;
- virtual Point2i mouse_get_absolute_position() const override;
virtual MouseButton mouse_get_button_state() const override;
virtual void clipboard_set(const String &p_text) override;
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 52cabfd821..e3b4333ec8 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -158,12 +158,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
if (wd.transient_parent != DisplayServerOSX::INVALID_WINDOW_ID) {
- DisplayServerOSX::WindowData &pwd = DS_OSX->windows[wd.transient_parent];
- [pwd.window_object makeKeyAndOrderFront:nil]; // Move focus back to parent.
DS_OSX->window_set_transient(window_id, DisplayServerOSX::INVALID_WINDOW_ID);
- } else if ((window_id != DisplayServerOSX::MAIN_WINDOW_ID) && (DS_OSX->windows.size() == 1)) {
- DisplayServerOSX::WindowData &pwd = DS_OSX->windows[DisplayServerOSX::MAIN_WINDOW_ID];
- [pwd.window_object makeKeyAndOrderFront:nil]; // Move focus back to main window if there is no parent or other windows left.
}
#if defined(GLES3_ENABLED)
@@ -2001,10 +1996,6 @@ void DisplayServerOSX::mouse_warp_to_position(const Point2i &p_to) {
}
Point2i DisplayServerOSX::mouse_get_position() const {
- return last_mouse_pos;
-}
-
-Point2i DisplayServerOSX::mouse_get_absolute_position() const {
_THREAD_SAFE_METHOD_
const NSPoint mouse_pos = [NSEvent mouseLocation];
@@ -2071,10 +2062,8 @@ int DisplayServerOSX::get_screen_count() const {
// to convert between OS X native screen coordinates and the ones expected by Godot
static bool displays_arrangement_dirty = true;
-static bool displays_scale_dirty = true;
static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info) {
displays_arrangement_dirty = true;
- displays_scale_dirty = true;
}
Point2i DisplayServerOSX::_get_screens_origin() const {
@@ -2185,15 +2174,8 @@ float DisplayServerOSX::screen_get_scale(int p_screen) const {
float DisplayServerOSX::screen_get_max_scale() const {
_THREAD_SAFE_METHOD_
- static float scale = 1.f;
- if (displays_scale_dirty) {
- int screen_count = get_screen_count();
- for (int i = 0; i < screen_count; i++) {
- scale = fmax(scale, screen_get_scale(i));
- }
- displays_scale_dirty = false;
- }
- return scale;
+ // Note: Do not update max display scale on screen configuration change, existing editor windows can't be rescaled on the fly.
+ return display_max_scale;
}
Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const {
@@ -2380,8 +2362,24 @@ int DisplayServerOSX::window_get_current_screen(WindowID p_window) const {
void DisplayServerOSX::window_set_current_screen(int p_screen, WindowID p_window) {
_THREAD_SAFE_METHOD_
+
+ ERR_FAIL_COND(!windows.has(p_window));
+ WindowData &wd = windows[p_window];
+
+ bool was_fullscreen = false;
+ if (wd.fullscreen) {
+ // Temporary exit fullscreen mode to move window.
+ [wd.window_object toggleFullScreen:nil];
+ was_fullscreen = true;
+ }
+
Point2i wpos = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window));
window_set_position(wpos + screen_get_position(p_screen), p_window);
+
+ if (was_fullscreen) {
+ // Re-enter fullscreen mode.
+ [wd.window_object toggleFullScreen:nil];
+ }
}
void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent) {
@@ -2404,7 +2402,7 @@ void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent
wd_window.transient_parent = INVALID_WINDOW_ID;
wd_parent.transient_children.erase(p_window);
- [wd_parent.window_object removeChildWindow:wd_window.window_object];
+ [wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
} else {
ERR_FAIL_COND(!windows.has(p_parent));
ERR_FAIL_COND_MSG(wd_window.transient_parent != INVALID_WINDOW_ID, "Window already has a transient parent");
@@ -2413,7 +2411,7 @@ void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent
wd_window.transient_parent = p_parent;
wd_parent.transient_children.insert(p_window);
- [wd_parent.window_object addChildWindow:wd_window.window_object ordered:NSWindowAbove];
+ [wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
}
}
@@ -2423,7 +2421,9 @@ Point2i DisplayServerOSX::window_get_position(WindowID p_window) const {
ERR_FAIL_COND_V(!windows.has(p_window), Point2i());
const WindowData &wd = windows[p_window];
- NSRect nsrect = [wd.window_object frame];
+ // Use content rect position (without titlebar / window border).
+ const NSRect contentRect = [wd.window_view frame];
+ const NSRect nsrect = [wd.window_object convertRectToScreen:contentRect];
Point2i pos;
// Return the position of the top-left corner, for OS X the y starts at the bottom
@@ -2451,7 +2451,16 @@ void DisplayServerOSX::window_set_position(const Point2i &p_position, WindowID p
position += _get_screens_origin();
position /= screen_get_max_scale();
- [wd.window_object setFrameTopLeftPoint:NSMakePoint(position.x, position.y)];
+ // Remove titlebar / window border size.
+ const NSRect contentRect = [wd.window_view frame];
+ const NSRect windowRect = [wd.window_object frame];
+ const NSRect nsrect = [wd.window_object convertRectToScreen:contentRect];
+ Point2i offset;
+ offset.x = (nsrect.origin.x - windowRect.origin.x);
+ offset.y = (nsrect.origin.y + nsrect.size.height);
+ offset.y -= (windowRect.origin.y + windowRect.size.height);
+
+ [wd.window_object setFrameTopLeftPoint:NSMakePoint(position.x - offset.x, position.y - offset.y)];
_update_window(wd);
_get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]);
@@ -3699,7 +3708,11 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
keyboard_layout_dirty = true;
displays_arrangement_dirty = true;
- displays_scale_dirty = true;
+
+ int screen_count = get_screen_count();
+ for (int i = 0; i < screen_count; i++) {
+ display_max_scale = fmax(display_max_scale, screen_get_scale(i));
+ }
// Register to be notified on keyboard layout changes
CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(),
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 1271e64945..bcddae45d8 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -674,8 +674,20 @@ void DisplayServerWindows::window_set_current_screen(int p_screen, WindowID p_wi
ERR_FAIL_COND(!windows.has(p_window));
ERR_FAIL_INDEX(p_screen, get_screen_count());
- Vector2 ofs = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window));
- window_set_position(ofs + screen_get_position(p_screen), p_window);
+ const WindowData &wd = windows[p_window];
+ if (wd.fullscreen) {
+ int cs = window_get_current_screen(p_window);
+ if (cs == p_screen) {
+ return;
+ }
+ Point2 pos = screen_get_position(p_screen);
+ Size2 size = screen_get_size(p_screen);
+
+ MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE);
+ } else {
+ Vector2 ofs = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window));
+ window_set_position(ofs + screen_get_position(p_screen), p_window);
+ }
}
Point2i DisplayServerWindows::window_get_position(WindowID p_window) const {
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 62dc4d1c15..5857b6710f 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1809,7 +1809,7 @@ void TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_
// Clear the scenes.
for (const KeyValue<Vector2i, String> &E : q.scenes) {
- Node *node = get_node(E.value);
+ Node *node = get_node_or_null(E.value);
if (node) {
node->queue_delete();
}
@@ -1857,7 +1857,7 @@ void TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_
void TileMap::_scenes_cleanup_quadrant(TileMapQuadrant *p_quadrant) {
// Clear the scenes.
for (const KeyValue<Vector2i, String> &E : p_quadrant->scenes) {
- Node *node = get_node(E.value);
+ Node *node = get_node_or_null(E.value);
if (node) {
node->queue_delete();
}
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 43de4187d4..532b457843 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -281,6 +281,11 @@ void Window::_clear_window() {
DisplayServer::get_singleton()->delete_sub_window(window_id);
window_id = DisplayServer::INVALID_WINDOW_ID;
+ // If closing window was focused and has a parent, return focus.
+ if (focused && transient_parent) {
+ transient_parent->grab_focus();
+ }
+
_update_viewport_size();
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
}
@@ -1574,6 +1579,7 @@ void Window::_bind_methods() {
ADD_SIGNAL(MethodInfo("go_back_requested"));
ADD_SIGNAL(MethodInfo("visibility_changed"));
ADD_SIGNAL(MethodInfo("about_to_popup"));
+ ADD_SIGNAL(MethodInfo("theme_changed"));
BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED);
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index e9f15ab535..eb12b5ffc0 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -139,10 +139,6 @@ void DisplayServer::mouse_warp_to_position(const Point2i &p_to) {
WARN_PRINT("Mouse warping is not supported by this display server.");
}
-Point2i DisplayServer::mouse_get_absolute_position() const {
- ERR_FAIL_V_MSG(Point2i(), "Mouse is not supported by this display server.");
-}
-
Point2i DisplayServer::mouse_get_position() const {
ERR_FAIL_V_MSG(Point2i(), "Mouse is not supported by this display server.");
}
@@ -359,7 +355,6 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("mouse_warp_to_position", "position"), &DisplayServer::mouse_warp_to_position);
ClassDB::bind_method(D_METHOD("mouse_get_position"), &DisplayServer::mouse_get_position);
- ClassDB::bind_method(D_METHOD("mouse_get_absolute_position"), &DisplayServer::mouse_get_absolute_position);
ClassDB::bind_method(D_METHOD("mouse_get_button_state"), &DisplayServer::mouse_get_button_state);
ClassDB::bind_method(D_METHOD("clipboard_set", "clipboard"), &DisplayServer::clipboard_set);
diff --git a/servers/display_server.h b/servers/display_server.h
index d896572b88..2fb9b5946b 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -156,7 +156,6 @@ public:
virtual void mouse_warp_to_position(const Point2i &p_to);
virtual Point2i mouse_get_position() const;
- virtual Point2i mouse_get_absolute_position() const;
virtual MouseButton mouse_get_button_state() const;
virtual void clipboard_set(const String &p_text);
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index a27ea75017..7987a98b0e 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -463,7 +463,6 @@ SceneShaderForwardClustered::MaterialData::~MaterialData() {
RendererStorageRD::MaterialData *SceneShaderForwardClustered::_create_material_func(ShaderData *p_shader) {
MaterialData *material_data = memnew(MaterialData);
material_data->shader_data = p_shader;
- material_data->last_frame = false;
//update will happen later anyway so do nothing.
return material_data;
}
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
index 8e7bbad63e..33049fad9c 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
@@ -189,7 +189,6 @@ public:
}
struct MaterialData : public RendererStorageRD::MaterialData {
- uint64_t last_frame;
ShaderData *shader_data;
RID uniform_set;
uint64_t last_pass = 0;
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index 1613a307ec..0b99948063 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -452,7 +452,6 @@ SceneShaderForwardMobile::MaterialData::~MaterialData() {
RendererStorageRD::MaterialData *SceneShaderForwardMobile::_create_material_func(ShaderData *p_shader) {
MaterialData *material_data = memnew(MaterialData);
material_data->shader_data = p_shader;
- material_data->last_frame = false;
//update will happen later anyway so do nothing.
return material_data;
}
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
index c136afd9f3..92db15e3b0 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
@@ -163,7 +163,6 @@ public:
}
struct MaterialData : public RendererStorageRD::MaterialData {
- uint64_t last_frame;
ShaderData *shader_data;
RID uniform_set;
uint64_t last_pass = 0;
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 7e188926e0..0f3daef371 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1377,14 +1377,6 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
if (md->shader_data->uses_time) {
time_used = true;
}
- if (md->last_frame != RendererCompositorRD::singleton->get_frame_number()) {
- md->last_frame = RendererCompositorRD::singleton->get_frame_number();
- if (!RD::get_singleton()->uniform_set_is_valid(md->uniform_set)) {
- // uniform set may be gone because a dependency was erased. In this case, it will happen
- // if a texture is deleted, so just re-create it.
- storage->material_force_update_textures(material, RendererStorageRD::SHADER_TYPE_2D);
- }
- }
}
}
@@ -2240,7 +2232,6 @@ RendererCanvasRenderRD::MaterialData::~MaterialData() {
RendererStorageRD::MaterialData *RendererCanvasRenderRD::_create_material_func(ShaderData *p_shader) {
MaterialData *material_data = memnew(MaterialData);
material_data->shader_data = p_shader;
- material_data->last_frame = false;
//update will happen later anyway so do nothing.
return material_data;
}
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index b409264c9a..84f64b6fda 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -200,7 +200,6 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
}
struct MaterialData : public RendererStorageRD::MaterialData {
- uint64_t last_frame;
ShaderData *shader_data;
RID uniform_set;
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 3a01c3377a..33f5a178e0 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -3993,7 +3993,6 @@ RendererStorageRD::ShaderData *RendererSceneRenderRD::_create_fog_shader_funcs()
RendererStorageRD::MaterialData *RendererSceneRenderRD::_create_fog_material_func(FogShaderData *p_shader) {
FogMaterialData *material_data = memnew(FogMaterialData);
material_data->shader_data = p_shader;
- material_data->last_frame = false;
//update will happen later anyway so do nothing.
return material_data;
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 08e084f5cc..276cb8f229 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -942,7 +942,6 @@ private:
};
struct FogMaterialData : public RendererStorageRD::MaterialData {
- uint64_t last_frame;
FogShaderData *shader_data;
RID uniform_set;
bool uniform_set_updated;
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index f0419b7907..856ea5e74d 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -750,7 +750,6 @@ RendererStorageRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_funcs() {
RendererStorageRD::MaterialData *RendererSceneSkyRD::_create_sky_material_func(SkyShaderData *p_shader) {
SkyMaterialData *material_data = memnew(SkyMaterialData);
material_data->shader_data = p_shader;
- material_data->last_frame = false;
//update will happen later anyway so do nothing.
return material_data;
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
index 46d376e667..d81a415c2d 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
@@ -228,7 +228,6 @@ public:
} sky_shader;
struct SkyMaterialData : public RendererStorageRD::MaterialData {
- uint64_t last_frame;
SkyShaderData *shader_data;
RID uniform_set;
bool uniform_set_updated;
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 19075fab86..2e63ac57d9 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -2962,24 +2962,19 @@ bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<St
return true;
}
-void RendererStorageRD::_material_uniform_set_erased(const RID &p_set, void *p_material) {
+void RendererStorageRD::_material_uniform_set_erased(void *p_material) {
RID rid = *(RID *)p_material;
Material *material = base_singleton->material_owner.get_or_null(rid);
if (material) {
+ if (material->data) {
+ // Uniform set may be gone because a dependency was erased. This happens
+ // if a texture is deleted, so re-create it.
+ base_singleton->_material_queue_update(material, false, true);
+ }
material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
}
}
-void RendererStorageRD::material_force_update_textures(RID p_material, ShaderType p_shader_type) {
- Material *material = material_owner.get_or_null(p_material);
- if (material->shader_type != p_shader_type) {
- return;
- }
- if (material->data) {
- material->data->update_parameters(material->params, false, true);
- }
-}
-
void RendererStorageRD::_update_queued_materials() {
while (material_update_list.first()) {
Material *material = material_update_list.first()->self();
@@ -5882,8 +5877,6 @@ RendererStorageRD::ShaderData *RendererStorageRD::_create_particles_shader_func(
}
bool RendererStorageRD::ParticlesMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
- uniform_set_updated = true;
-
return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, base_singleton->particles_shader.shader.version_get_shader(shader_data->version, 0), 3);
}
@@ -5894,7 +5887,6 @@ RendererStorageRD::ParticlesMaterialData::~ParticlesMaterialData() {
RendererStorageRD::MaterialData *RendererStorageRD::_create_particles_material_func(ParticlesShaderData *p_shader) {
ParticlesMaterialData *material_data = memnew(ParticlesMaterialData);
material_data->shader_data = p_shader;
- material_data->last_frame = false;
//update will happen later anyway so do nothing.
return material_data;
}
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
index 8c04274c3f..43bbcf6520 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.h
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.h
@@ -177,7 +177,7 @@ public:
Vector<RID> texture_cache;
};
typedef MaterialData *(*MaterialDataRequestFunction)(ShaderData *);
- static void _material_uniform_set_erased(const RID &p_set, void *p_material);
+ static void _material_uniform_set_erased(void *p_material);
enum DefaultRDTexture {
DEFAULT_RD_TEXTURE_WHITE,
@@ -910,10 +910,8 @@ private:
}
struct ParticlesMaterialData : public MaterialData {
- uint64_t last_frame = 0;
ParticlesShaderData *shader_data = nullptr;
RID uniform_set;
- bool uniform_set_updated = false;
virtual void set_render_priority(int p_priority) {}
virtual void set_next_pass(RID p_pass) {}
@@ -1448,7 +1446,6 @@ public:
void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters);
void material_update_dependency(RID p_material, DependencyTracker *p_instance);
- void material_force_update_textures(RID p_material, ShaderType p_shader_type);
void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function);
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index 3e74741de0..655a32a805 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -742,7 +742,7 @@ public:
virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) = 0;
virtual bool uniform_set_is_valid(RID p_uniform_set) = 0;
- typedef void (*UniformSetInvalidatedCallback)(const RID &, void *);
+ typedef void (*UniformSetInvalidatedCallback)(void *);
virtual void uniform_set_set_invalidation_callback(RID p_uniform_set, UniformSetInvalidatedCallback p_callback, void *p_userdata) = 0;
virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index bb6cfd7b03..4e07582187 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -2742,13 +2742,13 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
//stage based function
const StageFunctionInfo &sf = p_function_info.stage_functions[name];
if (argcount != sf.arguments.size()) {
- _set_error(vformat("Invalid number of arguments when calling stage function '%s', which expects %d arguments.", String(name), sf.arguments.size()));
+ _set_error(vformat(RTR("Invalid number of arguments when calling stage function '%s', which expects %d arguments."), String(name), sf.arguments.size()));
return false;
}
//validate arguments
for (int i = 0; i < argcount; i++) {
if (args[i] != sf.arguments[i].type) {
- _set_error(vformat("Invalid argument type when calling stage function '%s', type expected is '%s'.", String(name), String(get_datatype_name(sf.arguments[i].type))));
+ _set_error(vformat(RTR("Invalid argument type when calling stage function '%s', type expected is '%s'."), String(name), get_datatype_name(sf.arguments[i].type)));
return false;
}
}
@@ -2852,7 +2852,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
}
}
if (error) {
- _set_error(vformat("Expected integer constant within %s..%s range.", min, max));
+ _set_error(vformat(RTR("Expected integer constant within [%d..%d] range."), min, max));
return false;
}
}
@@ -2871,7 +2871,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
}
if (arg_idx < argcount) {
if (p_func->arguments[arg_idx + 1]->type != Node::TYPE_VARIABLE && p_func->arguments[arg_idx + 1]->type != Node::TYPE_MEMBER && p_func->arguments[arg_idx + 1]->type != Node::TYPE_ARRAY) {
- _set_error("Argument " + itos(arg_idx + 1) + " of function '" + String(name) + "' is not a variable, array or member.");
+ _set_error(vformat(RTR("Argument %d of function '%s' is not a variable, array, or member."), arg_idx + 1, String(name)));
return false;
}
@@ -2895,7 +2895,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
fail = true;
} else {
if (shader->varyings.has(varname)) {
- _set_error(vformat("Varyings cannot be passed for '%s' parameter!", "out"));
+ _set_error(vformat(RTR("Varyings cannot be passed for the '%s' parameter."), "out"));
return false;
}
if (p_function_info.built_ins.has(varname)) {
@@ -2908,7 +2908,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
}
}
if (fail) {
- _set_error(vformat("Constant value cannot be passed for '%s' parameter!", "out"));
+ _set_error(vformat(RTR("A constant value cannot be passed for the '%s' parameter."), "out"));
return false;
}
@@ -2921,7 +2921,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
n = static_cast<const MemberNode *>(n)->owner;
}
if (n->type != Node::TYPE_VARIABLE && n->type != Node::TYPE_ARRAY) {
- _set_error("Argument " + itos(arg_idx + 1) + " of function '" + String(name) + "' is not a variable, array or member.");
+ _set_error(vformat(RTR("Argument %d of function '%s' is not a variable, array, or member."), arg_idx + 1, String(name)));
return false;
}
if (n->type == Node::TYPE_VARIABLE) {
@@ -2951,7 +2951,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
}
if (!valid) {
- _set_error("Argument " + itos(arg_idx + 1) + " of function '" + String(name) + "' can only take a local variable, array or member.");
+ _set_error(vformat(RTR("Argument %d of function '%s' can only take a local variable, array, or member."), arg_idx + 1, String(name)));
return false;
}
}
@@ -2998,16 +2998,15 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
arglist += get_datatype_name(builtin_func_defs[builtin_idx].args[i]);
}
- String err = "Built-in function \"" + String(name) + "(" + arglist + ")\" is supported only on high-end platform!";
- _set_error(err);
+ _set_error(vformat(RTR("Built-in function \"%s(%s)\" is only supported on high-end platforms."), String(name), arglist));
return false;
}
if (failed_builtin) {
- String err = "Invalid arguments for built-in function: " + String(name) + "(";
+ String arg_list;
for (int i = 0; i < argcount; i++) {
if (i > 0) {
- err += ",";
+ arg_list += ",";
}
String arg_name;
@@ -3021,10 +3020,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
arg_name += itos(args3[i]);
arg_name += "]";
}
- err += arg_name;
+ arg_list += arg_name;
}
- err += ")";
- _set_error(err);
+ _set_error(vformat(RTR("Invalid arguments for the built-in function: \"%s(%s)\"."), String(name), arg_list));
return false;
}
@@ -3041,7 +3039,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
}
if (name == exclude_function) {
- _set_error("Recursion is not allowed");
+ _set_error(RTR("Recursion is not allowed."));
return false;
}
@@ -3054,7 +3052,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
}
if (!shader->functions[i].callable) {
- _set_error("Function '" + String(name) + " can't be called from source code.");
+ _set_error(vformat(RTR("Function '%s' can't be called from source code."), String(name)));
return false;
}
@@ -3113,7 +3111,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
arg_name += "]";
}
- _set_error(vformat("Invalid argument for \"%s(%s)\" function: argument %s should be %s but is %s.", String(name), arg_list, j + 1, func_arg_name, arg_name));
+ _set_error(vformat(RTR("Invalid argument for \"%s(%s)\" function: argument %d should be %s but is %s."), String(name), arg_list, j + 1, func_arg_name, arg_name));
fail = true;
break;
}
@@ -3150,9 +3148,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
}
if (last_arg_count > args.size()) {
- _set_error(vformat("Too few arguments for \"%s(%s)\" call. Expected at least %s but received %s.", String(name), arg_list, last_arg_count, args.size()));
+ _set_error(vformat(RTR("Too few arguments for \"%s(%s)\" call. Expected at least %d but received %d."), String(name), arg_list, last_arg_count, args.size()));
} else if (last_arg_count < args.size()) {
- _set_error(vformat("Too many arguments for \"%s(%s)\" call. Expected at most %s but received %s.", String(name), arg_list, last_arg_count, args.size()));
+ _set_error(vformat(RTR("Too many arguments for \"%s(%s)\" call. Expected at most %d but received %d."), String(name), arg_list, last_arg_count, args.size()));
}
return false;
@@ -3190,7 +3188,7 @@ bool ShaderLanguage::_compare_datatypes(DataType p_datatype_a, String p_datatype
type_name2 += "]";
}
- _set_error("Invalid assignment of '" + type_name2 + "' to '" + type_name + "'");
+ _set_error(vformat(RTR("Invalid assignment of '%s' to '%s'."), type_name2, type_name));
}
return result;
}
@@ -3235,7 +3233,7 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Functio
return true;
} else if (tk.type != TK_COMMA) {
// something is broken
- _set_error("Expected ',' or ')' after argument");
+ _set_error(RTR("Expected ',' or ')' after argument."));
return false;
}
}
@@ -4247,14 +4245,14 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam
ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
if (arg->tex_builtin_check) {
- _set_error("Sampler argument #" + itos(p_argument) + " of function '" + String(p_name) + "' called more than once using both built-ins and uniform textures, this is not supported (use either one or the other).");
+ _set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using both built-ins and uniform textures, this is not supported (use either one or the other)."), p_argument, String(p_name)));
return false;
} else if (arg->tex_argument_check) {
//was checked, verify that filter and repeat are the same
if (arg->tex_argument_filter == p_filter && arg->tex_argument_repeat == p_repeat) {
return true;
} else {
- _set_error("Sampler argument #" + itos(p_argument) + " of function '" + String(p_name) + "' called more than once using textures that differ in either filter or repeat setting.");
+ _set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using textures that differ in either filter or repeat setting."), p_argument, String(p_name)));
return false;
}
} else {
@@ -4281,14 +4279,14 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa
ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
if (arg->tex_argument_check) {
- _set_error("Sampler argument #" + itos(p_argument) + " of function '" + String(p_name) + "' called more than once using both built-ins and uniform textures, this is not supported (use either one or the other).");
+ _set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using both built-ins and uniform textures, this is not supported (use either one or the other)."), p_argument, String(p_name)));
return false;
} else if (arg->tex_builtin_check) {
//was checked, verify that the built-in is the same
if (arg->tex_builtin == p_builtin) {
return true;
} else {
- _set_error("Sampler argument #" + itos(p_argument) + " of function '" + String(p_name) + "' called more than once using different built-ins. Only calling with the same built-in is supported.");
+ _set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using different built-ins. Only calling with the same built-in is supported."), p_argument, String(p_name)));
return false;
}
} else {
@@ -4318,7 +4316,7 @@ Error ShaderLanguage::_parse_array_size(BlockNode *p_block, const FunctionInfo &
error = true;
}
if (error) {
- _set_error("Array size is already defined!");
+ _set_error(vformat(RTR("Array size is already defined.")));
return ERR_PARSE_ERROR;
}
@@ -4327,7 +4325,7 @@ Error ShaderLanguage::_parse_array_size(BlockNode *p_block, const FunctionInfo &
if (tk.type == TK_BRACKET_CLOSE) {
if (p_forbid_unknown_size) {
- _set_error("Unknown array size is forbidden in that context!");
+ _set_error(vformat(RTR("Unknown array size is forbidden in that context.")));
return ERR_PARSE_ERROR;
}
if (r_unknown_size != nullptr) {
@@ -4364,7 +4362,7 @@ Error ShaderLanguage::_parse_array_size(BlockNode *p_block, const FunctionInfo &
}
}
} else if (n->type == Node::TYPE_OPERATOR) {
- _set_error("Array size expressions are not yet implemented.");
+ _set_error(vformat(RTR("Array size expressions are not supported.")));
return ERR_PARSE_ERROR;
}
if (r_size_expression != nullptr) {
@@ -4376,13 +4374,13 @@ Error ShaderLanguage::_parse_array_size(BlockNode *p_block, const FunctionInfo &
}
if (array_size <= 0) {
- _set_error("Expected single integer constant > 0");
+ _set_error(RTR("Expected a positive integer constant."));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
+ _set_expected_error("]");
return ERR_PARSE_ERROR;
}
@@ -4409,7 +4407,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc
struct_name = tk.text;
} else {
if (!is_token_variable_datatype(tk.type)) {
- _set_error("Invalid data type for array");
+ _set_error(RTR("Invalid data type for the array."));
return nullptr;
}
type = get_token_datatype(tk.type);
@@ -4422,7 +4420,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc
}
tk = _get_token();
} else {
- _set_error("Expected '['");
+ _set_expected_error("[");
return nullptr;
}
}
@@ -4460,20 +4458,20 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc
break;
} else {
if (auto_size) {
- _set_error("Expected '}' or ','");
+ _set_expected_error("}", ",");
} else {
- _set_error("Expected ')' or ','");
+ _set_expected_error(")", ",");
}
return nullptr;
}
idx++;
}
if (!auto_size && !undefined_size && an->initializer.size() != array_size) {
- _set_error("Array size mismatch");
+ _set_error(RTR("Array size mismatch."));
return nullptr;
}
} else {
- _set_error("Expected array initialization!");
+ _set_error(RTR("Expected array initialization."));
return nullptr;
}
@@ -4503,7 +4501,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc
Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
- _set_error("Invalid data type for array");
+ _set_error(RTR("Invalid data type for the array."));
return nullptr;
}
@@ -4526,30 +4524,32 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc
}
tk = _get_token();
} else {
- _set_error("Expected '['");
+ _set_expected_error("[");
return nullptr;
}
if (type != p_type || struct_name != p_struct_name || array_size != p_array_size) {
- String error_str = "Cannot convert from '";
+ String from;
if (type == TYPE_STRUCT) {
- error_str += struct_name;
+ from += struct_name;
} else {
- error_str += get_datatype_name(type);
+ from += get_datatype_name(type);
}
- error_str += "[";
- error_str += itos(array_size);
- error_str += "]'";
- error_str += " to '";
+ from += "[";
+ from += itos(array_size);
+ from += "]'";
+
+ String to;
if (type == TYPE_STRUCT) {
- error_str += p_struct_name;
+ to += p_struct_name;
} else {
- error_str += get_datatype_name(p_type);
+ to += get_datatype_name(p_type);
}
- error_str += "[";
- error_str += itos(p_array_size);
- error_str += "]'";
- _set_error(error_str);
+ to += "[";
+ to += itos(p_array_size);
+ to += "]'";
+
+ _set_error(vformat(RTR("Cannot convert from '%s' to '%s'."), from, to));
return nullptr;
}
}
@@ -4580,19 +4580,19 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc
break;
} else {
if (auto_size) {
- _set_error("Expected '}' or ','");
+ _set_expected_error("}", ",");
} else {
- _set_error("Expected ')' or ','");
+ _set_expected_error(")", ",");
}
return nullptr;
}
}
if (an->initializer.size() != p_array_size) {
- _set_error("Array size mismatch");
+ _set_error(RTR("Array size mismatch."));
return nullptr;
}
} else {
- _set_error("Expected array initialization!");
+ _set_error(RTR("Expected array initialization."));
return nullptr;
}
@@ -4623,7 +4623,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' in expression");
+ _set_error(RTR("Expected ')' in expression."));
return nullptr;
}
@@ -4671,7 +4671,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else if (tk.type == TK_TYPE_VOID) {
//make sure void is not used in expression
- _set_error("Void value not allowed in Expression");
+ _set_error(RTR("Void value not allowed in expression."));
return nullptr;
} else if (is_token_nonvoid_datatype(tk.type) || tk.type == TK_CURLY_BRACKET_OPEN) {
if (tk.type == TK_CURLY_BRACKET_OPEN) {
@@ -4700,7 +4700,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr = _parse_array_constructor(p_block, p_function_info);
} else {
if (tk.type != TK_PARENTHESIS_OPEN) {
- _set_error("Expected '(' after type name");
+ _set_error(RTR("Expected '(' after the type name."));
return nullptr;
}
//basic type constructor
@@ -4733,7 +4733,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name)) {
- _set_error("No matching constructor found for: '" + String(funcname->name) + "'");
+ _set_error(vformat(RTR("No matching constructor found for: '%s'."), String(funcname->name)));
return nullptr;
}
@@ -4790,7 +4790,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (i + 1 < pstruct->members.size()) {
tk = _get_token();
if (tk.type != TK_COMMA) {
- _set_error("Expected ','");
+ _set_expected_error(",");
return nullptr;
}
}
@@ -4798,7 +4798,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')'");
+ _set_expected_error(")");
return nullptr;
}
@@ -4822,7 +4822,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
ShaderLanguage::BlockNode *bnode = p_block;
while (bnode) {
if (bnode->variables.has(name)) {
- _set_error("Expected function name");
+ _set_error(RTR("Expected a function name."));
return nullptr;
}
bnode = bnode->parent_block;
@@ -4859,7 +4859,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name)) {
- _set_error("No matching function found for: '" + String(funcname->name) + "'");
+ _set_error(vformat(RTR("No matching function found for: '%s'."), String(funcname->name)));
return nullptr;
}
completion_class = TAG_GLOBAL; // reset sub-class
@@ -4912,7 +4912,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (shader->varyings.has(varname)) {
switch (shader->varyings[varname].stage) {
case ShaderNode::Varying::STAGE_UNKNOWN: {
- _set_error(vformat("Varying '%s' must be assigned in the vertex or fragment function first!", varname));
+ _set_error(vformat(RTR("Varying '%s' must be assigned in the vertex or fragment function first."), varname));
return nullptr;
}
case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT:
@@ -4938,7 +4938,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
if (error) {
- _set_error(vformat("Varying '%s' cannot be passed for the '%s' parameter in that context!", varname, _get_qualifier_str(arg_qual)));
+ _set_error(vformat(RTR("Varying '%s' cannot be passed for the '%s' parameter in that context."), varname, _get_qualifier_str(arg_qual)));
return nullptr;
}
}
@@ -4985,7 +4985,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
if (error) {
- _set_error(vformat("Constant value cannot be passed for '%s' parameter!", _get_qualifier_str(arg_qual)));
+ _set_error(vformat(RTR("A constant value cannot be passed for '%s' parameter."), _get_qualifier_str(arg_qual)));
return nullptr;
}
}
@@ -5067,12 +5067,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
idx++;
}
if (!found) {
- _set_error("Unknown identifier in expression: " + String(identifier));
+ _set_error(vformat(RTR("Unknown identifier in expression: '%s'."), String(identifier)));
return nullptr;
}
} else {
if (!_find_identifier(p_block, false, p_function_info, identifier, &data_type, &ident_type, &is_const, &array_size, &struct_name)) {
- _set_error("Unknown identifier in expression: " + String(identifier));
+ _set_error(vformat(RTR("Unknown identifier in expression: '%s'."), String(identifier)));
return nullptr;
}
if (ident_type == IDENTIFIER_VARYING) {
@@ -5114,7 +5114,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
if (ident_type == IDENTIFIER_FUNCTION) {
- _set_error("Can't use function as identifier: " + String(identifier));
+ _set_error(vformat(RTR("Can't use function as identifier: '%s'."), String(identifier)));
return nullptr;
}
if (is_const) {
@@ -5136,7 +5136,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (tk.type == TK_OP_ASSIGN) {
if (is_const) {
- _set_error("Constants cannot be modified.");
+ _set_error(RTR("Constants cannot be modified."));
return nullptr;
}
assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size);
@@ -5159,7 +5159,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
if (index_expression->get_array_size() != 0 || (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT)) {
- _set_error("Only integer expressions are allowed for indexing.");
+ _set_error(RTR("Only integer expressions are allowed for indexing."));
return nullptr;
}
@@ -5169,7 +5169,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (!cnode->values.is_empty()) {
int value = cnode->values[0].sint;
if (value < 0 || value >= array_size) {
- _set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1));
+ _set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), value, 0, array_size - 1));
return nullptr;
}
}
@@ -5178,7 +5178,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
+ _set_expected_error("]");
return nullptr;
}
} else {
@@ -5247,12 +5247,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
continue;
} else {
if (tk.type != TK_SEMICOLON) {
- _set_error("Expected expression, found: " + get_token_text(tk));
+ _set_error(vformat(RTR("Expected expression, found: '%s'."), get_token_text(tk)));
return nullptr;
} else {
#ifdef DEBUG_ENABLED
if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) {
- _add_line_warning(ShaderWarning::FORMATTING_ERROR, "Empty statement. Remove ';' to fix this warning.");
+ _add_line_warning(ShaderWarning::FORMATTING_ERROR, RTR("Empty statement. Remove ';' to fix this warning."));
}
#endif // DEBUG_ENABLED
_set_tkpos(prepos);
@@ -5299,7 +5299,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
if (identifier == StringName()) {
- _set_error("Expected identifier as member");
+ _set_error(RTR("Expected an identifier as a member."));
return nullptr;
}
String ident = identifier;
@@ -5544,12 +5544,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
if (mix_error) {
- _set_error("Cannot combine symbols from different sets in expression ." + ident);
+ _set_error(vformat(RTR("Cannot combine symbols from different sets in expression '.%s'."), ident));
return nullptr;
}
if (!ok) {
- _set_error("Invalid member for " + (dt == TYPE_STRUCT ? st : get_datatype_name(dt)) + " expression: ." + ident);
+ _set_error(vformat(RTR("Invalid member for '%s' expression: '.%s'."), (dt == TYPE_STRUCT ? st : get_datatype_name(dt)), ident));
return nullptr;
}
@@ -5569,7 +5569,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
tk = _get_token();
if (tk.type == TK_OP_ASSIGN) {
if (last_type == IDENTIFIER_CONSTANT) {
- _set_error("Constants cannot be modified.");
+ _set_error(RTR("Constants cannot be modified."));
return nullptr;
}
Node *assign_expression = _parse_array_constructor(p_block, p_function_info, member_type, member_struct_name, array_size);
@@ -5594,7 +5594,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
if (index_expression->get_array_size() != 0 || (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT)) {
- _set_error("Only integer expressions are allowed for indexing.");
+ _set_error(RTR("Only integer expressions are allowed for indexing."));
return nullptr;
}
@@ -5604,7 +5604,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (!cnode->values.is_empty()) {
int value = cnode->values[0].sint;
if (value < 0 || value >= array_size) {
- _set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1));
+ _set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), value, 0, array_size - 1));
return nullptr;
}
}
@@ -5613,7 +5613,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
+ _set_expected_error("]");
return nullptr;
}
mn->index_expression = index_expression;
@@ -5640,7 +5640,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
if (index->get_array_size() != 0 || (index->get_datatype() != TYPE_INT && index->get_datatype() != TYPE_UINT)) {
- _set_error("Only integer expressions are allowed for indexing.");
+ _set_error(RTR("Only integer expressions are allowed for indexing."));
return nullptr;
}
@@ -5651,7 +5651,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (index->type == Node::TYPE_CONSTANT) {
uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
if (index_constant >= (uint32_t)expr->get_array_size()) {
- _set_error(vformat("Index [%s] out of range [%s..%s]", index_constant, 0, expr->get_array_size() - 1));
+ _set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), index_constant, 0, expr->get_array_size() - 1));
return nullptr;
}
}
@@ -5669,7 +5669,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (index->type == Node::TYPE_CONSTANT) {
uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
if (index_constant >= 2) {
- _set_error("Index out of range (0-1)");
+ _set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), index_constant, 0, 1));
return nullptr;
}
}
@@ -5703,7 +5703,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (index->type == Node::TYPE_CONSTANT) {
uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
if (index_constant >= 3) {
- _set_error("Index out of range (0-2)");
+ _set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), index_constant, 0, 2));
return nullptr;
}
}
@@ -5736,7 +5736,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (index->type == Node::TYPE_CONSTANT) {
uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
if (index_constant >= 4) {
- _set_error("Index out of range (0-3)");
+ _set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), index_constant, 0, 3));
return nullptr;
}
}
@@ -5762,7 +5762,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
break;
default: {
- _set_error("Object of type '" + (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype())) + "' can't be indexed");
+ _set_error(vformat(RTR("An object of type '%s' can't be indexed."), (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype()))));
return nullptr;
}
}
@@ -5777,7 +5777,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']' after indexing expression");
+ _set_expected_error("]");
return nullptr;
}
@@ -5787,12 +5787,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
op->arguments.push_back(expr);
if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) {
- _set_error("Invalid base type for increment/decrement operator");
+ _set_error(RTR("Invalid base type for increment/decrement operator."));
return nullptr;
}
if (!_validate_assign(expr, p_function_info)) {
- _set_error("Invalid use of increment/decrement operator in constant expression.");
+ _set_error(RTR("Invalid use of increment/decrement operator in a constant expression."));
return nullptr;
}
expr = op;
@@ -5909,7 +5909,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
o.op = OP_SELECT_ELSE;
break;
default: {
- _set_error("Invalid token for operator: " + get_token_text(tk));
+ _set_error(vformat(RTR("Invalid token for the operator: '%s'."), get_token_text(tk)));
return nullptr;
}
}
@@ -6088,7 +6088,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr_pos++;
if (expr_pos == expression.size()) {
//can happen..
- _set_error("Unexpected end of expression...");
+ _set_error(RTR("Unexpected end of expression."));
return nullptr;
}
}
@@ -6098,7 +6098,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
OperatorNode *op = alloc_node<OperatorNode>();
op->op = expression[i].op;
if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_function_info)) {
- _set_error("Can't use increment/decrement operator in constant expression.");
+ _set_error(RTR("Can't use increment/decrement operator in a constant expression."));
return nullptr;
}
op->arguments.push_back(expression[i + 1].node);
@@ -6110,7 +6110,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
String at;
for (int j = 0; j < op->arguments.size(); j++) {
if (j > 0) {
- at += " and ";
+ at += ", ";
}
at += get_datatype_name(op->arguments[j]->get_datatype());
if (!op->arguments[j]->is_indexed() && op->arguments[j]->get_array_size() > 0) {
@@ -6119,7 +6119,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
at += "]";
}
}
- _set_error("Invalid arguments to unary operator '" + get_operator_text(op->op) + "' :" + at);
+ _set_error(vformat(RTR("Invalid arguments to unary operator '%s': %s."), get_operator_text(op->op), at));
return nullptr;
}
expression.remove_at(i + 1);
@@ -6127,12 +6127,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else if (is_ternary) {
if (next_op < 1 || next_op >= (expression.size() - 1)) {
- _set_error("Parser bug...");
+ _set_parsing_error();
ERR_FAIL_V(nullptr);
}
if (next_op + 2 >= expression.size() || !expression[next_op + 2].is_op || expression[next_op + 2].op != OP_SELECT_ELSE) {
- _set_error("Missing matching ':' for select operator");
+ _set_error(RTR("Missing matching ':' for select operator."));
return nullptr;
}
@@ -6148,7 +6148,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
String at;
for (int i = 0; i < op->arguments.size(); i++) {
if (i > 0) {
- at += " and ";
+ at += ", ";
}
at += get_datatype_name(op->arguments[i]->get_datatype());
if (!op->arguments[i]->is_indexed() && op->arguments[i]->get_array_size() > 0) {
@@ -6157,7 +6157,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
at += "]";
}
}
- _set_error("Invalid argument to ternary ?: operator: " + at);
+ _set_error(vformat(RTR("Invalid argument to ternary operator: '%s'."), at));
return nullptr;
}
@@ -6167,7 +6167,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else {
if (next_op < 1 || next_op >= (expression.size() - 1)) {
- _set_error("Parser bug...");
+ _set_parsing_error();
ERR_FAIL_V(nullptr);
}
@@ -6175,7 +6175,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
op->op = expression[next_op].op;
if (expression[next_op - 1].is_op) {
- _set_error("Parser bug...");
+ _set_parsing_error();
ERR_FAIL_V(nullptr);
}
@@ -6193,7 +6193,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
// can be followed by a unary op in a valid combination,
// due to how precedence works, unaries will always disappear first
- _set_error("Parser bug...");
+ _set_parsing_error();
}
op->arguments.push_back(expression[next_op - 1].node); //expression goes as left
@@ -6206,7 +6206,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
String at;
for (int i = 0; i < op->arguments.size(); i++) {
if (i > 0) {
- at += " and ";
+ at += ", ";
}
if (op->arguments[i]->get_datatype() == TYPE_STRUCT) {
at += op->arguments[i]->get_datatype_name();
@@ -6219,7 +6219,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
at += "]";
}
}
- _set_error("Invalid arguments to operator '" + get_operator_text(op->op) + "' :" + at);
+ _set_error(vformat(RTR("Invalid arguments to operator '%s': '%s'."), get_operator_text(op->op), at));
return nullptr;
}
@@ -6359,7 +6359,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_SWITCH) {
if (tk.type != TK_CF_CASE && tk.type != TK_CF_DEFAULT && tk.type != TK_CURLY_BRACKET_CLOSE) {
- _set_error("Switch may contains only case and default blocks");
+ _set_error(vformat(RTR("A switch may only contain '%s' and '%s' blocks."), "case", "default"));
return ERR_PARSE_ERROR;
}
}
@@ -6368,7 +6368,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (tk.type == TK_CURLY_BRACKET_CLOSE) { //end of block
if (p_just_one) {
- _set_error("Unexpected '}'");
+ _set_expected_error("}");
return ERR_PARSE_ERROR;
}
@@ -6406,18 +6406,18 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
is_struct = shader->structs.has(tk.text); // check again.
}
if (is_struct && precision != PRECISION_DEFAULT) {
- _set_error("Precision modifier cannot be used on structs.");
+ _set_error(RTR("The precision modifier cannot be used on structs."));
return ERR_PARSE_ERROR;
}
if (!is_token_nonvoid_datatype(tk.type)) {
- _set_error("Expected datatype after precision");
+ _set_error(RTR("Expected variable type after precision modifier."));
return ERR_PARSE_ERROR;
}
}
if (!is_struct) {
if (!is_token_variable_datatype(tk.type)) {
- _set_error("Invalid data type for variable (samplers not allowed)");
+ _set_error(RTR("Invalid variable type (samplers are not allowed)."));
return ERR_PARSE_ERROR;
}
}
@@ -6452,7 +6452,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
first = false;
if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
- _set_error("Expected identifier or '[' after datatype.");
+ _set_error(RTR("Expected an identifier or '[' after type."));
return ERR_PARSE_ERROR;
}
@@ -6469,7 +6469,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
if (tk.type != TK_IDENTIFIER) {
- _set_error("Expected identifier!");
+ _set_error(RTR("Expected an identifier."));
return ERR_PARSE_ERROR;
}
@@ -6477,7 +6477,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
ShaderLanguage::IdentifierType itype;
if (_find_identifier(p_block, true, p_function_info, name, (ShaderLanguage::DataType *)nullptr, &itype)) {
if (itype != IDENTIFIER_FUNCTION) {
- _set_error("Redefinition of '" + String(name) + "'");
+ _set_redefinition_error(String(name));
return ERR_PARSE_ERROR;
}
}
@@ -6509,7 +6509,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (tk.type == TK_BRACKET_OPEN) {
if (RenderingServer::get_singleton()->is_low_end() && is_const) {
- _set_error("Local const arrays are supported only on high-end platform!");
+ _set_error(RTR("Local const arrays are only supported on high-end platforms."));
return ERR_PARSE_ERROR;
}
@@ -6529,7 +6529,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (tk.type == TK_OP_ASSIGN) {
if (RenderingServer::get_singleton()->is_low_end()) {
- _set_error("Array initialization is supported only on high-end platform!");
+ _set_error(RTR("Array initialization is only supported on high-end platforms."));
return ERR_PARSE_ERROR;
}
@@ -6541,7 +6541,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
- _set_error("Expected correct array initializer!");
+ _set_error(RTR("Expected array initializer."));
return ERR_PARSE_ERROR;
} else {
if (unknown_size) {
@@ -6561,7 +6561,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
} else {
if (tk.type != TK_CURLY_BRACKET_OPEN) {
if (unknown_size) {
- _set_error("Expected '{'");
+ _set_expected_error("{");
return ERR_PARSE_ERROR;
}
@@ -6572,11 +6572,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
precision2 = get_token_precision(tk.type);
tk = _get_token();
if (shader->structs.has(tk.text)) {
- _set_error("Precision modifier cannot be used on structs.");
+ _set_error(RTR("The precision modifier cannot be used on structs."));
return ERR_PARSE_ERROR;
}
if (!is_token_nonvoid_datatype(tk.type)) {
- _set_error("Expected datatype after precision");
+ _set_error(RTR("Expected data type after precision modifier."));
return ERR_PARSE_ERROR;
}
}
@@ -6589,7 +6589,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
struct_name2 = tk.text;
} else {
if (!is_token_variable_datatype(tk.type)) {
- _set_error("Invalid data type for array");
+ _set_error(RTR("Invalid data type for the array."));
return ERR_PARSE_ERROR;
}
type2 = get_token_datatype(tk.type);
@@ -6609,38 +6609,40 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
tk = _get_token();
} else {
- _set_error("Expected '['");
+ _set_expected_error("[");
return ERR_PARSE_ERROR;
}
if (precision != precision2 || type != type2 || struct_name != struct_name2 || var.array_size != array_size2) {
- String error_str = "Cannot convert from '";
+ String from;
if (precision2 != PRECISION_DEFAULT) {
- error_str += get_precision_name(precision2);
- error_str += " ";
+ from += get_precision_name(precision2);
+ from += " ";
}
if (type2 == TYPE_STRUCT) {
- error_str += struct_name2;
+ from += struct_name2;
} else {
- error_str += get_datatype_name(type2);
+ from += get_datatype_name(type2);
}
- error_str += "[";
- error_str += itos(array_size2);
- error_str += "]'";
- error_str += " to '";
+ from += "[";
+ from += itos(array_size2);
+ from += "]'";
+
+ String to;
if (precision != PRECISION_DEFAULT) {
- error_str += get_precision_name(precision);
- error_str += " ";
+ to += get_precision_name(precision);
+ to += " ";
}
if (type == TYPE_STRUCT) {
- error_str += struct_name;
+ to += struct_name;
} else {
- error_str += get_datatype_name(type);
+ to += get_datatype_name(type);
}
- error_str += "[";
- error_str += itos(var.array_size);
- error_str += "]'";
- _set_error(error_str);
+ to += "[";
+ to += itos(var.array_size);
+ to += "]'";
+
+ _set_error(vformat(RTR("Cannot convert from '%s' to '%s'."), from, to));
return ERR_PARSE_ERROR;
}
}
@@ -6649,13 +6651,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (unknown_size) {
if (!curly) {
- _set_error("Expected '{'");
+ _set_expected_error("{");
return ERR_PARSE_ERROR;
}
} else {
if (full_def) {
if (curly) {
- _set_error("Expected '('");
+ _set_expected_error("(");
return ERR_PARSE_ERROR;
}
}
@@ -6669,7 +6671,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
if (is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) {
- _set_error("Expected constant expression");
+ _set_error(RTR("Expected a constant expression."));
return ERR_PARSE_ERROR;
}
@@ -6689,9 +6691,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
break;
} else {
if (curly) {
- _set_error("Expected '}' or ','");
+ _set_expected_error("}", ",");
} else {
- _set_error("Expected ')' or ','");
+ _set_expected_error(")", ",");
}
return ERR_PARSE_ERROR;
}
@@ -6700,7 +6702,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
decl.size = decl.initializer.size();
var.array_size = decl.initializer.size();
} else if (decl.initializer.size() != var.array_size) {
- _set_error("Array size mismatch");
+ _set_error(RTR("Array size mismatch."));
return ERR_PARSE_ERROR;
}
tk = _get_token();
@@ -6708,11 +6710,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
} else {
if (unknown_size) {
- _set_error("Expected array initialization");
+ _set_error(RTR("Expected array initialization."));
return ERR_PARSE_ERROR;
}
if (is_const) {
- _set_error("Expected initialization of constant");
+ _set_error(RTR("Expected initialization of constant."));
return ERR_PARSE_ERROR;
}
}
@@ -6728,7 +6730,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
OperatorNode *op = ((OperatorNode *)n);
for (int i = 1; i < op->arguments.size(); i++) {
if (!_check_node_constness(op->arguments[i])) {
- _set_error("Expected constant expression for argument '" + itos(i - 1) + "' of function call after '='");
+ _set_error(vformat(RTR("Expected constant expression for argument %d of function call after '='."), i - 1));
return ERR_PARSE_ERROR;
}
}
@@ -6749,7 +6751,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
} else {
if (is_const) {
- _set_error("Expected initialization of constant");
+ _set_error(RTR("Expected initialization of constant."));
return ERR_PARSE_ERROR;
}
}
@@ -6763,13 +6765,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (tk.type == TK_COMMA) {
if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR) {
- _set_error("Multiple declarations in 'for' loop are not implemented yet.");
+ _set_error(vformat("Multiple declarations in '%s' loop are not supported.", "for"));
return ERR_PARSE_ERROR;
}
} else if (tk.type == TK_SEMICOLON) {
break;
} else {
- _set_error("Expected ',' or ';' after variable");
+ _set_expected_error(",", ";");
return ERR_PARSE_ERROR;
}
} while (tk.type == TK_COMMA); //another variable
@@ -6787,7 +6789,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
//if () {}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
- _set_error("Expected '(' after if");
+ _set_expected_after_error("(", "if");
return ERR_PARSE_ERROR;
}
@@ -6799,13 +6801,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
if (n->get_datatype() != TYPE_BOOL) {
- _set_error("Expected boolean expression");
+ _set_error(RTR("Expected a boolean expression."));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' after expression");
+ _set_expected_error(")");
return ERR_PARSE_ERROR;
}
@@ -6835,14 +6837,14 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
} else if (tk.type == TK_CF_SWITCH) {
if (RenderingServer::get_singleton()->is_low_end()) {
- _set_error("\"switch\" operator is supported only on high-end platform!");
+ _set_error(vformat(RTR("The '%s' operator is only supported on high-end platforms."), "switch"));
return ERR_PARSE_ERROR;
}
// switch() {}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
- _set_error("Expected '(' after switch");
+ _set_expected_after_error("(", "switch");
return ERR_PARSE_ERROR;
}
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
@@ -6852,17 +6854,17 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
return ERR_PARSE_ERROR;
}
if (n->get_datatype() != TYPE_INT) {
- _set_error("Expected integer expression");
+ _set_error(RTR("Expected an integer expression."));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' after expression");
+ _set_expected_error(")");
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_CURLY_BRACKET_OPEN) {
- _set_error("Expected '{' after switch statement");
+ _set_expected_after_error("{", "switch");
return ERR_PARSE_ERROR;
}
BlockNode *switch_block = alloc_node<BlockNode>();
@@ -6883,10 +6885,10 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (tk.type == TK_CF_CASE || tk.type == TK_CF_DEFAULT) {
if (prev_type == TK_CF_DEFAULT) {
if (tk.type == TK_CF_CASE) {
- _set_error("Cases must be defined before default case.");
+ _set_error(RTR("Cases must be defined before default case."));
return ERR_PARSE_ERROR;
} else if (prev_type == TK_CF_DEFAULT) {
- _set_error("Default case must be defined only once.");
+ _set_error(RTR("Default case must be defined only once."));
return ERR_PARSE_ERROR;
}
}
@@ -6905,7 +6907,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
return ERR_PARSE_ERROR;
}
if (constants.has(cn->values[0].sint)) {
- _set_error("Duplicated case label: '" + itos(cn->values[0].sint) + "'");
+ _set_error(vformat(RTR("Duplicated case label: %d."), cn->values[0].sint));
return ERR_PARSE_ERROR;
}
constants.insert(cn->values[0].sint);
@@ -6917,7 +6919,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
ConstantNode::Value v;
_find_identifier(p_block, false, p_function_info, vn->name, nullptr, nullptr, nullptr, nullptr, nullptr, &v);
if (constants.has(v.sint)) {
- _set_error("Duplicated case label: '" + itos(v.sint) + "'");
+ _set_error(vformat(RTR("Duplicated case label: %d."), v.sint));
return ERR_PARSE_ERROR;
}
constants.insert(v.sint);
@@ -6944,7 +6946,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
if (!p_block || (p_block->block_type != BlockNode::BLOCK_TYPE_SWITCH)) {
- _set_error("case must be placed within switch block");
+ _set_error(vformat(RTR("'%s' must be placed within a '%s' block."), "case", "switch"));
return ERR_PARSE_ERROR;
}
@@ -6973,7 +6975,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
}
if (!correct_constant_expression) {
- _set_error("Expected integer constant");
+ _set_error(RTR("Expected an integer constant."));
return ERR_PARSE_ERROR;
}
@@ -6997,7 +6999,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
if (tk.type != TK_COLON) {
- _set_error("Expected ':'");
+ _set_expected_error(":");
return ERR_PARSE_ERROR;
}
@@ -7025,14 +7027,14 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
if (!p_block || (p_block->block_type != BlockNode::BLOCK_TYPE_SWITCH)) {
- _set_error("default must be placed within switch block");
+ _set_error(vformat(RTR("'%s' must be placed within a '%s' block."), "default", "switch"));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_COLON) {
- _set_error("Expected ':'");
+ _set_expected_error(":");
return ERR_PARSE_ERROR;
}
@@ -7069,14 +7071,14 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
if (tk.type != TK_CF_WHILE) {
- _set_error("Expected while after do");
+ _set_expected_after_error("while", "do");
return ERR_PARSE_ERROR;
}
}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
- _set_error("Expected '(' after while");
+ _set_expected_after_error("(", "while");
return ERR_PARSE_ERROR;
}
@@ -7093,7 +7095,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' after expression");
+ _set_expected_error(")");
return ERR_PARSE_ERROR;
}
if (!is_do) {
@@ -7114,7 +7116,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';'");
+ _set_expected_error(";");
return ERR_PARSE_ERROR;
}
}
@@ -7122,7 +7124,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
// for() {}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
- _set_error("Expected '(' after for");
+ _set_expected_after_error("(", "for");
return ERR_PARSE_ERROR;
}
@@ -7144,13 +7146,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
if (n->get_datatype() != TYPE_BOOL) {
- _set_error("Middle expression is expected to be boolean.");
+ _set_error(RTR("The middle expression is expected to be boolean."));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';' after middle expression");
+ _set_expected_error(";");
return ERR_PARSE_ERROR;
}
@@ -7165,7 +7167,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' after third expression");
+ _set_expected_error(")");
return ERR_PARSE_ERROR;
}
@@ -7188,12 +7190,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
if (!b) {
- _set_error("Bug");
+ _set_parsing_error();
return ERR_BUG;
}
if (b && b->parent_function && p_function_info.main_function) {
- _set_error(vformat("Using 'return' in '%s' processor function results in undefined behavior!", b->parent_function->name));
+ _set_error(vformat(RTR("Using '%s' in the '%s' processor function is incorrect."), "return", b->parent_function->name));
return ERR_PARSE_ERROR;
}
@@ -7212,7 +7214,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (tk.type == TK_SEMICOLON) {
//all is good
if (b->parent_function->return_type != TYPE_VOID) {
- _set_error("Expected return with an expression of type '" + (!return_struct_name.is_empty() ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'");
+ _set_error(vformat(RTR("Expected '%s' with an expression of type '%s'."), "return", (!return_struct_name.is_empty() ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string));
return ERR_PARSE_ERROR;
}
} else {
@@ -7224,13 +7226,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
if (b->parent_function->return_type != expr->get_datatype() || b->parent_function->return_array_size != expr->get_array_size() || return_struct_name != expr->get_datatype_name()) {
- _set_error("Expected return with an expression of type '" + (!return_struct_name.is_empty() ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'");
+ _set_error(vformat(RTR("Expected return with an expression of type '%s'."), (!return_struct_name.is_empty() ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';' after return expression");
+ _set_expected_after_error(";", "return");
return ERR_PARSE_ERROR;
}
@@ -7253,12 +7255,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
b = b->parent_block;
}
if (!b) {
- _set_error("Bug");
+ _set_parsing_error();
return ERR_BUG;
}
if (!b->parent_function->can_discard) {
- _set_error("Use of 'discard' is not allowed here.");
+ _set_error(vformat(RTR("Use of '%s' is not allowed here."), "discard"));
return ERR_PARSE_ERROR;
}
@@ -7268,14 +7270,14 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
pos = _get_tkpos();
tk = _get_token();
if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';' after discard");
+ _set_expected_after_error(";", "discard");
return ERR_PARSE_ERROR;
}
p_block->statements.push_back(flow);
} else if (tk.type == TK_CF_BREAK) {
if (!p_can_break) {
- _set_error("'break' is not allowed outside of a loop or 'switch' statement");
+ _set_error(vformat(RTR("'%s' is not allowed outside of a loop or '%s' statement."), "break", "switch"));
return ERR_PARSE_ERROR;
}
@@ -7285,7 +7287,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
pos = _get_tkpos();
tk = _get_token();
if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';' after break");
+ _set_expected_after_error(";", "break");
return ERR_PARSE_ERROR;
}
@@ -7301,7 +7303,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
} else if (tk.type == TK_CF_CONTINUE) {
if (!p_can_continue) {
- _set_error("'continue' is not allowed outside of a loop");
+ _set_error(vformat(RTR("'%s' is not allowed outside of a loop."), "continue"));
return ERR_PARSE_ERROR;
}
@@ -7312,7 +7314,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
if (tk.type != TK_SEMICOLON) {
//all is good
- _set_error("Expected ';' after continue");
+ _set_expected_after_error(";", "continue");
return ERR_PARSE_ERROR;
}
@@ -7329,7 +7331,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';' after statement");
+ _set_expected_error(";");
return ERR_PARSE_ERROR;
}
}
@@ -7390,7 +7392,7 @@ Error ShaderLanguage::_validate_datatype(DataType p_type) {
}
if (invalid_type) {
- _set_error(vformat("\"%s\" type is supported only on high-end platform!", get_datatype_name(p_type)));
+ _set_error(vformat(RTR("The \"%s\" type is only supported on high-end platforms."), get_datatype_name(p_type)));
return ERR_UNAVAILABLE;
}
}
@@ -7402,7 +7404,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
TkPos prev_pos;
if (tk.type != TK_SHADER_TYPE) {
- _set_error("Expected 'shader_type' at the beginning of shader. Valid types are: " + _get_shader_type_list(p_shader_types));
+ _set_error(vformat(RTR("Expected '%s' at the beginning of shader. Valid types are: %s."), "shader_type", _get_shader_type_list(p_shader_types)));
return ERR_PARSE_ERROR;
}
@@ -7410,11 +7412,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
_get_completable_identifier(nullptr, COMPLETION_SHADER_TYPE, shader_type_identifier);
if (shader_type_identifier == StringName()) {
- _set_error("Expected identifier after 'shader_type', indicating type of shader. Valid types are: " + _get_shader_type_list(p_shader_types));
+ _set_error(vformat(RTR("Expected an identifier after '%s', indicating the type of shader. Valid types are: %s."), "shader_type", _get_shader_type_list(p_shader_types)));
return ERR_PARSE_ERROR;
}
if (!p_shader_types.has(shader_type_identifier)) {
- _set_error("Invalid shader type. Valid types are: " + _get_shader_type_list(p_shader_types));
+ _set_error(vformat(RTR("Invalid shader type. Valid types are: %s"), _get_shader_type_list(p_shader_types)));
return ERR_PARSE_ERROR;
}
prev_pos = _get_tkpos();
@@ -7422,7 +7424,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type != TK_SEMICOLON) {
_set_tkpos(prev_pos);
- _set_error("Expected ';' after 'shader_type <type>'.");
+ _set_expected_after_error(";", "shader_type " + String(shader_type_identifier));
return ERR_PARSE_ERROR;
}
@@ -7462,14 +7464,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
_get_completable_identifier(nullptr, COMPLETION_RENDER_MODE, mode);
if (mode == StringName()) {
- _set_error("Expected identifier for render mode");
+ _set_error(RTR("Expected an identifier for render mode."));
return ERR_PARSE_ERROR;
}
const String smode = String(mode);
if (shader->render_modes.find(mode) != -1) {
- _set_error(vformat("Duplicated render mode: '%s'.", smode));
+ _set_error(vformat(RTR("Duplicated render mode: '%s'."), smode));
return ERR_PARSE_ERROR;
}
@@ -7485,7 +7487,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
found = true;
if (defined_modes.has(name)) {
- _set_error(vformat("Redefinition of render mode: '%s'. The %s mode has already been set to '%s'.", smode, name, defined_modes[name]));
+ _set_error(vformat(RTR("Redefinition of render mode: '%s'. The '%s' mode has already been set to '%s'."), smode, name, defined_modes[name]));
return ERR_PARSE_ERROR;
}
defined_modes.insert(name, smode);
@@ -7499,7 +7501,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (!found) {
- _set_error(vformat("Invalid render mode: '%s'.", smode));
+ _set_error(vformat(RTR("Invalid render mode: '%s'."), smode));
return ERR_PARSE_ERROR;
}
@@ -7511,7 +7513,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else if (tk.type == TK_SEMICOLON) {
break; //done
} else {
- _set_error("Unexpected token: " + get_token_text(tk));
+ _set_error(vformat(RTR("Unexpected token: '%s'."), get_token_text(tk)));
return ERR_PARSE_ERROR;
}
}
@@ -7524,16 +7526,16 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_IDENTIFIER) {
st.name = tk.text;
if (shader->constants.has(st.name) || shader->structs.has(st.name)) {
- _set_error("Redefinition of '" + String(st.name) + "'");
+ _set_redefinition_error(String(st.name));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_CURLY_BRACKET_OPEN) {
- _set_error("Expected '{'");
+ _set_expected_error("{");
return ERR_PARSE_ERROR;
}
} else {
- _set_error("Expected struct identifier!");
+ _set_error(RTR("Expected a struct identifier."));
return ERR_PARSE_ERROR;
}
@@ -7553,7 +7555,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
DataPrecision precision = DataPrecision::PRECISION_DEFAULT;
if (tk.type == TK_STRUCT) {
- _set_error("nested structs are not allowed!");
+ _set_error(RTR("Nested structs are not allowed."));
return ERR_PARSE_ERROR;
}
@@ -7572,22 +7574,19 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
#endif // DEBUG_ENABLED
struct_dt = true;
if (use_precision) {
- _set_error("Precision modifier cannot be used on structs.");
+ _set_error(RTR("The precision modifier cannot be used on structs."));
return ERR_PARSE_ERROR;
}
}
if (!is_token_datatype(tk.type) && !struct_dt) {
- _set_error("Expected datatype.");
+ _set_error(RTR("Expected data type."));
return ERR_PARSE_ERROR;
} else {
type = struct_dt ? TYPE_STRUCT : get_token_datatype(tk.type);
- if (is_sampler_type(type)) {
- _set_error("sampler datatype not allowed here");
- return ERR_PARSE_ERROR;
- } else if (type == TYPE_VOID) {
- _set_error("void datatype not allowed here");
+ if (type == TYPE_VOID || is_sampler_type(type)) {
+ _set_error(vformat(RTR("A '%s' data type is not allowed here."), get_datatype_name(type)));
return ERR_PARSE_ERROR;
}
@@ -7602,7 +7601,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
first = false;
if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
- _set_error("Expected identifier or '['.");
+ _set_error(RTR("Expected an identifier or '['."));
return ERR_PARSE_ERROR;
}
@@ -7617,7 +7616,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type != TK_IDENTIFIER) {
- _set_error("Expected identifier!");
+ _set_error(RTR("Expected an identifier."));
return ERR_PARSE_ERROR;
}
@@ -7629,7 +7628,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
member->array_size = array_size;
if (member_names.has(member->name)) {
- _set_error("Redefinition of '" + String(member->name) + "'");
+ _set_redefinition_error(String(member->name));
return ERR_PARSE_ERROR;
}
member_names.insert(member->name);
@@ -7648,7 +7647,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type != TK_SEMICOLON && tk.type != TK_COMMA) {
- _set_error("Expected ',' or ';' after struct member.");
+ _set_expected_error(",", ";");
return ERR_PARSE_ERROR;
}
@@ -7658,13 +7657,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
}
if (member_count == 0) {
- _set_error("Empty structs are not allowed!");
+ _set_error(RTR("Empty structs are not allowed."));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';'");
+ _set_expected_error(";");
return ERR_PARSE_ERROR;
}
shader->structs[st.name] = st;
@@ -7678,7 +7677,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
case TK_GLOBAL: {
tk = _get_token();
if (tk.type != TK_UNIFORM) {
- _set_error("Expected 'uniform' after 'global'");
+ _set_expected_after_error("uniform", "global");
return ERR_PARSE_ERROR;
}
uniform_scope = ShaderNode::Uniform::SCOPE_GLOBAL;
@@ -7688,7 +7687,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL) {
tk = _get_token();
if (tk.type != TK_UNIFORM) {
- _set_error("Expected 'uniform' after 'instance'");
+ _set_expected_after_error("uniform", "instance");
return ERR_PARSE_ERROR;
}
uniform_scope = ShaderNode::Uniform::SCOPE_INSTANCE;
@@ -7701,7 +7700,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (!uniform) {
if (shader_type_identifier == "particles" || shader_type_identifier == "sky" || shader_type_identifier == "fog") {
- _set_error(vformat("Varyings cannot be used in '%s' shaders!", shader_type_identifier));
+ _set_error(vformat(RTR("Varyings cannot be used in '%s' shaders."), shader_type_identifier));
return ERR_PARSE_ERROR;
}
}
@@ -7716,7 +7715,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (is_token_interpolation(tk.type)) {
if (uniform) {
- _set_error("Interpolation qualifiers are not supported for uniforms!");
+ _set_error(RTR("Interpolation qualifiers are not supported for uniforms."));
return ERR_PARSE_ERROR;
}
interpolation = get_token_interpolation(tk.type);
@@ -7732,38 +7731,38 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (shader->structs.has(tk.text)) {
if (uniform) {
if (precision_defined) {
- _set_error("Precision modifier cannot be used on structs.");
+ _set_error(RTR("The precision modifier cannot be used on structs."));
return ERR_PARSE_ERROR;
}
- _set_error("struct datatype is not yet supported for uniforms!");
+ _set_error(vformat(RTR("The '%s' data type is not supported for uniforms."), "struct"));
return ERR_PARSE_ERROR;
} else {
- _set_error("struct datatype not allowed here");
+ _set_error(vformat(RTR("The '%s' data type not allowed here."), "struct"));
return ERR_PARSE_ERROR;
}
}
if (!is_token_datatype(tk.type)) {
- _set_error("Expected datatype. ");
+ _set_error(RTR("Expected data type."));
return ERR_PARSE_ERROR;
}
type = get_token_datatype(tk.type);
if (type == TYPE_VOID) {
- _set_error("void datatype not allowed here");
+ _set_error(vformat(RTR("The '%s' data type is not allowed here."), "void"));
return ERR_PARSE_ERROR;
}
if (!uniform && (type < TYPE_FLOAT || type > TYPE_MAT4)) {
- _set_error("Invalid type for varying, only float,vec2,vec3,vec4,mat2,mat3,mat4 or array of these types allowed.");
+ _set_error(RTR("Invalid type for varying, only 'float', 'vec2', 'vec3', 'vec4', 'mat2', 'mat3', 'mat4', or arrays of these types are allowed."));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
- _set_error("Expected identifier or '['.");
+ _set_error(RTR("Expected an identifier or '['."));
return ERR_PARSE_ERROR;
}
@@ -7776,7 +7775,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type != TK_IDENTIFIER) {
- _set_error("Expected identifier!");
+ _set_error(RTR("Expected an identifier."));
return ERR_PARSE_ERROR;
}
@@ -7784,12 +7783,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
name = tk.text;
if (_find_identifier(nullptr, false, constants, name)) {
- _set_error("Redefinition of '" + String(name) + "'");
+ _set_redefinition_error(String(name));
return ERR_PARSE_ERROR;
}
if (has_builtin(p_functions, name)) {
- _set_error("Redefinition of '" + String(name) + "'");
+ _set_redefinition_error(String(name));
return ERR_PARSE_ERROR;
}
@@ -7798,12 +7797,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
//validate global uniform
DataType gvtype = global_var_get_type_func(name);
if (gvtype == TYPE_MAX) {
- _set_error("Global uniform '" + String(name) + "' does not exist. Create it in Project Settings.");
+ _set_error(vformat(RTR("Global uniform '%s' does not exist. Create it in Project Settings."), String(name)));
return ERR_PARSE_ERROR;
}
if (type != gvtype) {
- _set_error("Global uniform '" + String(name) + "' must be of type '" + get_datatype_name(gvtype) + "'.");
+ _set_error(vformat(RTR("Global uniform '%s' must be of type '%s'."), String(name), get_datatype_name(gvtype)));
return ERR_PARSE_ERROR;
}
}
@@ -7825,7 +7824,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (is_sampler_type(type)) {
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
- _set_error("Uniforms with 'instance' qualifiers can't be of sampler type.");
+ _set_error(vformat(RTR("Uniforms with '%s' qualifiers can't be of sampler type.", "instance")));
return ERR_PARSE_ERROR;
}
uniform2.texture_order = texture_uniforms++;
@@ -7841,7 +7840,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
} else {
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) {
- _set_error("Uniforms with 'instance' qualifiers can't be of matrix type.");
+ _set_error(vformat(RTR("Uniforms with '%s' qualifier can't be of matrix type.", "instance")));
return ERR_PARSE_ERROR;
}
uniform2.texture_order = -1;
@@ -7870,11 +7869,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (uniform2.array_size > 0) {
if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL) {
- _set_error("'SCOPE_GLOBAL' qualifier is not yet supported for uniform array!");
+ _set_error(vformat(RTR("The '%s' qualifier is not supported for uniform arrays."), "SCOPE_GLOBAL"));
return ERR_PARSE_ERROR;
}
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
- _set_error("'SCOPE_INSTANCE' qualifier is not yet supported for uniform array!");
+ _set_error(vformat(RTR("The '%s' qualifier is not supported for uniform arrays."), "SCOPE_INSTANCE"));
return ERR_PARSE_ERROR;
}
}
@@ -7892,13 +7891,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
completion_line = tk.line;
if (!is_token_hint(tk.type)) {
- _set_error("Expected valid type hint after ':'.");
+ _set_error(RTR("Expected valid type hint after ':'."));
return ERR_PARSE_ERROR;
}
if (uniform2.array_size > 0) {
if (tk.type != TK_HINT_COLOR) {
- _set_error("This hint is not yet supported for uniform arrays!");
+ _set_error(RTR("This hint is not supported for uniform arrays."));
return ERR_PARSE_ERROR;
}
}
@@ -7929,20 +7928,20 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
uniform2.hint = ShaderNode::Uniform::HINT_BLACK_ALBEDO;
} else if (tk.type == TK_HINT_COLOR) {
if (type != TYPE_VEC4) {
- _set_error("Color hint is for vec4 only");
+ _set_error(vformat(RTR("Color hint is for '%s' only."), "vec4"));
return ERR_PARSE_ERROR;
}
uniform2.hint = ShaderNode::Uniform::HINT_COLOR;
} else if (tk.type == TK_HINT_RANGE) {
uniform2.hint = ShaderNode::Uniform::HINT_RANGE;
if (type != TYPE_FLOAT && type != TYPE_INT) {
- _set_error("Range hint is for float and int only");
+ _set_error(vformat(RTR("Range hint is for '%s' and '%s' only."), "float", "int"));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
- _set_error("Expected '(' after hint_range");
+ _set_expected_after_error("(", "hint_range");
return ERR_PARSE_ERROR;
}
@@ -7956,7 +7955,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
- _set_error("Expected integer constant");
+ _set_error(RTR("Expected an integer constant."));
return ERR_PARSE_ERROR;
}
@@ -7966,7 +7965,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type != TK_COMMA) {
- _set_error("Expected ',' after integer constant");
+ _set_error(RTR("Expected ',' after integer constant."));
return ERR_PARSE_ERROR;
}
@@ -7980,7 +7979,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
- _set_error("Expected integer constant after ','");
+ _set_error(RTR("Expected an integer constant after ','."));
return ERR_PARSE_ERROR;
}
@@ -7993,7 +7992,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
- _set_error("Expected integer constant after ','");
+ _set_error(RTR("Expected an integer constant after ','."));
return ERR_PARSE_ERROR;
}
@@ -8008,44 +8007,44 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')'");
+ _set_expected_error(")");
return ERR_PARSE_ERROR;
}
} else if (tk.type == TK_HINT_INSTANCE_INDEX) {
if (custom_instance_index != -1) {
- _set_error("Can only specify 'instance_index' once.");
+ _set_error(vformat(RTR("Can only specify '%s' once."), "instance_index"));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
- _set_error("Expected '(' after 'instance_index'");
+ _set_expected_after_error("(", "instance_index");
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type == TK_OP_SUB) {
- _set_error("The instance index can't be negative.");
+ _set_error(RTR("The instance index can't be negative."));
return ERR_PARSE_ERROR;
}
if (!tk.is_integer_constant()) {
- _set_error("Expected integer constant");
+ _set_error(RTR("Expected an integer constant."));
return ERR_PARSE_ERROR;
}
custom_instance_index = tk.constant;
if (custom_instance_index >= MAX_INSTANCE_UNIFORM_INDICES) {
- _set_error("Allowed instance uniform indices are 0-" + itos(MAX_INSTANCE_UNIFORM_INDICES - 1));
+ _set_error(vformat(RTR("Allowed instance uniform indices must be within [0..%d] range."), MAX_INSTANCE_UNIFORM_INDICES - 1));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')'");
+ _set_expected_error(")");
return ERR_PARSE_ERROR;
}
} else if (tk.type == TK_FILTER_LINEAR) {
@@ -8067,7 +8066,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (uniform2.hint != ShaderNode::Uniform::HINT_RANGE && uniform2.hint != ShaderNode::Uniform::HINT_NONE && uniform2.hint != ShaderNode::Uniform::HINT_COLOR && type <= TYPE_MAT4) {
- _set_error("This hint is only for sampler types");
+ _set_error(RTR("This hint is only for sampler types."));
return ERR_PARSE_ERROR;
}
@@ -8082,7 +8081,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else {
uniform2.instance_index = instance_index++;
if (instance_index > MAX_INSTANCE_UNIFORM_INDICES) {
- _set_error("Too many 'instance' uniforms in shader, maximum supported is " + itos(MAX_INSTANCE_UNIFORM_INDICES));
+ _set_error(vformat(RTR("Too many '%s' uniforms in shader, maximum supported is %d."), "instance", MAX_INSTANCE_UNIFORM_INDICES));
return ERR_PARSE_ERROR;
}
}
@@ -8092,7 +8091,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_OP_ASSIGN) {
if (uniform2.array_size > 0) {
- _set_error("Setting default value to a uniform array is not yet supported!");
+ _set_error(RTR("Setting default values to uniform arrays is not supported."));
return ERR_PARSE_ERROR;
}
@@ -8101,7 +8100,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
if (expr->type != Node::TYPE_CONSTANT) {
- _set_error("Expected constant expression after '='");
+ _set_error(RTR("Expected constant expression after '='."));
return ERR_PARSE_ERROR;
}
@@ -8110,7 +8109,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
uniform2.default_value.resize(cn->values.size());
if (!convert_constant(cn, uniform2.type, uniform2.default_value.ptrw())) {
- _set_error("Can't convert constant to " + get_datatype_name(uniform2.type));
+ _set_error(vformat(RTR("Can't convert constant to '%s'."), get_datatype_name(uniform2.type)));
return ERR_PARSE_ERROR;
}
tk = _get_token();
@@ -8127,7 +8126,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';'");
+ _set_expected_error(";");
return ERR_PARSE_ERROR;
}
@@ -8143,9 +8142,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type != TK_SEMICOLON && tk.type != TK_BRACKET_OPEN) {
if (array_size == 0) {
- _set_error("Expected ';' or '['");
+ _set_expected_error(";", "[");
} else {
- _set_error("Expected ';'");
+ _set_expected_error(";");
}
return ERR_PARSE_ERROR;
}
@@ -8168,7 +8167,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} break;
case TK_SHADER_TYPE: {
- _set_error("Shader type is already defined.");
+ _set_error(RTR("Shader type is already defined."));
return ERR_PARSE_ERROR;
} break;
default: {
@@ -8194,19 +8193,23 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (shader->structs.has(tk.text)) {
if (precision != PRECISION_DEFAULT) {
- _set_error("Precision modifier cannot be used on structs.");
+ _set_error(RTR("The precision modifier cannot be used on structs."));
return ERR_PARSE_ERROR;
}
is_struct = true;
struct_name = tk.text;
} else {
if (!is_token_datatype(tk.type)) {
- _set_error("Expected constant, function, uniform or varying");
+ _set_error(RTR("Expected constant, function, uniform or varying."));
return ERR_PARSE_ERROR;
}
if (!is_token_variable_datatype(tk.type)) {
- _set_error("Invalid data type for constants or function return (samplers not allowed)");
+ if (is_constant) {
+ _set_error(RTR("Invalid constant type (samplers are not allowed)."));
+ } else {
+ _set_error(RTR("Invalid function type (samplers are not allowed)."));
+ }
return ERR_PARSE_ERROR;
}
}
@@ -8224,7 +8227,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_BRACKET_OPEN) {
if (is_constant && RenderingServer::get_singleton()->is_low_end()) {
- _set_error("Global const arrays are only supported on high-end platform!");
+ _set_error(RTR("Global constant arrays are only supported on high-end platforms."));
return ERR_PARSE_ERROR;
}
Error error = _parse_array_size(nullptr, constants, !is_constant, nullptr, &array_size, &unknown_size);
@@ -8241,22 +8244,22 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (name == StringName()) {
if (is_constant) {
- _set_error("Expected identifier or '[' after datatype.");
+ _set_error(RTR("Expected an identifier or '[' after type."));
} else {
- _set_error("Expected function name after datatype.");
+ _set_error(RTR("Expected a function name after type."));
}
return ERR_PARSE_ERROR;
}
if (shader->structs.has(name) || _find_identifier(nullptr, false, constants, name) || has_builtin(p_functions, name)) {
- _set_error("Redefinition of '" + String(name) + "'");
+ _set_redefinition_error(String(name));
return ERR_PARSE_ERROR;
}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
if (type == TYPE_VOID) {
- _set_error("Expected '(' after function identifier");
+ _set_error(RTR("Expected '(' after function identifier."));
return ERR_PARSE_ERROR;
}
@@ -8272,7 +8275,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_BRACKET_OPEN) {
if (RenderingServer::get_singleton()->is_low_end()) {
- _set_error("Global const arrays are only supported on high-end platform!");
+ _set_error(RTR("Global const arrays are only supported on high-end platforms."));
return ERR_PARSE_ERROR;
}
Error error = _parse_array_size(nullptr, constants, false, nullptr, &constant.array_size, &unknown_size);
@@ -8284,7 +8287,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_OP_ASSIGN) {
if (!is_constant) {
- _set_error("Expected 'const' keyword before constant definition");
+ _set_error(vformat(RTR("Global non-constant variables are not supported. Expected '%s' keyword before constant definition."), "const"));
return ERR_PARSE_ERROR;
}
@@ -8299,7 +8302,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type != TK_CURLY_BRACKET_OPEN) {
if (unknown_size) {
- _set_error("Expected '{'");
+ _set_expected_error("{");
return ERR_PARSE_ERROR;
}
@@ -8310,7 +8313,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
precision2 = get_token_precision(tk.type);
tk = _get_token();
if (!is_token_nonvoid_datatype(tk.type)) {
- _set_error("Expected datatype after precision");
+ _set_error(RTR("Expected data type after precision modifier."));
return ERR_PARSE_ERROR;
}
}
@@ -8323,7 +8326,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
struct_name2 = tk.text;
} else {
if (!is_token_variable_datatype(tk.type)) {
- _set_error("Invalid data type for array");
+ _set_error(RTR("Invalid data type for the array."));
return ERR_PARSE_ERROR;
}
type2 = get_token_datatype(tk.type);
@@ -8343,38 +8346,40 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
tk = _get_token();
} else {
- _set_error("Expected '[");
+ _set_expected_error("[");
return ERR_PARSE_ERROR;
}
if (constant.precision != precision2 || constant.type != type2 || struct_name != struct_name2 || constant.array_size != array_size2) {
- String error_str = "Cannot convert from '";
+ String from;
if (type2 == TYPE_STRUCT) {
- error_str += struct_name2;
+ from += struct_name2;
} else {
if (precision2 != PRECISION_DEFAULT) {
- error_str += get_precision_name(precision2);
- error_str += " ";
+ from += get_precision_name(precision2);
+ from += " ";
}
- error_str += get_datatype_name(type2);
+ from += get_datatype_name(type2);
}
- error_str += "[";
- error_str += itos(array_size2);
- error_str += "]'";
- error_str += " to '";
+ from += "[";
+ from += itos(array_size2);
+ from += "]'";
+
+ String to;
if (type == TYPE_STRUCT) {
- error_str += struct_name;
+ to += struct_name;
} else {
if (precision != PRECISION_DEFAULT) {
- error_str += get_precision_name(precision);
- error_str += " ";
+ to += get_precision_name(precision);
+ to += " ";
}
- error_str += get_datatype_name(type);
+ to += get_datatype_name(type);
}
- error_str += "[";
- error_str += itos(constant.array_size);
- error_str += "]'";
- _set_error(error_str);
+ to += "[";
+ to += itos(constant.array_size);
+ to += "]'";
+
+ _set_error(vformat(RTR("Cannot convert from '%s' to '%s'."), from, to));
return ERR_PARSE_ERROR;
}
}
@@ -8383,13 +8388,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (unknown_size) {
if (!curly) {
- _set_error("Expected '{'");
+ _set_expected_error("{");
return ERR_PARSE_ERROR;
}
} else {
if (full_def) {
if (curly) {
- _set_error("Expected '('");
+ _set_expected_error("(");
return ERR_PARSE_ERROR;
}
}
@@ -8403,7 +8408,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) {
- _set_error("Expected constant expression");
+ _set_error(RTR("Expected constant expression."));
return ERR_PARSE_ERROR;
}
@@ -8423,9 +8428,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
break;
} else {
if (curly) {
- _set_error("Expected '}' or ','");
+ _set_expected_error("}", ",");
} else {
- _set_error("Expected ')' or ','");
+ _set_expected_error(")", ",");
}
return ERR_PARSE_ERROR;
}
@@ -8434,7 +8439,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
decl.size = decl.initializer.size();
constant.array_size = decl.initializer.size();
} else if (decl.initializer.size() != constant.array_size) {
- _set_error("Array size mismatch");
+ _set_error(RTR("Array size mismatch."));
return ERR_PARSE_ERROR;
}
}
@@ -8462,7 +8467,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
OperatorNode *op = ((OperatorNode *)expr);
for (int i = 1; i < op->arguments.size(); i++) {
if (!_check_node_constness(op->arguments[i])) {
- _set_error("Expected constant expression for argument '" + itos(i - 1) + "' of function call after '='");
+ _set_error(vformat(RTR("Expected constant expression for argument %d of function call after '='."), i - 1));
return ERR_PARSE_ERROR;
}
}
@@ -8477,10 +8482,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
} else {
if (constant.array_size > 0 || unknown_size) {
- _set_error("Expected array initialization");
+ _set_error(RTR("Expected array initialization."));
return ERR_PARSE_ERROR;
} else {
- _set_error("Expected initialization of constant");
+ _set_error(RTR("Expected initialization of constant."));
return ERR_PARSE_ERROR;
}
}
@@ -8496,18 +8501,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_COMMA) {
tk = _get_token();
if (tk.type != TK_IDENTIFIER) {
- _set_error("Expected identifier after type");
+ _set_error(RTR("Expected an identifier after type."));
return ERR_PARSE_ERROR;
}
name = tk.text;
if (_find_identifier(nullptr, false, constants, name)) {
- _set_error("Redefinition of '" + String(name) + "'");
+ _set_redefinition_error(String(name));
return ERR_PARSE_ERROR;
}
if (has_builtin(p_functions, name)) {
- _set_error("Redefinition of '" + String(name) + "'");
+ _set_redefinition_error(String(name));
return ERR_PARSE_ERROR;
}
@@ -8521,7 +8526,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else if (tk.type == TK_SEMICOLON) {
break;
} else {
- _set_error("Expected ',' or ';' after constant");
+ _set_expected_error(",", ";");
return ERR_PARSE_ERROR;
}
}
@@ -8548,7 +8553,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
for (int i = 0; i < shader->functions.size(); i++) {
if (!shader->functions[i].callable && shader->functions[i].name == name) {
- _set_error("Redefinition of '" + String(name) + "'");
+ _set_redefinition_error(String(name));
return ERR_PARSE_ERROR;
}
}
@@ -8603,14 +8608,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
} else if (tk.type == TK_ARG_OUT) {
if (is_const) {
- _set_error("'out' qualifier cannot be used within a function parameter declared with 'const'.");
+ _set_error(vformat(RTR("The '%s' qualifier cannot be used within a function parameter declared with '%s'."), "out", "const"));
return ERR_PARSE_ERROR;
}
qualifier = ARGUMENT_QUALIFIER_OUT;
tk = _get_token();
} else if (tk.type == TK_ARG_INOUT) {
if (is_const) {
- _set_error("'inout' qualifier cannot be used within a function parameter declared with 'const'.");
+ _set_error(vformat(RTR("The '%s' qualifier cannot be used within a function parameter declared with '%s'."), "inout", "const"));
return ERR_PARSE_ERROR;
}
qualifier = ARGUMENT_QUALIFIER_INOUT;
@@ -8641,19 +8646,19 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
#endif // DEBUG_ENABLED
if (use_precision) {
- _set_error("Precision modifier cannot be used on structs.");
+ _set_error(RTR("The precision modifier cannot be used on structs."));
return ERR_PARSE_ERROR;
}
}
if (!is_struct && !is_token_datatype(tk.type)) {
- _set_error("Expected a valid datatype for argument");
+ _set_error(RTR("Expected a valid data type for argument."));
return ERR_PARSE_ERROR;
}
if (qualifier == ARGUMENT_QUALIFIER_OUT || qualifier == ARGUMENT_QUALIFIER_INOUT) {
if (is_sampler_type(get_token_datatype(tk.type))) {
- _set_error("Opaque types cannot be output parameters.");
+ _set_error(RTR("Opaque types cannot be output parameters."));
return ERR_PARSE_ERROR;
}
}
@@ -8666,7 +8671,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
if (ptype == TYPE_VOID) {
- _set_error("void not allowed in argument");
+ _set_error(RTR("Void type not allowed as argument."));
return ERR_PARSE_ERROR;
}
}
@@ -8681,7 +8686,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
if (tk.type != TK_IDENTIFIER) {
- _set_error("Expected identifier for argument name");
+ _set_error(RTR("Expected an identifier for argument name."));
return ERR_PARSE_ERROR;
}
@@ -8690,13 +8695,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
ShaderLanguage::IdentifierType itype;
if (_find_identifier(func_node->body, false, builtins, pname, (ShaderLanguage::DataType *)nullptr, &itype)) {
if (itype != IDENTIFIER_FUNCTION) {
- _set_error("Redefinition of '" + String(pname) + "'");
+ _set_redefinition_error(String(pname));
return ERR_PARSE_ERROR;
}
}
if (has_builtin(p_functions, pname)) {
- _set_error("Redefinition of '" + String(pname) + "'");
+ _set_redefinition_error(String(pname));
return ERR_PARSE_ERROR;
}
@@ -8728,7 +8733,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
//do none and go on
} else if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ',' or ')' after identifier");
+ _set_expected_error(",", ")");
return ERR_PARSE_ERROR;
}
}
@@ -8736,11 +8741,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (p_functions.has(name)) {
//if one of the core functions, make sure they are of the correct form
if (func_node->arguments.size() > 0) {
- _set_error("Function '" + String(name) + "' expects no arguments.");
+ _set_error(vformat(RTR("Function '%s' expects no arguments."), String(name)));
return ERR_PARSE_ERROR;
}
if (func_node->return_type != TYPE_VOID) {
- _set_error("Function '" + String(name) + "' must be of void return type.");
+ _set_error(vformat(RTR("Function '%s' must be of '%s' return type."), String(name), "void"));
return ERR_PARSE_ERROR;
}
}
@@ -8748,7 +8753,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
//all good let's parse inside the function!
tk = _get_token();
if (tk.type != TK_CURLY_BRACKET_OPEN) {
- _set_error("Expected '{' to begin function");
+ _set_error(RTR("Expected a '{' to begin function."));
return ERR_PARSE_ERROR;
}
@@ -8762,7 +8767,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (func_node->return_type != DataType::TYPE_VOID) {
BlockNode *block = func_node->body;
if (_find_last_flow_op_in_block(block, FlowOperation::FLOW_OP_RETURN) != OK) {
- _set_error("Expected at least one return statement in a non-void function.");
+ _set_error(vformat(RTR("Expected at least one '%s' statement in a non-void function."), "return"));
return ERR_PARSE_ERROR;
}
}
@@ -8775,7 +8780,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
#ifdef DEBUG_ENABLED
if (check_device_limit_warnings && uniform_buffer_exceeded_line != -1) {
- _add_warning(ShaderWarning::DEVICE_LIMIT_EXCEEDED, uniform_buffer_exceeded_line, "uniform buffer", { uniform_buffer_size, max_uniform_buffer_size });
+ _add_warning(ShaderWarning::DEVICE_LIMIT_EXCEEDED, uniform_buffer_exceeded_line, RTR("uniform buffer"), { uniform_buffer_size, max_uniform_buffer_size });
}
#endif // DEBUG_ENABLED
return OK;
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index c619934182..1307eeac2b 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -945,6 +945,26 @@ private:
error_str = p_str;
}
+ void _set_expected_error(const String &p_what) {
+ _set_error(vformat(RTR("Expected a '%s'."), p_what));
+ }
+
+ void _set_expected_error(const String &p_first, const String p_second) {
+ _set_error(vformat(RTR("Expected a '%s' or '%s'."), p_first, p_second));
+ }
+
+ void _set_expected_after_error(const String &p_what, const String &p_after) {
+ _set_error(vformat(RTR("Expected a '%s' after '%s'."), p_what, p_after));
+ }
+
+ void _set_redefinition_error(const String &p_what) {
+ _set_error(vformat(RTR("Redefinition of '%s'."), p_what));
+ }
+
+ void _set_parsing_error() {
+ _set_error("Parser bug.");
+ }
+
static const char *token_names[TK_MAX];
Token _make_token(TokenType p_type, const StringName &p_text = StringName());
diff --git a/servers/rendering/shader_warnings.cpp b/servers/rendering/shader_warnings.cpp
index f2e74c4d78..639b9bd165 100644
--- a/servers/rendering/shader_warnings.cpp
+++ b/servers/rendering/shader_warnings.cpp
@@ -48,23 +48,23 @@ const StringName &ShaderWarning::get_subject() const {
String ShaderWarning::get_message() const {
switch (code) {
case FLOAT_COMPARISON:
- return vformat("Direct floating-point comparison (this may not evaluate to `true` as you expect). Instead, use `abs(a - b) < 0.0001` for an approximate but predictable comparison.");
+ return vformat(RTR("Direct floating-point comparison (this may not evaluate to `true` as you expect). Instead, use `abs(a - b) < 0.0001` for an approximate but predictable comparison."));
case UNUSED_CONSTANT:
- return vformat("The const '%s' is declared but never used.", subject);
+ return vformat(RTR("The const '%s' is declared but never used."), subject);
case UNUSED_FUNCTION:
- return vformat("The function '%s' is declared but never used.", subject);
+ return vformat(RTR("The function '%s' is declared but never used."), subject);
case UNUSED_STRUCT:
- return vformat("The struct '%s' is declared but never used.", subject);
+ return vformat(RTR("The struct '%s' is declared but never used."), subject);
case UNUSED_UNIFORM:
- return vformat("The uniform '%s' is declared but never used.", subject);
+ return vformat(RTR("The uniform '%s' is declared but never used."), subject);
case UNUSED_VARYING:
- return vformat("The varying '%s' is declared but never used.", subject);
+ return vformat(RTR("The varying '%s' is declared but never used."), subject);
case UNUSED_LOCAL_VARIABLE:
- return vformat("The local variable '%s' is declared but never used.", subject);
+ return vformat(RTR("The local variable '%s' is declared but never used."), subject);
case FORMATTING_ERROR:
return subject;
case DEVICE_LIMIT_EXCEEDED:
- return vformat("The total size of the %s for this shader on this device has been exceeded (%s/%s). The shader may not work correctly.", subject, (int)extra_args[0], (int)extra_args[1]);
+ return vformat(RTR("The total size of the %s for this shader on this device has been exceeded (%d/%d). The shader may not work correctly."), subject, (int)extra_args[0], (int)extra_args[1]);
default:
break;
}