summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gdscript/gdscript_editor.cpp3
-rw-r--r--modules/gdscript/gdscript_parser.cpp13
-rw-r--r--modules/gdscript/gdscript_parser.h4
-rw-r--r--modules/gdscript/gdscript_rpc_callable.cpp1
-rw-r--r--modules/gltf/editor/editor_scene_importer_blend.cpp5
-rw-r--r--modules/gltf/gltf_document.cpp34
-rw-r--r--modules/gridmap/editor/grid_map_editor_plugin.cpp9
-rw-r--r--modules/gridmap/grid_map.cpp5
-rw-r--r--modules/mono/csharp_script.cpp24
-rw-r--r--modules/mono/csharp_script.h14
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs2
-rw-r--r--modules/mono/editor/bindings_generator.cpp42
-rw-r--r--modules/mono/editor/code_completion.cpp1
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Compat.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs12
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs90
-rw-r--r--modules/multiplayer/doc_classes/SceneReplicationConfig.xml38
-rw-r--r--modules/multiplayer/editor/editor_network_profiler.cpp23
-rw-r--r--modules/multiplayer/editor/replication_editor.cpp128
-rw-r--r--modules/multiplayer/editor/replication_editor.h6
-rw-r--r--modules/multiplayer/scene_cache_interface.h1
-rw-r--r--modules/multiplayer/scene_replication_config.cpp168
-rw-r--r--modules/multiplayer/scene_replication_config.h24
-rw-r--r--modules/navigation/editor/navigation_mesh_editor_plugin.cpp5
-rw-r--r--modules/navigation/godot_navigation_server.h4
-rw-r--r--modules/openxr/editor/openxr_action_editor.cpp4
-rw-r--r--modules/openxr/editor/openxr_action_set_editor.cpp9
-rw-r--r--modules/openxr/editor/openxr_interaction_profile_editor.cpp5
-rw-r--r--modules/text_server_adv/text_server_adv.cpp13
-rw-r--r--modules/text_server_fb/text_server_fb.cpp6
-rw-r--r--modules/webrtc/doc_classes/WebRTCPeerConnection.xml2
-rw-r--r--modules/webrtc/webrtc_data_channel_extension.h1
-rw-r--r--modules/webrtc/webrtc_peer_connection_extension.h1
33 files changed, 455 insertions, 244 deletions
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 3019354d93..6cad3b2b90 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -1207,6 +1207,9 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
for (const PropertyInfo &E : members) {
if (!String(E.name).contains("/")) {
ScriptLanguage::CodeCompletionOption option(E.name, ScriptLanguage::CODE_COMPLETION_KIND_MEMBER);
+ if (GDScriptParser::theme_color_names.has(E.name)) {
+ option.theme_color_name = GDScriptParser::theme_color_names[E.name];
+ }
r_result.insert(option.display, option);
}
}
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 039d46f678..a0d02b12b5 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -66,6 +66,10 @@ Variant::Type GDScriptParser::get_builtin_type(const StringName &p_type) {
return Variant::VARIANT_MAX;
}
+#ifdef TOOLS_ENABLED
+HashMap<String, String> GDScriptParser::theme_color_names;
+#endif
+
void GDScriptParser::cleanup() {
builtin_types.clear();
}
@@ -121,6 +125,15 @@ GDScriptParser::GDScriptParser() {
#ifdef DEBUG_ENABLED
is_ignoring_warnings = !(bool)GLOBAL_GET("debug/gdscript/warnings/enable");
#endif
+
+#ifdef TOOLS_ENABLED
+ if (theme_color_names.is_empty()) {
+ theme_color_names.insert("x", "axis_x_color");
+ theme_color_names.insert("y", "axis_y_color");
+ theme_color_names.insert("z", "axis_z_color");
+ theme_color_names.insert("w", "axis_w_color");
+ }
+#endif
}
GDScriptParser::~GDScriptParser() {
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index 05c5bc2f11..9690784cba 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -1540,6 +1540,10 @@ public:
int get_last_line_number() const { return current.end_line; }
#endif
+#ifdef TOOLS_ENABLED
+ static HashMap<String, String> theme_color_names;
+#endif // TOOLS_ENABLED
+
GDScriptParser();
~GDScriptParser();
diff --git a/modules/gdscript/gdscript_rpc_callable.cpp b/modules/gdscript/gdscript_rpc_callable.cpp
index 265e624b6c..199ea81330 100644
--- a/modules/gdscript/gdscript_rpc_callable.cpp
+++ b/modules/gdscript/gdscript_rpc_callable.cpp
@@ -30,6 +30,7 @@
#include "gdscript_rpc_callable.h"
+#include "core/object/script_language.h"
#include "core/templates/hashfuncs.h"
#include "scene/main/node.h"
diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp
index 91271da331..3787d0fe5e 100644
--- a/modules/gltf/editor/editor_scene_importer_blend.cpp
+++ b/modules/gltf/editor/editor_scene_importer_blend.cpp
@@ -40,6 +40,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
#include "main/main.h"
#include "scene/gui/line_edit.h"
@@ -366,10 +367,10 @@ void EditorFileSystemImportFormatSupportQueryBlend::_validate_path(String p_path
path_status->set_text(error);
if (success) {
- path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("success_color"), SNAME("Editor")));
+ path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("success_color"), EditorStringName(Editor)));
configure_blender_dialog->get_ok_button()->set_disabled(false);
} else {
- path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
configure_blender_dialog->get_ok_button()->set_disabled(true);
}
}
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 9e7611bc5e..984052d2ca 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -563,17 +563,17 @@ Error GLTFDocument::_parse_scenes(Ref<GLTFState> p_state) {
if (scenes.size()) {
ERR_FAIL_COND_V(loaded_scene >= scenes.size(), ERR_FILE_CORRUPT);
- const Dictionary &s = scenes[loaded_scene];
- ERR_FAIL_COND_V(!s.has("nodes"), ERR_UNAVAILABLE);
- const Array &nodes = s["nodes"];
+ const Dictionary &scene_dict = scenes[loaded_scene];
+ ERR_FAIL_COND_V(!scene_dict.has("nodes"), ERR_UNAVAILABLE);
+ const Array &nodes = scene_dict["nodes"];
for (int j = 0; j < nodes.size(); j++) {
p_state->root_nodes.push_back(nodes[j]);
}
-
- if (s.has("name") && !String(s["name"]).is_empty() && !((String)s["name"]).begins_with("Scene")) {
- p_state->scene_name = _gen_unique_name(p_state, s["name"]);
+ // Determine what to use for the scene name.
+ if (scene_dict.has("name") && !String(scene_dict["name"]).is_empty() && !((String)scene_dict["name"]).begins_with("Scene")) {
+ p_state->scene_name = scene_dict["name"];
} else {
- p_state->scene_name = _gen_unique_name(p_state, p_state->filename);
+ p_state->scene_name = p_state->filename;
}
}
@@ -5271,23 +5271,21 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> p_state) {
void GLTFDocument::_assign_node_names(Ref<GLTFState> p_state) {
for (int i = 0; i < p_state->nodes.size(); i++) {
Ref<GLTFNode> gltf_node = p_state->nodes[i];
-
// Any joints get unique names generated when the skeleton is made, unique to the skeleton
if (gltf_node->skeleton >= 0) {
continue;
}
-
- if (gltf_node->get_name().is_empty()) {
+ String gltf_node_name = gltf_node->get_name();
+ if (gltf_node_name.is_empty()) {
if (gltf_node->mesh >= 0) {
- gltf_node->set_name(_gen_unique_name(p_state, "Mesh"));
+ gltf_node_name = "Mesh";
} else if (gltf_node->camera >= 0) {
- gltf_node->set_name(_gen_unique_name(p_state, "Camera3D"));
+ gltf_node_name = "Camera3D";
} else {
- gltf_node->set_name(_gen_unique_name(p_state, "Node"));
+ gltf_node_name = "Node";
}
}
-
- gltf_node->set_name(_gen_unique_name(p_state, gltf_node->get_name()));
+ gltf_node->set_name(_gen_unique_name(p_state, gltf_node_name));
}
}
@@ -5804,10 +5802,14 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn
// If none of our GLTFDocumentExtension classes generated us a node, we generate one.
if (!current_node) {
if (gltf_node->skin >= 0 && gltf_node->mesh >= 0 && !gltf_node->children.is_empty()) {
+ // GLTF specifies that skinned meshes should ignore their node transforms,
+ // only being controlled by the skeleton, so Godot will reparent a skinned
+ // mesh to its skeleton. However, we still need to ensure any child nodes
+ // keep their place in the tree, so if there are any child nodes, the skinned
+ // mesh must not be the base node, so generate an empty spatial base.
current_node = _generate_spatial(p_state, p_node_index);
Node3D *mesh_inst = _generate_mesh_instance(p_state, p_node_index);
mesh_inst->set_name(gltf_node->get_name());
-
current_node->add_child(mesh_inst, true);
} else if (gltf_node->mesh >= 0) {
current_node = _generate_mesh_instance(p_state, p_node_index);
diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp
index 0c9f8fb3e0..f96cc86142 100644
--- a/modules/gridmap/editor/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/camera_3d.h"
@@ -1059,10 +1060,10 @@ void GridMapEditor::_draw_grids(const Vector3 &cell_size) {
}
void GridMapEditor::_update_theme() {
- options->set_icon(get_theme_icon(SNAME("GridMap"), SNAME("EditorIcons")));
- search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- mode_thumbnail->set_icon(get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons")));
- mode_list->set_icon(get_theme_icon(SNAME("FileList"), SNAME("EditorIcons")));
+ options->set_icon(get_theme_icon(SNAME("GridMap"), EditorStringName(EditorIcons)));
+ search_box->set_right_icon(get_theme_icon(SNAME("Search"), EditorStringName(EditorIcons)));
+ mode_thumbnail->set_icon(get_theme_icon(SNAME("FileThumbnail"), EditorStringName(EditorIcons)));
+ mode_list->set_icon(get_theme_icon(SNAME("FileList"), EditorStringName(EditorIcons)));
}
void GridMapEditor::_notification(int p_what) {
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 34c53b5de5..4ac143c7ff 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -906,13 +906,14 @@ void GridMap::_notification(int p_what) {
}
} break;
-#ifdef DEBUG_ENABLED
case NOTIFICATION_ENTER_TREE: {
+#ifdef DEBUG_ENABLED
if (bake_navigation && NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) {
_update_navigation_debug_edge_connections();
}
- } break;
#endif // DEBUG_ENABLED
+ _update_visibility();
+ } break;
case NOTIFICATION_TRANSFORM_CHANGED: {
Transform3D new_xform = get_global_transform();
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 692eb2dc6a..9e23a27093 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -68,8 +68,6 @@
#include <stdint.h>
-#define CACHED_STRING_NAME(m_var) (CSharpLanguage::get_singleton()->get_string_names().m_var)
-
// Types that will be skipped over (in favor of their base types) when setting up instance bindings.
// This must be a superset of `ignored_types` in bindings_generator.cpp.
const Vector<String> ignored_types = {};
@@ -1686,7 +1684,7 @@ bool CSharpInstance::property_can_revert(const StringName &p_name) const {
Variant ret;
Callable::CallError call_error;
GDMonoCache::managed_callbacks.CSharpInstanceBridge_Call(
- gchandle.get_intptr(), &CACHED_STRING_NAME(_property_can_revert), args, 1, &call_error, &ret);
+ gchandle.get_intptr(), &SNAME("_property_can_revert"), args, 1, &call_error, &ret);
if (call_error.error != Callable::CallError::CALL_OK) {
return false;
@@ -1722,7 +1720,7 @@ bool CSharpInstance::property_get_revert(const StringName &p_name, Variant &r_re
Variant ret;
Callable::CallError call_error;
GDMonoCache::managed_callbacks.CSharpInstanceBridge_Call(
- gchandle.get_intptr(), &CACHED_STRING_NAME(_property_get_revert), args, 1, &call_error, &ret);
+ gchandle.get_intptr(), &SNAME("_property_get_revert"), args, 1, &call_error, &ret);
if (call_error.error != Callable::CallError::CALL_OK) {
return false;
@@ -2010,13 +2008,11 @@ void CSharpInstance::notification(int p_notification, bool p_reversed) {
void CSharpInstance::_call_notification(int p_notification, bool p_reversed) {
Variant arg = p_notification;
const Variant *args[1] = { &arg };
- StringName method_name = SNAME("_notification");
-
- Callable::CallError call_error;
Variant ret;
+ Callable::CallError call_error;
GDMonoCache::managed_callbacks.CSharpInstanceBridge_Call(
- gchandle.get_intptr(), &method_name, args, 1, &call_error, &ret);
+ gchandle.get_intptr(), &SNAME("_notification"), args, 1, &call_error, &ret);
}
String CSharpInstance::to_string(bool *r_valid) {
@@ -2240,7 +2236,7 @@ bool CSharpScript::_update_exports(PlaceHolderScriptInstance *p_instance_to_upda
}
bool CSharpScript::_get(const StringName &p_name, Variant &r_ret) const {
- if (p_name == CSharpLanguage::singleton->string_names._script_source) {
+ if (p_name == SNAME("script/source")) {
r_ret = get_source_code();
return true;
}
@@ -2249,7 +2245,7 @@ bool CSharpScript::_get(const StringName &p_name, Variant &r_ret) const {
}
bool CSharpScript::_set(const StringName &p_name, const Variant &p_value) {
- if (p_name == CSharpLanguage::singleton->string_names._script_source) {
+ if (p_name == SNAME("script/source")) {
set_source_code(p_value);
reload();
return true;
@@ -2259,7 +2255,7 @@ bool CSharpScript::_set(const StringName &p_name, const Variant &p_value) {
}
void CSharpScript::_get_property_list(List<PropertyInfo> *p_properties) const {
- p_properties->push_back(PropertyInfo(Variant::STRING, CSharpLanguage::singleton->string_names._script_source, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
+ p_properties->push_back(PropertyInfo(Variant::STRING, SNAME("script/source"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
}
void CSharpScript::_bind_methods() {
@@ -2906,9 +2902,3 @@ void ResourceFormatSaverCSharpScript::get_recognized_extensions(const Ref<Resour
bool ResourceFormatSaverCSharpScript::recognize(const Ref<Resource> &p_resource) const {
return Object::cast_to<CSharpScript>(p_resource.ptr()) != nullptr;
}
-
-CSharpLanguage::StringNameCache::StringNameCache() {
- _property_can_revert = StaticCString::create("_property_can_revert");
- _property_get_revert = StaticCString::create("_property_get_revert");
- _script_source = StaticCString::create("script/source");
-}
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index bea6d4f7a3..33862016a4 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -335,14 +335,6 @@ class CSharpLanguage : public ScriptLanguage {
ManagedCallableMiddleman *managed_callable_middleman = memnew(ManagedCallableMiddleman);
- struct StringNameCache {
- StringName _property_can_revert;
- StringName _property_get_revert;
- StringName _script_source;
-
- StringNameCache();
- };
-
int lang_idx = -1;
// For debug_break and debug_break_parse
@@ -370,8 +362,6 @@ public:
static void set_instance_binding(Object *p_object, void *p_binding);
static bool has_instance_binding(Object *p_object);
- StringNameCache string_names;
-
const Mutex &get_language_bind_mutex() {
return language_bind_mutex;
}
@@ -384,10 +374,6 @@ public:
}
void set_language_index(int p_idx);
- _FORCE_INLINE_ const StringNameCache &get_string_names() {
- return string_names;
- }
-
_FORCE_INLINE_ static CSharpLanguage *get_singleton() {
return singleton;
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index ec28658557..f01fbbd1b9 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -440,7 +440,7 @@ namespace GodotTools
{
base._EnablePlugin();
- ProjectSettingsChanged += GodotSharpDirs.DetermineProjectLocation;
+ ProjectSettings.SettingsChanged += GodotSharpDirs.DetermineProjectLocation;
if (Instance != null)
throw new InvalidOperationException();
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 006aca6c73..9b41f9cd1b 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -367,9 +367,19 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
}
if (target_itype) {
- xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
- xml_output.append(target_itype->proxy_name);
- xml_output.append("\"/>");
+ if ((!p_itype || p_itype->api_type == ClassDB::API_CORE) && target_itype->api_type == ClassDB::API_EDITOR) {
+ // Editor references in core documentation cannot be resolved,
+ // handle as standard codeblock.
+ _log("Cannot reference editor type '%s' in documentation for core type '%s'\n",
+ target_itype->proxy_name.utf8().get_data(), p_itype ? p_itype->proxy_name.utf8().get_data() : "@GlobalScope");
+ xml_output.append("<c>");
+ xml_output.append(target_itype->proxy_name);
+ xml_output.append("</c>");
+ } else {
+ xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
+ xml_output.append(target_itype->proxy_name);
+ xml_output.append("\"/>");
+ }
} else {
ERR_PRINT("Cannot resolve type reference in documentation: '" + tag + "'.");
@@ -523,7 +533,31 @@ void BindingsGenerator::_append_xml_method(StringBuilder &p_xml_output, const Ty
p_xml_output.append(p_target_itype->proxy_name);
p_xml_output.append(".");
p_xml_output.append(target_imethod->proxy_name);
- p_xml_output.append("\"/>");
+ p_xml_output.append("(");
+ bool first_key = true;
+ for (const ArgumentInterface &iarg : target_imethod->arguments) {
+ const TypeInterface *arg_type = _get_type_or_null(iarg.type);
+
+ if (first_key) {
+ first_key = false;
+ } else {
+ p_xml_output.append(", ");
+ }
+ if (!arg_type) {
+ ERR_PRINT("Cannot resolve argument type in documentation: '" + p_link_target + "'.");
+ p_xml_output.append(iarg.type.cname);
+ continue;
+ }
+ if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL) {
+ p_xml_output.append("Nullable{");
+ }
+ String arg_cs_type = arg_type->cs_type + _get_generic_type_parameters(*arg_type, iarg.type.generic_type_parameters);
+ p_xml_output.append(arg_cs_type.replacen("<", "{").replacen(">", "}").replacen("params ", ""));
+ if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL) {
+ p_xml_output.append("}");
+ }
+ }
+ p_xml_output.append(")\"/>");
} else {
if (!p_target_itype->is_intentionally_ignored(p_link_target)) {
ERR_PRINT("Cannot resolve method reference in documentation: '" + p_link_target + "'.");
diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp
index ae02e16256..ae914e71ef 100644
--- a/modules/mono/editor/code_completion.cpp
+++ b/modules/mono/editor/code_completion.cpp
@@ -31,6 +31,7 @@
#include "code_completion.h"
#include "core/config/project_settings.h"
+#include "core/object/script_language.h"
#include "editor/editor_file_system.h"
#include "editor/editor_settings.h"
#include "scene/gui/control.h"
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Compat.cs b/modules/mono/glue/GodotSharp/GodotSharp/Compat.cs
index 41cea031ab..48b47b166a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Compat.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Compat.cs
@@ -26,7 +26,7 @@ partial class AnimationNode
partial class CodeEdit
{
- /// <inheritdoc cref="AddCodeCompletionOption(CodeCompletionKind, string, string, Nullable{Color}, Resource, Nullable{Variant})"/>
+ /// <inheritdoc cref="AddCodeCompletionOption(CodeCompletionKind, string, string, Nullable{Color}, Resource, Nullable{Variant}, int)"/>
[EditorBrowsable(EditorBrowsableState.Never)]
public void AddCodeCompletionOption(CodeCompletionKind type, string displayText, string insertText, Nullable<Color> textColor, Resource icon, Nullable<Variant> value)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
index 5163ea5113..10aeeae995 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
@@ -52,7 +52,7 @@ namespace Godot.Collections
/// </summary>
/// <param name="array">The objects to put in the new array.</param>
/// <returns>A new Godot Array.</returns>
- public Array(Variant[] array) : this()
+ public Array(Variant[] array)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
@@ -68,7 +68,7 @@ namespace Godot.Collections
this[i] = array[i];
}
- public Array(Span<StringName> array) : this()
+ public Array(Span<StringName> array)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
@@ -84,7 +84,7 @@ namespace Godot.Collections
this[i] = array[i];
}
- public Array(Span<NodePath> array) : this()
+ public Array(Span<NodePath> array)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
@@ -100,7 +100,7 @@ namespace Godot.Collections
this[i] = array[i];
}
- public Array(Span<Rid> array) : this()
+ public Array(Span<Rid> array)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
@@ -121,7 +121,7 @@ namespace Godot.Collections
// fine as long as the array is not mutated. However, Span does this type checking at
// instantiation, so it's not possible to use it even when not mutating anything.
// ReSharper disable once RedundantNameQualifier
- public Array(ReadOnlySpan<GodotObject> array) : this()
+ public Array(ReadOnlySpan<GodotObject> array)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
@@ -1057,7 +1057,7 @@ namespace Godot.Collections
/// </summary>
/// <param name="array">The items to put in the new array.</param>
/// <returns>A new Godot Array.</returns>
- public Array(T[] array) : this()
+ public Array(T[] array)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
index ca0032df73..81b2ffef34 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
@@ -104,6 +104,36 @@ namespace Godot
}
/// <summary>
+ /// Returns the hyperbolic arc (also called inverse) cosine of <paramref name="s"/> in radians.
+ /// Use it to get the angle from an angle's cosine in hyperbolic space if
+ /// <paramref name="s"/> is larger or equal to 1.
+ /// </summary>
+ /// <param name="s">The input hyperbolic cosine value.</param>
+ /// <returns>
+ /// An angle that would result in the given hyperbolic cosine value.
+ /// </returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Acosh(float s)
+ {
+ return MathF.Acosh(s);
+ }
+
+ /// <summary>
+ /// Returns the hyperbolic arc (also called inverse) cosine of <paramref name="s"/> in radians.
+ /// Use it to get the angle from an angle's cosine in hyperbolic space if
+ /// <paramref name="s"/> is larger or equal to 1.
+ /// </summary>
+ /// <param name="s">The input hyperbolic cosine value.</param>
+ /// <returns>
+ /// An angle that would result in the given hyperbolic cosine value.
+ /// </returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Acosh(double s)
+ {
+ return Math.Acosh(s);
+ }
+
+ /// <summary>
/// Returns the arc sine of <paramref name="s"/> in radians.
/// Use to get the angle of sine <paramref name="s"/>.
/// </summary>
@@ -132,6 +162,36 @@ namespace Godot
}
/// <summary>
+ /// Returns the hyperbolic arc (also called inverse) sine of <paramref name="s"/> in radians.
+ /// Use it to get the angle from an angle's sine in hyperbolic space if
+ /// <paramref name="s"/> is larger or equal to 1.
+ /// </summary>
+ /// <param name="s">The input hyperbolic sine value.</param>
+ /// <returns>
+ /// An angle that would result in the given hyperbolic sine value.
+ /// </returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Asinh(float s)
+ {
+ return MathF.Asinh(s);
+ }
+
+ /// <summary>
+ /// Returns the hyperbolic arc (also called inverse) sine of <paramref name="s"/> in radians.
+ /// Use it to get the angle from an angle's sine in hyperbolic space if
+ /// <paramref name="s"/> is larger or equal to 1.
+ /// </summary>
+ /// <param name="s">The input hyperbolic sine value.</param>
+ /// <returns>
+ /// An angle that would result in the given hyperbolic sine value.
+ /// </returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Asinh(double s)
+ {
+ return Math.Asinh(s);
+ }
+
+ /// <summary>
/// Returns the arc tangent of <paramref name="s"/> in radians.
/// Use to get the angle of tangent <paramref name="s"/>.
///
@@ -202,6 +262,36 @@ namespace Godot
}
/// <summary>
+ /// Returns the hyperbolic arc (also called inverse) tangent of <paramref name="s"/> in radians.
+ /// Use it to get the angle from an angle's tangent in hyperbolic space if
+ /// <paramref name="s"/> is between -1 and 1 (non-inclusive).
+ /// </summary>
+ /// <param name="s">The input hyperbolic tangent value.</param>
+ /// <returns>
+ /// An angle that would result in the given hyperbolic tangent value.
+ /// </returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Atanh(float s)
+ {
+ return MathF.Atanh(s);
+ }
+
+ /// <summary>
+ /// Returns the hyperbolic arc (also called inverse) tangent of <paramref name="s"/> in radians.
+ /// Use it to get the angle from an angle's tangent in hyperbolic space if
+ /// <paramref name="s"/> is between -1 and 1 (non-inclusive).
+ /// </summary>
+ /// <param name="s">The input hyperbolic tangent value.</param>
+ /// <returns>
+ /// An angle that would result in the given hyperbolic tangent value.
+ /// </returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Atanh(double s)
+ {
+ return Math.Atanh(s);
+ }
+
+ /// <summary>
/// Rounds <paramref name="s"/> upward (towards positive infinity).
/// </summary>
/// <param name="s">The number to ceil.</param>
diff --git a/modules/multiplayer/doc_classes/SceneReplicationConfig.xml b/modules/multiplayer/doc_classes/SceneReplicationConfig.xml
index b976eea30b..1a51e4b6e9 100644
--- a/modules/multiplayer/doc_classes/SceneReplicationConfig.xml
+++ b/modules/multiplayer/doc_classes/SceneReplicationConfig.xml
@@ -37,6 +37,13 @@
Finds the index of the given [param path].
</description>
</method>
+ <method name="property_get_replication_mode">
+ <return type="int" enum="SceneReplicationConfig.ReplicationMode" />
+ <param index="0" name="path" type="NodePath" />
+ <description>
+ Returns the replication mode for the property identified by the given [param path]. See [enum ReplicationMode].
+ </description>
+ </method>
<method name="property_get_spawn">
<return type="bool" />
<param index="0" name="path" type="NodePath" />
@@ -44,18 +51,28 @@
Returns whether the property identified by the given [param path] is configured to be synchronized on spawn.
</description>
</method>
- <method name="property_get_sync">
+ <method name="property_get_sync" is_deprecated="true">
<return type="bool" />
<param index="0" name="path" type="NodePath" />
<description>
Returns whether the property identified by the given [param path] is configured to be synchronized on process.
+ [i]Deprecated.[/i] Use [method property_get_replication_mode] instead.
</description>
</method>
- <method name="property_get_watch">
+ <method name="property_get_watch" is_deprecated="true">
<return type="bool" />
<param index="0" name="path" type="NodePath" />
<description>
Returns whether the property identified by the given [param path] is configured to be reliably synchronized when changes are detected on process.
+ [i]Deprecated.[/i] Use [method property_get_replication_mode] instead.
+ </description>
+ </method>
+ <method name="property_set_replication_mode">
+ <return type="void" />
+ <param index="0" name="path" type="NodePath" />
+ <param index="1" name="mode" type="int" enum="SceneReplicationConfig.ReplicationMode" />
+ <description>
+ Sets the synchronization mode for the property identified by the given [param path]. See [enum ReplicationMode].
</description>
</method>
<method name="property_set_spawn">
@@ -66,20 +83,22 @@
Sets whether the property identified by the given [param path] is configured to be synchronized on spawn.
</description>
</method>
- <method name="property_set_sync">
+ <method name="property_set_sync" is_deprecated="true">
<return type="void" />
<param index="0" name="path" type="NodePath" />
<param index="1" name="enabled" type="bool" />
<description>
Sets whether the property identified by the given [param path] is configured to be synchronized on process.
+ [i]Deprecated.[/i] Use [method property_set_replication_mode] with [constant REPLICATION_MODE_ALWAYS] instead.
</description>
</method>
- <method name="property_set_watch">
+ <method name="property_set_watch" is_deprecated="true">
<return type="void" />
<param index="0" name="path" type="NodePath" />
<param index="1" name="enabled" type="bool" />
<description>
Sets whether the property identified by the given [param path] is configured to be reliably synchronized when changes are detected on process.
+ [i]Deprecated.[/i] Use [method property_set_replication_mode] with [constant REPLICATION_MODE_ON_CHANGE] instead.
</description>
</method>
<method name="remove_property">
@@ -90,4 +109,15 @@
</description>
</method>
</methods>
+ <constants>
+ <constant name="REPLICATION_MODE_NEVER" value="0" enum="ReplicationMode">
+ Do not keep the given property synchronized.
+ </constant>
+ <constant name="REPLICATION_MODE_ALWAYS" value="1" enum="ReplicationMode">
+ Replicate the given property on process by constantly sending updates using unreliable transfer mode.
+ </constant>
+ <constant name="REPLICATION_MODE_ON_CHANGE" value="2" enum="ReplicationMode">
+ Replicate the given property on process by sending updates using reliable transfer mode when its value changes.
+ </constant>
+ </constants>
</class>
diff --git a/modules/multiplayer/editor/editor_network_profiler.cpp b/modules/multiplayer/editor/editor_network_profiler.cpp
index c2cb0a3d1a..a53eefc452 100644
--- a/modules/multiplayer/editor/editor_network_profiler.cpp
+++ b/modules/multiplayer/editor/editor_network_profiler.cpp
@@ -33,6 +33,7 @@
#include "core/os/os.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
void EditorNetworkProfiler::_bind_methods() {
ADD_SIGNAL(MethodInfo("enable_profiling", PropertyInfo(Variant::BOOL, "enable")));
@@ -62,19 +63,19 @@ void EditorNetworkProfiler::_notification(int p_what) {
void EditorNetworkProfiler::_update_theme_item_cache() {
VBoxContainer::_update_theme_item_cache();
- theme_cache.node_icon = get_theme_icon(SNAME("Node"), SNAME("EditorIcons"));
- theme_cache.stop_icon = get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"));
- theme_cache.play_icon = get_theme_icon(SNAME("Play"), SNAME("EditorIcons"));
- theme_cache.clear_icon = get_theme_icon(SNAME("Clear"), SNAME("EditorIcons"));
+ theme_cache.node_icon = get_theme_icon(SNAME("Node"), EditorStringName(EditorIcons));
+ theme_cache.stop_icon = get_theme_icon(SNAME("Stop"), EditorStringName(EditorIcons));
+ theme_cache.play_icon = get_theme_icon(SNAME("Play"), EditorStringName(EditorIcons));
+ theme_cache.clear_icon = get_theme_icon(SNAME("Clear"), EditorStringName(EditorIcons));
- theme_cache.multiplayer_synchronizer_icon = get_theme_icon("MultiplayerSynchronizer", SNAME("EditorIcons"));
- theme_cache.instance_options_icon = get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons"));
+ theme_cache.multiplayer_synchronizer_icon = get_theme_icon("MultiplayerSynchronizer", EditorStringName(EditorIcons));
+ theme_cache.instance_options_icon = get_theme_icon(SNAME("InstanceOptions"), EditorStringName(EditorIcons));
- theme_cache.incoming_bandwidth_icon = get_theme_icon(SNAME("ArrowDown"), SNAME("EditorIcons"));
- theme_cache.outgoing_bandwidth_icon = get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons"));
+ theme_cache.incoming_bandwidth_icon = get_theme_icon(SNAME("ArrowDown"), EditorStringName(EditorIcons));
+ theme_cache.outgoing_bandwidth_icon = get_theme_icon(SNAME("ArrowUp"), EditorStringName(EditorIcons));
- theme_cache.incoming_bandwidth_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
- theme_cache.outgoing_bandwidth_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ theme_cache.incoming_bandwidth_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
+ theme_cache.outgoing_bandwidth_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
}
void EditorNetworkProfiler::_refresh() {
@@ -128,7 +129,7 @@ void EditorNetworkProfiler::refresh_replication_data() {
const NodeInfo &cfg_info = node_data[E.value.config];
node->set_text(0, root_info.path.get_file());
- node->set_icon(0, has_theme_icon(root_info.type, SNAME("EditorIcons")) ? get_theme_icon(root_info.type, SNAME("EditorIcons")) : theme_cache.node_icon);
+ node->set_icon(0, has_theme_icon(root_info.type, EditorStringName(EditorIcons)) ? get_theme_icon(root_info.type, EditorStringName(EditorIcons)) : theme_cache.node_icon);
node->set_tooltip_text(0, root_info.path);
node->set_text(1, sync_info.path.get_file());
diff --git a/modules/multiplayer/editor/replication_editor.cpp b/modules/multiplayer/editor/replication_editor.cpp
index 04aa856bf9..0051d82e99 100644
--- a/modules/multiplayer/editor/replication_editor.cpp
+++ b/modules/multiplayer/editor/replication_editor.cpp
@@ -35,6 +35,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/scene_tree_editor.h"
#include "editor/inspector_dock.h"
@@ -176,11 +177,6 @@ ReplicationEditor::ReplicationEditor() {
delete_dialog->connect("confirmed", callable_mp(this, &ReplicationEditor::_dialog_closed).bind(true));
add_child(delete_dialog);
- error_dialog = memnew(AcceptDialog);
- error_dialog->set_ok_button_text(TTR("Close"));
- error_dialog->set_title(TTR("Error!"));
- add_child(error_dialog);
-
VBoxContainer *vb = memnew(VBoxContainer);
vb->set_v_size_flags(SIZE_EXPAND_FILL);
add_child(vb);
@@ -256,6 +252,7 @@ ReplicationEditor::ReplicationEditor() {
np_line_edit = memnew(LineEdit);
np_line_edit->set_placeholder(":property");
np_line_edit->set_h_size_flags(SIZE_EXPAND_FILL);
+ np_line_edit->connect("text_submitted", callable_mp(this, &ReplicationEditor::_np_text_submitted));
hb->add_child(np_line_edit);
add_from_path_button = memnew(Button);
add_from_path_button->connect("pressed", callable_mp(this, &ReplicationEditor::_add_pressed));
@@ -271,20 +268,17 @@ ReplicationEditor::ReplicationEditor() {
tree = memnew(Tree);
tree->set_hide_root(true);
- tree->set_columns(5);
+ tree->set_columns(4);
tree->set_column_titles_visible(true);
tree->set_column_title(0, TTR("Properties"));
tree->set_column_expand(0, true);
tree->set_column_title(1, TTR("Spawn"));
tree->set_column_expand(1, false);
tree->set_column_custom_minimum_width(1, 100);
- tree->set_column_title(2, TTR("Sync"));
+ tree->set_column_title(2, TTR("Replicate"));
tree->set_column_custom_minimum_width(2, 100);
- tree->set_column_title(3, TTR("Watch"));
- tree->set_column_custom_minimum_width(3, 100);
tree->set_column_expand(2, false);
tree->set_column_expand(3, false);
- tree->set_column_expand(4, false);
tree->create_item();
tree->connect("button_clicked", callable_mp(this, &ReplicationEditor::_tree_button_pressed));
tree->connect("item_edited", callable_mp(this, &ReplicationEditor::_tree_item_edited));
@@ -292,7 +286,7 @@ ReplicationEditor::ReplicationEditor() {
vb->add_child(tree);
drop_label = memnew(Label);
- drop_label->set_text(TTR("Add properties using the buttons above or\ndrag them them from the inspector and drop them here."));
+ drop_label->set_text(TTR("Add properties using the options above, or\ndrag them them from the inspector and drop them here."));
drop_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
drop_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
tree->add_child(drop_label);
@@ -303,7 +297,7 @@ ReplicationEditor::ReplicationEditor() {
void ReplicationEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_config"), &ReplicationEditor::_update_config);
- ClassDB::bind_method(D_METHOD("_update_checked", "property", "column", "checked"), &ReplicationEditor::_update_checked);
+ ClassDB::bind_method(D_METHOD("_update_value", "property", "column", "value"), &ReplicationEditor::_update_value);
}
bool ReplicationEditor::_can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
@@ -366,24 +360,28 @@ void ReplicationEditor::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
- add_pick_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- pin->set_icon(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")));
+ add_pick_button->set_icon(get_theme_icon(SNAME("Add"), EditorStringName(EditorIcons)));
+ pin->set_icon(get_theme_icon(SNAME("Pin"), EditorStringName(EditorIcons)));
} break;
}
}
void ReplicationEditor::_add_pressed() {
if (!current) {
- error_dialog->set_text(TTR("Please select a MultiplayerSynchronizer first."));
- error_dialog->popup_centered();
+ EditorNode::get_singleton()->show_warning(TTR("Please select a MultiplayerSynchronizer first."));
return;
}
if (current->get_root_path().is_empty()) {
- error_dialog->set_text(TTR("The MultiplayerSynchronizer needs a root path."));
- error_dialog->popup_centered();
+ EditorNode::get_singleton()->show_warning(TTR("The MultiplayerSynchronizer needs a root path."));
return;
}
String np_text = np_line_edit->get_text();
+
+ if (np_text.is_empty()) {
+ EditorNode::get_singleton()->show_warning(TTR("Property/path must not be empty."));
+ return;
+ }
+
int idx = np_text.find(":");
if (idx == -1) {
np_text = ".:" + np_text;
@@ -391,46 +389,54 @@ void ReplicationEditor::_add_pressed() {
np_text = "." + np_text;
}
NodePath path = NodePath(np_text);
+ if (path.is_empty()) {
+ EditorNode::get_singleton()->show_warning(vformat(TTR("Invalid property path: '%s'"), np_text));
+ return;
+ }
_add_sync_property(path);
}
+void ReplicationEditor::_np_text_submitted(const String &p_newtext) {
+ _add_pressed();
+}
+
void ReplicationEditor::_tree_item_edited() {
TreeItem *ti = tree->get_edited();
if (!ti || config.is_null()) {
return;
}
int column = tree->get_edited_column();
- ERR_FAIL_COND(column < 1 || column > 3);
+ ERR_FAIL_COND(column < 1 || column > 2);
const NodePath prop = ti->get_metadata(0);
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
- bool value = ti->is_checked(column);
- // We have a hard limit of 64 watchable properties per synchronizer.
- if (column == 3 && value && config->get_watch_properties().size() > 64) {
- error_dialog->set_text(TTR("Each MultiplayerSynchronizer can have no more than 64 watched properties."));
- error_dialog->popup_centered();
- ti->set_checked(column, false);
- return;
- }
- String method;
if (column == 1) {
undo_redo->create_action(TTR("Set spawn property"));
- method = "property_set_spawn";
+ bool value = ti->is_checked(column);
+ undo_redo->add_do_method(config.ptr(), "property_set_spawn", prop, value);
+ undo_redo->add_undo_method(config.ptr(), "property_set_spawn", prop, !value);
+ undo_redo->add_do_method(this, "_update_value", prop, column, value ? 1 : 0);
+ undo_redo->add_undo_method(this, "_update_value", prop, column, value ? 1 : 0);
+ undo_redo->commit_action();
} else if (column == 2) {
undo_redo->create_action(TTR("Set sync property"));
- method = "property_set_sync";
- } else if (column == 3) {
- undo_redo->create_action(TTR("Set watch property"));
- method = "property_set_watch";
+ int value = ti->get_range(column);
+ int old_value = config->property_get_replication_mode(prop);
+ // We have a hard limit of 64 watchable properties per synchronizer.
+ if (value == SceneReplicationConfig::REPLICATION_MODE_ON_CHANGE && config->get_watch_properties().size() >= 64) {
+ EditorNode::get_singleton()->show_warning(TTR("Each MultiplayerSynchronizer can have no more than 64 watched properties."));
+ ti->set_range(column, old_value);
+ return;
+ }
+ undo_redo->add_do_method(config.ptr(), "property_set_replication_mode", prop, value);
+ undo_redo->add_undo_method(config.ptr(), "property_set_replication_mode", prop, old_value);
+ undo_redo->add_do_method(this, "_update_value", prop, column, value);
+ undo_redo->add_undo_method(this, "_update_value", prop, column, old_value);
+ undo_redo->commit_action();
} else {
ERR_FAIL();
}
- undo_redo->add_do_method(config.ptr(), method, prop, value);
- undo_redo->add_undo_method(config.ptr(), method, prop, !value);
- undo_redo->add_do_method(this, "_update_checked", prop, column, value);
- undo_redo->add_undo_method(this, "_update_checked", prop, column, !value);
- undo_redo->commit_action();
}
void ReplicationEditor::_tree_button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button) {
@@ -455,15 +461,13 @@ void ReplicationEditor::_dialog_closed(bool p_confirmed) {
const NodePath prop = deleting;
int idx = config->property_get_index(prop);
bool spawn = config->property_get_spawn(prop);
- bool sync = config->property_get_sync(prop);
- bool watch = config->property_get_watch(prop);
+ SceneReplicationConfig::ReplicationMode mode = config->property_get_replication_mode(prop);
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Remove Property"));
undo_redo->add_do_method(config.ptr(), "remove_property", prop);
undo_redo->add_undo_method(config.ptr(), "add_property", prop, idx);
undo_redo->add_undo_method(config.ptr(), "property_set_spawn", prop, spawn);
- undo_redo->add_undo_method(config.ptr(), "property_set_sync", prop, sync);
- undo_redo->add_undo_method(config.ptr(), "property_set_watch", prop, watch);
+ undo_redo->add_undo_method(config.ptr(), "property_set_replication_mode", prop, mode);
undo_redo->add_do_method(this, "_update_config");
undo_redo->add_undo_method(this, "_update_config");
undo_redo->commit_action();
@@ -471,14 +475,18 @@ void ReplicationEditor::_dialog_closed(bool p_confirmed) {
deleting = NodePath();
}
-void ReplicationEditor::_update_checked(const NodePath &p_prop, int p_column, bool p_checked) {
+void ReplicationEditor::_update_value(const NodePath &p_prop, int p_column, int p_value) {
if (!tree->get_root()) {
return;
}
TreeItem *ti = tree->get_root()->get_first_child();
while (ti) {
if (ti->get_metadata(0).operator NodePath() == p_prop) {
- ti->set_checked(p_column, p_checked);
+ if (p_column == 1) {
+ ti->set_checked(p_column, p_value != 0);
+ } else if (p_column == 2) {
+ ti->set_range(p_column, p_value);
+ }
return;
}
ti = ti->get_next();
@@ -499,7 +507,7 @@ void ReplicationEditor::_update_config() {
}
for (int i = 0; i < props.size(); i++) {
const NodePath path = props[i];
- _add_property(path, config->property_get_spawn(path), config->property_get_sync(path), config->property_get_watch(path));
+ _add_property(path, config->property_get_spawn(path), config->property_get_replication_mode(path));
}
}
@@ -517,10 +525,10 @@ void ReplicationEditor::edit(MultiplayerSynchronizer *p_sync) {
}
Ref<Texture2D> ReplicationEditor::_get_class_icon(const Node *p_node) {
- if (!p_node || !has_theme_icon(p_node->get_class(), "EditorIcons")) {
- return get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons"));
+ if (!p_node || !has_theme_icon(p_node->get_class(), EditorStringName(EditorIcons))) {
+ return get_theme_icon(SNAME("ImportFail"), EditorStringName(EditorIcons));
}
- return get_theme_icon(p_node->get_class(), "EditorIcons");
+ return get_theme_icon(p_node->get_class(), EditorStringName(EditorIcons));
}
static bool can_sync(const Variant &p_var) {
@@ -541,14 +549,13 @@ static bool can_sync(const Variant &p_var) {
}
}
-void ReplicationEditor::_add_property(const NodePath &p_property, bool p_spawn, bool p_sync, bool p_watch) {
+void ReplicationEditor::_add_property(const NodePath &p_property, bool p_spawn, SceneReplicationConfig::ReplicationMode p_mode) {
String prop = String(p_property);
TreeItem *item = tree->create_item();
item->set_selectable(0, false);
item->set_selectable(1, false);
item->set_selectable(2, false);
item->set_selectable(3, false);
- item->set_selectable(4, false);
item->set_text(0, prop);
item->set_metadata(0, prop);
Node *root_node = current && !current->get_root_path().is_empty() ? current->get_node(current->get_root_path()) : nullptr;
@@ -565,22 +572,23 @@ void ReplicationEditor::_add_property(const NodePath &p_property, bool p_spawn,
bool valid = false;
Variant value = node->get(subpath, &valid);
if (valid && !can_sync(value)) {
- item->set_icon(3, get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
- item->set_tooltip_text(3, TTR("Property of this type not supported."));
+ item->set_icon(0, get_theme_icon(SNAME("StatusWarning"), EditorStringName(EditorIcons)));
+ item->set_tooltip_text(0, TTR("Property of this type not supported."));
+ } else {
+ item->set_icon(0, icon);
}
+ } else {
+ item->set_icon(0, icon);
}
- item->set_icon(0, icon);
- item->add_button(4, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ item->add_button(3, get_theme_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
item->set_text_alignment(1, HORIZONTAL_ALIGNMENT_CENTER);
item->set_cell_mode(1, TreeItem::CELL_MODE_CHECK);
item->set_checked(1, p_spawn);
item->set_editable(1, true);
item->set_text_alignment(2, HORIZONTAL_ALIGNMENT_CENTER);
- item->set_cell_mode(2, TreeItem::CELL_MODE_CHECK);
- item->set_checked(2, p_sync);
+ item->set_cell_mode(2, TreeItem::CELL_MODE_RANGE);
+ item->set_range_config(2, 0, 2, 1);
+ item->set_text(2, "Never,Always,On Change");
+ item->set_range(2, (int)p_mode);
item->set_editable(2, true);
- item->set_text_alignment(3, HORIZONTAL_ALIGNMENT_CENTER);
- item->set_cell_mode(3, TreeItem::CELL_MODE_CHECK);
- item->set_checked(3, p_watch);
- item->set_editable(3, true);
}
diff --git a/modules/multiplayer/editor/replication_editor.h b/modules/multiplayer/editor/replication_editor.h
index 208eaabff5..80c1892ec3 100644
--- a/modules/multiplayer/editor/replication_editor.h
+++ b/modules/multiplayer/editor/replication_editor.h
@@ -51,7 +51,6 @@ class ReplicationEditor : public VBoxContainer {
private:
MultiplayerSynchronizer *current = nullptr;
- AcceptDialog *error_dialog = nullptr;
ConfirmationDialog *delete_dialog = nullptr;
Button *add_pick_button = nullptr;
Button *add_from_path_button = nullptr;
@@ -72,12 +71,13 @@ private:
Ref<Texture2D> _get_class_icon(const Node *p_node);
void _add_pressed();
+ void _np_text_submitted(const String &p_newtext);
void _tree_item_edited();
void _tree_button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button);
- void _update_checked(const NodePath &p_prop, int p_column, bool p_checked);
+ void _update_value(const NodePath &p_prop, int p_column, int p_checked);
void _update_config();
void _dialog_closed(bool p_confirmed);
- void _add_property(const NodePath &p_property, bool p_spawn = true, bool p_sync = true, bool p_watch = false);
+ void _add_property(const NodePath &p_property, bool p_spawn, SceneReplicationConfig::ReplicationMode p_mode);
void _pick_node_filter_text_changed(const String &p_newtext);
void _pick_node_select_recursive(TreeItem *p_item, const String &p_filter, Vector<Node *> &p_select_candidates);
diff --git a/modules/multiplayer/scene_cache_interface.h b/modules/multiplayer/scene_cache_interface.h
index 9400417cdb..7a7304fde8 100644
--- a/modules/multiplayer/scene_cache_interface.h
+++ b/modules/multiplayer/scene_cache_interface.h
@@ -33,6 +33,7 @@
#include "scene/main/multiplayer_api.h"
+class Node;
class SceneMultiplayer;
class SceneCacheInterface : public RefCounted {
diff --git a/modules/multiplayer/scene_replication_config.cpp b/modules/multiplayer/scene_replication_config.cpp
index db615f8c20..836fa1014d 100644
--- a/modules/multiplayer/scene_replication_config.cpp
+++ b/modules/multiplayer/scene_replication_config.cpp
@@ -47,38 +47,26 @@ bool SceneReplicationConfig::_set(const StringName &p_name, const Variant &p_val
add_property(path);
return true;
}
- ERR_FAIL_COND_V(p_value.get_type() != Variant::BOOL, false);
ERR_FAIL_INDEX_V(idx, properties.size(), false);
ReplicationProperty &prop = properties[idx];
- if (what == "sync") {
- if ((bool)p_value == prop.sync) {
- return true;
- }
- prop.sync = p_value;
- if (prop.sync) {
- sync_props.push_back(prop.name);
- } else {
- sync_props.erase(prop.name);
- }
+ if (what == "replication_mode") {
+ ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
+ ReplicationMode mode = (ReplicationMode)p_value.operator int();
+ ERR_FAIL_COND_V(mode < REPLICATION_MODE_NEVER || mode > REPLICATION_MODE_ON_CHANGE, false);
+ property_set_replication_mode(prop.name, mode);
return true;
- } else if (what == "spawn") {
- if ((bool)p_value == prop.spawn) {
- return true;
- }
- prop.spawn = p_value;
- if (prop.spawn) {
- spawn_props.push_back(prop.name);
- } else {
- spawn_props.erase(prop.name);
- }
+ }
+ ERR_FAIL_COND_V(p_value.get_type() != Variant::BOOL, false);
+ if (what == "spawn") {
+ property_set_spawn(prop.name, p_value);
+ return true;
+ } else if (what == "sync") {
+ // Deprecated.
+ property_set_sync(prop.name, p_value);
return true;
} else if (what == "watch") {
- prop.watch = p_value;
- if (prop.watch) {
- watch_props.push_back(prop.name);
- } else {
- watch_props.erase(prop.name);
- }
+ // Deprecated.
+ property_set_watch(prop.name, p_value);
return true;
}
}
@@ -96,14 +84,11 @@ bool SceneReplicationConfig::_get(const StringName &p_name, Variant &r_ret) cons
if (what == "path") {
r_ret = prop.name;
return true;
- } else if (what == "sync") {
- r_ret = prop.sync;
- return true;
} else if (what == "spawn") {
r_ret = prop.spawn;
return true;
- } else if (what == "watch") {
- r_ret = prop.watch;
+ } else if (what == "replication_mode") {
+ r_ret = prop.mode;
return true;
}
}
@@ -114,8 +99,7 @@ void SceneReplicationConfig::_get_property_list(List<PropertyInfo> *p_list) cons
for (int i = 0; i < properties.size(); i++) {
p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/spawn", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
- p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/sync", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
- p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/watch", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::INT, "properties/" + itos(i) + "/replication_mode", PROPERTY_HINT_ENUM, "Never,Always,On Change", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
}
}
@@ -129,11 +113,11 @@ TypedArray<NodePath> SceneReplicationConfig::get_properties() const {
void SceneReplicationConfig::add_property(const NodePath &p_path, int p_index) {
ERR_FAIL_COND(properties.find(p_path));
+ ERR_FAIL_COND(p_path == NodePath());
if (p_index < 0 || p_index == properties.size()) {
properties.push_back(ReplicationProperty(p_path));
- sync_props.push_back(p_path);
- spawn_props.push_back(p_path);
+ dirty = true;
return;
}
@@ -146,23 +130,12 @@ void SceneReplicationConfig::add_property(const NodePath &p_path, int p_index) {
c++;
}
properties.insert_before(I, ReplicationProperty(p_path));
- sync_props.clear();
- spawn_props.clear();
- for (const ReplicationProperty &prop : properties) {
- if (prop.sync) {
- sync_props.push_back(prop.name);
- }
- if (prop.spawn) {
- spawn_props.push_back(prop.name);
- }
- }
+ dirty = true;
}
void SceneReplicationConfig::remove_property(const NodePath &p_path) {
properties.erase(p_path);
- sync_props.erase(p_path);
- spawn_props.erase(p_path);
- watch_props.clear();
+ dirty = true;
}
bool SceneReplicationConfig::has_property(const NodePath &p_path) const {
@@ -196,56 +169,99 @@ void SceneReplicationConfig::property_set_spawn(const NodePath &p_path, bool p_e
return;
}
E->get().spawn = p_enabled;
- spawn_props.clear();
- for (const ReplicationProperty &prop : properties) {
- if (prop.spawn) {
- spawn_props.push_back(prop.name);
- }
- }
+ dirty = true;
}
bool SceneReplicationConfig::property_get_sync(const NodePath &p_path) {
List<ReplicationProperty>::Element *E = properties.find(p_path);
ERR_FAIL_COND_V(!E, false);
- return E->get().sync;
+ return E->get().mode == REPLICATION_MODE_ALWAYS;
}
void SceneReplicationConfig::property_set_sync(const NodePath &p_path, bool p_enabled) {
- List<ReplicationProperty>::Element *E = properties.find(p_path);
- ERR_FAIL_COND(!E);
- if (E->get().sync == p_enabled) {
- return;
- }
- E->get().sync = p_enabled;
- sync_props.clear();
- for (const ReplicationProperty &prop : properties) {
- if (prop.sync) {
- sync_props.push_back(prop.name);
- }
+ if (p_enabled) {
+ property_set_replication_mode(p_path, REPLICATION_MODE_ALWAYS);
+ } else if (property_get_replication_mode(p_path) == REPLICATION_MODE_ALWAYS) {
+ property_set_replication_mode(p_path, REPLICATION_MODE_NEVER);
}
}
bool SceneReplicationConfig::property_get_watch(const NodePath &p_path) {
List<ReplicationProperty>::Element *E = properties.find(p_path);
ERR_FAIL_COND_V(!E, false);
- return E->get().watch;
+ return E->get().mode == REPLICATION_MODE_ON_CHANGE;
}
void SceneReplicationConfig::property_set_watch(const NodePath &p_path, bool p_enabled) {
+ if (p_enabled) {
+ property_set_replication_mode(p_path, REPLICATION_MODE_ON_CHANGE);
+ } else if (property_get_replication_mode(p_path) == REPLICATION_MODE_ON_CHANGE) {
+ property_set_replication_mode(p_path, REPLICATION_MODE_NEVER);
+ }
+}
+
+SceneReplicationConfig::ReplicationMode SceneReplicationConfig::property_get_replication_mode(const NodePath &p_path) {
+ List<ReplicationProperty>::Element *E = properties.find(p_path);
+ ERR_FAIL_COND_V(!E, REPLICATION_MODE_NEVER);
+ return E->get().mode;
+}
+
+void SceneReplicationConfig::property_set_replication_mode(const NodePath &p_path, ReplicationMode p_mode) {
List<ReplicationProperty>::Element *E = properties.find(p_path);
ERR_FAIL_COND(!E);
- if (E->get().watch == p_enabled) {
+ if (E->get().mode == p_mode) {
return;
}
- E->get().watch = p_enabled;
+ E->get().mode = p_mode;
+ dirty = true;
+}
+
+void SceneReplicationConfig::_update() {
+ if (!dirty) {
+ return;
+ }
+ dirty = false;
+ sync_props.clear();
+ spawn_props.clear();
watch_props.clear();
for (const ReplicationProperty &prop : properties) {
- if (prop.watch) {
- watch_props.push_back(p_path);
+ if (prop.spawn) {
+ spawn_props.push_back(prop.name);
+ }
+ switch (prop.mode) {
+ case REPLICATION_MODE_ALWAYS:
+ sync_props.push_back(prop.name);
+ break;
+ case REPLICATION_MODE_ON_CHANGE:
+ watch_props.push_back(prop.name);
+ break;
+ default:
+ break;
}
}
}
+const List<NodePath> &SceneReplicationConfig::get_spawn_properties() {
+ if (dirty) {
+ _update();
+ }
+ return spawn_props;
+}
+
+const List<NodePath> &SceneReplicationConfig::get_sync_properties() {
+ if (dirty) {
+ _update();
+ }
+ return sync_props;
+}
+
+const List<NodePath> &SceneReplicationConfig::get_watch_properties() {
+ if (dirty) {
+ _update();
+ }
+ return watch_props;
+}
+
void SceneReplicationConfig::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_properties"), &SceneReplicationConfig::get_properties);
ClassDB::bind_method(D_METHOD("add_property", "path", "index"), &SceneReplicationConfig::add_property, DEFVAL(-1));
@@ -254,6 +270,14 @@ void SceneReplicationConfig::_bind_methods() {
ClassDB::bind_method(D_METHOD("property_get_index", "path"), &SceneReplicationConfig::property_get_index);
ClassDB::bind_method(D_METHOD("property_get_spawn", "path"), &SceneReplicationConfig::property_get_spawn);
ClassDB::bind_method(D_METHOD("property_set_spawn", "path", "enabled"), &SceneReplicationConfig::property_set_spawn);
+ ClassDB::bind_method(D_METHOD("property_get_replication_mode", "path"), &SceneReplicationConfig::property_get_replication_mode);
+ ClassDB::bind_method(D_METHOD("property_set_replication_mode", "path", "mode"), &SceneReplicationConfig::property_set_replication_mode);
+
+ BIND_ENUM_CONSTANT(REPLICATION_MODE_NEVER);
+ BIND_ENUM_CONSTANT(REPLICATION_MODE_ALWAYS);
+ BIND_ENUM_CONSTANT(REPLICATION_MODE_ON_CHANGE);
+
+ // Deprecated.
ClassDB::bind_method(D_METHOD("property_get_sync", "path"), &SceneReplicationConfig::property_get_sync);
ClassDB::bind_method(D_METHOD("property_set_sync", "path", "enabled"), &SceneReplicationConfig::property_set_sync);
ClassDB::bind_method(D_METHOD("property_get_watch", "path"), &SceneReplicationConfig::property_get_watch);
diff --git a/modules/multiplayer/scene_replication_config.h b/modules/multiplayer/scene_replication_config.h
index 44f8259904..3f870ba2d8 100644
--- a/modules/multiplayer/scene_replication_config.h
+++ b/modules/multiplayer/scene_replication_config.h
@@ -39,12 +39,18 @@ class SceneReplicationConfig : public Resource {
OBJ_SAVE_TYPE(SceneReplicationConfig);
RES_BASE_EXTENSION("repl");
+public:
+ enum ReplicationMode {
+ REPLICATION_MODE_NEVER,
+ REPLICATION_MODE_ALWAYS,
+ REPLICATION_MODE_ON_CHANGE,
+ };
+
private:
struct ReplicationProperty {
NodePath name;
bool spawn = true;
- bool sync = true;
- bool watch = false;
+ ReplicationMode mode = REPLICATION_MODE_ALWAYS;
bool operator==(const ReplicationProperty &p_to) {
return name == p_to.name;
@@ -61,6 +67,9 @@ private:
List<NodePath> spawn_props;
List<NodePath> sync_props;
List<NodePath> watch_props;
+ bool dirty = false;
+
+ void _update();
protected:
static void _bind_methods();
@@ -86,11 +95,16 @@ public:
bool property_get_watch(const NodePath &p_path);
void property_set_watch(const NodePath &p_path, bool p_enabled);
- const List<NodePath> &get_spawn_properties() { return spawn_props; }
- const List<NodePath> &get_sync_properties() { return sync_props; }
- const List<NodePath> &get_watch_properties() { return watch_props; }
+ ReplicationMode property_get_replication_mode(const NodePath &p_path);
+ void property_set_replication_mode(const NodePath &p_path, ReplicationMode p_mode);
+
+ const List<NodePath> &get_spawn_properties();
+ const List<NodePath> &get_sync_properties();
+ const List<NodePath> &get_watch_properties();
SceneReplicationConfig() {}
};
+VARIANT_ENUM_CAST(SceneReplicationConfig::ReplicationMode);
+
#endif // SCENE_REPLICATION_CONFIG_H
diff --git a/modules/navigation/editor/navigation_mesh_editor_plugin.cpp b/modules/navigation/editor/navigation_mesh_editor_plugin.cpp
index 535091e5b6..85948e7547 100644
--- a/modules/navigation/editor/navigation_mesh_editor_plugin.cpp
+++ b/modules/navigation/editor/navigation_mesh_editor_plugin.cpp
@@ -35,6 +35,7 @@
#include "core/io/marshalls.h"
#include "core/io/resource_saver.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/navigation_region_3d.h"
#include "scene/gui/box_container.h"
@@ -54,8 +55,8 @@ void NavigationMeshEditor::_node_removed(Node *p_node) {
void NavigationMeshEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- button_bake->set_icon(get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
- button_reset->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
+ button_bake->set_icon(get_theme_icon(SNAME("Bake"), EditorStringName(EditorIcons)));
+ button_reset->set_icon(get_theme_icon(SNAME("Reload"), EditorStringName(EditorIcons)));
} break;
}
}
diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h
index 40893bada6..c12605bc7a 100644
--- a/modules/navigation/godot_navigation_server.h
+++ b/modules/navigation/godot_navigation_server.h
@@ -56,7 +56,9 @@
void MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1)
class GodotNavigationServer;
+#ifndef _3D_DISABLED
class NavMeshGenerator3D;
+#endif // _3D_DISABLED
struct SetCommand {
virtual ~SetCommand() {}
@@ -80,7 +82,9 @@ class GodotNavigationServer : public NavigationServer3D {
LocalVector<NavMap *> active_maps;
LocalVector<uint32_t> active_maps_update_id;
+#ifndef _3D_DISABLED
NavMeshGenerator3D *navmesh_generator_3d = nullptr;
+#endif // _3D_DISABLED
// Performance Monitor
int pm_region_count = 0;
diff --git a/modules/openxr/editor/openxr_action_editor.cpp b/modules/openxr/editor/openxr_action_editor.cpp
index 586b0b0697..4b188471a0 100644
--- a/modules/openxr/editor/openxr_action_editor.cpp
+++ b/modules/openxr/editor/openxr_action_editor.cpp
@@ -30,6 +30,8 @@
#include "openxr_action_editor.h"
+#include "editor/editor_string_names.h"
+
void OpenXRActionEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_do_set_name", "name"), &OpenXRActionEditor::_do_set_name);
ClassDB::bind_method(D_METHOD("_do_set_localized_name", "name"), &OpenXRActionEditor::_do_set_localized_name);
@@ -39,7 +41,7 @@ void OpenXRActionEditor::_bind_methods() {
}
void OpenXRActionEditor::_theme_changed() {
- rem_action->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ rem_action->set_icon(get_theme_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
}
void OpenXRActionEditor::_notification(int p_what) {
diff --git a/modules/openxr/editor/openxr_action_set_editor.cpp b/modules/openxr/editor/openxr_action_set_editor.cpp
index 6a63720257..a9fc6c4db6 100644
--- a/modules/openxr/editor/openxr_action_set_editor.cpp
+++ b/modules/openxr/editor/openxr_action_set_editor.cpp
@@ -30,6 +30,7 @@
#include "openxr_action_set_editor.h"
+#include "editor/editor_string_names.h"
#include "openxr_action_editor.h"
void OpenXRActionSetEditor::_bind_methods() {
@@ -45,16 +46,16 @@ void OpenXRActionSetEditor::_bind_methods() {
void OpenXRActionSetEditor::_set_fold_icon() {
if (is_expanded) {
- fold_btn->set_icon(get_theme_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons")));
+ fold_btn->set_icon(get_theme_icon(SNAME("GuiTreeArrowDown"), EditorStringName(EditorIcons)));
} else {
- fold_btn->set_icon(get_theme_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons")));
+ fold_btn->set_icon(get_theme_icon(SNAME("GuiTreeArrowRight"), EditorStringName(EditorIcons)));
}
}
void OpenXRActionSetEditor::_theme_changed() {
_set_fold_icon();
- add_action->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- rem_action_set->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ add_action->set_icon(get_theme_icon(SNAME("Add"), EditorStringName(EditorIcons)));
+ rem_action_set->set_icon(get_theme_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
}
void OpenXRActionSetEditor::_notification(int p_what) {
diff --git a/modules/openxr/editor/openxr_interaction_profile_editor.cpp b/modules/openxr/editor/openxr_interaction_profile_editor.cpp
index 9998bb80e3..7bccabf936 100644
--- a/modules/openxr/editor/openxr_interaction_profile_editor.cpp
+++ b/modules/openxr/editor/openxr_interaction_profile_editor.cpp
@@ -30,6 +30,7 @@
#include "openxr_interaction_profile_editor.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/label.h"
@@ -220,7 +221,7 @@ void OpenXRInteractionProfileEditor::_add_io_path(VBoxContainer *p_container, co
path_hb->add_child(type_label);
Button *path_add = memnew(Button);
- path_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ path_add->set_icon(get_theme_icon(SNAME("Add"), EditorStringName(EditorIcons)));
path_add->set_flat(true);
path_add->connect("pressed", callable_mp(this, &OpenXRInteractionProfileEditor::select_action_for).bind(String(p_io_path->openxr_path)));
path_hb->add_child(path_add);
@@ -248,7 +249,7 @@ void OpenXRInteractionProfileEditor::_add_io_path(VBoxContainer *p_container, co
Button *action_rem = memnew(Button);
action_rem->set_flat(true);
- action_rem->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ action_rem->set_icon(get_theme_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
action_rem->connect("pressed", callable_mp((OpenXRInteractionProfileEditor *)this, &OpenXRInteractionProfileEditor::_on_remove_pressed).bind(action->get_name_with_set(), String(p_io_path->openxr_path)));
action_hb->add_child(action_rem);
}
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index cbe48db494..3850fc4518 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -2383,10 +2383,8 @@ void TextServerAdvanced::_font_set_variation_coordinates(const RID &p_font_rid,
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
- if (fd->variation_coordinates != p_variation_coordinates) {
- _font_clear_cache(fd);
- fd->variation_coordinates = p_variation_coordinates;
- }
+ _font_clear_cache(fd);
+ fd->variation_coordinates = p_variation_coordinates;
}
Dictionary TextServerAdvanced::_font_get_variation_coordinates(const RID &p_font_rid) const {
@@ -5882,8 +5880,11 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
sd->para_direction = (direction == UBIDI_RTL) ? DIRECTION_RTL : DIRECTION_LTR;
sd->base_para_direction = direction;
} else {
- sd->para_direction = DIRECTION_LTR;
- sd->base_para_direction = UBIDI_DEFAULT_LTR;
+ const String &lang = (sd->spans.is_empty() || sd->spans[0].language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : sd->spans[0].language;
+ bool lang_rtl = _is_locale_right_to_left(lang);
+
+ sd->para_direction = lang_rtl ? DIRECTION_RTL : DIRECTION_LTR;
+ sd->base_para_direction = lang_rtl ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR;
}
} break;
}
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index d0587bf6c0..5d4de7a0d6 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -1376,10 +1376,8 @@ void TextServerFallback::_font_set_variation_coordinates(const RID &p_font_rid,
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
- if (fd->variation_coordinates != p_variation_coordinates) {
- _font_clear_cache(fd);
- fd->variation_coordinates = p_variation_coordinates;
- }
+ _font_clear_cache(fd);
+ fd->variation_coordinates = p_variation_coordinates;
}
Dictionary TextServerFallback::_font_get_variation_coordinates(const RID &p_font_rid) const {
diff --git a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml
index f8c015dd06..454f8f2ed4 100644
--- a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml
+++ b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
A WebRTC connection between the local computer and a remote peer. Provides an interface to connect, maintain and monitor the connection.
- Setting up a WebRTC connection between two peers from now on) may not seem a trivial task, but it can be broken down into 3 main steps:
+ Setting up a WebRTC connection between two peers may not seem a trivial task, but it can be broken down into 3 main steps:
- The peer that wants to initiate the connection ([code]A[/code] from now on) creates an offer and send it to the other peer ([code]B[/code] from now on).
- [code]B[/code] receives the offer, generate and answer, and sends it to [code]A[/code]).
- [code]A[/code] and [code]B[/code] then generates and exchange ICE candidates with each other.
diff --git a/modules/webrtc/webrtc_data_channel_extension.h b/modules/webrtc/webrtc_data_channel_extension.h
index 462e089592..b7afbaf13a 100644
--- a/modules/webrtc/webrtc_data_channel_extension.h
+++ b/modules/webrtc/webrtc_data_channel_extension.h
@@ -35,7 +35,6 @@
#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
class WebRTCDataChannelExtension : public WebRTCDataChannel {
diff --git a/modules/webrtc/webrtc_peer_connection_extension.h b/modules/webrtc/webrtc_peer_connection_extension.h
index f3339f1eb4..05d88e0f65 100644
--- a/modules/webrtc/webrtc_peer_connection_extension.h
+++ b/modules/webrtc/webrtc_peer_connection_extension.h
@@ -35,7 +35,6 @@
#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
class WebRTCPeerConnectionExtension : public WebRTCPeerConnection {