diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 56e9057a2a8..933b9891cc2 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1304,16 +1304,8 @@ ProjectSettings::ProjectSettings() { } extensions.push_back("gdshader"); - GLOBAL_DEF("editor/run/main_run_args", ""); - GLOBAL_DEF(PropertyInfo(Variant::PACKED_STRING_ARRAY, "editor/script/search_in_file_extensions"), extensions); - GLOBAL_DEF(PropertyInfo(Variant::STRING, "editor/script/templates_search_path", PROPERTY_HINT_DIR), "res://script_templates"); - - // For correct doc generation. - GLOBAL_DEF("editor/naming/default_signal_callback_name", "_on_{node_name}_{signal_name}"); - GLOBAL_DEF("editor/naming/default_signal_callback_to_self_name", "_on_{signal_name}"); - _add_builtin_input_map(); // Keep the enum values in sync with the `DisplayServer::ScreenOrientation` enum. diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index e26ead6d8cb..79b0ebc6414 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -1052,6 +1052,7 @@ void GDExtensionAPIDump::generate_extension_json_file(const String &p_path) { String text = json->stringify(api, "\t", false) + "\n"; Ref fa = FileAccess::open(p_path, FileAccess::WRITE); + ERR_FAIL_COND_MSG(fa.is_null(), vformat("Cannot open file '%s' for writing.", p_path)); fa->store_string(text); } diff --git a/core/extension/make_interface_dumper.py b/core/extension/make_interface_dumper.py index a8af0e9ff6f..a604112d137 100644 --- a/core/extension/make_interface_dumper.py +++ b/core/extension/make_interface_dumper.py @@ -27,6 +27,7 @@ class GDExtensionInterfaceDump { public: static void generate_gdextension_interface_file(const String &p_path) { Ref fa = FileAccess::open(p_path, FileAccess::WRITE); + ERR_FAIL_COND_MSG(fa.is_null(), vformat("Cannot open file '%s' for writing.", p_path)); CharString cs(gdextension_interface_dump); fa->store_buffer((const uint8_t *)cs.ptr(), cs.length()); }; diff --git a/doc/Makefile b/doc/Makefile index c8bf32d6e29..cc2ebf98818 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,28 +1,28 @@ BASEDIR = . -CLASSES = $(BASEDIR)/classes/ $(BASEDIR)/../modules/ +CLASSES = "$(BASEDIR)/classes/" "$(BASEDIR)/../modules/" OUTPUTDIR = $(BASEDIR)/_build TOOLSDIR = $(BASEDIR)/tools -JSDIR = $(BASEDIR)/../platform/web +JSDIR = "$(BASEDIR)/../platform/web" LANGARG ?= en LANGCMD = -l $(LANGARG) .ONESHELL: clean: - rm -rf $(OUTPUTDIR) + rm -rf "$(OUTPUTDIR)" doxygen: - rm -rf $(OUTPUTDIR)/doxygen - mkdir -p $(OUTPUTDIR)/doxygen + rm -rf "$(OUTPUTDIR)/doxygen" + mkdir -p "$(OUTPUTDIR)/doxygen" doxygen Doxyfile rst: - rm -rf $(OUTPUTDIR)/rst - mkdir -p $(OUTPUTDIR)/rst - python3 $(TOOLSDIR)/make_rst.py -o $(OUTPUTDIR)/rst $(LANGCMD) $(CLASSES) + rm -rf "$(OUTPUTDIR)/rst" + mkdir -p "$(OUTPUTDIR)/rst" + python3 "$(TOOLSDIR)/make_rst.py" -o "$(OUTPUTDIR)/rst" "$(LANGCMD)" $(CLASSES) rstjs: - rm -rf $(OUTPUTDIR)/rstjs - mkdir -p $(OUTPUTDIR)/rstjs - npm --prefix $(JSDIR) ci - npm --prefix $(JSDIR) run docs -- --destination $(OUTPUTDIR)/rstjs/html5_shell_classref.rst + rm -rf "$(OUTPUTDIR)/rstjs" + mkdir -p "$(OUTPUTDIR)/rstjs" + npm --prefix "$(JSDIR)" ci + npm --prefix "$(JSDIR)" run docs -- --destination "$(OUTPUTDIR)/rstjs/html5_shell_classref.rst" diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml index 2c5337eea3d..b4bab2de674 100644 --- a/doc/classes/AABB.xml +++ b/doc/classes/AABB.xml @@ -188,7 +188,7 @@ - Returns [code]true[/code] if the given ray intersects with this [AABB]. Ray length is infinite. + Returns the point of intersection of the given ray with this [AABB] or [code]null[/code] if there is no intersection. Ray length is infinite. @@ -196,7 +196,7 @@ - Returns [code]true[/code] if the [AABB] intersects the line segment between [param from] and [param to]. + Returns the point of intersection between [param from] and [param to] with this [AABB] or [code]null[/code] if there is no intersection. diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index c4fec5a7295..86f8f357f86 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -41,7 +41,6 @@ [b]Note:[/b] Concatenating with the [code]+=[/code] operator will create a new array, which has a cost. If you want to append another array to an existing array, [method append_array] is more efficient. [b]Note:[/b] Arrays are always passed by reference. To get a copy of an array that can be modified independently of the original array, use [method duplicate]. [b]Note:[/b] Erasing elements while iterating over arrays is [b]not[/b] supported and will result in unpredictable behavior. - [b]Note:[/b] When declaring an array with [code]const[/code], the array itself can still be mutated by defining the values at individual indices or pushing/removing elements. Using [code]const[/code] will only prevent assigning the constant with another value after it was initialized. diff --git a/doc/classes/DTLSServer.xml b/doc/classes/DTLSServer.xml index ae1ba10ec76..3e917800954 100644 --- a/doc/classes/DTLSServer.xml +++ b/doc/classes/DTLSServer.xml @@ -23,8 +23,8 @@ func _process(delta): while server.is_connection_available(): - var peer : PacketPeerUDP = server.take_connection() - var dtls_peer : PacketPeerDTLS = dtls.take_connection(peer) + var peer: PacketPeerUDP = server.take_connection() + var dtls_peer: PacketPeerDTLS = dtls.take_connection(peer) if dtls_peer.get_status() != PacketPeerDTLS.STATUS_HANDSHAKING: continue # It is normal that 50% of the connections fails due to cookie exchange. print("Peer connected!") diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index a5a50b4c6a1..d31fd75a045 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -135,7 +135,6 @@ [/csharp] [/codeblocks] [b]Note:[/b] Erasing elements while iterating over dictionaries is [b]not[/b] supported and will result in unpredictable behavior. - [b]Note:[/b] When declaring a dictionary with [code]const[/code], the dictionary becomes read-only. A read-only Dictionary's entries cannot be overridden at run-time. This does [i]not[/i] affect nested [Array] and [Dictionary] values. $DOCS_URL/tutorials/scripting/gdscript/gdscript_basics.html#dictionary diff --git a/doc/classes/DirAccess.xml b/doc/classes/DirAccess.xml index 27f2eb7f2f5..8e1528f1c65 100644 --- a/doc/classes/DirAccess.xml +++ b/doc/classes/DirAccess.xml @@ -290,7 +290,7 @@ - If [code]true[/code], hidden files are included when the navigating directory. + If [code]true[/code], hidden files are included when navigating the directory. Affects [method list_dir_begin], [method get_directories] and [method get_files]. diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 31b9703b017..18c11ec68db 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -190,7 +190,7 @@ Adds a new checkable item with text [param label] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. - An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using boolean OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). + An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). [b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag]. [b]Note:[/b] This method is implemented on macOS. [b]Supported system menu IDs:[/b] @@ -213,7 +213,7 @@ Adds a new checkable item with text [param label] and icon [param icon] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. - An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using boolean OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). + An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). [b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag]. [b]Note:[/b] This method is implemented on macOS. [b]Supported system menu IDs:[/b] @@ -236,7 +236,7 @@ Adds a new item with text [param label] and icon [param icon] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. - An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using boolean OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). + An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). [b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag]. [b]Note:[/b] This method is implemented on macOS. [b]Supported system menu IDs:[/b] @@ -259,7 +259,7 @@ Adds a new radio-checkable item with text [param label] and icon [param icon] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. - An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using boolean OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). + An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). [b]Note:[/b] Radio-checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method global_menu_set_item_checked] for more info on how to control it. [b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag]. [b]Note:[/b] This method is implemented on macOS. @@ -282,7 +282,7 @@ Adds a new item with text [param label] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. - An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using boolean OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). + An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). [b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag]. [b]Note:[/b] This method is implemented on macOS. [b]Supported system menu IDs:[/b] @@ -307,7 +307,7 @@ Adds a new item with text [param label] to the global menu with ID [param menu_root]. Contrarily to normal binary items, multistate items can have more than two states, as defined by [param max_states]. Each press or activate of the item will increase the state by one. The default value is defined by [param default_state]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. - An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using boolean OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). + An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). [b]Note:[/b] By default, there's no indication of the current item state, it should be changed manually. [b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag]. [b]Note:[/b] This method is implemented on macOS. @@ -330,7 +330,7 @@ Adds a new radio-checkable item with text [param label] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. - An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using boolean OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). + An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). [b]Note:[/b] Radio-checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method global_menu_set_item_checked] for more info on how to control it. [b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag]. [b]Note:[/b] This method is implemented on macOS. @@ -507,7 +507,7 @@ - Returns the tooltip associated with the specified index index [param idx]. + Returns the tooltip associated with the specified index [param idx]. [b]Note:[/b] This method is implemented on macOS. @@ -565,7 +565,7 @@ - Sets the accelerator of the item at index [param idx]. [param keycode] can be a single [enum Key], or a combination of [enum KeyModifierMask]s and [enum Key]s using boolean OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). + Sets the accelerator of the item at index [param idx]. [param keycode] can be a single [enum Key], or a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). [b]Note:[/b] This method is implemented on macOS. @@ -576,7 +576,7 @@ Sets the callback of the item at index [param idx]. Callback is emitted when an item is pressed. - [b]Note:[/b] The [param callback] Callable needs to accept exactly one Variant parameter, the parameter passed to the Callable will be the value passed to the tag parameter when the menu item was created. + [b]Note:[/b] The [param callback] Callable needs to accept exactly one Variant parameter, the parameter passed to the Callable will be the value passed to the [code]tag[/code] parameter when the menu item was created. [b]Note:[/b] This method is implemented on macOS. @@ -638,7 +638,7 @@ Sets the callback of the item at index [param idx]. Callback is emitted when its accelerator is activated. - [b]Note:[/b] The [param key_callback] Callable needs to accept exactly one Variant parameter, the parameter passed to the Callable will be the value passed to the tag parameter when the menu item was created. + [b]Note:[/b] The [param key_callback] Callable needs to accept exactly one Variant parameter, the parameter passed to the Callable will be the value passed to the [code]tag[/code] parameter when the menu item was created. [b]Note:[/b] This method is implemented on macOS. diff --git a/doc/classes/EditorFileDialog.xml b/doc/classes/EditorFileDialog.xml index 7f8808acc79..b0032564cfb 100644 --- a/doc/classes/EditorFileDialog.xml +++ b/doc/classes/EditorFileDialog.xml @@ -67,7 +67,7 @@ The view format in which the [EditorFileDialog] displays resources to the user. - The dialog's open or save mode, which affects the selection behavior. See [enum FileMode] + The dialog's open or save mode, which affects the selection behavior. See [enum FileMode]. The available file type filters. For example, this shows only [code].png[/code] and [code].gd[/code] files: [code]set_filters(PackedStringArray(["*.png ; PNG Images","*.gd ; GDScript Files"]))[/code]. Multiple file types can also be specified in a single filter. [code]"*.png, *.jpg, *.jpeg ; Supported Images"[/code] will show both PNG and JPEG files when selected. diff --git a/doc/classes/EditorResourceConversionPlugin.xml b/doc/classes/EditorResourceConversionPlugin.xml index 6bdfbbe40c5..7d125d731cc 100644 --- a/doc/classes/EditorResourceConversionPlugin.xml +++ b/doc/classes/EditorResourceConversionPlugin.xml @@ -10,13 +10,13 @@ [gdscript] extends EditorResourceConversionPlugin - func _handles(resource : Resource): + func _handles(resource: Resource): return resource is ImageTexture func _converts_to(): return "PortableCompressedTexture2D" - func _convert(itex : Resource): + func _convert(itex: Resource): var ptex = PortableCompressedTexture2D.new() ptex.create_from_image(itex.get_image(), PortableCompressedTexture2D.COMPRESSION_MODE_LOSSLESS) return ptex diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 86b84849f85..b2ccaa3e60b 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -87,7 +87,7 @@ - Gets an array of the settings which have been changed since the last save. Note that internally [code]changed_settings[/code] is cleared after a successful save, so generally the most appropriate place to use this method is when processing [constant NOTIFICATION_EDITOR_SETTINGS_CHANGED] + Gets an array of the settings which have been changed since the last save. Note that internally [code]changed_settings[/code] is cleared after a successful save, so generally the most appropriate place to use this method is when processing [constant NOTIFICATION_EDITOR_SETTINGS_CHANGED]. diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 7ee1f2dfd4e..580aefbcc82 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -277,7 +277,7 @@ [b]Note:[/b] SSR is only supported in the Forward+ rendering method, not Mobile or Compatibility. - The fade-in distance for screen-space reflections. Affects the area from the reflected material to the screen-space reflection). Only positive values are valid (negative values will be clamped to [code]0.0[/code]). + The fade-in distance for screen-space reflections. Affects the area from the reflected material to the screen-space reflection. Only positive values are valid (negative values will be clamped to [code]0.0[/code]). The fade-out distance for screen-space reflections. Affects the area from the screen-space reflection to the "global" reflection. Only positive values are valid (negative values will be clamped to [code]0.0[/code]). diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml index 2f1c68c3224..4b46f008211 100644 --- a/doc/classes/Font.xml +++ b/doc/classes/Font.xml @@ -271,6 +271,17 @@ Returns list of supported [url=https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg]variation coordinates[/url], each coordinate is returned as [code]tag: Vector3i(min_value,max_value,default_value)[/code]. Font variations allow for continuous change of glyph characteristics along some given design axis, such as weight, width or slant. + To print available variation axes of a variable font: + [codeblock] + var fv = FontVariation.new() + fv.set_base_font = load("res://RobotoFlex.ttf") + var variation_list = fv.get_supported_variation_list() + for tag in variation_list: + var name = TextServerManager.get_primary_interface().tag_to_name(tag) + var values = variation_list[tag] + print("variation axis: %s (%d)\n\tmin, max, default: %s" % [name, tag, values]) + [/codeblock] + [b]Note:[/b] To set and get variation coordinates of a [FontVariation], use [member FontVariation.variation_opentype]. diff --git a/doc/classes/FontVariation.xml b/doc/classes/FontVariation.xml index 11286e46a40..abe282db7e4 100644 --- a/doc/classes/FontVariation.xml +++ b/doc/classes/FontVariation.xml @@ -22,6 +22,13 @@ GetNode("Label").AddThemeFontSizeOverride("font_size", 64); [/csharp] [/codeblocks] + To set the coordinate of multiple variation axes: + [codeblock] + var fv = FontVariation.new(); + var ts = TextServerManager.get_primary_interface() + fv.base_font = load("res://BarlowCondensed-Regular.ttf") + fv.variation_opentype = { ts.name_to_tag("wght"): 900, ts.name_to_tag("custom_hght"): 900 } + [/codeblock] @@ -40,7 +47,7 @@ Base font used to create a variation. If not set, default [Theme] font is used. - Array of fallback [Font]s. If not set [member base_font] fallback are ussed. + Array of fallback [Font]s to use as a substitute if a glyph is not found in this [FontVariation]. If not set, [member base_font]'s fallbacks are used instead. A set of OpenType feature tags. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. @@ -66,6 +73,8 @@ Font OpenType variation coordinates. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg]OpenType variation tags[/url]. + [b]Note:[/b] This [Dictionary] uses OpenType tags as keys. Variation axes can be identified both by tags([code]int[/code]) and names ([code]string[/code]). Some axes might be accessible by multiple names. For example, [code]wght[/code] refers to the same axis as [code]weight[/code]. Tags on the other hand are unique. To convert between names and tags, use [method TextServer.name_to_tag] and [method TextServer.tag_to_name]. + [b]Note:[/b] To get available variation axes of a font, use [method Font.get_supported_variation_list]. 2D transform, applied to the font outlines, can be used for slanting, flipping and rotating glyphs. diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml index bf8567751e9..0cc3281236c 100644 --- a/doc/classes/GraphEdit.xml +++ b/doc/classes/GraphEdit.xml @@ -31,8 +31,8 @@ Below is a sample code to help get started: [codeblock] func _is_in_input_hotzone(in_node, in_port, mouse_position): - var port_size : Vector2 = Vector2(get_theme_constant("port_grab_distance_horizontal"), get_theme_constant("port_grab_distance_vertical")) - var port_pos : Vector2 = in_node.get_position() + in_node.get_connection_input_position(in_port) - port_size / 2 + var port_size: Vector2 = Vector2(get_theme_constant("port_grab_distance_horizontal"), get_theme_constant("port_grab_distance_vertical")) + var port_pos: Vector2 = in_node.get_position() + in_node.get_connection_input_position(in_port) - port_size / 2 var rect = Rect2(port_pos, port_size) return rect.has_point(mouse_position) @@ -49,8 +49,8 @@ Below is a sample code to help get started: [codeblock] func _is_in_output_hotzone(in_node, in_port, mouse_position): - var port_size : Vector2 = Vector2(get_theme_constant("port_grab_distance_horizontal"), get_theme_constant("port_grab_distance_vertical")) - var port_pos : Vector2 = in_node.get_position() + in_node.get_connection_output_position(in_port) - port_size / 2 + var port_size: Vector2 = Vector2(get_theme_constant("port_grab_distance_horizontal"), get_theme_constant("port_grab_distance_vertical")) + var port_pos: Vector2 = in_node.get_position() + in_node.get_connection_output_position(in_port) - port_size / 2 var rect = Rect2(port_pos, port_size) return rect.has_point(mouse_position) diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index 8c0e8dc3c30..f97fc78b235 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -342,7 +342,7 @@ Color of the title text. - + The vertical offset of the close button. diff --git a/doc/classes/ImageTexture.xml b/doc/classes/ImageTexture.xml index 03d19474755..7248861cf7b 100644 --- a/doc/classes/ImageTexture.xml +++ b/doc/classes/ImageTexture.xml @@ -20,7 +20,7 @@ [b]Note:[/b] The image can be retrieved from an imported texture using the [method Texture2D.get_image] method, which returns a copy of the image: [codeblock] var texture = load("res://icon.svg") - var image : Image = texture.get_image() + var image: Image = texture.get_image() [/codeblock] An [ImageTexture] is not meant to be operated from within the editor interface directly, and is mostly useful for rendering images on screen dynamically via code. If you need to generate images procedurally from within the editor, consider saving and importing images as custom texture resources implementing a new [EditorImportPlugin]. [b]Note:[/b] The maximum texture size is 16384×16384 pixels due to graphics hardware limitations. diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index bc43f228a77..d904d203352 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -188,6 +188,7 @@ GetTree().CreateTween().BindNode(this); [/csharp] [/codeblocks] + The Tween will start automatically on the next process frame or physics frame (depending on [enum Tween.TweenProcessMode]). diff --git a/doc/classes/ParticleProcessMaterial.xml b/doc/classes/ParticleProcessMaterial.xml index d046d52ed19..50886d96068 100644 --- a/doc/classes/ParticleProcessMaterial.xml +++ b/doc/classes/ParticleProcessMaterial.xml @@ -285,11 +285,11 @@ Enables and disables Turbulence for the particle system. - Minimum turbulence influence on each particle. - The actual amount of turbulence influence on each particle is calculated as a random value between [member turbulence_influence_min] and [member turbulence_influence_max] and multiplied by the amount of turbulence influence from [member turbulence_influence_over_life]. + Maximum turbulence influence on each particle. + The actual amount of turbulence influence on each particle is calculated as a random value between [member turbulence_influence_min] and [member turbulence_influence_max] and multiplied by the amount of turbulence influence from [member turbulence_influence_over_life]. - Maximum turbulence influence on each particle. + Minimum turbulence influence on each particle. The actual amount of turbulence influence on each particle is calculated as a random value between [member turbulence_influence_min] and [member turbulence_influence_max] and multiplied by the amount of turbulence influence from [member turbulence_influence_over_life]. diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index 97cc05d1a19..1439321b88a 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -192,7 +192,7 @@ - Returns the accelerator of the item at the given [param index]. An accelerator is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The return value is an integer which is generally a combination of [enum KeyModifierMask]s and [enum Key]s using boolean OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). If no accelerator is defined for the specified [param index], [method get_item_accelerator] returns [code]0[/code] (corresponding to [constant @GlobalScope.KEY_NONE]). + Returns the accelerator of the item at the given [param index]. An accelerator is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The return value is an integer which is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). If no accelerator is defined for the specified [param index], [method get_item_accelerator] returns [code]0[/code] (corresponding to [constant @GlobalScope.KEY_NONE]). @@ -345,7 +345,7 @@ - Sets the accelerator of the item at the given [param index]. An accelerator is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. [param accel] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using boolean OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). + Sets the accelerator of the item at the given [param index]. An accelerator is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. [param accel] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index b321a1f8217..27bec07cba8 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -753,6 +753,9 @@ What to use to separate node name from number. This is mostly an editor setting. + + When generating file names from scene root node, set the type of casing in this project. This is mostly an editor setting. + The command-line arguments to append to Godot's own command line when running the project. This doesn't affect the editor itself. It is possible to make another executable run Godot by using the [code]%command%[/code] placeholder. The placeholder will be replaced with Godot's own command line. Program-specific arguments should be placed [i]before[/i] the placeholder, whereas Godot-specific arguments should be placed [i]after[/i] the placeholder. diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index 6adb37a3f71..0466d6f2819 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -88,7 +88,7 @@ - Creates and returns a new [Tween]. + Creates and returns a new [Tween]. The Tween will start automatically on the next process frame or physics frame (depending on [enum Tween.TweenProcessMode]). diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml index 7fc01ea3536..4e038c68028 100644 --- a/doc/classes/Theme.xml +++ b/doc/classes/Theme.xml @@ -240,7 +240,7 @@ Returns the theme property of [param data_type] defined by [param name] and [param theme_type], if it exists. - Returns the engine fallback icon value if the property doesn't exist (see [ThemeDB]). Use [method has_theme_item] to check for existence. + Returns the engine fallback value if the property doesn't exist (see [ThemeDB]). Use [method has_theme_item] to check for existence. [b]Note:[/b] This method is analogous to calling the corresponding data type specific method, but can be used for more generalized logic. diff --git a/doc/classes/Thread.xml b/doc/classes/Thread.xml index 846dae0baee..d2304e0046e 100644 --- a/doc/classes/Thread.xml +++ b/doc/classes/Thread.xml @@ -16,13 +16,13 @@ - Returns the current [Thread]'s ID, uniquely identifying it among all threads. If the [Thread] is not running this returns an empty string. + Returns the current [Thread]'s ID, uniquely identifying it among all threads. If the [Thread] has not started running or if [method wait_to_finish] has been called, this returns an empty string. - Returns [code]true[/code] if this [Thread] is currently running. This is useful for determining if [method wait_to_finish] can be called without blocking the calling thread. + Returns [code]true[/code] if this [Thread] is currently running the provided function. This is useful for determining if [method wait_to_finish] can be called without blocking the calling thread. To check if a [Thread] is joinable, use [method is_started]. diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml index f3ed90a015e..7bb9bf85ef9 100644 --- a/doc/classes/Transform2D.xml +++ b/doc/classes/Transform2D.xml @@ -120,7 +120,7 @@ - Returns [code]true[/code] if this transform and [code]transform[/code] are approximately equal, by calling [code]is_equal_approx[/code] on each component. + Returns [code]true[/code] if this transform and [param xform] are approximately equal, by calling [code]is_equal_approx[/code] on each component. @@ -133,7 +133,7 @@ - Returns a copy of the transform rotated such that it's rotation on the X-axis points towards the [param target] position. + Returns a copy of the transform rotated such that the rotated X-axis points towards the [param target] position. Operations take place in global space. diff --git a/doc/classes/Transform3D.xml b/doc/classes/Transform3D.xml index 90c10e36643..e0485c7756d 100644 --- a/doc/classes/Transform3D.xml +++ b/doc/classes/Transform3D.xml @@ -80,7 +80,7 @@ - Returns [code]true[/code] if this transform and [code]transform[/code] are approximately equal, by calling [code]is_equal_approx[/code] on each component. + Returns [code]true[/code] if this transform and [param xform] are approximately equal, by calling [code]is_equal_approx[/code] on each component. diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml index 704430a1c29..37a58722a45 100644 --- a/doc/classes/Tween.xml +++ b/doc/classes/Tween.xml @@ -89,8 +89,8 @@ [/codeblocks] Some [Tweener]s use transitions and eases. The first accepts a [enum TransitionType] constant, and refers to the way the timing of the animation is handled (see [url=https://easings.net/]easings.net[/url] for some examples). The second accepts an [enum EaseType] constant, and controls where the [code]trans_type[/code] is applied to the interpolation (in the beginning, the end, or both). If you don't know which transition and easing to pick, you can try different [enum TransitionType] constants with [constant EASE_IN_OUT], and use the one that looks best. [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url] - [b]Note:[/b] All [Tween]s will automatically start by default. To prevent a [Tween] from autostarting, you can call [method stop] immediately after it is created. - [b]Note:[/b] [Tween]s are processing after all of nodes in the current frame, i.e. after [method Node._process] or [method Node._physics_process] (depending on [enum TweenProcessMode]). + [b]Note:[/b] Tweens are not designed to be re-used and trying to do so results in an undefined behavior. Create a new Tween for each animation and every time you replay an animation from start. Keep in mind that Tweens start immediately, so only create a Tween when you want to start animating. + [b]Note:[/b] Tweens are processing after all of nodes in the current frame, i.e. after [method Node._process] or [method Node._physics_process] (depending on [enum TweenProcessMode]). @@ -129,7 +129,6 @@ Processes the [Tween] by the given [param delta] value, in seconds. This is mostly useful for manual control when the [Tween] is paused. It can also be used to end the [Tween] animation immediately, by setting [param delta] longer than the whole duration of the [Tween] animation. Returns [code]true[/code] if the [Tween] still has [Tweener]s that haven't finished. - [b]Note:[/b] The [Tween] will become invalid in the next processing frame after its animation finishes. Calling [method stop] after performing [method custom_step] instead keeps and resets the [Tween]. @@ -432,7 +431,6 @@ Emitted when the [Tween] has finished all tweening. Never emitted when the [Tween] is set to infinite looping (see [method set_loops]). - [b]Note:[/b] The [Tween] is removed (invalidated) in the next processing frame after this signal is emitted. Calling [method stop] inside the signal callback will prevent the [Tween] from being removed. diff --git a/doc/classes/UDPServer.xml b/doc/classes/UDPServer.xml index 8151ecb625b..60d1986bee8 100644 --- a/doc/classes/UDPServer.xml +++ b/doc/classes/UDPServer.xml @@ -22,7 +22,7 @@ func _process(delta): server.poll() # Important! if server.is_connection_available(): - var peer : PacketPeerUDP = server.take_connection() + var peer: PacketPeerUDP = server.take_connection() var packet = peer.get_packet() print("Accepted peer: %s:%s" % [peer.get_packet_ip(), peer.get_packet_port()]) print("Received data: %s" % [packet.get_string_from_utf8()]) diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index 92050eaa342..b8f731809ae 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -582,7 +582,7 @@ The window's title. If the [Window] is non-embedded, title styles set in [Theme] will have no effect. - If [code]true[/code], the [Window] is transient, i.e. it's considered a child of another [Window]. Transient window is will be destroyed with its transient parent and will return focus to their parent when closed. The transient window is displayed on top of a non-exclusive full-screen parent window. Transient windows can't enter full-screen mode. + If [code]true[/code], the [Window] is transient, i.e. it's considered a child of another [Window]. The transient window will be destroyed with its transient parent and will return focus to their parent when closed. The transient window is displayed on top of a non-exclusive full-screen parent window. Transient windows can't enter full-screen mode. Note that behavior might be different depending on the platform. @@ -764,7 +764,7 @@ The content can be expanded horizontally. Scaling vertically will result in keeping the height ratio and then black bars on top and bottom sides. - The content's aspect will be preserved. If the target size has different aspect from the base one, the content will stay in the to-left corner and add an extra visible area in the stretched space. + The content's aspect will be preserved. If the target size has different aspect from the base one, the content will stay in the top-left corner and add an extra visible area in the stretched space. Automatic layout direction, determined from the parent window layout direction. diff --git a/doc/classes/XRInterface.xml b/doc/classes/XRInterface.xml index cdada35970f..96a6f5decd8 100644 --- a/doc/classes/XRInterface.xml +++ b/doc/classes/XRInterface.xml @@ -116,9 +116,9 @@ [b]Note:[/b] Not all runtimes support all environment blend modes, so it is important to check this at startup. For example: [codeblock] func _ready(): - var xr_interface : XRInterface = XRServer.find_interface("OpenXR") + var xr_interface: XRInterface = XRServer.find_interface("OpenXR") if xr_interface and xr_interface.is_initialized(): - var vp : Viewport = get_viewport() + var vp: Viewport = get_viewport() vp.use_xr = true var acceptable_modes = [ XRInterface.XR_ENV_BLEND_MODE_OPAQUE, XRInterface.XR_ENV_BLEND_MODE_ADDITIVE ] var modes = xr_interface.get_supported_environment_blend_modes() diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index ce669433282..dae722186cc 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -832,6 +832,8 @@ void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) { tex->is_render_target = false; tex->is_proxy = true; tex->proxies.clear(); + tex->canvas_texture = nullptr; + tex->tex_id = 0; proxy_to->proxies.push_back(p_texture); } diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index ed7638414cf..ece5537ff3e 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -257,7 +257,14 @@ void EditorAudioBus::update_bus() { } void EditorAudioBus::_name_changed(const String &p_new_name) { + if (updating_bus) { + return; + } + updating_bus = true; + track_name->release_focus(); + if (p_new_name == AudioServer::get_singleton()->get_bus_name(get_index())) { + updating_bus = false; return; } @@ -280,12 +287,15 @@ void EditorAudioBus::_name_changed(const String &p_new_name) { attempts++; attempt = p_new_name + " " + itos(attempts); } - updating_bus = true; EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); StringName current = AudioServer::get_singleton()->get_bus_name(get_index()); + ur->create_action(TTR("Rename Audio Bus")); + ur->add_do_method(buses, "_set_renaming_buses", true); + ur->add_undo_method(buses, "_set_renaming_buses", true); + ur->add_do_method(AudioServer::get_singleton(), "set_bus_name", get_index(), attempt); ur->add_undo_method(AudioServer::get_singleton(), "set_bus_name", get_index(), current); @@ -301,11 +311,12 @@ void EditorAudioBus::_name_changed(const String &p_new_name) { ur->add_do_method(buses, "_update_sends"); ur->add_undo_method(buses, "_update_sends"); + + ur->add_do_method(buses, "_set_renaming_buses", false); + ur->add_undo_method(buses, "_set_renaming_buses", false); ur->commit_action(); updating_bus = false; - - track_name->release_focus(); } void EditorAudioBus::_volume_changed(float p_normalized) { @@ -995,12 +1006,31 @@ void EditorAudioBusDrop::_bind_methods() { EditorAudioBusDrop::EditorAudioBusDrop() { } +void EditorAudioBuses::_set_renaming_buses(bool p_renaming) { + renaming_buses = p_renaming; +} + void EditorAudioBuses::_update_buses() { - while (bus_hb->get_child_count() > 0) { - memdelete(bus_hb->get_child(0)); + if (renaming_buses) { + // This case will be handled more gracefully, no need to trigger a full rebuild. + // This is possibly a mistake in the AudioServer, which fires bus_layout_changed + // on a rename. This may not be intended, but no way to tell at the moment. + return; } - drop_end = nullptr; + for (int i = bus_hb->get_child_count() - 1; i >= 0; i--) { + EditorAudioBus *audio_bus = Object::cast_to(bus_hb->get_child(i)); + if (audio_bus) { + bus_hb->remove_child(audio_bus); + audio_bus->queue_free(); + } + } + + if (drop_end) { + bus_hb->remove_child(drop_end); + drop_end->queue_free(); + drop_end = nullptr; + } for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { bool is_master = (i == 0); @@ -1033,6 +1063,7 @@ void EditorAudioBuses::_notification(int p_what) { case NOTIFICATION_DRAG_END: { if (drop_end) { + bus_hb->remove_child(drop_end); drop_end->queue_free(); drop_end = nullptr; } @@ -1259,6 +1290,7 @@ void EditorAudioBuses::_file_dialog_callback(const String &p_string) { } void EditorAudioBuses::_bind_methods() { + ClassDB::bind_method("_set_renaming_buses", &EditorAudioBuses::_set_renaming_buses); ClassDB::bind_method("_update_buses", &EditorAudioBuses::_update_buses); ClassDB::bind_method("_update_bus", &EditorAudioBuses::_update_bus); ClassDB::bind_method("_update_sends", &EditorAudioBuses::_update_sends); diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h index 8a7f9b6456f..9ff5afac662 100644 --- a/editor/editor_audio_buses.h +++ b/editor/editor_audio_buses.h @@ -172,6 +172,9 @@ class EditorAudioBuses : public VBoxContainer { Timer *save_timer = nullptr; String edited_path; + bool renaming_buses = false; + void _set_renaming_buses(bool p_renaming); + void _add_bus(); void _update_buses(); void _update_bus(int p_index); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 6fcf0928346..8040ba5f1c4 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -151,6 +151,51 @@ EditorNode *EditorNode::singleton = nullptr; // The metadata key used to store and retrieve the version text to copy to the clipboard. static const String META_TEXT_TO_COPY = "text_to_copy"; +class AcceptDialogAutoReparent : public AcceptDialog { + GDCLASS(AcceptDialogAutoReparent, AcceptDialog); + +protected: + void _notification(int p_what) { + if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { + if (!is_visible()) { + Node *p = get_parent(); + if (p) { + p->remove_child(this); + } + } + } + } + +public: + void attach_and_popup_centered() { + EditorNode *ed = EditorNode::get_singleton(); + if (ed && !is_inside_tree()) { + Window *w = ed->get_window(); + while (w && w->get_exclusive_child()) { + w = w->get_exclusive_child(); + } + if (w && w != this) { + w->add_child(this); + popup_centered(); + } + } + } + + void attach_and_popup_centered_ratio(float p_ratio = 0.8) { + EditorNode *ed = EditorNode::get_singleton(); + if (ed && !is_inside_tree()) { + Window *w = ed->get_window(); + while (w && w->get_exclusive_child()) { + w = w->get_exclusive_child(); + } + if (w && w != this) { + w->add_child(this); + popup_centered_ratio(p_ratio); + } + } + } +}; + void EditorNode::disambiguate_filenames(const Vector p_full_paths, Vector &r_filenames) { ERR_FAIL_COND_MSG(p_full_paths.size() != r_filenames.size(), vformat("disambiguate_filenames requires two string vectors of same length (%d != %d).", p_full_paths.size(), r_filenames.size())); @@ -615,6 +660,21 @@ void EditorNode::_notification(int p_what) { if (progress_dialog) { progress_dialog->queue_free(); } + if (load_error_dialog) { + load_error_dialog->queue_free(); + } + if (execute_output_dialog) { + execute_output_dialog->queue_free(); + } + if (warning) { + warning->queue_free(); + } + if (accept) { + accept->queue_free(); + } + if (save_accept) { + save_accept->queue_free(); + } editor_data.save_editor_external_data(); FileAccess::set_file_close_fail_notify_callback(nullptr); log->deinit(); // Do not get messages anymore. @@ -1233,6 +1293,12 @@ void EditorNode::edit_resource(const Ref &p_resource) { void EditorNode::save_resource_in_path(const Ref &p_resource, const String &p_path) { editor_data.apply_changes_in_editors(); + + if (saving_resources_in_path.has(p_resource)) { + return; + } + saving_resources_in_path.insert(p_resource); + int flg = 0; if (EDITOR_GET("filesystem/on_save/compress_binary_resources")) { flg |= ResourceSaver::FLAG_COMPRESS; @@ -1247,10 +1313,16 @@ void EditorNode::save_resource_in_path(const Ref &p_resource, const St } else { show_accept(TTR("Error saving resource!"), TTR("OK")); } + + saving_resources_in_path.erase(p_resource); return; } ((Resource *)p_resource.ptr())->set_path(path); + saving_resources_in_path.erase(p_resource); + + _resource_saved(p_resource, path); + emit_signal(SNAME("resource_saved"), p_resource); editor_data.notify_resource_saved(p_resource); } @@ -4266,9 +4338,11 @@ void EditorNode::add_io_error(const String &p_error) { void EditorNode::_load_error_notify(void *p_ud, const String &p_text) { EditorNode *en = static_cast(p_ud); - en->load_errors->add_image(en->gui_base->get_theme_icon(SNAME("Error"), SNAME("EditorIcons"))); - en->load_errors->add_text(p_text + "\n"); - en->load_error_dialog->popup_centered_ratio(0.5); + if (en && en->load_error_dialog) { + en->load_errors->add_image(en->gui_base->get_theme_icon(SNAME("Error"), SNAME("EditorIcons"))); + en->load_errors->add_text(p_text + "\n"); + en->load_error_dialog->attach_and_popup_centered_ratio(0.5); + } } bool EditorNode::_find_scene_in_use(Node *p_node, const String &p_path) const { @@ -4639,23 +4713,27 @@ Error EditorNode::export_preset(const String &p_preset, const String &p_path, bo void EditorNode::show_accept(const String &p_text, const String &p_title) { current_menu_option = -1; - accept->set_ok_button_text(p_title); - accept->set_text(p_text); - accept->popup_centered(); + if (accept) { + accept->set_ok_button_text(p_title); + accept->set_text(p_text); + accept->attach_and_popup_centered(); + } } void EditorNode::show_save_accept(const String &p_text, const String &p_title) { current_menu_option = -1; - save_accept->set_ok_button_text(p_title); - save_accept->set_text(p_text); - save_accept->popup_centered(); + if (save_accept) { + save_accept->set_ok_button_text(p_title); + save_accept->set_text(p_text); + save_accept->attach_and_popup_centered(); + } } void EditorNode::show_warning(const String &p_text, const String &p_title) { - if (warning->is_inside_tree()) { + if (warning) { warning->set_text(p_text); warning->set_title(p_title); - warning->popup_centered(); + warning->attach_and_popup_centered(); } else { WARN_PRINT(p_title + " " + p_text); } @@ -4795,6 +4873,7 @@ void EditorNode::_dock_select_input(const Ref &p_input) { dock_slot[nrect]->add_child(dock); dock_popup_selected_idx = nrect; dock_slot[nrect]->set_current_tab(dock_slot[nrect]->get_tab_count() - 1); + dock_slot[nrect]->set_tab_title(dock_slot[nrect]->get_tab_count() - 1, TTRGET(dock->get_name())); dock_slot[nrect]->show(); dock_select->queue_redraw(); @@ -5152,6 +5231,7 @@ void EditorNode::_load_docks_from_config(Ref p_layout, const String } dock_slot[i]->add_child(node); dock_slot[i]->move_child(node, 0); + dock_slot[i]->set_tab_title(0, TTRGET(node->get_name())); dock_slot[i]->show(); } } @@ -6441,6 +6521,11 @@ void EditorNode::_renderer_selected(int p_which) { } void EditorNode::_resource_saved(Ref p_resource, const String &p_path) { + if (singleton->saving_resources_in_path.has(p_resource)) { + // This is going to be handled by save_resource_in_path when the time is right. + return; + } + if (EditorFileSystem::get_singleton()) { EditorFileSystem::get_singleton()->update_file(p_path); } @@ -6492,7 +6577,6 @@ void EditorNode::_feature_profile_changed() { } void EditorNode::_bind_methods() { - GLOBAL_DEF(PropertyInfo(Variant::INT, "editor/naming/scene_name_casing", PROPERTY_HINT_ENUM, "Auto,PascalCase,snake_case"), SCENE_NAME_CASING_SNAKE_CASE); ClassDB::bind_method("edit_current", &EditorNode::edit_current); ClassDB::bind_method("edit_node", &EditorNode::edit_node); @@ -6549,11 +6633,13 @@ static void _execute_thread(void *p_ud) { } int EditorNode::execute_and_show_output(const String &p_title, const String &p_path, const List &p_arguments, bool p_close_on_ok, bool p_close_on_errors) { - execute_output_dialog->set_title(p_title); - execute_output_dialog->get_ok_button()->set_disabled(true); - execute_outputs->clear(); - execute_outputs->set_scroll_follow(true); - execute_output_dialog->popup_centered_ratio(); + if (execute_output_dialog) { + execute_output_dialog->set_title(p_title); + execute_output_dialog->get_ok_button()->set_disabled(true); + execute_outputs->clear(); + execute_outputs->set_scroll_follow(true); + execute_output_dialog->attach_and_popup_centered_ratio(); + } ExecuteThreadArgs eta; eta.path = p_path; @@ -6571,6 +6657,7 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p String to_add = eta.output.substr(prev_len, eta.output.length()); prev_len = eta.output.length(); execute_outputs->add_text(to_add); + DisplayServer::get_singleton()->process_events(); // Get rid of pending events. Main::iteration(); } } @@ -6580,14 +6667,16 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p eta.execute_output_thread.wait_to_finish(); execute_outputs->add_text("\nExit Code: " + itos(eta.exitcode)); - if (p_close_on_errors && eta.exitcode != 0) { - execute_output_dialog->hide(); - } - if (p_close_on_ok && eta.exitcode == 0) { - execute_output_dialog->hide(); - } + if (execute_output_dialog) { + if (p_close_on_errors && eta.exitcode != 0) { + execute_output_dialog->hide(); + } + if (p_close_on_ok && eta.exitcode == 0) { + execute_output_dialog->hide(); + } - execute_output_dialog->get_ok_button()->set_disabled(false); + execute_output_dialog->get_ok_button()->set_disabled(false); + } return eta.exitcode; } @@ -7158,12 +7247,10 @@ EditorNode::EditorNode() { prev_scene->set_position(Point2(3, 24)); prev_scene->hide(); - accept = memnew(AcceptDialog); - gui_base->add_child(accept); + accept = memnew(AcceptDialogAutoReparent); accept->connect("confirmed", callable_mp(this, &EditorNode::_menu_confirm_current)); - save_accept = memnew(AcceptDialog); - gui_base->add_child(save_accept); + save_accept = memnew(AcceptDialogAutoReparent); save_accept->connect("confirmed", callable_mp(this, &EditorNode::_menu_option).bind((int)MenuOptions::FILE_SAVE_AS_SCENE)); project_export = memnew(ProjectExportDialog); @@ -7208,9 +7295,8 @@ EditorNode::EditorNode() { gui_base->add_child(fbx_importer_manager); #endif - warning = memnew(AcceptDialog); + warning = memnew(AcceptDialogAutoReparent); warning->add_button(TTR("Copy Text"), true, "copy"); - gui_base->add_child(warning); warning->connect("custom_action", callable_mp(this, &EditorNode::_copy_warning)); ED_SHORTCUT("editor/next_tab", TTR("Next Scene Tab"), KeyModifierMask::CMD_OR_CTRL + Key::TAB); @@ -7978,17 +8064,15 @@ EditorNode::EditorNode() { set_process_shortcut_input(true); load_errors = memnew(RichTextLabel); - load_error_dialog = memnew(AcceptDialog); + load_error_dialog = memnew(AcceptDialogAutoReparent); load_error_dialog->add_child(load_errors); load_error_dialog->set_title(TTR("Load Errors")); - gui_base->add_child(load_error_dialog); execute_outputs = memnew(RichTextLabel); execute_outputs->set_selection_enabled(true); - execute_output_dialog = memnew(AcceptDialog); + execute_output_dialog = memnew(AcceptDialogAutoReparent); execute_output_dialog->add_child(execute_outputs); execute_output_dialog->set_title(""); - gui_base->add_child(execute_output_dialog); EditorFileSystem::get_singleton()->connect("sources_changed", callable_mp(this, &EditorNode::_sources_changed)); EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &EditorNode::_fs_changed)); diff --git a/editor/editor_node.h b/editor/editor_node.h index 8ad5969249d..66a3bf5be2d 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -45,6 +45,7 @@ typedef void (*EditorPluginInitializeCallback)(); typedef bool (*EditorBuildCallback)(); class AcceptDialog; +class AcceptDialogAutoReparent; class AudioStreamPreviewGenerator; class BackgroundProgress; class CenterContainer; @@ -370,10 +371,10 @@ private: PluginConfigDialog *plugin_config_dialog = nullptr; RichTextLabel *load_errors = nullptr; - AcceptDialog *load_error_dialog = nullptr; + AcceptDialogAutoReparent *load_error_dialog = nullptr; RichTextLabel *execute_outputs = nullptr; - AcceptDialog *execute_output_dialog = nullptr; + AcceptDialogAutoReparent *execute_output_dialog = nullptr; Ref theme; @@ -388,10 +389,10 @@ private: ConfirmationDialog *import_confirmation = nullptr; ConfirmationDialog *pick_main_scene = nullptr; Button *select_current_scene_button = nullptr; - AcceptDialog *accept = nullptr; - AcceptDialog *save_accept = nullptr; + AcceptDialogAutoReparent *accept = nullptr; + AcceptDialogAutoReparent *save_accept = nullptr; EditorAbout *about = nullptr; - AcceptDialog *warning = nullptr; + AcceptDialogAutoReparent *warning = nullptr; int overridden_default_layout = -1; Ref default_layout; @@ -485,6 +486,7 @@ private: Object *current = nullptr; Ref saving_resource; + HashSet> saving_resources_in_path; uint64_t update_spinner_step_msec = 0; uint64_t update_spinner_step_frame = 0; diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 7b01ae69bf5..fb2110dea37 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -137,6 +137,7 @@ Vector> EditorInterface::make_mesh_previews(const Vectorinstance_set_transform(light_instance2, xform * Transform3D().looking_at(Vector3(+1, -1, -2), Vector3(0, 1, 0))); ep.step(TTR("Thumbnail..."), i); + DisplayServer::get_singleton()->process_events(); Main::iteration(); Main::iteration(); Ref img = RS::get_singleton()->texture_2d_get(viewport_texture); diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 86ffbccefd0..a83db21f20f 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -399,8 +399,12 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { file_system_dock->navigate_to_path(edited_resource->get_path()); // Ensure that the FileSystem dock is visible. - TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); - tab_container->set_current_tab(tab_container->get_tab_idx_from_control(file_system_dock)); + if (file_system_dock->get_window() == get_tree()->get_root()) { + TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); + tab_container->set_current_tab(tab_container->get_tab_idx_from_control(file_system_dock)); + } else { + file_system_dock->get_window()->grab_focus(); + } } break; default: { diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 2ab15c1c2cb..3e6b0ee07f3 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -231,11 +231,11 @@ static Ref make_line_stylebox(Color p_color, int p_thickness = 1, return style; } -#ifdef MODULE_SVG_ENABLED // See also `generate_icon()` in `scene/resources/default_theme.cpp`. static Ref editor_generate_icon(int p_index, float p_scale, float p_saturation, const HashMap &p_convert_colors = HashMap()) { Ref img = memnew(Image); +#ifdef MODULE_SVG_ENABLED // Upsample icon generation only if the editor scale isn't an integer multiplier. // Generating upsampled icons is slower, and the benefit is hardly visible // with integer editor scales. @@ -246,13 +246,16 @@ static Ref editor_generate_icon(int p_index, float p_scale, float if (p_saturation != 1.0) { img->adjust_bcs(1.0, 1.0, p_saturation); } +#else + // If the SVG module is disabled, we can't really display the UI well, but at least we won't crash. + // 16 pixels is used as it's the most common base size for Godot icons. + img = Image::create_empty(16 * p_scale, 16 * p_scale, false, Image::FORMAT_RGBA8); +#endif return ImageTexture::create_from_image(img); } -#endif void editor_register_and_generate_icons(Ref p_theme, bool p_dark_theme, float p_icon_saturation, int p_thumb_size, bool p_only_thumbs = false) { -#ifdef MODULE_SVG_ENABLED // Before we register the icons, we adjust their colors and saturation. // Most icons follow the standard rules for color conversion to follow the editor // theme's polarity (dark/light). We also adjust the saturation for most icons, @@ -379,9 +382,6 @@ void editor_register_and_generate_icons(Ref p_theme, bool p_dark_theme, f p_theme->set_icon(editor_icons_names[index], SNAME("EditorIcons"), icon); } } -#else - WARN_PRINT("SVG support disabled, editor icons won't be rendered."); -#endif } Ref create_editor_theme(const Ref p_theme) { @@ -618,6 +618,10 @@ Ref create_editor_theme(const Ref p_theme) { regenerate_thumb_icons = !Math::is_equal_approx(prev_thumb_size, thumb_size); } +#ifndef MODULE_SVG_ENABLED + WARN_PRINT("SVG support disabled, editor icons won't be rendered."); +#endif + if (keep_old_icons) { for (int i = 0; i < editor_icons_count; i++) { theme->set_icon(editor_icons_names[i], SNAME("EditorIcons"), p_theme->get_icon(editor_icons_names[i], SNAME("EditorIcons"))); diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp index 73b645f351d..10c3e963af1 100644 --- a/editor/editor_toaster.cpp +++ b/editor/editor_toaster.cpp @@ -90,10 +90,10 @@ void EditorToaster::_notification(int p_what) { } // Hide element if it is not visible anymore. - if (modulate_fade.a <= 0 && element.key->is_visible()) { + if (modulate_fade.a <= 0.0 && element.key->is_visible()) { element.key->hide(); needs_update = true; - } else if (modulate_fade.a >= 0 && !element.key->is_visible()) { + } else if (modulate_fade.a > 0.0 && !element.key->is_visible()) { element.key->show(); needs_update = true; } diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp index e9ea0012bee..a7ac95bd5b1 100644 --- a/editor/export/project_export.cpp +++ b/editor/export/project_export.cpp @@ -943,8 +943,8 @@ void ProjectExportDialog::_export_pck_zip_selected(const String &p_path) { } void ProjectExportDialog::_open_export_template_manager() { - EditorNode::get_singleton()->open_export_template_manager(); hide(); + EditorNode::get_singleton()->open_export_template_manager(); } void ProjectExportDialog::_validate_export_path(const String &p_path) { diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index fcefbb7d065..235e34d9b5c 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -648,7 +648,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { if (!tile_data_editors.has("texture_origin")) { TileDataTextureOriginEditor *tile_data_texture_origin_editor = memnew(TileDataTextureOriginEditor); tile_data_texture_origin_editor->hide(); - tile_data_texture_origin_editor->setup_property_editor(Variant::VECTOR2, "texture_origin"); + tile_data_texture_origin_editor->setup_property_editor(Variant::VECTOR2I, "texture_origin"); tile_data_texture_origin_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::queue_redraw)); tile_data_texture_origin_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::queue_redraw)); tile_data_editors["texture_origin"] = tile_data_texture_origin_editor; diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp index 78522dfa735..1682d07e13a 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.cpp +++ b/editor/plugins/tiles/tiles_editor_plugin.cpp @@ -145,7 +145,10 @@ void TilesEditorPlugin::_tile_map_changed() { void TilesEditorPlugin::_update_editors() { // If tile_map is not edited, we change the edited only if we are not editing a tile_set. - tileset_editor->edit(tile_set); + if (tile_set.is_valid()) { + tileset_editor->edit(tile_set); + } + TileMap *tile_map = Object::cast_to(ObjectDB::get_instance(tile_map_id)); if (tile_map) { tilemap_editor->edit(tile_map); @@ -158,6 +161,7 @@ void TilesEditorPlugin::_update_editors() { // Make sure the tile set editor is visible if we have one assigned. tileset_editor_button->set_visible(is_visible && tile_set.is_valid()); + tilemap_editor_button->set_visible(is_visible && tile_map); // Update visibility of bottom panel buttons. if (tileset_editor_button->is_pressed() && !tile_set.is_valid()) { diff --git a/editor/progress_dialog.cpp b/editor/progress_dialog.cpp index 9695a7042da..4d76fdc9976 100644 --- a/editor/progress_dialog.cpp +++ b/editor/progress_dialog.cpp @@ -221,9 +221,7 @@ bool ProgressDialog::task_step(const String &p_task, const String &p_state, int t.state->set_text(p_state); last_progress_tick = OS::get_singleton()->get_ticks_usec(); - if (cancel_hb->is_visible()) { - DisplayServer::get_singleton()->process_events(); - } + DisplayServer::get_singleton()->process_events(); #ifndef ANDROID_ENABLED Main::iteration(); // this will not work on a lot of platforms, so it's only meant for the editor diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index 3c6f5c09554..6aa403de176 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -70,9 +70,9 @@ public: RegEx reg_json_print = RegEx("\\bJSON\\b\\.print\\("); RegEx reg_export = RegEx("export\\(([a-zA-Z0-9_]+)\\)[ ]+var[ ]+([a-zA-Z0-9_]+)"); RegEx reg_export_advanced = RegEx("export\\(([^)^\n]+)\\)[ ]+var[ ]+([a-zA-Z0-9_]+)([^\n]+)"); - RegEx reg_setget_setget = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+([a-zA-Z0-9_]+)[ \t]*,[ \t]*([a-zA-Z0-9_]+)"); - RegEx reg_setget_set = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+([a-zA-Z0-9_]+)[ \t]*[,]*[^a-z^A-Z^0-9^_]*$"); - RegEx reg_setget_get = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+,[ \t]*([a-zA-Z0-9_]+)[ \t]*$"); + RegEx reg_setget_setget = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+?)[ \t]*setget[ \t]+([a-zA-Z0-9_]+)[ \t]*,[ \t]*([a-zA-Z0-9_]+)"); + RegEx reg_setget_set = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+?)[ \t]*setget[ \t]+([a-zA-Z0-9_]+)[ \t]*[,]*[^\n]*$"); + RegEx reg_setget_get = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+?)[ \t]*setget[ \t]+,[ \t]*([a-zA-Z0-9_]+)[ \t]*$"); RegEx reg_join = RegEx("([\\(\\)a-zA-Z0-9_]+)\\.join\\(([^\n^\\)]+)\\)"); RegEx reg_image_lock = RegEx("([a-zA-Z0-9_\\.]+)\\.lock\\(\\)"); RegEx reg_image_unlock = RegEx("([a-zA-Z0-9_\\.]+)\\.unlock\\(\\)"); @@ -828,10 +828,10 @@ bool ProjectConverter3To4::test_conversion(RegExContainer ®_container) { valid = valid && test_conversion_with_regex("\n\nmaster func", "\n\nThe master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using get_multiplayer().get_remote_sender_id()\n@rpc func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container); valid = valid && test_conversion_with_regex("\n\nmastersync func", "\n\nThe master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using get_multiplayer().get_remote_sender_id()\n@rpc(\"call_local\") func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container); - valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function , get_function", "var size : Vector2 = Vector2() : get = get_function, set = set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function , ", "var size : Vector2 = Vector2() : set = set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function", "var size : Vector2 = Vector2() : set = set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget , get_function", "var size : Vector2 = Vector2() : get = get_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid && test_conversion_gdscript_builtin("var size: Vector2 = Vector2() setget set_function, get_function", "var size: Vector2 = Vector2(): get = get_function, set = set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid && test_conversion_gdscript_builtin("var size: Vector2 = Vector2() setget set_function, ", "var size: Vector2 = Vector2(): set = set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid && test_conversion_gdscript_builtin("var size: Vector2 = Vector2() setget set_function", "var size: Vector2 = Vector2(): set = set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid && test_conversion_gdscript_builtin("var size: Vector2 = Vector2() setget , get_function", "var size: Vector2 = Vector2(): get = get_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid && test_conversion_gdscript_builtin("get_node(@", "get_node(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); diff --git a/editor/register_editor_types.cpp b/editor/register_editor_types.cpp index 061baaff7ee..d9138128cde 100644 --- a/editor/register_editor_types.cpp +++ b/editor/register_editor_types.cpp @@ -212,6 +212,15 @@ void register_editor_types() { EditorPlugins::add_by_type(); EditorPlugins::add_by_type(); EditorPlugins::add_by_type(); + + // For correct doc generation. + GLOBAL_DEF("editor/run/main_run_args", ""); + + GLOBAL_DEF(PropertyInfo(Variant::STRING, "editor/script/templates_search_path", PROPERTY_HINT_DIR), "res://script_templates"); + + GLOBAL_DEF("editor/naming/default_signal_callback_name", "_on_{node_name}_{signal_name}"); + GLOBAL_DEF("editor/naming/default_signal_callback_to_self_name", "_on_{signal_name}"); + GLOBAL_DEF(PropertyInfo(Variant::INT, "editor/naming/scene_name_casing", PROPERTY_HINT_ENUM, "Auto,PascalCase,snake_case"), EditorNode::SCENE_NAME_CASING_SNAKE_CASE); } void unregister_editor_types() { diff --git a/main/main.cpp b/main/main.cpp index b15588e7007..f4d2dbef52b 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -108,6 +108,10 @@ #include "modules/modules_enabled.gen.h" // For mono. +#if defined(MODULE_MONO_ENABLED) && defined(TOOLS_ENABLED) +#include "modules/mono/editor/bindings_generator.h" +#endif + /* Static members */ // Singletons @@ -312,7 +316,6 @@ void finalize_navigation_server() { void initialize_theme_db() { theme_db = memnew(ThemeDB); - theme_db->initialize_theme(); } void finalize_theme_db() { @@ -532,6 +535,7 @@ Error Main::test_setup() { // Theme needs modules to be initialized so that sub-resources can be loaded. initialize_theme_db(); + theme_db->initialize_theme(); register_scene_singletons(); ERR_FAIL_COND_V(TextServerManager::get_singleton()->get_interface_count() == 0, ERR_CANT_CREATE); @@ -2314,6 +2318,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { register_platform_apis(); // Theme needs modules to be initialized so that sub-resources can be loaded. + // Default theme is initialized later, after ScriptServer is ready. initialize_theme_db(); register_scene_singletons(); @@ -2341,8 +2346,18 @@ Error Main::setup2(Thread::ID p_main_tid_override) { // This loads global classes, so it must happen before custom loaders and savers are registered ScriptServer::init_languages(); + theme_db->initialize_theme(); audio_server->load_default_bus_layout(); +#if defined(MODULE_MONO_ENABLED) && defined(TOOLS_ENABLED) + // Hacky to have it here, but we don't have good facility yet to let modules + // register command line options to call at the right time. This needs to happen + // after init'ing the ScriptServer, but also after init'ing the ThemeDB, + // for the C# docs generation in the bindings. + List cmdline_args = OS::get_singleton()->get_cmdline_args(); + BindingsGenerator::handle_cmdline_args(cmdline_args); +#endif + if (use_debug_profiler && EngineDebugger::is_active()) { // Start the "scripts" profiler, used in local debugging. // We could add more, and make the CLI arg require a comma-separated list of profilers. diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index 045505b720f..effc0aab96d 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -285,7 +285,7 @@ @export var string = "" @export var int_number = 5 @export var float_number: float = 5 - @export var image : Image + @export var image: Image [/codeblock] @@ -309,7 +309,7 @@ Export a [Color] property without allowing its transparency ([member Color.a]) to be edited. See also [constant PROPERTY_HINT_COLOR_NO_ALPHA]. [codeblock] - @export_color_no_alpha var dye_color : Color + @export_color_no_alpha var dye_color: Color [/codeblock] diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index b6caefbdb58..1a1d021dbcd 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1010,12 +1010,14 @@ void GDScript::_bind_methods() { } void GDScript::set_path(const String &p_path, bool p_take_over) { - String old_path = path; if (is_root_script()) { Script::set_path(p_path, p_take_over); } - this->path = p_path; + + String old_path = path; + path = p_path; GDScriptCache::move_script(old_path, p_path); + for (KeyValue> &kv : subclasses) { kv.value->set_path(p_path, p_take_over); } diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_function_parameter_wrong_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/enum_function_parameter_wrong_type.gd index 62ac1c3108c..900155569cd 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/enum_function_parameter_wrong_type.gd +++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_function_parameter_wrong_type.gd @@ -1,7 +1,7 @@ enum MyEnum { ENUM_VALUE_1, ENUM_VALUE_2 } enum MyOtherEnum { OTHER_ENUM_VALUE_1, OTHER_ENUM_VALUE_2 } -func enum_func(e : MyEnum) -> void: +func enum_func(e: MyEnum) -> void: print(e) func test(): diff --git a/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.gd b/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.gd index dd2708b21d5..63c080e5834 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.gd +++ b/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.gd @@ -4,4 +4,4 @@ func test(): x.free() var ok = x - var bad : Node = x + var bad: Node = x diff --git a/modules/gdscript/tests/scripts/analyzer/errors/preload_enum_error.gd b/modules/gdscript/tests/scripts/analyzer/errors/preload_enum_error.gd index 4e75ded96aa..c84a4ad8afa 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/preload_enum_error.gd +++ b/modules/gdscript/tests/scripts/analyzer/errors/preload_enum_error.gd @@ -2,5 +2,5 @@ enum LocalNamed { VALUE_A, VALUE_B, VALUE_C = 42 } func test(): const P = preload("../features/enum_from_outer.gd") - var x : LocalNamed + var x: LocalNamed x = P.Named.VALUE_A diff --git a/modules/gdscript/tests/scripts/analyzer/errors/property_function_get_type_error.gd b/modules/gdscript/tests/scripts/analyzer/errors/property_function_get_type_error.gd index f1be6aaa0c1..35f506aabd1 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/property_function_get_type_error.gd +++ b/modules/gdscript/tests/scripts/analyzer/errors/property_function_get_type_error.gd @@ -1,7 +1,7 @@ -var _prop : int +var _prop: int # Getter function has wrong return type. -var prop : String: +var prop: String: get = get_prop func get_prop(): diff --git a/modules/gdscript/tests/scripts/analyzer/errors/property_function_set_type_error.gd b/modules/gdscript/tests/scripts/analyzer/errors/property_function_set_type_error.gd index dd190157a1b..eedeea915d5 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/property_function_set_type_error.gd +++ b/modules/gdscript/tests/scripts/analyzer/errors/property_function_set_type_error.gd @@ -1,10 +1,10 @@ -var _prop : int +var _prop: int # Setter function has wrong argument type. -var prop : String: +var prop: String: set = set_prop -func set_prop(value : int): +func set_prop(value: int): _prop = value func test(): diff --git a/modules/gdscript/tests/scripts/analyzer/errors/property_inline_get_type_error.gd b/modules/gdscript/tests/scripts/analyzer/errors/property_inline_get_type_error.gd index 7f2b29222ad..90b00fbe13d 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/property_inline_get_type_error.gd +++ b/modules/gdscript/tests/scripts/analyzer/errors/property_inline_get_type_error.gd @@ -1,7 +1,7 @@ -var _prop : int +var _prop: int # Inline getter returns int instead of String. -var prop : String: +var prop: String: get: return _prop diff --git a/modules/gdscript/tests/scripts/analyzer/errors/property_inline_set_type_error.gd b/modules/gdscript/tests/scripts/analyzer/errors/property_inline_set_type_error.gd index 0ce239dbbd3..5747b85fc76 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/property_inline_set_type_error.gd +++ b/modules/gdscript/tests/scripts/analyzer/errors/property_inline_set_type_error.gd @@ -1,7 +1,7 @@ -var _prop : int +var _prop: int # Inline setter assigns String to int. -var prop : String: +var prop: String: set(value): _prop = value diff --git a/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.gd b/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.gd index 758fbaccc95..b0cfdea75da 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.gd +++ b/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.gd @@ -7,4 +7,4 @@ func test(): x.free() var ok = x - var bad : A = x + var bad: A = x diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_duplicate_into_dict.gd b/modules/gdscript/tests/scripts/analyzer/features/enum_duplicate_into_dict.gd index 3076e7069f6..8e6bb22a122 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/enum_duplicate_into_dict.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/enum_duplicate_into_dict.gd @@ -1,7 +1,7 @@ enum Enum {V1, V2} func test(): - var enumAsDict : Dictionary = Enum.duplicate() + var enumAsDict: Dictionary = Enum.duplicate() var enumAsVariant = Enum.duplicate() print(Enum.has("V1")) print(enumAsDict.has("V1")) diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_function_typecheck.gd b/modules/gdscript/tests/scripts/analyzer/features/enum_function_typecheck.gd index 8a4e89d0d6a..3a1863a1f40 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/enum_function_typecheck.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/enum_function_typecheck.gd @@ -5,19 +5,19 @@ enum MyEnum { V0, V1, V2 } class InnerClass: enum MyEnum { V0, V2, V1 } - func inner_inner_no_class(e : MyEnum) -> MyEnum: + func inner_inner_no_class(e: MyEnum) -> MyEnum: print(e) return e - func inner_inner_class(e : InnerClass.MyEnum) -> InnerClass.MyEnum: + func inner_inner_class(e: InnerClass.MyEnum) -> InnerClass.MyEnum: print(e) return e - func inner_inner_class_class(e : EnumFunctionTypecheckOuterClass.InnerClass.MyEnum) -> EnumFunctionTypecheckOuterClass.InnerClass.MyEnum: + func inner_inner_class_class(e: EnumFunctionTypecheckOuterClass.InnerClass.MyEnum) -> EnumFunctionTypecheckOuterClass.InnerClass.MyEnum: print(e) return e - func inner_outer(e : EnumFunctionTypecheckOuterClass.MyEnum) -> EnumFunctionTypecheckOuterClass.MyEnum: + func inner_outer(e: EnumFunctionTypecheckOuterClass.MyEnum) -> EnumFunctionTypecheckOuterClass.MyEnum: print(e) return e @@ -59,19 +59,19 @@ class InnerClass: print() -func outer_outer_no_class(e : MyEnum) -> MyEnum: +func outer_outer_no_class(e: MyEnum) -> MyEnum: print(e) return e -func outer_outer_class(e : EnumFunctionTypecheckOuterClass.MyEnum) -> EnumFunctionTypecheckOuterClass.MyEnum: +func outer_outer_class(e: EnumFunctionTypecheckOuterClass.MyEnum) -> EnumFunctionTypecheckOuterClass.MyEnum: print(e) return e -func outer_inner_class(e : InnerClass.MyEnum) -> InnerClass.MyEnum: +func outer_inner_class(e: InnerClass.MyEnum) -> InnerClass.MyEnum: print(e) return e -func outer_inner_class_class(e : EnumFunctionTypecheckOuterClass.InnerClass.MyEnum) -> EnumFunctionTypecheckOuterClass.InnerClass.MyEnum: +func outer_inner_class_class(e: EnumFunctionTypecheckOuterClass.InnerClass.MyEnum) -> EnumFunctionTypecheckOuterClass.InnerClass.MyEnum: print(e) return e diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_native_access_types.gd b/modules/gdscript/tests/scripts/analyzer/features/enum_native_access_types.gd index 6a0a1e1969e..0e4fd59267f 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/enum_native_access_types.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/enum_native_access_types.gd @@ -1,9 +1,9 @@ -func print_enum(e : TileSet.TileShape) -> TileSet.TileShape: +func print_enum(e: TileSet.TileShape) -> TileSet.TileShape: print(e) return e func test(): - var v : TileSet.TileShape + var v: TileSet.TileShape v = TileSet.TILE_SHAPE_SQUARE v = print_enum(v) v = print_enum(TileSet.TILE_SHAPE_SQUARE) diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_typecheck_inner_class.gd b/modules/gdscript/tests/scripts/analyzer/features/enum_typecheck_inner_class.gd index b05ae820489..1c4b19d8e0e 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/enum_typecheck_inner_class.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/enum_typecheck_inner_class.gd @@ -7,9 +7,9 @@ class InnerClass: static func test_inner_from_inner(): print("Inner - Inner") - var e1 : MyEnum - var e2 : InnerClass.MyEnum - var e3 : EnumTypecheckOuterClass.InnerClass.MyEnum + var e1: MyEnum + var e2: InnerClass.MyEnum + var e3: EnumTypecheckOuterClass.InnerClass.MyEnum print("Self ", e1, e2, e3) e1 = MyEnum.V1 @@ -36,7 +36,7 @@ class InnerClass: static func test_outer_from_inner(): print("Inner - Outer") - var e : EnumTypecheckOuterClass.MyEnum + var e: EnumTypecheckOuterClass.MyEnum e = EnumTypecheckOuterClass.MyEnum.V1 print("Outer.MyEnum ", e) @@ -45,8 +45,8 @@ class InnerClass: func test_outer_from_outer(): print("Outer - Outer") - var e1 : MyEnum - var e2 : EnumTypecheckOuterClass.MyEnum + var e1: MyEnum + var e2: EnumTypecheckOuterClass.MyEnum print("Self ", e1, e2) e1 = MyEnum.V1 @@ -63,8 +63,8 @@ func test_outer_from_outer(): func test_inner_from_outer(): print("Outer - Inner") - var e1 : InnerClass.MyEnum - var e2 : EnumTypecheckOuterClass.InnerClass.MyEnum + var e1: InnerClass.MyEnum + var e2: EnumTypecheckOuterClass.InnerClass.MyEnum print("Inner ", e1, e2) e1 = InnerClass.MyEnum.V1 diff --git a/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.gd b/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.gd index 38bb7f6e9c2..5b0e5c0bf07 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.gd @@ -1,4 +1,4 @@ -var Value:int = 8 : +var Value:int = 8: get: return Value set(v): diff --git a/modules/gdscript/tests/scripts/analyzer/features/property_inline.gd b/modules/gdscript/tests/scripts/analyzer/features/property_inline.gd index 23eb011b237..474bb49a3b4 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/property_inline.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/property_inline.gd @@ -6,21 +6,21 @@ var prop1: prop1 = value # Typed inline property -var prop2 : int: +var prop2: int: get: return prop2 set(value): prop2 = value # Typed inline property with default value -var prop3 : int = 1: +var prop3: int = 1: get: return prop3 set(value): prop3 = value # Typed inline property with backing variable -var _prop4 : int = 2 +var _prop4: int = 2 var prop4: int: get: return _prop4 diff --git a/modules/gdscript/tests/scripts/analyzer/features/use_preload_script_as_type.gd b/modules/gdscript/tests/scripts/analyzer/features/use_preload_script_as_type.gd index beabf3d2e5c..5fbc91be5ec 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/use_preload_script_as_type.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/use_preload_script_as_type.gd @@ -1,4 +1,4 @@ -const preloaded : GDScript = preload("gdscript_to_preload.notest.gd") +const preloaded: GDScript = preload("gdscript_to_preload.notest.gd") func test(): var preloaded_instance: preloaded = preloaded.new() diff --git a/modules/gdscript/tests/scripts/parser/features/static_typing.gd b/modules/gdscript/tests/scripts/parser/features/static_typing.gd index d42632c82d3..0157ca2128b 100644 --- a/modules/gdscript/tests/scripts/parser/features/static_typing.gd +++ b/modules/gdscript/tests/scripts/parser/features/static_typing.gd @@ -1,3 +1,5 @@ +# Do not fix code style here! + func test(): # The following lines are equivalent: var _integer: int = 1 diff --git a/modules/gdscript/tests/scripts/parser/features/static_typing.out b/modules/gdscript/tests/scripts/parser/features/static_typing.out index 92ce7bc0e0f..207d90fef13 100644 --- a/modules/gdscript/tests/scripts/parser/features/static_typing.out +++ b/modules/gdscript/tests/scripts/parser/features/static_typing.out @@ -1,21 +1,21 @@ GDTEST_OK >> WARNING ->> Line: 9 ->> UNUSED_LOCAL_CONSTANT ->> The local constant '_INTEGER' is declared but never used in the block. If this is intended, prefix it with an underscore: '__INTEGER' ->> WARNING ->> Line: 10 ->> UNUSED_LOCAL_CONSTANT ->> The local constant '_INTEGER_REDUNDANT_TYPED' is declared but never used in the block. If this is intended, prefix it with an underscore: '__INTEGER_REDUNDANT_TYPED' ->> WARNING >> Line: 11 >> UNUSED_LOCAL_CONSTANT ->> The local constant '_INTEGER_REDUNDANT_TYPED2' is declared but never used in the block. If this is intended, prefix it with an underscore: '__INTEGER_REDUNDANT_TYPED2' +>> The local constant '_INTEGER' is declared but never used in the block. If this is intended, prefix it with an underscore: '__INTEGER' >> WARNING >> Line: 12 >> UNUSED_LOCAL_CONSTANT ->> The local constant '_INTEGER_REDUNDANT_INFERRED' is declared but never used in the block. If this is intended, prefix it with an underscore: '__INTEGER_REDUNDANT_INFERRED' +>> The local constant '_INTEGER_REDUNDANT_TYPED' is declared but never used in the block. If this is intended, prefix it with an underscore: '__INTEGER_REDUNDANT_TYPED' >> WARNING >> Line: 13 >> UNUSED_LOCAL_CONSTANT +>> The local constant '_INTEGER_REDUNDANT_TYPED2' is declared but never used in the block. If this is intended, prefix it with an underscore: '__INTEGER_REDUNDANT_TYPED2' +>> WARNING +>> Line: 14 +>> UNUSED_LOCAL_CONSTANT +>> The local constant '_INTEGER_REDUNDANT_INFERRED' is declared but never used in the block. If this is intended, prefix it with an underscore: '__INTEGER_REDUNDANT_INFERRED' +>> WARNING +>> Line: 15 +>> UNUSED_LOCAL_CONSTANT >> The local constant '_INTEGER_REDUNDANT_INFERRED2' is declared but never used in the block. If this is intended, prefix it with an underscore: '__INTEGER_REDUNDANT_INFERRED2' diff --git a/modules/gdscript/tests/scripts/runtime/features/default_set_beforehand.gd b/modules/gdscript/tests/scripts/runtime/features/default_set_beforehand.gd index 03278e453f5..0851d939dc1 100644 --- a/modules/gdscript/tests/scripts/runtime/features/default_set_beforehand.gd +++ b/modules/gdscript/tests/scripts/runtime/features/default_set_beforehand.gd @@ -1,8 +1,8 @@ extends Node @onready var later_inferred := [1] -@onready var later_static : Array -@onready var later_static_with_init : Array = [1] +@onready var later_static: Array +@onready var later_static_with_init: Array = [1] @onready var later_untyped = [1] func test(): diff --git a/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.gd b/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.gd index 3eb02816edc..14c93eb159f 100644 --- a/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.gd +++ b/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.gd @@ -1,5 +1,5 @@ #GDTEST_OK -var prop : int = 0: +var prop: int = 0: get: return prop set(value): diff --git a/modules/gdscript/tests/scripts/runtime/features/use_conversion_assign_with_variant_value.gd b/modules/gdscript/tests/scripts/runtime/features/use_conversion_assign_with_variant_value.gd index efa8270526a..20b024f09ed 100644 --- a/modules/gdscript/tests/scripts/runtime/features/use_conversion_assign_with_variant_value.gd +++ b/modules/gdscript/tests/scripts/runtime/features/use_conversion_assign_with_variant_value.gd @@ -4,6 +4,6 @@ func test(): @warning_ignore("narrowing_conversion") var foo: int = 0.0 print(typeof(foo) == TYPE_INT) - var dict : Dictionary = {"a":0.0} + var dict: Dictionary = {"a": 0.0} foo = dict.get("a") print(typeof(foo) == TYPE_INT) diff --git a/modules/gltf/doc_classes/GLTFNode.xml b/modules/gltf/doc_classes/GLTFNode.xml index f3b3e615011..b9223bfdfac 100644 --- a/modules/gltf/doc_classes/GLTFNode.xml +++ b/modules/gltf/doc_classes/GLTFNode.xml @@ -5,6 +5,7 @@ Represents a GLTF node. GLTF nodes may have names, transforms, children (other GLTF nodes), and more specialized properties (represented by their own classes). + GLTF nodes generally exist inside of [GLTFState] which represents all data of a GLTF file. Most of GLTFNode's properties are indices of other data in the GLTF file. You can extend a GLTF node with additional properties by using [method get_additional_data] and [method set_additional_data]. https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_004_ScenesNodes.md" @@ -30,28 +31,40 @@ + If this GLTF node is a camera, the index of the [GLTFCamera] in the [GLTFState] that describes the camera's properties. If -1, this node is not a camera. + The indices of the children nodes in the [GLTFState]. If this GLTF node has no children, this will be an empty array. + How deep into the node hierarchy this node is. A root node will have a height of 0, its children will have a height of 1, and so on. If -1, the height has not been calculated. + If this GLTF node is a light, the index of the [GLTFLight] in the [GLTFState] that describes the light's properties. If -1, this node is not a light. + If this GLTF node is a mesh, the index of the [GLTFMesh] in the [GLTFState] that describes the mesh's properties. If -1, this node is not a mesh. + The index of the parent node in the [GLTFState]. If -1, this node is a root node. + The position of the GLTF node relative to its parent. + The rotation of the GLTF node relative to its parent. + The scale of the GLTF node relative to its parent. + If this GLTF node has a skeleton, the index of the [GLTFSkeleton] in the [GLTFState] that describes the skeleton's properties. If -1, this node does not have a skeleton. + If this GLTF node has a skin, the index of the [GLTFSkin] in the [GLTFState] that describes the skin's properties. If -1, this node does not have a skin. + The transform of the GLTF node relative to its parent. This property is usually unused since the position, rotation, and scale properties are preferred. diff --git a/modules/gltf/doc_classes/GLTFState.xml b/modules/gltf/doc_classes/GLTFState.xml index 33b92f37c82..7a46fb8dfc6 100644 --- a/modules/gltf/doc_classes/GLTFState.xml +++ b/modules/gltf/doc_classes/GLTFState.xml @@ -1,8 +1,11 @@ + Represents all data of a GLTF file. + Contains all nodes and resources of a GLTF file. This is used by [GLTFDocument] as data storage, which allows [GLTFDocument] and all [GLTFDocumentExtension] classes to remain stateless. + GLTFState can be populated by [GLTFDocument] reading a file or by converting a Godot scene. Then the data can either be used to create a Godot scene or save to a GLTF file. The code that converts to/from a Godot scene can be intercepted at arbitrary points by [GLTFDocumentExtension] classes. This allows for custom data to be stored in the GLTF file or for custom data to be converted to/from Godot nodes. @@ -32,17 +35,20 @@ + Returns the [AnimationPlayer] node with the given index. These nodes are only used during the export process when converting Godot [AnimationPlayer] nodes to GLTF animations. + Returns the number of [AnimationPlayer] nodes in this [GLTFState]. These nodes are only used during the export process when converting Godot [AnimationPlayer] nodes to GLTF animations. + Returns an array of all [GLTFAnimation]s in the GLTF file. When importing, these will be generated as animations in an [AnimationPlayer] node. When exporting, these will be generated from Godot [AnimationPlayer] nodes. @@ -53,6 +59,7 @@ + Returns an array of all [GLTFCamera]s in the GLTF file. These are the cameras that the [member GLTFNode.camera] index refers to. @@ -68,6 +75,7 @@ + Returns an array of all [GLTFLight]s in the GLTF file. These are the lights that the [member GLTFNode.light] index refers to. @@ -78,27 +86,32 @@ + Returns an array of all [GLTFMesh]es in the GLTF file. These are the meshes that the [member GLTFNode.mesh] index refers to. + Returns an array of all [GLTFNode]s in the GLTF file. These are the nodes that [member GLTFNode.children] and [member root_nodes] refer to. This includes nodes that may not be generated in the Godot scene, or nodes that may generate multiple Godot scene nodes. + Returns the Godot scene node that corresponds to the same index as the [GLTFNode] it was generated from. Not every [GLTFNode] will have a scene node generated, and not every generated scene node will have a corresponding [GLTFNode]. + Returns an array of all [GLTFSkeleton]s in the GLTF file. These are the skeletons that the [member GLTFNode.skeleton] index refers to. + Returns an array of all [GLTFSkin]s in the GLTF file. These are the skins that the [member GLTFNode.skin] index refers to. @@ -115,11 +128,13 @@ + Returns an array of unique animation names. This is only used during the import process. + Returns an array of unique node names. This is used in both the import process and export process. @@ -141,6 +156,7 @@ + Sets the [GLTFAnimation]s in the state. When importing, these will be generated as animations in an [AnimationPlayer] node. When exporting, these will be generated from Godot [AnimationPlayer] nodes. @@ -153,6 +169,7 @@ + Sets the [GLTFCamera]s in the state. These are the cameras that the [member GLTFNode.camera] index refers to. @@ -171,6 +188,7 @@ + Sets the [GLTFLight]s in the state. These are the lights that the [member GLTFNode.light] index refers to. @@ -183,24 +201,28 @@ + Sets the [GLTFMesh]es in the state. These are the meshes that the [member GLTFNode.mesh] index refers to. + Sets the [GLTFNode]s in the state. These are the nodes that [member GLTFNode.children] and [member root_nodes] refer to. Some of the nodes set here may not be generated in the Godot scene, or may generate multiple Godot scene nodes. + Sets the [GLTFSkeleton]s in the state. These are the skeletons that the [member GLTFNode.skeleton] index refers to. + Sets the [GLTFSkin]s in the state. These are the skins that the [member GLTFNode.skin] index refers to. @@ -220,12 +242,14 @@ + Sets the unique animation names in the state. This is only used during the import process. + Sets the unique node names in the state. This is used in both the import process and export process. @@ -245,8 +269,10 @@ + The root nodes of the GLTF file. Typically, a GLTF file will only have one scene, and therefore one root node. However, a GLTF file may have multiple scenes and therefore multiple root nodes, which will be generated as siblings of each other and as children of the root node of the generated Godot scene. + The name of the scene. When importing, if not specified, this will be the file name. When exporting, if specified, the scene name will be saved to the GLTF file. diff --git a/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp index 388c3ec7400..2af716b8677 100644 --- a/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp +++ b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp @@ -70,7 +70,7 @@ Error GLTFDocumentExtensionConvertImporterMesh::import_post(Ref p_sta } queue.pop_front(); } - while (!queue.is_empty()) { + while (!delete_queue.is_empty()) { List::Element *E = delete_queue.front(); Node *node = E->get(); memdelete(node); diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 872e803b9ca..aad8ab9a57e 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -42,7 +42,6 @@ #ifdef TOOLS_ENABLED #include "core/os/keyboard.h" -#include "editor/bindings_generator.h" #include "editor/editor_internal_calls.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" @@ -102,13 +101,6 @@ void CSharpLanguage::init() { } #endif -#if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED) - // Generate the bindings here, before loading assemblies. The Godot assemblies - // may be missing if the glue wasn't generated yet in order to build them. - List cmdline_args = OS::get_singleton()->get_cmdline_args(); - BindingsGenerator::handle_cmdline_args(cmdline_args); -#endif - GLOBAL_DEF("dotnet/project/assembly_name", ""); #ifdef TOOLS_ENABLED GLOBAL_DEF("dotnet/project/solution_directory", ""); @@ -589,7 +581,7 @@ Vector CSharpLanguage::debug_get_current_stack_info() _recursion_flag_ = false; }; - if (!gdmono->is_runtime_initialized()) { + if (!gdmono || !gdmono->is_runtime_initialized()) { return Vector(); } @@ -679,6 +671,7 @@ void CSharpLanguage::reload_tool_script(const Ref