diff options
Diffstat (limited to 'modules')
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 { |
