summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/extension/gdnative_interface.cpp136
-rw-r--r--core/extension/gdnative_interface.h26
-rw-r--r--core/io/multiplayer_replicator.cpp2
-rw-r--r--core/math/vector2.cpp4
-rw-r--r--core/math/vector2.h1
-rw-r--r--core/object/object.h1
-rw-r--r--core/templates/vector.h2
-rw-r--r--core/variant/variant_call.cpp2
-rw-r--r--core/variant/variant_utility.cpp11
-rw-r--r--doc/classes/@GlobalScope.xml17
-rw-r--r--doc/classes/EditorPlugin.xml16
-rw-r--r--doc/classes/HTTPRequest.xml2
-rw-r--r--doc/classes/TextureProgressBar.xml3
-rw-r--r--doc/classes/Vector2.xml12
-rw-r--r--editor/debugger/debug_adapter/debug_adapter_parser.cpp203
-rw-r--r--editor/debugger/debug_adapter/debug_adapter_parser.h16
-rw-r--r--editor/debugger/debug_adapter/debug_adapter_protocol.cpp541
-rw-r--r--editor/debugger/debug_adapter/debug_adapter_protocol.h17
-rw-r--r--editor/debugger/debug_adapter/debug_adapter_server.cpp31
-rw-r--r--editor/debugger/debug_adapter/debug_adapter_server.h2
-rw-r--r--editor/debugger/debug_adapter/debug_adapter_types.h10
-rw-r--r--editor/debugger/editor_debugger_node.cpp3
-rw-r--r--editor/debugger/script_editor_debugger.cpp14
-rw-r--r--editor/debugger/script_editor_debugger.h3
-rw-r--r--editor/editor_inspector.cpp15
-rw-r--r--editor/editor_inspector.h1
-rw-r--r--editor/editor_node.cpp10
-rw-r--r--editor/editor_node.h1
-rw-r--r--editor/editor_properties.cpp169
-rw-r--r--editor/editor_properties.h30
-rw-r--r--editor/editor_run_native.cpp18
-rw-r--r--editor/editor_run_native.h3
-rw-r--r--editor/editor_spin_slider.cpp8
-rw-r--r--editor/editor_themes.cpp25
-rw-r--r--editor/icons/GuiCheckedDisabled.svg1
-rw-r--r--editor/icons/GuiRadioCheckedDisabled.svg1
-rw-r--r--editor/icons/GuiRadioUncheckedDisabled.svg1
-rw-r--r--editor/icons/GuiSpinboxUpdownDisabled.svg1
-rw-r--r--editor/icons/GuiUncheckedDisabled.svg1
-rw-r--r--editor/plugins/script_editor_plugin.cpp26
-rw-r--r--editor/plugins/script_editor_plugin.h4
-rw-r--r--editor/plugins/script_text_editor.cpp8
-rw-r--r--editor/plugins/script_text_editor.h2
-rw-r--r--editor/plugins/text_editor.h2
-rw-r--r--modules/enet/enet_multiplayer_peer.cpp4
-rw-r--r--modules/gdnative/SCsub1
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp86
-rw-r--r--modules/gdscript/gdscript_analyzer.h6
-rw-r--r--modules/gdscript/gdscript_compiler.cpp29
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs32
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/ProcessExtensions.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs80
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/IdentifierUtils.cs10
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs15
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs122
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs44
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs7
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs22
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs77
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs14
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs36
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs85
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs26
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs23
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs13
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs12
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/FsPathUtils.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs12
-rw-r--r--modules/mono/editor/bindings_generator.cpp2
-rw-r--r--modules/mono/editor/bindings_generator.h2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs291
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs138
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs123
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs44
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs153
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs143
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs40
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs148
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs24
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs19
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs24
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs388
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs3
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTraceListener.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs123
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs227
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs29
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs162
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs34
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs106
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs161
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/RID.cs39
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs144
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs144
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs24
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs15
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs423
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs33
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs112
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs85
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs187
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs98
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs187
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs104
-rw-r--r--modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml54
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp40
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.h2
-rw-r--r--modules/visual_script/visual_script_editor.h2
-rw-r--r--platform/android/export/export_plugin.cpp5
-rw-r--r--platform/android/export/gradle_export_util.cpp6
-rw-r--r--platform/android/java/app/AndroidManifest.xml4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java6
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java14
-rw-r--r--platform/osx/display_server_osx.mm4
-rw-r--r--scene/gui/check_box.cpp18
-rw-r--r--scene/gui/line_edit.cpp2
-rw-r--r--scene/gui/tab_container.cpp17
-rw-r--r--scene/gui/texture_progress_bar.cpp57
-rw-r--r--scene/gui/texture_progress_bar.h4
-rw-r--r--scene/main/window.cpp2
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp2
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp2
134 files changed, 4728 insertions, 1702 deletions
diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp
index de107b4156..a65bdd16dc 100644
--- a/core/extension/gdnative_interface.cpp
+++ b/core/extension/gdnative_interface.cpp
@@ -661,6 +661,116 @@ static const char32_t *gdnative_string_operator_index_const(const GDNativeString
return &self->ptr()[p_index];
}
+/* Packed array functions */
+
+static uint8_t *gdnative_packed_byte_array_operator_index(GDNativeTypePtr p_self, GDNativeInt p_index) {
+ PackedByteArray *self = (PackedByteArray *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return &self->ptrw()[p_index];
+}
+
+static const uint8_t *gdnative_packed_byte_array_operator_index_const(const GDNativeTypePtr p_self, GDNativeInt p_index) {
+ const PackedByteArray *self = (const PackedByteArray *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return &self->ptr()[p_index];
+}
+
+static GDNativeTypePtr gdnative_packed_color_array_operator_index(GDNativeTypePtr p_self, GDNativeInt p_index) {
+ PackedColorArray *self = (PackedColorArray *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return (GDNativeTypePtr)&self->ptrw()[p_index];
+}
+
+static GDNativeTypePtr gdnative_packed_color_array_operator_index_const(const GDNativeTypePtr p_self, GDNativeInt p_index) {
+ const PackedColorArray *self = (const PackedColorArray *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return (GDNativeTypePtr)&self->ptr()[p_index];
+}
+
+static float *gdnative_packed_float32_array_operator_index(GDNativeTypePtr p_self, GDNativeInt p_index) {
+ PackedFloat32Array *self = (PackedFloat32Array *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return &self->ptrw()[p_index];
+}
+
+static const float *gdnative_packed_float32_array_operator_index_const(const GDNativeTypePtr p_self, GDNativeInt p_index) {
+ const PackedFloat32Array *self = (const PackedFloat32Array *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return &self->ptr()[p_index];
+}
+
+static double *gdnative_packed_float64_array_operator_index(GDNativeTypePtr p_self, GDNativeInt p_index) {
+ PackedFloat64Array *self = (PackedFloat64Array *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return &self->ptrw()[p_index];
+}
+
+static const double *gdnative_packed_float64_array_operator_index_const(const GDNativeTypePtr p_self, GDNativeInt p_index) {
+ const PackedFloat64Array *self = (const PackedFloat64Array *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return &self->ptr()[p_index];
+}
+
+static int32_t *gdnative_packed_int32_array_operator_index(GDNativeTypePtr p_self, GDNativeInt p_index) {
+ PackedInt32Array *self = (PackedInt32Array *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return &self->ptrw()[p_index];
+}
+
+static const int32_t *gdnative_packed_int32_array_operator_index_const(const GDNativeTypePtr p_self, GDNativeInt p_index) {
+ const PackedInt32Array *self = (const PackedInt32Array *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return &self->ptr()[p_index];
+}
+
+static int64_t *gdnative_packed_int64_array_operator_index(GDNativeTypePtr p_self, GDNativeInt p_index) {
+ PackedInt64Array *self = (PackedInt64Array *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return &self->ptrw()[p_index];
+}
+
+static const int64_t *gdnative_packed_int64_array_operator_index_const(const GDNativeTypePtr p_self, GDNativeInt p_index) {
+ const PackedInt64Array *self = (const PackedInt64Array *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return &self->ptr()[p_index];
+}
+
+static GDNativeStringPtr gdnative_packed_string_array_operator_index(GDNativeTypePtr p_self, GDNativeInt p_index) {
+ PackedStringArray *self = (PackedStringArray *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return (GDNativeStringPtr)&self->ptrw()[p_index];
+}
+
+static GDNativeStringPtr gdnative_packed_string_array_operator_index_const(const GDNativeTypePtr p_self, GDNativeInt p_index) {
+ const PackedStringArray *self = (const PackedStringArray *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return (GDNativeStringPtr)&self->ptr()[p_index];
+}
+
+static GDNativeTypePtr gdnative_packed_vector2_array_operator_index(GDNativeTypePtr p_self, GDNativeInt p_index) {
+ PackedVector2Array *self = (PackedVector2Array *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return (GDNativeTypePtr)&self->ptrw()[p_index];
+}
+
+static GDNativeTypePtr gdnative_packed_vector2_array_operator_index_const(const GDNativeTypePtr p_self, GDNativeInt p_index) {
+ const PackedVector2Array *self = (const PackedVector2Array *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return (GDNativeTypePtr)&self->ptr()[p_index];
+}
+
+static GDNativeTypePtr gdnative_packed_vector3_array_operator_index(GDNativeTypePtr p_self, GDNativeInt p_index) {
+ PackedVector3Array *self = (PackedVector3Array *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return (GDNativeTypePtr)&self->ptrw()[p_index];
+}
+
+static GDNativeTypePtr gdnative_packed_vector3_array_operator_index_const(const GDNativeTypePtr p_self, GDNativeInt p_index) {
+ const PackedVector3Array *self = (const PackedVector3Array *)p_self;
+ ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
+ return (GDNativeTypePtr)&self->ptr()[p_index];
+}
+
/* OBJECT API */
static void gdnative_object_method_bind_call(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeVariantPtr *p_args, GDNativeInt p_arg_count, GDNativeVariantPtr r_return, GDNativeCallError *r_error) {
@@ -843,6 +953,32 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
gdni.string_operator_index = gdnative_string_operator_index;
gdni.string_operator_index_const = gdnative_string_operator_index_const;
+ /* Packed array functions */
+
+ gdni.packed_byte_array_operator_index = gdnative_packed_byte_array_operator_index;
+ gdni.packed_byte_array_operator_index_const = gdnative_packed_byte_array_operator_index_const;
+
+ gdni.packed_color_array_operator_index = gdnative_packed_color_array_operator_index;
+ gdni.packed_color_array_operator_index_const = gdnative_packed_color_array_operator_index_const;
+
+ gdni.packed_float32_array_operator_index = gdnative_packed_float32_array_operator_index;
+ gdni.packed_float32_array_operator_index_const = gdnative_packed_float32_array_operator_index_const;
+ gdni.packed_float64_array_operator_index = gdnative_packed_float64_array_operator_index;
+ gdni.packed_float64_array_operator_index_const = gdnative_packed_float64_array_operator_index_const;
+
+ gdni.packed_int32_array_operator_index = gdnative_packed_int32_array_operator_index;
+ gdni.packed_int32_array_operator_index_const = gdnative_packed_int32_array_operator_index_const;
+ gdni.packed_int64_array_operator_index = gdnative_packed_int64_array_operator_index;
+ gdni.packed_int64_array_operator_index_const = gdnative_packed_int64_array_operator_index_const;
+
+ gdni.packed_string_array_operator_index = gdnative_packed_string_array_operator_index;
+ gdni.packed_string_array_operator_index_const = gdnative_packed_string_array_operator_index_const;
+
+ gdni.packed_vector2_array_operator_index = gdnative_packed_vector2_array_operator_index;
+ gdni.packed_vector2_array_operator_index_const = gdnative_packed_vector2_array_operator_index_const;
+ gdni.packed_vector3_array_operator_index = gdnative_packed_vector3_array_operator_index;
+ gdni.packed_vector3_array_operator_index_const = gdnative_packed_vector3_array_operator_index_const;
+
/* OBJECT */
gdni.object_method_bind_call = gdnative_object_method_bind_call;
diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h
index 3a5b04429c..63f4b0917c 100644
--- a/core/extension/gdnative_interface.h
+++ b/core/extension/gdnative_interface.h
@@ -387,6 +387,32 @@ typedef struct {
char32_t *(*string_operator_index)(GDNativeStringPtr p_self, GDNativeInt p_index);
const char32_t *(*string_operator_index_const)(const GDNativeStringPtr p_self, GDNativeInt p_index);
+ /* Packed array functions */
+
+ uint8_t *(*packed_byte_array_operator_index)(GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedByteArray
+ const uint8_t *(*packed_byte_array_operator_index_const)(const GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedByteArray
+
+ GDNativeTypePtr (*packed_color_array_operator_index)(GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedColorArray, returns Color ptr
+ GDNativeTypePtr (*packed_color_array_operator_index_const)(const GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedColorArray, returns Color ptr
+
+ float *(*packed_float32_array_operator_index)(GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedFloat32Array
+ const float *(*packed_float32_array_operator_index_const)(const GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedFloat32Array
+ double *(*packed_float64_array_operator_index)(GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedFloat64Array
+ const double *(*packed_float64_array_operator_index_const)(const GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedFloat64Array
+
+ int32_t *(*packed_int32_array_operator_index)(GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedInt32Array
+ const int32_t *(*packed_int32_array_operator_index_const)(const GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedInt32Array
+ int64_t *(*packed_int64_array_operator_index)(GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedInt32Array
+ const int64_t *(*packed_int64_array_operator_index_const)(const GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedInt32Array
+
+ GDNativeStringPtr (*packed_string_array_operator_index)(GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedStringArray
+ GDNativeStringPtr (*packed_string_array_operator_index_const)(const GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedStringArray
+
+ GDNativeTypePtr (*packed_vector2_array_operator_index)(GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedVector2Array, returns Vector2 ptr
+ GDNativeTypePtr (*packed_vector2_array_operator_index_const)(const GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedVector2Array, returns Vector2 ptr
+ GDNativeTypePtr (*packed_vector3_array_operator_index)(GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedVector3Array, returns Vector3 ptr
+ GDNativeTypePtr (*packed_vector3_array_operator_index_const)(const GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be a PackedVector3Array, returns Vector3 ptr
+
/* OBJECT */
void (*object_method_bind_call)(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeVariantPtr *p_args, GDNativeInt p_arg_count, GDNativeVariantPtr r_ret, GDNativeCallError *r_error);
diff --git a/core/io/multiplayer_replicator.cpp b/core/io/multiplayer_replicator.cpp
index 1642aab136..b9d0675af1 100644
--- a/core/io/multiplayer_replicator.cpp
+++ b/core/io/multiplayer_replicator.cpp
@@ -189,6 +189,8 @@ Error MultiplayerReplicator::_send_default_spawn_despawn(int p_peer_id, const Re
bool is_raw = false;
if (state_variants.size() == 1 && state_variants[0].get_type() == Variant::PACKED_BYTE_ARRAY) {
is_raw = true;
+ const PackedByteArray pba = state_variants[0];
+ state_len = pba.size();
} else if (state_variants.size()) {
err = _encode_state(state_variants, nullptr, state_len);
ERR_FAIL_COND_V(err, err);
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index 54abc1b7f2..b53dc05a00 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -34,6 +34,10 @@ real_t Vector2::angle() const {
return Math::atan2(y, x);
}
+Vector2 Vector2::from_angle(const real_t p_angle) {
+ return Vector2(Math::cos(p_angle), Math::sin(p_angle));
+}
+
real_t Vector2::length() const {
return Math::sqrt(x * x + y * y);
}
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 330b4741b1..332c0475fa 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -147,6 +147,7 @@ struct Vector2 {
bool operator>=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); }
real_t angle() const;
+ static Vector2 from_angle(const real_t p_angle);
_FORCE_INLINE_ Vector2 abs() const {
return Vector2(Math::abs(x), Math::abs(y));
diff --git a/core/object/object.h b/core/object/object.h
index 102776a589..1838e7eb3d 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -132,6 +132,7 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_DEFERRED_SET_RESOURCE = 1 << 26, // when loading, the resource for this property can be set at the end of loading
PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT = 1 << 27, // For Object properties, instantiate them when creating in editor.
PROPERTY_USAGE_EDITOR_BASIC_SETTING = 1 << 28, //for project or editor settings, show when basic settings are selected
+ PROPERTY_USAGE_READ_ONLY = 1 << 29,
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
diff --git a/core/templates/vector.h b/core/templates/vector.h
index 08cbef6ba4..033345d04c 100644
--- a/core/templates/vector.h
+++ b/core/templates/vector.h
@@ -229,7 +229,7 @@ public:
_FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return elem_ptr == b.elem_ptr; }
_FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return elem_ptr != b.elem_ptr; }
- ConstIterator(T *p_ptr) { elem_ptr = p_ptr; }
+ ConstIterator(const T *p_ptr) { elem_ptr = p_ptr; }
ConstIterator() {}
ConstIterator(const ConstIterator &p_it) { elem_ptr = p_it.elem_ptr; }
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index c9c7eca40d..39207df9e7 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1502,6 +1502,8 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, clamp, sarray("min", "max"), varray());
bind_method(Vector2, snapped, sarray("step"), varray());
+ bind_static_method(Vector2, from_angle, sarray("angle"), varray());
+
/* Vector2i */
bind_method(Vector2i, aspect, sarray(), varray());
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index f5cb2d40d6..232054d0ca 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -267,14 +267,6 @@ struct VariantUtilityFunctions {
return Math::db2linear(db);
}
- static inline Vector2 polar2cartesian(double r, double th) {
- return Vector2(r * Math::cos(th), r * Math::sin(th));
- }
-
- static inline Vector2 cartesian2polar(double x, double y) {
- return Vector2(Math::sqrt(x * x + y * y), Math::atan2(y, x));
- }
-
static inline int64_t wrapi(int64_t value, int64_t min, int64_t max) {
return Math::wrapi(value, min, max);
}
@@ -1214,9 +1206,6 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(linear2db, sarray("lin"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(db2linear, sarray("db"), Variant::UTILITY_FUNC_TYPE_MATH);
- FUNCBINDR(polar2cartesian, sarray("r", "th"), Variant::UTILITY_FUNC_TYPE_MATH);
- FUNCBINDR(cartesian2polar, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH);
-
FUNCBINDR(wrapi, sarray("value", "min", "max"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(wrapf, sarray("value", "min", "max"), Variant::UTILITY_FUNC_TYPE_MATH);
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 585b94a522..616d88c7f3 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -99,14 +99,6 @@
[b]Warning:[/b] Deserialized object can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats (remote code execution).
</description>
</method>
- <method name="cartesian2polar">
- <return type="Vector2" />
- <argument index="0" name="x" type="float" />
- <argument index="1" name="y" type="float" />
- <description>
- Converts a 2D point expressed in the cartesian coordinate system (X and Y axis) to the polar coordinate system (a distance from the origin and an angle).
- </description>
- </method>
<method name="ceil">
<return type="float" />
<argument index="0" name="x" type="float" />
@@ -521,14 +513,6 @@
[b]Warning:[/b] Due to the way it is implemented, this function returns [code]0[/code] rather than [code]1[/code] for non-positive values of [code]value[/code] (in reality, 1 is the smallest integer power of 2).
</description>
</method>
- <method name="polar2cartesian">
- <return type="Vector2" />
- <argument index="0" name="r" type="float" />
- <argument index="1" name="th" type="float" />
- <description>
- Converts a 2D point expressed in the polar coordinate system (a distance from the origin [code]r[/code] and an angle [code]th[/code]) to the cartesian coordinate system (X and Y axis).
- </description>
- </method>
<method name="posmod">
<return type="int" />
<argument index="0" name="x" type="int" />
@@ -2474,6 +2458,7 @@
<constant name="METHOD_FLAG_STATIC" value="256" enum="MethodFlags">
</constant>
<constant name="METHOD_FLAG_OBJECT_CORE" value="512" enum="MethodFlags">
+ Used internally. Allows to not dump core virtuals such as [code]_notification[/code] to the JSON API.
</constant>
<constant name="METHOD_FLAGS_DEFAULT" value="1" enum="MethodFlags">
Default method flags.
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index e564e8045c..b8436be76a 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -56,11 +56,11 @@
Called by the engine when the 3D editor's viewport is updated. Use the [code]overlay[/code] [Control] for drawing. You can update the viewport manually by calling [method update_overlays].
[codeblocks]
[gdscript]
- func _forward_spatial_3d_over_viewport(overlay):
+ func _forward_3d_draw_over_viewport(overlay):
# Draw a circle at cursor position.
overlay.draw_circle(overlay.get_local_mouse_position(), 64)
- func _forward_spatial_gui_input(camera, event):
+ func _forward_3d_gui_input(camera, event):
if event is InputEventMouseMotion:
# Redraw viewport when cursor is moved.
update_overlays()
@@ -68,13 +68,13 @@
return false
[/gdscript]
[csharp]
- public override void ForwardSpatialDrawOverViewport(Godot.Control overlay)
+ public override void _Forward3dDrawOverViewport(Godot.Control overlay)
{
// Draw a circle at cursor position.
overlay.DrawCircle(overlay.GetLocalMousePosition(), 64, Colors.White);
}
- public override bool ForwardSpatialGuiInput(Godot.Camera3D camera, InputEvent @event)
+ public override bool _Forward3dGuiInput(Godot.Camera3D camera, InputEvent @event)
{
if (@event is InputEventMouseMotion)
{
@@ -104,12 +104,12 @@
[codeblocks]
[gdscript]
# Prevents the InputEvent to reach other Editor classes.
- func _forward_spatial_gui_input(camera, event):
+ func _forward_3d_gui_input(camera, event):
return true
[/gdscript]
[csharp]
// Prevents the InputEvent to reach other Editor classes.
- public override bool ForwardSpatialGuiInput(Camera3D camera, InputEvent @event)
+ public override bool _Forward3dGuiInput(Camera3D camera, InputEvent @event)
{
return true;
}
@@ -119,12 +119,12 @@
[codeblocks]
[gdscript]
# Consumes InputEventMouseMotion and forwards other InputEvent types.
- func _forward_spatial_gui_input(camera, event):
+ func _forward_3d_gui_input(camera, event):
return event is InputEventMouseMotion
[/gdscript]
[csharp]
// Consumes InputEventMouseMotion and forwards other InputEvent types.
- public override bool ForwardSpatialGuiInput(Camera3D camera, InputEvent @event)
+ public override bool _Forward3dGuiInput(Camera3D camera, InputEvent @event)
{
return @event is InputEventMouseMotion;
}
diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml
index f45ddd0abb..4fafa0a0a1 100644
--- a/doc/classes/HTTPRequest.xml
+++ b/doc/classes/HTTPRequest.xml
@@ -192,7 +192,7 @@
<description>
Creates request on the underlying [HTTPClient]. If there is no configuration errors, it tries to connect using [method HTTPClient.connect_to_host] and passes parameters onto [method HTTPClient.request].
Returns [constant OK] if request is successfully created. (Does not imply that the server has responded), [constant ERR_UNCONFIGURED] if not in the tree, [constant ERR_BUSY] if still processing previous request, [constant ERR_INVALID_PARAMETER] if given string is not a valid URL format, or [constant ERR_CANT_CONNECT] if not using thread and the [HTTPClient] cannot connect to host.
- [b]Note:[/b] The [code]request_data[/code] parameter is ignored if [code]method[/code] is [constant HTTPClient.METHOD_GET]. This is because GET methods can't contain request data. As a workaround, you can pass request data as a query string in the URL. See [method String.uri_encode] for an example.
+ [b]Note:[/b] When [code]method[/code] is [constant HTTPClient.METHOD_GET], the payload sent via [code]request_data[/code] might be ignored by the server or even cause the server to reject the request (check [url=https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.1]RFC 7231 section 4.3.1[/url] for more details). As a workaround, you can send data as a query string in the URL. See [method String.uri_encode] for an example.
</description>
</method>
<method name="request_raw">
diff --git a/doc/classes/TextureProgressBar.xml b/doc/classes/TextureProgressBar.xml
index 9da89ebe43..ee47557b39 100644
--- a/doc/classes/TextureProgressBar.xml
+++ b/doc/classes/TextureProgressBar.xml
@@ -60,6 +60,9 @@
[Texture2D] that clips based on the node's [code]value[/code] and [member fill_mode]. As [code]value[/code] increased, the texture fills up. It shows entirely when [code]value[/code] reaches [code]max_value[/code]. It doesn't show at all if [code]value[/code] is equal to [code]min_value[/code].
The [code]value[/code] property comes from [Range]. See [member Range.value], [member Range.min_value], [member Range.max_value].
</member>
+ <member name="texture_progress_offset" type="Vector2" setter="set_texture_progress_offset" getter="get_texture_progress_offset" default="Vector2(0, 0)">
+ The offset of [member texture_progress]. Useful for [member texture_over] and [member texture_under] with fancy borders, to avoid transparent margins in your progress texture.
+ </member>
<member name="texture_under" type="Texture2D" setter="set_under_texture" getter="get_under_texture">
[Texture2D] that draws under the progress bar. The bar's background.
</member>
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index cb5662419e..ab4d0e181a 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -155,6 +155,18 @@
Returns the vector with all components rounded down (towards negative infinity).
</description>
</method>
+ <method name="from_angle" qualifiers="static">
+ <return type="Vector2" />
+ <argument index="0" name="angle" type="float" />
+ <description>
+ Creates a unit [Vector2] rotated to the given [code]angle[/code] in radians. This is equivalent to doing [code]Vector2(cos(angle), sin(angle))[/code] or [code]Vector2.RIGHT.rotated(angle)[/code].
+ [codeblock]
+ print(Vector2.from_angle(0)) # Prints (1, 0).
+ print(Vector2(1, 0).angle()) # Prints 0, which is the angle used above.
+ print(Vector2.from_angle(PI / 2)) # Prints (0, 1).
+ [/codeblock]
+ </description>
+ </method>
<method name="is_equal_approx" qualifiers="const">
<return type="bool" />
<argument index="0" name="to" type="Vector2" />
diff --git a/editor/debugger/debug_adapter/debug_adapter_parser.cpp b/editor/debugger/debug_adapter/debug_adapter_parser.cpp
index 945291b163..fbd3aaa409 100644
--- a/editor/debugger/debug_adapter/debug_adapter_parser.cpp
+++ b/editor/debugger/debug_adapter/debug_adapter_parser.cpp
@@ -33,12 +33,15 @@
#include "editor/debugger/editor_debugger_node.h"
#include "editor/debugger/script_editor_debugger.h"
#include "editor/editor_node.h"
+#include "editor/editor_run_native.h"
void DebugAdapterParser::_bind_methods() {
// Requests
ClassDB::bind_method(D_METHOD("req_initialize", "params"), &DebugAdapterParser::req_initialize);
- ClassDB::bind_method(D_METHOD("req_disconnect", "params"), &DebugAdapterParser::prepare_success_response);
+ ClassDB::bind_method(D_METHOD("req_disconnect", "params"), &DebugAdapterParser::req_disconnect);
ClassDB::bind_method(D_METHOD("req_launch", "params"), &DebugAdapterParser::req_launch);
+ ClassDB::bind_method(D_METHOD("req_attach", "params"), &DebugAdapterParser::req_attach);
+ ClassDB::bind_method(D_METHOD("req_restart", "params"), &DebugAdapterParser::req_restart);
ClassDB::bind_method(D_METHOD("req_terminate", "params"), &DebugAdapterParser::req_terminate);
ClassDB::bind_method(D_METHOD("req_configurationDone", "params"), &DebugAdapterParser::prepare_success_response);
ClassDB::bind_method(D_METHOD("req_pause", "params"), &DebugAdapterParser::req_pause);
@@ -46,10 +49,13 @@ void DebugAdapterParser::_bind_methods() {
ClassDB::bind_method(D_METHOD("req_threads", "params"), &DebugAdapterParser::req_threads);
ClassDB::bind_method(D_METHOD("req_stackTrace", "params"), &DebugAdapterParser::req_stackTrace);
ClassDB::bind_method(D_METHOD("req_setBreakpoints", "params"), &DebugAdapterParser::req_setBreakpoints);
+ ClassDB::bind_method(D_METHOD("req_breakpointLocations", "params"), &DebugAdapterParser::req_breakpointLocations);
ClassDB::bind_method(D_METHOD("req_scopes", "params"), &DebugAdapterParser::req_scopes);
ClassDB::bind_method(D_METHOD("req_variables", "params"), &DebugAdapterParser::req_variables);
ClassDB::bind_method(D_METHOD("req_next", "params"), &DebugAdapterParser::req_next);
ClassDB::bind_method(D_METHOD("req_stepIn", "params"), &DebugAdapterParser::req_stepIn);
+ ClassDB::bind_method(D_METHOD("req_evaluate", "params"), &DebugAdapterParser::req_evaluate);
+ ClassDB::bind_method(D_METHOD("req_godot/put_msg", "params"), &DebugAdapterParser::req_godot_put_msg);
}
Dictionary DebugAdapterParser::prepare_base_event() const {
@@ -80,13 +86,31 @@ Dictionary DebugAdapterParser::prepare_error_response(const Dictionary &p_params
DAP::Message message;
String error, error_desc;
switch (err_type) {
+ case DAP::ErrorType::WRONG_PATH:
+ error = "wrong_path";
+ error_desc = "The editor and client are working on different paths; the client is on \"{clientPath}\", but the editor is on \"{editorPath}\"";
+ break;
+ case DAP::ErrorType::NOT_RUNNING:
+ error = "not_running";
+ error_desc = "Can't attach to a running session since there isn't one.";
+ break;
+ case DAP::ErrorType::TIMEOUT:
+ error = "timeout";
+ error_desc = "Timeout reached while processing a request.";
+ break;
+ case DAP::ErrorType::UNKNOWN_PLATFORM:
+ error = "unknown_platform";
+ error_desc = "The specified platform is unknown.";
+ break;
+ case DAP::ErrorType::MISSING_DEVICE:
+ error = "missing_device";
+ error_desc = "There's no connected device with specified id.";
+ break;
case DAP::ErrorType::UNKNOWN:
+ default:
error = "unknown";
error_desc = "An unknown error has ocurred when processing the request.";
break;
- case DAP::ErrorType::WRONG_PATH:
- error = "wrong_path";
- error_desc = "The editor and client are working on different paths; the client is on \"{clientPath}\", but the editor is on \"{editorPath}\"";
}
message.id = err_type;
@@ -114,10 +138,35 @@ Dictionary DebugAdapterParser::req_initialize(const Dictionary &p_params) const
DebugAdapterProtocol::get_singleton()->notify_initialized();
+ if (DebugAdapterProtocol::get_singleton()->_sync_breakpoints) {
+ // Send all current breakpoints
+ List<String> breakpoints;
+ ScriptEditor::get_singleton()->get_breakpoints(&breakpoints);
+ for (List<String>::Element *E = breakpoints.front(); E; E = E->next()) {
+ String breakpoint = E->get();
+
+ String path = breakpoint.left(breakpoint.find(":", 6)); // Skip initial part of path, aka "res://"
+ int line = breakpoint.substr(path.size()).to_int();
+
+ DebugAdapterProtocol::get_singleton()->on_debug_breakpoint_toggled(path, line, true);
+ }
+ } else {
+ // Remove all current breakpoints
+ EditorDebuggerNode::get_singleton()->get_default_debugger()->_clear_breakpoints();
+ }
+
return response;
}
-Dictionary DebugAdapterParser::req_launch(const Dictionary &p_params) {
+Dictionary DebugAdapterParser::req_disconnect(const Dictionary &p_params) const {
+ if (!DebugAdapterProtocol::get_singleton()->get_current_peer()->attached) {
+ EditorNode::get_singleton()->run_stop();
+ }
+
+ return prepare_success_response(p_params);
+}
+
+Dictionary DebugAdapterParser::req_launch(const Dictionary &p_params) const {
Dictionary args = p_params["arguments"];
if (args.has("project") && !is_valid_path(args["project"])) {
Dictionary variables;
@@ -126,17 +175,85 @@ Dictionary DebugAdapterParser::req_launch(const Dictionary &p_params) {
return prepare_error_response(p_params, DAP::ErrorType::WRONG_PATH, variables);
}
+ if (args.has("godot/custom_data")) {
+ DebugAdapterProtocol::get_singleton()->get_current_peer()->supportsCustomData = args["godot/custom_data"];
+ }
+
ScriptEditorDebugger *dbg = EditorDebuggerNode::get_singleton()->get_default_debugger();
if ((bool)args["noDebug"] != dbg->is_skip_breakpoints()) {
dbg->debug_skip_breakpoints();
}
- EditorNode::get_singleton()->run_play();
+ String platform_string = args.get("platform", "host");
+ if (platform_string == "host") {
+ EditorNode::get_singleton()->run_play();
+ } else {
+ int device = args.get("device", -1);
+ int idx = -1;
+ if (platform_string == "android") {
+ for (int i = 0; i < EditorExport::get_singleton()->get_export_platform_count(); i++) {
+ if (EditorExport::get_singleton()->get_export_platform(i)->get_name() == "Android") {
+ idx = i;
+ break;
+ }
+ }
+ } else if (platform_string == "web") {
+ for (int i = 0; i < EditorExport::get_singleton()->get_export_platform_count(); i++) {
+ if (EditorExport::get_singleton()->get_export_platform(i)->get_name() == "HTML5") {
+ idx = i;
+ break;
+ }
+ }
+ }
+
+ if (idx == -1) {
+ return prepare_error_response(p_params, DAP::ErrorType::UNKNOWN_PLATFORM);
+ }
+
+ EditorNode *editor = EditorNode::get_singleton();
+ Error err = platform_string == "android" ? editor->run_play_native(device, idx) : editor->run_play_native(-1, idx);
+ if (err) {
+ if (err == ERR_INVALID_PARAMETER && platform_string == "android") {
+ return prepare_error_response(p_params, DAP::ErrorType::MISSING_DEVICE);
+ } else {
+ return prepare_error_response(p_params, DAP::ErrorType::UNKNOWN);
+ }
+ }
+ }
+
+ DebugAdapterProtocol::get_singleton()->get_current_peer()->attached = false;
DebugAdapterProtocol::get_singleton()->notify_process();
return prepare_success_response(p_params);
}
+Dictionary DebugAdapterParser::req_attach(const Dictionary &p_params) const {
+ ScriptEditorDebugger *dbg = EditorDebuggerNode::get_singleton()->get_default_debugger();
+ if (!dbg->is_session_active()) {
+ return prepare_error_response(p_params, DAP::ErrorType::NOT_RUNNING);
+ }
+
+ DebugAdapterProtocol::get_singleton()->get_current_peer()->attached = true;
+ DebugAdapterProtocol::get_singleton()->notify_process();
+ return prepare_success_response(p_params);
+}
+
+Dictionary DebugAdapterParser::req_restart(const Dictionary &p_params) const {
+ // Extract embedded "arguments" so it can be given to req_launch/req_attach
+ Dictionary params = p_params, args;
+ args = params["arguments"];
+ args = args["arguments"];
+ params["arguments"] = args;
+
+ Dictionary response = DebugAdapterProtocol::get_singleton()->get_current_peer()->attached ? req_attach(params) : req_launch(params);
+ if (!response["success"]) {
+ response["command"] = p_params["command"];
+ return response;
+ }
+
+ return prepare_success_response(p_params);
+}
+
Dictionary DebugAdapterParser::req_terminate(const Dictionary &p_params) const {
EditorNode::get_singleton()->run_stop();
@@ -205,7 +322,7 @@ Dictionary DebugAdapterParser::req_stackTrace(const Dictionary &p_params) const
return response;
}
-Dictionary DebugAdapterParser::req_setBreakpoints(const Dictionary &p_params) {
+Dictionary DebugAdapterParser::req_setBreakpoints(const Dictionary &p_params) const {
Dictionary response = prepare_success_response(p_params), body;
response["body"] = body;
@@ -230,14 +347,30 @@ Dictionary DebugAdapterParser::req_setBreakpoints(const Dictionary &p_params) {
lines.push_back(breakpoint.line + !lines_at_one);
}
- EditorDebuggerNode::get_singleton()->set_breakpoints(ProjectSettings::get_singleton()->localize_path(source.path), lines);
Array updated_breakpoints = DebugAdapterProtocol::get_singleton()->update_breakpoints(source.path, lines);
body["breakpoints"] = updated_breakpoints;
return response;
}
-Dictionary DebugAdapterParser::req_scopes(const Dictionary &p_params) {
+Dictionary DebugAdapterParser::req_breakpointLocations(const Dictionary &p_params) const {
+ Dictionary response = prepare_success_response(p_params), body;
+ response["body"] = body;
+ Dictionary args = p_params["arguments"];
+
+ Array locations;
+ DAP::BreakpointLocation location;
+ location.line = args["line"];
+ if (args.has("endLine")) {
+ location.endLine = args["endLine"];
+ }
+ locations.push_back(location.to_json());
+
+ body["breakpoints"] = locations;
+ return response;
+}
+
+Dictionary DebugAdapterParser::req_scopes(const Dictionary &p_params) const {
Dictionary response = prepare_success_response(p_params), body;
response["body"] = body;
@@ -291,7 +424,14 @@ Dictionary DebugAdapterParser::req_variables(const Dictionary &p_params) const {
int variable_id = args["variablesReference"];
Map<int, Array>::Element *E = DebugAdapterProtocol::get_singleton()->variable_list.find(variable_id);
+
if (E) {
+ if (!DebugAdapterProtocol::get_singleton()->get_current_peer()->supportsVariableType) {
+ for (int i = 0; i < E->value().size(); i++) {
+ Dictionary variable = E->value()[i];
+ variable.erase("type");
+ }
+ }
body["variables"] = E ? E->value() : Array();
return response;
} else {
@@ -313,6 +453,29 @@ Dictionary DebugAdapterParser::req_stepIn(const Dictionary &p_params) const {
return prepare_success_response(p_params);
}
+Dictionary DebugAdapterParser::req_evaluate(const Dictionary &p_params) const {
+ Dictionary response = prepare_success_response(p_params), body;
+ response["body"] = body;
+
+ Dictionary args = p_params["arguments"];
+
+ String value = EditorDebuggerNode::get_singleton()->get_var_value(args["expression"]);
+ body["result"] = value;
+
+ return response;
+}
+
+Dictionary DebugAdapterParser::req_godot_put_msg(const Dictionary &p_params) const {
+ Dictionary args = p_params["arguments"];
+
+ String msg = args["message"];
+ Array data = args["data"];
+
+ EditorDebuggerNode::get_singleton()->get_default_debugger()->_put_msg(msg, data);
+
+ return prepare_success_response(p_params);
+}
+
Dictionary DebugAdapterParser::ev_initialized() const {
Dictionary event = prepare_base_event();
event["event"] = "initialized";
@@ -423,3 +586,25 @@ Dictionary DebugAdapterParser::ev_output(const String &p_message) const {
return event;
}
+
+Dictionary DebugAdapterParser::ev_breakpoint(const DAP::Breakpoint &p_breakpoint, const bool &p_enabled) const {
+ Dictionary event = prepare_base_event(), body;
+ event["event"] = "breakpoint";
+ event["body"] = body;
+
+ body["reason"] = p_enabled ? "new" : "removed";
+ body["breakpoint"] = p_breakpoint.to_json();
+
+ return event;
+}
+
+Dictionary DebugAdapterParser::ev_custom_data(const String &p_msg, const Array &p_data) const {
+ Dictionary event = prepare_base_event(), body;
+ event["event"] = "godot/custom_data";
+ event["body"] = body;
+
+ body["message"] = p_msg;
+ body["data"] = p_data;
+
+ return event;
+}
diff --git a/editor/debugger/debug_adapter/debug_adapter_parser.h b/editor/debugger/debug_adapter/debug_adapter_parser.h
index b86b37d067..4c93464e39 100644
--- a/editor/debugger/debug_adapter/debug_adapter_parser.h
+++ b/editor/debugger/debug_adapter/debug_adapter_parser.h
@@ -44,7 +44,7 @@ class DebugAdapterParser : public Object {
private:
friend DebugAdapterProtocol;
- _FORCE_INLINE_ bool is_valid_path(const String &p_path) {
+ _FORCE_INLINE_ bool is_valid_path(const String &p_path) const {
return p_path.begins_with(ProjectSettings::get_singleton()->get_resource_path());
}
@@ -60,17 +60,23 @@ protected:
public:
// Requests
Dictionary req_initialize(const Dictionary &p_params) const;
- Dictionary req_launch(const Dictionary &p_params);
+ Dictionary req_launch(const Dictionary &p_params) const;
+ Dictionary req_disconnect(const Dictionary &p_params) const;
+ Dictionary req_attach(const Dictionary &p_params) const;
+ Dictionary req_restart(const Dictionary &p_params) const;
Dictionary req_terminate(const Dictionary &p_params) const;
Dictionary req_pause(const Dictionary &p_params) const;
Dictionary req_continue(const Dictionary &p_params) const;
Dictionary req_threads(const Dictionary &p_params) const;
Dictionary req_stackTrace(const Dictionary &p_params) const;
- Dictionary req_setBreakpoints(const Dictionary &p_params);
- Dictionary req_scopes(const Dictionary &p_params);
+ Dictionary req_setBreakpoints(const Dictionary &p_params) const;
+ Dictionary req_breakpointLocations(const Dictionary &p_params) const;
+ Dictionary req_scopes(const Dictionary &p_params) const;
Dictionary req_variables(const Dictionary &p_params) const;
Dictionary req_next(const Dictionary &p_params) const;
Dictionary req_stepIn(const Dictionary &p_params) const;
+ Dictionary req_evaluate(const Dictionary &p_params) const;
+ Dictionary req_godot_put_msg(const Dictionary &p_params) const;
// Events
Dictionary ev_initialized() const;
@@ -83,6 +89,8 @@ public:
Dictionary ev_stopped_step() const;
Dictionary ev_continued() const;
Dictionary ev_output(const String &p_message) const;
+ Dictionary ev_custom_data(const String &p_msg, const Array &p_data) const;
+ Dictionary ev_breakpoint(const DAP::Breakpoint &p_breakpoint, const bool &p_enabled) const;
};
#endif
diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp
index 0482271432..2e0e6cb7c8 100644
--- a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp
+++ b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp
@@ -94,11 +94,17 @@ Error DAPeer::handle_data() {
String msg;
msg.parse_utf8((const char *)req_buf, req_pos);
+ // Apply a timestamp if it there's none yet
+ if (!timestamp) {
+ timestamp = OS::get_singleton()->get_ticks_msec();
+ }
+
// Response
if (DebugAdapterProtocol::get_singleton()->process_message(msg)) {
// Reset to read again
req_pos = 0;
has_header = false;
+ timestamp = 0;
}
}
return OK;
@@ -180,12 +186,460 @@ void DebugAdapterProtocol::reset_stack_info() {
variable_list.clear();
}
+int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
+ switch (p_var.get_type()) {
+ case Variant::VECTOR2:
+ case Variant::VECTOR2I: {
+ int id = variable_id++;
+ Vector2 vec = p_var;
+ DAP::Variable x, y;
+ x.name = "x";
+ y.name = "y";
+ x.type = y.type = Variant::get_type_name(p_var.get_type() == Variant::VECTOR2 ? Variant::FLOAT : Variant::INT);
+ x.value = rtos(vec.x);
+ y.value = rtos(vec.y);
+
+ Array arr;
+ arr.push_back(x.to_json());
+ arr.push_back(y.to_json());
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::RECT2:
+ case Variant::RECT2I: {
+ int id = variable_id++;
+ Rect2 rect = p_var;
+ DAP::Variable x, y, w, h;
+ x.name = "x";
+ y.name = "y";
+ w.name = "w";
+ h.name = "h";
+ x.type = y.type = w.type = h.type = Variant::get_type_name(p_var.get_type() == Variant::RECT2 ? Variant::FLOAT : Variant::INT);
+ x.value = rtos(rect.position.x);
+ y.value = rtos(rect.position.y);
+ w.value = rtos(rect.size.x);
+ h.value = rtos(rect.size.y);
+
+ Array arr;
+ arr.push_back(x.to_json());
+ arr.push_back(y.to_json());
+ arr.push_back(w.to_json());
+ arr.push_back(h.to_json());
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::VECTOR3:
+ case Variant::VECTOR3I: {
+ int id = variable_id++;
+ Vector3 vec = p_var;
+ DAP::Variable x, y, z;
+ x.name = "x";
+ y.name = "y";
+ z.name = "z";
+ x.type = y.type = z.type = Variant::get_type_name(p_var.get_type() == Variant::VECTOR3 ? Variant::FLOAT : Variant::INT);
+ x.value = rtos(vec.x);
+ y.value = rtos(vec.y);
+ z.value = rtos(vec.z);
+
+ Array arr;
+ arr.push_back(x.to_json());
+ arr.push_back(y.to_json());
+ arr.push_back(z.to_json());
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::TRANSFORM2D: {
+ int id = variable_id++;
+ Transform2D transform = p_var;
+ DAP::Variable x, y, origin;
+ x.name = "x";
+ y.name = "y";
+ origin.name = "origin";
+ x.type = y.type = origin.type = Variant::get_type_name(Variant::VECTOR2);
+ x.value = transform.elements[0];
+ y.value = transform.elements[1];
+ origin.value = transform.elements[2];
+ x.variablesReference = parse_variant(transform.elements[0]);
+ y.variablesReference = parse_variant(transform.elements[1]);
+ origin.variablesReference = parse_variant(transform.elements[2]);
+
+ Array arr;
+ arr.push_back(x.to_json());
+ arr.push_back(y.to_json());
+ arr.push_back(origin.to_json());
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::PLANE: {
+ int id = variable_id++;
+ Plane plane = p_var;
+ DAP::Variable d, normal;
+ d.name = "d";
+ normal.name = "normal";
+ d.type = Variant::get_type_name(Variant::FLOAT);
+ normal.type = Variant::get_type_name(Variant::VECTOR3);
+ d.value = rtos(plane.d);
+ normal.value = plane.normal;
+ normal.variablesReference = parse_variant(plane.normal);
+
+ Array arr;
+ arr.push_back(d.to_json());
+ arr.push_back(normal.to_json());
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::QUATERNION: {
+ int id = variable_id++;
+ Quaternion quat = p_var;
+ DAP::Variable x, y, z, w;
+ x.name = "x";
+ y.name = "y";
+ z.name = "z";
+ w.name = "w";
+ x.type = y.type = z.type = w.type = Variant::get_type_name(Variant::FLOAT);
+ x.value = rtos(quat.x);
+ y.value = rtos(quat.y);
+ z.value = rtos(quat.z);
+ w.value = rtos(quat.w);
+
+ Array arr;
+ arr.push_back(x.to_json());
+ arr.push_back(y.to_json());
+ arr.push_back(z.to_json());
+ arr.push_back(w.to_json());
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::AABB: {
+ int id = variable_id++;
+ AABB aabb = p_var;
+ DAP::Variable position, size;
+ position.name = "position";
+ size.name = "size";
+ position.type = size.type = Variant::get_type_name(Variant::VECTOR3);
+ position.value = aabb.position;
+ size.value = aabb.size;
+ position.variablesReference = parse_variant(aabb.position);
+ size.variablesReference = parse_variant(aabb.size);
+
+ Array arr;
+ arr.push_back(position.to_json());
+ arr.push_back(size.to_json());
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::BASIS: {
+ int id = variable_id++;
+ Basis basis = p_var;
+ DAP::Variable x, y, z;
+ x.name = "x";
+ y.name = "y";
+ z.name = "z";
+ x.type = y.type = z.type = Variant::get_type_name(Variant::VECTOR2);
+ x.value = basis.elements[0];
+ y.value = basis.elements[1];
+ z.value = basis.elements[2];
+ x.variablesReference = parse_variant(basis.elements[0]);
+ y.variablesReference = parse_variant(basis.elements[1]);
+ z.variablesReference = parse_variant(basis.elements[2]);
+
+ Array arr;
+ arr.push_back(x.to_json());
+ arr.push_back(y.to_json());
+ arr.push_back(z.to_json());
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::TRANSFORM3D: {
+ int id = variable_id++;
+ Transform3D transform = p_var;
+ DAP::Variable basis, origin;
+ basis.name = "basis";
+ origin.name = "origin";
+ basis.type = Variant::get_type_name(Variant::BASIS);
+ origin.type = Variant::get_type_name(Variant::VECTOR3);
+ basis.value = transform.basis;
+ origin.value = transform.origin;
+ basis.variablesReference = parse_variant(transform.basis);
+ origin.variablesReference = parse_variant(transform.origin);
+
+ Array arr;
+ arr.push_back(basis.to_json());
+ arr.push_back(origin.to_json());
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::COLOR: {
+ int id = variable_id++;
+ Color color = p_var;
+ DAP::Variable r, g, b, a;
+ r.name = "r";
+ g.name = "g";
+ b.name = "b";
+ a.name = "a";
+ r.type = g.type = b.type = a.type = Variant::get_type_name(Variant::FLOAT);
+ r.value = rtos(color.r);
+ g.value = rtos(color.g);
+ b.value = rtos(color.b);
+ a.value = rtos(color.a);
+
+ Array arr;
+ arr.push_back(r.to_json());
+ arr.push_back(g.to_json());
+ arr.push_back(b.to_json());
+ arr.push_back(a.to_json());
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::ARRAY: {
+ int id = variable_id++;
+ Array array = p_var;
+ DAP::Variable size;
+ size.name = "size";
+ size.type = Variant::get_type_name(Variant::INT);
+ size.value = itos(array.size());
+
+ Array arr;
+ arr.push_back(size.to_json());
+
+ for (int i = 0; i < array.size(); i++) {
+ DAP::Variable var;
+ var.name = itos(i);
+ var.type = Variant::get_type_name(array[i].get_type());
+ var.value = array[i];
+ var.variablesReference = parse_variant(array[i]);
+ arr.push_back(var.to_json());
+ }
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::DICTIONARY: {
+ int id = variable_id++;
+ Dictionary dictionary = p_var;
+ Array arr;
+
+ for (int i = 0; i < dictionary.size(); i++) {
+ DAP::Variable var;
+ var.name = dictionary.get_key_at_index(i);
+ Variant value = dictionary.get_value_at_index(i);
+ var.type = Variant::get_type_name(value.get_type());
+ var.value = value;
+ var.variablesReference = parse_variant(value);
+ arr.push_back(var.to_json());
+ }
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::PACKED_BYTE_ARRAY: {
+ int id = variable_id++;
+ PackedByteArray array = p_var;
+ DAP::Variable size;
+ size.name = "size";
+ size.type = Variant::get_type_name(Variant::INT);
+ size.value = itos(array.size());
+
+ Array arr;
+ arr.push_back(size.to_json());
+
+ for (int i = 0; i < array.size(); i++) {
+ DAP::Variable var;
+ var.name = itos(i);
+ var.type = "byte";
+ var.value = itos(array[i]);
+ arr.push_back(var.to_json());
+ }
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::PACKED_INT32_ARRAY: {
+ int id = variable_id++;
+ PackedInt32Array array = p_var;
+ DAP::Variable size;
+ size.name = "size";
+ size.type = Variant::get_type_name(Variant::INT);
+ size.value = itos(array.size());
+
+ Array arr;
+ arr.push_back(size.to_json());
+
+ for (int i = 0; i < array.size(); i++) {
+ DAP::Variable var;
+ var.name = itos(i);
+ var.type = "int";
+ var.value = itos(array[i]);
+ arr.push_back(var.to_json());
+ }
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::PACKED_INT64_ARRAY: {
+ int id = variable_id++;
+ PackedInt64Array array = p_var;
+ DAP::Variable size;
+ size.name = "size";
+ size.type = Variant::get_type_name(Variant::INT);
+ size.value = itos(array.size());
+
+ Array arr;
+ arr.push_back(size.to_json());
+
+ for (int i = 0; i < array.size(); i++) {
+ DAP::Variable var;
+ var.name = itos(i);
+ var.type = "long";
+ var.value = itos(array[i]);
+ arr.push_back(var.to_json());
+ }
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::PACKED_FLOAT32_ARRAY: {
+ int id = variable_id++;
+ PackedFloat32Array array = p_var;
+ DAP::Variable size;
+ size.name = "size";
+ size.type = Variant::get_type_name(Variant::INT);
+ size.value = itos(array.size());
+
+ Array arr;
+ arr.push_back(size.to_json());
+
+ for (int i = 0; i < array.size(); i++) {
+ DAP::Variable var;
+ var.name = itos(i);
+ var.type = "float";
+ var.value = rtos(array[i]);
+ arr.push_back(var.to_json());
+ }
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::PACKED_FLOAT64_ARRAY: {
+ int id = variable_id++;
+ PackedFloat64Array array = p_var;
+ DAP::Variable size;
+ size.name = "size";
+ size.type = Variant::get_type_name(Variant::INT);
+ size.value = itos(array.size());
+
+ Array arr;
+ arr.push_back(size.to_json());
+
+ for (int i = 0; i < array.size(); i++) {
+ DAP::Variable var;
+ var.name = itos(i);
+ var.type = "double";
+ var.value = rtos(array[i]);
+ arr.push_back(var.to_json());
+ }
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::PACKED_STRING_ARRAY: {
+ int id = variable_id++;
+ PackedStringArray array = p_var;
+ DAP::Variable size;
+ size.name = "size";
+ size.type = Variant::get_type_name(Variant::INT);
+ size.value = itos(array.size());
+
+ Array arr;
+ arr.push_back(size.to_json());
+
+ for (int i = 0; i < array.size(); i++) {
+ DAP::Variable var;
+ var.name = itos(i);
+ var.type = Variant::get_type_name(Variant::STRING);
+ var.value = array[i];
+ arr.push_back(var.to_json());
+ }
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::PACKED_VECTOR2_ARRAY: {
+ int id = variable_id++;
+ PackedVector2Array array = p_var;
+ DAP::Variable size;
+ size.name = "size";
+ size.type = Variant::get_type_name(Variant::INT);
+ size.value = itos(array.size());
+
+ Array arr;
+ arr.push_back(size.to_json());
+
+ for (int i = 0; i < array.size(); i++) {
+ DAP::Variable var;
+ var.name = itos(i);
+ var.type = Variant::get_type_name(Variant::VECTOR2);
+ var.value = array[i];
+ var.variablesReference = parse_variant(array[i]);
+ arr.push_back(var.to_json());
+ }
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::PACKED_VECTOR3_ARRAY: {
+ int id = variable_id++;
+ PackedVector2Array array = p_var;
+ DAP::Variable size;
+ size.name = "size";
+ size.type = Variant::get_type_name(Variant::INT);
+ size.value = itos(array.size());
+
+ Array arr;
+ arr.push_back(size.to_json());
+
+ for (int i = 0; i < array.size(); i++) {
+ DAP::Variable var;
+ var.name = itos(i);
+ var.type = Variant::get_type_name(Variant::VECTOR3);
+ var.value = array[i];
+ var.variablesReference = parse_variant(array[i]);
+ arr.push_back(var.to_json());
+ }
+ variable_list.insert(id, arr);
+ return id;
+ }
+ case Variant::PACKED_COLOR_ARRAY: {
+ int id = variable_id++;
+ PackedColorArray array = p_var;
+ DAP::Variable size;
+ size.name = "size";
+ size.type = Variant::get_type_name(Variant::INT);
+ size.value = itos(array.size());
+
+ Array arr;
+ arr.push_back(size.to_json());
+
+ for (int i = 0; i < array.size(); i++) {
+ DAP::Variable var;
+ var.name = itos(i);
+ var.type = Variant::get_type_name(Variant::COLOR);
+ var.value = array[i];
+ var.variablesReference = parse_variant(array[i]);
+ arr.push_back(var.to_json());
+ }
+ variable_list.insert(id, arr);
+ return id;
+ }
+ default:
+ // Simple atomic stuff, or too complex to be manipulated
+ return 0;
+ }
+}
+
bool DebugAdapterProtocol::process_message(const String &p_text) {
JSON json;
ERR_FAIL_COND_V_MSG(json.parse(p_text) != OK, true, "Mal-formed message!");
Dictionary params = json.get_data();
bool completed = true;
+ if (OS::get_singleton()->get_ticks_msec() - _current_peer->timestamp > _request_timeout) {
+ Dictionary response = parser->prepare_error_response(params, DAP::ErrorType::TIMEOUT);
+ _current_peer->res_queue.push_front(response);
+ return true;
+ }
+
// Append "req_" to any command received; prevents name clash with existing functions, and possibly exploiting
String command = "req_" + (String)params["command"];
if (parser->has_method(command)) {
@@ -211,7 +665,7 @@ void DebugAdapterProtocol::notify_initialized() {
}
void DebugAdapterProtocol::notify_process() {
- String launch_mode = _current_request.is_empty() ? "launch" : _current_request;
+ String launch_mode = _current_peer->attached ? "attach" : "launch";
Dictionary event = parser->ev_process(launch_mode);
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
@@ -222,7 +676,7 @@ void DebugAdapterProtocol::notify_process() {
void DebugAdapterProtocol::notify_terminated() {
Dictionary event = parser->ev_terminated();
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
- if (_current_request == "launch" && _current_peer == E->get()) {
+ if ((_current_request == "launch" || _current_request == "restart") && _current_peer == E->get()) {
continue;
}
E->get()->res_queue.push_back(event);
@@ -232,7 +686,7 @@ void DebugAdapterProtocol::notify_terminated() {
void DebugAdapterProtocol::notify_exited(const int &p_exitcode) {
Dictionary event = parser->ev_exited(p_exitcode);
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
- if (_current_request == "launch" && _current_peer == E->get()) {
+ if ((_current_request == "launch" || _current_request == "restart") && _current_peer == E->get()) {
continue;
}
E->get()->res_queue.push_back(event);
@@ -286,25 +740,46 @@ void DebugAdapterProtocol::notify_output(const String &p_message) {
}
}
+void DebugAdapterProtocol::notify_custom_data(const String &p_msg, const Array &p_data) {
+ Dictionary event = parser->ev_custom_data(p_msg, p_data);
+ for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
+ Ref<DAPeer> peer = E->get();
+ if (peer->supportsCustomData) {
+ peer->res_queue.push_back(event);
+ }
+ }
+}
+
+void DebugAdapterProtocol::notify_breakpoint(const DAP::Breakpoint &p_breakpoint, const bool &p_enabled) {
+ Dictionary event = parser->ev_breakpoint(p_breakpoint, p_enabled);
+ for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
+ if (_current_request == "setBreakpoints" && E->get() == _current_peer) {
+ continue;
+ }
+ E->get()->res_queue.push_back(event);
+ }
+}
+
Array DebugAdapterProtocol::update_breakpoints(const String &p_path, const Array &p_lines) {
Array updated_breakpoints;
+ // Add breakpoints
for (int i = 0; i < p_lines.size(); i++) {
+ EditorDebuggerNode::get_singleton()->get_default_debugger()->_set_breakpoint(p_path, p_lines[i], true);
DAP::Breakpoint breakpoint;
- breakpoint.verified = true;
- breakpoint.source.path = p_path;
- breakpoint.source.compute_checksums();
breakpoint.line = p_lines[i];
+ breakpoint.source.path = p_path;
- List<DAP::Breakpoint>::Element *E = breakpoint_list.find(breakpoint);
- if (E) {
- breakpoint.id = E->get().id;
- } else {
- breakpoint.id = breakpoint_id++;
- breakpoint_list.push_back(breakpoint);
- }
+ ERR_FAIL_COND_V(!breakpoint_list.find(breakpoint), Array());
+ updated_breakpoints.push_back(breakpoint_list.find(breakpoint)->get().to_json());
+ }
- updated_breakpoints.push_back(breakpoint.to_json());
+ // Remove breakpoints
+ for (List<DAP::Breakpoint>::Element *E = breakpoint_list.front(); E; E = E->next()) {
+ DAP::Breakpoint b = E->get();
+ if (b.source.path == p_path && !p_lines.has(b.line)) {
+ EditorDebuggerNode::get_singleton()->get_default_debugger()->_set_breakpoint(p_path, b.line, false);
+ }
}
return updated_breakpoints;
@@ -347,6 +822,29 @@ void DebugAdapterProtocol::on_debug_breaked(const bool &p_reallydid, const bool
_processing_stackdump = p_has_stackdump;
}
+void DebugAdapterProtocol::on_debug_breakpoint_toggled(const String &p_path, const int &p_line, const bool &p_enabled) {
+ DAP::Breakpoint breakpoint;
+ breakpoint.verified = true;
+ breakpoint.source.path = ProjectSettings::get_singleton()->globalize_path(p_path);
+ breakpoint.source.compute_checksums();
+ breakpoint.line = p_line;
+
+ if (p_enabled) {
+ // Add the breakpoint
+ breakpoint.id = breakpoint_id++;
+ breakpoint_list.push_back(breakpoint);
+ } else {
+ // Remove the breakpoint
+ List<DAP::Breakpoint>::Element *E = breakpoint_list.find(breakpoint);
+ if (E) {
+ breakpoint.id = E->get().id;
+ breakpoint_list.erase(E);
+ }
+ }
+
+ notify_breakpoint(breakpoint, p_enabled);
+}
+
void DebugAdapterProtocol::on_debug_stack_dump(const Array &p_stack_dump) {
if (_processing_breakpoint && !p_stack_dump.is_empty()) {
// Find existing breakpoint
@@ -424,11 +922,21 @@ void DebugAdapterProtocol::on_debug_stack_frame_var(const Array &p_data) {
variable.name = stack_var.name;
variable.value = stack_var.value;
variable.type = Variant::get_type_name(stack_var.value.get_type());
+ variable.variablesReference = parse_variant(stack_var.value);
variable_list.find(variable_id)->value().push_back(variable.to_json());
_remaining_vars--;
}
+void DebugAdapterProtocol::on_debug_data(const String &p_msg, const Array &p_data) {
+ // Ignore data that is already handled by DAP
+ if (p_msg == "debug_enter" || p_msg == "debug_exit" || p_msg == "stack_dump" || p_msg == "stack_frame_vars" || p_msg == "stack_frame_var" || p_msg == "output" || p_msg == "request_quit") {
+ return;
+ }
+
+ notify_custom_data(p_msg, p_data);
+}
+
void DebugAdapterProtocol::poll() {
if (server->is_connection_available()) {
on_client_connected();
@@ -459,6 +967,8 @@ void DebugAdapterProtocol::poll() {
}
Error DebugAdapterProtocol::start(int p_port, const IPAddress &p_bind_ip) {
+ _request_timeout = (uint64_t)_EDITOR_GET("network/debug_adapter/request_timeout");
+ _sync_breakpoints = (bool)_EDITOR_GET("network/debug_adapter/sync_breakpoints");
_initialized = true;
return server->listen(p_port, p_bind_ip);
}
@@ -484,12 +994,15 @@ DebugAdapterProtocol::DebugAdapterProtocol() {
node->get_pause_button()->connect("pressed", callable_mp(this, &DebugAdapterProtocol::on_debug_paused));
EditorDebuggerNode *debugger_node = EditorDebuggerNode::get_singleton();
+ debugger_node->connect("breakpoint_toggled", callable_mp(this, &DebugAdapterProtocol::on_debug_breakpoint_toggled));
+
debugger_node->get_default_debugger()->connect("stopped", callable_mp(this, &DebugAdapterProtocol::on_debug_stopped));
debugger_node->get_default_debugger()->connect("output", callable_mp(this, &DebugAdapterProtocol::on_debug_output));
debugger_node->get_default_debugger()->connect("breaked", callable_mp(this, &DebugAdapterProtocol::on_debug_breaked));
debugger_node->get_default_debugger()->connect("stack_dump", callable_mp(this, &DebugAdapterProtocol::on_debug_stack_dump));
debugger_node->get_default_debugger()->connect("stack_frame_vars", callable_mp(this, &DebugAdapterProtocol::on_debug_stack_frame_vars));
debugger_node->get_default_debugger()->connect("stack_frame_var", callable_mp(this, &DebugAdapterProtocol::on_debug_stack_frame_var));
+ debugger_node->get_default_debugger()->connect("debug_data", callable_mp(this, &DebugAdapterProtocol::on_debug_data));
}
DebugAdapterProtocol::~DebugAdapterProtocol() {
diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.h b/editor/debugger/debug_adapter/debug_adapter_protocol.h
index 6b542033ed..d4291992bf 100644
--- a/editor/debugger/debug_adapter/debug_adapter_protocol.h
+++ b/editor/debugger/debug_adapter/debug_adapter_protocol.h
@@ -52,12 +52,17 @@ struct DAPeer : RefCounted {
int content_length = 0;
List<Dictionary> res_queue;
int seq = 0;
+ uint64_t timestamp = 0;
// Client specific info
bool linesStartAt1 = false;
bool columnsStartAt1 = false;
bool supportsVariableType = false;
bool supportsInvalidatedEvent = false;
+ bool supportsCustomData = false;
+
+ // Internal client info
+ bool attached = false;
Error handle_data();
Error send_data();
@@ -82,20 +87,26 @@ private:
void on_debug_stopped();
void on_debug_output(const String &p_message);
void on_debug_breaked(const bool &p_reallydid, const bool &p_can_debug, const String &p_reason, const bool &p_has_stackdump);
+ void on_debug_breakpoint_toggled(const String &p_path, const int &p_line, const bool &p_enabled);
void on_debug_stack_dump(const Array &p_stack_dump);
void on_debug_stack_frame_vars(const int &p_size);
void on_debug_stack_frame_var(const Array &p_data);
+ void on_debug_data(const String &p_msg, const Array &p_data);
void reset_current_info();
void reset_ids();
void reset_stack_info();
+ int parse_variant(const Variant &p_var);
+
bool _initialized = false;
bool _processing_breakpoint = false;
bool _stepping = false;
bool _processing_stackdump = false;
int _remaining_vars = 0;
int _current_frame = 0;
+ uint64_t _request_timeout = 1000;
+ bool _sync_breakpoints = false;
String _current_request;
Ref<DAPeer> _current_peer;
@@ -108,6 +119,8 @@ private:
Map<int, Array> variable_list;
public:
+ friend class DebugAdapterServer;
+
_FORCE_INLINE_ static DebugAdapterProtocol *get_singleton() { return singleton; }
_FORCE_INLINE_ bool is_active() const { return _initialized && clients.size() > 0; }
@@ -126,8 +139,10 @@ public:
void notify_stopped_step();
void notify_continued();
void notify_output(const String &p_message);
+ void notify_custom_data(const String &p_msg, const Array &p_data);
+ void notify_breakpoint(const DAP::Breakpoint &p_breakpoint, const bool &p_enabled);
- Array update_breakpoints(const String &p_path, const Array &p_breakpoints);
+ Array update_breakpoints(const String &p_path, const Array &p_lines);
void poll();
Error start(int p_port, const IPAddress &p_bind_ip);
diff --git a/editor/debugger/debug_adapter/debug_adapter_server.cpp b/editor/debugger/debug_adapter/debug_adapter_server.cpp
index f9092a1791..4775e2c8b0 100644
--- a/editor/debugger/debug_adapter/debug_adapter_server.cpp
+++ b/editor/debugger/debug_adapter/debug_adapter_server.cpp
@@ -36,7 +36,8 @@
DebugAdapterServer::DebugAdapterServer() {
_EDITOR_DEF("network/debug_adapter/remote_port", remote_port);
- _EDITOR_DEF("network/debug_adapter/use_thread", use_thread);
+ _EDITOR_DEF("network/debug_adapter/request_timeout", protocol._request_timeout);
+ _EDITOR_DEF("network/debug_adapter/sync_breakpoints", protocol._sync_breakpoints);
}
void DebugAdapterServer::_notification(int p_what) {
@@ -50,16 +51,17 @@ void DebugAdapterServer::_notification(int p_what) {
case NOTIFICATION_INTERNAL_PROCESS: {
// The main loop can be run again during request processing, which modifies internal state of the protocol.
// Thus, "polling" is needed to prevent it from parsing other requests while the current one isn't finished.
- if (started && !use_thread && !polling) {
+ if (started && !polling) {
polling = true;
protocol.poll();
polling = false;
}
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ protocol._request_timeout = EditorSettings::get_singleton()->get("network/debug_adapter/request_timeout");
+ protocol._sync_breakpoints = EditorSettings::get_singleton()->get("network/debug_adapter/sync_breakpoints");
int remote_port = (int)_EDITOR_GET("network/debug_adapter/remote_port");
- bool use_thread = (bool)_EDITOR_GET("network/debug_adapter/use_thread");
- if (remote_port != this->remote_port || use_thread != this->use_thread) {
+ if (remote_port != this->remote_port) {
this->stop();
this->start();
}
@@ -67,35 +69,16 @@ void DebugAdapterServer::_notification(int p_what) {
}
}
-void DebugAdapterServer::thread_func(void *p_userdata) {
- DebugAdapterServer *self = static_cast<DebugAdapterServer *>(p_userdata);
- while (self->thread_running) {
- // Poll 20 times per second
- self->protocol.poll();
- OS::get_singleton()->delay_usec(50000);
- }
-}
-
void DebugAdapterServer::start() {
remote_port = (int)_EDITOR_GET("network/debug_adapter/remote_port");
- use_thread = (bool)_EDITOR_GET("network/debug_adapter/use_thread");
if (protocol.start(remote_port, IPAddress("127.0.0.1")) == OK) {
EditorNode::get_log()->add_message("--- Debug adapter server started ---", EditorLog::MSG_TYPE_EDITOR);
- if (use_thread) {
- thread_running = true;
- thread.start(DebugAdapterServer::thread_func, this);
- }
- set_process_internal(!use_thread);
+ set_process_internal(true);
started = true;
}
}
void DebugAdapterServer::stop() {
- if (use_thread) {
- ERR_FAIL_COND(!thread.is_started());
- thread_running = false;
- thread.wait_to_finish();
- }
protocol.stop();
started = false;
EditorNode::get_log()->add_message("--- Debug adapter server stopped ---", EditorLog::MSG_TYPE_EDITOR);
diff --git a/editor/debugger/debug_adapter/debug_adapter_server.h b/editor/debugger/debug_adapter/debug_adapter_server.h
index f8a38965cc..c449403cc2 100644
--- a/editor/debugger/debug_adapter/debug_adapter_server.h
+++ b/editor/debugger/debug_adapter/debug_adapter_server.h
@@ -39,11 +39,9 @@ class DebugAdapterServer : public EditorPlugin {
DebugAdapterProtocol protocol;
- Thread thread;
int remote_port = 6006;
bool thread_running = false;
bool started = false;
- bool use_thread = false;
bool polling = false;
static void thread_func(void *p_userdata);
diff --git a/editor/debugger/debug_adapter/debug_adapter_types.h b/editor/debugger/debug_adapter/debug_adapter_types.h
index aa9ab1adcd..5156c91d14 100644
--- a/editor/debugger/debug_adapter/debug_adapter_types.h
+++ b/editor/debugger/debug_adapter/debug_adapter_types.h
@@ -38,7 +38,11 @@ namespace DAP {
enum ErrorType {
UNKNOWN,
- WRONG_PATH
+ WRONG_PATH,
+ NOT_RUNNING,
+ TIMEOUT,
+ UNKNOWN_PLATFORM,
+ MISSING_DEVICE
};
struct Checksum {
@@ -118,10 +122,14 @@ struct Breakpoint {
struct BreakpointLocation {
int line;
+ int endLine = -1;
_FORCE_INLINE_ Dictionary to_json() const {
Dictionary dict;
dict["line"] = line;
+ if (endLine >= 0) {
+ dict["endLine"] = endLine;
+ }
return dict;
}
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp
index a9cb1a0131..07c02eb022 100644
--- a/editor/debugger/editor_debugger_node.cpp
+++ b/editor/debugger/editor_debugger_node.cpp
@@ -164,6 +164,7 @@ void EditorDebuggerNode::_bind_methods() {
ADD_SIGNAL(MethodInfo("set_execution", PropertyInfo("script"), PropertyInfo(Variant::INT, "line")));
ADD_SIGNAL(MethodInfo("clear_execution", PropertyInfo("script")));
ADD_SIGNAL(MethodInfo("breaked", PropertyInfo(Variant::BOOL, "reallydid"), PropertyInfo(Variant::BOOL, "can_debug")));
+ ADD_SIGNAL(MethodInfo("breakpoint_toggled", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "line"), PropertyInfo(Variant::BOOL, "enabled")));
}
EditorDebuggerRemoteObject *EditorDebuggerNode::get_inspected_remote_object() {
@@ -487,6 +488,8 @@ void EditorDebuggerNode::set_breakpoint(const String &p_path, int p_line, bool p
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
dbg->set_breakpoint(p_path, p_line, p_enabled);
});
+
+ emit_signal("breakpoint_toggled", p_path, p_line, p_enabled);
}
void EditorDebuggerNode::set_breakpoints(const String &p_path, Array p_lines) {
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index 2a5013893f..2f5bde64a9 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -296,6 +296,7 @@ Size2 ScriptEditorDebugger::get_minimum_size() const {
}
void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_data) {
+ emit_signal(SNAME("debug_data"), p_msg, p_data);
if (p_msg == "debug_enter") {
_put_msg("get_stack_dump", Array());
@@ -872,6 +873,16 @@ void ScriptEditorDebugger::_clear_execution() {
inspector->clear_stack_variables();
}
+void ScriptEditorDebugger::_set_breakpoint(const String &p_file, const int &p_line, const bool &p_enabled) {
+ Ref<Script> script = ResourceLoader::load(p_file);
+ emit_signal("set_breakpoint", script, p_line - 1, p_enabled);
+ script.unref();
+}
+
+void ScriptEditorDebugger::_clear_breakpoints() {
+ emit_signal("clear_breakpoints");
+}
+
void ScriptEditorDebugger::start(Ref<RemoteDebuggerPeer> p_peer) {
error_count = 0;
warning_count = 0;
@@ -1503,6 +1514,9 @@ void ScriptEditorDebugger::_bind_methods() {
ADD_SIGNAL(MethodInfo("stack_dump", PropertyInfo(Variant::ARRAY, "stack_dump")));
ADD_SIGNAL(MethodInfo("stack_frame_vars", PropertyInfo(Variant::INT, "num_vars")));
ADD_SIGNAL(MethodInfo("stack_frame_var", PropertyInfo(Variant::ARRAY, "data")));
+ ADD_SIGNAL(MethodInfo("debug_data", PropertyInfo(Variant::STRING, "msg"), PropertyInfo(Variant::ARRAY, "data")));
+ ADD_SIGNAL(MethodInfo("set_breakpoint", PropertyInfo("script"), PropertyInfo(Variant::INT, "line"), PropertyInfo(Variant::BOOL, "enabled")));
+ ADD_SIGNAL(MethodInfo("clear_breakpoints"));
}
void ScriptEditorDebugger::add_debugger_plugin(const Ref<Script> &p_script) {
diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h
index 499dda86da..1c1c0fd3e5 100644
--- a/editor/debugger/script_editor_debugger.h
+++ b/editor/debugger/script_editor_debugger.h
@@ -205,6 +205,9 @@ private:
void _clear_execution();
void _stop_and_notify();
+ void _set_breakpoint(const String &p_path, const int &p_line, const bool &p_enabled);
+ void _clear_breakpoints();
+
protected:
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index fee27dae58..03d1521bab 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -246,9 +246,9 @@ void EditorProperty::_notification(int p_what) {
Color color;
if (draw_red) {
- color = get_theme_color(SNAME("error_color"));
+ color = get_theme_color(is_read_only() ? SNAME("readonly_error_color") : SNAME("error_color"));
} else {
- color = get_theme_color(SNAME("property_color"));
+ color = get_theme_color(is_read_only() ? SNAME("readonly_color") : SNAME("property_color"));
}
if (label.find(".") != -1) {
color.a = 0.5; //this should be un-hacked honestly, as it's used for editor overrides
@@ -283,7 +283,7 @@ void EditorProperty::_notification(int p_what) {
check_rect = Rect2();
}
- if (can_revert) {
+ if (can_revert && !is_read_only()) {
Ref<Texture2D> reload_icon = get_theme_icon(SNAME("ReloadSmall"), SNAME("EditorIcons"));
text_limit -= reload_icon->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree")) * 2;
revert_rect = Rect2(text_limit + get_theme_constant(SNAME("hseparator"), SNAME("Tree")), (size.height - reload_icon->get_height()) / 2, reload_icon->get_width(), reload_icon->get_height());
@@ -384,8 +384,12 @@ void EditorProperty::update_property() {
GDVIRTUAL_CALL(_update_property);
}
+void EditorProperty::_set_read_only(bool p_read_only) {
+}
+
void EditorProperty::set_read_only(bool p_read_only) {
read_only = p_read_only;
+ _set_read_only(p_read_only);
}
bool EditorProperty::is_read_only() const {
@@ -1910,6 +1914,8 @@ void EditorInspector::update_tree() {
checked = p.usage & PROPERTY_USAGE_CHECKED;
}
+ bool property_read_only = (p.usage & PROPERTY_USAGE_READ_ONLY) || read_only;
+
if (p.usage & PROPERTY_USAGE_RESTART_IF_CHANGED) {
restart_request_props.insert(p.name);
}
@@ -2008,8 +2014,7 @@ void EditorInspector::update_tree() {
ep->set_checkable(checkable);
ep->set_checked(checked);
ep->set_keying(keying);
-
- ep->set_read_only(read_only);
+ ep->set_read_only(property_read_only);
ep->set_deletable(deletable_properties);
}
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index 8c522f00ef..b5d70d5454 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -115,6 +115,7 @@ private:
protected:
void _notification(int p_what);
static void _bind_methods();
+ virtual void _set_read_only(bool p_read_only);
virtual void gui_input(const Ref<InputEvent> &p_event) override;
virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override;
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index b1c546a8c0..f86a36df2f 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -2092,7 +2092,6 @@ void EditorNode::_edit_current() {
Object *prev_inspected_object = get_inspector()->get_edited_object();
- bool capitalize = bool(EDITOR_GET("interface/inspector/capitalize_properties"));
bool disable_folding = bool(EDITOR_GET("interface/inspector/disable_folding"));
bool is_resource = current_obj->is_class("Resource");
bool is_node = current_obj->is_class("Node");
@@ -2150,7 +2149,6 @@ void EditorNode::_edit_current() {
if (current_obj->is_class("EditorDebuggerRemoteObject")) {
editable_warning = TTR("This is a remote object, so changes to it won't be kept.\nPlease read the documentation relevant to debugging to better understand this workflow.");
- capitalize = false;
disable_folding = true;
} else if (current_obj->is_class("MultiNodeEdit")) {
Node *scene = get_edited_scene();
@@ -2187,10 +2185,6 @@ void EditorNode::_edit_current() {
inspector_dock->set_warning(editable_warning);
- if (get_inspector()->is_capitalize_paths_enabled() != capitalize) {
- get_inspector()->set_enable_capitalize_paths(capitalize);
- }
-
if (get_inspector()->is_using_folding() == disable_folding) {
get_inspector()->set_use_folding(!disable_folding);
}
@@ -4770,6 +4764,10 @@ bool EditorNode::ensure_main_scene(bool p_from_native) {
return true;
}
+Error EditorNode::run_play_native(int p_idx, int p_platform) {
+ return run_native->run_native(p_idx, p_platform);
+}
+
void EditorNode::run_play() {
_menu_option_confirm(RUN_STOP, true);
_run(false);
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 51d01d07ef..03c18a8972 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -898,6 +898,7 @@ public:
bool ensure_main_scene(bool p_from_native);
+ Error run_play_native(int p_idx, int p_platform);
void run_play();
void run_play_current();
void run_play_custom(const String &p_custom);
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 9507833746..1729705be5 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -51,6 +51,10 @@ EditorPropertyNil::EditorPropertyNil() {
///////////////////// TEXT /////////////////////////
+void EditorPropertyText::_set_read_only(bool p_read_only) {
+ text->set_editable(!p_read_only);
+};
+
void EditorPropertyText::_text_submitted(const String &p_string) {
if (updating) {
return;
@@ -108,6 +112,11 @@ EditorPropertyText::EditorPropertyText() {
///////////////////// MULTILINE TEXT /////////////////////////
+void EditorPropertyMultilineText::_set_read_only(bool p_read_only) {
+ text->set_editable(!p_read_only);
+ open_big_text->set_disabled(p_read_only);
+};
+
void EditorPropertyMultilineText::_big_text_changed() {
text->set_text(big_text->get_text());
emit_changed(get_edited_property(), big_text->get_text(), "", true);
@@ -180,6 +189,11 @@ EditorPropertyMultilineText::EditorPropertyMultilineText() {
///////////////////// TEXT ENUM /////////////////////////
+void EditorPropertyTextEnum::_set_read_only(bool p_read_only) {
+ option_button->set_disabled(p_read_only);
+ edit_button->set_disabled(p_read_only);
+};
+
void EditorPropertyTextEnum::_emit_changed_value(String p_string) {
if (string_name) {
emit_changed(get_edited_property(), StringName(p_string));
@@ -328,6 +342,11 @@ EditorPropertyTextEnum::EditorPropertyTextEnum() {
///////////////////// PATH /////////////////////////
+void EditorPropertyPath::_set_read_only(bool p_read_only) {
+ path->set_editable(!p_read_only);
+ path_edit->set_disabled(p_read_only);
+};
+
void EditorPropertyPath::_path_selected(const String &p_path) {
emit_changed(get_edited_property(), p_path);
update_property();
@@ -420,6 +439,10 @@ EditorPropertyPath::EditorPropertyPath() {
///////////////////// CLASS NAME /////////////////////////
+void EditorPropertyClassName::_set_read_only(bool p_read_only) {
+ property->set_disabled(p_read_only);
+};
+
void EditorPropertyClassName::setup(const String &p_base_type, const String &p_selected_type) {
base_type = p_base_type;
dialog->set_base_type(base_type);
@@ -461,6 +484,10 @@ EditorPropertyClassName::EditorPropertyClassName() {
///////////////////// MEMBER /////////////////////////
+void EditorPropertyMember::_set_read_only(bool p_read_only) {
+ property->set_disabled(p_read_only);
+};
+
void EditorPropertyMember::_property_selected(const String &p_selected) {
emit_changed(get_edited_property(), p_selected);
update_property();
@@ -557,6 +584,11 @@ EditorPropertyMember::EditorPropertyMember() {
}
///////////////////// CHECK /////////////////////////
+
+void EditorPropertyCheck::_set_read_only(bool p_read_only) {
+ checkbox->set_disabled(p_read_only);
+};
+
void EditorPropertyCheck::_checkbox_pressed() {
emit_changed(get_edited_property(), checkbox->is_pressed());
}
@@ -580,6 +612,10 @@ EditorPropertyCheck::EditorPropertyCheck() {
///////////////////// ENUM /////////////////////////
+void EditorPropertyEnum::_set_read_only(bool p_read_only) {
+ options->set_disabled(p_read_only);
+};
+
void EditorPropertyEnum::_option_selected(int p_which) {
int64_t val = options->get_item_metadata(p_which);
emit_changed(get_edited_property(), val);
@@ -628,6 +664,12 @@ EditorPropertyEnum::EditorPropertyEnum() {
///////////////////// FLAGS /////////////////////////
+void EditorPropertyFlags::_set_read_only(bool p_read_only) {
+ for (CheckBox *check : flags) {
+ check->set_disabled(p_read_only);
+ }
+};
+
void EditorPropertyFlags::_flag_toggled() {
uint32_t value = 0;
for (int i = 0; i < flags.size(); i++) {
@@ -698,6 +740,7 @@ private:
bool expanded = false;
int expansion_rows = 0;
int hovered_index = -1;
+ bool read_only = false;
Size2 get_grid_size() const {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
@@ -712,6 +755,10 @@ public:
Vector<String> names;
Vector<String> tooltips;
+ void set_read_only(bool p_read_only) {
+ read_only = p_read_only;
+ }
+
virtual Size2 get_minimum_size() const override {
Size2 min_size = get_grid_size();
@@ -736,6 +783,9 @@ public:
}
void gui_input(const Ref<InputEvent> &p_ev) override {
+ if (read_only) {
+ return;
+ }
const Ref<InputEventMouseMotion> mm = p_ev;
if (mm.is_valid()) {
bool expand_was_hovered = expand_hovered;
@@ -799,12 +849,12 @@ public:
const int bsize = (grid_size.height * 80 / 100) / 2;
const int h = bsize * 2 + 1;
- Color color = get_theme_color(SNAME("highlight_color"), SNAME("Editor"));
+ Color color = get_theme_color(read_only ? SNAME("disabled_highlight_color") : SNAME("highlight_color"), SNAME("Editor"));
- Color text_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ Color text_color = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_color"), SNAME("Editor"));
text_color.a *= 0.5;
- Color text_color_on = get_theme_color(SNAME("font_hover_color"), SNAME("Editor"));
+ Color text_color_on = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_hover_color"), SNAME("Editor"));
text_color_on.a *= 0.7;
const int vofs = (grid_size.height - h) / 2;
@@ -935,6 +985,11 @@ public:
}
};
+void EditorPropertyLayers::_set_read_only(bool p_read_only) {
+ button->set_disabled(p_read_only);
+ grid->set_read_only(p_read_only);
+};
+
void EditorPropertyLayers::_grid_changed(uint32_t p_grid) {
emit_changed(get_edited_property(), p_grid);
}
@@ -1071,6 +1126,10 @@ EditorPropertyLayers::EditorPropertyLayers() {
///////////////////// INT /////////////////////////
+void EditorPropertyInteger::_set_read_only(bool p_read_only) {
+ spin->set_read_only(p_read_only);
+};
+
void EditorPropertyInteger::_value_changed(int64_t val) {
if (setting) {
return;
@@ -1113,6 +1172,10 @@ EditorPropertyInteger::EditorPropertyInteger() {
///////////////////// OBJECT ID /////////////////////////
+void EditorPropertyObjectID::_set_read_only(bool p_read_only) {
+ edit->set_disabled(p_read_only);
+};
+
void EditorPropertyObjectID::_edit_pressed() {
emit_signal(SNAME("object_id_selected"), get_edited_property(), get_edited_object()->get(get_edited_property()));
}
@@ -1151,6 +1214,10 @@ EditorPropertyObjectID::EditorPropertyObjectID() {
///////////////////// FLOAT /////////////////////////
+void EditorPropertyFloat::_set_read_only(bool p_read_only) {
+ spin->set_read_only(p_read_only);
+};
+
void EditorPropertyFloat::_value_changed(double val) {
if (setting) {
return;
@@ -1197,7 +1264,14 @@ EditorPropertyFloat::EditorPropertyFloat() {
///////////////////// EASING /////////////////////////
+void EditorPropertyEasing::_set_read_only(bool p_read_only) {
+ spin->set_read_only(p_read_only);
+};
+
void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) {
+ if (is_read_only()) {
+ return;
+ }
const Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid()) {
if (mb->is_double_click() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
@@ -1271,12 +1345,12 @@ void EditorPropertyEasing::_draw_easing() {
const Ref<Font> f = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
- const Color font_color = get_theme_color(SNAME("font_color"), SNAME("Label"));
+ const Color font_color = get_theme_color(is_read_only() ? SNAME("font_uneditable_color") : SNAME("font_color"), SNAME("LineEdit"));
Color line_color;
if (dragging) {
line_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
} else {
- line_color = get_theme_color(SNAME("font_color"), SNAME("Label")) * Color(1, 1, 1, 0.9);
+ line_color = get_theme_color(is_read_only() ? SNAME("font_uneditable_color") : SNAME("font_color"), SNAME("LineEdit")) * Color(1, 1, 1, 0.9);
}
Vector<Point2> points;
@@ -1409,6 +1483,12 @@ EditorPropertyEasing::EditorPropertyEasing() {
///////////////////// VECTOR2 /////////////////////////
+void EditorPropertyVector2::_set_read_only(bool p_read_only) {
+ for (int i = 0; i < 2; i++) {
+ spin[i]->set_read_only(p_read_only);
+ }
+};
+
void EditorPropertyVector2::_value_changed(double val, const String &p_name) {
if (setting) {
return;
@@ -1492,6 +1572,12 @@ EditorPropertyVector2::EditorPropertyVector2(bool p_force_wide) {
///////////////////// RECT2 /////////////////////////
+void EditorPropertyRect2::_set_read_only(bool p_read_only) {
+ for (int i = 0; i < 4; i++) {
+ spin[i]->set_read_only(p_read_only);
+ }
+};
+
void EditorPropertyRect2::_value_changed(double val, const String &p_name) {
if (setting) {
return;
@@ -1589,6 +1675,12 @@ EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) {
///////////////////// VECTOR3 /////////////////////////
+void EditorPropertyVector3::_set_read_only(bool p_read_only) {
+ for (int i = 0; i < 3; i++) {
+ spin[i]->set_read_only(p_read_only);
+ }
+};
+
void EditorPropertyVector3::_value_changed(double val, const String &p_name) {
if (setting) {
return;
@@ -1701,6 +1793,12 @@ EditorPropertyVector3::EditorPropertyVector3(bool p_force_wide) {
///////////////////// VECTOR2i /////////////////////////
+void EditorPropertyVector2i::_set_read_only(bool p_read_only) {
+ for (int i = 0; i < 2; i++) {
+ spin[i]->set_read_only(p_read_only);
+ }
+};
+
void EditorPropertyVector2i::_value_changed(double val, const String &p_name) {
if (setting) {
return;
@@ -1784,6 +1882,12 @@ EditorPropertyVector2i::EditorPropertyVector2i(bool p_force_wide) {
///////////////////// RECT2i /////////////////////////
+void EditorPropertyRect2i::_set_read_only(bool p_read_only) {
+ for (int i = 0; i < 4; i++) {
+ spin[i]->set_read_only(p_read_only);
+ }
+};
+
void EditorPropertyRect2i::_value_changed(double val, const String &p_name) {
if (setting) {
return;
@@ -1881,6 +1985,12 @@ EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) {
///////////////////// VECTOR3i /////////////////////////
+void EditorPropertyVector3i::_set_read_only(bool p_read_only) {
+ for (int i = 0; i < 3; i++) {
+ spin[i]->set_read_only(p_read_only);
+ }
+};
+
void EditorPropertyVector3i::_value_changed(double val, const String &p_name) {
if (setting) {
return;
@@ -1965,6 +2075,12 @@ EditorPropertyVector3i::EditorPropertyVector3i(bool p_force_wide) {
///////////////////// PLANE /////////////////////////
+void EditorPropertyPlane::_set_read_only(bool p_read_only) {
+ for (int i = 0; i < 4; i++) {
+ spin[i]->set_read_only(p_read_only);
+ }
+};
+
void EditorPropertyPlane::_value_changed(double val, const String &p_name) {
if (setting) {
return;
@@ -2052,6 +2168,12 @@ EditorPropertyPlane::EditorPropertyPlane(bool p_force_wide) {
///////////////////// QUATERNION /////////////////////////
+void EditorPropertyQuaternion::_set_read_only(bool p_read_only) {
+ for (int i = 0; i < 4; i++) {
+ spin[i]->set_read_only(p_read_only);
+ }
+};
+
void EditorPropertyQuaternion::_value_changed(double val, const String &p_name) {
if (setting) {
return;
@@ -2136,6 +2258,12 @@ EditorPropertyQuaternion::EditorPropertyQuaternion() {
///////////////////// AABB /////////////////////////
+void EditorPropertyAABB::_set_read_only(bool p_read_only) {
+ for (int i = 0; i < 6; i++) {
+ spin[i]->set_read_only(p_read_only);
+ }
+};
+
void EditorPropertyAABB::_value_changed(double val, const String &p_name) {
if (setting) {
return;
@@ -2213,6 +2341,12 @@ EditorPropertyAABB::EditorPropertyAABB() {
///////////////////// TRANSFORM2D /////////////////////////
+void EditorPropertyTransform2D::_set_read_only(bool p_read_only) {
+ for (int i = 0; i < 6; i++) {
+ spin[i]->set_read_only(p_read_only);
+ }
+};
+
void EditorPropertyTransform2D::_value_changed(double val, const String &p_name) {
if (setting) {
return;
@@ -2289,6 +2423,12 @@ EditorPropertyTransform2D::EditorPropertyTransform2D() {
///////////////////// BASIS /////////////////////////
+void EditorPropertyBasis::_set_read_only(bool p_read_only) {
+ for (int i = 0; i < 9; i++) {
+ spin[i]->set_read_only(p_read_only);
+ }
+};
+
void EditorPropertyBasis::_value_changed(double val, const String &p_name) {
if (setting) {
return;
@@ -2371,6 +2511,12 @@ EditorPropertyBasis::EditorPropertyBasis() {
///////////////////// TRANSFORM /////////////////////////
+void EditorPropertyTransform3D::_set_read_only(bool p_read_only) {
+ for (int i = 0; i < 12; i++) {
+ spin[i]->set_read_only(p_read_only);
+ }
+};
+
void EditorPropertyTransform3D::_value_changed(double val, const String &p_name) {
if (setting) {
return;
@@ -2461,6 +2607,10 @@ EditorPropertyTransform3D::EditorPropertyTransform3D() {
////////////// COLOR PICKER //////////////////////
+void EditorPropertyColor::_set_read_only(bool p_read_only) {
+ picker->set_disabled(p_read_only);
+};
+
void EditorPropertyColor::_color_changed(const Color &p_color) {
// Cancel the color change if the current color is identical to the new one.
if (get_edited_object()->get(get_edited_property()) == p_color) {
@@ -2533,6 +2683,11 @@ EditorPropertyColor::EditorPropertyColor() {
////////////// NODE PATH //////////////////////
+void EditorPropertyNodePath::_set_read_only(bool p_read_only) {
+ assign->set_disabled(p_read_only);
+ clear->set_disabled(p_read_only);
+};
+
void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
NodePath path = p_path;
Node *base_node = nullptr;
@@ -2678,6 +2833,10 @@ EditorPropertyRID::EditorPropertyRID() {
////////////// RESOURCE //////////////////////
+void EditorPropertyResource::_set_read_only(bool p_read_only) {
+ resource_picker->set_editable(!p_read_only);
+};
+
void EditorPropertyResource::_resource_selected(const RES &p_resource) {
if (use_sub_inspector) {
bool unfold = !get_edited_object()->editor_is_section_unfolded(get_edited_property());
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 0cb21bb391..cee5ab96a7 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -59,6 +59,7 @@ class EditorPropertyText : public EditorProperty {
void _text_submitted(const String &p_string);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
public:
@@ -81,6 +82,7 @@ class EditorPropertyMultilineText : public EditorProperty {
void _open_big_text();
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -115,6 +117,7 @@ class EditorPropertyTextEnum : public EditorProperty {
void _custom_value_cancelled();
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
void _notification(int p_what);
@@ -139,6 +142,7 @@ class EditorPropertyPath : public EditorProperty {
void _path_focus_exited();
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
void _notification(int p_what);
@@ -161,6 +165,7 @@ private:
void _dialog_created();
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
public:
@@ -182,7 +187,6 @@ public:
MEMBER_PROPERTY_OF_BASE_TYPE, ///< a property of a base type
MEMBER_PROPERTY_OF_INSTANCE, ///< a property of an instance
MEMBER_PROPERTY_OF_SCRIPT, ///< a property of a script & base
-
};
private:
@@ -195,6 +199,7 @@ private:
void _property_select();
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
public:
@@ -210,6 +215,7 @@ class EditorPropertyCheck : public EditorProperty {
void _checkbox_pressed();
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
public:
@@ -224,6 +230,7 @@ class EditorPropertyEnum : public EditorProperty {
void _option_selected(int p_which);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
public:
@@ -242,6 +249,7 @@ class EditorPropertyFlags : public EditorProperty {
void _flag_toggled();
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
public:
@@ -276,6 +284,7 @@ private:
void _menu_pressed(int p_menu);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
public:
@@ -291,6 +300,7 @@ class EditorPropertyInteger : public EditorProperty {
void _value_changed(int64_t p_val);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
public:
@@ -306,6 +316,7 @@ class EditorPropertyObjectID : public EditorProperty {
void _edit_pressed();
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
public:
@@ -322,6 +333,7 @@ class EditorPropertyFloat : public EditorProperty {
void _value_changed(double p_val);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
public:
@@ -363,6 +375,7 @@ class EditorPropertyEasing : public EditorProperty {
void _notification(int p_what);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
public:
@@ -378,6 +391,7 @@ class EditorPropertyVector2 : public EditorProperty {
void _value_changed(double p_val, const String &p_name);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -394,6 +408,7 @@ class EditorPropertyRect2 : public EditorProperty {
void _value_changed(double p_val, const String &p_name);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -411,6 +426,7 @@ class EditorPropertyVector3 : public EditorProperty {
void _value_changed(double p_val, const String &p_name);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -429,6 +445,7 @@ class EditorPropertyVector2i : public EditorProperty {
void _value_changed(double p_val, const String &p_name);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -445,6 +462,7 @@ class EditorPropertyRect2i : public EditorProperty {
void _value_changed(double p_val, const String &p_name);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -461,6 +479,7 @@ class EditorPropertyVector3i : public EditorProperty {
void _value_changed(double p_val, const String &p_name);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -477,6 +496,7 @@ class EditorPropertyPlane : public EditorProperty {
void _value_changed(double p_val, const String &p_name);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -493,6 +513,7 @@ class EditorPropertyQuaternion : public EditorProperty {
void _value_changed(double p_val, const String &p_name);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -509,6 +530,7 @@ class EditorPropertyAABB : public EditorProperty {
void _value_changed(double p_val, const String &p_name);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -525,6 +547,7 @@ class EditorPropertyTransform2D : public EditorProperty {
void _value_changed(double p_val, const String &p_name);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -541,6 +564,7 @@ class EditorPropertyBasis : public EditorProperty {
void _value_changed(double p_val, const String &p_name);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -557,6 +581,7 @@ class EditorPropertyTransform3D : public EditorProperty {
void _value_changed(double p_val, const String &p_name);
protected:
+ virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
static void _bind_methods();
@@ -578,6 +603,7 @@ class EditorPropertyColor : public EditorProperty {
Color last_color;
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
public:
@@ -600,6 +626,7 @@ class EditorPropertyNodePath : public EditorProperty {
void _node_clear();
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
void _notification(int p_what);
@@ -644,6 +671,7 @@ class EditorPropertyResource : public EditorProperty {
void _update_property_bg();
protected:
+ virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
void _notification(int p_what);
diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp
index e115cd77e1..5828549bdc 100644
--- a/editor/editor_run_native.cpp
+++ b/editor/editor_run_native.cpp
@@ -52,8 +52,8 @@ void EditorRunNative::_notification(int p_what) {
small_icon.instantiate();
small_icon->create_from_image(im);
MenuButton *mb = memnew(MenuButton);
- mb->get_popup()->connect("id_pressed", callable_mp(this, &EditorRunNative::_run_native), varray(i));
- mb->connect("pressed", callable_mp(this, &EditorRunNative::_run_native), varray(-1, i));
+ mb->get_popup()->connect("id_pressed", callable_mp(this, &EditorRunNative::run_native), varray(i));
+ mb->connect("pressed", callable_mp(this, &EditorRunNative::run_native), varray(-1, i));
mb->set_icon(small_icon);
add_child(mb);
menus[i] = mb;
@@ -93,22 +93,22 @@ void EditorRunNative::_notification(int p_what) {
}
}
-void EditorRunNative::_run_native(int p_idx, int p_platform) {
+Error EditorRunNative::run_native(int p_idx, int p_platform) {
if (!EditorNode::get_singleton()->ensure_main_scene(true)) {
resume_idx = p_idx;
resume_platform = p_platform;
- return;
+ return OK;
}
Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(p_platform);
- ERR_FAIL_COND(eep.is_null());
+ ERR_FAIL_COND_V(eep.is_null(), ERR_UNAVAILABLE);
if (p_idx == -1) {
if (eep->get_options_count() == 1) {
menus[p_platform]->get_popup()->hide();
p_idx = 0;
} else {
- return;
+ return ERR_INVALID_PARAMETER;
}
}
@@ -124,7 +124,7 @@ void EditorRunNative::_run_native(int p_idx, int p_platform) {
if (preset.is_null()) {
EditorNode::get_singleton()->show_warning(TTR("No runnable export preset found for this platform.\nPlease add a runnable preset in the Export menu or define an existing preset as runnable."));
- return;
+ return ERR_UNAVAILABLE;
}
emit_signal(SNAME("native_run"), preset);
@@ -149,11 +149,11 @@ void EditorRunNative::_run_native(int p_idx, int p_platform) {
flags |= EditorExportPlatform::DEBUG_FLAG_VIEW_NAVIGATION;
}
- eep->run(preset, p_idx, flags);
+ return eep->run(preset, p_idx, flags);
}
void EditorRunNative::resume_run_native() {
- _run_native(resume_idx, resume_platform);
+ run_native(resume_idx, resume_platform);
}
void EditorRunNative::_bind_methods() {
diff --git a/editor/editor_run_native.h b/editor/editor_run_native.h
index 3516f668c6..97f6fc005a 100644
--- a/editor/editor_run_native.h
+++ b/editor/editor_run_native.h
@@ -43,13 +43,12 @@ class EditorRunNative : public HBoxContainer {
int resume_idx;
int resume_platform;
- void _run_native(int p_idx, int p_platform);
-
protected:
static void _bind_methods();
void _notification(int p_what);
public:
+ Error run_native(int p_idx, int p_platform);
bool is_deploy_debug_remote_enabled() const;
void resume_run_native();
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index 3f65b101f7..8cd636ddf3 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -221,7 +221,7 @@ void EditorSpinSlider::_draw_spin_slider() {
bool rtl = is_layout_rtl();
Vector2 size = get_size();
- Ref<StyleBox> sb = get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"));
+ Ref<StyleBox> sb = get_theme_stylebox(is_read_only() ? SNAME("read_only") : SNAME("normal"), SNAME("LineEdit"));
if (!flat) {
draw_style_box(sb, Rect2(Vector2(), size));
}
@@ -233,7 +233,7 @@ void EditorSpinSlider::_draw_spin_slider() {
int label_width = font->get_string_size(label, font_size).width;
int number_width = size.width - sb->get_minimum_size().width - label_width - sep;
- Ref<Texture2D> updown = get_theme_icon(SNAME("updown"), SNAME("SpinBox"));
+ Ref<Texture2D> updown = get_theme_icon(is_read_only() ? SNAME("updown_disabled") : SNAME("updown"), SNAME("SpinBox"));
if (get_step() == 1) {
number_width -= updown->get_width();
@@ -243,7 +243,7 @@ void EditorSpinSlider::_draw_spin_slider() {
int vofs = (size.height - font->get_height(font_size)) / 2 + font->get_ascent(font_size);
- Color fc = get_theme_color(SNAME("font_color"), SNAME("LineEdit"));
+ Color fc = get_theme_color(is_read_only() ? SNAME("font_uneditable_color") : SNAME("font_color"), SNAME("LineEdit"));
Color lc;
if (use_custom_label_color) {
lc = custom_label_color;
@@ -299,7 +299,7 @@ void EditorSpinSlider::_draw_spin_slider() {
TS->free(num_rid);
if (get_step() == 1) {
- Ref<Texture2D> updown2 = get_theme_icon(SNAME("updown"), SNAME("SpinBox"));
+ Ref<Texture2D> updown2 = get_theme_icon(is_read_only() ? SNAME("updown_disabled") : SNAME("updown"), SNAME("SpinBox"));
int updown_vofs = (size.height - updown2->get_height()) / 2;
if (rtl) {
updown_offset = sb->get_margin(SIDE_LEFT);
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 8c348731d6..8a08f4e450 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -395,12 +395,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color separator_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.1);
const Color highlight_color = Color(accent_color.r, accent_color.g, accent_color.b, 0.275);
+ const Color disabled_highlight_color = highlight_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5);
float prev_icon_saturation = theme->has_color("icon_saturation", "Editor") ? theme->get_color("icon_saturation", "Editor").r : 1.0;
theme->set_color("icon_saturation", "Editor", Color(icon_saturation, icon_saturation, icon_saturation)); //can't save single float in theme, so using color
theme->set_color("accent_color", "Editor", accent_color);
theme->set_color("highlight_color", "Editor", highlight_color);
+ theme->set_color("disabled_highlight_color", "Editor", disabled_highlight_color);
theme->set_color("base_color", "Editor", base_color);
theme->set_color("dark_color_1", "Editor", dark_color_1);
theme->set_color("dark_color_2", "Editor", dark_color_2);
@@ -424,6 +426,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Color warning_color = Color(1, 0.87, 0.4);
Color error_color = Color(1, 0.47, 0.42);
Color property_color = font_color.lerp(Color(0.5, 0.5, 0.5), 0.5);
+ Color readonly_color = property_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5);
+ Color readonly_error_color = error_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5);
if (!dark_theme) {
// Darken some colors to be readable on a light background
@@ -436,6 +440,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("warning_color", "Editor", warning_color);
theme->set_color("error_color", "Editor", error_color);
theme->set_color("property_color", "Editor", property_color);
+ theme->set_color("readonly_color", "Editor", readonly_color);
+ theme->set_color("readonly_error_color", "EditorProperty", readonly_error_color);
if (!dark_theme) {
theme->set_color("vulkan_color", "Editor", Color::hex(0xad1128ff));
@@ -696,6 +702,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("unchecked", "CheckBox", theme->get_icon("GuiUnchecked", "EditorIcons"));
theme->set_icon("radio_checked", "CheckBox", theme->get_icon("GuiRadioChecked", "EditorIcons"));
theme->set_icon("radio_unchecked", "CheckBox", theme->get_icon("GuiRadioUnchecked", "EditorIcons"));
+ theme->set_icon("checked_disabled", "CheckBox", theme->get_icon("GuiCheckedDisabled", "EditorIcons"));
+ theme->set_icon("unchecked_disabled", "CheckBox", theme->get_icon("GuiUncheckedDisabled", "EditorIcons"));
+ theme->set_icon("radio_checked_disabled", "CheckBox", theme->get_icon("GuiRadioCheckedDisabled", "EditorIcons"));
+ theme->set_icon("radio_unchecked_disabled", "CheckBox", theme->get_icon("GuiRadioUncheckedDisabled", "EditorIcons"));
theme->set_color("font_color", "CheckBox", font_color);
theme->set_color("font_hover_color", "CheckBox", font_hover_color);
@@ -742,6 +752,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons"));
theme->set_icon("radio_checked", "PopupMenu", theme->get_icon("GuiRadioChecked", "EditorIcons"));
theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon("GuiRadioUnchecked", "EditorIcons"));
+ theme->set_icon("checked_disabled", "PopupMenu", theme->get_icon("GuiCheckedDisabled", "EditorIcons"));
+ theme->set_icon("unchecked_disabled", "PopupMenu", theme->get_icon("GuiUncheckedDisabled", "EditorIcons"));
+ theme->set_icon("radio_checked_disabled", "PopupMenu", theme->get_icon("GuiRadioCheckedDisabled", "EditorIcons"));
+ theme->set_icon("radio_unchecked_disabled", "PopupMenu", theme->get_icon("GuiRadioUncheckedDisabled", "EditorIcons"));
theme->set_icon("submenu", "PopupMenu", theme->get_icon("ArrowRight", "EditorIcons"));
theme->set_icon("submenu_mirrored", "PopupMenu", theme->get_icon("ArrowLeft", "EditorIcons"));
theme->set_icon("visibility_hidden", "PopupMenu", theme->get_icon("GuiVisibilityHidden", "EditorIcons"));
@@ -803,6 +817,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("vseparation", "EditorProperty", (extra_spacing + default_margin_size) * EDSCALE);
theme->set_color("error_color", "EditorProperty", error_color);
theme->set_color("property_color", "EditorProperty", property_color);
+ theme->set_color("readonly_color", "EditorProperty", readonly_color);
+ theme->set_color("readonly_error_color", "EditorProperty", readonly_error_color);
Color inspector_section_color = font_color.lerp(Color(0.5, 0.5, 0.5), 0.35);
theme->set_color("font_color", "EditorInspectorSection", inspector_section_color);
@@ -1052,7 +1068,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("tab", "TextEdit", theme->get_icon("GuiTab", "EditorIcons"));
theme->set_icon("space", "TextEdit", theme->get_icon("GuiSpace", "EditorIcons"));
theme->set_color("font_color", "TextEdit", font_color);
- theme->set_color("font_readonly_color", "LineEdit", font_readonly_color);
+ theme->set_color("font_readonly_color", "TextEdit", font_readonly_color);
theme->set_color("caret_color", "TextEdit", font_color);
theme->set_color("selection_color", "TextEdit", selection_color);
theme->set_constant("line_spacing", "TextEdit", 4 * EDSCALE);
@@ -1201,11 +1217,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// TooltipPanel
Ref<StyleBoxFlat> style_tooltip = style_popup->duplicate();
style_tooltip->set_shadow_size(0);
- style_tooltip->set_default_margin(SIDE_LEFT, default_margin_size * EDSCALE);
+ style_tooltip->set_default_margin(SIDE_LEFT, default_margin_size * EDSCALE * 0.5);
style_tooltip->set_default_margin(SIDE_TOP, default_margin_size * EDSCALE * 0.5);
- style_tooltip->set_default_margin(SIDE_RIGHT, default_margin_size * EDSCALE);
+ style_tooltip->set_default_margin(SIDE_RIGHT, default_margin_size * EDSCALE * 0.5);
style_tooltip->set_default_margin(SIDE_BOTTOM, default_margin_size * EDSCALE * 0.5);
- style_tooltip->set_bg_color(mono_color.inverted() * Color(1, 1, 1, 0.9));
+ style_tooltip->set_bg_color(dark_color_3 * Color(0.8, 0.8, 0.8, 0.9));
style_tooltip->set_border_width_all(0);
theme->set_color("font_color", "TooltipLabel", font_hover_color);
theme->set_color("font_color_shadow", "TooltipLabel", Color(0, 0, 0, 0));
@@ -1216,6 +1232,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// SpinBox
theme->set_icon("updown", "SpinBox", theme->get_icon("GuiSpinboxUpdown", "EditorIcons"));
+ theme->set_icon("updown_disabled", "SpinBox", theme->get_icon("GuiSpinboxUpdownDisabled", "EditorIcons"));
// ProgressBar
theme->set_stylebox("bg", "ProgressBar", make_stylebox(theme->get_icon("GuiProgressBar", "EditorIcons"), 4, 4, 4, 4, 0, 0, 0, 0));
diff --git a/editor/icons/GuiCheckedDisabled.svg b/editor/icons/GuiCheckedDisabled.svg
new file mode 100644
index 0000000000..6252176241
--- /dev/null
+++ b/editor/icons/GuiCheckedDisabled.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 16 16" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.333 1c-1.289 0-2.333 1.045-2.333 2.333v9.333c0 1.289 1.044 2.334 2.333 2.334h9.333c1.289 0 2.334-1.045 2.334-2.334v-9.333c0-1.289-1.045-2.333-2.334-2.333z" fill="#808080"/><path d="m11.501 3.734-5.612 5.612-1.704-1.681-1.5 1.5 3.204 3.181 7.111-7.113z" fill="#b3b3b3"/></svg>
diff --git a/editor/icons/GuiRadioCheckedDisabled.svg b/editor/icons/GuiRadioCheckedDisabled.svg
new file mode 100644
index 0000000000..94a1fffa0b
--- /dev/null
+++ b/editor/icons/GuiRadioCheckedDisabled.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 16 16" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 8c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7" fill="#808080"/><path d="m12 8c0 2.209-1.791 4-4 4s-4-1.791-4-4 1.791-4 4-4 4 1.791 4 4" fill="#b3b3b3"/></svg>
diff --git a/editor/icons/GuiRadioUncheckedDisabled.svg b/editor/icons/GuiRadioUncheckedDisabled.svg
new file mode 100644
index 0000000000..3a75797c4d
--- /dev/null
+++ b/editor/icons/GuiRadioUncheckedDisabled.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 16 16" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 8c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7" fill="#808080" fill-opacity=".1882"/></svg>
diff --git a/editor/icons/GuiSpinboxUpdownDisabled.svg b/editor/icons/GuiSpinboxUpdownDisabled.svg
new file mode 100644
index 0000000000..332c5e7bf8
--- /dev/null
+++ b/editor/icons/GuiSpinboxUpdownDisabled.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 16 16" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.984 1.002c-.259.004-.507.108-.691.291l-4 4c-.398.383-.41 1.016-.027 1.414s1.016.41 1.414.027l.027-.027 3.293-3.293 3.293 3.293c.383.398 1.016.41 1.414.027s.41-1.016.027-1.414c-.01-.009-.018-.018-.027-.027l-4-4c-.191-.19-.452-.296-.723-.291zm4.006 7.984c-.264.006-.514.117-.697.307l-3.293 3.293-3.293-3.293c-.188-.193-.447-.303-.717-.303-.552 0-1 .448-1 1 0 .271.109.529.303.717l4 4c.391.391 1.023.391 1.414 0l4-4c.398-.383.41-1.016.027-1.414-.193-.202-.463-.313-.744-.307z" fill="#b3b3b3" fill-opacity=".7843"/></svg>
diff --git a/editor/icons/GuiUncheckedDisabled.svg b/editor/icons/GuiUncheckedDisabled.svg
new file mode 100644
index 0000000000..2b6515f9d7
--- /dev/null
+++ b/editor/icons/GuiUncheckedDisabled.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 16 16" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.333 1c-1.289 0-2.333 1.045-2.333 2.333v9.333c0 1.289 1.044 2.334 2.333 2.334h9.333c1.289 0 2.334-1.045 2.334-2.334v-9.333c0-1.289-1.045-2.333-2.334-2.333z" fill="#808080" fill-opacity=".1882"/></svg>
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index a24249b95b..7ef5993ec5 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -37,6 +37,7 @@
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "editor/debugger/editor_debugger_node.h"
+#include "editor/debugger/script_editor_debugger.h"
#include "editor/editor_node.h"
#include "editor/editor_run_script.h"
#include "editor/editor_scale.h"
@@ -479,6 +480,29 @@ void ScriptEditor::_clear_execution(REF p_script) {
}
}
+void ScriptEditor::_set_breakpoint(REF p_script, int p_line, bool p_enabled) {
+ Ref<Script> script = Object::cast_to<Script>(*p_script);
+ if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) {
+ if (edit(p_script, p_line, 0, false)) {
+ editor->push_item(p_script.ptr());
+
+ ScriptEditorBase *se = _get_current_editor();
+ if (se) {
+ se->set_breakpoint(p_line, p_enabled);
+ }
+ }
+ }
+}
+
+void ScriptEditor::_clear_breakpoints() {
+ for (int i = 0; i < tab_container->get_child_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ if (se) {
+ se->clear_breakpoints();
+ }
+ }
+}
+
ScriptEditorBase *ScriptEditor::_get_current_editor() const {
int selected = tab_container->get_current_tab();
if (selected < 0 || selected >= tab_container->get_child_count()) {
@@ -3484,6 +3508,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
debugger->connect("set_execution", callable_mp(this, &ScriptEditor::_set_execution));
debugger->connect("clear_execution", callable_mp(this, &ScriptEditor::_clear_execution));
debugger->connect("breaked", callable_mp(this, &ScriptEditor::_breaked));
+ debugger->get_default_debugger()->connect("set_breakpoint", callable_mp(this, &ScriptEditor::_set_breakpoint));
+ debugger->get_default_debugger()->connect("clear_breakpoints", callable_mp(this, &ScriptEditor::_clear_breakpoints));
menu_hb->add_spacer();
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index a57aeea5c0..e2420b4623 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -155,6 +155,8 @@ public:
virtual void tag_saved_version() = 0;
virtual void reload(bool p_soft) {}
virtual Array get_breakpoints() = 0;
+ virtual void set_breakpoint(int p_line, bool p_enabled) = 0;
+ virtual void clear_breakpoints() = 0;
virtual void add_callback(const String &p_function, PackedStringArray p_args) = 0;
virtual void update_settings() = 0;
virtual void set_debugger_active(bool p_active) = 0;
@@ -374,6 +376,8 @@ class ScriptEditor : public PanelContainer {
void _breaked(bool p_breaked, bool p_can_debug);
void _update_window_menu();
void _script_created(Ref<Script> p_script);
+ void _set_breakpoint(REF p_scrpt, int p_line, bool p_enabled);
+ void _clear_breakpoints();
ScriptEditorBase *_get_current_editor() const;
Array _get_open_script_editors() const;
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index b7d5403919..c44760807f 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -1370,6 +1370,14 @@ Array ScriptTextEditor::get_breakpoints() {
return code_editor->get_text_editor()->get_breakpointed_lines();
}
+void ScriptTextEditor::set_breakpoint(int p_line, bool p_enabled) {
+ code_editor->get_text_editor()->set_line_as_breakpoint(p_line, p_enabled);
+}
+
+void ScriptTextEditor::clear_breakpoints() {
+ code_editor->get_text_editor()->clear_breakpointed_lines();
+}
+
void ScriptTextEditor::set_tooltip_request_func(String p_method, Object *p_obj) {
code_editor->get_text_editor()->set_tooltip_request_func(p_obj, p_method, this);
}
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index 1ca6f56ea1..4208d67f17 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -225,6 +225,8 @@ public:
virtual void reload(bool p_soft) override;
virtual Array get_breakpoints() override;
+ virtual void set_breakpoint(int p_line, bool p_enabled) override;
+ virtual void clear_breakpoints() override;
virtual void add_callback(const String &p_function, PackedStringArray p_args) override;
virtual void update_settings() override;
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index 839e1c5f7a..6bf0042393 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -121,6 +121,8 @@ public:
virtual void set_edit_state(const Variant &p_state) override;
virtual Vector<String> get_functions() override;
virtual Array get_breakpoints() override;
+ virtual void set_breakpoint(int p_line, bool p_enabled) override{};
+ virtual void clear_breakpoints() override{};
virtual void goto_line(int p_line, bool p_with_error = false) override;
void goto_line_selection(int p_line, int p_begin, int p_end);
virtual void set_executing_line(int p_line) override;
diff --git a/modules/enet/enet_multiplayer_peer.cpp b/modules/enet/enet_multiplayer_peer.cpp
index 38ca38385c..7a9a780238 100644
--- a/modules/enet/enet_multiplayer_peer.cpp
+++ b/modules/enet/enet_multiplayer_peer.cpp
@@ -393,7 +393,9 @@ bool ENetMultiplayerPeer::is_server() const {
}
void ENetMultiplayerPeer::close_connection(uint32_t wait_usec) {
- ERR_FAIL_COND_MSG(!_is_active(), "The multiplayer instance isn't currently active.");
+ if (!_is_active()) {
+ return;
+ }
_pop_current_packet();
diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub
index 45354ce692..21ee39f3ed 100644
--- a/modules/gdnative/SCsub
+++ b/modules/gdnative/SCsub
@@ -17,7 +17,6 @@ env_gdnative.Prepend(CPPPATH=["#modules/gdnative/include/"])
Export("env_gdnative")
SConscript("net/SCsub")
-SConscript("xr/SCsub")
SConscript("pluginscript/SCsub")
SConscript("videodecoder/SCsub")
SConscript("text/SCsub")
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 6f76ca05dc..f2b601dc2c 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -132,6 +132,76 @@ static GDScriptParser::DataType make_builtin_meta_type(Variant::Type p_type) {
return type;
}
+bool GDScriptAnalyzer::has_member_name_conflict_in_script_class(const StringName &p_member_name, const GDScriptParser::ClassNode *p_class) {
+ if (p_class->members_indices.has(p_member_name)) {
+ int index = p_class->members_indices[p_member_name];
+ const GDScriptParser::ClassNode::Member *member = &p_class->members[index];
+
+ if (member->type == GDScriptParser::ClassNode::Member::VARIABLE ||
+ member->type == GDScriptParser::ClassNode::Member::CONSTANT ||
+ member->type == GDScriptParser::ClassNode::Member::ENUM ||
+ member->type == GDScriptParser::ClassNode::Member::ENUM_VALUE ||
+ member->type == GDScriptParser::ClassNode::Member::CLASS ||
+ member->type == GDScriptParser::ClassNode::Member::SIGNAL) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool GDScriptAnalyzer::has_member_name_conflict_in_native_type(const StringName &p_member_name, const StringName &p_native_type_string) {
+ if (ClassDB::has_signal(p_native_type_string, p_member_name)) {
+ return true;
+ }
+ if (ClassDB::has_property(p_native_type_string, p_member_name)) {
+ return true;
+ }
+ if (ClassDB::has_integer_constant(p_native_type_string, p_member_name)) {
+ return true;
+ }
+
+ return false;
+}
+
+Error GDScriptAnalyzer::check_native_member_name_conflict(const StringName &p_member_name, const GDScriptParser::Node *p_member_node, const StringName &p_native_type_string) {
+ if (has_member_name_conflict_in_native_type(p_member_name, p_native_type_string)) {
+ push_error(vformat(R"(Member "%s" redefined (original in native class '%s'))", p_member_name, p_native_type_string), p_member_node);
+ return ERR_PARSE_ERROR;
+ }
+
+ if (class_exists(p_member_name)) {
+ push_error(vformat(R"(The class "%s" shadows a native class.)", p_member_name), p_member_node);
+ return ERR_PARSE_ERROR;
+ }
+
+ return OK;
+}
+
+Error GDScriptAnalyzer::check_class_member_name_conflict(const GDScriptParser::ClassNode *p_class_node, const StringName &p_member_name, const GDScriptParser::Node *p_member_node) {
+ const GDScriptParser::DataType *current_data_type = &p_class_node->base_type;
+ while (current_data_type && current_data_type->kind == GDScriptParser::DataType::Kind::CLASS) {
+ GDScriptParser::ClassNode *current_class_node = current_data_type->class_type;
+ if (has_member_name_conflict_in_script_class(p_member_name, current_class_node)) {
+ push_error(vformat(R"(The member "%s" already exists in a parent class.)", p_member_name),
+ p_member_node);
+ return ERR_PARSE_ERROR;
+ }
+ current_data_type = &current_class_node->base_type;
+ }
+
+ if (current_data_type && current_data_type->kind == GDScriptParser::DataType::Kind::NATIVE) {
+ if (current_data_type->native_type != StringName("")) {
+ return check_native_member_name_conflict(
+ p_member_name,
+ p_member_node,
+ current_data_type->native_type);
+ }
+ }
+
+ return OK;
+}
+
Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class, bool p_recursive) {
if (p_class->base_type.is_set()) {
// Already resolved
@@ -525,6 +595,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
switch (member.type) {
case GDScriptParser::ClassNode::Member::VARIABLE: {
+ check_class_member_name_conflict(p_class, member.variable->identifier->name, member.variable);
+
GDScriptParser::DataType datatype;
datatype.kind = GDScriptParser::DataType::VARIANT;
datatype.type_source = GDScriptParser::DataType::UNDETECTED;
@@ -598,6 +670,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
}
} break;
case GDScriptParser::ClassNode::Member::CONSTANT: {
+ check_class_member_name_conflict(p_class, member.constant->identifier->name, member.constant);
+
reduce_expression(member.constant->initializer);
GDScriptParser::DataType specified_type;
@@ -647,6 +721,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
}
} break;
case GDScriptParser::ClassNode::Member::SIGNAL: {
+ check_class_member_name_conflict(p_class, member.signal->identifier->name, member.signal);
+
for (int j = 0; j < member.signal->parameters.size(); j++) {
GDScriptParser::DataType signal_type = resolve_datatype(member.signal->parameters[j]->datatype_specifier);
signal_type.is_meta_type = false;
@@ -666,6 +742,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
}
} break;
case GDScriptParser::ClassNode::Member::ENUM: {
+ check_class_member_name_conflict(p_class, member.m_enum->identifier->name, member.m_enum);
+
GDScriptParser::DataType enum_type;
enum_type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
enum_type.kind = GDScriptParser::DataType::ENUM;
@@ -717,6 +795,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
break;
case GDScriptParser::ClassNode::Member::ENUM_VALUE: {
if (member.enum_value.custom_value) {
+ check_class_member_name_conflict(p_class, member.enum_value.identifier->name, member.enum_value.custom_value);
+
current_enum = member.enum_value.parent_enum;
reduce_expression(member.enum_value.custom_value);
current_enum = nullptr;
@@ -730,6 +810,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
member.enum_value.resolved = true;
}
} else {
+ check_class_member_name_conflict(p_class, member.enum_value.identifier->name, member.enum_value.parent_enum);
+
if (member.enum_value.index > 0) {
member.enum_value.value = member.enum_value.parent_enum->values[member.enum_value.index - 1].value + 1;
} else {
@@ -742,7 +824,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
p_class->members.write[i].enum_value = member.enum_value;
} break;
case GDScriptParser::ClassNode::Member::CLASS:
- break; // Done later.
+ check_class_member_name_conflict(p_class, member.m_class->identifier->name, member.m_class);
+ break;
case GDScriptParser::ClassNode::Member::UNDEFINED:
ERR_PRINT("Trying to resolve undefined member.");
break;
@@ -2411,6 +2494,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
case GDScriptParser::ClassNode::Member::VARIABLE:
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_VARIABLE;
p_identifier->variable_source = member.variable;
+ member.variable->usages += 1;
break;
case GDScriptParser::ClassNode::Member::FUNCTION:
resolve_function_signature(member.function);
diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h
index 32bf049fa1..2e17e15452 100644
--- a/modules/gdscript/gdscript_analyzer.h
+++ b/modules/gdscript/gdscript_analyzer.h
@@ -44,6 +44,12 @@ class GDScriptAnalyzer {
const GDScriptParser::EnumNode *current_enum = nullptr;
List<const GDScriptParser::LambdaNode *> lambda_stack;
+ // Tests for detecting invalid overloading of script members
+ static _FORCE_INLINE_ bool has_member_name_conflict_in_script_class(const StringName &p_name, const GDScriptParser::ClassNode *p_current_class_node);
+ static _FORCE_INLINE_ bool has_member_name_conflict_in_native_type(const StringName &p_name, const StringName &p_native_type_string);
+ Error check_native_member_name_conflict(const StringName &p_member_name, const GDScriptParser::Node *p_member_node, const StringName &p_native_type_string);
+ Error check_class_member_name_conflict(const GDScriptParser::ClassNode *p_class_node, const StringName &p_member_name, const GDScriptParser::Node *p_member_node);
+
Error resolve_inheritance(GDScriptParser::ClassNode *p_class, bool p_recursive = true);
GDScriptParser::DataType resolve_datatype(GDScriptParser::TypeNode *p_type);
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index ddf4f281b4..e5cbcc545f 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -2186,6 +2186,13 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
p_script->tool = parser->is_tool();
p_script->name = p_class->identifier ? p_class->identifier->name : "";
+ if (p_script->name != "") {
+ if (ClassDB::class_exists(p_script->name) && ClassDB::is_class_exposed(p_script->name)) {
+ _set_error("The class '" + p_script->name + "' shadows a native class", p_class);
+ return ERR_ALREADY_EXISTS;
+ }
+ }
+
Ref<GDScriptNativeClass> native;
GDScriptDataType base_type = _gdtype_from_datatype(p_class->base_type);
@@ -2337,28 +2344,6 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
const GDScriptParser::SignalNode *signal = member.signal;
StringName name = signal->identifier->name;
- GDScript *c = p_script;
-
- while (c) {
- if (c->_signals.has(name)) {
- _set_error("Signal '" + name + "' redefined (in current or parent class)", p_class);
- return ERR_ALREADY_EXISTS;
- }
-
- if (c->base.is_valid()) {
- c = c->base.ptr();
- } else {
- c = nullptr;
- }
- }
-
- if (native.is_valid()) {
- if (ClassDB::has_signal(native->get_name(), name)) {
- _set_error("Signal '" + name + "' redefined (original in native class '" + String(native->get_name()) + "')", p_class);
- return ERR_ALREADY_EXISTS;
- }
- }
-
Vector<StringName> parameters_names;
parameters_names.resize(signal->parameters.size());
for (int j = 0; j < signal->parameters.size(); j++) {
diff --git a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs
index 9b7b422276..2bf1cb7a18 100644
--- a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs
@@ -12,12 +12,16 @@ namespace GodotTools.BuildLogger
public string Parameters { get; set; }
public LoggerVerbosity Verbosity { get; set; }
+ private StreamWriter _logStreamWriter;
+ private StreamWriter _issuesStreamWriter;
+ private int _indent;
+
public void Initialize(IEventSource eventSource)
{
if (null == Parameters)
throw new LoggerException("Log directory parameter not specified.");
- var parameters = Parameters.Split(new[] { ';' });
+ string[] parameters = Parameters.Split(new[] { ';' });
string logDir = parameters[0];
@@ -35,8 +39,8 @@ namespace GodotTools.BuildLogger
if (!Directory.Exists(logDir))
Directory.CreateDirectory(logDir);
- logStreamWriter = new StreamWriter(logFile);
- issuesStreamWriter = new StreamWriter(issuesFile);
+ _logStreamWriter = new StreamWriter(logFile);
+ _issuesStreamWriter = new StreamWriter(issuesFile);
}
catch (Exception ex)
{
@@ -66,12 +70,12 @@ namespace GodotTools.BuildLogger
private void eventSource_ProjectStarted(object sender, ProjectStartedEventArgs e)
{
WriteLine(e.Message);
- indent++;
+ _indent++;
}
private void eventSource_ProjectFinished(object sender, ProjectFinishedEventArgs e)
{
- indent--;
+ _indent--;
WriteLine(e.Message);
}
@@ -87,7 +91,7 @@ namespace GodotTools.BuildLogger
string errorLine = $@"error,{e.File.CsvEscape()},{e.LineNumber},{e.ColumnNumber}," +
$"{e.Code?.CsvEscape() ?? string.Empty},{e.Message.CsvEscape()}," +
$"{e.ProjectFile?.CsvEscape() ?? string.Empty}";
- issuesStreamWriter.WriteLine(errorLine);
+ _issuesStreamWriter.WriteLine(errorLine);
}
private void eventSource_WarningRaised(object sender, BuildWarningEventArgs e)
@@ -102,7 +106,7 @@ namespace GodotTools.BuildLogger
string warningLine = $@"warning,{e.File.CsvEscape()},{e.LineNumber},{e.ColumnNumber}," +
$"{e.Code?.CsvEscape() ?? string.Empty},{e.Message.CsvEscape()}," +
$"{e.ProjectFile?.CsvEscape() ?? string.Empty}";
- issuesStreamWriter.WriteLine(warningLine);
+ _issuesStreamWriter.WriteLine(warningLine);
}
private void eventSource_MessageRaised(object sender, BuildMessageEventArgs e)
@@ -136,28 +140,24 @@ namespace GodotTools.BuildLogger
private void WriteLine(string line)
{
- for (int i = indent; i > 0; i--)
+ for (int i = _indent; i > 0; i--)
{
- logStreamWriter.Write("\t");
+ _logStreamWriter.Write("\t");
}
- logStreamWriter.WriteLine(line);
+ _logStreamWriter.WriteLine(line);
}
public void Shutdown()
{
- logStreamWriter.Close();
- issuesStreamWriter.Close();
+ _logStreamWriter.Close();
+ _issuesStreamWriter.Close();
}
private bool IsVerbosityAtLeast(LoggerVerbosity checkVerbosity)
{
return Verbosity >= checkVerbosity;
}
-
- private StreamWriter logStreamWriter;
- private StreamWriter issuesStreamWriter;
- private int indent;
}
internal static class StringExtensions
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/ProcessExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.Core/ProcessExtensions.cs
index 43d40f2ad9..a4d7dedbd5 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Core/ProcessExtensions.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/ProcessExtensions.cs
@@ -7,7 +7,7 @@ namespace GodotTools.Core
{
public static class ProcessExtensions
{
- public static async Task WaitForExitAsync(this Process process, CancellationToken cancellationToken = default(CancellationToken))
+ public static async Task WaitForExitAsync(this Process process, CancellationToken cancellationToken = default)
{
var tcs = new TaskCompletionSource<bool>();
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
index b217ae4bf7..60a4f297c9 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
@@ -7,6 +7,8 @@ namespace GodotTools.Core
{
public static class StringExtensions
{
+ private static readonly string _driveRoot = Path.GetPathRoot(Environment.CurrentDirectory);
+
public static string RelativeToPath(this string path, string dir)
{
// Make sure the directory ends with a path separator
@@ -49,13 +51,11 @@ namespace GodotTools.Core
return Path.DirectorySeparatorChar + path;
}
- private static readonly string DriveRoot = Path.GetPathRoot(Environment.CurrentDirectory);
-
public static bool IsAbsolutePath(this string path)
{
return path.StartsWith("/", StringComparison.Ordinal) ||
path.StartsWith("\\", StringComparison.Ordinal) ||
- path.StartsWith(DriveRoot, StringComparison.Ordinal);
+ path.StartsWith(_driveRoot, StringComparison.Ordinal);
}
public static string ToSafeDirName(this string dirName, bool allowDirSeparator = false)
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
index 284e94810a..355b21d63a 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
@@ -9,15 +9,40 @@ namespace GodotTools.ProjectEditor
{
public class DotNetSolution
{
- private string directoryPath;
- private readonly Dictionary<string, ProjectInfo> projects = new Dictionary<string, ProjectInfo>();
+ private const string _solutionTemplate =
+@"Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+{0}
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+{1}
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+{2}
+ EndGlobalSection
+EndGlobal
+";
+
+ private const string _projectDeclaration =
+@"Project(""{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}"") = ""{0}"", ""{1}"", ""{{{2}}}""
+EndProject";
+
+ private const string _solutionPlatformsConfig =
+@" {0}|Any CPU = {0}|Any CPU";
+
+ private const string _projectPlatformsConfig =
+@" {{{0}}}.{1}|Any CPU.ActiveCfg = {1}|Any CPU
+ {{{0}}}.{1}|Any CPU.Build.0 = {1}|Any CPU";
+
+ private string _directoryPath;
+ private readonly Dictionary<string, ProjectInfo> _projects = new Dictionary<string, ProjectInfo>();
public string Name { get; }
public string DirectoryPath
{
- get => directoryPath;
- set => directoryPath = value.IsAbsolutePath() ? value : Path.GetFullPath(value);
+ get => _directoryPath;
+ set => _directoryPath = value.IsAbsolutePath() ? value : Path.GetFullPath(value);
}
public class ProjectInfo
@@ -29,22 +54,22 @@ namespace GodotTools.ProjectEditor
public void AddNewProject(string name, ProjectInfo projectInfo)
{
- projects[name] = projectInfo;
+ _projects[name] = projectInfo;
}
public bool HasProject(string name)
{
- return projects.ContainsKey(name);
+ return _projects.ContainsKey(name);
}
public ProjectInfo GetProjectInfo(string name)
{
- return projects[name];
+ return _projects[name];
}
public bool RemoveProject(string name)
{
- return projects.Remove(name);
+ return _projects.Remove(name);
}
public void Save()
@@ -58,7 +83,7 @@ namespace GodotTools.ProjectEditor
bool isFirstProject = true;
- foreach (var pair in projects)
+ foreach (var pair in _projects)
{
string name = pair.Key;
ProjectInfo projectInfo = pair.Value;
@@ -66,7 +91,7 @@ namespace GodotTools.ProjectEditor
if (!isFirstProject)
projectsDecl += "\n";
- projectsDecl += string.Format(ProjectDeclaration,
+ projectsDecl += string.Format(_projectDeclaration,
name, projectInfo.PathRelativeToSolution.Replace("/", "\\"), projectInfo.Guid);
for (int i = 0; i < projectInfo.Configs.Count; i++)
@@ -79,15 +104,15 @@ namespace GodotTools.ProjectEditor
projPlatformsCfg += "\n";
}
- slnPlatformsCfg += string.Format(SolutionPlatformsConfig, config);
- projPlatformsCfg += string.Format(ProjectPlatformsConfig, projectInfo.Guid, config);
+ slnPlatformsCfg += string.Format(_solutionPlatformsConfig, config);
+ projPlatformsCfg += string.Format(_projectPlatformsConfig, projectInfo.Guid, config);
}
isFirstProject = false;
}
string solutionPath = Path.Combine(DirectoryPath, Name + ".sln");
- string content = string.Format(SolutionTemplate, projectsDecl, slnPlatformsCfg, projPlatformsCfg);
+ string content = string.Format(_solutionTemplate, projectsDecl, slnPlatformsCfg, projPlatformsCfg);
File.WriteAllText(solutionPath, content, Encoding.UTF8); // UTF-8 with BOM
}
@@ -97,37 +122,12 @@ namespace GodotTools.ProjectEditor
Name = name;
}
- const string SolutionTemplate =
-@"Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-{0}
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
-{1}
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
-{2}
- EndGlobalSection
-EndGlobal
-";
-
- const string ProjectDeclaration =
-@"Project(""{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}"") = ""{0}"", ""{1}"", ""{{{2}}}""
-EndProject";
-
- const string SolutionPlatformsConfig =
-@" {0}|Any CPU = {0}|Any CPU";
-
- const string ProjectPlatformsConfig =
-@" {{{0}}}.{1}|Any CPU.ActiveCfg = {1}|Any CPU
- {{{0}}}.{1}|Any CPU.Build.0 = {1}|Any CPU";
-
public static void MigrateFromOldConfigNames(string slnPath)
{
if (!File.Exists(slnPath))
return;
- var input = File.ReadAllText(slnPath);
+ string input = File.ReadAllText(slnPath);
if (!Regex.IsMatch(input, Regex.Escape("Tools|Any CPU")))
return;
@@ -151,7 +151,7 @@ EndProject";
};
var regex = new Regex(string.Join("|", dict.Keys.Select(Regex.Escape)));
- var result = regex.Replace(input, m => dict[m.Value]);
+ string result = regex.Replace(input, m => dict[m.Value]);
if (result != input)
{
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/IdentifierUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/IdentifierUtils.cs
index ed77076df3..31363df9ef 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/IdentifierUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/IdentifierUtils.cs
@@ -91,7 +91,7 @@ namespace GodotTools.ProjectEditor
return identifier;
}
- static bool IsKeyword(string value, bool anyDoubleUnderscore)
+ private static bool IsKeyword(string value, bool anyDoubleUnderscore)
{
// Identifiers that start with double underscore are meant to be used for reserved keywords.
// Only existing keywords are enforced, but it may be useful to forbid any identifier
@@ -103,14 +103,14 @@ namespace GodotTools.ProjectEditor
}
else
{
- if (DoubleUnderscoreKeywords.Contains(value))
+ if (_doubleUnderscoreKeywords.Contains(value))
return true;
}
- return Keywords.Contains(value);
+ return _keywords.Contains(value);
}
- private static readonly HashSet<string> DoubleUnderscoreKeywords = new HashSet<string>
+ private static readonly HashSet<string> _doubleUnderscoreKeywords = new HashSet<string>
{
"__arglist",
"__makeref",
@@ -118,7 +118,7 @@ namespace GodotTools.ProjectEditor
"__refvalue",
};
- private static readonly HashSet<string> Keywords = new HashSet<string>
+ private static readonly HashSet<string> _keywords = new HashSet<string>
{
"as",
"do",
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs
index 27737c3da0..28bf57dc21 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs
@@ -13,7 +13,8 @@ namespace GodotTools.Build
public string[] Targets { get; }
public string Configuration { get; }
public bool Restore { get; }
- public Array<string> CustomProperties { get; } = new Array<string>(); // TODO Use List once we have proper serialization
+ // TODO Use List once we have proper serialization
+ public Array<string> CustomProperties { get; } = new Array<string>();
public string LogsDirPath => Path.Combine(GodotSharpDirs.BuildLogsDirs, $"{Solution.MD5Text()}_{Configuration}");
@@ -32,12 +33,12 @@ namespace GodotTools.Build
unchecked
{
int hash = 17;
- hash = hash * 29 + Solution.GetHashCode();
- hash = hash * 29 + Targets.GetHashCode();
- hash = hash * 29 + Configuration.GetHashCode();
- hash = hash * 29 + Restore.GetHashCode();
- hash = hash * 29 + CustomProperties.GetHashCode();
- hash = hash * 29 + LogsDirPath.GetHashCode();
+ hash = (hash * 29) + Solution.GetHashCode();
+ hash = (hash * 29) + Targets.GetHashCode();
+ hash = (hash * 29) + Configuration.GetHashCode();
+ hash = (hash * 29) + Restore.GetHashCode();
+ hash = (hash * 29) + CustomProperties.GetHashCode();
+ hash = (hash * 29) + LogsDirPath.GetHashCode();
return hash;
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
index 2b6f972529..21bff70b15 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
@@ -32,7 +32,7 @@ namespace GodotTools.Build
private static void RemoveOldIssuesFile(BuildInfo buildInfo)
{
- var issuesFile = GetIssuesFilePath(buildInfo);
+ string issuesFile = GetIssuesFilePath(buildInfo);
if (!File.Exists(issuesFile))
return;
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
index 25e260beed..b53347fc4c 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
@@ -22,14 +22,6 @@ namespace GodotTools.Build
public string ProjectFile { get; set; }
}
- private readonly Array<BuildIssue> issues = new Array<BuildIssue>(); // TODO Use List once we have proper serialization
- private ItemList issuesList;
- private TextEdit buildLog;
- private PopupMenu issuesListContextMenu;
-
- private readonly object pendingBuildLogTextLock = new object();
- [NotNull] private string pendingBuildLogText = string.Empty;
-
[Signal] public event Action BuildStateChanged;
public bool HasBuildExited { get; private set; } = false;
@@ -60,13 +52,21 @@ namespace GodotTools.Build
}
}
- private BuildInfo BuildInfo { get; set; }
-
public bool LogVisible
{
- set => buildLog.Visible = value;
+ set => _buildLog.Visible = value;
}
+ // TODO Use List once we have proper serialization.
+ private readonly Array<BuildIssue> _issues = new Array<BuildIssue>();
+ private ItemList _issuesList;
+ private PopupMenu _issuesListContextMenu;
+ private TextEdit _buildLog;
+ private BuildInfo _buildInfo;
+
+ private readonly object _pendingBuildLogTextLock = new object();
+ [NotNull] private string _pendingBuildLogText = string.Empty;
+
private void LoadIssuesFromFile(string csvFile)
{
using (var file = new Godot.File())
@@ -107,7 +107,7 @@ namespace GodotTools.Build
else
ErrorCount += 1;
- issues.Add(issue);
+ _issues.Add(issue);
}
}
finally
@@ -119,21 +119,21 @@ namespace GodotTools.Build
private void IssueActivated(int idx)
{
- if (idx < 0 || idx >= issuesList.GetItemCount())
+ if (idx < 0 || idx >= _issuesList.GetItemCount())
throw new IndexOutOfRangeException("Item list index out of range");
// Get correct issue idx from issue list
- int issueIndex = (int)(long)issuesList.GetItemMetadata(idx);
+ int issueIndex = (int)(long)_issuesList.GetItemMetadata(idx);
- if (issueIndex < 0 || issueIndex >= issues.Count)
+ if (issueIndex < 0 || issueIndex >= _issues.Count)
throw new IndexOutOfRangeException("Issue index out of range");
- BuildIssue issue = issues[issueIndex];
+ BuildIssue issue = _issues[issueIndex];
if (string.IsNullOrEmpty(issue.ProjectFile) && string.IsNullOrEmpty(issue.File))
return;
- string projectDir = issue.ProjectFile.Length > 0 ? issue.ProjectFile.GetBaseDir() : BuildInfo.Solution.GetBaseDir();
+ string projectDir = issue.ProjectFile.Length > 0 ? issue.ProjectFile.GetBaseDir() : _buildInfo.Solution.GetBaseDir();
string file = Path.Combine(projectDir.SimplifyGodotPath(), issue.File.SimplifyGodotPath());
@@ -153,14 +153,14 @@ namespace GodotTools.Build
public void UpdateIssuesList()
{
- issuesList.Clear();
+ _issuesList.Clear();
using (var warningIcon = GetThemeIcon("Warning", "EditorIcons"))
using (var errorIcon = GetThemeIcon("Error", "EditorIcons"))
{
- for (int i = 0; i < issues.Count; i++)
+ for (int i = 0; i < _issues.Count; i++)
{
- BuildIssue issue = issues[i];
+ BuildIssue issue = _issues[i];
if (!(issue.Warning ? WarningsVisible : ErrorsVisible))
continue;
@@ -191,11 +191,11 @@ namespace GodotTools.Build
int lineBreakIdx = text.IndexOf("\n", StringComparison.Ordinal);
string itemText = lineBreakIdx == -1 ? text : text.Substring(0, lineBreakIdx);
- issuesList.AddItem(itemText, issue.Warning ? warningIcon : errorIcon);
+ _issuesList.AddItem(itemText, issue.Warning ? warningIcon : errorIcon);
- int index = issuesList.GetItemCount() - 1;
- issuesList.SetItemTooltip(index, tooltip);
- issuesList.SetItemMetadata(index, i);
+ int index = _issuesList.GetItemCount() - 1;
+ _issuesList.SetItemTooltip(index, tooltip);
+ _issuesList.SetItemMetadata(index, i);
}
}
}
@@ -205,12 +205,12 @@ namespace GodotTools.Build
HasBuildExited = true;
BuildResult = Build.BuildResult.Error;
- issuesList.Clear();
+ _issuesList.Clear();
var issue = new BuildIssue {Message = cause, Warning = false};
ErrorCount += 1;
- issues.Add(issue);
+ _issues.Add(issue);
UpdateIssuesList();
@@ -219,13 +219,13 @@ namespace GodotTools.Build
private void BuildStarted(BuildInfo buildInfo)
{
- BuildInfo = buildInfo;
+ _buildInfo = buildInfo;
HasBuildExited = false;
- issues.Clear();
+ _issues.Clear();
WarningCount = 0;
ErrorCount = 0;
- buildLog.Text = string.Empty;
+ _buildLog.Text = string.Empty;
UpdateIssuesList();
@@ -237,7 +237,7 @@ namespace GodotTools.Build
HasBuildExited = true;
BuildResult = result;
- LoadIssuesFromFile(Path.Combine(BuildInfo.LogsDirPath, BuildManager.MsBuildIssuesFileName));
+ LoadIssuesFromFile(Path.Combine(_buildInfo.LogsDirPath, BuildManager.MsBuildIssuesFileName));
UpdateIssuesList();
@@ -246,46 +246,46 @@ namespace GodotTools.Build
private void UpdateBuildLogText()
{
- lock (pendingBuildLogTextLock)
+ lock (_pendingBuildLogTextLock)
{
- buildLog.Text += pendingBuildLogText;
- pendingBuildLogText = string.Empty;
+ _buildLog.Text += _pendingBuildLogText;
+ _pendingBuildLogText = string.Empty;
ScrollToLastNonEmptyLogLine();
}
}
private void StdOutputReceived(string text)
{
- lock (pendingBuildLogTextLock)
+ lock (_pendingBuildLogTextLock)
{
- if (pendingBuildLogText.Length == 0)
+ if (_pendingBuildLogText.Length == 0)
CallDeferred(nameof(UpdateBuildLogText));
- pendingBuildLogText += text + "\n";
+ _pendingBuildLogText += text + "\n";
}
}
private void StdErrorReceived(string text)
{
- lock (pendingBuildLogTextLock)
+ lock (_pendingBuildLogTextLock)
{
- if (pendingBuildLogText.Length == 0)
+ if (_pendingBuildLogText.Length == 0)
CallDeferred(nameof(UpdateBuildLogText));
- pendingBuildLogText += text + "\n";
+ _pendingBuildLogText += text + "\n";
}
}
private void ScrollToLastNonEmptyLogLine()
{
int line;
- for (line = buildLog.GetLineCount(); line > 0; line--)
+ for (line = _buildLog.GetLineCount(); line > 0; line--)
{
- string lineText = buildLog.GetLine(line);
+ string lineText = _buildLog.GetLine(line);
if (!string.IsNullOrEmpty(lineText) || !string.IsNullOrEmpty(lineText?.Trim()))
break;
}
- buildLog.SetCaretLine(line);
+ _buildLog.SetCaretLine(line);
}
public void RestartBuild()
@@ -318,11 +318,11 @@ namespace GodotTools.Build
// We don't allow multi-selection but just in case that changes later...
string text = null;
- foreach (int issueIndex in issuesList.GetSelectedItems())
+ foreach (int issueIndex in _issuesList.GetSelectedItems())
{
if (text != null)
text += "\n";
- text += issuesList.GetItemText(issueIndex);
+ text += _issuesList.GetItemText(issueIndex);
}
if (text != null)
@@ -338,20 +338,20 @@ namespace GodotTools.Build
{
_ = index; // Unused
- issuesListContextMenu.Clear();
- issuesListContextMenu.Size = new Vector2i(1, 1);
+ _issuesListContextMenu.Clear();
+ _issuesListContextMenu.Size = new Vector2i(1, 1);
- if (issuesList.IsAnythingSelected())
+ if (_issuesList.IsAnythingSelected())
{
// Add menu entries for the selected item
- issuesListContextMenu.AddIconItem(GetThemeIcon("ActionCopy", "EditorIcons"),
+ _issuesListContextMenu.AddIconItem(GetThemeIcon("ActionCopy", "EditorIcons"),
label: "Copy Error".TTR(), (int)IssuesContextMenuOption.Copy);
}
- if (issuesListContextMenu.GetItemCount() > 0)
+ if (_issuesListContextMenu.GetItemCount() > 0)
{
- issuesListContextMenu.Position = (Vector2i)(issuesList.RectGlobalPosition + atPosition);
- issuesListContextMenu.Popup();
+ _issuesListContextMenu.Position = (Vector2i)(_issuesList.RectGlobalPosition + atPosition);
+ _issuesListContextMenu.Popup();
}
}
@@ -368,27 +368,27 @@ namespace GodotTools.Build
};
AddChild(hsc);
- issuesList = new ItemList
+ _issuesList = new ItemList
{
SizeFlagsVertical = (int)SizeFlags.ExpandFill,
SizeFlagsHorizontal = (int)SizeFlags.ExpandFill // Avoid being squashed by the build log
};
- issuesList.ItemActivated += IssueActivated;
- issuesList.AllowRmbSelect = true;
- issuesList.ItemRmbSelected += IssuesListRmbSelected;
- hsc.AddChild(issuesList);
+ _issuesList.ItemActivated += IssueActivated;
+ _issuesList.AllowRmbSelect = true;
+ _issuesList.ItemRmbSelected += IssuesListRmbSelected;
+ hsc.AddChild(_issuesList);
- issuesListContextMenu = new PopupMenu();
- issuesListContextMenu.IdPressed += IssuesListContextOptionPressed;
- issuesList.AddChild(issuesListContextMenu);
+ _issuesListContextMenu = new PopupMenu();
+ _issuesListContextMenu.IdPressed += IssuesListContextOptionPressed;
+ _issuesList.AddChild(_issuesListContextMenu);
- buildLog = new TextEdit
+ _buildLog = new TextEdit
{
Editable = false,
SizeFlagsVertical = (int)SizeFlags.ExpandFill,
SizeFlagsHorizontal = (int)SizeFlags.ExpandFill // Avoid being squashed by the issues list
};
- hsc.AddChild(buildLog);
+ hsc.AddChild(_buildLog);
AddBuildEventListeners();
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
index 5f35d506de..e9cf7911be 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
@@ -11,10 +11,10 @@ namespace GodotTools.Build
{
public BuildOutputView BuildOutputView { get; private set; }
- private MenuButton buildMenuBtn;
- private Button errorsBtn;
- private Button warningsBtn;
- private Button viewLogBtn;
+ private MenuButton _buildMenuBtn;
+ private Button _errorsBtn;
+ private Button _warningsBtn;
+ private Button _viewLogBtn;
private void WarningsToggled(bool pressed)
{
@@ -132,16 +132,16 @@ namespace GodotTools.Build
var toolBarHBox = new HBoxContainer { SizeFlagsHorizontal = (int)SizeFlags.ExpandFill };
AddChild(toolBarHBox);
- buildMenuBtn = new MenuButton { Text = "Build", Icon = GetThemeIcon("Play", "EditorIcons") };
- toolBarHBox.AddChild(buildMenuBtn);
+ _buildMenuBtn = new MenuButton { Text = "Build", Icon = GetThemeIcon("Play", "EditorIcons") };
+ toolBarHBox.AddChild(_buildMenuBtn);
- var buildMenu = buildMenuBtn.GetPopup();
+ var buildMenu = _buildMenuBtn.GetPopup();
buildMenu.AddItem("Build Solution".TTR(), (int)BuildMenuOptions.BuildSolution);
buildMenu.AddItem("Rebuild Solution".TTR(), (int)BuildMenuOptions.RebuildSolution);
buildMenu.AddItem("Clean Solution".TTR(), (int)BuildMenuOptions.CleanSolution);
buildMenu.IdPressed += BuildMenuOptionPressed;
- errorsBtn = new Button
+ _errorsBtn = new Button
{
HintTooltip = "Show Errors".TTR(),
Icon = GetThemeIcon("StatusError", "EditorIcons"),
@@ -150,10 +150,10 @@ namespace GodotTools.Build
Pressed = true,
FocusMode = FocusModeEnum.None
};
- errorsBtn.Toggled += ErrorsToggled;
- toolBarHBox.AddChild(errorsBtn);
+ _errorsBtn.Toggled += ErrorsToggled;
+ toolBarHBox.AddChild(_errorsBtn);
- warningsBtn = new Button
+ _warningsBtn = new Button
{
HintTooltip = "Show Warnings".TTR(),
Icon = GetThemeIcon("NodeWarning", "EditorIcons"),
@@ -162,18 +162,18 @@ namespace GodotTools.Build
Pressed = true,
FocusMode = FocusModeEnum.None
};
- warningsBtn.Toggled += WarningsToggled;
- toolBarHBox.AddChild(warningsBtn);
+ _warningsBtn.Toggled += WarningsToggled;
+ toolBarHBox.AddChild(_warningsBtn);
- viewLogBtn = new Button
+ _viewLogBtn = new Button
{
Text = "Show Output".TTR(),
ToggleMode = true,
Pressed = true,
FocusMode = FocusModeEnum.None
};
- viewLogBtn.Toggled += ViewLogToggled;
- toolBarHBox.AddChild(viewLogBtn);
+ _viewLogBtn.Toggled += ViewLogToggled;
+ toolBarHBox.AddChild(_viewLogBtn);
BuildOutputView = new BuildOutputView();
AddChild(BuildOutputView);
@@ -185,12 +185,12 @@ namespace GodotTools.Build
if (what == NotificationThemeChanged)
{
- if (buildMenuBtn != null)
- buildMenuBtn.Icon = GetThemeIcon("Play", "EditorIcons");
- if (errorsBtn != null)
- errorsBtn.Icon = GetThemeIcon("StatusError", "EditorIcons");
- if (warningsBtn != null)
- warningsBtn.Icon = GetThemeIcon("NodeWarning", "EditorIcons");
+ if (_buildMenuBtn != null)
+ _buildMenuBtn.Icon = GetThemeIcon("Play", "EditorIcons");
+ if (_errorsBtn != null)
+ _errorsBtn.Icon = GetThemeIcon("StatusError", "EditorIcons");
+ if (_warningsBtn != null)
+ _warningsBtn.Icon = GetThemeIcon("NodeWarning", "EditorIcons");
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
index 774c49e705..a859c6f717 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
@@ -61,7 +61,7 @@ namespace GodotTools.Build
}
case BuildTool.JetBrainsMsBuild:
{
- var editorPath = (string)editorSettings.GetSetting(RiderPathManager.EditorPathSettingName);
+ string editorPath = (string)editorSettings.GetSetting(RiderPathManager.EditorPathSettingName);
if (!File.Exists(editorPath))
throw new FileNotFoundException($"Cannot find Rider executable. Tried with path: {editorPath}");
@@ -165,7 +165,9 @@ namespace GodotTools.Build
// Try to find 15.0 with vswhere
- var envNames = Internal.GodotIs32Bits() ? new[] {"ProgramFiles", "ProgramW6432"} : new[] {"ProgramFiles(x86)", "ProgramFiles"};
+ string[] envNames = Internal.GodotIs32Bits() ?
+ envNames = new[] { "ProgramFiles", "ProgramW6432" } :
+ envNames = new[] { "ProgramFiles(x86)", "ProgramFiles" };
string vsWherePath = null;
foreach (var envName in envNames)
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
index f69307104f..37e6a34977 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
@@ -65,12 +65,12 @@ namespace GodotTools.Export
if (platform == OS.Platforms.iOS)
{
- var architectures = GetEnablediOSArchs(features).ToArray();
+ string[] architectures = GetEnablediOSArchs(features).ToArray();
CompileAssembliesForiOS(exporter, isDebug, architectures, aotOpts, aotTempDir, assembliesPrepared, bclDir);
}
else if (platform == OS.Platforms.Android)
{
- var abis = GetEnabledAndroidAbis(features).ToArray();
+ string[] abis = GetEnabledAndroidAbis(features).ToArray();
CompileAssembliesForAndroid(exporter, isDebug, abis, aotOpts, aotTempDir, assembliesPrepared, bclDir);
}
else
@@ -138,7 +138,8 @@ namespace GodotTools.Export
}
else
{
- string outputDataLibDir = Path.Combine(outputDataDir, "Mono", platform == OS.Platforms.Windows ? "bin" : "lib");
+ string libDir = platform == OS.Platforms.Windows ? "bin" : "lib";
+ string outputDataLibDir = Path.Combine(outputDataDir, "Mono", libDir);
File.Copy(tempOutputFilePath, Path.Combine(outputDataLibDir, outputFileName));
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index 0b5aa72a81..3e46a89b7c 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -20,7 +20,7 @@ namespace GodotTools.Export
public class ExportPlugin : EditorExportPlugin
{
[Flags]
- enum I18NCodesets : long
+ private enum I18NCodesets : long
{
None = 0,
CJK = 1,
@@ -31,6 +31,8 @@ namespace GodotTools.Export
All = CJK | MidEast | Other | Rare | West
}
+ private string _maybeLastExportError;
+
private void AddI18NAssemblies(Godot.Collections.Dictionary<string, string> assemblies, string bclDir)
{
var codesets = (I18NCodesets)ProjectSettings.GetSetting("mono/export/i18n_codesets");
@@ -83,8 +85,6 @@ namespace GodotTools.Export
GlobalDef("mono/export/aot/android_toolchain_path", "");
}
- private string maybeLastExportError;
-
private void AddFile(string srcPath, string dstPath, bool remap = false)
{
// Add file to the PCK
@@ -129,14 +129,14 @@ namespace GodotTools.Export
}
catch (Exception e)
{
- maybeLastExportError = e.Message;
+ _maybeLastExportError = e.Message;
// 'maybeLastExportError' cannot be null or empty if there was an error, so we
// must consider the possibility of exceptions being thrown without a message.
- if (string.IsNullOrEmpty(maybeLastExportError))
- maybeLastExportError = $"Exception thrown: {e.GetType().Name}";
+ if (string.IsNullOrEmpty(_maybeLastExportError))
+ _maybeLastExportError = $"Exception thrown: {e.GetType().Name}";
- GD.PushError($"Failed to export project: {maybeLastExportError}");
+ GD.PushError($"Failed to export project: {_maybeLastExportError}");
Console.Error.WriteLine(e);
// TODO: Do something on error once _ExportBegin supports failing.
}
@@ -317,10 +317,10 @@ namespace GodotTools.Export
Directory.Delete(aotTempDir, recursive: true);
// TODO: Just a workaround until the export plugins can be made to abort with errors
- if (!string.IsNullOrEmpty(maybeLastExportError)) // Check empty as well, because it's set to empty after hot-reloading
+ if (!string.IsNullOrEmpty(_maybeLastExportError)) // Check empty as well, because it's set to empty after hot-reloading
{
- string lastExportError = maybeLastExportError;
- maybeLastExportError = null;
+ string lastExportError = _maybeLastExportError;
+ _maybeLastExportError = null;
GodotSharpEditor.Instance.ShowErrorDialog(lastExportError, "Failed to export C# project");
}
@@ -470,7 +470,7 @@ namespace GodotTools.Export
private static string DetermineDataDirNameForProject()
{
- var appName = (string)ProjectSettings.GetSetting("application/config/name");
+ string appName = (string)ProjectSettings.GetSetting("application/config/name");
string appNameSafe = appName.ToSafeDirName();
return $"data_{appNameSafe}";
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index 1faa6eeac0..73cabf8561 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -21,18 +21,19 @@ namespace GodotTools
{
public class GodotSharpEditor : EditorPlugin, ISerializationListener
{
- private EditorSettings editorSettings;
+ private EditorSettings _editorSettings;
- private PopupMenu menuPopup;
+ private PopupMenu _menuPopup;
- private AcceptDialog errorDialog;
+ private AcceptDialog _errorDialog;
- private Button bottomPanelBtn;
- private Button toolBarBuildButton;
+ private Button _bottomPanelBtn;
+ private Button _toolBarBuildButton;
- public GodotIdeManager GodotIdeManager { get; private set; }
+ // TODO Use WeakReference once we have proper serialization.
+ private WeakRef _exportPluginWeak;
- private WeakRef exportPluginWeak; // TODO Use WeakReference once we have proper serialization
+ public GodotIdeManager GodotIdeManager { get; private set; }
public MSBuildPanel MSBuildPanel { get; private set; }
@@ -42,7 +43,7 @@ namespace GodotTools
{
get
{
- var projectAssemblyName = (string)ProjectSettings.GetSetting("application/config/name");
+ string projectAssemblyName = (string)ProjectSettings.GetSetting("application/config/name");
projectAssemblyName = projectAssemblyName.ToSafeDirName();
if (string.IsNullOrEmpty(projectAssemblyName))
projectAssemblyName = "UnnamedProject";
@@ -123,9 +124,9 @@ namespace GodotTools
private void _RemoveCreateSlnMenuOption()
{
- menuPopup.RemoveItem(menuPopup.GetItemIndex((int)MenuOptions.CreateSln));
- bottomPanelBtn.Show();
- toolBarBuildButton.Show();
+ _menuPopup.RemoveItem(_menuPopup.GetItemIndex((int)MenuOptions.CreateSln));
+ _bottomPanelBtn.Show();
+ _toolBarBuildButton.Show();
}
private void _MenuOptionPressed(int id)
@@ -181,9 +182,9 @@ namespace GodotTools
public void ShowErrorDialog(string message, string title = "Error")
{
- errorDialog.Title = title;
- errorDialog.DialogText = message;
- errorDialog.PopupCentered();
+ _errorDialog.Title = title;
+ _errorDialog.DialogText = message;
+ _errorDialog.PopupCentered();
}
private static string _vsCodePath = string.Empty;
@@ -196,7 +197,7 @@ namespace GodotTools
[UsedImplicitly]
public Error OpenInExternalEditor(Script script, int line, int col)
{
- var editorId = (ExternalEditorId)editorSettings.GetSetting("mono/editor/external_editor");
+ var editorId = (ExternalEditorId)_editorSettings.GetSetting("mono/editor/external_editor");
switch (editorId)
{
@@ -287,7 +288,7 @@ namespace GodotTools
}
}
- var resourcePath = ProjectSettings.GlobalizePath("res://");
+ string resourcePath = ProjectSettings.GlobalizePath("res://");
args.Add(resourcePath);
string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath);
@@ -346,7 +347,7 @@ namespace GodotTools
[UsedImplicitly]
public bool OverridesExternalEditor()
{
- return (ExternalEditorId)editorSettings.GetSetting("mono/editor/external_editor") != ExternalEditorId.None;
+ return (ExternalEditorId)_editorSettings.GetSetting("mono/editor/external_editor") != ExternalEditorId.None;
}
public override bool _Build()
@@ -387,8 +388,8 @@ namespace GodotTools
private void BuildStateChanged()
{
- if (bottomPanelBtn != null)
- bottomPanelBtn.Icon = MSBuildPanel.BuildOutputView.BuildStateIcon;
+ if (_bottomPanelBtn != null)
+ _bottomPanelBtn.Icon = MSBuildPanel.BuildOutputView.BuildStateIcon;
}
public override void _EnablePlugin()
@@ -402,29 +403,29 @@ namespace GodotTools
var editorInterface = GetEditorInterface();
var editorBaseControl = editorInterface.GetBaseControl();
- editorSettings = editorInterface.GetEditorSettings();
+ _editorSettings = editorInterface.GetEditorSettings();
- errorDialog = new AcceptDialog();
- editorBaseControl.AddChild(errorDialog);
+ _errorDialog = new AcceptDialog();
+ editorBaseControl.AddChild(_errorDialog);
MSBuildPanel = new MSBuildPanel();
- bottomPanelBtn = AddControlToBottomPanel(MSBuildPanel, "MSBuild".TTR());
+ _bottomPanelBtn = AddControlToBottomPanel(MSBuildPanel, "MSBuild".TTR());
AddChild(new HotReloadAssemblyWatcher {Name = "HotReloadAssemblyWatcher"});
- menuPopup = new PopupMenu();
- menuPopup.Hide();
+ _menuPopup = new PopupMenu();
+ _menuPopup.Hide();
- AddToolSubmenuItem("C#", menuPopup);
+ AddToolSubmenuItem("C#", _menuPopup);
- toolBarBuildButton = new Button
+ _toolBarBuildButton = new Button
{
Text = "Build",
HintTooltip = "Build solution",
FocusMode = Control.FocusModeEnum.None
};
- toolBarBuildButton.PressedSignal += BuildSolutionPressed;
- AddControlToContainer(CustomControlContainer.Toolbar, toolBarBuildButton);
+ _toolBarBuildButton.PressedSignal += BuildSolutionPressed;
+ AddControlToContainer(CustomControlContainer.Toolbar, _toolBarBuildButton);
if (File.Exists(GodotSharpDirs.ProjectSlnPath) && File.Exists(GodotSharpDirs.ProjectCsProjPath))
{
@@ -432,12 +433,12 @@ namespace GodotTools
}
else
{
- bottomPanelBtn.Hide();
- toolBarBuildButton.Hide();
- menuPopup.AddItem("Create C# solution".TTR(), (int)MenuOptions.CreateSln);
+ _bottomPanelBtn.Hide();
+ _toolBarBuildButton.Hide();
+ _menuPopup.AddItem("Create C# solution".TTR(), (int)MenuOptions.CreateSln);
}
- menuPopup.IdPressed += _MenuOptionPressed;
+ _menuPopup.IdPressed += _MenuOptionPressed;
// External editor settings
EditorDef("mono/editor/external_editor", ExternalEditorId.None);
@@ -465,7 +466,7 @@ namespace GodotTools
$",JetBrains Rider:{(int)ExternalEditorId.Rider}";
}
- editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
+ _editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
{
["type"] = Variant.Type.Int,
["name"] = "mono/editor/external_editor",
@@ -477,7 +478,7 @@ namespace GodotTools
var exportPlugin = new ExportPlugin();
AddExportPlugin(exportPlugin);
exportPlugin.RegisterExportSettings();
- exportPluginWeak = WeakRef(exportPlugin);
+ _exportPluginWeak = WeakRef(exportPlugin);
try
{
@@ -500,15 +501,15 @@ namespace GodotTools
{
base.Dispose(disposing);
- if (exportPluginWeak != null)
+ if (_exportPluginWeak != null)
{
// We need to dispose our export plugin before the editor destroys EditorSettings.
// Otherwise, if the GC disposes it at a later time, EditorExportPlatformAndroid
// will be freed after EditorSettings already was, and its device polling thread
// will try to access the EditorSettings singleton, resulting in null dereferencing.
- (exportPluginWeak.GetRef() as ExportPlugin)?.Dispose();
+ (_exportPluginWeak.GetRef() as ExportPlugin)?.Dispose();
- exportPluginWeak.Dispose();
+ _exportPluginWeak.Dispose();
}
GodotIdeManager?.Dispose();
diff --git a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
index b30c857c64..dd05f28af0 100644
--- a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
@@ -6,7 +6,7 @@ namespace GodotTools
{
public class HotReloadAssemblyWatcher : Node
{
- private Timer watchTimer;
+ private Timer _watchTimer;
public override void _Notification(int what)
{
@@ -27,22 +27,22 @@ namespace GodotTools
public void RestartTimer()
{
- watchTimer.Stop();
- watchTimer.Start();
+ _watchTimer.Stop();
+ _watchTimer.Start();
}
public override void _Ready()
{
base._Ready();
- watchTimer = new Timer
+ _watchTimer = new Timer
{
OneShot = false,
WaitTime = (float)EditorDef("mono/assembly_watch_interval_sec", 0.5)
};
- watchTimer.Timeout += TimerTimeout;
- AddChild(watchTimer);
- watchTimer.Start();
+ _watchTimer.Timeout += TimerTimeout;
+ AddChild(_watchTimer);
+ _watchTimer.Start();
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
index 451ce39f5c..23339fe50b 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
@@ -10,22 +10,22 @@ namespace GodotTools.Ides
{
public sealed class GodotIdeManager : Node, ISerializationListener
{
- private MessagingServer MessagingServer { get; set; }
+ private MessagingServer _messagingServer;
- private MonoDevelop.Instance monoDevelInstance;
- private MonoDevelop.Instance vsForMacInstance;
+ private MonoDevelop.Instance _monoDevelInstance;
+ private MonoDevelop.Instance _vsForMacInstance;
private MessagingServer GetRunningOrNewServer()
{
- if (MessagingServer != null && !MessagingServer.IsDisposed)
- return MessagingServer;
+ if (_messagingServer != null && !_messagingServer.IsDisposed)
+ return _messagingServer;
- MessagingServer?.Dispose();
- MessagingServer = new MessagingServer(OS.GetExecutablePath(), ProjectSettings.GlobalizePath(GodotSharpDirs.ResMetadataDir), new GodotLogger());
+ _messagingServer?.Dispose();
+ _messagingServer = new MessagingServer(OS.GetExecutablePath(), ProjectSettings.GlobalizePath(GodotSharpDirs.ResMetadataDir), new GodotLogger());
- _ = MessagingServer.Listen();
+ _ = _messagingServer.Listen();
- return MessagingServer;
+ return _messagingServer;
}
public override void _Ready()
@@ -48,7 +48,7 @@ namespace GodotTools.Ides
if (disposing)
{
- MessagingServer?.Dispose();
+ _messagingServer?.Dispose();
}
}
@@ -113,14 +113,14 @@ namespace GodotTools.Ides
{
if (Utils.OS.IsMacOS && editorId == ExternalEditorId.VisualStudioForMac)
{
- vsForMacInstance = (vsForMacInstance?.IsDisposed ?? true ? null : vsForMacInstance) ??
+ _vsForMacInstance = (_vsForMacInstance?.IsDisposed ?? true ? null : _vsForMacInstance) ??
new MonoDevelop.Instance(solutionPath, MonoDevelop.EditorId.VisualStudioForMac);
- return vsForMacInstance;
+ return _vsForMacInstance;
}
- monoDevelInstance = (monoDevelInstance?.IsDisposed ?? true ? null : monoDevelInstance) ??
+ _monoDevelInstance = (_monoDevelInstance?.IsDisposed ?? true ? null : _monoDevelInstance) ??
new MonoDevelop.Instance(solutionPath, MonoDevelop.EditorId.MonoDevelop);
- return monoDevelInstance;
+ return _monoDevelInstance;
}
try
@@ -159,15 +159,15 @@ namespace GodotTools.Ides
public readonly struct EditorPick
{
- private readonly string identity;
+ private readonly string _identity;
public EditorPick(string identity)
{
- this.identity = identity;
+ _identity = identity;
}
public bool IsAnyConnected() =>
- GodotSharpEditor.Instance.GodotIdeManager.GetRunningOrNewServer().IsAnyConnected(identity);
+ GodotSharpEditor.Instance.GodotIdeManager.GetRunningOrNewServer().IsAnyConnected(_identity);
private void SendRequest<TResponse>(Request request)
where TResponse : Response, new()
@@ -175,7 +175,7 @@ namespace GodotTools.Ides
// Logs an error if no client is connected with the specified identity
GodotSharpEditor.Instance.GodotIdeManager
.GetRunningOrNewServer()
- .BroadcastRequest<TResponse>(identity, request);
+ .BroadcastRequest<TResponse>(_identity, request);
}
public void SendOpenFile(string file)
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs
index eb34a2d0f7..6f11831b80 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs
@@ -21,24 +21,26 @@ namespace GodotTools.Ides
{
public sealed class MessagingServer : IDisposable
{
- private readonly ILogger logger;
+ private readonly ILogger _logger;
- private readonly FileStream metaFile;
- private string MetaFilePath { get; }
+ private readonly FileStream _metaFile;
+ private string _metaFilePath;
- private readonly SemaphoreSlim peersSem = new SemaphoreSlim(1);
+ private readonly SemaphoreSlim _peersSem = new SemaphoreSlim(1);
- private readonly TcpListener listener;
+ private readonly TcpListener _listener;
- private readonly Dictionary<string, Queue<NotifyAwaiter<bool>>> clientConnectedAwaiters = new Dictionary<string, Queue<NotifyAwaiter<bool>>>();
- private readonly Dictionary<string, Queue<NotifyAwaiter<bool>>> clientDisconnectedAwaiters = new Dictionary<string, Queue<NotifyAwaiter<bool>>>();
+ private readonly Dictionary<string, Queue<NotifyAwaiter<bool>>> _clientConnectedAwaiters =
+ new Dictionary<string, Queue<NotifyAwaiter<bool>>>();
+ private readonly Dictionary<string, Queue<NotifyAwaiter<bool>>> _clientDisconnectedAwaiters =
+ new Dictionary<string, Queue<NotifyAwaiter<bool>>>();
public async Task<bool> AwaitClientConnected(string identity)
{
- if (!clientConnectedAwaiters.TryGetValue(identity, out var queue))
+ if (!_clientConnectedAwaiters.TryGetValue(identity, out var queue))
{
queue = new Queue<NotifyAwaiter<bool>>();
- clientConnectedAwaiters.Add(identity, queue);
+ _clientConnectedAwaiters.Add(identity, queue);
}
var awaiter = new NotifyAwaiter<bool>();
@@ -48,10 +50,10 @@ namespace GodotTools.Ides
public async Task<bool> AwaitClientDisconnected(string identity)
{
- if (!clientDisconnectedAwaiters.TryGetValue(identity, out var queue))
+ if (!_clientDisconnectedAwaiters.TryGetValue(identity, out var queue))
{
queue = new Queue<NotifyAwaiter<bool>>();
- clientDisconnectedAwaiters.Add(identity, queue);
+ _clientDisconnectedAwaiters.Add(identity, queue);
}
var awaiter = new NotifyAwaiter<bool>();
@@ -77,7 +79,7 @@ namespace GodotTools.Ides
if (IsDisposed)
return;
- using (await peersSem.UseAsync())
+ using (await _peersSem.UseAsync())
{
if (IsDisposed) // lock may not be fair
return;
@@ -95,19 +97,19 @@ namespace GodotTools.Ides
foreach (var connection in Peers)
connection.Dispose();
Peers.Clear();
- listener?.Stop();
+ _listener?.Stop();
- metaFile?.Dispose();
+ _metaFile?.Dispose();
- File.Delete(MetaFilePath);
+ File.Delete(_metaFilePath);
}
}
public MessagingServer(string editorExecutablePath, string projectMetadataDir, ILogger logger)
{
- this.logger = logger;
+ this._logger = logger;
- MetaFilePath = Path.Combine(projectMetadataDir, GodotIdeMetadata.DefaultFileName);
+ _metaFilePath = Path.Combine(projectMetadataDir, GodotIdeMetadata.DefaultFileName);
// Make sure the directory exists
Directory.CreateDirectory(projectMetadataDir);
@@ -115,13 +117,13 @@ namespace GodotTools.Ides
// The Godot editor's file system thread can keep the file open for writing, so we are forced to allow write sharing...
const FileShare metaFileShare = FileShare.ReadWrite;
- metaFile = File.Open(MetaFilePath, FileMode.Create, FileAccess.Write, metaFileShare);
+ _metaFile = File.Open(_metaFilePath, FileMode.Create, FileAccess.Write, metaFileShare);
- listener = new TcpListener(new IPEndPoint(IPAddress.Loopback, port: 0));
- listener.Start();
+ _listener = new TcpListener(new IPEndPoint(IPAddress.Loopback, port: 0));
+ _listener.Start();
- int port = ((IPEndPoint)listener.Server.LocalEndPoint).Port;
- using (var metaFileWriter = new StreamWriter(metaFile, Encoding.UTF8))
+ int port = ((IPEndPoint)_listener.Server.LocalEndPoint).Port;
+ using (var metaFileWriter = new StreamWriter(_metaFile, Encoding.UTF8))
{
metaFileWriter.WriteLine(port);
metaFileWriter.WriteLine(editorExecutablePath);
@@ -130,30 +132,30 @@ namespace GodotTools.Ides
private async Task AcceptClient(TcpClient tcpClient)
{
- logger.LogDebug("Accept client...");
+ _logger.LogDebug("Accept client...");
- using (var peer = new Peer(tcpClient, new ServerHandshake(), new ServerMessageHandler(), logger))
+ using (var peer = new Peer(tcpClient, new ServerHandshake(), new ServerMessageHandler(), _logger))
{
// ReSharper disable AccessToDisposedClosure
peer.Connected += () =>
{
- logger.LogInfo("Connection open with Ide Client");
+ _logger.LogInfo("Connection open with Ide Client");
- if (clientConnectedAwaiters.TryGetValue(peer.RemoteIdentity, out var queue))
+ if (_clientConnectedAwaiters.TryGetValue(peer.RemoteIdentity, out var queue))
{
while (queue.Count > 0)
queue.Dequeue().SetResult(true);
- clientConnectedAwaiters.Remove(peer.RemoteIdentity);
+ _clientConnectedAwaiters.Remove(peer.RemoteIdentity);
}
};
peer.Disconnected += () =>
{
- if (clientDisconnectedAwaiters.TryGetValue(peer.RemoteIdentity, out var queue))
+ if (_clientDisconnectedAwaiters.TryGetValue(peer.RemoteIdentity, out var queue))
{
while (queue.Count > 0)
queue.Dequeue().SetResult(true);
- clientDisconnectedAwaiters.Remove(peer.RemoteIdentity);
+ _clientDisconnectedAwaiters.Remove(peer.RemoteIdentity);
}
};
// ReSharper restore AccessToDisposedClosure
@@ -162,17 +164,17 @@ namespace GodotTools.Ides
{
if (!await peer.DoHandshake("server"))
{
- logger.LogError("Handshake failed");
+ _logger.LogError("Handshake failed");
return;
}
}
catch (Exception e)
{
- logger.LogError("Handshake failed with unhandled exception: ", e);
+ _logger.LogError("Handshake failed with unhandled exception: ", e);
return;
}
- using (await peersSem.UseAsync())
+ using (await _peersSem.UseAsync())
Peers.Add(peer);
try
@@ -181,7 +183,7 @@ namespace GodotTools.Ides
}
finally
{
- using (await peersSem.UseAsync())
+ using (await _peersSem.UseAsync())
Peers.Remove(peer);
}
}
@@ -192,7 +194,7 @@ namespace GodotTools.Ides
try
{
while (!IsDisposed)
- _ = AcceptClient(await listener.AcceptTcpClientAsync());
+ _ = AcceptClient(await _listener.AcceptTcpClientAsync());
}
catch (Exception e)
{
@@ -204,11 +206,11 @@ namespace GodotTools.Ides
public async void BroadcastRequest<TResponse>(string identity, Request request)
where TResponse : Response, new()
{
- using (await peersSem.UseAsync())
+ using (await _peersSem.UseAsync())
{
if (!IsAnyConnected(identity))
{
- logger.LogError("Cannot write request. No client connected to the Godot Ide Server.");
+ _logger.LogError("Cannot write request. No client connected to the Godot Ide Server.");
return;
}
@@ -225,16 +227,19 @@ namespace GodotTools.Ides
private class ServerHandshake : IHandshake
{
- private static readonly string ServerHandshakeBase = $"{Peer.ServerHandshakeName},Version={Peer.ProtocolVersionMajor}.{Peer.ProtocolVersionMinor}.{Peer.ProtocolVersionRevision}";
- private static readonly string ClientHandshakePattern = $@"{Regex.Escape(Peer.ClientHandshakeName)},Version=([0-9]+)\.([0-9]+)\.([0-9]+),([_a-zA-Z][_a-zA-Z0-9]{{0,63}})";
+ private static readonly string _serverHandshakeBase =
+ $"{Peer.ServerHandshakeName},Version={Peer.ProtocolVersionMajor}.{Peer.ProtocolVersionMinor}.{Peer.ProtocolVersionRevision}";
- public string GetHandshakeLine(string identity) => $"{ServerHandshakeBase},{identity}";
+ private static readonly string _clientHandshakePattern =
+ $@"{Regex.Escape(Peer.ClientHandshakeName)},Version=([0-9]+)\.([0-9]+)\.([0-9]+),([_a-zA-Z][_a-zA-Z0-9]{{0,63}})";
+
+ public string GetHandshakeLine(string identity) => $"{_serverHandshakeBase},{identity}";
public bool IsValidPeerHandshake(string handshake, out string identity, ILogger logger)
{
identity = null;
- var match = Regex.Match(handshake, ClientHandshakePattern);
+ var match = Regex.Match(handshake, _clientHandshakePattern);
if (!match.Success)
return false;
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
index fd7bbd5578..3f1d5ac3ca 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
@@ -10,17 +10,17 @@ namespace GodotTools.Ides.MonoDevelop
public class Instance : IDisposable
{
public DateTime LaunchTime { get; private set; }
- private readonly string solutionFile;
- private readonly EditorId editorId;
+ private readonly string _solutionFile;
+ private readonly EditorId _editorId;
- private Process process;
+ private Process _process;
- public bool IsRunning => process != null && !process.HasExited;
+ public bool IsRunning => _process != null && !_process.HasExited;
public bool IsDisposed { get; private set; }
public void Execute()
{
- bool newWindow = process == null || process.HasExited;
+ bool newWindow = _process == null || _process.HasExited;
var args = new List<string>();
@@ -28,7 +28,7 @@ namespace GodotTools.Ides.MonoDevelop
if (OS.IsMacOS)
{
- string bundleId = BundleIds[editorId];
+ string bundleId = BundleIds[_editorId];
if (Internal.IsOsxAppBundleInstalled(bundleId))
{
@@ -45,18 +45,18 @@ namespace GodotTools.Ides.MonoDevelop
}
else
{
- command = OS.PathWhich(ExecutableNames[editorId]);
+ command = OS.PathWhich(ExecutableNames[_editorId]);
}
}
else
{
- command = OS.PathWhich(ExecutableNames[editorId]);
+ command = OS.PathWhich(ExecutableNames[_editorId]);
}
args.Add("--ipc-tcp");
if (newWindow)
- args.Add("\"" + Path.GetFullPath(solutionFile) + "\"");
+ args.Add("\"" + Path.GetFullPath(_solutionFile) + "\"");
if (command == null)
throw new FileNotFoundException();
@@ -65,7 +65,7 @@ namespace GodotTools.Ides.MonoDevelop
if (newWindow)
{
- process = Process.Start(new ProcessStartInfo
+ _process = Process.Start(new ProcessStartInfo
{
FileName = command,
Arguments = string.Join(" ", args),
@@ -88,14 +88,14 @@ namespace GodotTools.Ides.MonoDevelop
if (editorId == EditorId.VisualStudioForMac && !OS.IsMacOS)
throw new InvalidOperationException($"{nameof(EditorId.VisualStudioForMac)} not supported on this platform");
- this.solutionFile = solutionFile;
- this.editorId = editorId;
+ _solutionFile = solutionFile;
+ _editorId = editorId;
}
public void Dispose()
{
IsDisposed = true;
- process?.Dispose();
+ _process?.Dispose();
}
private static readonly IReadOnlyDictionary<EditorId, string> ExecutableNames;
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
index 821532f759..71055f0125 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
@@ -11,6 +11,7 @@ using Environment = System.Environment;
using File = System.IO.File;
using Path = System.IO.Path;
using OS = GodotTools.Utils.OS;
+
// ReSharper disable UnassignedField.Local
// ReSharper disable InconsistentNaming
// ReSharper disable UnassignedField.Global
@@ -53,10 +54,10 @@ namespace GodotTools.Ides.Rider
private static RiderInfo[] CollectAllRiderPathsLinux()
{
var installInfos = new List<RiderInfo>();
- var home = Environment.GetEnvironmentVariable("HOME");
+ string home = Environment.GetEnvironmentVariable("HOME");
if (!string.IsNullOrEmpty(home))
{
- var toolboxRiderRootPath = GetToolboxBaseDir();
+ string toolboxRiderRootPath = GetToolboxBaseDir();
installInfos.AddRange(CollectPathsFromToolbox(toolboxRiderRootPath, "bin", "rider.sh", false)
.Select(a => new RiderInfo(a, true)).ToList());
@@ -65,12 +66,12 @@ namespace GodotTools.Ides.Rider
if (shortcut.Exists)
{
- var lines = File.ReadAllLines(shortcut.FullName);
- foreach (var line in lines)
+ string[] lines = File.ReadAllLines(shortcut.FullName);
+ foreach (string line in lines)
{
if (!line.StartsWith("Exec=\""))
continue;
- var path = line.Split('"').Where((item, index) => index == 1).SingleOrDefault();
+ string path = line.Split('"').Where((item, index) => index == 1).SingleOrDefault();
if (string.IsNullOrEmpty(path))
continue;
@@ -82,7 +83,7 @@ namespace GodotTools.Ides.Rider
}
// snap install
- var snapInstallPath = "/snap/rider/current/bin/rider.sh";
+ string snapInstallPath = "/snap/rider/current/bin/rider.sh";
if (new FileInfo(snapInstallPath).Exists)
installInfos.Add(new RiderInfo(snapInstallPath, false));
@@ -98,15 +99,15 @@ namespace GodotTools.Ides.Rider
if (folder.Exists)
{
installInfos.AddRange(folder.GetDirectories("*Rider*.app")
- .Select(a => new RiderInfo(Path.Combine(a.FullName, "Contents/MacOS/rider"), false))
- .ToList());
+ .Select(a => new RiderInfo(Path.Combine(a.FullName, "Contents/MacOS/rider"), false))
+ .ToList());
}
// /Users/user/Library/Application Support/JetBrains/Toolbox/apps/Rider/ch-1/181.3870.267/Rider EAP.app
// should be combined with "Contents/MacOS/rider"
- var toolboxRiderRootPath = GetToolboxBaseDir();
+ string toolboxRiderRootPath = GetToolboxBaseDir();
var paths = CollectPathsFromToolbox(toolboxRiderRootPath, "", "Rider*.app", true)
- .Select(a => new RiderInfo(Path.Combine(a, "Contents/MacOS/rider"), true));
+ .Select(a => new RiderInfo(Path.Combine(a, "Contents/MacOS/rider"), true));
installInfos.AddRange(paths);
return installInfos.ToArray();
@@ -134,7 +135,7 @@ namespace GodotTools.Ides.Rider
{
if (OS.IsWindows)
{
- var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+ string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
return GetToolboxRiderRootPath(localAppData);
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
index 60dd565ef2..ac29efb716 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
@@ -49,7 +49,7 @@ namespace GodotTools.Ides.Rider
if (!paths.Any())
return;
- var newPath = paths.Last().Path;
+ string newPath = paths.Last().Path;
Globals.EditorDef(EditorPathSettingName, newPath);
editorSettings.SetSetting(EditorPathSettingName, newPath);
}
@@ -57,7 +57,8 @@ namespace GodotTools.Ides.Rider
public static bool IsExternalEditorSetToRider(EditorSettings editorSettings)
{
- return editorSettings.HasSetting(EditorPathSettingName) && IsRider((string)editorSettings.GetSetting(EditorPathSettingName));
+ return editorSettings.HasSetting(EditorPathSettingName) &&
+ IsRider((string)editorSettings.GetSetting(EditorPathSettingName));
}
public static bool IsRider(string path)
@@ -66,7 +67,7 @@ namespace GodotTools.Ides.Rider
return false;
var fileInfo = new FileInfo(path);
- var filename = fileInfo.Name.ToLowerInvariant();
+ string filename = fileInfo.Name.ToLowerInvariant();
return filename.StartsWith("rider", StringComparison.Ordinal);
}
@@ -83,7 +84,7 @@ namespace GodotTools.Ides.Rider
if (!paths.Any())
return null;
- var newPath = paths.Last().Path;
+ string newPath = paths.Last().Path;
editorSettings.SetSetting(EditorPathSettingName, newPath);
Globals.EditorDef(EditorPathSettingName, newPath);
return newPath;
@@ -96,8 +97,8 @@ namespace GodotTools.Ides.Rider
public static void OpenFile(string slnPath, string scriptPath, int line)
{
- var pathFromSettings = GetRiderPathFromSettings();
- var path = CheckAndUpdatePath(pathFromSettings);
+ string pathFromSettings = GetRiderPathFromSettings();
+ string path = CheckAndUpdatePath(pathFromSettings);
var args = new List<string>();
args.Add(slnPath);
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs
index 6893bc1974..5e70c399b2 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs
@@ -39,45 +39,57 @@ namespace GodotTools.Internals
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_ResDataDir();
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_ResMetadataDir();
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_ResAssembliesBaseDir();
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_ResAssembliesDir();
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_ResConfigDir();
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_ResTempDir();
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_ResTempAssembliesBaseDir();
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_ResTempAssembliesDir();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_MonoUserDir();
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_MonoLogsDir();
#region Tools-only
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_MonoSolutionsDir();
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_BuildLogsDirs();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_ProjectSlnPath();
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_ProjectCsProjPath();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_DataEditorToolsDir();
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_DataEditorPrebuiltApiDir();
#endregion
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_DataMonoEtcDir();
+
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_DataMonoLibDir();
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/FsPathUtils.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/FsPathUtils.cs
index c6724ccaf7..05499339b1 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/FsPathUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/FsPathUtils.cs
@@ -8,7 +8,7 @@ namespace GodotTools.Utils
{
public static class FsPathUtils
{
- private static readonly string ResourcePath = ProjectSettings.GlobalizePath("res://");
+ private static readonly string _resourcePath = ProjectSettings.GlobalizePath("res://");
private static bool PathStartsWithAlreadyNorm(this string childPath, string parentPath)
{
@@ -34,7 +34,7 @@ namespace GodotTools.Utils
public static string LocalizePathWithCaseChecked(string path)
{
string pathNorm = path.NormalizePath() + Path.DirectorySeparatorChar;
- string resourcePathNorm = ResourcePath.NormalizePath() + Path.DirectorySeparatorChar;
+ string resourcePathNorm = _resourcePath.NormalizePath() + Path.DirectorySeparatorChar;
if (!pathNorm.PathStartsWithAlreadyNorm(resourcePathNorm))
return null;
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
index 4624439665..93a1360cb6 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
@@ -13,10 +13,10 @@ namespace GodotTools.Utils
public static class OS
{
[MethodImpl(MethodImplOptions.InternalCall)]
- static extern string GetPlatformName();
+ private static extern string GetPlatformName();
[MethodImpl(MethodImplOptions.InternalCall)]
- static extern bool UnixFileHasExecutableAccess(string filePath);
+ private static extern bool UnixFileHasExecutableAccess(string filePath);
public static class Names
{
@@ -106,7 +106,10 @@ namespace GodotTools.Utils
public static string PathWhich([NotNull] string name)
{
- return IsWindows ? PathWhichWindows(name) : PathWhichUnix(name);
+ if (IsWindows)
+ return PathWhichWindows(name);
+
+ return PathWhichUnix(name);
}
private static string PathWhichWindows([NotNull] string name)
@@ -129,7 +132,8 @@ namespace GodotTools.Utils
}
string nameExt = Path.GetExtension(name);
- bool hasPathExt = !string.IsNullOrEmpty(nameExt) && windowsExts.Contains(nameExt, StringComparer.OrdinalIgnoreCase);
+ bool hasPathExt = !string.IsNullOrEmpty(nameExt) &&
+ windowsExts.Contains(nameExt, StringComparer.OrdinalIgnoreCase);
searchDirs.Add(System.IO.Directory.GetCurrentDirectory()); // last in the list
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 7fdef8ff45..67bcb34b1c 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -387,7 +387,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append(link_target);
xml_output.append("</c>");
}
- } else if (link_tag == "const") {
+ } else if (link_tag == "constant") {
if (!target_itype || !target_itype->is_object_type) {
if (OS::get_singleton()->is_stdout_verbose()) {
if (target_itype) {
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index 8a85a1acbd..51a27ee934 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -575,7 +575,7 @@ class BindingsGenerator {
StaticCString::create(_STR(PackedByteArray)),
StaticCString::create(_STR(PackedInt32Array)),
- StaticCString::create(_STR(PackedInt64rray)),
+ StaticCString::create(_STR(PackedInt64Array)),
StaticCString::create(_STR(PackedFloat32Array)),
StaticCString::create(_STR(PackedFloat64Array)),
StaticCString::create(_STR(PackedStringArray)),
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs
index 1a3b81487f..8b12537f7f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs
@@ -20,7 +20,7 @@ namespace Godot
private Vector3 _size;
/// <summary>
- /// Beginning corner. Typically has values lower than End.
+ /// Beginning corner. Typically has values lower than <see cref="End"/>.
/// </summary>
/// <value>Directly uses a private field.</value>
public Vector3 Position
@@ -30,7 +30,7 @@ namespace Godot
}
/// <summary>
- /// Size from Position to End. Typically all components are positive.
+ /// Size from <see cref="Position"/> to <see cref="End"/>. Typically all components are positive.
/// If the size is negative, you can use <see cref="Abs"/> to fix it.
/// </summary>
/// <value>Directly uses a private field.</value>
@@ -44,7 +44,10 @@ namespace Godot
/// Ending corner. This is calculated as <see cref="Position"/> plus
/// <see cref="Size"/>. Setting this value will change the size.
/// </summary>
- /// <value>Getting is equivalent to `value = Position + Size`, setting is equivalent to `Size = value - Position`.</value>
+ /// <value>
+ /// Getting is equivalent to <paramref name="value"/> = <see cref="Position"/> + <see cref="Size"/>,
+ /// setting is equivalent to <see cref="Size"/> = <paramref name="value"/> - <see cref="Position"/>
+ /// </value>
public Vector3 End
{
get { return _position + _size; }
@@ -52,10 +55,10 @@ namespace Godot
}
/// <summary>
- /// Returns an AABB with equivalent position and size, modified so that
+ /// Returns an <see cref="AABB"/> with equivalent position and size, modified so that
/// the most-negative corner is the origin and the size is positive.
/// </summary>
- /// <returns>The modified AABB.</returns>
+ /// <returns>The modified <see cref="AABB"/>.</returns>
public AABB Abs()
{
Vector3 end = End;
@@ -64,30 +67,32 @@ namespace Godot
}
/// <summary>
- /// Returns true if this AABB completely encloses another one.
+ /// Returns <see langword="true"/> if this <see cref="AABB"/> completely encloses another one.
/// </summary>
- /// <param name="with">The other AABB that may be enclosed.</param>
- /// <returns>A bool for whether or not this AABB encloses `b`.</returns>
+ /// <param name="with">The other <see cref="AABB"/> that may be enclosed.</param>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not this <see cref="AABB"/> encloses <paramref name="with"/>.
+ /// </returns>
public bool Encloses(AABB with)
{
- Vector3 src_min = _position;
- Vector3 src_max = _position + _size;
- Vector3 dst_min = with._position;
- Vector3 dst_max = with._position + with._size;
+ Vector3 srcMin = _position;
+ Vector3 srcMax = _position + _size;
+ Vector3 dstMin = with._position;
+ Vector3 dstMax = with._position + with._size;
- return src_min.x <= dst_min.x &&
- src_max.x > dst_max.x &&
- src_min.y <= dst_min.y &&
- src_max.y > dst_max.y &&
- src_min.z <= dst_min.z &&
- src_max.z > dst_max.z;
+ return srcMin.x <= dstMin.x &&
+ srcMax.x > dstMax.x &&
+ srcMin.y <= dstMin.y &&
+ srcMax.y > dstMax.y &&
+ srcMin.z <= dstMin.z &&
+ srcMax.z > dstMax.z;
}
/// <summary>
- /// Returns this AABB expanded to include a given point.
+ /// Returns this <see cref="AABB"/> expanded to include a given point.
/// </summary>
/// <param name="point">The point to include.</param>
- /// <returns>The expanded AABB.</returns>
+ /// <returns>The expanded <see cref="AABB"/>.</returns>
public AABB Expand(Vector3 point)
{
Vector3 begin = _position;
@@ -123,7 +128,7 @@ namespace Godot
}
/// <summary>
- /// Returns the area of the AABB.
+ /// Returns the area of the <see cref="AABB"/>.
/// </summary>
/// <returns>The area.</returns>
public real_t GetArea()
@@ -132,10 +137,10 @@ namespace Godot
}
/// <summary>
- /// Gets the position of one of the 8 endpoints of the AABB.
+ /// Gets the position of one of the 8 endpoints of the <see cref="AABB"/>.
/// </summary>
/// <param name="idx">Which endpoint to get.</param>
- /// <returns>An endpoint of the AABB.</returns>
+ /// <returns>An endpoint of the <see cref="AABB"/>.</returns>
public Vector3 GetEndpoint(int idx)
{
switch (idx)
@@ -157,26 +162,29 @@ namespace Godot
case 7:
return new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z + _size.z);
default:
- throw new ArgumentOutOfRangeException(nameof(idx), String.Format("Index is {0}, but a value from 0 to 7 is expected.", idx));
+ {
+ throw new ArgumentOutOfRangeException(nameof(idx),
+ $"Index is {idx}, but a value from 0 to 7 is expected.");
+ }
}
}
/// <summary>
- /// Returns the normalized longest axis of the AABB.
+ /// Returns the normalized longest axis of the <see cref="AABB"/>.
/// </summary>
- /// <returns>A vector representing the normalized longest axis of the AABB.</returns>
+ /// <returns>A vector representing the normalized longest axis of the <see cref="AABB"/>.</returns>
public Vector3 GetLongestAxis()
{
var axis = new Vector3(1f, 0f, 0f);
- real_t max_size = _size.x;
+ real_t maxSize = _size.x;
- if (_size.y > max_size)
+ if (_size.y > maxSize)
{
axis = new Vector3(0f, 1f, 0f);
- max_size = _size.y;
+ maxSize = _size.y;
}
- if (_size.z > max_size)
+ if (_size.z > maxSize)
{
axis = new Vector3(0f, 0f, 1f);
}
@@ -185,21 +193,21 @@ namespace Godot
}
/// <summary>
- /// Returns the <see cref="Vector3.Axis"/> index of the longest axis of the AABB.
+ /// Returns the <see cref="Vector3.Axis"/> index of the longest axis of the <see cref="AABB"/>.
/// </summary>
/// <returns>A <see cref="Vector3.Axis"/> index for which axis is longest.</returns>
public Vector3.Axis GetLongestAxisIndex()
{
var axis = Vector3.Axis.X;
- real_t max_size = _size.x;
+ real_t maxSize = _size.x;
- if (_size.y > max_size)
+ if (_size.y > maxSize)
{
axis = Vector3.Axis.Y;
- max_size = _size.y;
+ maxSize = _size.y;
}
- if (_size.z > max_size)
+ if (_size.z > maxSize)
{
axis = Vector3.Axis.Z;
}
@@ -208,38 +216,38 @@ namespace Godot
}
/// <summary>
- /// Returns the scalar length of the longest axis of the AABB.
+ /// Returns the scalar length of the longest axis of the <see cref="AABB"/>.
/// </summary>
- /// <returns>The scalar length of the longest axis of the AABB.</returns>
+ /// <returns>The scalar length of the longest axis of the <see cref="AABB"/>.</returns>
public real_t GetLongestAxisSize()
{
- real_t max_size = _size.x;
+ real_t maxSize = _size.x;
- if (_size.y > max_size)
- max_size = _size.y;
+ if (_size.y > maxSize)
+ maxSize = _size.y;
- if (_size.z > max_size)
- max_size = _size.z;
+ if (_size.z > maxSize)
+ maxSize = _size.z;
- return max_size;
+ return maxSize;
}
/// <summary>
- /// Returns the normalized shortest axis of the AABB.
+ /// Returns the normalized shortest axis of the <see cref="AABB"/>.
/// </summary>
- /// <returns>A vector representing the normalized shortest axis of the AABB.</returns>
+ /// <returns>A vector representing the normalized shortest axis of the <see cref="AABB"/>.</returns>
public Vector3 GetShortestAxis()
{
var axis = new Vector3(1f, 0f, 0f);
- real_t max_size = _size.x;
+ real_t maxSize = _size.x;
- if (_size.y < max_size)
+ if (_size.y < maxSize)
{
axis = new Vector3(0f, 1f, 0f);
- max_size = _size.y;
+ maxSize = _size.y;
}
- if (_size.z < max_size)
+ if (_size.z < maxSize)
{
axis = new Vector3(0f, 0f, 1f);
}
@@ -248,21 +256,21 @@ namespace Godot
}
/// <summary>
- /// Returns the <see cref="Vector3.Axis"/> index of the shortest axis of the AABB.
+ /// Returns the <see cref="Vector3.Axis"/> index of the shortest axis of the <see cref="AABB"/>.
/// </summary>
/// <returns>A <see cref="Vector3.Axis"/> index for which axis is shortest.</returns>
public Vector3.Axis GetShortestAxisIndex()
{
var axis = Vector3.Axis.X;
- real_t max_size = _size.x;
+ real_t maxSize = _size.x;
- if (_size.y < max_size)
+ if (_size.y < maxSize)
{
axis = Vector3.Axis.Y;
- max_size = _size.y;
+ maxSize = _size.y;
}
- if (_size.z < max_size)
+ if (_size.z < maxSize)
{
axis = Vector3.Axis.Z;
}
@@ -271,20 +279,20 @@ namespace Godot
}
/// <summary>
- /// Returns the scalar length of the shortest axis of the AABB.
+ /// Returns the scalar length of the shortest axis of the <see cref="AABB"/>.
/// </summary>
- /// <returns>The scalar length of the shortest axis of the AABB.</returns>
+ /// <returns>The scalar length of the shortest axis of the <see cref="AABB"/>.</returns>
public real_t GetShortestAxisSize()
{
- real_t max_size = _size.x;
+ real_t maxSize = _size.x;
- if (_size.y < max_size)
- max_size = _size.y;
+ if (_size.y < maxSize)
+ maxSize = _size.y;
- if (_size.z < max_size)
- max_size = _size.z;
+ if (_size.z < maxSize)
+ maxSize = _size.z;
- return max_size;
+ return maxSize;
}
/// <summary>
@@ -295,23 +303,23 @@ namespace Godot
/// <returns>A vector representing the support.</returns>
public Vector3 GetSupport(Vector3 dir)
{
- Vector3 half_extents = _size * 0.5f;
- Vector3 ofs = _position + half_extents;
+ Vector3 halfExtents = _size * 0.5f;
+ Vector3 ofs = _position + halfExtents;
return ofs + new Vector3(
- dir.x > 0f ? -half_extents.x : half_extents.x,
- dir.y > 0f ? -half_extents.y : half_extents.y,
- dir.z > 0f ? -half_extents.z : half_extents.z);
+ dir.x > 0f ? -halfExtents.x : halfExtents.x,
+ dir.y > 0f ? -halfExtents.y : halfExtents.y,
+ dir.z > 0f ? -halfExtents.z : halfExtents.z);
}
/// <summary>
- /// Returns a copy of the AABB grown a given amount of units towards all the sides.
+ /// Returns a copy of the <see cref="AABB"/> grown a given amount of units towards all the sides.
/// </summary>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown AABB.</returns>
+ /// <returns>The grown <see cref="AABB"/>.</returns>
public AABB Grow(real_t by)
{
- var res = this;
+ AABB res = this;
res._position.x -= by;
res._position.y -= by;
@@ -324,28 +332,37 @@ namespace Godot
}
/// <summary>
- /// Returns true if the AABB is flat or empty, or false otherwise.
+ /// Returns <see langword="true"/> if the <see cref="AABB"/> is flat or empty,
+ /// or <see langword="false"/> otherwise.
/// </summary>
- /// <returns>A bool for whether or not the AABB has area.</returns>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not the <see cref="AABB"/> has area.
+ /// </returns>
public bool HasNoArea()
{
return _size.x <= 0f || _size.y <= 0f || _size.z <= 0f;
}
/// <summary>
- /// Returns true if the AABB has no surface (no size), or false otherwise.
+ /// Returns <see langword="true"/> if the <see cref="AABB"/> has no surface (no size),
+ /// or <see langword="false"/> otherwise.
/// </summary>
- /// <returns>A bool for whether or not the AABB has area.</returns>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not the <see cref="AABB"/> has area.
+ /// </returns>
public bool HasNoSurface()
{
return _size.x <= 0f && _size.y <= 0f && _size.z <= 0f;
}
/// <summary>
- /// Returns true if the AABB contains a point, or false otherwise.
+ /// Returns <see langword="true"/> if the <see cref="AABB"/> contains a point,
+ /// or <see langword="false"/> otherwise.
/// </summary>
/// <param name="point">The point to check.</param>
- /// <returns>A bool for whether or not the AABB contains `point`.</returns>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not the <see cref="AABB"/> contains <paramref name="point"/>.
+ /// </returns>
public bool HasPoint(Vector3 point)
{
if (point.x < _position.x)
@@ -365,56 +382,59 @@ namespace Godot
}
/// <summary>
- /// Returns the intersection of this AABB and `b`.
+ /// Returns the intersection of this <see cref="AABB"/> and <paramref name="with"/>.
/// </summary>
- /// <param name="with">The other AABB.</param>
- /// <returns>The clipped AABB.</returns>
+ /// <param name="with">The other <see cref="AABB"/>.</param>
+ /// <returns>The clipped <see cref="AABB"/>.</returns>
public AABB Intersection(AABB with)
{
- Vector3 src_min = _position;
- Vector3 src_max = _position + _size;
- Vector3 dst_min = with._position;
- Vector3 dst_max = with._position + with._size;
+ Vector3 srcMin = _position;
+ Vector3 srcMax = _position + _size;
+ Vector3 dstMin = with._position;
+ Vector3 dstMax = with._position + with._size;
Vector3 min, max;
- if (src_min.x > dst_max.x || src_max.x < dst_min.x)
+ if (srcMin.x > dstMax.x || srcMax.x < dstMin.x)
{
return new AABB();
}
- min.x = src_min.x > dst_min.x ? src_min.x : dst_min.x;
- max.x = src_max.x < dst_max.x ? src_max.x : dst_max.x;
+ min.x = srcMin.x > dstMin.x ? srcMin.x : dstMin.x;
+ max.x = srcMax.x < dstMax.x ? srcMax.x : dstMax.x;
- if (src_min.y > dst_max.y || src_max.y < dst_min.y)
+ if (srcMin.y > dstMax.y || srcMax.y < dstMin.y)
{
return new AABB();
}
- min.y = src_min.y > dst_min.y ? src_min.y : dst_min.y;
- max.y = src_max.y < dst_max.y ? src_max.y : dst_max.y;
+ min.y = srcMin.y > dstMin.y ? srcMin.y : dstMin.y;
+ max.y = srcMax.y < dstMax.y ? srcMax.y : dstMax.y;
- if (src_min.z > dst_max.z || src_max.z < dst_min.z)
+ if (srcMin.z > dstMax.z || srcMax.z < dstMin.z)
{
return new AABB();
}
- min.z = src_min.z > dst_min.z ? src_min.z : dst_min.z;
- max.z = src_max.z < dst_max.z ? src_max.z : dst_max.z;
+ min.z = srcMin.z > dstMin.z ? srcMin.z : dstMin.z;
+ max.z = srcMax.z < dstMax.z ? srcMax.z : dstMax.z;
return new AABB(min, max - min);
}
/// <summary>
- /// Returns true if the AABB overlaps with `b`
+ /// Returns <see langword="true"/> if the <see cref="AABB"/> overlaps with <paramref name="with"/>
/// (i.e. they have at least one point in common).
///
- /// If `includeBorders` is true, they will also be considered overlapping
- /// if their borders touch, even without intersection.
+ /// If <paramref name="includeBorders"/> is <see langword="true"/>,
+ /// they will also be considered overlapping if their borders touch,
+ /// even without intersection.
/// </summary>
- /// <param name="with">The other AABB to check for intersections with.</param>
+ /// <param name="with">The other <see cref="AABB"/> to check for intersections with.</param>
/// <param name="includeBorders">Whether or not to consider borders.</param>
- /// <returns>A bool for whether or not they are intersecting.</returns>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not they are intersecting.
+ /// </returns>
public bool Intersects(AABB with, bool includeBorders = false)
{
if (includeBorders)
@@ -452,10 +472,12 @@ namespace Godot
}
/// <summary>
- /// Returns true if the AABB is on both sides of `plane`.
+ /// Returns <see langword="true"/> if the <see cref="AABB"/> is on both sides of <paramref name="plane"/>.
/// </summary>
- /// <param name="plane">The plane to check for intersection.</param>
- /// <returns>A bool for whether or not the AABB intersects the plane.</returns>
+ /// <param name="plane">The <see cref="Plane"/> to check for intersection.</param>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not the <see cref="AABB"/> intersects the <see cref="Plane"/>.
+ /// </returns>
public bool IntersectsPlane(Plane plane)
{
Vector3[] points =
@@ -489,11 +511,14 @@ namespace Godot
}
/// <summary>
- /// Returns true if the AABB intersects the line segment between `from` and `to`.
+ /// Returns <see langword="true"/> if the <see cref="AABB"/> intersects
+ /// the line segment between <paramref name="from"/> and <paramref name="to"/>.
/// </summary>
/// <param name="from">The start of the line segment.</param>
/// <param name="to">The end of the line segment.</param>
- /// <returns>A bool for whether or not the AABB intersects the line segment.</returns>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not the <see cref="AABB"/> intersects the line segment.
+ /// </returns>
public bool IntersectsSegment(Vector3 from, Vector3 to)
{
real_t min = 0f;
@@ -549,10 +574,10 @@ namespace Godot
}
/// <summary>
- /// Returns a larger AABB that contains this AABB and `b`.
+ /// Returns a larger <see cref="AABB"/> that contains this <see cref="AABB"/> and <paramref name="with"/>.
/// </summary>
- /// <param name="with">The other AABB.</param>
- /// <returns>The merged AABB.</returns>
+ /// <param name="with">The other <see cref="AABB"/>.</param>
+ /// <returns>The merged <see cref="AABB"/>.</returns>
public AABB Merge(AABB with)
{
Vector3 beg1 = _position;
@@ -561,22 +586,22 @@ namespace Godot
var end2 = new Vector3(with._size.x, with._size.y, with._size.z) + beg2;
var min = new Vector3(
- beg1.x < beg2.x ? beg1.x : beg2.x,
- beg1.y < beg2.y ? beg1.y : beg2.y,
- beg1.z < beg2.z ? beg1.z : beg2.z
- );
+ beg1.x < beg2.x ? beg1.x : beg2.x,
+ beg1.y < beg2.y ? beg1.y : beg2.y,
+ beg1.z < beg2.z ? beg1.z : beg2.z
+ );
var max = new Vector3(
- end1.x > end2.x ? end1.x : end2.x,
- end1.y > end2.y ? end1.y : end2.y,
- end1.z > end2.z ? end1.z : end2.z
- );
+ end1.x > end2.x ? end1.x : end2.x,
+ end1.y > end2.y ? end1.y : end2.y,
+ end1.z > end2.z ? end1.z : end2.z
+ );
return new AABB(min, max - min);
}
/// <summary>
- /// Constructs an AABB from a position and size.
+ /// Constructs an <see cref="AABB"/> from a position and size.
/// </summary>
/// <param name="position">The position.</param>
/// <param name="size">The size, typically positive.</param>
@@ -587,7 +612,8 @@ namespace Godot
}
/// <summary>
- /// Constructs an AABB from a position, width, height, and depth.
+ /// Constructs an <see cref="AABB"/> from a <paramref name="position"/>,
+ /// <paramref name="width"/>, <paramref name="height"/>, and <paramref name="depth"/>.
/// </summary>
/// <param name="position">The position.</param>
/// <param name="width">The width, typically positive.</param>
@@ -600,7 +626,8 @@ namespace Godot
}
/// <summary>
- /// Constructs an AABB from x, y, z, and size.
+ /// Constructs an <see cref="AABB"/> from <paramref name="x"/>,
+ /// <paramref name="y"/>, <paramref name="z"/>, and <paramref name="size"/>.
/// </summary>
/// <param name="x">The position's X coordinate.</param>
/// <param name="y">The position's Y coordinate.</param>
@@ -613,7 +640,9 @@ namespace Godot
}
/// <summary>
- /// Constructs an AABB from x, y, z, width, height, and depth.
+ /// Constructs an <see cref="AABB"/> from <paramref name="x"/>,
+ /// <paramref name="y"/>, <paramref name="z"/>, <paramref name="width"/>,
+ /// <paramref name="height"/>, and <paramref name="depth"/>.
/// </summary>
/// <param name="x">The position's X coordinate.</param>
/// <param name="y">The position's Y coordinate.</param>
@@ -637,6 +666,11 @@ namespace Godot
return !left.Equals(right);
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this AABB and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the AABB structure and the other object are equal.</returns>
public override bool Equals(object obj)
{
if (obj is AABB)
@@ -647,32 +681,49 @@ namespace Godot
return false;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this AABB and <paramref name="other"/> are equal
+ /// </summary>
+ /// <param name="other">The other AABB to compare.</param>
+ /// <returns>Whether or not the AABBs are equal.</returns>
public bool Equals(AABB other)
{
return _position == other._position && _size == other._size;
}
/// <summary>
- /// Returns true if this AABB and `other` are approximately equal, by running
- /// <see cref="Vector3.IsEqualApprox(Vector3)"/> on each component.
+ /// Returns <see langword="true"/> if this AABB and <paramref name="other"/> are approximately equal,
+ /// by running <see cref="Vector3.IsEqualApprox(Vector3)"/> on each component.
/// </summary>
/// <param name="other">The other AABB to compare.</param>
- /// <returns>Whether or not the AABBs are approximately equal.</returns>
+ /// <returns>Whether or not the AABBs structures are approximately equal.</returns>
public bool IsEqualApprox(AABB other)
{
return _position.IsEqualApprox(other._position) && _size.IsEqualApprox(other._size);
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="AABB"/>.
+ /// </summary>
+ /// <returns>A hash code for this AABB.</returns>
public override int GetHashCode()
{
return _position.GetHashCode() ^ _size.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="AABB"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this AABB.</returns>
public override string ToString()
{
return $"{_position}, {_size}";
}
+ /// <summary>
+ /// Converts this <see cref="AABB"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this AABB.</returns>
public string ToString(string format)
{
return $"{_position.ToString(format)}, {_size.ToString(format)}";
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
index f52a767018..a412047196 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
@@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
namespace Godot.Collections
{
- class ArraySafeHandle : SafeHandle
+ internal class ArraySafeHandle : SafeHandle
{
public ArraySafeHandle(IntPtr handle) : base(IntPtr.Zero, true)
{
@@ -33,15 +33,15 @@ namespace Godot.Collections
/// </summary>
public class Array : IList, IDisposable
{
- ArraySafeHandle safeHandle;
- bool disposed = false;
+ private ArraySafeHandle _safeHandle;
+ private bool _disposed = false;
/// <summary>
/// Constructs a new empty <see cref="Array"/>.
/// </summary>
public Array()
{
- safeHandle = new ArraySafeHandle(godot_icall_Array_Ctor());
+ _safeHandle = new ArraySafeHandle(godot_icall_Array_Ctor());
}
/// <summary>
@@ -69,31 +69,31 @@ namespace Godot.Collections
{
throw new NullReferenceException($"Parameter '{nameof(array)} cannot be null.'");
}
- safeHandle = new ArraySafeHandle(godot_icall_Array_Ctor_MonoArray(array));
+ _safeHandle = new ArraySafeHandle(godot_icall_Array_Ctor_MonoArray(array));
}
internal Array(ArraySafeHandle handle)
{
- safeHandle = handle;
+ _safeHandle = handle;
}
internal Array(IntPtr handle)
{
- safeHandle = new ArraySafeHandle(handle);
+ _safeHandle = new ArraySafeHandle(handle);
}
internal IntPtr GetPtr()
{
- if (disposed)
+ if (_disposed)
throw new ObjectDisposedException(GetType().FullName);
- return safeHandle.DangerousGetHandle();
+ return _safeHandle.DangerousGetHandle();
}
/// <summary>
/// Duplicates this <see cref="Array"/>.
/// </summary>
- /// <param name="deep">If true, performs a deep copy.</param>
+ /// <param name="deep">If <see langword="true"/>, performs a deep copy.</param>
/// <returns>A new Godot Array.</returns>
public Array Duplicate(bool deep = false)
{
@@ -136,16 +136,16 @@ namespace Godot.Collections
/// </summary>
public void Dispose()
{
- if (disposed)
+ if (_disposed)
return;
- if (safeHandle != null)
+ if (_safeHandle != null)
{
- safeHandle.Dispose();
- safeHandle = null;
+ _safeHandle.Dispose();
+ _safeHandle = null;
}
- disposed = true;
+ _disposed = true;
}
// IList
@@ -155,9 +155,9 @@ namespace Godot.Collections
bool IList.IsFixedSize => false;
/// <summary>
- /// Returns the object at the given index.
+ /// Returns the object at the given <paramref name="index"/>.
/// </summary>
- /// <value>The object at the given index.</value>
+ /// <value>The object at the given <paramref name="index"/>.</value>
public object this[int index]
{
get => godot_icall_Array_At(GetPtr(), index);
@@ -166,7 +166,7 @@ namespace Godot.Collections
/// <summary>
/// Adds an object to the end of this <see cref="Array"/>.
- /// This is the same as `append` or `push_back` in GDScript.
+ /// This is the same as <c>append</c> or <c>push_back</c> in GDScript.
/// </summary>
/// <param name="value">The object to add.</param>
/// <returns>The new size after adding the object.</returns>
@@ -203,7 +203,7 @@ namespace Godot.Collections
public void Insert(int index, object value) => godot_icall_Array_Insert(GetPtr(), index, value);
/// <summary>
- /// Removes the first occurrence of the specified value
+ /// Removes the first occurrence of the specified <paramref name="value"/>
/// from this <see cref="Array"/>.
/// </summary>
/// <param name="value">The value to remove.</param>
@@ -272,67 +272,67 @@ namespace Godot.Collections
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Array_Ctor();
+ internal static extern IntPtr godot_icall_Array_Ctor();
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Array_Ctor_MonoArray(System.Array array);
+ internal static extern IntPtr godot_icall_Array_Ctor_MonoArray(System.Array array);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_Dtor(IntPtr ptr);
+ internal static extern void godot_icall_Array_Dtor(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static object godot_icall_Array_At(IntPtr ptr, int index);
+ internal static extern object godot_icall_Array_At(IntPtr ptr, int index);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static object godot_icall_Array_At_Generic(IntPtr ptr, int index, int elemTypeEncoding, IntPtr elemTypeClass);
+ internal static extern object godot_icall_Array_At_Generic(IntPtr ptr, int index, int elemTypeEncoding, IntPtr elemTypeClass);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_SetAt(IntPtr ptr, int index, object value);
+ internal static extern void godot_icall_Array_SetAt(IntPtr ptr, int index, object value);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_Array_Count(IntPtr ptr);
+ internal static extern int godot_icall_Array_Count(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_Array_Add(IntPtr ptr, object item);
+ internal static extern int godot_icall_Array_Add(IntPtr ptr, object item);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_Clear(IntPtr ptr);
+ internal static extern void godot_icall_Array_Clear(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Array_Concatenate(IntPtr left, IntPtr right);
+ internal static extern IntPtr godot_icall_Array_Concatenate(IntPtr left, IntPtr right);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Array_Contains(IntPtr ptr, object item);
+ internal static extern bool godot_icall_Array_Contains(IntPtr ptr, object item);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_CopyTo(IntPtr ptr, System.Array array, int arrayIndex);
+ internal static extern void godot_icall_Array_CopyTo(IntPtr ptr, System.Array array, int arrayIndex);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Array_Duplicate(IntPtr ptr, bool deep);
+ internal static extern IntPtr godot_icall_Array_Duplicate(IntPtr ptr, bool deep);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_Array_IndexOf(IntPtr ptr, object item);
+ internal static extern int godot_icall_Array_IndexOf(IntPtr ptr, object item);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_Insert(IntPtr ptr, int index, object item);
+ internal static extern void godot_icall_Array_Insert(IntPtr ptr, int index, object item);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Array_Remove(IntPtr ptr, object item);
+ internal static extern bool godot_icall_Array_Remove(IntPtr ptr, object item);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_RemoveAt(IntPtr ptr, int index);
+ internal static extern void godot_icall_Array_RemoveAt(IntPtr ptr, int index);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static Error godot_icall_Array_Resize(IntPtr ptr, int newSize);
+ internal static extern Error godot_icall_Array_Resize(IntPtr ptr, int newSize);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static Error godot_icall_Array_Shuffle(IntPtr ptr);
+ internal static extern Error godot_icall_Array_Shuffle(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_Generic_GetElementTypeInfo(Type elemType, out int elemTypeEncoding, out IntPtr elemTypeClass);
+ internal static extern void godot_icall_Array_Generic_GetElementTypeInfo(Type elemType, out int elemTypeEncoding, out IntPtr elemTypeClass);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string godot_icall_Array_ToString(IntPtr ptr);
+ internal static extern string godot_icall_Array_ToString(IntPtr ptr);
}
/// <summary>
@@ -344,7 +344,7 @@ namespace Godot.Collections
/// <typeparam name="T">The type of the array.</typeparam>
public class Array<T> : IList<T>, ICollection<T>, IEnumerable<T>
{
- Array objectArray;
+ private Array _objectArray;
internal static int elemTypeEncoding;
internal static IntPtr elemTypeClass;
@@ -359,7 +359,7 @@ namespace Godot.Collections
/// </summary>
public Array()
{
- objectArray = new Array();
+ _objectArray = new Array();
}
/// <summary>
@@ -372,7 +372,7 @@ namespace Godot.Collections
if (collection == null)
throw new NullReferenceException($"Parameter '{nameof(collection)} cannot be null.'");
- objectArray = new Array(collection);
+ _objectArray = new Array(collection);
}
/// <summary>
@@ -386,7 +386,7 @@ namespace Godot.Collections
{
throw new NullReferenceException($"Parameter '{nameof(array)} cannot be null.'");
}
- objectArray = new Array(array);
+ _objectArray = new Array(array);
}
/// <summary>
@@ -395,22 +395,22 @@ namespace Godot.Collections
/// <param name="array">The untyped array to construct from.</param>
public Array(Array array)
{
- objectArray = array;
+ _objectArray = array;
}
internal Array(IntPtr handle)
{
- objectArray = new Array(handle);
+ _objectArray = new Array(handle);
}
internal Array(ArraySafeHandle handle)
{
- objectArray = new Array(handle);
+ _objectArray = new Array(handle);
}
internal IntPtr GetPtr()
{
- return objectArray.GetPtr();
+ return _objectArray.GetPtr();
}
/// <summary>
@@ -419,17 +419,17 @@ namespace Godot.Collections
/// <param name="from">The typed array to convert.</param>
public static explicit operator Array(Array<T> from)
{
- return from.objectArray;
+ return from._objectArray;
}
/// <summary>
/// Duplicates this <see cref="Array{T}"/>.
/// </summary>
- /// <param name="deep">If true, performs a deep copy.</param>
+ /// <param name="deep">If <see langword="true"/>, performs a deep copy.</param>
/// <returns>A new Godot Array.</returns>
public Array<T> Duplicate(bool deep = false)
{
- return new Array<T>(objectArray.Duplicate(deep));
+ return new Array<T>(_objectArray.Duplicate(deep));
}
/// <summary>
@@ -439,7 +439,7 @@ namespace Godot.Collections
/// <returns><see cref="Error.Ok"/> if successful, or an error code.</returns>
public Error Resize(int newSize)
{
- return objectArray.Resize(newSize);
+ return _objectArray.Resize(newSize);
}
/// <summary>
@@ -447,7 +447,7 @@ namespace Godot.Collections
/// </summary>
public void Shuffle()
{
- objectArray.Shuffle();
+ _objectArray.Shuffle();
}
/// <summary>
@@ -458,19 +458,19 @@ namespace Godot.Collections
/// <returns>A new Godot Array with the contents of both arrays.</returns>
public static Array<T> operator +(Array<T> left, Array<T> right)
{
- return new Array<T>(left.objectArray + right.objectArray);
+ return new Array<T>(left._objectArray + right._objectArray);
}
// IList<T>
/// <summary>
- /// Returns the value at the given index.
+ /// Returns the value at the given <paramref name="index"/>.
/// </summary>
- /// <value>The value at the given index.</value>
+ /// <value>The value at the given <paramref name="index"/>.</value>
public T this[int index]
{
get { return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass); }
- set { objectArray[index] = value; }
+ set { _objectArray[index] = value; }
}
/// <summary>
@@ -481,7 +481,7 @@ namespace Godot.Collections
/// <returns>The index of the item, or -1 if not found.</returns>
public int IndexOf(T item)
{
- return objectArray.IndexOf(item);
+ return _objectArray.IndexOf(item);
}
/// <summary>
@@ -494,7 +494,7 @@ namespace Godot.Collections
/// <param name="item">The item to insert.</param>
public void Insert(int index, T item)
{
- objectArray.Insert(index, item);
+ _objectArray.Insert(index, item);
}
/// <summary>
@@ -503,7 +503,7 @@ namespace Godot.Collections
/// <param name="index">The index of the element to remove.</param>
public void RemoveAt(int index)
{
- objectArray.RemoveAt(index);
+ _objectArray.RemoveAt(index);
}
// ICollection<T>
@@ -515,20 +515,20 @@ namespace Godot.Collections
/// <returns>The number of elements.</returns>
public int Count
{
- get { return objectArray.Count; }
+ get { return _objectArray.Count; }
}
bool ICollection<T>.IsReadOnly => false;
/// <summary>
/// Adds an item to the end of this <see cref="Array{T}"/>.
- /// This is the same as `append` or `push_back` in GDScript.
+ /// This is the same as <c>append</c> or <c>push_back</c> in GDScript.
/// </summary>
/// <param name="item">The item to add.</param>
/// <returns>The new size after adding the item.</returns>
public void Add(T item)
{
- objectArray.Add(item);
+ _objectArray.Add(item);
}
/// <summary>
@@ -536,7 +536,7 @@ namespace Godot.Collections
/// </summary>
public void Clear()
{
- objectArray.Clear();
+ _objectArray.Clear();
}
/// <summary>
@@ -546,7 +546,7 @@ namespace Godot.Collections
/// <returns>Whether or not this array contains the given item.</returns>
public bool Contains(T item)
{
- return objectArray.Contains(item);
+ return _objectArray.Contains(item);
}
/// <summary>
@@ -566,7 +566,7 @@ namespace Godot.Collections
// TODO This may be quite slow because every element access is an internal call.
// It could be moved entirely to an internal call if we find out how to do the cast there.
- int count = objectArray.Count;
+ int count = _objectArray.Count;
if (array.Length < (arrayIndex + count))
throw new ArgumentException("Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
@@ -583,7 +583,7 @@ namespace Godot.Collections
/// from this <see cref="Array{T}"/>.
/// </summary>
/// <param name="item">The value to remove.</param>
- /// <returns>A bool indicating success or failure.</returns>
+ /// <returns>A <see langword="bool"/> indicating success or failure.</returns>
public bool Remove(T item)
{
return Array.godot_icall_Array_Remove(GetPtr(), item);
@@ -597,7 +597,7 @@ namespace Godot.Collections
/// <returns>An enumerator.</returns>
public IEnumerator<T> GetEnumerator()
{
- int count = objectArray.Count;
+ int count = _objectArray.Count;
for (int i = 0; i < count; i++)
{
@@ -614,6 +614,6 @@ namespace Godot.Collections
/// Converts this <see cref="Array{T}"/> to a string.
/// </summary>
/// <returns>A string representation of this array.</returns>
- public override string ToString() => objectArray.ToString();
+ public override string ToString() => _objectArray.ToString();
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs
index ac6cffceb2..e93bc89811 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs
@@ -3,7 +3,5 @@ using System;
namespace Godot
{
[AttributeUsage(AttributeTargets.Class)]
- public class DisableGodotGeneratorsAttribute : Attribute
- {
- }
+ public class DisableGodotGeneratorsAttribute : Attribute { }
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs
index 8aaa9e849d..2dedba2be3 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs
@@ -3,8 +3,8 @@ using System;
namespace Godot
{
[AttributeUsage(AttributeTargets.Method)]
- public class RemoteAttribute : Attribute {}
+ public class RemoteAttribute : Attribute { }
[AttributeUsage(AttributeTargets.Method)]
- public class PuppetAttribute : Attribute {}
+ public class PuppetAttribute : Attribute { }
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs
index 39d5782db8..07a214f543 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs
@@ -3,7 +3,5 @@ using System;
namespace Godot
{
[AttributeUsage(AttributeTargets.Delegate | AttributeTargets.Event)]
- public class SignalAttribute : Attribute
- {
- }
+ public class SignalAttribute : Attribute { }
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs
index d0437409af..d2344389f4 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs
@@ -3,5 +3,5 @@ using System;
namespace Godot
{
[AttributeUsage(AttributeTargets.Class)]
- public class ToolAttribute : Attribute {}
+ public class ToolAttribute : Attribute { }
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
index 968f853c2d..0fb1df6c2f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
@@ -31,7 +31,7 @@ namespace Godot
/// <summary>
/// The basis matrix's X vector (column 0).
/// </summary>
- /// <value>Equivalent to <see cref="Column0"/> and array index `[0]`.</value>
+ /// <value>Equivalent to <see cref="Column0"/> and array index <c>[0]</c>.</value>
public Vector3 x
{
get => Column0;
@@ -41,7 +41,7 @@ namespace Godot
/// <summary>
/// The basis matrix's Y vector (column 1).
/// </summary>
- /// <value>Equivalent to <see cref="Column1"/> and array index `[1]`.</value>
+ /// <value>Equivalent to <see cref="Column1"/> and array index <c>[1]</c>.</value>
public Vector3 y
{
get => Column1;
@@ -51,7 +51,7 @@ namespace Godot
/// <summary>
/// The basis matrix's Z vector (column 2).
/// </summary>
- /// <value>Equivalent to <see cref="Column2"/> and array index `[2]`.</value>
+ /// <value>Equivalent to <see cref="Column2"/> and array index <c>[2]</c>.</value>
public Vector3 z
{
get => Column2;
@@ -82,45 +82,45 @@ namespace Godot
/// <summary>
/// Column 0 of the basis matrix (the X vector).
/// </summary>
- /// <value>Equivalent to <see cref="x"/> and array index `[0]`.</value>
+ /// <value>Equivalent to <see cref="x"/> and array index <c>[0]</c>.</value>
public Vector3 Column0
{
get => new Vector3(Row0.x, Row1.x, Row2.x);
set
{
- this.Row0.x = value.x;
- this.Row1.x = value.y;
- this.Row2.x = value.z;
+ Row0.x = value.x;
+ Row1.x = value.y;
+ Row2.x = value.z;
}
}
/// <summary>
/// Column 1 of the basis matrix (the Y vector).
/// </summary>
- /// <value>Equivalent to <see cref="y"/> and array index `[1]`.</value>
+ /// <value>Equivalent to <see cref="y"/> and array index <c>[1]</c>.</value>
public Vector3 Column1
{
get => new Vector3(Row0.y, Row1.y, Row2.y);
set
{
- this.Row0.y = value.x;
- this.Row1.y = value.y;
- this.Row2.y = value.z;
+ Row0.y = value.x;
+ Row1.y = value.y;
+ Row2.y = value.z;
}
}
/// <summary>
/// Column 2 of the basis matrix (the Z vector).
/// </summary>
- /// <value>Equivalent to <see cref="z"/> and array index `[2]`.</value>
+ /// <value>Equivalent to <see cref="z"/> and array index <c>[2]</c>.</value>
public Vector3 Column2
{
get => new Vector3(Row0.z, Row1.z, Row2.z);
set
{
- this.Row0.z = value.x;
- this.Row1.z = value.y;
- this.Row2.z = value.z;
+ Row0.z = value.x;
+ Row1.z = value.y;
+ Row2.z = value.z;
}
}
@@ -150,9 +150,10 @@ namespace Godot
}
/// <summary>
- /// Access whole columns in the form of Vector3.
+ /// Access whole columns in the form of <see cref="Vector3"/>.
/// </summary>
/// <param name="column">Which column vector.</param>
+ /// <value>The basis column.</value>
public Vector3 this[int column]
{
get
@@ -193,6 +194,7 @@ namespace Godot
/// </summary>
/// <param name="column">Which column, the matrix horizontal position.</param>
/// <param name="row">Which row, the matrix vertical position.</param>
+ /// <value>The matrix element.</value>
public real_t this[int column, int row]
{
get
@@ -207,6 +209,13 @@ namespace Godot
}
}
+ /// <summary>
+ /// Returns the <see cref="Basis"/>'s rotation in the form of a
+ /// <see cref="Quaternion"/>. See <see cref="GetEuler"/> if you
+ /// need Euler angles, but keep in mind quaternions should generally
+ /// be preferred to Euler angles.
+ /// </summary>
+ /// <returns>The basis rotation.</returns>
public Quaternion GetRotationQuaternion()
{
Basis orthonormalizedBasis = Orthonormalized();
@@ -263,10 +272,10 @@ namespace Godot
/// The returned vector contains the rotation angles in
/// the format (X angle, Y angle, Z angle).
///
- /// Consider using the <see cref="Basis.Quaternion()"/> method instead, which
+ /// Consider using the <see cref="Quaternion()"/> method instead, which
/// returns a <see cref="Godot.Quaternion"/> quaternion instead of Euler angles.
/// </summary>
- /// <returns>A Vector3 representing the basis rotation in Euler angles.</returns>
+ /// <returns>A <see cref="Vector3"/> representing the basis rotation in Euler angles.</returns>
public Vector3 GetEuler()
{
Basis m = Orthonormalized();
@@ -304,7 +313,10 @@ namespace Godot
/// but are more efficient for some internal calculations.
/// </summary>
/// <param name="index">Which row.</param>
- /// <returns>One of `Row0`, `Row1`, or `Row2`.</returns>
+ /// <exception cref="IndexOutOfRangeException">
+ /// Thrown when the <paramref name="index"/> is not 0, 1 or 2.
+ /// </exception>
+ /// <returns>One of <c>Row0</c>, <c>Row1</c>, or <c>Row2</c>.</returns>
public Vector3 GetRow(int index)
{
switch (index)
@@ -326,6 +338,9 @@ namespace Godot
/// </summary>
/// <param name="index">Which row.</param>
/// <param name="value">The vector to set the row to.</param>
+ /// <exception cref="IndexOutOfRangeException">
+ /// Thrown when the <paramref name="index"/> is not 0, 1 or 2.
+ /// </exception>
public void SetRow(int index, Vector3 value)
{
switch (index)
@@ -452,8 +467,8 @@ namespace Godot
}
/// <summary>
- /// Introduce an additional rotation around the given `axis`
- /// by `phi` (in radians). The axis must be a normalized vector.
+ /// Introduce an additional rotation around the given <paramref name="axis"/>
+ /// by <paramref name="phi"/> (in radians). The axis must be a normalized vector.
/// </summary>
/// <param name="axis">The axis to rotate around. Must be normalized.</param>
/// <param name="phi">The angle to rotate, in radians.</param>
@@ -504,7 +519,7 @@ namespace Godot
/// <returns>The resulting dot product.</returns>
public real_t Tdotx(Vector3 with)
{
- return this.Row0[0] * with[0] + this.Row1[0] * with[1] + this.Row2[0] * with[2];
+ return Row0[0] * with[0] + Row1[0] * with[1] + Row2[0] * with[2];
}
/// <summary>
@@ -514,7 +529,7 @@ namespace Godot
/// <returns>The resulting dot product.</returns>
public real_t Tdoty(Vector3 with)
{
- return this.Row0[1] * with[0] + this.Row1[1] * with[1] + this.Row2[1] * with[2];
+ return Row0[1] * with[0] + Row1[1] * with[1] + Row2[1] * with[2];
}
/// <summary>
@@ -524,7 +539,7 @@ namespace Godot
/// <returns>The resulting dot product.</returns>
public real_t Tdotz(Vector3 with)
{
- return this.Row0[2] * with[0] + this.Row1[2] * with[1] + this.Row2[2] * with[2];
+ return Row0[2] * with[0] + Row1[2] * with[1] + Row2[2] * with[2];
}
/// <summary>
@@ -533,7 +548,7 @@ namespace Godot
/// <returns>The transposed basis matrix.</returns>
public Basis Transposed()
{
- var tr = this;
+ Basis tr = this;
real_t temp = tr.Row0[1];
tr.Row0[1] = tr.Row1[0];
@@ -553,15 +568,16 @@ namespace Godot
/// <summary>
/// Returns a vector transformed (multiplied) by the basis matrix.
/// </summary>
+ /// <seealso cref="XformInv(Vector3)"/>
/// <param name="v">A vector to transform.</param>
/// <returns>The transformed vector.</returns>
public Vector3 Xform(Vector3 v)
{
return new Vector3
(
- this.Row0.Dot(v),
- this.Row1.Dot(v),
- this.Row2.Dot(v)
+ Row0.Dot(v),
+ Row1.Dot(v),
+ Row2.Dot(v)
);
}
@@ -571,15 +587,16 @@ namespace Godot
/// Note: This results in a multiplication by the inverse of the
/// basis matrix only if it represents a rotation-reflection.
/// </summary>
+ /// <seealso cref="Xform(Vector3)"/>
/// <param name="v">A vector to inversely transform.</param>
/// <returns>The inversely transformed vector.</returns>
public Vector3 XformInv(Vector3 v)
{
return new Vector3
(
- this.Row0[0] * v.x + this.Row1[0] * v.y + this.Row2[0] * v.z,
- this.Row0[1] * v.x + this.Row1[1] * v.y + this.Row2[1] * v.z,
- this.Row0[2] * v.x + this.Row1[2] * v.y + this.Row2[2] * v.z
+ Row0[0] * v.x + Row1[0] * v.y + Row2[0] * v.z,
+ Row0[1] * v.x + Row1[1] * v.y + Row2[1] * v.z,
+ Row0[2] * v.x + Row1[2] * v.y + Row2[2] * v.z
);
}
@@ -675,25 +692,25 @@ namespace Godot
/// <summary>
/// The identity basis, with no rotation or scaling applied.
- /// This is used as a replacement for `Basis()` in GDScript.
- /// Do not use `new Basis()` with no arguments in C#, because it sets all values to zero.
+ /// This is used as a replacement for <c>Basis()</c> in GDScript.
+ /// Do not use <c>new Basis()</c> with no arguments in C#, because it sets all values to zero.
/// </summary>
- /// <value>Equivalent to `new Basis(Vector3.Right, Vector3.Up, Vector3.Back)`.</value>
+ /// <value>Equivalent to <c>new Basis(Vector3.Right, Vector3.Up, Vector3.Back)</c>.</value>
public static Basis Identity { get { return _identity; } }
/// <summary>
/// The basis that will flip something along the X axis when used in a transformation.
/// </summary>
- /// <value>Equivalent to `new Basis(Vector3.Left, Vector3.Up, Vector3.Back)`.</value>
+ /// <value>Equivalent to <c>new Basis(Vector3.Left, Vector3.Up, Vector3.Back)</c>.</value>
public static Basis FlipX { get { return _flipX; } }
/// <summary>
/// The basis that will flip something along the Y axis when used in a transformation.
/// </summary>
- /// <value>Equivalent to `new Basis(Vector3.Right, Vector3.Down, Vector3.Back)`.</value>
+ /// <value>Equivalent to <c>new Basis(Vector3.Right, Vector3.Down, Vector3.Back)</c>.</value>
public static Basis FlipY { get { return _flipY; } }
/// <summary>
/// The basis that will flip something along the Z axis when used in a transformation.
/// </summary>
- /// <value>Equivalent to `new Basis(Vector3.Right, Vector3.Up, Vector3.Forward)`.</value>
+ /// <value>Equivalent to <c>new Basis(Vector3.Right, Vector3.Up, Vector3.Forward)</c>.</value>
public static Basis FlipZ { get { return _flipZ; } }
/// <summary>
@@ -752,8 +769,8 @@ namespace Godot
}
/// <summary>
- /// Constructs a pure rotation basis matrix, rotated around the given `axis`
- /// by `phi` (in radians). The axis must be a normalized vector.
+ /// Constructs a pure rotation basis matrix, rotated around the given <paramref name="axis"/>
+ /// by <paramref name="phi"/> (in radians). The axis must be a normalized vector.
/// </summary>
/// <param name="axis">The axis to rotate around. Must be normalized.</param>
/// <param name="phi">The angle to rotate, in radians.</param>
@@ -830,6 +847,11 @@ namespace Godot
return !left.Equals(right);
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this basis and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the basis and the other object are equal.</returns>
public override bool Equals(object obj)
{
if (obj is Basis)
@@ -840,32 +862,49 @@ namespace Godot
return false;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this basis and <paramref name="other"/> are equal
+ /// </summary>
+ /// <param name="other">The other basis to compare.</param>
+ /// <returns>Whether or not the bases are equal.</returns>
public bool Equals(Basis other)
{
return Row0.Equals(other.Row0) && Row1.Equals(other.Row1) && Row2.Equals(other.Row2);
}
/// <summary>
- /// Returns true if this basis and `other` are approximately equal, by running
- /// <see cref="Vector3.IsEqualApprox(Vector3)"/> on each component.
+ /// Returns <see langword="true"/> if this basis and <paramref name="other"/> are approximately equal,
+ /// by running <see cref="Vector3.IsEqualApprox(Vector3)"/> on each component.
/// </summary>
/// <param name="other">The other basis to compare.</param>
- /// <returns>Whether or not the matrices are approximately equal.</returns>
+ /// <returns>Whether or not the bases are approximately equal.</returns>
public bool IsEqualApprox(Basis other)
{
return Row0.IsEqualApprox(other.Row0) && Row1.IsEqualApprox(other.Row1) && Row2.IsEqualApprox(other.Row2);
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="Basis"/>.
+ /// </summary>
+ /// <returns>A hash code for this basis.</returns>
public override int GetHashCode()
{
return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="Basis"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this basis.</returns>
public override string ToString()
{
return $"[X: {x}, Y: {y}, Z: {z}]";
}
+ /// <summary>
+ /// Converts this <see cref="Basis"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this basis.</returns>
public string ToString(string format)
{
return $"[X: {x.ToString(format)}, Y: {y.ToString(format)}, Z: {z.ToString(format)}]";
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
index c85cc1884c..a28a46896b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
@@ -2,18 +2,58 @@ using System;
namespace Godot
{
+ /// <summary>
+ /// Callable is a first class object which can be held in variables and passed to functions.
+ /// It represents a given method in an Object, and is typically used for signal callbacks.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// public void PrintArgs(object ar1, object arg2, object arg3 = null)
+ /// {
+ /// GD.PrintS(arg1, arg2, arg3);
+ /// }
+ ///
+ /// public void Test()
+ /// {
+ /// // This Callable object will call the PrintArgs method defined above.
+ /// Callable callable = new Callable(this, nameof(PrintArgs));
+ /// callable.Call("hello", "world"); // Prints "hello world null".
+ /// callable.Call(Vector2.Up, 42, callable); // Prints "(0, -1) 42 Node(Node.cs)::PrintArgs".
+ /// callable.Call("invalid"); // Invalid call, should have at least 2 arguments.
+ /// }
+ /// </code>
+ /// </example>
public struct Callable
{
private readonly Object _target;
private readonly StringName _method;
private readonly Delegate _delegate;
+ /// <summary>
+ /// Object that contains the method.
+ /// </summary>
public Object Target => _target;
+ /// <summary>
+ /// Name of the method that will be called.
+ /// </summary>
public StringName Method => _method;
+ /// <summary>
+ /// Delegate of the method that will be called.
+ /// </summary>
public Delegate Delegate => _delegate;
+ /// <summary>
+ /// Converts a <see cref="Delegate"/> to a <see cref="Callable"/>.
+ /// </summary>
+ /// <param name="delegate">The delegate to convert.</param>
public static implicit operator Callable(Delegate @delegate) => new Callable(@delegate);
+ /// <summary>
+ /// Constructs a new <see cref="Callable"/> for the method called <paramref name="method"/>
+ /// in the specified <paramref name="target"/>.
+ /// </summary>
+ /// <param name="target">Object that contains the method.</param>
+ /// <param name="method">Name of the method that will be called.</param>
public Callable(Object target, StringName method)
{
_target = target;
@@ -21,6 +61,10 @@ namespace Godot
_delegate = null;
}
+ /// <summary>
+ /// Constructs a new <see cref="Callable"/> for the given <paramref name="delegate"/>.
+ /// </summary>
+ /// <param name="delegate">Delegate method that will be called.</param>
public Callable(Delegate @delegate)
{
_target = null;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
index b9a98ba9c7..2a869bc335 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
@@ -7,11 +7,11 @@ namespace Godot
/// A color represented by red, green, blue, and alpha (RGBA) components.
/// The alpha component is often used for transparency.
/// Values are in floating-point and usually range from 0 to 1.
- /// Some properties (such as CanvasItem.modulate) may accept values
+ /// Some properties (such as <see cref="CanvasItem.Modulate"/>) may accept values
/// greater than 1 (overbright or HDR colors).
///
/// If you want to supply values in a range of 0 to 255, you should use
- /// <see cref="Color8"/> and the `r8`/`g8`/`b8`/`a8` properties.
+ /// <see cref="Color8"/> and the <c>r8</c>/<c>g8</c>/<c>b8</c>/<c>a8</c> properties.
/// </summary>
[Serializable]
[StructLayout(LayoutKind.Sequential)]
@@ -127,11 +127,11 @@ namespace Godot
}
else if (g == max)
{
- h = 2 + (b - r) / delta; // Between cyan & yellow
+ h = 2 + ((b - r) / delta); // Between cyan & yellow
}
else
{
- h = 4 + (r - g) / delta; // Between magenta & cyan
+ h = 4 + ((r - g) / delta); // Between magenta & cyan
}
h /= 6.0f;
@@ -173,7 +173,7 @@ namespace Godot
/// <summary>
/// The HSV value (brightness) of this color, on the range 0 to 1.
/// </summary>
- /// <value>Getting is equivalent to using `Max()` on the RGB components. Setting uses <see cref="FromHSV"/>.</value>
+ /// <value>Getting is equivalent to using <see cref="Math.Max(float, float)"/> on the RGB components. Setting uses <see cref="FromHSV"/>.</value>
public float v
{
get
@@ -189,7 +189,12 @@ namespace Godot
/// <summary>
/// Access color components using their index.
/// </summary>
- /// <value>`[0]` is equivalent to `.r`, `[1]` is equivalent to `.g`, `[2]` is equivalent to `.b`, `[3]` is equivalent to `.a`.</value>
+ /// <value>
+ /// <c>[0]</c> is equivalent to <see cref="r"/>,
+ /// <c>[1]</c> is equivalent to <see cref="g"/>,
+ /// <c>[2]</c> is equivalent to <see cref="b"/>,
+ /// <c>[3]</c> is equivalent to <see cref="a"/>.
+ /// </value>
public float this[int index]
{
get
@@ -236,30 +241,30 @@ namespace Godot
/// The second color may have a range of alpha values.
/// </summary>
/// <param name="over">The color to blend over.</param>
- /// <returns>This color blended over `over`.</returns>
+ /// <returns>This color blended over <paramref name="over"/>.</returns>
public Color Blend(Color over)
{
Color res;
float sa = 1.0f - over.a;
- res.a = a * sa + over.a;
+ res.a = (a * sa) + over.a;
if (res.a == 0)
{
return new Color(0, 0, 0, 0);
}
- res.r = (r * a * sa + over.r * over.a) / res.a;
- res.g = (g * a * sa + over.g * over.a) / res.a;
- res.b = (b * a * sa + over.b * over.a) / res.a;
+ res.r = ((r * a * sa) + (over.r * over.a)) / res.a;
+ res.g = ((g * a * sa) + (over.g * over.a)) / res.a;
+ res.b = ((b * a * sa) + (over.b * over.a)) / res.a;
return res;
}
/// <summary>
/// Returns a new color with all components clamped between the
- /// components of `min` and `max` using
- /// <see cref="Mathf.Clamp(float, float, float)"/>.
+ /// components of <paramref name="min"/> and <paramref name="max"/>
+ /// using <see cref="Mathf.Clamp(float, float, float)"/>.
/// </summary>
/// <param name="min">The color with minimum allowed values.</param>
/// <param name="max">The color with maximum allowed values.</param>
@@ -286,14 +291,14 @@ namespace Godot
public Color Darkened(float amount)
{
Color res = this;
- res.r = res.r * (1.0f - amount);
- res.g = res.g * (1.0f - amount);
- res.b = res.b * (1.0f - amount);
+ res.r *= 1.0f - amount;
+ res.g *= 1.0f - amount;
+ res.b *= 1.0f - amount;
return res;
}
/// <summary>
- /// Returns the inverted color: `(1 - r, 1 - g, 1 - b, a)`.
+ /// Returns the inverted color: <c>(1 - r, 1 - g, 1 - b, a)</c>.
/// </summary>
/// <returns>The inverted color.</returns>
public Color Inverted()
@@ -315,15 +320,15 @@ namespace Godot
public Color Lightened(float amount)
{
Color res = this;
- res.r = res.r + (1.0f - res.r) * amount;
- res.g = res.g + (1.0f - res.g) * amount;
- res.b = res.b + (1.0f - res.b) * amount;
+ res.r += (1.0f - res.r) * amount;
+ res.g += (1.0f - res.g) * amount;
+ res.b += (1.0f - res.b) * amount;
return res;
}
/// <summary>
/// Returns the result of the linear interpolation between
- /// this color and `to` by amount `weight`.
+ /// this color and <paramref name="to"/> by amount <paramref name="weight"/>.
/// </summary>
/// <param name="to">The destination color for interpolation.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
@@ -341,7 +346,7 @@ namespace Godot
/// <summary>
/// Returns the result of the linear interpolation between
- /// this color and `to` by color amount `weight`.
+ /// this color and <paramref name="to"/> by color amount <paramref name="weight"/>.
/// </summary>
/// <param name="to">The destination color for interpolation.</param>
/// <param name="weight">A color with components on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
@@ -362,7 +367,7 @@ namespace Godot
/// format (each byte represents a color channel).
/// ABGR is the reversed version of the default format.
/// </summary>
- /// <returns>A uint representing this color in ABGR32 format.</returns>
+ /// <returns>A <see langword="uint"/> representing this color in ABGR32 format.</returns>
public uint ToAbgr32()
{
uint c = (byte)Math.Round(a * 255);
@@ -381,7 +386,7 @@ namespace Godot
/// format (each word represents a color channel).
/// ABGR is the reversed version of the default format.
/// </summary>
- /// <returns>A ulong representing this color in ABGR64 format.</returns>
+ /// <returns>A <see langword="ulong"/> representing this color in ABGR64 format.</returns>
public ulong ToAbgr64()
{
ulong c = (ushort)Math.Round(a * 65535);
@@ -400,7 +405,7 @@ namespace Godot
/// format (each byte represents a color channel).
/// ARGB is more compatible with DirectX, but not used much in Godot.
/// </summary>
- /// <returns>A uint representing this color in ARGB32 format.</returns>
+ /// <returns>A <see langword="uint"/> representing this color in ARGB32 format.</returns>
public uint ToArgb32()
{
uint c = (byte)Math.Round(a * 255);
@@ -419,7 +424,7 @@ namespace Godot
/// format (each word represents a color channel).
/// ARGB is more compatible with DirectX, but not used much in Godot.
/// </summary>
- /// <returns>A ulong representing this color in ARGB64 format.</returns>
+ /// <returns>A <see langword="ulong"/> representing this color in ARGB64 format.</returns>
public ulong ToArgb64()
{
ulong c = (ushort)Math.Round(a * 65535);
@@ -438,7 +443,7 @@ namespace Godot
/// format (each byte represents a color channel).
/// RGBA is Godot's default and recommended format.
/// </summary>
- /// <returns>A uint representing this color in RGBA32 format.</returns>
+ /// <returns>A <see langword="uint"/> representing this color in RGBA32 format.</returns>
public uint ToRgba32()
{
uint c = (byte)Math.Round(r * 255);
@@ -457,7 +462,7 @@ namespace Godot
/// format (each word represents a color channel).
/// RGBA is Godot's default and recommended format.
/// </summary>
- /// <returns>A ulong representing this color in RGBA64 format.</returns>
+ /// <returns>A <see langword="ulong"/> representing this color in RGBA64 format.</returns>
public ulong ToRgba64()
{
ulong c = (ushort)Math.Round(r * 65535);
@@ -474,11 +479,13 @@ namespace Godot
/// <summary>
/// Returns the color's HTML hexadecimal color string in RGBA format.
/// </summary>
- /// <param name="includeAlpha">Whether or not to include alpha. If false, the color is RGB instead of RGBA.</param>
+ /// <param name="includeAlpha">
+ /// Whether or not to include alpha. If <see langword="false"/>, the color is RGB instead of RGBA.
+ /// </param>
/// <returns>A string for the HTML hexadecimal representation of this color.</returns>
public string ToHTML(bool includeAlpha = true)
{
- var txt = string.Empty;
+ string txt = string.Empty;
txt += ToHex32(r);
txt += ToHex32(g);
@@ -493,7 +500,7 @@ namespace Godot
}
/// <summary>
- /// Constructs a color from RGBA values, typically on the range of 0 to 1.
+ /// Constructs a <see cref="Color"/> from RGBA values, typically on the range of 0 to 1.
/// </summary>
/// <param name="r">The color's red component, typically on the range of 0 to 1.</param>
/// <param name="g">The color's green component, typically on the range of 0 to 1.</param>
@@ -508,7 +515,7 @@ namespace Godot
}
/// <summary>
- /// Constructs a color from an existing color and an alpha value.
+ /// Constructs a <see cref="Color"/> from an existing color and an alpha value.
/// </summary>
/// <param name="c">The color to construct from. Only its RGB values are used.</param>
/// <param name="a">The color's alpha (transparency) value, typically on the range of 0 to 1. Default: 1.</param>
@@ -521,10 +528,10 @@ namespace Godot
}
/// <summary>
- /// Constructs a color from an unsigned 32-bit integer in RGBA format
+ /// Constructs a <see cref="Color"/> from an unsigned 32-bit integer in RGBA format
/// (each byte represents a color channel).
/// </summary>
- /// <param name="rgba">The uint representing the color.</param>
+ /// <param name="rgba">The <see langword="uint"/> representing the color.</param>
public Color(uint rgba)
{
a = (rgba & 0xFF) / 255.0f;
@@ -537,10 +544,10 @@ namespace Godot
}
/// <summary>
- /// Constructs a color from an unsigned 64-bit integer in RGBA format
+ /// Constructs a <see cref="Color"/> from an unsigned 64-bit integer in RGBA format
/// (each word represents a color channel).
/// </summary>
- /// <param name="rgba">The ulong representing the color.</param>
+ /// <param name="rgba">The <see langword="ulong"/> representing the color.</param>
public Color(ulong rgba)
{
a = (rgba & 0xFFFF) / 65535.0f;
@@ -553,9 +560,9 @@ namespace Godot
}
/// <summary>
- /// Constructs a color either from an HTML color code or from a
- /// standardized color name. Supported
- /// color names are the same as the <see cref="Colors"/> constants.
+ /// Constructs a <see cref="Color"/> either from an HTML color code or from a
+ /// standardized color name. Supported color names are the same as the
+ /// <see cref="Colors"/> constants.
/// </summary>
/// <param name="code">The HTML color code or color name to construct from.</param>
public Color(string code)
@@ -571,8 +578,8 @@ namespace Godot
}
/// <summary>
- /// Constructs a color either from an HTML color code or from a
- /// standardized color name, with `alpha` on the range of 0 to 1. Supported
+ /// Constructs a <see cref="Color"/> either from an HTML color code or from a
+ /// standardized color name, with <paramref name="alpha"/> on the range of 0 to 1. Supported
/// color names are the same as the <see cref="Colors"/> constants.
/// </summary>
/// <param name="code">The HTML color code or color name to construct from.</param>
@@ -584,9 +591,12 @@ namespace Godot
}
/// <summary>
- /// Constructs a color from the HTML hexadecimal color string in RGBA format.
+ /// Constructs a <see cref="Color"/> from the HTML hexadecimal color string in RGBA format.
/// </summary>
/// <param name="rgba">A string for the HTML hexadecimal representation of this color.</param>
+ /// <exception name="ArgumentOutOfRangeException">
+ /// Thrown when the given <paramref name="rgba"/> color code is invalid.
+ /// </exception>
private static Color FromHTML(string rgba)
{
Color c;
@@ -627,7 +637,8 @@ namespace Godot
}
else
{
- throw new ArgumentOutOfRangeException("Invalid color code. Length is " + rgba.Length + " but a length of 6 or 8 is expected: " + rgba);
+ throw new ArgumentOutOfRangeException(
+ $"Invalid color code. Length is {rgba.Length}, but a length of 6 or 8 is expected: {rgba}");
}
c.a = 1.0f;
@@ -697,11 +708,11 @@ namespace Godot
/// <returns>The constructed color.</returns>
private static Color Named(string name)
{
- name = name.Replace(" ", String.Empty);
- name = name.Replace("-", String.Empty);
- name = name.Replace("_", String.Empty);
- name = name.Replace("'", String.Empty);
- name = name.Replace(".", String.Empty);
+ name = name.Replace(" ", string.Empty);
+ name = name.Replace("-", string.Empty);
+ name = name.Replace("_", string.Empty);
+ name = name.Replace("'", string.Empty);
+ name = name.Replace(".", string.Empty);
name = name.ToUpper();
if (!Colors.namedColors.ContainsKey(name))
@@ -715,7 +726,7 @@ namespace Godot
/// <summary>
/// Constructs a color from an HSV profile, with values on the
/// range of 0 to 1. This is equivalent to using each of
- /// the `h`/`s`/`v` properties, but much more efficient.
+ /// the <c>h</c>/<c>s</c>/<c>v</c> properties, but much more efficient.
/// </summary>
/// <param name="hue">The HSV hue, typically on the range of 0 to 1.</param>
/// <param name="saturation">The HSV saturation, typically on the range of 0 to 1.</param>
@@ -739,8 +750,8 @@ namespace Godot
f = hue - i;
p = value * (1 - saturation);
- q = value * (1 - saturation * f);
- t = value * (1 - saturation * (1 - f));
+ q = value * (1 - (saturation * f));
+ t = value * (1 - (saturation * (1 - f)));
switch (i)
{
@@ -761,7 +772,7 @@ namespace Godot
/// <summary>
/// Converts a color to HSV values. This is equivalent to using each of
- /// the `h`/`s`/`v` properties, but much more efficient.
+ /// the <c>h</c>/<c>s</c>/<c>v</c> properties, but much more efficient.
/// </summary>
/// <param name="hue">Output parameter for the HSV hue.</param>
/// <param name="saturation">Output parameter for the HSV saturation.</param>
@@ -785,22 +796,24 @@ namespace Godot
}
else if (g == max)
{
- hue = 2 + (b - r) / delta; // Between cyan & yellow
+ hue = 2 + ((b - r) / delta); // Between cyan & yellow
}
else
{
- hue = 4 + (r - g) / delta; // Between magenta & cyan
+ hue = 4 + ((r - g) / delta); // Between magenta & cyan
}
hue /= 6.0f;
if (hue < 0)
- {
hue += 1.0f;
- }
}
- saturation = max == 0 ? 0 : 1f - 1f * min / max;
+ if (max == 0)
+ saturation = 0;
+ else
+ saturation = 1 - (min / max);
+
value = max;
}
@@ -977,6 +990,11 @@ namespace Godot
return left.r > right.r;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this color and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the color and the other object are equal.</returns>
public override bool Equals(object obj)
{
if (obj is Color)
@@ -987,14 +1005,19 @@ namespace Godot
return false;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this color and <paramref name="other"/> are equal
+ /// </summary>
+ /// <param name="other">The other color to compare.</param>
+ /// <returns>Whether or not the colors are equal.</returns>
public bool Equals(Color other)
{
return r == other.r && g == other.g && b == other.b && a == other.a;
}
/// <summary>
- /// Returns true if this color and `other` are approximately equal, by running
- /// <see cref="Godot.Mathf.IsEqualApprox(float, float)"/> on each component.
+ /// Returns <see langword="true"/> if this color and <paramref name="other"/> are approximately equal,
+ /// by running <see cref="Mathf.IsEqualApprox(float, float)"/> on each component.
/// </summary>
/// <param name="other">The other color to compare.</param>
/// <returns>Whether or not the colors are approximately equal.</returns>
@@ -1003,16 +1026,28 @@ namespace Godot
return Mathf.IsEqualApprox(r, other.r) && Mathf.IsEqualApprox(g, other.g) && Mathf.IsEqualApprox(b, other.b) && Mathf.IsEqualApprox(a, other.a);
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="Color"/>.
+ /// </summary>
+ /// <returns>A hash code for this color.</returns>
public override int GetHashCode()
{
return r.GetHashCode() ^ g.GetHashCode() ^ b.GetHashCode() ^ a.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="Color"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this color.</returns>
public override string ToString()
{
return $"({r}, {g}, {b}, {a})";
}
+ /// <summary>
+ /// Converts this <see cref="Color"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this color.</returns>
public string ToString(string format)
{
return $"({r.ToString(format)}, {g.ToString(format)}, {b.ToString(format)}, {a.ToString(format)})";
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
index 61a34bfc87..2dfe304aaa 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
@@ -7,7 +7,7 @@ using System.Diagnostics.CodeAnalysis;
namespace Godot.Collections
{
- class DictionarySafeHandle : SafeHandle
+ internal class DictionarySafeHandle : SafeHandle
{
public DictionarySafeHandle(IntPtr handle) : base(IntPtr.Zero, true)
{
@@ -31,19 +31,17 @@ namespace Godot.Collections
/// typed elements allocated in the engine in C++. Useful when
/// interfacing with the engine.
/// </summary>
- public class Dictionary :
- IDictionary,
- IDisposable
+ public class Dictionary : IDictionary, IDisposable
{
- DictionarySafeHandle safeHandle;
- bool disposed = false;
+ private DictionarySafeHandle _safeHandle;
+ private bool _disposed = false;
/// <summary>
/// Constructs a new empty <see cref="Dictionary"/>.
/// </summary>
public Dictionary()
{
- safeHandle = new DictionarySafeHandle(godot_icall_Dictionary_Ctor());
+ _safeHandle = new DictionarySafeHandle(godot_icall_Dictionary_Ctor());
}
/// <summary>
@@ -62,20 +60,20 @@ namespace Godot.Collections
internal Dictionary(DictionarySafeHandle handle)
{
- safeHandle = handle;
+ _safeHandle = handle;
}
internal Dictionary(IntPtr handle)
{
- safeHandle = new DictionarySafeHandle(handle);
+ _safeHandle = new DictionarySafeHandle(handle);
}
internal IntPtr GetPtr()
{
- if (disposed)
+ if (_disposed)
throw new ObjectDisposedException(GetType().FullName);
- return safeHandle.DangerousGetHandle();
+ return _safeHandle.DangerousGetHandle();
}
/// <summary>
@@ -83,16 +81,16 @@ namespace Godot.Collections
/// </summary>
public void Dispose()
{
- if (disposed)
+ if (_disposed)
return;
- if (safeHandle != null)
+ if (_safeHandle != null)
{
- safeHandle.Dispose();
- safeHandle = null;
+ _safeHandle.Dispose();
+ _safeHandle = null;
}
- disposed = true;
+ _disposed = true;
}
/// <summary>
@@ -230,17 +228,17 @@ namespace Godot.Collections
private class DictionaryEnumerator : IDictionaryEnumerator
{
- private readonly Dictionary dictionary;
- private readonly int count;
- private int index = -1;
- private bool dirty = true;
+ private readonly Dictionary _dictionary;
+ private readonly int _count;
+ private int _index = -1;
+ private bool _dirty = true;
- private DictionaryEntry entry;
+ private DictionaryEntry _entry;
public DictionaryEnumerator(Dictionary dictionary)
{
- this.dictionary = dictionary;
- count = dictionary.Count;
+ _dictionary = dictionary;
+ _count = dictionary.Count;
}
public object Current => Entry;
@@ -249,19 +247,19 @@ namespace Godot.Collections
{
get
{
- if (dirty)
+ if (_dirty)
{
UpdateEntry();
}
- return entry;
+ return _entry;
}
}
private void UpdateEntry()
{
- dirty = false;
- godot_icall_Dictionary_KeyValuePairAt(dictionary.GetPtr(), index, out object key, out object value);
- entry = new DictionaryEntry(key, value);
+ _dirty = false;
+ godot_icall_Dictionary_KeyValuePairAt(_dictionary.GetPtr(), _index, out object key, out object value);
+ _entry = new DictionaryEntry(key, value);
}
public object Key => Entry.Key;
@@ -270,15 +268,15 @@ namespace Godot.Collections
public bool MoveNext()
{
- index++;
- dirty = true;
- return index < count;
+ _index++;
+ _dirty = true;
+ return _index < _count;
}
public void Reset()
{
- index = -1;
- dirty = true;
+ _index = -1;
+ _dirty = true;
}
}
@@ -292,28 +290,28 @@ namespace Godot.Collections
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Dictionary_Ctor();
+ internal static extern IntPtr godot_icall_Dictionary_Ctor();
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Dictionary_Dtor(IntPtr ptr);
+ internal static extern void godot_icall_Dictionary_Dtor(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static object godot_icall_Dictionary_GetValue(IntPtr ptr, object key);
+ internal static extern object godot_icall_Dictionary_GetValue(IntPtr ptr, object key);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static object godot_icall_Dictionary_GetValue_Generic(IntPtr ptr, object key, int valTypeEncoding, IntPtr valTypeClass);
+ internal static extern object godot_icall_Dictionary_GetValue_Generic(IntPtr ptr, object key, int valTypeEncoding, IntPtr valTypeClass);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Dictionary_SetValue(IntPtr ptr, object key, object value);
+ internal static extern void godot_icall_Dictionary_SetValue(IntPtr ptr, object key, object value);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Dictionary_Keys(IntPtr ptr);
+ internal static extern IntPtr godot_icall_Dictionary_Keys(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Dictionary_Values(IntPtr ptr);
+ internal static extern IntPtr godot_icall_Dictionary_Values(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_Dictionary_Count(IntPtr ptr);
+ internal static extern int godot_icall_Dictionary_Count(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static int godot_icall_Dictionary_KeyValuePairs(IntPtr ptr, out IntPtr keys, out IntPtr values);
@@ -325,34 +323,34 @@ namespace Godot.Collections
internal extern static void godot_icall_Dictionary_Add(IntPtr ptr, object key, object value);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Dictionary_Clear(IntPtr ptr);
+ internal static extern void godot_icall_Dictionary_Clear(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Dictionary_Contains(IntPtr ptr, object key, object value);
+ internal static extern bool godot_icall_Dictionary_Contains(IntPtr ptr, object key, object value);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Dictionary_ContainsKey(IntPtr ptr, object key);
+ internal static extern bool godot_icall_Dictionary_ContainsKey(IntPtr ptr, object key);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Dictionary_Duplicate(IntPtr ptr, bool deep);
+ internal static extern IntPtr godot_icall_Dictionary_Duplicate(IntPtr ptr, bool deep);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Dictionary_RemoveKey(IntPtr ptr, object key);
+ internal static extern bool godot_icall_Dictionary_RemoveKey(IntPtr ptr, object key);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Dictionary_Remove(IntPtr ptr, object key, object value);
+ internal static extern bool godot_icall_Dictionary_Remove(IntPtr ptr, object key, object value);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Dictionary_TryGetValue(IntPtr ptr, object key, out object value);
+ internal static extern bool godot_icall_Dictionary_TryGetValue(IntPtr ptr, object key, out object value);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Dictionary_TryGetValue_Generic(IntPtr ptr, object key, out object value, int valTypeEncoding, IntPtr valTypeClass);
+ internal static extern bool godot_icall_Dictionary_TryGetValue_Generic(IntPtr ptr, object key, out object value, int valTypeEncoding, IntPtr valTypeClass);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Dictionary_Generic_GetValueTypeInfo(Type valueType, out int valTypeEncoding, out IntPtr valTypeClass);
+ internal static extern void godot_icall_Dictionary_Generic_GetValueTypeInfo(Type valueType, out int valTypeEncoding, out IntPtr valTypeClass);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string godot_icall_Dictionary_ToString(IntPtr ptr);
+ internal static extern string godot_icall_Dictionary_ToString(IntPtr ptr);
}
/// <summary>
@@ -363,10 +361,9 @@ namespace Godot.Collections
/// </summary>
/// <typeparam name="TKey">The type of the dictionary's keys.</typeparam>
/// <typeparam name="TValue">The type of the dictionary's values.</typeparam>
- public class Dictionary<TKey, TValue> :
- IDictionary<TKey, TValue>
+ public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
- private readonly Dictionary objectDict;
+ private readonly Dictionary _objectDict;
internal static int valTypeEncoding;
internal static IntPtr valTypeClass;
@@ -381,7 +378,7 @@ namespace Godot.Collections
/// </summary>
public Dictionary()
{
- objectDict = new Dictionary();
+ _objectDict = new Dictionary();
}
/// <summary>
@@ -391,7 +388,7 @@ namespace Godot.Collections
/// <returns>A new Godot Dictionary.</returns>
public Dictionary(IDictionary<TKey, TValue> dictionary)
{
- objectDict = new Dictionary();
+ _objectDict = new Dictionary();
if (dictionary == null)
throw new NullReferenceException($"Parameter '{nameof(dictionary)} cannot be null.'");
@@ -413,17 +410,17 @@ namespace Godot.Collections
/// <returns>A new Godot Dictionary.</returns>
public Dictionary(Dictionary dictionary)
{
- objectDict = dictionary;
+ _objectDict = dictionary;
}
internal Dictionary(IntPtr handle)
{
- objectDict = new Dictionary(handle);
+ _objectDict = new Dictionary(handle);
}
internal Dictionary(DictionarySafeHandle handle)
{
- objectDict = new Dictionary(handle);
+ _objectDict = new Dictionary(handle);
}
/// <summary>
@@ -432,12 +429,12 @@ namespace Godot.Collections
/// <param name="from">The typed dictionary to convert.</param>
public static explicit operator Dictionary(Dictionary<TKey, TValue> from)
{
- return from.objectDict;
+ return from._objectDict;
}
internal IntPtr GetPtr()
{
- return objectDict.GetPtr();
+ return _objectDict.GetPtr();
}
/// <summary>
@@ -447,7 +444,7 @@ namespace Godot.Collections
/// <returns>A new Godot Dictionary.</returns>
public Dictionary<TKey, TValue> Duplicate(bool deep = false)
{
- return new Dictionary<TKey, TValue>(objectDict.Duplicate(deep));
+ return new Dictionary<TKey, TValue>(_objectDict.Duplicate(deep));
}
// IDictionary<TKey, TValue>
@@ -458,8 +455,8 @@ namespace Godot.Collections
/// <value>The value at the given <paramref name="key"/>.</value>
public TValue this[TKey key]
{
- get { return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass); }
- set { objectDict[key] = value; }
+ get { return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(_objectDict.GetPtr(), key, valTypeEncoding, valTypeClass); }
+ set { _objectDict[key] = value; }
}
/// <summary>
@@ -469,7 +466,7 @@ namespace Godot.Collections
{
get
{
- IntPtr handle = Dictionary.godot_icall_Dictionary_Keys(objectDict.GetPtr());
+ IntPtr handle = Dictionary.godot_icall_Dictionary_Keys(_objectDict.GetPtr());
return new Array<TKey>(new ArraySafeHandle(handle));
}
}
@@ -481,7 +478,7 @@ namespace Godot.Collections
{
get
{
- IntPtr handle = Dictionary.godot_icall_Dictionary_Values(objectDict.GetPtr());
+ IntPtr handle = Dictionary.godot_icall_Dictionary_Values(_objectDict.GetPtr());
return new Array<TValue>(new ArraySafeHandle(handle));
}
}
@@ -500,7 +497,7 @@ namespace Godot.Collections
/// <param name="value">The object to add.</param>
public void Add(TKey key, TValue value)
{
- objectDict.Add(key, value);
+ _objectDict.Add(key, value);
}
/// <summary>
@@ -510,7 +507,7 @@ namespace Godot.Collections
/// <returns>Whether or not this dictionary contains the given key.</returns>
public bool ContainsKey(TKey key)
{
- return objectDict.Contains(key);
+ return _objectDict.Contains(key);
}
/// <summary>
@@ -544,14 +541,14 @@ namespace Godot.Collections
/// <returns>The number of elements.</returns>
public int Count
{
- get { return objectDict.Count; }
+ get { return _objectDict.Count; }
}
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => false;
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
{
- objectDict.Add(item.Key, item.Value);
+ _objectDict.Add(item.Key, item.Value);
}
/// <summary>
@@ -559,12 +556,12 @@ namespace Godot.Collections
/// </summary>
public void Clear()
{
- objectDict.Clear();
+ _objectDict.Clear();
}
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
{
- return objectDict.Contains(new KeyValuePair<object, object>(item.Key, item.Value));
+ return _objectDict.Contains(new KeyValuePair<object, object>(item.Key, item.Value));
}
/// <summary>
@@ -622,6 +619,6 @@ namespace Godot.Collections
/// Converts this <see cref="Dictionary{TKey, TValue}"/> to a string.
/// </summary>
/// <returns>A string representation of this dictionary.</returns>
- public override string ToString() => objectDict.ToString();
+ public override string ToString() => _objectDict.ToString();
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs
index 0c21bcaa3f..26d5f9c796 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs
@@ -7,20 +7,20 @@ using System.Runtime.CompilerServices;
namespace Godot
{
/// <summary>
- /// Represents an <see cref="Godot.Object"/> whose members can be dynamically accessed at runtime through the Variant API.
+ /// Represents an <see cref="Object"/> whose members can be dynamically accessed at runtime through the Variant API.
/// </summary>
/// <remarks>
/// <para>
- /// The <see cref="Godot.DynamicGodotObject"/> class enables access to the Variant
- /// members of a <see cref="Godot.Object"/> instance at runtime.
+ /// The <see cref="DynamicGodotObject"/> class enables access to the Variant
+ /// members of a <see cref="Object"/> instance at runtime.
/// </para>
/// <para>
/// This allows accessing the class members using their original names in the engine as well as the members from the
- /// script attached to the <see cref="Godot.Object"/>, regardless of the scripting language it was written in.
+ /// script attached to the <see cref="Object"/>, regardless of the scripting language it was written in.
/// </para>
/// </remarks>
/// <example>
- /// This sample shows how to use <see cref="Godot.DynamicGodotObject"/> to dynamically access the engine members of a <see cref="Godot.Object"/>.
+ /// This sample shows how to use <see cref="DynamicGodotObject"/> to dynamically access the engine members of a <see cref="Object"/>.
/// <code>
/// dynamic sprite = GetNode("Sprite2D").DynamicGodotObject;
/// sprite.add_child(this);
@@ -30,7 +30,7 @@ namespace Godot
/// </code>
/// </example>
/// <example>
- /// This sample shows how to use <see cref="Godot.DynamicGodotObject"/> to dynamically access the members of the script attached to a <see cref="Godot.Object"/>.
+ /// This sample shows how to use <see cref="DynamicGodotObject"/> to dynamically access the members of the script attached to a <see cref="Object"/>.
/// <code>
/// dynamic childNode = GetNode("ChildNode").DynamicGodotObject;
///
@@ -54,32 +54,34 @@ namespace Godot
public class DynamicGodotObject : DynamicObject
{
/// <summary>
- /// Gets the <see cref="Godot.Object"/> associated with this <see cref="Godot.DynamicGodotObject"/>.
+ /// Gets the <see cref="Object"/> associated with this <see cref="DynamicGodotObject"/>.
/// </summary>
public Object Value { get; }
/// <summary>
- /// Initializes a new instance of the <see cref="Godot.DynamicGodotObject"/> class.
+ /// Initializes a new instance of the <see cref="DynamicGodotObject"/> class.
/// </summary>
/// <param name="godotObject">
- /// The <see cref="Godot.Object"/> that will be associated with this <see cref="Godot.DynamicGodotObject"/>.
+ /// The <see cref="Object"/> that will be associated with this <see cref="DynamicGodotObject"/>.
/// </param>
- /// <exception cref="System.ArgumentNullException">
- /// Thrown when the <paramref name="godotObject"/> parameter is null.
+ /// <exception cref="ArgumentNullException">
+ /// Thrown when the <paramref name="godotObject"/> parameter is <see langword="null"/>.
/// </exception>
public DynamicGodotObject(Object godotObject)
{
if (godotObject == null)
throw new ArgumentNullException(nameof(godotObject));
- this.Value = godotObject;
+ Value = godotObject;
}
+ /// <inheritdoc/>
public override IEnumerable<string> GetDynamicMemberNames()
{
return godot_icall_DynamicGodotObject_SetMemberList(Object.GetPtr(Value));
}
+ /// <inheritdoc/>
public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result)
{
switch (binder.Operation)
@@ -121,6 +123,7 @@ namespace Godot
return base.TryBinaryOperation(binder, arg, out result);
}
+ /// <inheritdoc/>
public override bool TryConvert(ConvertBinder binder, out object result)
{
if (binder.Type == typeof(Object))
@@ -139,6 +142,7 @@ namespace Godot
return base.TryConvert(binder, out result);
}
+ /// <inheritdoc/>
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
if (indexes.Length == 1)
@@ -152,16 +156,19 @@ namespace Godot
return base.TryGetIndex(binder, indexes, out result);
}
+ /// <inheritdoc/>
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return godot_icall_DynamicGodotObject_GetMember(Object.GetPtr(Value), binder.Name, out result);
}
+ /// <inheritdoc/>
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
return godot_icall_DynamicGodotObject_InvokeMember(Object.GetPtr(Value), binder.Name, args, out result);
}
+ /// <inheritdoc/>
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
{
if (indexes.Length == 1)
@@ -175,22 +182,23 @@ namespace Godot
return base.TrySetIndex(binder, indexes, value);
}
+ /// <inheritdoc/>
public override bool TrySetMember(SetMemberBinder binder, object value)
{
return godot_icall_DynamicGodotObject_SetMember(Object.GetPtr(Value), binder.Name, value);
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string[] godot_icall_DynamicGodotObject_SetMemberList(IntPtr godotObject);
+ internal static extern string[] godot_icall_DynamicGodotObject_SetMemberList(IntPtr godotObject);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_DynamicGodotObject_InvokeMember(IntPtr godotObject, string name, object[] args, out object result);
+ internal static extern bool godot_icall_DynamicGodotObject_InvokeMember(IntPtr godotObject, string name, object[] args, out object result);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_DynamicGodotObject_GetMember(IntPtr godotObject, string name, out object result);
+ internal static extern bool godot_icall_DynamicGodotObject_GetMember(IntPtr godotObject, string name, out object result);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_DynamicGodotObject_SetMember(IntPtr godotObject, string name, object value);
+ internal static extern bool godot_icall_DynamicGodotObject_SetMember(IntPtr godotObject, string name, object value);
#region We don't override these methods
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs
index 5d16260f5d..658582960f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs
@@ -1,42 +1,190 @@
+using System;
+
namespace Godot
{
public partial class Node
{
+ /// <summary>
+ /// Fetches a node. The <see cref="NodePath"/> can be either a relative path (from
+ /// the current node) or an absolute path (in the scene tree) to a node. If the path
+ /// does not exist, a <see langword="null"/> instance is returned and an error
+ /// is logged. Attempts to access methods on the return value will result in an
+ /// "Attempt to call &lt;method&gt; on a null instance." error.
+ /// Note: Fetching absolute paths only works when the node is inside the scene tree
+ /// (see <see cref="IsInsideTree"/>).
+ /// </summary>
+ /// <example>
+ /// Example: Assume your current node is Character and the following tree:
+ /// <code>
+ /// /root
+ /// /root/Character
+ /// /root/Character/Sword
+ /// /root/Character/Backpack/Dagger
+ /// /root/MyGame
+ /// /root/Swamp/Alligator
+ /// /root/Swamp/Mosquito
+ /// /root/Swamp/Goblin
+ /// </code>
+ /// Possible paths are:
+ /// <code>
+ /// GetNode("Sword");
+ /// GetNode("Backpack/Dagger");
+ /// GetNode("../Swamp/Alligator");
+ /// GetNode("/root/MyGame");
+ /// </code>
+ /// </example>
+ /// <seealso cref="GetNodeOrNull{T}(NodePath)"/>
+ /// <param name="path">The path to the node to fetch.</param>
+ /// <exception cref="InvalidCastException">
+ /// Thrown when the given the fetched node can't be casted to the given type <typeparamref name="T"/>.
+ /// </exception>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>
+ /// <returns>
+ /// The <see cref="Node"/> at the given <paramref name="path"/>.
+ /// </returns>
public T GetNode<T>(NodePath path) where T : class
{
return (T)(object)GetNode(path);
}
+ /// <summary>
+ /// Fetches a node. The <see cref="NodePath"/> can be either a relative path (from
+ /// the current node) or an absolute path (in the scene tree) to a node. If the path
+ /// does not exist, a <see langword="null"/> instance is returned and an error
+ /// is logged. Attempts to access methods on the return value will result in an
+ /// "Attempt to call &lt;method&gt; on a null instance." error.
+ /// Note: Fetching absolute paths only works when the node is inside the scene tree
+ /// (see <see cref="IsInsideTree"/>).
+ /// </summary>
+ /// <example>
+ /// Example: Assume your current node is Character and the following tree:
+ /// <code>
+ /// /root
+ /// /root/Character
+ /// /root/Character/Sword
+ /// /root/Character/Backpack/Dagger
+ /// /root/MyGame
+ /// /root/Swamp/Alligator
+ /// /root/Swamp/Mosquito
+ /// /root/Swamp/Goblin
+ /// </code>
+ /// Possible paths are:
+ /// <code>
+ /// GetNode("Sword");
+ /// GetNode("Backpack/Dagger");
+ /// GetNode("../Swamp/Alligator");
+ /// GetNode("/root/MyGame");
+ /// </code>
+ /// </example>
+ /// <seealso cref="GetNode{T}(NodePath)"/>
+ /// <param name="path">The path to the node to fetch.</param>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>/// ///////// <returns>
+ /// The <see cref="Node"/> at the given <paramref name="path"/>, or <see langword="null"/> if not found.
+ /// </returns>
public T GetNodeOrNull<T>(NodePath path) where T : class
{
return GetNodeOrNull(path) as T;
}
+ /// <summary>
+ /// Returns a child node by its index (see <see cref="GetChildCount"/>).
+ /// This method is often used for iterating all children of a node.
+ /// Negative indices access the children from the last one.
+ /// To access a child node via its name, use <see cref="GetNode"/>.
+ /// </summary>
+ /// <seealso cref="GetChildOrNull{T}(int)"/>
+ /// <param name="idx">Child index.</param>
+ /// <exception cref="InvalidCastException">
+ /// Thrown when the given the fetched node can't be casted to the given type <typeparamref name="T"/>.
+ /// </exception>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>/// ///////// <returns>
+ /// The child <see cref="Node"/> at the given index <paramref name="idx"/>.
+ /// </returns>
public T GetChild<T>(int idx) where T : class
{
return (T)(object)GetChild(idx);
}
+ /// <summary>
+ /// Returns a child node by its index (see <see cref="GetChildCount"/>).
+ /// This method is often used for iterating all children of a node.
+ /// Negative indices access the children from the last one.
+ /// To access a child node via its name, use <see cref="GetNode"/>.
+ /// </summary>
+ /// <seealso cref="GetChild{T}(int)"/>
+ /// <param name="idx">Child index.</param>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>
+ /// <returns>
+ /// The child <see cref="Node"/> at the given index <paramref name="idx"/>, or <see langword="null"/> if not found.
+ /// </returns>
public T GetChildOrNull<T>(int idx) where T : class
{
return GetChild(idx) as T;
}
+ /// <summary>
+ /// The node owner. A node can have any other node as owner (as long as it is
+ /// a valid parent, grandparent, etc. ascending in the tree). When saving a
+ /// node (using <see cref="PackedScene"/>), all the nodes it owns will be saved
+ /// with it. This allows for the creation of complex <see cref="SceneTree"/>s,
+ /// with instancing and subinstancing.
+ /// </summary>
+ /// <seealso cref="GetOwnerOrNull{T}"/>
+ /// <exception cref="InvalidCastException">
+ /// Thrown when the given the fetched node can't be casted to the given type <typeparamref name="T"/>.
+ /// </exception>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>
+ /// <returns>
+ /// The owner <see cref="Node"/>.
+ /// </returns>
public T GetOwner<T>() where T : class
{
return (T)(object)Owner;
}
+ /// <summary>
+ /// The node owner. A node can have any other node as owner (as long as it is
+ /// a valid parent, grandparent, etc. ascending in the tree). When saving a
+ /// node (using <see cref="PackedScene"/>), all the nodes it owns will be saved
+ /// with it. This allows for the creation of complex <see cref="SceneTree"/>s,
+ /// with instancing and subinstancing.
+ /// </summary>
+ /// <seealso cref="GetOwner{T}"/>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>
+ /// <returns>
+ /// The owner <see cref="Node"/>, or <see langword="null"/> if there is no owner.
+ /// </returns>
public T GetOwnerOrNull<T>() where T : class
{
return Owner as T;
}
+ /// <summary>
+ /// Returns the parent node of the current node, or a <see langword="null"/> instance
+ /// if the node lacks a parent.
+ /// </summary>
+ /// <seealso cref="GetParentOrNull{T}"/>
+ /// <exception cref="InvalidCastException">
+ /// Thrown when the given the fetched node can't be casted to the given type <typeparamref name="T"/>.
+ /// </exception>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>
+ /// <returns>
+ /// The parent <see cref="Node"/>.
+ /// </returns>
public T GetParent<T>() where T : class
{
return (T)(object)GetParent();
}
+ /// <summary>
+ /// Returns the parent node of the current node, or a <see langword="null"/> instance
+ /// if the node lacks a parent.
+ /// </summary>
+ /// <seealso cref="GetParent{T}"/>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>
+ /// <returns>
+ /// The parent <see cref="Node"/>, or <see langword="null"/> if the node has no parent.
+ /// </returns>
public T GetParentOrNull<T>() where T : class
{
return GetParent() as T;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs
index 9ef0959750..691fd85964 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs
@@ -5,17 +5,37 @@ namespace Godot
{
public partial class Object
{
+ /// <summary>
+ /// Returns whether <paramref name="instance"/> is a valid object
+ /// (e.g. has not been deleted from memory).
+ /// </summary>
+ /// <param name="instance">The instance to check.</param>
+ /// <returns>If the instance is a valid object.</returns>
public static bool IsInstanceValid(Object instance)
{
return instance != null && instance.NativeInstance != IntPtr.Zero;
}
+ /// <summary>
+ /// Returns a weak reference to an object, or <see langword="null"/>
+ /// if the argument is invalid.
+ /// A weak reference to an object is not enough to keep the object alive:
+ /// when the only remaining references to a referent are weak references,
+ /// garbage collection is free to destroy the referent and reuse its memory
+ /// for something else. However, until the object is actually destroyed the
+ /// weak reference may return the object even if there are no strong references
+ /// to it.
+ /// </summary>
+ /// <param name="obj">The object.</param>
+ /// <returns>
+ /// The <see cref="WeakRef"/> reference to the object or <see langword="null"/>.
+ /// </returns>
public static WeakRef WeakRef(Object obj)
{
- return godot_icall_Object_weakref(Object.GetPtr(obj));
+ return godot_icall_Object_weakref(GetPtr(obj));
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static WeakRef godot_icall_Object_weakref(IntPtr obj);
+ internal static extern WeakRef godot_icall_Object_weakref(IntPtr obj);
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs
index 214bbf5179..435b59d5f3 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace Godot
{
public partial class PackedScene
@@ -5,20 +7,27 @@ namespace Godot
/// <summary>
/// Instantiates the scene's node hierarchy, erroring on failure.
/// Triggers child scene instantiation(s). Triggers a
- /// `Node.NotificationInstanced` notification on the root node.
+ /// <see cref="Node.NotificationInstanced"/> notification on the root node.
/// </summary>
- /// <typeparam name="T">The type to cast to. Should be a descendant of Node.</typeparam>
+ /// <seealso cref="InstantiateOrNull{T}(GenEditState)"/>
+ /// <exception cref="InvalidCastException">
+ /// Thrown when the given the instantiated node can't be casted to the given type <typeparamref name="T"/>.
+ /// </exception>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>
+ /// <returns>The instantiated scene.</returns>
public T Instantiate<T>(PackedScene.GenEditState editState = (PackedScene.GenEditState)0) where T : class
{
return (T)(object)Instantiate(editState);
}
/// <summary>
- /// Instantiates the scene's node hierarchy, returning null on failure.
+ /// Instantiates the scene's node hierarchy, returning <see langword="null"/> on failure.
/// Triggers child scene instantiation(s). Triggers a
- /// `Node.NotificationInstanced` notification on the root node.
+ /// <see cref="Node.NotificationInstanced"/> notification on the root node.
/// </summary>
- /// <typeparam name="T">The type to cast to. Should be a descendant of Node.</typeparam>
+ /// <seealso cref="Instantiate{T}(GenEditState)"/>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>
+ /// <returns>The instantiated scene.</returns>
public T InstantiateOrNull<T>(PackedScene.GenEditState editState = (PackedScene.GenEditState)0) where T : class
{
return Instantiate(editState) as T;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs
index 74fa05d1fd..25c11d5cf6 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs
@@ -1,10 +1,30 @@
+using System;
+
namespace Godot
{
public static partial class ResourceLoader
{
- public static T Load<T>(string path, string typeHint = null, CacheMode noCache = CacheMode.Reuse) where T : class
+ /// <summary>
+ /// Loads a resource at the given <paramref name="path"/>, caching the result
+ /// for further access.
+ /// The registered <see cref="ResourceFormatLoader"/> instances are queried sequentially
+ /// to find the first one which can handle the file's extension, and then attempt
+ /// loading. If loading fails, the remaining ResourceFormatLoaders are also attempted.
+ /// An optional <paramref name="typeHint"/> can be used to further specify the
+ /// <see cref="Resource"/> type that should be handled by the <see cref="ResourceFormatLoader"/>.
+ /// Anything that inherits from <see cref="Resource"/> can be used as a type hint,
+ /// for example <see cref="Image"/>.
+ /// The <paramref name="cacheMode"/> property defines whether and how the cache should
+ /// be used or updated when loading the resource. See <see cref="CacheMode"/> for details.
+ /// Returns an empty resource if no <see cref="ResourceFormatLoader"/> could handle the file.
+ /// </summary>
+ /// <exception cref="InvalidCastException">
+ /// Thrown when the given the loaded resource can't be casted to the given type <typeparamref name="T"/>.
+ /// </exception>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Resource"/>.</typeparam>
+ public static T Load<T>(string path, string typeHint = null, CacheMode cacheMode = CacheMode.Reuse) where T : class
{
- return (T)(object)Load(path, typeHint, noCache);
+ return (T)(object)Load(path, typeHint, cacheMode);
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs
index 20b11a48dd..df130a5c77 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs
@@ -6,12 +6,16 @@ namespace Godot
{
public partial class SceneTree
{
+ /// <summary>
+ /// Returns a list of all nodes assigned to the given <paramref name="group"/>.
+ /// </summary>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>
public Array<T> GetNodesInGroup<T>(StringName group) where T : class
{
- return new Array<T>(godot_icall_SceneTree_get_nodes_in_group_Generic(Object.GetPtr(this), StringName.GetPtr(group), typeof(T)));
+ return new Array<T>(godot_icall_SceneTree_get_nodes_in_group_Generic(GetPtr(this), StringName.GetPtr(group), typeof(T)));
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_SceneTree_get_nodes_in_group_Generic(IntPtr obj, IntPtr group, Type elemType);
+ internal static extern IntPtr godot_icall_SceneTree_get_nodes_in_group_Generic(IntPtr obj, IntPtr group, Type elemType);
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
index 71d0593916..53c02feaa2 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
@@ -7,22 +7,56 @@ using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
-// TODO: Add comments describing what this class does. It is not obvious.
-
namespace Godot
{
+ /// <summary>
+ /// Godot's global functions.
+ /// </summary>
public static partial class GD
{
+ /// <summary>
+ /// Decodes a byte array back to a <c>Variant</c> value.
+ /// If <paramref name="allowObjects"/> is <see langword="true"/> decoding objects is allowed.
+ ///
+ /// WARNING: Deserialized object can contain code which gets executed.
+ /// Do not set <paramref name="allowObjects"/> to <see langword="true"/>
+ /// if the serialized object comes from untrusted sources to avoid
+ /// potential security threats (remote code execution).
+ /// </summary>
+ /// <param name="bytes">Byte array that will be decoded to a <c>Variant</c>.</param>
+ /// <param name="allowObjects">If objects should be decoded.</param>
+ /// <returns>The decoded <c>Variant</c>.</returns>
public static object Bytes2Var(byte[] bytes, bool allowObjects = false)
{
return godot_icall_GD_bytes2var(bytes, allowObjects);
}
+ /// <summary>
+ /// Converts from a <c>Variant</c> type to another in the best way possible.
+ /// The <paramref name="type"/> parameter uses the <see cref="Variant.Type"/> values.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// var a = new Vector2(1, 0);
+ /// // Prints 1
+ /// GD.Print(a.Length());
+ /// var b = GD.Convert(a, Variant.Type.String)
+ /// // Prints 6 as "(1, 0)" is 6 characters
+ /// GD.Print(b.Length);
+ /// </code>
+ /// </example>
+ /// <returns>The <c>Variant</c> converted to the given <paramref name="type"/>.</returns>
public static object Convert(object what, Variant.Type type)
{
return godot_icall_GD_convert(what, type);
}
+ /// <summary>
+ /// Converts from decibels to linear energy (audio).
+ /// </summary>
+ /// <seealso cref="Linear2Db(real_t)"/>
+ /// <param name="db">Decibels to convert.</param>
+ /// <returns>Audio volume as linear energy.</returns>
public static real_t Db2Linear(real_t db)
{
return (real_t)Math.Exp(db * 0.11512925464970228420089957273422);
@@ -38,111 +72,360 @@ namespace Godot
return Array.ConvertAll(parameters, x => x?.ToString() ?? "null");
}
+ /// <summary>
+ /// Returns the integer hash of the variable passed.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.Print(GD.Hash("a")); // Prints 177670
+ /// </code>
+ /// </example>
+ /// <param name="var">Variable that will be hashed.</param>
+ /// <returns>Hash of the variable passed.</returns>
public static int Hash(object var)
{
return godot_icall_GD_hash(var);
}
+ /// <summary>
+ /// Returns the <see cref="Object"/> that corresponds to <paramref name="instanceId"/>.
+ /// All Objects have a unique instance ID.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// public class MyNode : Node
+ /// {
+ /// public string foo = "bar";
+ ///
+ /// public override void _Ready()
+ /// {
+ /// ulong id = GetInstanceId();
+ /// var inst = (MyNode)GD.InstanceFromId(Id);
+ /// GD.Print(inst.foo); // Prints bar
+ /// }
+ /// }
+ /// </code>
+ /// </example>
+ /// <param name="instanceId">Instance ID of the Object to retrieve.</param>
+ /// <returns>The <see cref="Object"/> instance.</returns>
public static Object InstanceFromId(ulong instanceId)
{
return godot_icall_GD_instance_from_id(instanceId);
}
+ /// <summary>
+ /// Converts from linear energy to decibels (audio).
+ /// This can be used to implement volume sliders that behave as expected (since volume isn't linear).
+ /// </summary>
+ /// <seealso cref="Db2Linear(real_t)"/>
+ /// <example>
+ /// <code>
+ /// // "slider" refers to a node that inherits Range such as HSlider or VSlider.
+ /// // Its range must be configured to go from 0 to 1.
+ /// // Change the bus name if you'd like to change the volume of a specific bus only.
+ /// AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("Master"), GD.Linear2Db(slider.value));
+ /// </code>
+ /// </example>
+ /// <param name="linear">The linear energy to convert.</param>
+ /// <returns>Audio as decibels</returns>
public static real_t Linear2Db(real_t linear)
{
return (real_t)(Math.Log(linear) * 8.6858896380650365530225783783321);
}
+ /// <summary>
+ /// Loads a resource from the filesystem located at <paramref name="path"/>.
+ /// The resource is loaded on the method call (unless it's referenced already
+ /// elsewhere, e.g. in another script or in the scene), which might cause slight delay,
+ /// especially when loading scenes. To avoid unnecessary delays when loading something
+ /// multiple times, either store the resource in a variable.
+ ///
+ /// Note: Resource paths can be obtained by right-clicking on a resource in the FileSystem
+ /// dock and choosing "Copy Path" or by dragging the file from the FileSystem dock into the script.
+ ///
+ /// Important: The path must be absolute, a local path will just return <see langword="null"/>.
+ /// This method is a simplified version of <see cref="ResourceLoader.Load"/>, which can be used
+ /// for more advanced scenarios.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// // Load a scene called main located in the root of the project directory and cache it in a variable.
+ /// var main = GD.Load("res://main.tscn"); // main will contain a PackedScene resource.
+ /// </code>
+ /// </example>
+ /// <param name="path">Path of the <see cref="Resource"/> to load.</param>
+ /// <returns>The loaded <see cref="Resource"/>.</returns>
public static Resource Load(string path)
{
return ResourceLoader.Load(path);
}
+ /// <summary>
+ /// Loads a resource from the filesystem located at <paramref name="path"/>.
+ /// The resource is loaded on the method call (unless it's referenced already
+ /// elsewhere, e.g. in another script or in the scene), which might cause slight delay,
+ /// especially when loading scenes. To avoid unnecessary delays when loading something
+ /// multiple times, either store the resource in a variable.
+ ///
+ /// Note: Resource paths can be obtained by right-clicking on a resource in the FileSystem
+ /// dock and choosing "Copy Path" or by dragging the file from the FileSystem dock into the script.
+ ///
+ /// Important: The path must be absolute, a local path will just return <see langword="null"/>.
+ /// This method is a simplified version of <see cref="ResourceLoader.Load"/>, which can be used
+ /// for more advanced scenarios.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// // Load a scene called main located in the root of the project directory and cache it in a variable.
+ /// var main = GD.Load&lt;PackedScene&gt;("res://main.tscn"); // main will contain a PackedScene resource.
+ /// </code>
+ /// </example>
+ /// <param name="path">Path of the <see cref="Resource"/> to load.</param>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Resource"/>.</typeparam>
public static T Load<T>(string path) where T : class
{
return ResourceLoader.Load<T>(path);
}
+ /// <summary>
+ /// Pushes an error message to Godot's built-in debugger and to the OS terminal.
+ ///
+ /// Note: Errors printed this way will not pause project execution.
+ /// To print an error message and pause project execution in debug builds,
+ /// use [code]assert(false, "test error")[/code] instead.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.PushError("test_error"); // Prints "test error" to debugger and terminal as error call
+ /// </code>
+ /// </example>
+ /// <param name="message">Error message.</param>
public static void PushError(string message)
{
godot_icall_GD_pusherror(message);
}
+ /// <summary>
+ /// Pushes a warning message to Godot's built-in debugger and to the OS terminal.
+ /// </summary>
+ /// <example>
+ /// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call
+ /// </example>
+ /// <param name="message">Warning message.</param>
public static void PushWarning(string message)
{
godot_icall_GD_pushwarning(message);
}
+ /// <summary>
+ /// Converts one or more arguments of any type to string in the best way possible
+ /// and prints them to the console.
+ ///
+ /// Note: Consider using <see cref="PushError(string)"/> and <see cref="PushWarning(string)"/>
+ /// to print error and warning messages instead of <see cref="Print(object[])"/>.
+ /// This distinguishes them from print messages used for debugging purposes,
+ /// while also displaying a stack trace when an error or warning is printed.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// var a = new int[] { 1, 2, 3 };
+ /// GD.Print("a", "b", a); // Prints ab[1, 2, 3]
+ /// </code>
+ /// </example>
+ /// <param name="what">Arguments that will be printed.</param>
public static void Print(params object[] what)
{
godot_icall_GD_print(GetPrintParams(what));
}
+ /// <summary>
+ /// Prints the current stack trace information to the console.
+ /// </summary>
public static void PrintStack()
{
Print(System.Environment.StackTrace);
}
+ /// <summary>
+ /// Prints one or more arguments to strings in the best way possible to standard error line.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.PrintErr("prints to stderr");
+ /// </code>
+ /// </example>
+ /// <param name="what">Arguments that will be printed.</param>
public static void PrintErr(params object[] what)
{
godot_icall_GD_printerr(GetPrintParams(what));
}
+ /// <summary>
+ /// Prints one or more arguments to strings in the best way possible to console.
+ /// No newline is added at the end.
+ ///
+ /// Note: Due to limitations with Godot's built-in console, this only prints to the terminal.
+ /// If you need to print in the editor, use another method, such as <see cref="Print(object[])"/>.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.PrintRaw("A");
+ /// GD.PrintRaw("B");
+ /// // Prints AB
+ /// </code>
+ /// </example>
+ /// <param name="what">Arguments that will be printed.</param>
public static void PrintRaw(params object[] what)
{
godot_icall_GD_printraw(GetPrintParams(what));
}
+ /// <summary>
+ /// Prints one or more arguments to the console with a space between each argument.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.PrintS("A", "B", "C"); // Prints A B C
+ /// </code>
+ /// </example>
+ /// <param name="what">Arguments that will be printed.</param>
public static void PrintS(params object[] what)
{
godot_icall_GD_prints(GetPrintParams(what));
}
+ /// <summary>
+ /// Prints one or more arguments to the console with a tab between each argument.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.PrintT("A", "B", "C"); // Prints A B C
+ /// </code>
+ /// </example>
+ /// <param name="what">Arguments that will be printed.</param>
public static void PrintT(params object[] what)
{
godot_icall_GD_printt(GetPrintParams(what));
}
+ /// <summary>
+ /// Returns a random floating point value between <c>0.0</c> and <c>1.0</c> (inclusive).
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.Randf(); // Returns e.g. 0.375671
+ /// </code>
+ /// </example>
+ /// <returns>A random <see langword="float"/> number.</returns>
public static float Randf()
{
return godot_icall_GD_randf();
}
+ /// <summary>
+ /// Returns a random unsigned 32-bit integer.
+ /// Use remainder to obtain a random value in the interval <c>[0, N - 1]</c> (where N is smaller than 2^32).
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.Randi(); // Returns random integer between 0 and 2^32 - 1
+ /// GD.Randi() % 20; // Returns random integer between 0 and 19
+ /// GD.Randi() % 100; // Returns random integer between 0 and 99
+ /// GD.Randi() % 100 + 1; // Returns random integer between 1 and 100
+ /// </code>
+ /// </example>
+ /// <returns>A random <see langword="uint"/> number.</returns>
public static uint Randi()
{
return godot_icall_GD_randi();
}
+ /// <summary>
+ /// Randomizes the seed (or the internal state) of the random number generator.
+ /// Current implementation reseeds using a number based on time.
+ ///
+ /// Note: This method is called automatically when the project is run.
+ /// If you need to fix the seed to have reproducible results, use <see cref="Seed(ulong)"/>
+ /// to initialize the random number generator.
+ /// </summary>
public static void Randomize()
{
godot_icall_GD_randomize();
}
+ /// <summary>
+ /// Returns a random floating point value on the interval between <paramref name="from"/>
+ /// and <paramref name="to"/> (inclusive).
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.PrintS(GD.RandRange(-10.0, 10.0), GD.RandRange(-10.0, 10.0)); // Prints e.g. -3.844535 7.45315
+ /// </code>
+ /// </example>
+ /// <returns>A random <see langword="double"/> number inside the given range.</returns>
public static double RandRange(double from, double to)
{
return godot_icall_GD_randf_range(from, to);
}
+ /// <summary>
+ /// Returns a random signed 32-bit integer between <paramref name="from"/>
+ /// and <paramref name="to"/> (inclusive). If <paramref name="to"/> is lesser than
+ /// <paramref name="from"/>, they are swapped.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.Print(GD.RandRange(0, 1)); // Prints 0 or 1
+ /// GD.Print(GD.RangeRange(-10, 1000)); // Prints any number from -10 to 1000
+ /// </code>
+ /// </example>
+ /// <returns>A random <see langword="int"/> number inside the given range.</returns>
public static int RandRange(int from, int to)
{
return godot_icall_GD_randi_range(from, to);
}
+ /// <summary>
+ /// Returns a random unsigned 32-bit integer, using the given <paramref name="seed"/>.
+ /// </summary>
+ /// <param name="seed">
+ /// Seed to use to generate the random number.
+ /// If a different seed is used, its value will be modfied.
+ /// </param>
+ /// <returns>A random <see langword="uint"/> number.</returns>
public static uint RandFromSeed(ref ulong seed)
{
return godot_icall_GD_rand_seed(seed, out seed);
}
+ /// <summary>
+ /// Returns a <see cref="IEnumerable{T}"/> that iterates from
+ /// <c>0</c> to <paramref name="end"/> in steps of <c>1</c>.
+ /// </summary>
+ /// <param name="end">The last index.</param>
public static IEnumerable<int> Range(int end)
{
return Range(0, end, 1);
}
+ /// <summary>
+ /// Returns a <see cref="IEnumerable{T}"/> that iterates from
+ /// <paramref name="start"/> to <paramref name="end"/> in steps of <c>1</c>.
+ /// </summary>
+ /// <param name="start">The first index.</param>
+ /// <param name="end">The last index.</param>
public static IEnumerable<int> Range(int start, int end)
{
return Range(start, end, 1);
}
+ /// <summary>
+ /// Returns a <see cref="IEnumerable{T}"/> that iterates from
+ /// <paramref name="start"/> to <paramref name="end"/> in steps of <paramref name="step"/>.
+ /// </summary>
+ /// <param name="start">The first index.</param>
+ /// <param name="end">The last index.</param>
+ /// <param name="step">The amount by which to increment the index on each iteration.</param>
public static IEnumerable<int> Range(int start, int end, int step)
{
if (end < start && step > 0)
@@ -163,109 +446,164 @@ namespace Godot
}
}
+ /// <summary>
+ /// Sets seed for the random number generator.
+ /// </summary>
+ /// <param name="seed">Seed that will be used.</param>
public static void Seed(ulong seed)
{
godot_icall_GD_seed(seed);
}
+ /// <summary>
+ /// Converts one or more arguments of any type to string in the best way possible.
+ /// </summary>
+ /// <param name="what">Arguments that will converted to string.</param>
+ /// <returns>The string formed by the given arguments.</returns>
public static string Str(params object[] what)
{
return godot_icall_GD_str(what);
}
+ /// <summary>
+ /// Converts a formatted string that was returned by <see cref="Var2Str(object)"/> to the original value.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// string a = "{\"a\": 1, \"b\": 2 }";
+ /// var b = (Godot.Collections.Dictionary)GD.Str2Var(a);
+ /// GD.Print(b["a"]); // Prints 1
+ /// </code>
+ /// </example>
+ /// <param name="str">String that will be converted to Variant.</param>
+ /// <returns>The decoded <c>Variant</c>.</returns>
public static object Str2Var(string str)
{
return godot_icall_GD_str2var(str);
}
+ /// <summary>
+ /// Returns whether the given class exists in <see cref="ClassDB"/>.
+ /// </summary>
+ /// <returns>If the class exists in <see cref="ClassDB"/>.</returns>
public static bool TypeExists(StringName type)
{
return godot_icall_GD_type_exists(StringName.GetPtr(type));
}
+ /// <summary>
+ /// Encodes a <c>Variant</c> value to a byte array.
+ /// If <paramref name="fullObjects"/> is <see langword="true"/> encoding objects is allowed
+ /// (and can potentially include code).
+ /// Deserialization can be done with <see cref="Bytes2Var(byte[], bool)"/>.
+ /// </summary>
+ /// <param name="var">Variant that will be encoded.</param>
+ /// <param name="fullObjects">If objects should be serialized.</param>
+ /// <returns>The <c>Variant</c> encoded as an array of bytes.</returns>
public static byte[] Var2Bytes(object var, bool fullObjects = false)
{
return godot_icall_GD_var2bytes(var, fullObjects);
}
+ /// <summary>
+ /// Converts a <c>Variant</c> <paramref name="var"/> to a formatted string that
+ /// can later be parsed using <see cref="Str2Var(string)"/>.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// var a = new Godot.Collections.Dictionary { ["a"] = 1, ["b"] = 2 };
+ /// GD.Print(GD.Var2Str(a));
+ /// // Prints
+ /// // {
+ /// // "a": 1,
+ /// // "b": 2
+ /// // }
+ /// </code>
+ /// </example>
+ /// <param name="var">Variant that will be converted to string.</param>
+ /// <returns>The <c>Variant</c> encoded as a string.</returns>
public static string Var2Str(object var)
{
return godot_icall_GD_var2str(var);
}
+ /// <summary>
+ /// Get the <see cref="Variant.Type"/> that corresponds for the given <see cref="Type"/>.
+ /// </summary>
+ /// <returns>The <see cref="Variant.Type"/> for the given <paramref name="type"/>.</returns>
public static Variant.Type TypeToVariantType(Type type)
{
return godot_icall_TypeToVariantType(type);
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static object godot_icall_GD_bytes2var(byte[] bytes, bool allowObjects);
+ internal static extern object godot_icall_GD_bytes2var(byte[] bytes, bool allowObjects);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static object godot_icall_GD_convert(object what, Variant.Type type);
+ internal static extern object godot_icall_GD_convert(object what, Variant.Type type);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_GD_hash(object var);
+ internal static extern int godot_icall_GD_hash(object var);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static Object godot_icall_GD_instance_from_id(ulong instanceId);
+ internal static extern Object godot_icall_GD_instance_from_id(ulong instanceId);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_GD_print(object[] what);
+ internal static extern void godot_icall_GD_print(object[] what);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_GD_printerr(object[] what);
+ internal static extern void godot_icall_GD_printerr(object[] what);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_GD_printraw(object[] what);
+ internal static extern void godot_icall_GD_printraw(object[] what);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_GD_prints(object[] what);
+ internal static extern void godot_icall_GD_prints(object[] what);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_GD_printt(object[] what);
+ internal static extern void godot_icall_GD_printt(object[] what);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static float godot_icall_GD_randf();
+ internal static extern float godot_icall_GD_randf();
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static uint godot_icall_GD_randi();
+ internal static extern uint godot_icall_GD_randi();
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_GD_randomize();
+ internal static extern void godot_icall_GD_randomize();
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static double godot_icall_GD_randf_range(double from, double to);
+ internal static extern double godot_icall_GD_randf_range(double from, double to);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_GD_randi_range(int from, int to);
+ internal static extern int godot_icall_GD_randi_range(int from, int to);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static uint godot_icall_GD_rand_seed(ulong seed, out ulong newSeed);
+ internal static extern uint godot_icall_GD_rand_seed(ulong seed, out ulong newSeed);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_GD_seed(ulong seed);
+ internal static extern void godot_icall_GD_seed(ulong seed);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string godot_icall_GD_str(object[] what);
+ internal static extern string godot_icall_GD_str(object[] what);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static object godot_icall_GD_str2var(string str);
+ internal static extern object godot_icall_GD_str2var(string str);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_GD_type_exists(IntPtr type);
+ internal static extern bool godot_icall_GD_type_exists(IntPtr type);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static byte[] godot_icall_GD_var2bytes(object what, bool fullObjects);
+ internal static extern byte[] godot_icall_GD_var2bytes(object what, bool fullObjects);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string godot_icall_GD_var2str(object var);
+ internal static extern string godot_icall_GD_var2str(object var);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_GD_pusherror(string type);
+ internal static extern void godot_icall_GD_pusherror(string type);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_GD_pushwarning(string type);
+ internal static extern void godot_icall_GD_pushwarning(string type);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern Variant.Type godot_icall_TypeToVariantType(Type type);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs
index 4b5e3f8761..c01c926e82 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs
@@ -6,7 +6,8 @@ namespace Godot
{
public class GodotSynchronizationContext : SynchronizationContext
{
- private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> _queue = new BlockingCollection<KeyValuePair<SendOrPostCallback, object>>();
+ private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> _queue =
+ new BlockingCollection<KeyValuePair<SendOrPostCallback, object>>();
public override void Post(SendOrPostCallback d, object state)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTraceListener.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTraceListener.cs
index a566b53659..9ccac1faaf 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTraceListener.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTraceListener.cs
@@ -24,7 +24,7 @@ namespace Godot
try
{
- var stackTrace = new StackTrace(true).ToString();
+ string stackTrace = new StackTrace(true).ToString();
GD.PrintErr(stackTrace);
}
catch
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
index f508211f68..3051bcedc7 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
@@ -3,60 +3,135 @@ using System.Collections.Generic;
namespace Godot
{
- static class MarshalUtils
+ internal static class MarshalUtils
{
/// <summary>
/// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
- /// is <see cref="Godot.Collections.Array{T}"/>; otherwise returns <see langword="false"/>.
+ /// is <see cref="Collections.Array{T}"/>; otherwise returns <see langword="false"/>.
/// </summary>
- /// <exception cref="System.InvalidOperationException">
- /// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false.
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when the given <paramref name="type"/> is not a generic type.
+ /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
/// </exception>
- static bool TypeIsGenericArray(Type type) =>
- type.GetGenericTypeDefinition() == typeof(Godot.Collections.Array<>);
+ private static bool TypeIsGenericArray(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(Collections.Array<>);
/// <summary>
/// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
- /// is <see cref="Godot.Collections.Dictionary{TKey, TValue}"/>; otherwise returns <see langword="false"/>.
+ /// is <see cref="Collections.Dictionary{TKey, TValue}"/>; otherwise returns <see langword="false"/>.
/// </summary>
- /// <exception cref="System.InvalidOperationException">
- /// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false.
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when the given <paramref name="type"/> is not a generic type.
+ /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
/// </exception>
- static bool TypeIsGenericDictionary(Type type) =>
- type.GetGenericTypeDefinition() == typeof(Godot.Collections.Dictionary<,>);
+ private static bool TypeIsGenericDictionary(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(Collections.Dictionary<,>);
- static bool TypeIsSystemGenericList(Type type) =>
- type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.List<>);
+ /// <summary>
+ /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
+ /// is <see cref="List{T}"/>; otherwise returns <see langword="false"/>.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when the given <paramref name="type"/> is not a generic type.
+ /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
+ /// </exception>
+ private static bool TypeIsSystemGenericList(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(List<>);
- static bool TypeIsSystemGenericDictionary(Type type) =>
- type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.Dictionary<,>);
+ /// <summary>
+ /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
+ /// is <see cref="Dictionary{TKey, TValue}"/>; otherwise returns <see langword="false"/>.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when the given <paramref name="type"/> is not a generic type.
+ /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
+ /// </exception>
+ private static bool TypeIsSystemGenericDictionary(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(Dictionary<,>);
- static bool TypeIsGenericIEnumerable(Type type) => type.GetGenericTypeDefinition() == typeof(IEnumerable<>);
+ /// <summary>
+ /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
+ /// is <see cref="IEnumerable{T}"/>; otherwise returns <see langword="false"/>.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when the given <paramref name="type"/> is not a generic type.
+ /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
+ /// </exception>
+ private static bool TypeIsGenericIEnumerable(Type type) => type.GetGenericTypeDefinition() == typeof(IEnumerable<>);
- static bool TypeIsGenericICollection(Type type) => type.GetGenericTypeDefinition() == typeof(ICollection<>);
+ /// <summary>
+ /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
+ /// is <see cref="ICollection{T}"/>; otherwise returns <see langword="false"/>.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when the given <paramref name="type"/> is not a generic type.
+ /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
+ /// </exception>
+ private static bool TypeIsGenericICollection(Type type) => type.GetGenericTypeDefinition() == typeof(ICollection<>);
- static bool TypeIsGenericIDictionary(Type type) => type.GetGenericTypeDefinition() == typeof(IDictionary<,>);
+ /// <summary>
+ /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
+ /// is <see cref="IDictionary{TKey, TValue}"/>; otherwise returns <see langword="false"/>.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when the given <paramref name="type"/> is not a generic type.
+ /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
+ /// </exception>
+ private static bool TypeIsGenericIDictionary(Type type) => type.GetGenericTypeDefinition() == typeof(IDictionary<,>);
- static void ArrayGetElementType(Type arrayType, out Type elementType)
+ /// <summary>
+ /// Gets the element type for the given <paramref name="arrayType"/>.
+ /// </summary>
+ /// <param name="arrayType">Type for the generic array.</param>
+ /// <param name="elementType">Element type for the generic array.</param>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when the given <paramref name="arrayType"/> is not a generic type.
+ /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
+ /// </exception>
+ private static void ArrayGetElementType(Type arrayType, out Type elementType)
{
elementType = arrayType.GetGenericArguments()[0];
}
- static void DictionaryGetKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType)
+ /// <summary>
+ /// Gets the key type and the value type for the given <paramref name="dictionaryType"/>.
+ /// </summary>
+ /// <param name="dictionaryType">The type for the generic dictionary.</param>
+ /// <param name="keyType">Key type for the generic dictionary.</param>
+ /// <param name="valueType">Value type for the generic dictionary.</param>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when the given <paramref name="dictionaryType"/> is not a generic type.
+ /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
+ /// </exception>
+ private static void DictionaryGetKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType)
{
var genericArgs = dictionaryType.GetGenericArguments();
keyType = genericArgs[0];
valueType = genericArgs[1];
}
- static Type MakeGenericArrayType(Type elemType)
+ /// <summary>
+ /// Constructs a new <see cref="Type"/> from <see cref="Collections.Array{T}"/>
+ /// where the generic type for the elements is <paramref name="elemType"/>.
+ /// </summary>
+ /// <param name="elemType">Element type for the array.</param>
+ /// <returns>The generic array type with the specified element type.</returns>
+ private static Type MakeGenericArrayType(Type elemType)
{
- return typeof(Godot.Collections.Array<>).MakeGenericType(elemType);
+ return typeof(Collections.Array<>).MakeGenericType(elemType);
}
- static Type MakeGenericDictionaryType(Type keyType, Type valueType)
+ /// <summary>
+ /// Constructs a new <see cref="Type"/> from <see cref="Collections.Dictionary{TKey, TValue}"/>
+ /// where the generic type for the keys is <paramref name="keyType"/> and
+ /// for the values is <paramref name="valueType"/>.
+ /// </summary>
+ /// <param name="keyType">Key type for the dictionary.</param>
+ /// <param name="valueType">Key type for the dictionary.</param>
+ /// <returns>The generic dictionary type with the specified key and value types.</returns>
+ private static Type MakeGenericDictionaryType(Type keyType, Type valueType)
{
- return typeof(Godot.Collections.Dictionary<,>).MakeGenericType(keyType, valueType);
+ return typeof(Collections.Dictionary<,>).MakeGenericType(keyType, valueType);
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
index 213f84ad73..6f7fac7429 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
@@ -7,6 +7,9 @@ using System;
namespace Godot
{
+ /// <summary>
+ /// Provides constants and static methods for common mathematical functions.
+ /// </summary>
public static partial class Mathf
{
// Define constants with Decimal precision and cast down to double or float.
@@ -19,121 +22,120 @@ namespace Godot
/// <summary>
/// Constant that represents how many times the diameter of a circle
- /// fits around its perimeter. This is equivalent to `Mathf.Tau / 2`.
+ /// fits around its perimeter. This is equivalent to <c>Mathf.Tau / 2</c>.
/// </summary>
// 3.1415927f and 3.14159265358979
public const real_t Pi = (real_t)3.1415926535897932384626433833M;
/// <summary>
- /// Positive infinity. For negative infinity, use `-Mathf.Inf`.
+ /// Positive infinity. For negative infinity, use <c>-Mathf.Inf</c>.
/// </summary>
public const real_t Inf = real_t.PositiveInfinity;
/// <summary>
- /// "Not a Number", an invalid value. `NaN` has special properties, including
+ /// "Not a Number", an invalid value. <c>NaN</c> has special properties, including
/// that it is not equal to itself. It is output by some invalid operations,
/// such as dividing zero by zero.
/// </summary>
public const real_t NaN = real_t.NaN;
// 0.0174532924f and 0.0174532925199433
- private const real_t Deg2RadConst = (real_t)0.0174532925199432957692369077M;
+ private const real_t _deg2RadConst = (real_t)0.0174532925199432957692369077M;
// 57.29578f and 57.2957795130823
- private const real_t Rad2DegConst = (real_t)57.295779513082320876798154814M;
+ private const real_t _rad2DegConst = (real_t)57.295779513082320876798154814M;
/// <summary>
- /// Returns the absolute value of `s` (i.e. positive value).
+ /// Returns the absolute value of <paramref name="s"/> (i.e. positive value).
/// </summary>
/// <param name="s">The input number.</param>
- /// <returns>The absolute value of `s`.</returns>
+ /// <returns>The absolute value of <paramref name="s"/>.</returns>
public static int Abs(int s)
{
return Math.Abs(s);
}
/// <summary>
- /// Returns the absolute value of `s` (i.e. positive value).
+ /// Returns the absolute value of <paramref name="s"/> (i.e. positive value).
/// </summary>
/// <param name="s">The input number.</param>
- /// <returns>The absolute value of `s`.</returns>
+ /// <returns>The absolute value of <paramref name="s"/>.</returns>
public static real_t Abs(real_t s)
{
return Math.Abs(s);
}
/// <summary>
- /// Returns the arc cosine of `s` in radians. Use to get the angle of cosine s.
+ /// Returns the arc cosine of <paramref name="s"/> in radians.
+ /// Use to get the angle of cosine <paramref name="s"/>.
/// </summary>
/// <param name="s">The input cosine value. Must be on the range of -1.0 to 1.0.</param>
- /// <returns>An angle that would result in the given cosine value. On the range `0` to `Tau/2`.</returns>
+ /// <returns>
+ /// An angle that would result in the given cosine value. On the range <c>0</c> to <c>Tau/2</c>.
+ /// </returns>
public static real_t Acos(real_t s)
{
return (real_t)Math.Acos(s);
}
/// <summary>
- /// Returns the arc sine of `s` in radians. Use to get the angle of sine s.
+ /// Returns the arc sine of <paramref name="s"/> in radians.
+ /// Use to get the angle of sine <paramref name="s"/>.
/// </summary>
/// <param name="s">The input sine value. Must be on the range of -1.0 to 1.0.</param>
- /// <returns>An angle that would result in the given sine value. On the range `-Tau/4` to `Tau/4`.</returns>
+ /// <returns>
+ /// An angle that would result in the given sine value. On the range <c>-Tau/4</c> to <c>Tau/4</c>.
+ /// </returns>
public static real_t Asin(real_t s)
{
return (real_t)Math.Asin(s);
}
/// <summary>
- /// Returns the arc tangent of `s` in radians. Use to get the angle of tangent s.
+ /// Returns the arc tangent of <paramref name="s"/> in radians.
+ /// Use to get the angle of tangent <paramref name="s"/>.
///
/// The method cannot know in which quadrant the angle should fall.
- /// See <see cref="Atan2(real_t, real_t)"/> if you have both `y` and `x`.
+ /// See <see cref="Atan2(real_t, real_t)"/> if you have both <c>y</c> and <c>x</c>.
/// </summary>
/// <param name="s">The input tangent value.</param>
- /// <returns>An angle that would result in the given tangent value. On the range `-Tau/4` to `Tau/4`.</returns>
+ /// <returns>
+ /// An angle that would result in the given tangent value. On the range <c>-Tau/4</c> to <c>Tau/4</c>.
+ /// </returns>
public static real_t Atan(real_t s)
{
return (real_t)Math.Atan(s);
}
/// <summary>
- /// Returns the arc tangent of `y` and `x` in radians. Use to get the angle
- /// of the tangent of `y/x`. To compute the value, the method takes into
+ /// Returns the arc tangent of <paramref name="y"/> and <paramref name="x"/> in radians.
+ /// Use to get the angle of the tangent of <c>y/x</c>. To compute the value, the method takes into
/// account the sign of both arguments in order to determine the quadrant.
///
/// Important note: The Y coordinate comes first, by convention.
/// </summary>
/// <param name="y">The Y coordinate of the point to find the angle to.</param>
/// <param name="x">The X coordinate of the point to find the angle to.</param>
- /// <returns>An angle that would result in the given tangent value. On the range `-Tau/2` to `Tau/2`.</returns>
+ /// <returns>
+ /// An angle that would result in the given tangent value. On the range <c>-Tau/2</c> to <c>Tau/2</c>.
+ /// </returns>
public static real_t Atan2(real_t y, real_t x)
{
return (real_t)Math.Atan2(y, x);
}
/// <summary>
- /// Converts a 2D point expressed in the cartesian coordinate
- /// system (X and Y axis) to the polar coordinate system
- /// (a distance from the origin and an angle).
- /// </summary>
- /// <param name="x">The input X coordinate.</param>
- /// <param name="y">The input Y coordinate.</param>
- /// <returns>A <see cref="Vector2"/> with X representing the distance and Y representing the angle.</returns>
- public static Vector2 Cartesian2Polar(real_t x, real_t y)
- {
- return new Vector2(Sqrt(x * x + y * y), Atan2(y, x));
- }
-
- /// <summary>
- /// Rounds `s` upward (towards positive infinity).
+ /// Rounds <paramref name="s"/> upward (towards positive infinity).
/// </summary>
/// <param name="s">The number to ceil.</param>
- /// <returns>The smallest whole number that is not less than `s`.</returns>
+ /// <returns>The smallest whole number that is not less than <paramref name="s"/>.</returns>
public static real_t Ceil(real_t s)
{
return (real_t)Math.Ceiling(s);
}
/// <summary>
- /// Clamps a `value` so that it is not less than `min` and not more than `max`.
+ /// Clamps a <paramref name="value"/> so that it is not less than <paramref name="min"/>
+ /// and not more than <paramref name="max"/>.
/// </summary>
/// <param name="value">The value to clamp.</param>
/// <param name="min">The minimum allowed value.</param>
@@ -145,7 +147,8 @@ namespace Godot
}
/// <summary>
- /// Clamps a `value` so that it is not less than `min` and not more than `max`.
+ /// Clamps a <paramref name="value"/> so that it is not less than <paramref name="min"/>
+ /// and not more than <paramref name="max"/>.
/// </summary>
/// <param name="value">The value to clamp.</param>
/// <param name="min">The minimum allowed value.</param>
@@ -157,7 +160,7 @@ namespace Godot
}
/// <summary>
- /// Returns the cosine of angle `s` in radians.
+ /// Returns the cosine of angle <paramref name="s"/> in radians.
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The cosine of that angle.</returns>
@@ -167,7 +170,7 @@ namespace Godot
}
/// <summary>
- /// Returns the hyperbolic cosine of angle `s` in radians.
+ /// Returns the hyperbolic cosine of angle <paramref name="s"/> in radians.
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The hyperbolic cosine of that angle.</returns>
@@ -183,16 +186,18 @@ namespace Godot
/// <returns>The same angle expressed in radians.</returns>
public static real_t Deg2Rad(real_t deg)
{
- return deg * Deg2RadConst;
+ return deg * _deg2RadConst;
}
/// <summary>
- /// Easing function, based on exponent. The curve values are:
- /// `0` is constant, `1` is linear, `0` to `1` is ease-in, `1` or more is ease-out.
+ /// Easing function, based on exponent. The <paramref name="curve"/> values are:
+ /// <c>0</c> is constant, <c>1</c> is linear, <c>0</c> to <c>1</c> is ease-in, <c>1</c> or more is ease-out.
/// Negative values are in-out/out-in.
/// </summary>
/// <param name="s">The value to ease.</param>
- /// <param name="curve">`0` is constant, `1` is linear, `0` to `1` is ease-in, `1` or more is ease-out.</param>
+ /// <param name="curve">
+ /// <c>0</c> is constant, <c>1</c> is linear, <c>0</c> to <c>1</c> is ease-in, <c>1</c> or more is ease-out.
+ /// </param>
/// <returns>The eased value.</returns>
public static real_t Ease(real_t s, real_t curve)
{
@@ -222,7 +227,7 @@ namespace Godot
return Pow(s * 2.0f, -curve) * 0.5f;
}
- return (1.0f - Pow(1.0f - (s - 0.5f) * 2.0f, -curve)) * 0.5f + 0.5f;
+ return ((1.0f - Pow(1.0f - ((s - 0.5f) * 2.0f), -curve)) * 0.5f) + 0.5f;
}
return 0f;
@@ -230,20 +235,20 @@ namespace Godot
/// <summary>
/// The natural exponential function. It raises the mathematical
- /// constant `e` to the power of `s` and returns it.
+ /// constant <c>e</c> to the power of <paramref name="s"/> and returns it.
/// </summary>
- /// <param name="s">The exponent to raise `e` to.</param>
- /// <returns>`e` raised to the power of `s`.</returns>
+ /// <param name="s">The exponent to raise <c>e</c> to.</param>
+ /// <returns><c>e</c> raised to the power of <paramref name="s"/>.</returns>
public static real_t Exp(real_t s)
{
return (real_t)Math.Exp(s);
}
/// <summary>
- /// Rounds `s` downward (towards negative infinity).
+ /// Rounds <paramref name="s"/> downward (towards negative infinity).
/// </summary>
/// <param name="s">The number to floor.</param>
- /// <returns>The largest whole number that is not more than `s`.</returns>
+ /// <returns>The largest whole number that is not more than <paramref name="s"/>.</returns>
public static real_t Floor(real_t s)
{
return (real_t)Math.Floor(s);
@@ -263,12 +268,13 @@ namespace Godot
}
/// <summary>
- /// Returns true if `a` and `b` are approximately equal to each other.
+ /// Returns <see langword="true"/> if <paramref name="a"/> and <paramref name="b"/> are approximately equal
+ /// to each other.
/// The comparison is done using a tolerance calculation with <see cref="Epsilon"/>.
/// </summary>
/// <param name="a">One of the values.</param>
/// <param name="b">The other value.</param>
- /// <returns>A bool for whether or not the two values are approximately equal.</returns>
+ /// <returns>A <see langword="bool"/> for whether or not the two values are approximately equal.</returns>
public static bool IsEqualApprox(real_t a, real_t b)
{
// Check for exact equality first, required to handle "infinity" values.
@@ -286,33 +292,33 @@ namespace Godot
}
/// <summary>
- /// Returns whether `s` is an infinity value (either positive infinity or negative infinity).
+ /// Returns whether <paramref name="s"/> is an infinity value (either positive infinity or negative infinity).
/// </summary>
/// <param name="s">The value to check.</param>
- /// <returns>A bool for whether or not the value is an infinity value.</returns>
+ /// <returns>A <see langword="bool"/> for whether or not the value is an infinity value.</returns>
public static bool IsInf(real_t s)
{
return real_t.IsInfinity(s);
}
/// <summary>
- /// Returns whether `s` is a `NaN` ("Not a Number" or invalid) value.
+ /// Returns whether <paramref name="s"/> is a <c>NaN</c> ("Not a Number" or invalid) value.
/// </summary>
/// <param name="s">The value to check.</param>
- /// <returns>A bool for whether or not the value is a `NaN` value.</returns>
+ /// <returns>A <see langword="bool"/> for whether or not the value is a <c>NaN</c> value.</returns>
public static bool IsNaN(real_t s)
{
return real_t.IsNaN(s);
}
/// <summary>
- /// Returns true if `s` is approximately zero.
+ /// Returns <see langword="true"/> if <paramref name="s"/> is approximately zero.
/// The comparison is done using a tolerance calculation with <see cref="Epsilon"/>.
///
/// This method is faster than using <see cref="IsEqualApprox(real_t, real_t)"/> with one value as zero.
/// </summary>
/// <param name="s">The value to check.</param>
- /// <returns>A bool for whether or not the value is nearly zero.</returns>
+ /// <returns>A <see langword="bool"/> for whether or not the value is nearly zero.</returns>
public static bool IsZeroApprox(real_t s)
{
return Abs(s) < Epsilon;
@@ -328,7 +334,7 @@ namespace Godot
/// <returns>The resulting value of the interpolation.</returns>
public static real_t Lerp(real_t from, real_t to, real_t weight)
{
- return from + (to - from) * weight;
+ return from + ((to - from) * weight);
}
/// <summary>
@@ -345,7 +351,7 @@ namespace Godot
{
real_t difference = (to - from) % Mathf.Tau;
real_t distance = ((2 * difference) % Mathf.Tau) - difference;
- return from + distance * weight;
+ return from + (distance * weight);
}
/// <summary>
@@ -354,7 +360,7 @@ namespace Godot
/// Note: This is not the same as the "log" function on most calculators, which uses a base 10 logarithm.
/// </summary>
/// <param name="s">The input value.</param>
- /// <returns>The natural log of `s`.</returns>
+ /// <returns>The natural log of <paramref name="s"/>.</returns>
public static real_t Log(real_t s)
{
return (real_t)Math.Log(s);
@@ -405,9 +411,9 @@ namespace Godot
}
/// <summary>
- /// Moves `from` toward `to` by the `delta` value.
+ /// Moves <paramref name="from"/> toward <paramref name="to"/> by the <paramref name="delta"/> value.
///
- /// Use a negative delta value to move away.
+ /// Use a negative <paramref name="delta"/> value to move away.
/// </summary>
/// <param name="from">The start value.</param>
/// <param name="to">The value to move towards.</param>
@@ -415,11 +421,14 @@ namespace Godot
/// <returns>The value after moving.</returns>
public static real_t MoveToward(real_t from, real_t to, real_t delta)
{
- return Abs(to - from) <= delta ? to : from + Sign(to - from) * delta;
+ if (Abs(to - from) <= delta)
+ return to;
+
+ return from + (Sign(to - from) * delta);
}
/// <summary>
- /// Returns the nearest larger power of 2 for the integer `value`.
+ /// Returns the nearest larger power of 2 for the integer <paramref name="value"/>.
/// </summary>
/// <param name="value">The input value.</param>
/// <returns>The nearest larger power of 2.</returns>
@@ -436,23 +445,10 @@ namespace Godot
}
/// <summary>
- /// Converts a 2D point expressed in the polar coordinate
- /// system (a distance from the origin `r` and an angle `th`)
- /// to the cartesian coordinate system (X and Y axis).
- /// </summary>
- /// <param name="r">The distance from the origin.</param>
- /// <param name="th">The angle of the point.</param>
- /// <returns>A <see cref="Vector2"/> representing the cartesian coordinate.</returns>
- public static Vector2 Polar2Cartesian(real_t r, real_t th)
- {
- return new Vector2(r * Cos(th), r * Sin(th));
- }
-
- /// <summary>
- /// Performs a canonical Modulus operation, where the output is on the range `[0, b)`.
+ /// Performs a canonical Modulus operation, where the output is on the range [0, <paramref name="b"/>).
/// </summary>
/// <param name="a">The dividend, the primary input.</param>
- /// <param name="b">The divisor. The output is on the range `[0, b)`.</param>
+ /// <param name="b">The divisor. The output is on the range [0, <paramref name="b"/>).</param>
/// <returns>The resulting output.</returns>
public static int PosMod(int a, int b)
{
@@ -465,10 +461,10 @@ namespace Godot
}
/// <summary>
- /// Performs a canonical Modulus operation, where the output is on the range `[0, b)`.
+ /// Performs a canonical Modulus operation, where the output is on the range [0, <paramref name="b"/>).
/// </summary>
/// <param name="a">The dividend, the primary input.</param>
- /// <param name="b">The divisor. The output is on the range `[0, b)`.</param>
+ /// <param name="b">The divisor. The output is on the range [0, <paramref name="b"/>).</param>
/// <returns>The resulting output.</returns>
public static real_t PosMod(real_t a, real_t b)
{
@@ -481,11 +477,11 @@ namespace Godot
}
/// <summary>
- /// Returns the result of `x` raised to the power of `y`.
+ /// Returns the result of <paramref name="x"/> raised to the power of <paramref name="y"/>.
/// </summary>
/// <param name="x">The base.</param>
/// <param name="y">The exponent.</param>
- /// <returns>`x` raised to the power of `y`.</returns>
+ /// <returns><paramref name="x"/> raised to the power of <paramref name="y"/>.</returns>
public static real_t Pow(real_t x, real_t y)
{
return (real_t)Math.Pow(x, y);
@@ -498,11 +494,11 @@ namespace Godot
/// <returns>The same angle expressed in degrees.</returns>
public static real_t Rad2Deg(real_t rad)
{
- return rad * Rad2DegConst;
+ return rad * _rad2DegConst;
}
/// <summary>
- /// Rounds `s` to the nearest whole number,
+ /// Rounds <paramref name="s"/> to the nearest whole number,
/// with halfway cases rounded towards the nearest multiple of two.
/// </summary>
/// <param name="s">The number to round.</param>
@@ -513,10 +509,11 @@ namespace Godot
}
/// <summary>
- /// Returns the sign of `s`: `-1` or `1`. Returns `0` if `s` is `0`.
+ /// Returns the sign of <paramref name="s"/>: <c>-1</c> or <c>1</c>.
+ /// Returns <c>0</c> if <paramref name="s"/> is <c>0</c>.
/// </summary>
/// <param name="s">The input number.</param>
- /// <returns>One of three possible values: `1`, `-1`, or `0`.</returns>
+ /// <returns>One of three possible values: <c>1</c>, <c>-1</c>, or <c>0</c>.</returns>
public static int Sign(int s)
{
if (s == 0)
@@ -525,10 +522,11 @@ namespace Godot
}
/// <summary>
- /// Returns the sign of `s`: `-1` or `1`. Returns `0` if `s` is `0`.
+ /// Returns the sign of <paramref name="s"/>: <c>-1</c> or <c>1</c>.
+ /// Returns <c>0</c> if <paramref name="s"/> is <c>0</c>.
/// </summary>
/// <param name="s">The input number.</param>
- /// <returns>One of three possible values: `1`, `-1`, or `0`.</returns>
+ /// <returns>One of three possible values: <c>1</c>, <c>-1</c>, or <c>0</c>.</returns>
public static int Sign(real_t s)
{
if (s == 0)
@@ -537,7 +535,7 @@ namespace Godot
}
/// <summary>
- /// Returns the sine of angle `s` in radians.
+ /// Returns the sine of angle <paramref name="s"/> in radians.
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The sine of that angle.</returns>
@@ -547,7 +545,7 @@ namespace Godot
}
/// <summary>
- /// Returns the hyperbolic sine of angle `s` in radians.
+ /// Returns the hyperbolic sine of angle <paramref name="s"/> in radians.
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The hyperbolic sine of that angle.</returns>
@@ -557,8 +555,8 @@ namespace Godot
}
/// <summary>
- /// Returns a number smoothly interpolated between `from` and `to`,
- /// based on the `weight`. Similar to <see cref="Lerp(real_t, real_t, real_t)"/>,
+ /// Returns a number smoothly interpolated between <paramref name="from"/> and <paramref name="to"/>,
+ /// based on the <paramref name="weight"/>. Similar to <see cref="Lerp(real_t, real_t, real_t)"/>,
/// but interpolates faster at the beginning and slower at the end.
/// </summary>
/// <param name="from">The start value for interpolation.</param>
@@ -572,16 +570,16 @@ namespace Godot
return from;
}
real_t x = Clamp((weight - from) / (to - from), (real_t)0.0, (real_t)1.0);
- return x * x * (3 - 2 * x);
+ return x * x * (3 - (2 * x));
}
/// <summary>
- /// Returns the square root of `s`, where `s` is a non-negative number.
+ /// Returns the square root of <paramref name="s"/>, where <paramref name="s"/> is a non-negative number.
///
- /// If you need negative inputs, use `System.Numerics.Complex`.
+ /// If you need negative inputs, use <see cref="System.Numerics.Complex"/>.
/// </summary>
/// <param name="s">The input number. Must not be negative.</param>
- /// <returns>The square root of `s`.</returns>
+ /// <returns>The square root of <paramref name="s"/>.</returns>
public static real_t Sqrt(real_t s)
{
return (real_t)Math.Sqrt(s);
@@ -596,7 +594,8 @@ namespace Godot
/// <returns>The position of the first non-zero digit.</returns>
public static int StepDecimals(real_t step)
{
- double[] sd = new double[] {
+ double[] sd = new double[]
+ {
0.9999,
0.09999,
0.009999,
@@ -607,7 +606,7 @@ namespace Godot
0.00000009999,
0.000000009999,
};
- double abs = Mathf.Abs(step);
+ double abs = Abs(step);
double decs = abs - (int)abs; // Strip away integer part
for (int i = 0; i < sd.Length; i++)
{
@@ -620,9 +619,8 @@ namespace Godot
}
/// <summary>
- /// Snaps float value `s` to a given `step`.
- /// This can also be used to round a floating point
- /// number to an arbitrary number of decimals.
+ /// Snaps float value <paramref name="s"/> to a given <paramref name="step"/>.
+ /// This can also be used to round a floating point number to an arbitrary number of decimals.
/// </summary>
/// <param name="s">The value to snap.</param>
/// <param name="step">The step size to snap to.</param>
@@ -631,14 +629,14 @@ namespace Godot
{
if (step != 0f)
{
- return Floor(s / step + 0.5f) * step;
+ return Floor((s / step) + 0.5f) * step;
}
return s;
}
/// <summary>
- /// Returns the tangent of angle `s` in radians.
+ /// Returns the tangent of angle <paramref name="s"/> in radians.
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The tangent of that angle.</returns>
@@ -648,7 +646,7 @@ namespace Godot
}
/// <summary>
- /// Returns the hyperbolic tangent of angle `s` in radians.
+ /// Returns the hyperbolic tangent of angle <paramref name="s"/> in radians.
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The hyperbolic tangent of that angle.</returns>
@@ -658,8 +656,9 @@ namespace Godot
}
/// <summary>
- /// Wraps `value` between `min` and `max`. Usable for creating loop-alike
- /// behavior or infinite surfaces. If `min` is `0`, this is equivalent
+ /// Wraps <paramref name="value"/> between <paramref name="min"/> and <paramref name="max"/>.
+ /// Usable for creating loop-alike behavior or infinite surfaces.
+ /// If <paramref name="min"/> is <c>0</c>, this is equivalent
/// to <see cref="PosMod(int, int)"/>, so prefer using that instead.
/// </summary>
/// <param name="value">The value to wrap.</param>
@@ -669,12 +668,16 @@ namespace Godot
public static int Wrap(int value, int min, int max)
{
int range = max - min;
- return range == 0 ? min : min + ((value - min) % range + range) % range;
+ if (range == 0)
+ return min;
+
+ return min + ((((value - min) % range) + range) % range);
}
/// <summary>
- /// Wraps `value` between `min` and `max`. Usable for creating loop-alike
- /// behavior or infinite surfaces. If `min` is `0`, this is equivalent
+ /// Wraps <paramref name="value"/> between <paramref name="min"/> and <paramref name="max"/>.
+ /// Usable for creating loop-alike behavior or infinite surfaces.
+ /// If <paramref name="min"/> is <c>0</c>, this is equivalent
/// to <see cref="PosMod(real_t, real_t)"/>, so prefer using that instead.
/// </summary>
/// <param name="value">The value to wrap.</param>
@@ -684,7 +687,11 @@ namespace Godot
public static real_t Wrap(real_t value, real_t min, real_t max)
{
real_t range = max - min;
- return IsZeroApprox(range) ? min : min + ((value - min) % range + range) % range;
+ if (IsZeroApprox(range))
+ {
+ return min;
+ }
+ return min + ((((value - min) % range) + range) % range);
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs
index 0888e33090..9bb73ce7dd 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs
@@ -12,7 +12,7 @@ namespace Godot
// Define constants with Decimal precision and cast down to double or float.
/// <summary>
- /// The natural number `e`.
+ /// The natural number <c>e</c>.
/// </summary>
public const real_t E = (real_t)2.7182818284590452353602874714M; // 2.7182817f and 2.718281828459045
@@ -23,7 +23,7 @@ namespace Godot
/// <summary>
/// A very small number used for float comparison with error tolerance.
- /// 1e-06 with single-precision floats, but 1e-14 if `REAL_T_IS_DOUBLE`.
+ /// 1e-06 with single-precision floats, but 1e-14 if <c>REAL_T_IS_DOUBLE</c>.
/// </summary>
#if REAL_T_IS_DOUBLE
public const real_t Epsilon = 1e-14; // Epsilon size should depend on the precision used.
@@ -44,7 +44,7 @@ namespace Godot
/// <summary>
/// Returns the amount of digits after the decimal place.
/// </summary>
- /// <param name="s">The input <see cref="System.Decimal"/> value.</param>
+ /// <param name="s">The input <see cref="decimal"/> value.</param>
/// <returns>The amount of digits.</returns>
public static int DecimalCount(decimal s)
{
@@ -52,48 +52,51 @@ namespace Godot
}
/// <summary>
- /// Rounds `s` upward (towards positive infinity).
+ /// Rounds <paramref name="s"/> upward (towards positive infinity).
///
- /// This is the same as <see cref="Ceil(real_t)"/>, but returns an `int`.
+ /// This is the same as <see cref="Ceil(real_t)"/>, but returns an <c>int</c>.
/// </summary>
/// <param name="s">The number to ceil.</param>
- /// <returns>The smallest whole number that is not less than `s`.</returns>
+ /// <returns>The smallest whole number that is not less than <paramref name="s"/>.</returns>
public static int CeilToInt(real_t s)
{
return (int)Math.Ceiling(s);
}
/// <summary>
- /// Rounds `s` downward (towards negative infinity).
+ /// Rounds <paramref name="s"/> downward (towards negative infinity).
///
- /// This is the same as <see cref="Floor(real_t)"/>, but returns an `int`.
+ /// This is the same as <see cref="Floor(real_t)"/>, but returns an <c>int</c>.
/// </summary>
/// <param name="s">The number to floor.</param>
- /// <returns>The largest whole number that is not more than `s`.</returns>
+ /// <returns>The largest whole number that is not more than <paramref name="s"/>.</returns>
public static int FloorToInt(real_t s)
{
return (int)Math.Floor(s);
}
/// <summary>
+ /// Rounds <paramref name="s"/> to the nearest whole number.
///
+ /// This is the same as <see cref="Round(real_t)"/>, but returns an <c>int</c>.
/// </summary>
- /// <param name="s"></param>
- /// <returns></returns>
+ /// <param name="s">The number to round.</param>
+ /// <returns>The rounded number.</returns>
public static int RoundToInt(real_t s)
{
return (int)Math.Round(s);
}
/// <summary>
- /// Returns true if `a` and `b` are approximately equal to each other.
+ /// Returns <see langword="true"/> if <paramref name="a"/> and <paramref name="b"/> are approximately
+ /// equal to each other.
/// The comparison is done using the provided tolerance value.
/// If you want the tolerance to be calculated for you, use <see cref="IsEqualApprox(real_t, real_t)"/>.
/// </summary>
/// <param name="a">One of the values.</param>
/// <param name="b">The other value.</param>
/// <param name="tolerance">The pre-calculated tolerance value.</param>
- /// <returns>A bool for whether or not the two values are equal.</returns>
+ /// <returns>A <see langword="bool"/> for whether or not the two values are equal.</returns>
public static bool IsEqualApprox(real_t a, real_t b, real_t tolerance)
{
// Check for exact equality first, required to handle "infinity" values.
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
index 4ecc55f94e..f53b5dc904 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
@@ -3,9 +3,45 @@ using System.Runtime.CompilerServices;
namespace Godot
{
+ /// <summary>
+ /// A pre-parsed relative or absolute path in a scene tree,
+ /// for use with <see cref="Node.GetNode(NodePath)"/> and similar functions.
+ /// It can reference a node, a resource within a node, or a property
+ /// of a node or resource.
+ /// For instance, <c>"Path2D/PathFollow2D/Sprite2D:texture:size"</c>
+ /// would refer to the <c>size</c> property of the <c>texture</c>
+ /// resource on the node named <c>"Sprite2D"</c> which is a child of
+ /// the other named nodes in the path.
+ /// You will usually just pass a string to <see cref="Node.GetNode(NodePath)"/>
+ /// and it will be automatically converted, but you may occasionally
+ /// want to parse a path ahead of time with NodePath.
+ /// Exporting a NodePath variable will give you a node selection widget
+ /// in the properties panel of the editor, which can often be useful.
+ /// A NodePath is composed of a list of slash-separated node names
+ /// (like a filesystem path) and an optional colon-separated list of
+ /// "subnames" which can be resources or properties.
+ ///
+ /// Note: In the editor, NodePath properties are automatically updated when moving,
+ /// renaming or deleting a node in the scene tree, but they are never updated at runtime.
+ /// </summary>
+ /// <example>
+ /// Some examples of NodePaths include the following:
+ /// <code>
+ /// // No leading slash means it is relative to the current node.
+ /// new NodePath("A"); // Immediate child A.
+ /// new NodePath("A/B"); // A's child B.
+ /// new NodePath("."); // The current node.
+ /// new NodePath(".."); // The parent node.
+ /// new NodePath("../C"); // A sibling node C.
+ /// // A leading slash means it is absolute from the SceneTree.
+ /// new NodePath("/root"); // Equivalent to GetTree().Root
+ /// new NodePath("/root/Main"); // If your main scene's root node were named "Main".
+ /// new NodePath("/root/MyAutoload"); // If you have an autoloaded node or scene.
+ /// </code>
+ /// </example>
public sealed partial class NodePath : IDisposable
{
- private bool disposed = false;
+ private bool _disposed = false;
private IntPtr ptr;
@@ -14,7 +50,7 @@ namespace Godot
if (instance == null)
throw new NullReferenceException($"The instance of type {nameof(NodePath)} is null.");
- if (instance.disposed)
+ if (instance._disposed)
throw new ObjectDisposedException(instance.GetType().FullName);
return instance.ptr;
@@ -25,6 +61,9 @@ namespace Godot
Dispose(false);
}
+ /// <summary>
+ /// Disposes of this <see cref="NodePath"/>.
+ /// </summary>
public void Dispose()
{
Dispose(true);
@@ -33,7 +72,7 @@ namespace Godot
private void Dispose(bool disposing)
{
- if (disposed)
+ if (_disposed)
return;
if (ptr != IntPtr.Zero)
@@ -42,7 +81,7 @@ namespace Godot
ptr = IntPtr.Zero;
}
- disposed = true;
+ _disposed = true;
}
internal NodePath(IntPtr ptr)
@@ -50,57 +89,168 @@ namespace Godot
this.ptr = ptr;
}
- public NodePath() : this(string.Empty) {}
-
+ /// <summary>
+ /// Constructs an empty <see cref="NodePath"/>.
+ /// </summary>
+ public NodePath() : this(string.Empty) { }
+
+ /// <summary>
+ /// Constructs a <see cref="NodePath"/> from a string <paramref name="path"/>,
+ /// e.g.: <c>"Path2D/PathFollow2D/Sprite2D:texture:size"</c>.
+ /// A path is absolute if it starts with a slash. Absolute paths
+ /// are only valid in the global scene tree, not within individual
+ /// scenes. In a relative path, <c>"."</c> and <c>".."</c> indicate
+ /// the current node and its parent.
+ /// The "subnames" optionally included after the path to the target
+ /// node can point to resources or properties, and can also be nested.
+ /// </summary>
+ /// <example>
+ /// Examples of valid NodePaths (assuming that those nodes exist and
+ /// have the referenced resources or properties):
+ /// <code>
+ /// // Points to the Sprite2D node.
+ /// "Path2D/PathFollow2D/Sprite2D"
+ /// // Points to the Sprite2D node and its "texture" resource.
+ /// // GetNode() would retrieve "Sprite2D", while GetNodeAndResource()
+ /// // would retrieve both the Sprite2D node and the "texture" resource.
+ /// "Path2D/PathFollow2D/Sprite2D:texture"
+ /// // Points to the Sprite2D node and its "position" property.
+ /// "Path2D/PathFollow2D/Sprite2D:position"
+ /// // Points to the Sprite2D node and the "x" component of its "position" property.
+ /// "Path2D/PathFollow2D/Sprite2D:position:x"
+ /// // Absolute path (from "root")
+ /// "/root/Level/Path2D"
+ /// </code>
+ /// </example>
+ /// <param name="path"></param>
public NodePath(string path)
{
ptr = godot_icall_NodePath_Ctor(path);
}
+ /// <summary>
+ /// Converts a string to a <see cref="NodePath"/>.
+ /// </summary>
+ /// <param name="from">The string to convert.</param>
public static implicit operator NodePath(string from) => new NodePath(from);
+ /// <summary>
+ /// Converts this <see cref="NodePath"/> to a string.
+ /// </summary>
+ /// <param name="from">The <see cref="NodePath"/> to convert.</param>
public static implicit operator string(NodePath from) => from.ToString();
+ /// <summary>
+ /// Converts this <see cref="NodePath"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this <see cref="NodePath"/>.</returns>
public override string ToString()
{
return godot_icall_NodePath_operator_String(GetPtr(this));
}
+ /// <summary>
+ /// Returns a node path with a colon character (<c>:</c>) prepended,
+ /// transforming it to a pure property path with no node name (defaults
+ /// to resolving from the current node).
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// // This will be parsed as a node path to the "x" property in the "position" node.
+ /// var nodePath = new NodePath("position:x");
+ /// // This will be parsed as a node path to the "x" component of the "position" property in the current node.
+ /// NodePath propertyPath = nodePath.GetAsPropertyPath();
+ /// GD.Print(propertyPath); // :position:x
+ /// </code>
+ /// </example>
+ /// <returns>The <see cref="NodePath"/> as a pure property path.</returns>
public NodePath GetAsPropertyPath()
{
return new NodePath(godot_icall_NodePath_get_as_property_path(GetPtr(this)));
}
+ /// <summary>
+ /// Returns all subnames concatenated with a colon character (<c>:</c>)
+ /// as separator, i.e. the right side of the first colon in a node path.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// var nodepath = new NodePath("Path2D/PathFollow2D/Sprite2D:texture:load_path");
+ /// GD.Print(nodepath.GetConcatenatedSubnames()); // texture:load_path
+ /// </code>
+ /// </example>
+ /// <returns>The subnames concatenated with <c>:</c>.</returns>
public string GetConcatenatedSubnames()
{
return godot_icall_NodePath_get_concatenated_subnames(GetPtr(this));
}
+ /// <summary>
+ /// Gets the node name indicated by <paramref name="idx"/> (0 to <see cref="GetNameCount"/>).
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// var nodePath = new NodePath("Path2D/PathFollow2D/Sprite2D");
+ /// GD.Print(nodePath.GetName(0)); // Path2D
+ /// GD.Print(nodePath.GetName(1)); // PathFollow2D
+ /// GD.Print(nodePath.GetName(2)); // Sprite
+ /// </code>
+ /// </example>
+ /// <param name="idx">The name index.</param>
+ /// <returns>The name at the given index <paramref name="idx"/>.</returns>
public string GetName(int idx)
{
return godot_icall_NodePath_get_name(GetPtr(this), idx);
}
+ /// <summary>
+ /// Gets the number of node names which make up the path.
+ /// Subnames (see <see cref="GetSubnameCount"/>) are not included.
+ /// For example, <c>"Path2D/PathFollow2D/Sprite2D"</c> has 3 names.
+ /// </summary>
+ /// <returns>The number of node names which make up the path.</returns>
public int GetNameCount()
{
return godot_icall_NodePath_get_name_count(GetPtr(this));
}
+ /// <summary>
+ /// Gets the resource or property name indicated by <paramref name="idx"/> (0 to <see cref="GetSubnameCount"/>).
+ /// </summary>
+ /// <param name="idx">The subname index.</param>
+ /// <returns>The subname at the given index <paramref name="idx"/>.</returns>
public string GetSubname(int idx)
{
return godot_icall_NodePath_get_subname(GetPtr(this), idx);
}
+ /// <summary>
+ /// Gets the number of resource or property names ("subnames") in the path.
+ /// Each subname is listed after a colon character (<c>:</c>) in the node path.
+ /// For example, <c>"Path2D/PathFollow2D/Sprite2D:texture:load_path"</c> has 2 subnames.
+ /// </summary>
+ /// <returns>The number of subnames in the path.</returns>
public int GetSubnameCount()
{
return godot_icall_NodePath_get_subname_count(GetPtr(this));
}
+ /// <summary>
+ /// Returns <see langword="true"/> if the node path is absolute (as opposed to relative),
+ /// which means that it starts with a slash character (<c>/</c>). Absolute node paths can
+ /// be used to access the root node (<c>"/root"</c>) or autoloads (e.g. <c>"/global"</c>
+ /// if a "global" autoload was registered).
+ /// </summary>
+ /// <returns>If the <see cref="NodePath"/> is an absolute path.</returns>
public bool IsAbsolute()
{
return godot_icall_NodePath_is_absolute(GetPtr(this));
}
+ /// <summary>
+ /// Returns <see langword="true"/> if the node path is empty.
+ /// </summary>
+ /// <returns>If the <see cref="NodePath"/> is empty.</returns>
public bool IsEmpty()
{
return godot_icall_NodePath_is_empty(GetPtr(this));
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
index d486d79557..8fe08e7e1d 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
@@ -5,13 +5,16 @@ namespace Godot
{
public partial class Object : IDisposable
{
- private bool disposed = false;
+ private bool _disposed = false;
private static StringName nativeName = "Object";
internal IntPtr ptr;
internal bool memoryOwn;
+ /// <summary>
+ /// Constructs a new <see cref="Object"/>.
+ /// </summary>
public Object() : this(false)
{
if (ptr == IntPtr.Zero)
@@ -29,6 +32,9 @@ namespace Godot
this.memoryOwn = memoryOwn;
}
+ /// <summary>
+ /// The pointer to the native instance of this <see cref="Object"/>.
+ /// </summary>
public IntPtr NativeInstance
{
get { return ptr; }
@@ -39,7 +45,7 @@ namespace Godot
if (instance == null)
return IntPtr.Zero;
- if (instance.disposed)
+ if (instance._disposed)
throw new ObjectDisposedException(instance.GetType().FullName);
return instance.ptr;
@@ -50,15 +56,21 @@ namespace Godot
Dispose(false);
}
+ /// <summary>
+ /// Disposes of this <see cref="Object"/>.
+ /// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
+ /// <summary>
+ /// Disposes implementation of this <see cref="Object"/>.
+ /// </summary>
protected virtual void Dispose(bool disposing)
{
- if (disposed)
+ if (_disposed)
return;
if (ptr != IntPtr.Zero)
@@ -73,19 +85,23 @@ namespace Godot
godot_icall_Object_Disposed(this, ptr);
}
- this.ptr = IntPtr.Zero;
+ ptr = IntPtr.Zero;
}
- disposed = true;
+ _disposed = true;
}
+ /// <summary>
+ /// Converts this <see cref="Object"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this object.</returns>
public override string ToString()
{
return godot_icall_Object_ToString(GetPtr(this));
}
/// <summary>
- /// Returns a new <see cref="Godot.SignalAwaiter"/> awaiter configured to complete when the instance
+ /// Returns a new <see cref="SignalAwaiter"/> awaiter configured to complete when the instance
/// <paramref name="source"/> emits the signal specified by the <paramref name="signal"/> parameter.
/// </summary>
/// <param name="source">
@@ -107,13 +123,17 @@ namespace Godot
/// }
/// </code>
/// </example>
+ /// <returns>
+ /// A <see cref="SignalAwaiter"/> that completes when
+ /// <paramref name="source"/> emits the <paramref name="signal"/>.
+ /// </returns>
public SignalAwaiter ToSignal(Object source, StringName signal)
{
return new SignalAwaiter(source, signal, this);
}
/// <summary>
- /// Gets a new <see cref="Godot.DynamicGodotObject"/> associated with this instance.
+ /// Gets a new <see cref="DynamicGodotObject"/> associated with this instance.
/// </summary>
public dynamic DynamicObject => new DynamicGodotObject(this);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs
index 6972102730..66f7b745f7 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs
@@ -21,10 +21,10 @@ namespace Godot
/// <summary>
/// The normal of the plane, which must be normalized.
- /// In the scalar equation of the plane `ax + by + cz = d`, this is
- /// the vector `(a, b, c)`, where `d` is the <see cref="D"/> property.
+ /// In the scalar equation of the plane <c>ax + by + cz = d</c>, this is
+ /// the vector <c>(a, b, c)</c>, where <c>d</c> is the <see cref="D"/> property.
/// </summary>
- /// <value>Equivalent to `x`, `y`, and `z`.</value>
+ /// <value>Equivalent to <see cref="x"/>, <see cref="y"/>, and <see cref="z"/>.</value>
public Vector3 Normal
{
get { return _normal; }
@@ -82,8 +82,8 @@ namespace Godot
/// <summary>
/// The distance from the origin to the plane (in the direction of
/// <see cref="Normal"/>). This value is typically non-negative.
- /// In the scalar equation of the plane `ax + by + cz = d`,
- /// this is `d`, while the `(a, b, c)` coordinates are represented
+ /// In the scalar equation of the plane <c>ax + by + cz = d</c>,
+ /// this is <c>d</c>, while the <c>(a, b, c)</c> coordinates are represented
/// by the <see cref="Normal"/> property.
/// </summary>
/// <value>The plane's distance from the origin.</value>
@@ -92,7 +92,7 @@ namespace Godot
/// <summary>
/// The center of the plane, the point where the normal line intersects the plane.
/// </summary>
- /// <value>Equivalent to <see cref="Normal"/> multiplied by `D`.</value>
+ /// <value>Equivalent to <see cref="Normal"/> multiplied by <see cref="D"/>.</value>
public Vector3 Center
{
get
@@ -107,7 +107,7 @@ namespace Godot
}
/// <summary>
- /// Returns the shortest distance from this plane to the position `point`.
+ /// Returns the shortest distance from this plane to the position <paramref name="point"/>.
/// </summary>
/// <param name="point">The position to use for the calculation.</param>
/// <returns>The shortest distance.</returns>
@@ -117,12 +117,12 @@ namespace Godot
}
/// <summary>
- /// Returns true if point is inside the plane.
+ /// Returns <see langword="true"/> if point is inside the plane.
/// Comparison uses a custom minimum epsilon threshold.
/// </summary>
/// <param name="point">The point to check.</param>
/// <param name="epsilon">The tolerance threshold.</param>
- /// <returns>A bool for whether or not the plane has the point.</returns>
+ /// <returns>A <see langword="bool"/> for whether or not the plane has the point.</returns>
public bool HasPoint(Vector3 point, real_t epsilon = Mathf.Epsilon)
{
real_t dist = _normal.Dot(point) - D;
@@ -130,12 +130,12 @@ namespace Godot
}
/// <summary>
- /// Returns the intersection point of the three planes: `b`, `c`,
- /// and this plane. If no intersection is found, `null` is returned.
+ /// Returns the intersection point of the three planes: <paramref name="b"/>, <paramref name="c"/>,
+ /// and this plane. If no intersection is found, <see langword="null"/> is returned.
/// </summary>
/// <param name="b">One of the three planes to use in the calculation.</param>
/// <param name="c">One of the three planes to use in the calculation.</param>
- /// <returns>The intersection, or `null` if none is found.</returns>
+ /// <returns>The intersection, or <see langword="null"/> if none is found.</returns>
public Vector3? Intersect3(Plane b, Plane c)
{
real_t denom = _normal.Cross(b._normal).Dot(c._normal);
@@ -145,21 +145,21 @@ namespace Godot
return null;
}
- Vector3 result = b._normal.Cross(c._normal) * D +
- c._normal.Cross(_normal) * b.D +
- _normal.Cross(b._normal) * c.D;
+ Vector3 result = (b._normal.Cross(c._normal) * D) +
+ (c._normal.Cross(_normal) * b.D) +
+ (_normal.Cross(b._normal) * c.D);
return result / denom;
}
/// <summary>
- /// Returns the intersection point of a ray consisting of the
- /// position `from` and the direction normal `dir` with this plane.
- /// If no intersection is found, `null` is returned.
+ /// Returns the intersection point of a ray consisting of the position <paramref name="from"/>
+ /// and the direction normal <paramref name="dir"/> with this plane.
+ /// If no intersection is found, <see langword="null"/> is returned.
/// </summary>
/// <param name="from">The start of the ray.</param>
/// <param name="dir">The direction of the ray, normalized.</param>
- /// <returns>The intersection, or `null` if none is found.</returns>
+ /// <returns>The intersection, or <see langword="null"/> if none is found.</returns>
public Vector3? IntersectRay(Vector3 from, Vector3 dir)
{
real_t den = _normal.Dot(dir);
@@ -182,12 +182,12 @@ namespace Godot
/// <summary>
/// Returns the intersection point of a line segment from
- /// position `begin` to position `end` with this plane.
- /// If no intersection is found, `null` is returned.
+ /// position <paramref name="begin"/> to position <paramref name="end"/> with this plane.
+ /// If no intersection is found, <see langword="null"/> is returned.
/// </summary>
/// <param name="begin">The start of the line segment.</param>
/// <param name="end">The end of the line segment.</param>
- /// <returns>The intersection, or `null` if none is found.</returns>
+ /// <returns>The intersection, or <see langword="null"/> if none is found.</returns>
public Vector3? IntersectSegment(Vector3 begin, Vector3 end)
{
Vector3 segment = begin - end;
@@ -210,10 +210,10 @@ namespace Godot
}
/// <summary>
- /// Returns true if `point` is located above the plane.
+ /// Returns <see langword="true"/> if <paramref name="point"/> is located above the plane.
/// </summary>
/// <param name="point">The point to check.</param>
- /// <returns>A bool for whether or not the point is above the plane.</returns>
+ /// <returns>A <see langword="bool"/> for whether or not the point is above the plane.</returns>
public bool IsPointOver(Vector3 point)
{
return _normal.Dot(point) > D;
@@ -236,13 +236,13 @@ namespace Godot
}
/// <summary>
- /// Returns the orthogonal projection of `point` into the plane.
+ /// Returns the orthogonal projection of <paramref name="point"/> into the plane.
/// </summary>
/// <param name="point">The point to project.</param>
/// <returns>The projected point.</returns>
public Vector3 Project(Vector3 point)
{
- return point - _normal * DistanceTo(point);
+ return point - (_normal * DistanceTo(point));
}
// Constants
@@ -251,27 +251,28 @@ namespace Godot
private static readonly Plane _planeXY = new Plane(0, 0, 1, 0);
/// <summary>
- /// A plane that extends in the Y and Z axes (normal vector points +X).
+ /// A <see cref="Plane"/> that extends in the Y and Z axes (normal vector points +X).
/// </summary>
- /// <value>Equivalent to `new Plane(1, 0, 0, 0)`.</value>
+ /// <value>Equivalent to <c>new Plane(1, 0, 0, 0)</c>.</value>
public static Plane PlaneYZ { get { return _planeYZ; } }
/// <summary>
- /// A plane that extends in the X and Z axes (normal vector points +Y).
+ /// A <see cref="Plane"/> that extends in the X and Z axes (normal vector points +Y).
/// </summary>
- /// <value>Equivalent to `new Plane(0, 1, 0, 0)`.</value>
+ /// <value>Equivalent to <c>new Plane(0, 1, 0, 0)</c>.</value>
public static Plane PlaneXZ { get { return _planeXZ; } }
/// <summary>
- /// A plane that extends in the X and Y axes (normal vector points +Z).
+ /// A <see cref="Plane"/> that extends in the X and Y axes (normal vector points +Z).
/// </summary>
- /// <value>Equivalent to `new Plane(0, 0, 1, 0)`.</value>
+ /// <value>Equivalent to <c>new Plane(0, 0, 1, 0)</c>.</value>
public static Plane PlaneXY { get { return _planeXY; } }
/// <summary>
- /// Constructs a plane from four values. `a`, `b` and `c` become the
+ /// Constructs a <see cref="Plane"/> from four values.
+ /// <paramref name="a"/>, <paramref name="b"/> and <paramref name="c"/> become the
/// components of the resulting plane's <see cref="Normal"/> vector.
- /// `d` becomes the plane's distance from the origin.
+ /// <paramref name="d"/> becomes the plane's distance from the origin.
/// </summary>
/// <param name="a">The X component of the plane's normal vector.</param>
/// <param name="b">The Y component of the plane's normal vector.</param>
@@ -280,22 +281,23 @@ namespace Godot
public Plane(real_t a, real_t b, real_t c, real_t d)
{
_normal = new Vector3(a, b, c);
- this.D = d;
+ D = d;
}
/// <summary>
- /// Constructs a plane from a normal vector and the plane's distance to the origin.
+ /// Constructs a <see cref="Plane"/> from a <paramref name="normal"/> vector and
+ /// the plane's distance to the origin <paramref name="d"/>.
/// </summary>
/// <param name="normal">The normal of the plane, must be normalized.</param>
/// <param name="d">The plane's distance from the origin. This value is typically non-negative.</param>
public Plane(Vector3 normal, real_t d)
{
- this._normal = normal;
- this.D = d;
+ _normal = normal;
+ D = d;
}
/// <summary>
- /// Constructs a plane from the three points, given in clockwise order.
+ /// Constructs a <see cref="Plane"/> from the three points, given in clockwise order.
/// </summary>
/// <param name="v1">The first point.</param>
/// <param name="v2">The second point.</param>
@@ -322,6 +324,11 @@ namespace Godot
return !left.Equals(right);
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this plane and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the plane and the other object are equal.</returns>
public override bool Equals(object obj)
{
if (obj is Plane)
@@ -332,14 +339,19 @@ namespace Godot
return false;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this plane and <paramref name="other"/> are equal.
+ /// </summary>
+ /// <param name="other">The other plane to compare.</param>
+ /// <returns>Whether or not the planes are equal.</returns>
public bool Equals(Plane other)
{
return _normal == other._normal && D == other.D;
}
/// <summary>
- /// Returns true if this plane and `other` are approximately equal, by running
- /// <see cref="Mathf.IsEqualApprox(real_t, real_t)"/> on each component.
+ /// Returns <see langword="true"/> if this plane and <paramref name="other"/> are
+ /// approximately equal, by running <see cref="Mathf.IsEqualApprox(real_t, real_t)"/> on each component.
/// </summary>
/// <param name="other">The other plane to compare.</param>
/// <returns>Whether or not the planes are approximately equal.</returns>
@@ -348,16 +360,28 @@ namespace Godot
return _normal.IsEqualApprox(other._normal) && Mathf.IsEqualApprox(D, other.D);
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="Plane"/>.
+ /// </summary>
+ /// <returns>A hash code for this plane.</returns>
public override int GetHashCode()
{
return _normal.GetHashCode() ^ D.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="Plane"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this plane.</returns>
public override string ToString()
{
return $"{_normal}, {D}";
}
+ /// <summary>
+ /// Converts this <see cref="Plane"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this plane.</returns>
public string ToString(string format)
{
return $"{_normal.ToString(format)}, {D.ToString(format)}";
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
index 0fed55cc30..1694ac0320 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
@@ -12,10 +12,10 @@ namespace Godot
/// A unit quaternion used for representing 3D rotations.
/// Quaternions need to be normalized to be used for rotation.
///
- /// It is similar to Basis, which implements matrix representation of
- /// rotations, and can be parametrized using both an axis-angle pair
- /// or Euler angles. Basis stores rotation, scale, and shearing,
- /// while Quaternion only stores rotation.
+ /// It is similar to <see cref="Basis"/>, which implements matrix
+ /// representation of rotations, and can be parametrized using both
+ /// an axis-angle pair or Euler angles. Basis stores rotation, scale,
+ /// and shearing, while Quaternion only stores rotation.
///
/// Due to its compactness and the way it is stored in memory, certain
/// operations (obtaining axis-angle and performing SLERP, in particular)
@@ -26,19 +26,19 @@ namespace Godot
public struct Quaternion : IEquatable<Quaternion>
{
/// <summary>
- /// X component of the quaternion (imaginary `i` axis part).
+ /// X component of the quaternion (imaginary <c>i</c> axis part).
/// Quaternion components should usually not be manipulated directly.
/// </summary>
public real_t x;
/// <summary>
- /// Y component of the quaternion (imaginary `j` axis part).
+ /// Y component of the quaternion (imaginary <c>j</c> axis part).
/// Quaternion components should usually not be manipulated directly.
/// </summary>
public real_t y;
/// <summary>
- /// Z component of the quaternion (imaginary `k` axis part).
+ /// Z component of the quaternion (imaginary <c>k</c> axis part).
/// Quaternion components should usually not be manipulated directly.
/// </summary>
public real_t z;
@@ -52,7 +52,12 @@ namespace Godot
/// <summary>
/// Access quaternion components using their index.
/// </summary>
- /// <value>`[0]` is equivalent to `.x`, `[1]` is equivalent to `.y`, `[2]` is equivalent to `.z`, `[3]` is equivalent to `.w`.</value>
+ /// <value>
+ /// <c>[0]</c> is equivalent to <see cref="x"/>,
+ /// <c>[1]</c> is equivalent to <see cref="y"/>,
+ /// <c>[2]</c> is equivalent to <see cref="z"/>,
+ /// <c>[3]</c> is equivalent to <see cref="w"/>.
+ /// </value>
public real_t this[int index]
{
get
@@ -96,7 +101,8 @@ namespace Godot
/// <summary>
/// Returns the length (magnitude) of the quaternion.
/// </summary>
- /// <value>Equivalent to `Mathf.Sqrt(LengthSquared)`.</value>
+ /// <seealso cref="LengthSquared"/>
+ /// <value>Equivalent to <c>Mathf.Sqrt(LengthSquared)</c>.</value>
public real_t Length
{
get { return Mathf.Sqrt(LengthSquared); }
@@ -107,14 +113,14 @@ namespace Godot
/// This method runs faster than <see cref="Length"/>, so prefer it if
/// you need to compare quaternions or need the squared length for some formula.
/// </summary>
- /// <value>Equivalent to `Dot(this)`.</value>
+ /// <value>Equivalent to <c>Dot(this)</c>.</value>
public real_t LengthSquared
{
get { return Dot(this); }
}
/// <summary>
- /// Returns the angle between this quaternion and `to`.
+ /// Returns the angle between this quaternion and <paramref name="to"/>.
/// This is the magnitude of the angle you would need to rotate
/// by to get from one to the other.
///
@@ -131,12 +137,12 @@ namespace Godot
}
/// <summary>
- /// Performs a cubic spherical interpolation between quaternions `preA`,
- /// this vector, `b`, and `postB`, by the given amount `t`.
+ /// Performs a cubic spherical interpolation between quaternions <paramref name="preA"/>, this quaternion,
+ /// <paramref name="b"/>, and <paramref name="postB"/>, by the given amount <paramref name="weight"/>.
/// </summary>
/// <param name="b">The destination quaternion.</param>
/// <param name="preA">A quaternion before this quaternion.</param>
- /// <param name="postB">A quaternion after `b`.</param>
+ /// <param name="postB">A quaternion after <paramref name="b"/>.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The interpolated quaternion.</returns>
public Quaternion CubicSlerp(Quaternion b, Quaternion preA, Quaternion postB, real_t weight)
@@ -154,7 +160,7 @@ namespace Godot
/// <returns>The dot product.</returns>
public real_t Dot(Quaternion b)
{
- return x * b.x + y * b.y + z * b.z + w * b.w;
+ return (x * b.x) + (y * b.y) + (z * b.z) + (w * b.w);
}
/// <summary>
@@ -194,7 +200,7 @@ namespace Godot
/// <summary>
/// Returns whether the quaternion is normalized or not.
/// </summary>
- /// <returns>A bool for whether the quaternion is normalized or not.</returns>
+ /// <returns>A <see langword="bool"/> for whether the quaternion is normalized or not.</returns>
public bool IsNormalized()
{
return Mathf.Abs(LengthSquared - 1) <= Mathf.Epsilon;
@@ -211,7 +217,7 @@ namespace Godot
/// <summary>
/// Returns the result of the spherical linear interpolation between
- /// this quaternion and `to` by amount `weight`.
+ /// this quaternion and <paramref name="to"/> by amount <paramref name="weight"/>.
///
/// Note: Both quaternions must be normalized.
/// </summary>
@@ -274,16 +280,16 @@ namespace Godot
// Calculate final values.
return new Quaternion
(
- scale0 * x + scale1 * to1.x,
- scale0 * y + scale1 * to1.y,
- scale0 * z + scale1 * to1.z,
- scale0 * w + scale1 * to1.w
+ (scale0 * x) + (scale1 * to1.x),
+ (scale0 * y) + (scale1 * to1.y),
+ (scale0 * z) + (scale1 * to1.z),
+ (scale0 * w) + (scale1 * to1.w)
);
}
/// <summary>
/// Returns the result of the spherical linear interpolation between
- /// this quaternion and `to` by amount `weight`, but without
+ /// this quaternion and <paramref name="to"/> by amount <paramref name="weight"/>, but without
/// checking if the rotation path is not bigger than 90 degrees.
/// </summary>
/// <param name="to">The destination quaternion for interpolation. Must be normalized.</param>
@@ -305,10 +311,10 @@ namespace Godot
return new Quaternion
(
- invFactor * x + newFactor * to.x,
- invFactor * y + newFactor * to.y,
- invFactor * z + newFactor * to.z,
- invFactor * w + newFactor * to.w
+ (invFactor * x) + (newFactor * to.x),
+ (invFactor * y) + (newFactor * to.y),
+ (invFactor * z) + (newFactor * to.z),
+ (invFactor * w) + (newFactor * to.w)
);
}
@@ -327,7 +333,7 @@ namespace Godot
#endif
var u = new Vector3(x, y, z);
Vector3 uv = u.Cross(v);
- return v + ((uv * w) + u.Cross(uv)) * 2;
+ return v + (((uv * w) + u.Cross(uv)) * 2);
}
// Constants
@@ -338,15 +344,15 @@ namespace Godot
/// Equivalent to an identity <see cref="Basis"/> matrix. If a vector is transformed by
/// an identity quaternion, it will not change.
/// </summary>
- /// <value>Equivalent to `new Quaternion(0, 0, 0, 1)`.</value>
+ /// <value>Equivalent to <c>new Quaternion(0, 0, 0, 1)</c>.</value>
public static Quaternion Identity { get { return _identity; } }
/// <summary>
- /// Constructs a quaternion defined by the given values.
+ /// Constructs a <see cref="Quaternion"/> defined by the given values.
/// </summary>
- /// <param name="x">X component of the quaternion (imaginary `i` axis part).</param>
- /// <param name="y">Y component of the quaternion (imaginary `j` axis part).</param>
- /// <param name="z">Z component of the quaternion (imaginary `k` axis part).</param>
+ /// <param name="x">X component of the quaternion (imaginary <c>i</c> axis part).</param>
+ /// <param name="y">Y component of the quaternion (imaginary <c>j</c> axis part).</param>
+ /// <param name="z">Z component of the quaternion (imaginary <c>k</c> axis part).</param>
/// <param name="w">W component of the quaternion (real part).</param>
public Quaternion(real_t x, real_t y, real_t z, real_t w)
{
@@ -357,7 +363,7 @@ namespace Godot
}
/// <summary>
- /// Constructs a quaternion from the given quaternion.
+ /// Constructs a <see cref="Quaternion"/> from the given <see cref="Quaternion"/>.
/// </summary>
/// <param name="q">The existing quaternion.</param>
public Quaternion(Quaternion q)
@@ -366,46 +372,45 @@ namespace Godot
}
/// <summary>
- /// Constructs a quaternion from the given <see cref="Basis"/>.
+ /// Constructs a <see cref="Quaternion"/> from the given <see cref="Basis"/>.
/// </summary>
- /// <param name="basis">The basis to construct from.</param>
+ /// <param name="basis">The <see cref="Basis"/> to construct from.</param>
public Quaternion(Basis basis)
{
this = basis.Quaternion();
}
/// <summary>
- /// Constructs a quaternion that will perform a rotation specified by
- /// Euler angles (in the YXZ convention: when decomposing,
- /// first Z, then X, and Y last),
+ /// Constructs a <see cref="Quaternion"/> that will perform a rotation specified by
+ /// Euler angles (in the YXZ convention: when decomposing, first Z, then X, and Y last),
/// given in the vector format as (X angle, Y angle, Z angle).
/// </summary>
- /// <param name="eulerYXZ"></param>
+ /// <param name="eulerYXZ">Euler angles that the quaternion will be rotated by.</param>
public Quaternion(Vector3 eulerYXZ)
{
- real_t half_a1 = eulerYXZ.y * 0.5f;
- real_t half_a2 = eulerYXZ.x * 0.5f;
- real_t half_a3 = eulerYXZ.z * 0.5f;
+ real_t halfA1 = eulerYXZ.y * 0.5f;
+ real_t halfA2 = eulerYXZ.x * 0.5f;
+ real_t halfA3 = eulerYXZ.z * 0.5f;
// R = Y(a1).X(a2).Z(a3) convention for Euler angles.
// Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6)
// a3 is the angle of the first rotation, following the notation in this reference.
- real_t cos_a1 = Mathf.Cos(half_a1);
- real_t sin_a1 = Mathf.Sin(half_a1);
- real_t cos_a2 = Mathf.Cos(half_a2);
- real_t sin_a2 = Mathf.Sin(half_a2);
- real_t cos_a3 = Mathf.Cos(half_a3);
- real_t sin_a3 = Mathf.Sin(half_a3);
+ real_t cosA1 = Mathf.Cos(halfA1);
+ real_t sinA1 = Mathf.Sin(halfA1);
+ real_t cosA2 = Mathf.Cos(halfA2);
+ real_t sinA2 = Mathf.Sin(halfA2);
+ real_t cosA3 = Mathf.Cos(halfA3);
+ real_t sinA3 = Mathf.Sin(halfA3);
- x = sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3;
- y = sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3;
- z = cos_a1 * cos_a2 * sin_a3 - sin_a1 * sin_a2 * cos_a3;
- w = sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3;
+ x = (sinA1 * cosA2 * sinA3) + (cosA1 * sinA2 * cosA3);
+ y = (sinA1 * cosA2 * cosA3) - (cosA1 * sinA2 * sinA3);
+ z = (cosA1 * cosA2 * sinA3) - (sinA1 * sinA2 * cosA3);
+ w = (sinA1 * sinA2 * sinA3) + (cosA1 * cosA2 * cosA3);
}
/// <summary>
- /// Constructs a quaternion that will rotate around the given axis
+ /// Constructs a <see cref="Quaternion"/> that will rotate around the given axis
/// by the specified angle. The axis must be a normalized vector.
/// </summary>
/// <param name="axis">The axis to rotate around. Must be normalized.</param>
@@ -445,10 +450,10 @@ namespace Godot
{
return new Quaternion
(
- left.w * right.x + left.x * right.w + left.y * right.z - left.z * right.y,
- left.w * right.y + left.y * right.w + left.z * right.x - left.x * right.z,
- left.w * right.z + left.z * right.w + left.x * right.y - left.y * right.x,
- left.w * right.w - left.x * right.x - left.y * right.y - left.z * right.z
+ (left.w * right.x) + (left.x * right.w) + (left.y * right.z) - (left.z * right.y),
+ (left.w * right.y) + (left.y * right.w) + (left.z * right.x) - (left.x * right.z),
+ (left.w * right.z) + (left.z * right.w) + (left.x * right.y) - (left.y * right.x),
+ (left.w * right.w) - (left.x * right.x) - (left.y * right.y) - (left.z * right.z)
);
}
@@ -471,10 +476,10 @@ namespace Godot
{
return new Quaternion
(
- left.w * right.x + left.y * right.z - left.z * right.y,
- left.w * right.y + left.z * right.x - left.x * right.z,
- left.w * right.z + left.x * right.y - left.y * right.x,
- -left.x * right.x - left.y * right.y - left.z * right.z
+ (left.w * right.x) + (left.y * right.z) - (left.z * right.y),
+ (left.w * right.y) + (left.z * right.x) - (left.x * right.z),
+ (left.w * right.z) + (left.x * right.y) - (left.y * right.x),
+ -(left.x * right.x) - (left.y * right.y) - (left.z * right.z)
);
}
@@ -482,10 +487,10 @@ namespace Godot
{
return new Quaternion
(
- right.w * left.x + right.y * left.z - right.z * left.y,
- right.w * left.y + right.z * left.x - right.x * left.z,
- right.w * left.z + right.x * left.y - right.y * left.x,
- -right.x * left.x - right.y * left.y - right.z * left.z
+ (right.w * left.x) + (right.y * left.z) - (right.z * left.y),
+ (right.w * left.y) + (right.z * left.x) - (right.x * left.z),
+ (right.w * left.z) + (right.x * left.y) - (right.y * left.x),
+ -(right.x * left.x) - (right.y * left.y) - (right.z * left.z)
);
}
@@ -514,6 +519,11 @@ namespace Godot
return !left.Equals(right);
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this quaternion and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the quaternion and the other object are equal.</returns>
public override bool Equals(object obj)
{
if (obj is Quaternion)
@@ -524,14 +534,19 @@ namespace Godot
return false;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this quaternion and <paramref name="other"/> are equal.
+ /// </summary>
+ /// <param name="other">The other quaternion to compare.</param>
+ /// <returns>Whether or not the quaternions are equal.</returns>
public bool Equals(Quaternion other)
{
return x == other.x && y == other.y && z == other.z && w == other.w;
}
/// <summary>
- /// Returns true if this quaternion and `other` are approximately equal, by running
- /// <see cref="Mathf.IsEqualApprox(real_t, real_t)"/> on each component.
+ /// Returns <see langword="true"/> if this quaternion and <paramref name="other"/> are approximately equal,
+ /// by running <see cref="Mathf.IsEqualApprox(real_t, real_t)"/> on each component.
/// </summary>
/// <param name="other">The other quaternion to compare.</param>
/// <returns>Whether or not the quaternions are approximately equal.</returns>
@@ -540,16 +555,28 @@ namespace Godot
return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y) && Mathf.IsEqualApprox(z, other.z) && Mathf.IsEqualApprox(w, other.w);
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="Quaternion"/>.
+ /// </summary>
+ /// <returns>A hash code for this quaternion.</returns>
public override int GetHashCode()
{
return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="Quaternion"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this quaternion.</returns>
public override string ToString()
{
return $"({x}, {y}, {z}, {w})";
}
+ /// <summary>
+ /// Converts this <see cref="Quaternion"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this quaternion.</returns>
public string ToString(string format)
{
return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)}, {w.ToString(format)})";
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/RID.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/RID.cs
index 94761531b1..1588869ec0 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/RID.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/RID.cs
@@ -3,9 +3,15 @@ using System.Runtime.CompilerServices;
namespace Godot
{
+ /// <summary>
+ /// The RID type is used to access the unique integer ID of a resource.
+ /// They are opaque, which means they do not grant access to the associated
+ /// resource by themselves. They are used by and with the low-level Server
+ /// classes such as <see cref="RenderingServer"/>.
+ /// </summary>
public sealed partial class RID : IDisposable
{
- private bool disposed = false;
+ private bool _disposed = false;
internal IntPtr ptr;
@@ -14,7 +20,7 @@ namespace Godot
if (instance == null)
throw new NullReferenceException($"The instance of type {nameof(RID)} is null.");
- if (instance.disposed)
+ if (instance._disposed)
throw new ObjectDisposedException(instance.GetType().FullName);
return instance.ptr;
@@ -25,6 +31,9 @@ namespace Godot
Dispose(false);
}
+ /// <summary>
+ /// Disposes of this <see cref="RID"/>.
+ /// </summary>
public void Dispose()
{
Dispose(true);
@@ -33,7 +42,7 @@ namespace Godot
private void Dispose(bool disposing)
{
- if (disposed)
+ if (_disposed)
return;
if (ptr != IntPtr.Zero)
@@ -42,7 +51,7 @@ namespace Godot
ptr = IntPtr.Zero;
}
- disposed = true;
+ _disposed = true;
}
internal RID(IntPtr ptr)
@@ -50,6 +59,9 @@ namespace Godot
this.ptr = ptr;
}
+ /// <summary>
+ /// The pointer to the native instance of this <see cref="RID"/>.
+ /// </summary>
public IntPtr NativeInstance
{
get { return ptr; }
@@ -60,25 +72,36 @@ namespace Godot
this.ptr = IntPtr.Zero;
}
+ /// <summary>
+ /// Constructs a new <see cref="RID"/> for the given <see cref="Object"/> <paramref name="from"/>.
+ /// </summary>
public RID(Object from)
{
this.ptr = godot_icall_RID_Ctor(Object.GetPtr(from));
}
+ /// <summary>
+ /// Returns the ID of the referenced resource.
+ /// </summary>
+ /// <returns>The ID of the referenced resource.</returns>
public int GetId()
{
- return godot_icall_RID_get_id(RID.GetPtr(this));
+ return godot_icall_RID_get_id(GetPtr(this));
}
+ /// <summary>
+ /// Converts this <see cref="RID"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this RID.</returns>
public override string ToString() => "[RID]";
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_RID_Ctor(IntPtr from);
+ internal static extern IntPtr godot_icall_RID_Ctor(IntPtr from);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_RID_Dtor(IntPtr ptr);
+ internal static extern void godot_icall_RID_Dtor(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_RID_get_id(IntPtr ptr);
+ internal static extern int godot_icall_RID_get_id(IntPtr ptr);
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
index dec69c7f94..1d001fba2d 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
@@ -20,7 +20,7 @@ namespace Godot
private Vector2 _size;
/// <summary>
- /// Beginning corner. Typically has values lower than End.
+ /// Beginning corner. Typically has values lower than <see cref="End"/>.
/// </summary>
/// <value>Directly uses a private field.</value>
public Vector2 Position
@@ -30,7 +30,7 @@ namespace Godot
}
/// <summary>
- /// Size from Position to End. Typically all components are positive.
+ /// Size from <see cref="Position"/> to <see cref="End"/>. Typically all components are positive.
/// If the size is negative, you can use <see cref="Abs"/> to fix it.
/// </summary>
/// <value>Directly uses a private field.</value>
@@ -41,10 +41,13 @@ namespace Godot
}
/// <summary>
- /// Ending corner. This is calculated as <see cref="Position"/> plus
- /// <see cref="Size"/>. Setting this value will change the size.
+ /// Ending corner. This is calculated as <see cref="Position"/> plus <see cref="Size"/>.
+ /// Setting this value will change the size.
/// </summary>
- /// <value>Getting is equivalent to `value = Position + Size`, setting is equivalent to `Size = value - Position`.</value>
+ /// <value>
+ /// Getting is equivalent to <paramref name="value"/> = <see cref="Position"/> + <see cref="Size"/>,
+ /// setting is equivalent to <see cref="Size"/> = <paramref name="value"/> - <see cref="Position"/>
+ /// </value>
public Vector2 End
{
get { return _position + _size; }
@@ -52,7 +55,7 @@ namespace Godot
}
/// <summary>
- /// The area of this Rect2.
+ /// The area of this <see cref="Rect2"/>.
/// </summary>
/// <value>Equivalent to <see cref="GetArea()"/>.</value>
public real_t Area
@@ -61,10 +64,10 @@ namespace Godot
}
/// <summary>
- /// Returns a Rect2 with equivalent position and size, modified so that
+ /// Returns a <see cref="Rect2"/> with equivalent position and size, modified so that
/// the top-left corner is the origin and width and height are positive.
/// </summary>
- /// <returns>The modified Rect2.</returns>
+ /// <returns>The modified <see cref="Rect2"/>.</returns>
public Rect2 Abs()
{
Vector2 end = End;
@@ -73,14 +76,17 @@ namespace Godot
}
/// <summary>
- /// Returns the intersection of this Rect2 and `b`.
- /// If the rectangles do not intersect, an empty Rect2 is returned.
+ /// Returns the intersection of this <see cref="Rect2"/> and <paramref name="b"/>.
+ /// If the rectangles do not intersect, an empty <see cref="Rect2"/> is returned.
/// </summary>
- /// <param name="b">The other Rect2.</param>
- /// <returns>The intersection of this Rect2 and `b`, or an empty Rect2 if they do not intersect.</returns>
+ /// <param name="b">The other <see cref="Rect2"/>.</param>
+ /// <returns>
+ /// The intersection of this <see cref="Rect2"/> and <paramref name="b"/>,
+ /// or an empty <see cref="Rect2"/> if they do not intersect.
+ /// </returns>
public Rect2 Intersection(Rect2 b)
{
- var newRect = b;
+ Rect2 newRect = b;
if (!Intersects(newRect))
{
@@ -100,10 +106,12 @@ namespace Godot
}
/// <summary>
- /// Returns true if this Rect2 completely encloses another one.
+ /// Returns <see langword="true"/> if this <see cref="Rect2"/> completely encloses another one.
/// </summary>
- /// <param name="b">The other Rect2 that may be enclosed.</param>
- /// <returns>A bool for whether or not this Rect2 encloses `b`.</returns>
+ /// <param name="b">The other <see cref="Rect2"/> that may be enclosed.</param>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not this <see cref="Rect2"/> encloses <paramref name="b"/>.
+ /// </returns>
public bool Encloses(Rect2 b)
{
return b._position.x >= _position.x && b._position.y >= _position.y &&
@@ -112,13 +120,13 @@ namespace Godot
}
/// <summary>
- /// Returns this Rect2 expanded to include a given point.
+ /// Returns this <see cref="Rect2"/> expanded to include a given point.
/// </summary>
/// <param name="to">The point to include.</param>
- /// <returns>The expanded Rect2.</returns>
+ /// <returns>The expanded <see cref="Rect2"/>.</returns>
public Rect2 Expand(Vector2 to)
{
- var expanded = this;
+ Rect2 expanded = this;
Vector2 begin = expanded._position;
Vector2 end = expanded._position + expanded._size;
@@ -148,7 +156,7 @@ namespace Godot
}
/// <summary>
- /// Returns the area of the Rect2.
+ /// Returns the area of the <see cref="Rect2"/>.
/// </summary>
/// <returns>The area.</returns>
public real_t GetArea()
@@ -157,13 +165,16 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2 grown by the specified amount on all sides.
+ /// Returns a copy of the <see cref="Rect2"/> grown by the specified amount
+ /// on all sides.
/// </summary>
+ /// <seealso cref="GrowIndividual(real_t, real_t, real_t, real_t)"/>
+ /// <seealso cref="GrowSide(Side, real_t)"/>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown Rect2.</returns>
+ /// <returns>The grown <see cref="Rect2"/>.</returns>
public Rect2 Grow(real_t by)
{
- var g = this;
+ Rect2 g = this;
g._position.x -= by;
g._position.y -= by;
@@ -174,16 +185,19 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2 grown by the specified amount on each side individually.
+ /// Returns a copy of the <see cref="Rect2"/> grown by the specified amount
+ /// on each side individually.
/// </summary>
+ /// <seealso cref="Grow(real_t)"/>
+ /// <seealso cref="GrowSide(Side, real_t)"/>
/// <param name="left">The amount to grow by on the left side.</param>
/// <param name="top">The amount to grow by on the top side.</param>
/// <param name="right">The amount to grow by on the right side.</param>
/// <param name="bottom">The amount to grow by on the bottom side.</param>
- /// <returns>The grown Rect2.</returns>
+ /// <returns>The grown <see cref="Rect2"/>.</returns>
public Rect2 GrowIndividual(real_t left, real_t top, real_t right, real_t bottom)
{
- var g = this;
+ Rect2 g = this;
g._position.x -= left;
g._position.y -= top;
@@ -194,14 +208,17 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2 grown by the specified amount on the specified Side.
+ /// Returns a copy of the <see cref="Rect2"/> grown by the specified amount
+ /// on the specified <see cref="Side"/>.
/// </summary>
+ /// <seealso cref="Grow(real_t)"/>
+ /// <seealso cref="GrowIndividual(real_t, real_t, real_t, real_t)"/>
/// <param name="side">The side to grow.</param>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown Rect2.</returns>
+ /// <returns>The grown <see cref="Rect2"/>.</returns>
public Rect2 GrowSide(Side side, real_t by)
{
- var g = this;
+ Rect2 g = this;
g = g.GrowIndividual(Side.Left == side ? by : 0,
Side.Top == side ? by : 0,
@@ -212,19 +229,25 @@ namespace Godot
}
/// <summary>
- /// Returns true if the Rect2 is flat or empty, or false otherwise.
+ /// Returns <see langword="true"/> if the <see cref="Rect2"/> is flat or empty,
+ /// or <see langword="false"/> otherwise.
/// </summary>
- /// <returns>A bool for whether or not the Rect2 has area.</returns>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not the <see cref="Rect2"/> has area.
+ /// </returns>
public bool HasNoArea()
{
return _size.x <= 0 || _size.y <= 0;
}
/// <summary>
- /// Returns true if the Rect2 contains a point, or false otherwise.
+ /// Returns <see langword="true"/> if the <see cref="Rect2"/> contains a point,
+ /// or <see langword="false"/> otherwise.
/// </summary>
/// <param name="point">The point to check.</param>
- /// <returns>A bool for whether or not the Rect2 contains `point`.</returns>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not the <see cref="Rect2"/> contains <paramref name="point"/>.
+ /// </returns>
public bool HasPoint(Vector2 point)
{
if (point.x < _position.x)
@@ -241,15 +264,16 @@ namespace Godot
}
/// <summary>
- /// Returns true if the Rect2 overlaps with `b`
+ /// Returns <see langword="true"/> if the <see cref="Rect2"/> overlaps with <paramref name="b"/>
/// (i.e. they have at least one point in common).
///
- /// If `includeBorders` is true, they will also be considered overlapping
- /// if their borders touch, even without intersection.
+ /// If <paramref name="includeBorders"/> is <see langword="true"/>,
+ /// they will also be considered overlapping if their borders touch,
+ /// even without intersection.
/// </summary>
- /// <param name="b">The other Rect2 to check for intersections with.</param>
+ /// <param name="b">The other <see cref="Rect2"/> to check for intersections with.</param>
/// <param name="includeBorders">Whether or not to consider borders.</param>
- /// <returns>A bool for whether or not they are intersecting.</returns>
+ /// <returns>A <see langword="bool"/> for whether or not they are intersecting.</returns>
public bool Intersects(Rect2 b, bool includeBorders = false)
{
if (includeBorders)
@@ -295,10 +319,10 @@ namespace Godot
}
/// <summary>
- /// Returns a larger Rect2 that contains this Rect2 and `b`.
+ /// Returns a larger <see cref="Rect2"/> that contains this <see cref="Rect2"/> and <paramref name="b"/>.
/// </summary>
- /// <param name="b">The other Rect2.</param>
- /// <returns>The merged Rect2.</returns>
+ /// <param name="b">The other <see cref="Rect2"/>.</param>
+ /// <returns>The merged <see cref="Rect2"/>.</returns>
public Rect2 Merge(Rect2 b)
{
Rect2 newRect;
@@ -315,7 +339,7 @@ namespace Godot
}
/// <summary>
- /// Constructs a Rect2 from a position and size.
+ /// Constructs a <see cref="Rect2"/> from a position and size.
/// </summary>
/// <param name="position">The position.</param>
/// <param name="size">The size.</param>
@@ -326,7 +350,7 @@ namespace Godot
}
/// <summary>
- /// Constructs a Rect2 from a position, width, and height.
+ /// Constructs a <see cref="Rect2"/> from a position, width, and height.
/// </summary>
/// <param name="position">The position.</param>
/// <param name="width">The width.</param>
@@ -338,7 +362,7 @@ namespace Godot
}
/// <summary>
- /// Constructs a Rect2 from x, y, and size.
+ /// Constructs a <see cref="Rect2"/> from x, y, and size.
/// </summary>
/// <param name="x">The position's X coordinate.</param>
/// <param name="y">The position's Y coordinate.</param>
@@ -350,7 +374,7 @@ namespace Godot
}
/// <summary>
- /// Constructs a Rect2 from x, y, width, and height.
+ /// Constructs a <see cref="Rect2"/> from x, y, width, and height.
/// </summary>
/// <param name="x">The position's X coordinate.</param>
/// <param name="y">The position's Y coordinate.</param>
@@ -372,6 +396,11 @@ namespace Godot
return !left.Equals(right);
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this rect and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the rect and the other object are equal.</returns>
public override bool Equals(object obj)
{
if (obj is Rect2)
@@ -382,32 +411,49 @@ namespace Godot
return false;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this rect and <paramref name="other"/> are equal.
+ /// </summary>
+ /// <param name="other">The other rect to compare.</param>
+ /// <returns>Whether or not the rects are equal.</returns>
public bool Equals(Rect2 other)
{
return _position.Equals(other._position) && _size.Equals(other._size);
}
/// <summary>
- /// Returns true if this Rect2 and `other` are approximately equal, by running
- /// <see cref="Vector2.IsEqualApprox(Vector2)"/> on each component.
+ /// Returns <see langword="true"/> if this rect and <paramref name="other"/> are approximately equal,
+ /// by running <see cref="Vector2.IsEqualApprox(Vector2)"/> on each component.
/// </summary>
- /// <param name="other">The other Rect2 to compare.</param>
- /// <returns>Whether or not the Rect2s are approximately equal.</returns>
+ /// <param name="other">The other rect to compare.</param>
+ /// <returns>Whether or not the rects are approximately equal.</returns>
public bool IsEqualApprox(Rect2 other)
{
return _position.IsEqualApprox(other._position) && _size.IsEqualApprox(other.Size);
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="Rect2"/>.
+ /// </summary>
+ /// <returns>A hash code for this rect.</returns>
public override int GetHashCode()
{
return _position.GetHashCode() ^ _size.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="Rect2"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this rect.</returns>
public override string ToString()
{
return $"{_position}, {_size}";
}
+ /// <summary>
+ /// Converts this <see cref="Rect2"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this rect.</returns>
public string ToString(string format)
{
return $"{_position.ToString(format)}, {_size.ToString(format)}";
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
index 7fb6614d2c..250b0d0baf 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
@@ -15,7 +15,7 @@ namespace Godot
private Vector2i _size;
/// <summary>
- /// Beginning corner. Typically has values lower than End.
+ /// Beginning corner. Typically has values lower than <see cref="End"/>.
/// </summary>
/// <value>Directly uses a private field.</value>
public Vector2i Position
@@ -25,7 +25,7 @@ namespace Godot
}
/// <summary>
- /// Size from Position to End. Typically all components are positive.
+ /// Size from <see cref="Position"/> to <see cref="End"/>. Typically all components are positive.
/// If the size is negative, you can use <see cref="Abs"/> to fix it.
/// </summary>
/// <value>Directly uses a private field.</value>
@@ -36,10 +36,13 @@ namespace Godot
}
/// <summary>
- /// Ending corner. This is calculated as <see cref="Position"/> plus
- /// <see cref="Size"/>. Setting this value will change the size.
+ /// Ending corner. This is calculated as <see cref="Position"/> plus <see cref="Size"/>.
+ /// Setting this value will change the size.
/// </summary>
- /// <value>Getting is equivalent to `value = Position + Size`, setting is equivalent to `Size = value - Position`.</value>
+ /// <value>
+ /// Getting is equivalent to <paramref name="value"/> = <see cref="Position"/> + <see cref="Size"/>,
+ /// setting is equivalent to <see cref="Size"/> = <paramref name="value"/> - <see cref="Position"/>
+ /// </value>
public Vector2i End
{
get { return _position + _size; }
@@ -47,7 +50,7 @@ namespace Godot
}
/// <summary>
- /// The area of this Rect2i.
+ /// The area of this <see cref="Rect2i"/>.
/// </summary>
/// <value>Equivalent to <see cref="GetArea()"/>.</value>
public int Area
@@ -56,10 +59,10 @@ namespace Godot
}
/// <summary>
- /// Returns a Rect2i with equivalent position and size, modified so that
+ /// Returns a <see cref="Rect2i"/> with equivalent position and size, modified so that
/// the top-left corner is the origin and width and height are positive.
/// </summary>
- /// <returns>The modified Rect2i.</returns>
+ /// <returns>The modified <see cref="Rect2i"/>.</returns>
public Rect2i Abs()
{
Vector2i end = End;
@@ -68,14 +71,17 @@ namespace Godot
}
/// <summary>
- /// Returns the intersection of this Rect2i and `b`.
- /// If the rectangles do not intersect, an empty Rect2i is returned.
+ /// Returns the intersection of this <see cref="Rect2i"/> and <paramref name="b"/>.
+ /// If the rectangles do not intersect, an empty <see cref="Rect2i"/> is returned.
/// </summary>
- /// <param name="b">The other Rect2i.</param>
- /// <returns>The intersection of this Rect2i and `b`, or an empty Rect2i if they do not intersect.</returns>
+ /// <param name="b">The other <see cref="Rect2i"/>.</param>
+ /// <returns>
+ /// The intersection of this <see cref="Rect2i"/> and <paramref name="b"/>,
+ /// or an empty <see cref="Rect2i"/> if they do not intersect.
+ /// </returns>
public Rect2i Intersection(Rect2i b)
{
- var newRect = b;
+ Rect2i newRect = b;
if (!Intersects(newRect))
{
@@ -95,10 +101,12 @@ namespace Godot
}
/// <summary>
- /// Returns true if this Rect2i completely encloses another one.
+ /// Returns <see langword="true"/> if this <see cref="Rect2i"/> completely encloses another one.
/// </summary>
- /// <param name="b">The other Rect2i that may be enclosed.</param>
- /// <returns>A bool for whether or not this Rect2i encloses `b`.</returns>
+ /// <param name="b">The other <see cref="Rect2i"/> that may be enclosed.</param>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not this <see cref="Rect2i"/> encloses <paramref name="b"/>.
+ /// </returns>
public bool Encloses(Rect2i b)
{
return b._position.x >= _position.x && b._position.y >= _position.y &&
@@ -107,13 +115,13 @@ namespace Godot
}
/// <summary>
- /// Returns this Rect2i expanded to include a given point.
+ /// Returns this <see cref="Rect2i"/> expanded to include a given point.
/// </summary>
/// <param name="to">The point to include.</param>
- /// <returns>The expanded Rect2i.</returns>
+ /// <returns>The expanded <see cref="Rect2i"/>.</returns>
public Rect2i Expand(Vector2i to)
{
- var expanded = this;
+ Rect2i expanded = this;
Vector2i begin = expanded._position;
Vector2i end = expanded._position + expanded._size;
@@ -143,7 +151,7 @@ namespace Godot
}
/// <summary>
- /// Returns the area of the Rect2.
+ /// Returns the area of the <see cref="Rect2"/>.
/// </summary>
/// <returns>The area.</returns>
public int GetArea()
@@ -152,13 +160,16 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2i grown by the specified amount on all sides.
+ /// Returns a copy of the <see cref="Rect2i"/> grown by the specified amount
+ /// on all sides.
/// </summary>
+ /// <seealso cref="GrowIndividual(int, int, int, int)"/>
+ /// <seealso cref="GrowSide(Side, int)"/>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown Rect2i.</returns>
+ /// <returns>The grown <see cref="Rect2i"/>.</returns>
public Rect2i Grow(int by)
{
- var g = this;
+ Rect2i g = this;
g._position.x -= by;
g._position.y -= by;
@@ -169,16 +180,19 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2i grown by the specified amount on each side individually.
+ /// Returns a copy of the <see cref="Rect2i"/> grown by the specified amount
+ /// on each side individually.
/// </summary>
+ /// <seealso cref="Grow(int)"/>
+ /// <seealso cref="GrowSide(Side, int)"/>
/// <param name="left">The amount to grow by on the left side.</param>
/// <param name="top">The amount to grow by on the top side.</param>
/// <param name="right">The amount to grow by on the right side.</param>
/// <param name="bottom">The amount to grow by on the bottom side.</param>
- /// <returns>The grown Rect2i.</returns>
+ /// <returns>The grown <see cref="Rect2i"/>.</returns>
public Rect2i GrowIndividual(int left, int top, int right, int bottom)
{
- var g = this;
+ Rect2i g = this;
g._position.x -= left;
g._position.y -= top;
@@ -189,14 +203,17 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2i grown by the specified amount on the specified Side.
+ /// Returns a copy of the <see cref="Rect2i"/> grown by the specified amount
+ /// on the specified <see cref="Side"/>.
/// </summary>
+ /// <seealso cref="Grow(int)"/>
+ /// <seealso cref="GrowIndividual(int, int, int, int)"/>
/// <param name="side">The side to grow.</param>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown Rect2i.</returns>
+ /// <returns>The grown <see cref="Rect2i"/>.</returns>
public Rect2i GrowSide(Side side, int by)
{
- var g = this;
+ Rect2i g = this;
g = g.GrowIndividual(Side.Left == side ? by : 0,
Side.Top == side ? by : 0,
@@ -207,19 +224,25 @@ namespace Godot
}
/// <summary>
- /// Returns true if the Rect2i is flat or empty, or false otherwise.
+ /// Returns <see langword="true"/> if the <see cref="Rect2i"/> is flat or empty,
+ /// or <see langword="false"/> otherwise.
/// </summary>
- /// <returns>A bool for whether or not the Rect2i has area.</returns>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not the <see cref="Rect2i"/> has area.
+ /// </returns>
public bool HasNoArea()
{
return _size.x <= 0 || _size.y <= 0;
}
/// <summary>
- /// Returns true if the Rect2i contains a point, or false otherwise.
+ /// Returns <see langword="true"/> if the <see cref="Rect2i"/> contains a point,
+ /// or <see langword="false"/> otherwise.
/// </summary>
/// <param name="point">The point to check.</param>
- /// <returns>A bool for whether or not the Rect2i contains `point`.</returns>
+ /// <returns>
+ /// A <see langword="bool"/> for whether or not the <see cref="Rect2i"/> contains <paramref name="point"/>.
+ /// </returns>
public bool HasPoint(Vector2i point)
{
if (point.x < _position.x)
@@ -236,15 +259,16 @@ namespace Godot
}
/// <summary>
- /// Returns true if the Rect2i overlaps with `b`
+ /// Returns <see langword="true"/> if the <see cref="Rect2i"/> overlaps with <paramref name="b"/>
/// (i.e. they have at least one point in common).
///
- /// If `includeBorders` is true, they will also be considered overlapping
- /// if their borders touch, even without intersection.
+ /// If <paramref name="includeBorders"/> is <see langword="true"/>,
+ /// they will also be considered overlapping if their borders touch,
+ /// even without intersection.
/// </summary>
- /// <param name="b">The other Rect2i to check for intersections with.</param>
+ /// <param name="b">The other <see cref="Rect2i"/> to check for intersections with.</param>
/// <param name="includeBorders">Whether or not to consider borders.</param>
- /// <returns>A bool for whether or not they are intersecting.</returns>
+ /// <returns>A <see langword="bool"/> for whether or not they are intersecting.</returns>
public bool Intersects(Rect2i b, bool includeBorders = false)
{
if (includeBorders)
@@ -274,10 +298,10 @@ namespace Godot
}
/// <summary>
- /// Returns a larger Rect2i that contains this Rect2i and `b`.
+ /// Returns a larger <see cref="Rect2i"/> that contains this <see cref="Rect2i"/> and <paramref name="b"/>.
/// </summary>
- /// <param name="b">The other Rect2i.</param>
- /// <returns>The merged Rect2i.</returns>
+ /// <param name="b">The other <see cref="Rect2i"/>.</param>
+ /// <returns>The merged <see cref="Rect2i"/>.</returns>
public Rect2i Merge(Rect2i b)
{
Rect2i newRect;
@@ -294,7 +318,7 @@ namespace Godot
}
/// <summary>
- /// Constructs a Rect2i from a position and size.
+ /// Constructs a <see cref="Rect2i"/> from a position and size.
/// </summary>
/// <param name="position">The position.</param>
/// <param name="size">The size.</param>
@@ -305,7 +329,7 @@ namespace Godot
}
/// <summary>
- /// Constructs a Rect2i from a position, width, and height.
+ /// Constructs a <see cref="Rect2i"/> from a position, width, and height.
/// </summary>
/// <param name="position">The position.</param>
/// <param name="width">The width.</param>
@@ -317,7 +341,7 @@ namespace Godot
}
/// <summary>
- /// Constructs a Rect2i from x, y, and size.
+ /// Constructs a <see cref="Rect2i"/> from x, y, and size.
/// </summary>
/// <param name="x">The position's X coordinate.</param>
/// <param name="y">The position's Y coordinate.</param>
@@ -329,7 +353,7 @@ namespace Godot
}
/// <summary>
- /// Constructs a Rect2i from x, y, width, and height.
+ /// Constructs a <see cref="Rect2i"/> from x, y, width, and height.
/// </summary>
/// <param name="x">The position's X coordinate.</param>
/// <param name="y">The position's Y coordinate.</param>
@@ -351,16 +375,29 @@ namespace Godot
return !left.Equals(right);
}
+ /// <summary>
+ /// Converts this <see cref="Rect2i"/> to a <see cref="Rect2"/>.
+ /// </summary>
+ /// <param name="value">The rect to convert.</param>
public static implicit operator Rect2(Rect2i value)
{
return new Rect2(value._position, value._size);
}
+ /// <summary>
+ /// Converts a <see cref="Rect2"/> to a <see cref="Rect2i"/>.
+ /// </summary>
+ /// <param name="value">The rect to convert.</param>
public static explicit operator Rect2i(Rect2 value)
{
return new Rect2i((Vector2i)value.Position, (Vector2i)value.Size);
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this rect and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the rect and the other object are equal.</returns>
public override bool Equals(object obj)
{
if (obj is Rect2i)
@@ -371,21 +408,38 @@ namespace Godot
return false;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this rect and <paramref name="other"/> are equal.
+ /// </summary>
+ /// <param name="other">The other rect to compare.</param>
+ /// <returns>Whether or not the rects are equal.</returns>
public bool Equals(Rect2i other)
{
return _position.Equals(other._position) && _size.Equals(other._size);
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="Rect2i"/>.
+ /// </summary>
+ /// <returns>A hash code for this rect.</returns>
public override int GetHashCode()
{
return _position.GetHashCode() ^ _size.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="Rect2i"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this rect.</returns>
public override string ToString()
{
return $"{_position}, {_size}";
}
+ /// <summary>
+ /// Converts this <see cref="Rect2i"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this rect.</returns>
public string ToString(string format)
{
return $"{_position.ToString(format)}, {_size.ToString(format)}";
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
index 4dc630238b..2ba0493002 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
@@ -5,9 +5,9 @@ namespace Godot
{
public class SignalAwaiter : IAwaiter<object[]>, IAwaitable<object[]>
{
- private bool completed;
- private object[] result;
- private Action action;
+ private bool _completed;
+ private object[] _result;
+ private Action _action;
public SignalAwaiter(Object source, StringName signal, Object target)
{
@@ -15,24 +15,24 @@ namespace Godot
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static Error godot_icall_SignalAwaiter_connect(IntPtr source, IntPtr signal, IntPtr target, SignalAwaiter awaiter);
+ internal static extern Error godot_icall_SignalAwaiter_connect(IntPtr source, IntPtr signal, IntPtr target, SignalAwaiter awaiter);
public bool IsCompleted
{
get
{
- return completed;
+ return _completed;
}
}
public void OnCompleted(Action action)
{
- this.action = action;
+ this._action = action;
}
public object[] GetResult()
{
- return result;
+ return _result;
}
public IAwaiter<object[]> GetAwaiter()
@@ -42,13 +42,9 @@ namespace Godot
internal void SignalCallback(object[] args)
{
- completed = true;
- result = args;
-
- if (action != null)
- {
- action();
- }
+ _completed = true;
+ _result = args;
+ _action?.Invoke();
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs
index dc92de7a61..5680c9d55a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs
@@ -1,13 +1,28 @@
namespace Godot
{
+ /// <summary>
+ /// Represents a signal defined in an object.
+ /// </summary>
public struct SignalInfo
{
private readonly Object _owner;
private readonly StringName _signalName;
+ /// <summary>
+ /// Object that contains the signal.
+ /// </summary>
public Object Owner => _owner;
+ /// <summary>
+ /// Name of the signal.
+ /// </summary>
public StringName Name => _signalName;
+ /// <summary>
+ /// Creates a new <see cref="Signal"/> with the name <paramref name="name"/>
+ /// in the specified <paramref name="owner"/>.
+ /// </summary>
+ /// <param name="owner">Object that contains the signal.</param>
+ /// <param name="name">Name of the signal.</param>
public SignalInfo(Object owner, StringName name)
{
_owner = owner;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
index bc598248bc..6b3eb09581 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
@@ -8,6 +8,9 @@ using System.Text.RegularExpressions;
namespace Godot
{
+ /// <summary>
+ /// Extension methods to manipulate strings.
+ /// </summary>
public static class StringExtensions
{
private static int GetSliceCount(this string instance, string splitter)
@@ -64,6 +67,11 @@ namespace Godot
/// <summary>
/// If the string is a path to a file, return the path to the file without the extension.
/// </summary>
+ /// <seealso cref="GetExtension(string)"/>
+ /// <seealso cref="GetBaseDir(string)"/>
+ /// <seealso cref="GetFile(string)"/>
+ /// <param name="instance">The path to a file.</param>
+ /// <returns>The path to the file without the extension.</returns>
public static string GetBaseName(this string instance)
{
int index = instance.LastIndexOf('.');
@@ -75,19 +83,25 @@ namespace Godot
}
/// <summary>
- /// Return <see langword="true"/> if the strings begins with the given string.
+ /// Returns <see langword="true"/> if the strings begins
+ /// with the given string <paramref name="text"/>.
/// </summary>
+ /// <param name="instance">The string to check.</param>
+ /// <param name="text">The beginning string.</param>
+ /// <returns>If the string begins with the given string.</returns>
public static bool BeginsWith(this string instance, string text)
{
return instance.StartsWith(text);
}
/// <summary>
- /// Return the bigrams (pairs of consecutive letters) of this string.
+ /// Returns the bigrams (pairs of consecutive letters) of this string.
/// </summary>
+ /// <param name="instance">The string that will be used.</param>
+ /// <returns>The bigrams of this string.</returns>
public static string[] Bigrams(this string instance)
{
- var b = new string[instance.Length - 1];
+ string[] b = new string[instance.Length - 1];
for (int i = 0; i < b.Length; i++)
{
@@ -99,8 +113,8 @@ namespace Godot
/// <summary>
/// Converts a string containing a binary number into an integer.
- /// Binary strings can either be prefixed with `0b` or not,
- /// and they can also start with a `-` before the optional prefix.
+ /// Binary strings can either be prefixed with <c>0b</c> or not,
+ /// and they can also start with a <c>-</c> before the optional prefix.
/// </summary>
/// <param name="instance">The string to convert.</param>
/// <returns>The converted string.</returns>
@@ -128,8 +142,14 @@ namespace Godot
}
/// <summary>
- /// Return the amount of substrings in string.
+ /// Returns the amount of substrings <paramref name="what"/> in the string.
/// </summary>
+ /// <param name="instance">The string where the substring will be searched.</param>
+ /// <param name="what">The substring that will be counted.</param>
+ /// <param name="caseSensitive">If the search is case sensitive.</param>
+ /// <param name="from">Index to start searching from.</param>
+ /// <param name="to">Index to stop searching at.</param>
+ /// <returns>Amount of substrings in the string.</returns>
public static int Count(this string instance, string what, bool caseSensitive = true, int from = 0, int to = 0)
{
if (what.Length == 0)
@@ -188,8 +208,10 @@ namespace Godot
}
/// <summary>
- /// Return a copy of the string with special characters escaped using the C language standard.
+ /// Returns a copy of the string with special characters escaped using the C language standard.
/// </summary>
+ /// <param name="instance">The string to escape.</param>
+ /// <returns>The escaped string.</returns>
public static string CEscape(this string instance)
{
var sb = new StringBuilder(string.Copy(instance));
@@ -210,9 +232,11 @@ namespace Godot
}
/// <summary>
- /// Return a copy of the string with escaped characters replaced by their meanings
+ /// Returns a copy of the string with escaped characters replaced by their meanings
/// according to the C language standard.
/// </summary>
+ /// <param name="instance">The string to unescape.</param>
+ /// <returns>The unescaped string.</returns>
public static string CUnescape(this string instance)
{
var sb = new StringBuilder(string.Copy(instance));
@@ -233,15 +257,17 @@ namespace Godot
}
/// <summary>
- /// Change the case of some letters. Replace underscores with spaces, convert all letters
+ /// Changes the case of some letters. Replace underscores with spaces, convert all letters
/// to lowercase then capitalize first and every letter following the space character.
/// For <c>capitalize camelCase mixed_with_underscores</c> it will return
/// <c>Capitalize Camelcase Mixed With Underscores</c>.
/// </summary>
+ /// <param name="instance">The string to capitalize.</param>
+ /// <returns>The capitalized string.</returns>
public static string Capitalize(this string instance)
{
string aux = instance.Replace("_", " ").ToLower();
- var cap = string.Empty;
+ string cap = string.Empty;
for (int i = 0; i < aux.GetSliceCount(" "); i++)
{
@@ -259,16 +285,27 @@ namespace Godot
}
/// <summary>
- /// Perform a case-sensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater.
+ /// Performs a case-sensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater.
/// </summary>
+ /// <seealso cref="NocasecmpTo(string, string)"/>
+ /// <seealso cref="CompareTo(string, string, bool)"/>
+ /// <param name="instance">The string to compare.</param>
+ /// <param name="to">The other string to compare.</param>
+ /// <returns>-1 if less, 0 if equal and +1 if greater.</returns>
public static int CasecmpTo(this string instance, string to)
{
return instance.CompareTo(to, caseSensitive: true);
}
/// <summary>
- /// Perform a comparison to another string, return -1 if less, 0 if equal and +1 if greater.
+ /// Performs a comparison to another string, return -1 if less, 0 if equal and +1 if greater.
/// </summary>
+ /// <param name="instance">The string to compare.</param>
+ /// <param name="to">The other string to compare.</param>
+ /// <param name="caseSensitive">
+ /// If <see langword="true"/>, the comparison will be case sensitive.
+ /// </param>
+ /// <returns>-1 if less, 0 if equal and +1 if greater.</returns>
public static int CompareTo(this string instance, string to, bool caseSensitive = true)
{
if (string.IsNullOrEmpty(instance))
@@ -321,8 +358,12 @@ namespace Godot
}
/// <summary>
- /// Return <see langword="true"/> if the strings ends with the given string.
+ /// Returns <see langword="true"/> if the strings ends
+ /// with the given string <paramref name="text"/>.
/// </summary>
+ /// <param name="instance">The string to check.</param>
+ /// <param name="text">The ending string.</param>
+ /// <returns>If the string ends with the given string.</returns>
public static bool EndsWith(this string instance, string text)
{
return instance.EndsWith(text);
@@ -331,14 +372,36 @@ namespace Godot
/// <summary>
/// Erase <paramref name="chars"/> characters from the string starting from <paramref name="pos"/>.
/// </summary>
+ /// <param name="instance">The string to modify.</param>
+ /// <param name="pos">Starting position from which to erase.</param>
+ /// <param name="chars">Amount of characters to erase.</param>
public static void Erase(this StringBuilder instance, int pos, int chars)
{
instance.Remove(pos, chars);
}
/// <summary>
- /// If the string is a path to a file, return the extension.
- /// </summary>
+ /// Returns the extension without the leading period character (<c>.</c>)
+ /// if the string is a valid file name or path. If the string does not contain
+ /// an extension, returns an empty string instead.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.Print("/path/to/file.txt".GetExtension()) // "txt"
+ /// GD.Print("file.txt".GetExtension()) // "txt"
+ /// GD.Print("file.sample.txt".GetExtension()) // "txt"
+ /// GD.Print(".txt".GetExtension()) // "txt"
+ /// GD.Print("file.txt.".GetExtension()) // "" (empty string)
+ /// GD.Print("file.txt..".GetExtension()) // "" (empty string)
+ /// GD.Print("txt".GetExtension()) // "" (empty string)
+ /// GD.Print("".GetExtension()) // "" (empty string)
+ /// </code>
+ /// </example>
+ /// <seealso cref="GetBaseName(string)"/>
+ /// <seealso cref="GetBaseDir(string)"/>
+ /// <seealso cref="GetFile(string)"/>
+ /// <param name="instance">The path to a file.</param>
+ /// <returns>The extension of the file or an empty string.</returns>
public static string GetExtension(this string instance)
{
int pos = instance.FindLast(".");
@@ -352,6 +415,10 @@ namespace Godot
/// <summary>
/// Find the first occurrence of a substring. Optionally, the search starting position can be passed.
/// </summary>
+ /// <param name="instance">The string that will be searched.</param>
+ /// <param name="what">The substring to find.</param>
+ /// <param name="from">The search starting position.</param>
+ /// <param name="caseSensitive">If <see langword="true"/>, the search is case sensitive.</param>
/// <returns>The starting position of the substring, or -1 if not found.</returns>
public static int Find(this string instance, string what, int from = 0, bool caseSensitive = true)
{
@@ -361,6 +428,14 @@ namespace Godot
/// <summary>
/// Find the first occurrence of a char. Optionally, the search starting position can be passed.
/// </summary>
+ /// <seealso cref="Find(string, string, int, bool)"/>
+ /// <seealso cref="FindLast(string, string, bool)"/>
+ /// <seealso cref="FindLast(string, string, int, bool)"/>
+ /// <seealso cref="FindN(string, string, int)"/>
+ /// <param name="instance">The string that will be searched.</param>
+ /// <param name="what">The substring to find.</param>
+ /// <param name="from">The search starting position.</param>
+ /// <param name="caseSensitive">If <see langword="true"/>, the search is case sensitive.</param>
/// <returns>The first instance of the char, or -1 if not found.</returns>
public static int Find(this string instance, char what, int from = 0, bool caseSensitive = true)
{
@@ -370,6 +445,13 @@ namespace Godot
}
/// <summary>Find the last occurrence of a substring.</summary>
+ /// <seealso cref="Find(string, string, int, bool)"/>
+ /// <seealso cref="Find(string, char, int, bool)"/>
+ /// <seealso cref="FindLast(string, string, int, bool)"/>
+ /// <seealso cref="FindN(string, string, int)"/>
+ /// <param name="instance">The string that will be searched.</param>
+ /// <param name="what">The substring to find.</param>
+ /// <param name="caseSensitive">If <see langword="true"/>, the search is case sensitive.</param>
/// <returns>The starting position of the substring, or -1 if not found.</returns>
public static int FindLast(this string instance, string what, bool caseSensitive = true)
{
@@ -377,6 +459,14 @@ namespace Godot
}
/// <summary>Find the last occurrence of a substring specifying the search starting position.</summary>
+ /// <seealso cref="Find(string, string, int, bool)"/>
+ /// <seealso cref="Find(string, char, int, bool)"/>
+ /// <seealso cref="FindLast(string, string, bool)"/>
+ /// <seealso cref="FindN(string, string, int)"/>
+ /// <param name="instance">The string that will be searched.</param>
+ /// <param name="what">The substring to find.</param>
+ /// <param name="from">The search starting position.</param>
+ /// <param name="caseSensitive">If <see langword="true"/>, the search is case sensitive.</param>
/// <returns>The starting position of the substring, or -1 if not found.</returns>
public static int FindLast(this string instance, string what, int from, bool caseSensitive = true)
{
@@ -387,6 +477,13 @@ namespace Godot
/// Find the first occurrence of a substring but search as case-insensitive.
/// Optionally, the search starting position can be passed.
/// </summary>
+ /// <seealso cref="Find(string, string, int, bool)"/>
+ /// <seealso cref="Find(string, char, int, bool)"/>
+ /// <seealso cref="FindLast(string, string, bool)"/>
+ /// <seealso cref="FindLast(string, string, int, bool)"/>
+ /// <param name="instance">The string that will be searched.</param>
+ /// <param name="what">The substring to find.</param>
+ /// <param name="from">The search starting position.</param>
/// <returns>The starting position of the substring, or -1 if not found.</returns>
public static int FindN(this string instance, string what, int from = 0)
{
@@ -396,25 +493,30 @@ namespace Godot
/// <summary>
/// If the string is a path to a file, return the base directory.
/// </summary>
+ /// <seealso cref="GetBaseName(string)"/>
+ /// <seealso cref="GetExtension(string)"/>
+ /// <seealso cref="GetFile(string)"/>
+ /// <param name="instance">The path to a file.</param>
+ /// <returns>The base directory.</returns>
public static string GetBaseDir(this string instance)
{
int basepos = instance.Find("://");
string rs;
- var @base = string.Empty;
+ string directory = string.Empty;
if (basepos != -1)
{
- var end = basepos + 3;
+ int end = basepos + 3;
rs = instance.Substring(end);
- @base = instance.Substring(0, end);
+ directory = instance.Substring(0, end);
}
else
{
if (instance.BeginsWith("/"))
{
rs = instance.Substring(1);
- @base = "/";
+ directory = "/";
}
else
{
@@ -425,14 +527,19 @@ namespace Godot
int sep = Mathf.Max(rs.FindLast("/"), rs.FindLast("\\"));
if (sep == -1)
- return @base;
+ return directory;
- return @base + rs.Substr(0, sep);
+ return directory + rs.Substr(0, sep);
}
/// <summary>
/// If the string is a path to a file, return the file and ignore the base directory.
/// </summary>
+ /// <seealso cref="GetBaseName(string)"/>
+ /// <seealso cref="GetExtension(string)"/>
+ /// <seealso cref="GetBaseDir(string)"/>
+ /// <param name="instance">The path to a file.</param>
+ /// <returns>The file name.</returns>
public static string GetFile(this string instance)
{
int sep = Mathf.Max(instance.FindLast("/"), instance.FindLast("\\"));
@@ -475,6 +582,8 @@ namespace Godot
/// <summary>
/// Hash the string and return a 32 bits unsigned integer.
/// </summary>
+ /// <param name="instance">The string to hash.</param>
+ /// <returns>The calculated hash of the string.</returns>
public static uint Hash(this string instance)
{
uint hash = 5381;
@@ -494,7 +603,7 @@ namespace Godot
/// <returns>The hexadecimal representation of this byte.</returns>
internal static string HexEncode(this byte b)
{
- var ret = string.Empty;
+ string ret = string.Empty;
for (int i = 0; i < 2; i++)
{
@@ -524,7 +633,7 @@ namespace Godot
/// <returns>The hexadecimal representation of this byte array.</returns>
public static string HexEncode(this byte[] bytes)
{
- var ret = string.Empty;
+ string ret = string.Empty;
foreach (byte b in bytes)
{
@@ -536,8 +645,8 @@ namespace Godot
/// <summary>
/// Converts a string containing a hexadecimal number into an integer.
- /// Hexadecimal strings can either be prefixed with `0x` or not,
- /// and they can also start with a `-` before the optional prefix.
+ /// Hexadecimal strings can either be prefixed with <c>0x</c> or not,
+ /// and they can also start with a <c>-</c> before the optional prefix.
/// </summary>
/// <param name="instance">The string to convert.</param>
/// <returns>The converted string.</returns>
@@ -565,16 +674,28 @@ namespace Godot
}
/// <summary>
- /// Insert a substring at a given position.
+ /// Inserts a substring at a given position.
/// </summary>
+ /// <param name="instance">The string to modify.</param>
+ /// <param name="pos">Position at which to insert the substring.</param>
+ /// <param name="what">Substring to insert.</param>
+ /// <returns>
+ /// The string with <paramref name="what"/> inserted at the given
+ /// position <paramref name="pos"/>.
+ /// </returns>
public static string Insert(this string instance, int pos, string what)
{
return instance.Insert(pos, what);
}
/// <summary>
- /// If the string is a path to a file or directory, return <see langword="true"/> if the path is absolute.
+ /// Returns <see langword="true"/> if the string is a path to a file or
+ /// directory and its startign point is explicitly defined. This includes
+ /// <c>res://</c>, <c>user://</c>, <c>C:\</c>, <c>/</c>, etc.
/// </summary>
+ /// <seealso cref="IsRelativePath(string)"/>
+ /// <param name="instance">The string to check.</param>
+ /// <returns>If the string is an absolute path.</returns>
public static bool IsAbsolutePath(this string instance)
{
if (string.IsNullOrEmpty(instance))
@@ -586,8 +707,14 @@ namespace Godot
}
/// <summary>
- /// If the string is a path to a file or directory, return <see langword="true"/> if the path is relative.
+ /// Returns <see langword="true"/> if the string is a path to a file or
+ /// directory and its starting point is implicitly defined within the
+ /// context it is being used. The starting point may refer to the current
+ /// directory (<c>./</c>), or the current <see cref="Node"/>.
/// </summary>
+ /// <seealso cref="IsAbsolutePath(string)"/>
+ /// <param name="instance">The string to check.</param>
+ /// <returns>If the string is a relative path.</returns>
public static bool IsRelativePath(this string instance)
{
return !IsAbsolutePath(instance);
@@ -596,6 +723,11 @@ namespace Godot
/// <summary>
/// Check whether this string is a subsequence of the given string.
/// </summary>
+ /// <seealso cref="IsSubsequenceOfI(string, string)"/>
+ /// <param name="instance">The subsequence to search.</param>
+ /// <param name="text">The string that contains the subsequence.</param>
+ /// <param name="caseSensitive">If <see langword="true"/>, the check is case sensitive.</param>
+ /// <returns>If the string is a subsequence of the given string.</returns>
public static bool IsSubsequenceOf(this string instance, string text, bool caseSensitive = true)
{
int len = instance.Length;
@@ -639,6 +771,10 @@ namespace Godot
/// <summary>
/// Check whether this string is a subsequence of the given string, ignoring case differences.
/// </summary>
+ /// <seealso cref="IsSubsequenceOf(string, string, bool)"/>
+ /// <param name="instance">The subsequence to search.</param>
+ /// <param name="text">The string that contains the subsequence.</param>
+ /// <returns>If the string is a subsequence of the given string.</returns>
public static bool IsSubsequenceOfI(this string instance, string text)
{
return instance.IsSubsequenceOf(text, caseSensitive: false);
@@ -647,6 +783,8 @@ namespace Godot
/// <summary>
/// Check whether the string contains a valid <see langword="float"/>.
/// </summary>
+ /// <param name="instance">The string to check.</param>
+ /// <returns>If the string contains a valid floating point number.</returns>
public static bool IsValidFloat(this string instance)
{
float f;
@@ -656,6 +794,8 @@ namespace Godot
/// <summary>
/// Check whether the string contains a valid color in HTML notation.
/// </summary>
+ /// <param name="instance">The string to check.</param>
+ /// <returns>If the string contains a valid HTML color.</returns>
public static bool IsValidHtmlColor(this string instance)
{
return Color.HtmlIsValid(instance);
@@ -666,6 +806,8 @@ namespace Godot
/// programming languages, a valid identifier may contain only letters,
/// digits and underscores (_) and the first character may not be a digit.
/// </summary>
+ /// <param name="instance">The string to check.</param>
+ /// <returns>If the string contains a valid identifier.</returns>
public static bool IsValidIdentifier(this string instance)
{
int len = instance.Length;
@@ -673,18 +815,15 @@ namespace Godot
if (len == 0)
return false;
+ if (instance[0] >= '0' && instance[0] <= '9')
+ return false; // Identifiers cannot start with numbers.
+
for (int i = 0; i < len; i++)
{
- if (i == 0)
- {
- if (instance[0] >= '0' && instance[0] <= '9')
- return false; // Don't start with number plz
- }
-
- bool validChar = instance[i] >= '0' &&
- instance[i] <= '9' || instance[i] >= 'a' &&
- instance[i] <= 'z' || instance[i] >= 'A' &&
- instance[i] <= 'Z' || instance[i] == '_';
+ bool validChar = instance[i] == '_' ||
+ (instance[i] >= 'a' && instance[i] <= 'z') ||
+ (instance[i] >= 'A' && instance[i] <= 'Z') ||
+ (instance[i] >= '0' && instance[i] <= '9');
if (!validChar)
return false;
@@ -696,6 +835,8 @@ namespace Godot
/// <summary>
/// Check whether the string contains a valid integer.
/// </summary>
+ /// <param name="instance">The string to check.</param>
+ /// <returns>If the string contains a valid integer.</returns>
public static bool IsValidInteger(this string instance)
{
int f;
@@ -705,6 +846,8 @@ namespace Godot
/// <summary>
/// Check whether the string contains a valid IP address.
/// </summary>
+ /// <param name="instance">The string to check.</param>
+ /// <returns>If the string contains a valid IP address.</returns>
public static bool IsValidIPAddress(this string instance)
{
// TODO: Support IPv6 addresses
@@ -728,8 +871,10 @@ namespace Godot
}
/// <summary>
- /// Return a copy of the string with special characters escaped using the JSON standard.
+ /// Returns a copy of the string with special characters escaped using the JSON standard.
/// </summary>
+ /// <param name="instance">The string to escape.</param>
+ /// <returns>The escaped string.</returns>
public static string JSONEscape(this string instance)
{
var sb = new StringBuilder(string.Copy(instance));
@@ -747,8 +892,12 @@ namespace Godot
}
/// <summary>
- /// Return an amount of characters from the left of the string.
+ /// Returns an amount of characters from the left of the string.
/// </summary>
+ /// <seealso cref="Right(string, int)"/>
+ /// <param name="instance">The original string.</param>
+ /// <param name="pos">The position in the string where the left side ends.</param>
+ /// <returns>The left side of the string from the given position.</returns>
public static string Left(this string instance, int pos)
{
if (pos <= 0)
@@ -761,8 +910,10 @@ namespace Godot
}
/// <summary>
- /// Return the length of the string in characters.
+ /// Returns the length of the string in characters.
/// </summary>
+ /// <param name="instance">The string to check.</param>
+ /// <returns>The length of the string.</returns>
public static int Length(this string instance)
{
return instance.Length;
@@ -771,6 +922,7 @@ namespace Godot
/// <summary>
/// Returns a copy of the string with characters removed from the left.
/// </summary>
+ /// <seealso cref="RStrip(string, string)"/>
/// <param name="instance">The string to remove characters from.</param>
/// <param name="chars">The characters to be removed.</param>
/// <returns>A copy of the string with characters removed from the left.</returns>
@@ -799,6 +951,12 @@ namespace Godot
/// Do a simple expression match, where '*' matches zero or more
/// arbitrary characters and '?' matches any single character except '.'.
/// </summary>
+ /// <param name="instance">The string to check.</param>
+ /// <param name="expr">Expression to check.</param>
+ /// <param name="caseSensitive">
+ /// If <see langword="true"/>, the check will be case sensitive.
+ /// </param>
+ /// <returns>If the expression has any matches.</returns>
private static bool ExprMatch(this string instance, string expr, bool caseSensitive)
{
// case '\0':
@@ -824,6 +982,13 @@ namespace Godot
/// Do a simple case sensitive expression match, using ? and * wildcards
/// (see <see cref="ExprMatch(string, string, bool)"/>).
/// </summary>
+ /// <seealso cref="MatchN(string, string)"/>
+ /// <param name="instance">The string to check.</param>
+ /// <param name="expr">Expression to check.</param>
+ /// <param name="caseSensitive">
+ /// If <see langword="true"/>, the check will be case sensitive.
+ /// </param>
+ /// <returns>If the expression has any matches.</returns>
public static bool Match(this string instance, string expr, bool caseSensitive = true)
{
if (instance.Length == 0 || expr.Length == 0)
@@ -836,6 +1001,10 @@ namespace Godot
/// Do a simple case insensitive expression match, using ? and * wildcards
/// (see <see cref="ExprMatch(string, string, bool)"/>).
/// </summary>
+ /// <seealso cref="Match(string, string, bool)"/>
+ /// <param name="instance">The string to check.</param>
+ /// <param name="expr">Expression to check.</param>
+ /// <returns>If the expression has any matches.</returns>
public static bool MatchN(this string instance, string expr)
{
if (instance.Length == 0 || expr.Length == 0)
@@ -845,46 +1014,65 @@ namespace Godot
}
/// <summary>
- /// Return the MD5 hash of the string as an array of bytes.
+ /// Returns the MD5 hash of the string as an array of bytes.
/// </summary>
+ /// <seealso cref="MD5Text(string)"/>
+ /// <param name="instance">The string to hash.</param>
+ /// <returns>The MD5 hash of the string.</returns>
public static byte[] MD5Buffer(this string instance)
{
return godot_icall_String_md5_buffer(instance);
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static byte[] godot_icall_String_md5_buffer(string str);
+ internal static extern byte[] godot_icall_String_md5_buffer(string str);
/// <summary>
- /// Return the MD5 hash of the string as a string.
+ /// Returns the MD5 hash of the string as a string.
/// </summary>
+ /// <seealso cref="MD5Buffer(string)"/>
+ /// <param name="instance">The string to hash.</param>
+ /// <returns>The MD5 hash of the string.</returns>
public static string MD5Text(this string instance)
{
return godot_icall_String_md5_text(instance);
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string godot_icall_String_md5_text(string str);
+ internal static extern string godot_icall_String_md5_text(string str);
/// <summary>
/// Perform a case-insensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater.
/// </summary>
+ /// <seealso cref="CasecmpTo(string, string)"/>
+ /// <seealso cref="CompareTo(string, string, bool)"/>
+ /// <param name="instance">The string to compare.</param>
+ /// <param name="to">The other string to compare.</param>
+ /// <returns>-1 if less, 0 if equal and +1 if greater.</returns>
public static int NocasecmpTo(this string instance, string to)
{
return instance.CompareTo(to, caseSensitive: false);
}
/// <summary>
- /// Return the character code at position <paramref name="at"/>.
+ /// Returns the character code at position <paramref name="at"/>.
/// </summary>
+ /// <param name="instance">The string to check.</param>
+ /// <param name="at">The position int the string for the character to check.</param>
+ /// <returns>The character code.</returns>
public static int OrdAt(this string instance, int at)
{
return instance[at];
}
/// <summary>
- /// Format a number to have an exact number of <paramref name="digits"/> after the decimal point.
+ /// Format a number to have an exact number of <paramref name="digits"/>
+ /// after the decimal point.
/// </summary>
+ /// <seealso cref="PadZeros(string, int)"/>
+ /// <param name="instance">The string to pad.</param>
+ /// <param name="digits">Amount of digits after the decimal point.</param>
+ /// <returns>The string padded with zeroes.</returns>
public static string PadDecimals(this string instance, int digits)
{
int c = instance.Find(".");
@@ -919,8 +1107,13 @@ namespace Godot
}
/// <summary>
- /// Format a number to have an exact number of <paramref name="digits"/> before the decimal point.
+ /// Format a number to have an exact number of <paramref name="digits"/>
+ /// before the decimal point.
/// </summary>
+ /// <seealso cref="PadDecimals(string, int)"/>
+ /// <param name="instance">The string to pad.</param>
+ /// <param name="digits">Amount of digits before the decimal point.</param>
+ /// <returns>The string padded with zeroes.</returns>
public static string PadZeros(this string instance, int digits)
{
string s = instance;
@@ -952,9 +1145,13 @@ namespace Godot
}
/// <summary>
- /// If the string is a path, this concatenates <paramref name="file"/> at the end of the string as a subpath.
+ /// If the string is a path, this concatenates <paramref name="file"/>
+ /// at the end of the string as a subpath.
/// E.g. <c>"this/is".PlusFile("path") == "this/is/path"</c>.
/// </summary>
+ /// <param name="instance">The path that will be concatenated.</param>
+ /// <param name="file">File name to concatenate with the path.</param>
+ /// <returns>The concatenated path with the given file name.</returns>
public static string PlusFile(this string instance, string file)
{
if (instance.Length > 0 && instance[instance.Length - 1] == '/')
@@ -965,6 +1162,11 @@ namespace Godot
/// <summary>
/// Replace occurrences of a substring for different ones inside the string.
/// </summary>
+ /// <seealso cref="ReplaceN(string, string, string)"/>
+ /// <param name="instance">The string to modify.</param>
+ /// <param name="what">The substring to be replaced in the string.</param>
+ /// <param name="forwhat">The substring that replaces <paramref name="what"/>.</param>
+ /// <returns>The string with the substring occurrences replaced.</returns>
public static string Replace(this string instance, string what, string forwhat)
{
return instance.Replace(what, forwhat);
@@ -973,6 +1175,11 @@ namespace Godot
/// <summary>
/// Replace occurrences of a substring for different ones inside the string, but search case-insensitive.
/// </summary>
+ /// <seealso cref="Replace(string, string, string)"/>
+ /// <param name="instance">The string to modify.</param>
+ /// <param name="what">The substring to be replaced in the string.</param>
+ /// <param name="forwhat">The substring that replaces <paramref name="what"/>.</param>
+ /// <returns>The string with the substring occurrences replaced.</returns>
public static string ReplaceN(this string instance, string what, string forwhat)
{
return Regex.Replace(instance, what, forwhat, RegexOptions.IgnoreCase);
@@ -981,29 +1188,43 @@ namespace Godot
/// <summary>
/// Perform a search for a substring, but start from the end of the string instead of the beginning.
/// </summary>
+ /// <seealso cref="RFindN(string, string, int)"/>
+ /// <param name="instance">The string that will be searched.</param>
+ /// <param name="what">The substring to search in the string.</param>
+ /// <param name="from">The position at which to start searching.</param>
+ /// <returns>The position at which the substring was found, or -1 if not found.</returns>
public static int RFind(this string instance, string what, int from = -1)
{
return godot_icall_String_rfind(instance, what, from);
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_String_rfind(string str, string what, int from);
+ internal static extern int godot_icall_String_rfind(string str, string what, int from);
/// <summary>
/// Perform a search for a substring, but start from the end of the string instead of the beginning.
/// Also search case-insensitive.
/// </summary>
+ /// <seealso cref="RFind(string, string, int)"/>
+ /// <param name="instance">The string that will be searched.</param>
+ /// <param name="what">The substring to search in the string.</param>
+ /// <param name="from">The position at which to start searching.</param>
+ /// <returns>The position at which the substring was found, or -1 if not found.</returns>
public static int RFindN(this string instance, string what, int from = -1)
{
return godot_icall_String_rfindn(instance, what, from);
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_String_rfindn(string str, string what, int from);
+ internal static extern int godot_icall_String_rfindn(string str, string what, int from);
/// <summary>
- /// Return the right side of the string from a given position.
+ /// Returns the right side of the string from a given position.
/// </summary>
+ /// <seealso cref="Left(string, int)"/>
+ /// <param name="instance">The original string.</param>
+ /// <param name="pos">The position in the string from which the right side starts.</param>
+ /// <returns>The right side of the string from the given position.</returns>
public static string Right(this string instance, int pos)
{
if (pos >= instance.Length)
@@ -1018,6 +1239,7 @@ namespace Godot
/// <summary>
/// Returns a copy of the string with characters removed from the right.
/// </summary>
+ /// <seealso cref="LStrip(string, string)"/>
/// <param name="instance">The string to remove characters from.</param>
/// <param name="chars">The characters to be removed.</param>
/// <returns>A copy of the string with characters removed from the right.</returns>
@@ -1042,29 +1264,41 @@ namespace Godot
return instance.Substr(0, end + 1);
}
+ /// <summary>
+ /// Returns the SHA-256 hash of the string as an array of bytes.
+ /// </summary>
+ /// <seealso cref="SHA256Text(string)"/>
+ /// <param name="instance">The string to hash.</param>
+ /// <returns>The SHA-256 hash of the string.</returns>
public static byte[] SHA256Buffer(this string instance)
{
return godot_icall_String_sha256_buffer(instance);
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static byte[] godot_icall_String_sha256_buffer(string str);
+ internal static extern byte[] godot_icall_String_sha256_buffer(string str);
/// <summary>
- /// Return the SHA-256 hash of the string as a string.
+ /// Returns the SHA-256 hash of the string as a string.
/// </summary>
+ /// <seealso cref="SHA256Buffer(string)"/>
+ /// <param name="instance">The string to hash.</param>
+ /// <returns>The SHA-256 hash of the string.</returns>
public static string SHA256Text(this string instance)
{
return godot_icall_String_sha256_text(instance);
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string godot_icall_String_sha256_text(string str);
+ internal static extern string godot_icall_String_sha256_text(string str);
/// <summary>
- /// Return the similarity index of the text compared to this string.
+ /// Returns the similarity index of the text compared to this string.
/// 1 means totally similar and 0 means totally dissimilar.
/// </summary>
+ /// <param name="instance">The string to compare.</param>
+ /// <param name="text">The other string to compare.</param>
+ /// <returns>The similarity index.</returns>
public static float Similarity(this string instance, string text)
{
if (instance == text)
@@ -1117,6 +1351,13 @@ namespace Godot
/// Split the string by a divisor string, return an array of the substrings.
/// Example "One,Two,Three" will return ["One","Two","Three"] if split by ",".
/// </summary>
+ /// <seealso cref="SplitFloats(string, string, bool)"/>
+ /// <param name="instance">The string to split.</param>
+ /// <param name="divisor">The divisor string that splits the string.</param>
+ /// <param name="allowEmpty">
+ /// If <see langword="true"/>, the array may include empty strings.
+ /// </param>
+ /// <returns>The array of strings split from the string.</returns>
public static string[] Split(this string instance, string divisor, bool allowEmpty = true)
{
return instance.Split(new[] { divisor }, allowEmpty ? StringSplitOptions.None : StringSplitOptions.RemoveEmptyEntries);
@@ -1126,6 +1367,13 @@ namespace Godot
/// Split the string in floats by using a divisor string, return an array of the substrings.
/// Example "1,2.5,3" will return [1,2.5,3] if split by ",".
/// </summary>
+ /// <seealso cref="Split(string, string, bool)"/>
+ /// <param name="instance">The string to split.</param>
+ /// <param name="divisor">The divisor string that splits the string.</param>
+ /// <param name="allowEmpty">
+ /// If <see langword="true"/>, the array may include empty floats.
+ /// </param>
+ /// <returns>The array of floats split from the string.</returns>
public static float[] SplitFloats(this string instance, string divisor, bool allowEmpty = true)
{
var ret = new List<float>();
@@ -1148,7 +1396,8 @@ namespace Godot
return ret.ToArray();
}
- private static readonly char[] _nonPrintable = {
+ private static readonly char[] _nonPrintable =
+ {
(char)00, (char)01, (char)02, (char)03, (char)04, (char)05,
(char)06, (char)07, (char)08, (char)09, (char)10, (char)11,
(char)12, (char)13, (char)14, (char)15, (char)16, (char)17,
@@ -1158,9 +1407,13 @@ namespace Godot
};
/// <summary>
- /// Return a copy of the string stripped of any non-printable character at the beginning and the end.
+ /// Returns a copy of the string stripped of any non-printable character at the beginning and the end.
/// The optional arguments are used to toggle stripping on the left and right edges respectively.
/// </summary>
+ /// <param name="instance">The string to strip.</param>
+ /// <param name="left">If the left side should be stripped.</param>
+ /// <param name="right">If the right side should be stripped.</param>
+ /// <returns>The string stripped of any non-printable characters.</returns>
public static string StripEdges(this string instance, bool left = true, bool right = true)
{
if (left)
@@ -1174,8 +1427,14 @@ namespace Godot
}
/// <summary>
- /// Return part of the string from the position <paramref name="from"/>, with length <paramref name="len"/>.
+ /// Returns part of the string from the position <paramref name="from"/>, with length <paramref name="len"/>.
/// </summary>
+ /// <param name="instance">The string to slice.</param>
+ /// <param name="from">The position in the string that the part starts from.</param>
+ /// <param name="len">The length of the returned part.</param>
+ /// <returns>
+ /// Part of the string from the position <paramref name="from"/>, with length <paramref name="len"/>.
+ /// </returns>
public static string Substr(this string instance, int from, int len)
{
int max = instance.Length - from;
@@ -1183,52 +1442,70 @@ namespace Godot
}
/// <summary>
- /// Convert the String (which is a character array) to PackedByteArray (which is an array of bytes).
+ /// Converts the String (which is a character array) to PackedByteArray (which is an array of bytes).
/// The conversion is speeded up in comparison to <see cref="ToUTF8(string)"/> with the assumption
/// that all the characters the String contains are only ASCII characters.
/// </summary>
+ /// <seealso cref="ToUTF8(string)"/>
+ /// <param name="instance">The string to convert.</param>
+ /// <returns>The string as ASCII encoded bytes.</returns>
public static byte[] ToAscii(this string instance)
{
return Encoding.ASCII.GetBytes(instance);
}
/// <summary>
- /// Convert a string, containing a decimal number, into a <see langword="float" />.
+ /// Converts a string, containing a decimal number, into a <see langword="float" />.
/// </summary>
+ /// <seealso cref="ToInt(string)"/>
+ /// <param name="instance">The string to convert.</param>
+ /// <returns>The number representation of the string.</returns>
public static float ToFloat(this string instance)
{
return float.Parse(instance);
}
/// <summary>
- /// Convert a string, containing an integer number, into an <see langword="int" />.
+ /// Converts a string, containing an integer number, into an <see langword="int" />.
/// </summary>
+ /// <seealso cref="ToFloat(string)"/>
+ /// <param name="instance">The string to convert.</param>
+ /// <returns>The number representation of the string.</returns>
public static int ToInt(this string instance)
{
return int.Parse(instance);
}
/// <summary>
- /// Return the string converted to lowercase.
+ /// Returns the string converted to lowercase.
/// </summary>
+ /// <seealso cref="ToUpper(string)"/>
+ /// <param name="instance">The string to convert.</param>
+ /// <returns>The string converted to lowercase.</returns>
public static string ToLower(this string instance)
{
return instance.ToLower();
}
/// <summary>
- /// Return the string converted to uppercase.
+ /// Returns the string converted to uppercase.
/// </summary>
+ /// <seealso cref="ToLower(string)"/>
+ /// <param name="instance">The string to convert.</param>
+ /// <returns>The string converted to uppercase.</returns>
public static string ToUpper(this string instance)
{
return instance.ToUpper();
}
/// <summary>
- /// Convert the String (which is an array of characters) to PackedByteArray (which is an array of bytes).
+ /// Converts the String (which is an array of characters) to PackedByteArray (which is an array of bytes).
/// The conversion is a bit slower than <see cref="ToAscii(string)"/>, but supports all UTF-8 characters.
/// Therefore, you should prefer this function over <see cref="ToAscii(string)"/>.
/// </summary>
+ /// <seealso cref="ToAscii(string)"/>
+ /// <param name="instance">The string to convert.</param>
+ /// <returns>The string as UTF-8 encoded bytes.</returns>
public static byte[] ToUTF8(this string instance)
{
return Encoding.UTF8.GetBytes(instance);
@@ -1237,8 +1514,8 @@ namespace Godot
/// <summary>
/// Decodes a string in URL encoded format. This is meant to
/// decode parameters in a URL when receiving an HTTP request.
- /// This mostly wraps around `System.Uri.UnescapeDataString()`,
- /// but also handles `+`.
+ /// This mostly wraps around <see cref="Uri.UnescapeDataString"/>,
+ /// but also handles <c>+</c>.
/// See <see cref="URIEncode"/> for encoding.
/// </summary>
/// <param name="instance">The string to decode.</param>
@@ -1251,7 +1528,7 @@ namespace Godot
/// <summary>
/// Encodes a string to URL friendly format. This is meant to
/// encode parameters in a URL when sending an HTTP request.
- /// This wraps around `System.Uri.EscapeDataString()`.
+ /// This wraps around <see cref="Uri.EscapeDataString"/>.
/// See <see cref="URIDecode"/> for decoding.
/// </summary>
/// <param name="instance">The string to encode.</param>
@@ -1262,17 +1539,23 @@ namespace Godot
}
/// <summary>
- /// Return a copy of the string with special characters escaped using the XML standard.
+ /// Returns a copy of the string with special characters escaped using the XML standard.
/// </summary>
+ /// <seealso cref="XMLUnescape(string)"/>
+ /// <param name="instance">The string to escape.</param>
+ /// <returns>The escaped string.</returns>
public static string XMLEscape(this string instance)
{
return SecurityElement.Escape(instance);
}
/// <summary>
- /// Return a copy of the string with escaped characters replaced by their meanings
+ /// Returns a copy of the string with escaped characters replaced by their meanings
/// according to the XML standard.
/// </summary>
+ /// <seealso cref="XMLEscape(string)"/>
+ /// <param name="instance">The string to unescape.</param>
+ /// <returns>The unescaped string.</returns>
public static string XMLUnescape(this string instance)
{
return SecurityElement.FromString(instance).Text;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs
index 7700b6d4ed..b1d504410b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs
@@ -3,6 +3,13 @@ using System.Runtime.CompilerServices;
namespace Godot
{
+ /// <summary>
+ /// StringNames are immutable strings designed for general-purpose representation of unique names.
+ /// StringName ensures that only one instance of a given name exists (so two StringNames with the
+ /// same value are the same object).
+ /// Comparing them is much faster than with regular strings, because only the pointers are compared,
+ /// not the whole strings.
+ /// </summary>
public sealed partial class StringName : IDisposable
{
private IntPtr ptr;
@@ -23,6 +30,9 @@ namespace Godot
Dispose(false);
}
+ /// <summary>
+ /// Disposes of this <see cref="StringName"/>.
+ /// </summary>
public void Dispose()
{
Dispose(true);
@@ -43,25 +53,48 @@ namespace Godot
this.ptr = ptr;
}
+ /// <summary>
+ /// Constructs an empty <see cref="StringName"/>.
+ /// </summary>
public StringName()
{
ptr = IntPtr.Zero;
}
+ /// <summary>
+ /// Constructs a <see cref="StringName"/> from the given <paramref name="path"/> string.
+ /// </summary>
+ /// <param name="path">String to construct the <see cref="StringName"/> from.</param>
public StringName(string path)
{
ptr = path == null ? IntPtr.Zero : godot_icall_StringName_Ctor(path);
}
+ /// <summary>
+ /// Converts a string to a <see cref="StringName"/>.
+ /// </summary>
+ /// <param name="from">The string to convert.</param>
public static implicit operator StringName(string from) => new StringName(from);
+ /// <summary>
+ /// Converts a <see cref="StringName"/> to a string.
+ /// </summary>
+ /// <param name="from">The <see cref="StringName"/> to convert.</param>
public static implicit operator string(StringName from) => from.ToString();
+ /// <summary>
+ /// Converts this <see cref="StringName"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this <see cref="StringName"/>.</returns>
public override string ToString()
{
return ptr == IntPtr.Zero ? string.Empty : godot_icall_StringName_operator_String(GetPtr(this));
}
+ /// <summary>
+ /// Check whether this <see cref="StringName"/> is empty.
+ /// </summary>
+ /// <returns>If the <see cref="StringName"/> is empty.</returns>
public bool IsEmpty()
{
return ptr == IntPtr.Zero || godot_icall_StringName_is_empty(GetPtr(this));
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
index 62a6fe6959..daea09ba72 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
@@ -21,18 +21,18 @@ namespace Godot
public struct Transform2D : IEquatable<Transform2D>
{
/// <summary>
- /// The basis matrix's X vector (column 0). Equivalent to array index `[0]`.
+ /// The basis matrix's X vector (column 0). Equivalent to array index <c>[0]</c>.
/// </summary>
/// <value></value>
public Vector2 x;
/// <summary>
- /// The basis matrix's Y vector (column 1). Equivalent to array index `[1]`.
+ /// The basis matrix's Y vector (column 1). Equivalent to array index <c>[1]</c>.
/// </summary>
public Vector2 y;
/// <summary>
- /// The origin vector (column 2, the third column). Equivalent to array index `[2]`.
+ /// The origin vector (column 2, the third column). Equivalent to array index <c>[2]</c>.
/// The origin vector represents translation.
/// </summary>
public Vector2 origin;
@@ -77,7 +77,8 @@ namespace Godot
}
/// <summary>
- /// Access whole columns in the form of Vector2. The third column is the origin vector.
+ /// Access whole columns in the form of <see cref="Vector2"/>.
+ /// The third column is the <see cref="origin"/> vector.
/// </summary>
/// <param name="column">Which column vector.</param>
public Vector2 this[int column]
@@ -116,7 +117,8 @@ namespace Godot
}
/// <summary>
- /// Access matrix elements in column-major order. The third column is the origin vector.
+ /// Access matrix elements in column-major order.
+ /// The third column is the <see cref="origin"/> vector.
/// </summary>
/// <param name="column">Which column, the matrix horizontal position.</param>
/// <param name="row">Which row, the matrix vertical position.</param>
@@ -138,6 +140,7 @@ namespace Godot
/// Returns the inverse of the transform, under the assumption that
/// the transformation is composed of rotation, scaling, and translation.
/// </summary>
+ /// <seealso cref="Inverse"/>
/// <returns>The inverse transformation matrix.</returns>
public Transform2D AffineInverse()
{
@@ -146,7 +149,7 @@ namespace Godot
if (det == 0)
throw new InvalidOperationException("Matrix determinant is zero and cannot be inverted.");
- var inv = this;
+ Transform2D inv = this;
real_t temp = inv[0, 0];
inv[0, 0] = inv[1, 1];
@@ -173,13 +176,14 @@ namespace Godot
/// <returns>The determinant of the basis matrix.</returns>
private real_t BasisDeterminant()
{
- return x.x * y.y - x.y * y.x;
+ return (x.x * y.y) - (x.y * y.x);
}
/// <summary>
/// Returns a vector transformed (multiplied) by the basis matrix.
- /// This method does not account for translation (the origin vector).
+ /// This method does not account for translation (the <see cref="origin"/> vector).
/// </summary>
+ /// <seealso cref="BasisXformInv(Vector2)"/>
/// <param name="v">A vector to transform.</param>
/// <returns>The transformed vector.</returns>
public Vector2 BasisXform(Vector2 v)
@@ -189,11 +193,12 @@ namespace Godot
/// <summary>
/// Returns a vector transformed (multiplied) by the inverse basis matrix.
- /// This method does not account for translation (the origin vector).
+ /// This method does not account for translation (the <see cref="origin"/> vector).
///
/// Note: This results in a multiplication by the inverse of the
/// basis matrix only if it represents a rotation-reflection.
/// </summary>
+ /// <seealso cref="BasisXform(Vector2)"/>
/// <param name="v">A vector to inversely transform.</param>
/// <returns>The inversely transformed vector.</returns>
public Vector2 BasisXformInv(Vector2 v)
@@ -202,7 +207,7 @@ namespace Godot
}
/// <summary>
- /// Interpolates this transform to the other `transform` by `weight`.
+ /// Interpolates this transform to the other <paramref name="transform"/> by <paramref name="weight"/>.
/// </summary>
/// <param name="transform">The other transform.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
@@ -233,8 +238,8 @@ namespace Godot
else
{
real_t angle = weight * Mathf.Acos(dot);
- Vector2 v3 = (v2 - v1 * dot).Normalized();
- v = v1 * Mathf.Cos(angle) + v3 * Mathf.Sin(angle);
+ Vector2 v3 = (v2 - (v1 * dot)).Normalized();
+ v = (v1 * Mathf.Cos(angle)) + (v3 * Mathf.Sin(angle));
}
// Extract parameters
@@ -258,7 +263,7 @@ namespace Godot
/// <returns>The inverse matrix.</returns>
public Transform2D Inverse()
{
- var inv = this;
+ Transform2D inv = this;
// Swap
real_t temp = inv.x.y;
@@ -277,13 +282,13 @@ namespace Godot
/// <returns>The orthonormalized transform.</returns>
public Transform2D Orthonormalized()
{
- var on = this;
+ Transform2D on = this;
Vector2 onX = on.x;
Vector2 onY = on.y;
onX.Normalize();
- onY = onY - onX * onX.Dot(onY);
+ onY = onY - (onX * onX.Dot(onY));
onY.Normalize();
on.x = onX;
@@ -293,7 +298,7 @@ namespace Godot
}
/// <summary>
- /// Rotates the transform by `phi` (in radians), using matrix multiplication.
+ /// Rotates the transform by <paramref name="phi"/> (in radians), using matrix multiplication.
/// </summary>
/// <param name="phi">The angle to rotate, in radians.</param>
/// <returns>The rotated transformation matrix.</returns>
@@ -309,7 +314,7 @@ namespace Godot
/// <returns>The scaled transformation matrix.</returns>
public Transform2D Scaled(Vector2 scale)
{
- var copy = this;
+ Transform2D copy = this;
copy.x *= scale;
copy.y *= scale;
copy.origin *= scale;
@@ -326,16 +331,16 @@ namespace Godot
private real_t Tdotx(Vector2 with)
{
- return this[0, 0] * with[0] + this[1, 0] * with[1];
+ return (this[0, 0] * with[0]) + (this[1, 0] * with[1]);
}
private real_t Tdoty(Vector2 with)
{
- return this[0, 1] * with[0] + this[1, 1] * with[1];
+ return (this[0, 1] * with[0]) + (this[1, 1] * with[1]);
}
/// <summary>
- /// Translates the transform by the given `offset`,
+ /// Translates the transform by the given <paramref name="offset"/>,
/// relative to the transform's basis vectors.
///
/// Unlike <see cref="Rotated"/> and <see cref="Scaled"/>,
@@ -345,7 +350,7 @@ namespace Godot
/// <returns>The translated matrix.</returns>
public Transform2D Translated(Vector2 offset)
{
- var copy = this;
+ Transform2D copy = this;
copy.origin += copy.BasisXform(offset);
return copy;
}
@@ -353,6 +358,7 @@ namespace Godot
/// <summary>
/// Returns a vector transformed (multiplied) by this transformation matrix.
/// </summary>
+ /// <seealso cref="XformInv(Vector2)"/>
/// <param name="v">A vector to transform.</param>
/// <returns>The transformed vector.</returns>
public Vector2 Xform(Vector2 v)
@@ -363,6 +369,7 @@ namespace Godot
/// <summary>
/// Returns a vector transformed (multiplied) by the inverse transformation matrix.
/// </summary>
+ /// <seealso cref="Xform(Vector2)"/>
/// <param name="v">A vector to inversely transform.</param>
/// <returns>The inversely transformed vector.</returns>
public Vector2 XformInv(Vector2 v)
@@ -378,20 +385,20 @@ namespace Godot
/// <summary>
/// The identity transform, with no translation, rotation, or scaling applied.
- /// This is used as a replacement for `Transform2D()` in GDScript.
- /// Do not use `new Transform2D()` with no arguments in C#, because it sets all values to zero.
+ /// This is used as a replacement for <c>Transform2D()</c> in GDScript.
+ /// Do not use <c>new Transform2D()</c> with no arguments in C#, because it sets all values to zero.
/// </summary>
- /// <value>Equivalent to `new Transform2D(Vector2.Right, Vector2.Down, Vector2.Zero)`.</value>
+ /// <value>Equivalent to <c>new Transform2D(Vector2.Right, Vector2.Down, Vector2.Zero)</c>.</value>
public static Transform2D Identity { get { return _identity; } }
/// <summary>
/// The transform that will flip something along the X axis.
/// </summary>
- /// <value>Equivalent to `new Transform2D(Vector2.Left, Vector2.Down, Vector2.Zero)`.</value>
+ /// <value>Equivalent to <c>new Transform2D(Vector2.Left, Vector2.Down, Vector2.Zero)</c>.</value>
public static Transform2D FlipX { get { return _flipX; } }
/// <summary>
/// The transform that will flip something along the Y axis.
/// </summary>
- /// <value>Equivalent to `new Transform2D(Vector2.Right, Vector2.Up, Vector2.Zero)`.</value>
+ /// <value>Equivalent to <c>new Transform2D(Vector2.Right, Vector2.Up, Vector2.Zero)</c>.</value>
public static Transform2D FlipY { get { return _flipY; } }
/// <summary>
@@ -411,12 +418,12 @@ namespace Godot
/// Constructs a transformation matrix from the given components.
/// Arguments are named such that xy is equal to calling x.y
/// </summary>
- /// <param name="xx">The X component of the X column vector, accessed via `t.x.x` or `[0][0]`</param>
- /// <param name="xy">The Y component of the X column vector, accessed via `t.x.y` or `[0][1]`</param>
- /// <param name="yx">The X component of the Y column vector, accessed via `t.y.x` or `[1][0]`</param>
- /// <param name="yy">The Y component of the Y column vector, accessed via `t.y.y` or `[1][1]`</param>
- /// <param name="ox">The X component of the origin vector, accessed via `t.origin.x` or `[2][0]`</param>
- /// <param name="oy">The Y component of the origin vector, accessed via `t.origin.y` or `[2][1]`</param>
+ /// <param name="xx">The X component of the X column vector, accessed via <c>t.x.x</c> or <c>[0][0]</c></param>
+ /// <param name="xy">The Y component of the X column vector, accessed via <c>t.x.y</c> or <c>[0][1]</c></param>
+ /// <param name="yx">The X component of the Y column vector, accessed via <c>t.y.x</c> or <c>[1][0]</c></param>
+ /// <param name="yy">The Y component of the Y column vector, accessed via <c>t.y.y</c> or <c>[1][1]</c></param>
+ /// <param name="ox">The X component of the origin vector, accessed via <c>t.origin.x</c> or <c>[2][0]</c></param>
+ /// <param name="oy">The Y component of the origin vector, accessed via <c>t.origin.y</c> or <c>[2][1]</c></param>
public Transform2D(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy)
{
x = new Vector2(xx, xy);
@@ -425,16 +432,17 @@ namespace Godot
}
/// <summary>
- /// Constructs a transformation matrix from a rotation value and origin vector.
+ /// Constructs a transformation matrix from a <paramref name="rotation"/> value and
+ /// <paramref name="origin"/> vector.
/// </summary>
- /// <param name="rot">The rotation of the new transform, in radians.</param>
- /// <param name="pos">The origin vector, or column index 2.</param>
- public Transform2D(real_t rot, Vector2 pos)
+ /// <param name="rotation">The rotation of the new transform, in radians.</param>
+ /// <param name="origin">The origin vector, or column index 2.</param>
+ public Transform2D(real_t rotation, Vector2 origin)
{
- x.x = y.y = Mathf.Cos(rot);
- x.y = y.x = Mathf.Sin(rot);
+ x.x = y.y = Mathf.Cos(rotation);
+ x.y = y.x = Mathf.Sin(rotation);
y.x *= -1;
- origin = pos;
+ this.origin = origin;
}
public static Transform2D operator *(Transform2D left, Transform2D right)
@@ -464,19 +472,29 @@ namespace Godot
return !left.Equals(right);
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this transform and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the transform and the other object are equal.</returns>
public override bool Equals(object obj)
{
return obj is Transform2D transform2D && Equals(transform2D);
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this transform and <paramref name="other"/> are equal.
+ /// </summary>
+ /// <param name="other">The other transform to compare.</param>
+ /// <returns>Whether or not the matrices are equal.</returns>
public bool Equals(Transform2D other)
{
return x.Equals(other.x) && y.Equals(other.y) && origin.Equals(other.origin);
}
/// <summary>
- /// Returns true if this transform and `other` are approximately equal, by running
- /// <see cref="Vector2.IsEqualApprox(Vector2)"/> on each component.
+ /// Returns <see langword="true"/> if this transform and <paramref name="other"/> are approximately equal,
+ /// by running <see cref="Vector2.IsEqualApprox(Vector2)"/> on each component.
/// </summary>
/// <param name="other">The other transform to compare.</param>
/// <returns>Whether or not the matrices are approximately equal.</returns>
@@ -485,16 +503,28 @@ namespace Godot
return x.IsEqualApprox(other.x) && y.IsEqualApprox(other.y) && origin.IsEqualApprox(other.origin);
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="Transform2D"/>.
+ /// </summary>
+ /// <returns>A hash code for this transform.</returns>
public override int GetHashCode()
{
return x.GetHashCode() ^ y.GetHashCode() ^ origin.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="Transform2D"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this transform.</returns>
public override string ToString()
{
return $"[X: {x}, Y: {y}, O: {origin}]";
}
+ /// <summary>
+ /// Converts this <see cref="Transform2D"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this transform.</returns>
public string ToString(string format)
{
return $"[X: {x.ToString(format)}, Y: {y.ToString(format)}, O: {origin.ToString(format)}]";
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
index afc6a65a45..7176cd60dc 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
@@ -28,12 +28,13 @@ namespace Godot
public Basis basis;
/// <summary>
- /// The origin vector (column 3, the fourth column). Equivalent to array index `[3]`.
+ /// The origin vector (column 3, the fourth column). Equivalent to array index <c>[3]</c>.
/// </summary>
public Vector3 origin;
/// <summary>
- /// Access whole columns in the form of Vector3. The fourth column is the origin vector.
+ /// Access whole columns in the form of <see cref="Vector3"/>.
+ /// The fourth column is the <see cref="origin"/> vector.
/// </summary>
/// <param name="column">Which column vector.</param>
public Vector3 this[int column]
@@ -77,7 +78,8 @@ namespace Godot
}
/// <summary>
- /// Access matrix elements in column-major order. The fourth column is the origin vector.
+ /// Access matrix elements in column-major order.
+ /// The fourth column is the <see cref="origin"/> vector.
/// </summary>
/// <param name="column">Which column, the matrix horizontal position.</param>
/// <param name="row">Which row, the matrix vertical position.</param>
@@ -106,6 +108,7 @@ namespace Godot
/// Returns the inverse of the transform, under the assumption that
/// the transformation is composed of rotation, scaling, and translation.
/// </summary>
+ /// <seealso cref="Inverse"/>
/// <returns>The inverse transformation matrix.</returns>
public Transform3D AffineInverse()
{
@@ -114,7 +117,7 @@ namespace Godot
}
/// <summary>
- /// Interpolates this transform to the other `transform` by `weight`.
+ /// Interpolates this transform to the other <paramref name="transform"/> by <paramref name="weight"/>.
/// </summary>
/// <param name="transform">The other transform.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
@@ -132,7 +135,9 @@ namespace Godot
Vector3 destinationLocation = transform.origin;
var interpolated = new Transform3D();
- interpolated.basis.SetQuaternionScale(sourceRotation.Slerp(destinationRotation, weight).Normalized(), sourceScale.Lerp(destinationScale, weight));
+ Quaternion quaternion = sourceRotation.Slerp(destinationRotation, weight).Normalized();
+ Vector3 scale = sourceScale.Lerp(destinationScale, weight);
+ interpolated.basis.SetQuaternionScale(quaternion, scale);
interpolated.origin = sourceLocation.Lerp(destinationLocation, weight);
return interpolated;
@@ -152,11 +157,11 @@ namespace Godot
/// <summary>
/// Returns a copy of the transform rotated such that its
- /// -Z axis (forward) points towards the target position.
+ /// -Z axis (forward) points towards the <paramref name="target"/> position.
///
- /// The transform will first be rotated around the given up vector,
- /// and then fully aligned to the target by a further rotation around
- /// an axis perpendicular to both the target and up vectors.
+ /// The transform will first be rotated around the given <paramref name="up"/> vector,
+ /// and then fully aligned to the <paramref name="target"/> by a further rotation around
+ /// an axis perpendicular to both the <paramref name="target"/> and <paramref name="up"/> vectors.
///
/// Operations take place in global space.
/// </summary>
@@ -165,7 +170,7 @@ namespace Godot
/// <returns>The resulting transform.</returns>
public Transform3D LookingAt(Vector3 target, Vector3 up)
{
- var t = this;
+ Transform3D t = this;
t.SetLookAt(origin, target, up);
return t;
}
@@ -181,7 +186,7 @@ namespace Godot
}
/// <summary>
- /// Rotates the transform around the given `axis` by `phi` (in radians),
+ /// Rotates the transform around the given <paramref name="axis"/> by <paramref name="phi"/> (in radians),
/// using matrix multiplication. The axis must be a normalized vector.
/// </summary>
/// <param name="axis">The axis to rotate around. Must be normalized.</param>
@@ -226,7 +231,7 @@ namespace Godot
}
/// <summary>
- /// Translates the transform by the given `offset`,
+ /// Translates the transform by the given <paramref name="offset"/>,
/// relative to the transform's basis vectors.
///
/// Unlike <see cref="Rotated"/> and <see cref="Scaled"/>,
@@ -247,6 +252,7 @@ namespace Godot
/// <summary>
/// Returns a vector transformed (multiplied) by this transformation matrix.
/// </summary>
+ /// <seealso cref="XformInv(Vector3)"/>
/// <param name="v">A vector to transform.</param>
/// <returns>The transformed vector.</returns>
public Vector3 Xform(Vector3 v)
@@ -265,6 +271,7 @@ namespace Godot
/// Note: This results in a multiplication by the inverse of the
/// transformation matrix only if it represents a rotation-reflection.
/// </summary>
+ /// <seealso cref="Xform(Vector3)"/>
/// <param name="v">A vector to inversely transform.</param>
/// <returns>The inversely transformed vector.</returns>
public Vector3 XformInv(Vector3 v)
@@ -273,9 +280,9 @@ namespace Godot
return new Vector3
(
- basis.Row0[0] * vInv.x + basis.Row1[0] * vInv.y + basis.Row2[0] * vInv.z,
- basis.Row0[1] * vInv.x + basis.Row1[1] * vInv.y + basis.Row2[1] * vInv.z,
- basis.Row0[2] * vInv.x + basis.Row1[2] * vInv.y + basis.Row2[2] * vInv.z
+ (basis.Row0[0] * vInv.x) + (basis.Row1[0] * vInv.y) + (basis.Row2[0] * vInv.z),
+ (basis.Row0[1] * vInv.x) + (basis.Row1[1] * vInv.y) + (basis.Row2[1] * vInv.z),
+ (basis.Row0[2] * vInv.x) + (basis.Row1[2] * vInv.y) + (basis.Row2[2] * vInv.z)
);
}
@@ -287,25 +294,25 @@ namespace Godot
/// <summary>
/// The identity transform, with no translation, rotation, or scaling applied.
- /// This is used as a replacement for `Transform()` in GDScript.
- /// Do not use `new Transform()` with no arguments in C#, because it sets all values to zero.
+ /// This is used as a replacement for <c>Transform()</c> in GDScript.
+ /// Do not use <c>new Transform()</c> with no arguments in C#, because it sets all values to zero.
/// </summary>
- /// <value>Equivalent to `new Transform(Vector3.Right, Vector3.Up, Vector3.Back, Vector3.Zero)`.</value>
+ /// <value>Equivalent to <c>new Transform(Vector3.Right, Vector3.Up, Vector3.Back, Vector3.Zero)</c>.</value>
public static Transform3D Identity { get { return _identity; } }
/// <summary>
/// The transform that will flip something along the X axis.
/// </summary>
- /// <value>Equivalent to `new Transform(Vector3.Left, Vector3.Up, Vector3.Back, Vector3.Zero)`.</value>
+ /// <value>Equivalent to <c>new Transform(Vector3.Left, Vector3.Up, Vector3.Back, Vector3.Zero)</c>.</value>
public static Transform3D FlipX { get { return _flipX; } }
/// <summary>
/// The transform that will flip something along the Y axis.
/// </summary>
- /// <value>Equivalent to `new Transform(Vector3.Right, Vector3.Down, Vector3.Back, Vector3.Zero)`.</value>
+ /// <value>Equivalent to <c>new Transform(Vector3.Right, Vector3.Down, Vector3.Back, Vector3.Zero)</c>.</value>
public static Transform3D FlipY { get { return _flipY; } }
/// <summary>
/// The transform that will flip something along the Z axis.
/// </summary>
- /// <value>Equivalent to `new Transform(Vector3.Right, Vector3.Up, Vector3.Forward, Vector3.Zero)`.</value>
+ /// <value>Equivalent to <c>new Transform(Vector3.Right, Vector3.Up, Vector3.Forward, Vector3.Zero)</c>.</value>
public static Transform3D FlipZ { get { return _flipZ; } }
/// <summary>
@@ -322,9 +329,10 @@ namespace Godot
}
/// <summary>
- /// Constructs a transformation matrix from the given quaternion and origin vector.
+ /// Constructs a transformation matrix from the given <paramref name="quaternion"/>
+ /// and <paramref name="origin"/> vector.
/// </summary>
- /// <param name="quaternion">The <see cref="Godot.Quaternion"/> to create the basis from.</param>
+ /// <param name="quaternion">The <see cref="Quaternion"/> to create the basis from.</param>
/// <param name="origin">The origin vector, or column index 3.</param>
public Transform3D(Quaternion quaternion, Vector3 origin)
{
@@ -333,9 +341,10 @@ namespace Godot
}
/// <summary>
- /// Constructs a transformation matrix from the given basis and origin vector.
+ /// Constructs a transformation matrix from the given <paramref name="basis"/> and
+ /// <paramref name="origin"/> vector.
/// </summary>
- /// <param name="basis">The <see cref="Godot.Basis"/> to create the basis from.</param>
+ /// <param name="basis">The <see cref="Basis"/> to create the basis from.</param>
/// <param name="origin">The origin vector, or column index 3.</param>
public Transform3D(Basis basis, Vector3 origin)
{
@@ -360,6 +369,11 @@ namespace Godot
return !left.Equals(right);
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this transform and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the transform and the other object are equal.</returns>
public override bool Equals(object obj)
{
if (obj is Transform3D)
@@ -370,14 +384,19 @@ namespace Godot
return false;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this transform and <paramref name="other"/> are equal.
+ /// </summary>
+ /// <param name="other">The other transform to compare.</param>
+ /// <returns>Whether or not the matrices are equal.</returns>
public bool Equals(Transform3D other)
{
return basis.Equals(other.basis) && origin.Equals(other.origin);
}
/// <summary>
- /// Returns true if this transform and `other` are approximately equal, by running
- /// <see cref="Vector3.IsEqualApprox(Vector3)"/> on each component.
+ /// Returns <see langword="true"/> if this transform and <paramref name="other"/> are approximately equal,
+ /// by running <see cref="Vector3.IsEqualApprox(Vector3)"/> on each component.
/// </summary>
/// <param name="other">The other transform to compare.</param>
/// <returns>Whether or not the matrices are approximately equal.</returns>
@@ -386,16 +405,28 @@ namespace Godot
return basis.IsEqualApprox(other.basis) && origin.IsEqualApprox(other.origin);
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="Transform3D"/>.
+ /// </summary>
+ /// <returns>A hash code for this transform.</returns>
public override int GetHashCode()
{
return basis.GetHashCode() ^ origin.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="Transform3D"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this transform.</returns>
public override string ToString()
{
return $"[X: {basis.x}, Y: {basis.y}, Z: {basis.z}, O: {origin}]";
}
+ /// <summary>
+ /// Converts this <see cref="Transform3D"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this transform.</returns>
public string ToString(string format)
{
return $"[X: {basis.x.ToString(format)}, Y: {basis.y.ToString(format)}, Z: {basis.z.ToString(format)}, O: {origin.ToString(format)}]";
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs
index be01674568..eae8927ceb 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs
@@ -8,7 +8,7 @@ namespace Godot
public class UnhandledExceptionArgs
{
/// <summary>
- /// Exception object
+ /// Exception object.
/// </summary>
public Exception Exception { get; private set; }
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
index 8bb5e90a68..fe70d71cce 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
@@ -21,23 +21,36 @@ namespace Godot
/// </summary>
public enum Axis
{
+ /// <summary>
+ /// The vector's X axis.
+ /// </summary>
X = 0,
+ /// <summary>
+ /// The vector's Y axis.
+ /// </summary>
Y
}
/// <summary>
- /// The vector's X component. Also accessible by using the index position `[0]`.
+ /// The vector's X component. Also accessible by using the index position <c>[0]</c>.
/// </summary>
public real_t x;
+
/// <summary>
- /// The vector's Y component. Also accessible by using the index position `[1]`.
+ /// The vector's Y component. Also accessible by using the index position <c>[1]</c>.
/// </summary>
public real_t y;
/// <summary>
/// Access vector components using their index.
/// </summary>
- /// <value>`[0]` is equivalent to `.x`, `[1]` is equivalent to `.y`.</value>
+ /// <exception cref="IndexOutOfRangeException">
+ /// Thrown when the given the <paramref name="index"/> is not 0 or 1.
+ /// </exception>
+ /// <value>
+ /// <c>[0]</c> is equivalent to <see cref="x"/>,
+ /// <c>[1]</c> is equivalent to <see cref="y"/>.
+ /// </value>
public real_t this[int index]
{
get
@@ -97,7 +110,7 @@ namespace Godot
/// Returns this vector's angle with respect to the X axis, or (1, 0) vector, in radians.
///
/// Equivalent to the result of <see cref="Mathf.Atan2(real_t, real_t)"/> when
- /// called with the vector's `y` and `x` as parameters: `Mathf.Atan2(v.y, v.x)`.
+ /// called with the vector's <see cref="y"/> and <see cref="x"/> as parameters: <c>Mathf.Atan2(v.y, v.x)</c>.
/// </summary>
/// <returns>The angle of this vector, in radians.</returns>
public real_t Angle()
@@ -126,9 +139,9 @@ namespace Godot
}
/// <summary>
- /// Returns the aspect ratio of this vector, the ratio of `x` to `y`.
+ /// Returns the aspect ratio of this vector, the ratio of <see cref="x"/> to <see cref="y"/>.
/// </summary>
- /// <returns>The `x` component divided by the `y` component.</returns>
+ /// <returns>The <see cref="x"/> component divided by the <see cref="y"/> component.</returns>
public real_t Aspect()
{
return x / y;
@@ -155,7 +168,7 @@ namespace Godot
/// <summary>
/// Returns a new vector with all components clamped between the
- /// components of `min` and `max` using
+ /// components of <paramref name="min"/> and <paramref name="max"/> using
/// <see cref="Mathf.Clamp(real_t, real_t, real_t)"/>.
/// </summary>
/// <param name="min">The vector with minimum allowed values.</param>
@@ -171,21 +184,22 @@ namespace Godot
}
/// <summary>
- /// Returns the cross product of this vector and `b`.
+ /// Returns the cross product of this vector and <paramref name="b"/>.
/// </summary>
/// <param name="b">The other vector.</param>
/// <returns>The cross product value.</returns>
public real_t Cross(Vector2 b)
{
- return x * b.y - y * b.x;
+ return (x * b.y) - (y * b.x);
}
/// <summary>
- /// Performs a cubic interpolation between vectors `preA`, this vector, `b`, and `postB`, by the given amount `t`.
+ /// Performs a cubic interpolation between vectors <paramref name="preA"/>, this vector,
+ /// <paramref name="b"/>, and <paramref name="postB"/>, by the given amount <paramref name="weight"/>.
/// </summary>
/// <param name="b">The destination vector.</param>
/// <param name="preA">A vector before this vector.</param>
- /// <param name="postB">A vector after `b`.</param>
+ /// <param name="postB">A vector after <paramref name="b"/>.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The interpolated vector.</returns>
public Vector2 CubicInterpolate(Vector2 b, Vector2 preA, Vector2 postB, real_t weight)
@@ -199,24 +213,26 @@ namespace Godot
real_t t2 = t * t;
real_t t3 = t2 * t;
- return 0.5f * (p1 * 2.0f +
- (-p0 + p2) * t +
- (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 +
- (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
+ return 0.5f * (
+ (p1 * 2.0f) +
+ ((-p0 + p2) * t) +
+ (((2.0f * p0) - (5.0f * p1) + (4 * p2) - p3) * t2) +
+ ((-p0 + (3.0f * p1) - (3.0f * p2) + p3) * t3)
+ );
}
/// <summary>
- /// Returns the normalized vector pointing from this vector to `b`.
+ /// Returns the normalized vector pointing from this vector to <paramref name="b"/>.
/// </summary>
/// <param name="b">The other vector to point towards.</param>
- /// <returns>The direction from this vector to `b`.</returns>
+ /// <returns>The direction from this vector to <paramref name="b"/>.</returns>
public Vector2 DirectionTo(Vector2 b)
{
return new Vector2(b.x - x, b.y - y).Normalized();
}
/// <summary>
- /// Returns the squared distance between this vector and `to`.
+ /// Returns the squared distance between this vector and <paramref name="to"/>.
/// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
/// you need to compare vectors or need the squared distance for some formula.
/// </summary>
@@ -228,7 +244,7 @@ namespace Godot
}
/// <summary>
- /// Returns the distance between this vector and `to`.
+ /// Returns the distance between this vector and <paramref name="to"/>.
/// </summary>
/// <param name="to">The other vector to use.</param>
/// <returns>The distance between the two vectors.</returns>
@@ -238,13 +254,13 @@ namespace Godot
}
/// <summary>
- /// Returns the dot product of this vector and `with`.
+ /// Returns the dot product of this vector and <paramref name="with"/>.
/// </summary>
/// <param name="with">The other vector to use.</param>
/// <returns>The dot product of the two vectors.</returns>
public real_t Dot(Vector2 with)
{
- return x * with.x + y * with.y;
+ return (x * with.x) + (y * with.y);
}
/// <summary>
@@ -257,7 +273,7 @@ namespace Godot
}
/// <summary>
- /// Returns the inverse of this vector. This is the same as `new Vector2(1 / v.x, 1 / v.y)`.
+ /// Returns the inverse of this vector. This is the same as <c>new Vector2(1 / v.x, 1 / v.y)</c>.
/// </summary>
/// <returns>The inverse of this vector.</returns>
public Vector2 Inverse()
@@ -266,9 +282,9 @@ namespace Godot
}
/// <summary>
- /// Returns true if the vector is normalized, and false otherwise.
+ /// Returns <see langword="true"/> if the vector is normalized, and <see langword="false"/> otherwise.
/// </summary>
- /// <returns>A bool indicating whether or not the vector is normalized.</returns>
+ /// <returns>A <see langword="bool"/> indicating whether or not the vector is normalized.</returns>
public bool IsNormalized()
{
return Mathf.Abs(LengthSquared() - 1.0f) < Mathf.Epsilon;
@@ -277,10 +293,11 @@ namespace Godot
/// <summary>
/// Returns the length (magnitude) of this vector.
/// </summary>
+ /// <seealso cref="LengthSquared"/>
/// <returns>The length of this vector.</returns>
public real_t Length()
{
- return Mathf.Sqrt(x * x + y * y);
+ return Mathf.Sqrt((x * x) + (y * y));
}
/// <summary>
@@ -291,12 +308,12 @@ namespace Godot
/// <returns>The squared length of this vector.</returns>
public real_t LengthSquared()
{
- return x * x + y * y;
+ return (x * x) + (y * y);
}
/// <summary>
/// Returns the result of the linear interpolation between
- /// this vector and `to` by amount `weight`.
+ /// this vector and <paramref name="to"/> by amount <paramref name="weight"/>.
/// </summary>
/// <param name="to">The destination vector for interpolation.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
@@ -312,10 +329,12 @@ namespace Godot
/// <summary>
/// Returns the result of the linear interpolation between
- /// this vector and `to` by the vector amount `weight`.
+ /// this vector and <paramref name="to"/> by the vector amount <paramref name="weight"/>.
/// </summary>
/// <param name="to">The destination vector for interpolation.</param>
- /// <param name="weight">A vector with components on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <param name="weight">
+ /// A vector with components on the range of 0.0 to 1.0, representing the amount of interpolation.
+ /// </param>
/// <returns>The resulting vector of the interpolation.</returns>
public Vector2 Lerp(Vector2 to, Vector2 weight)
{
@@ -327,7 +346,7 @@ namespace Godot
}
/// <summary>
- /// Returns the vector with a maximum length by limiting its length to `length`.
+ /// Returns the vector with a maximum length by limiting its length to <paramref name="length"/>.
/// </summary>
/// <param name="length">The length to limit to.</param>
/// <returns>The vector with its length limited.</returns>
@@ -366,35 +385,41 @@ namespace Godot
}
/// <summary>
- /// Moves this vector toward `to` by the fixed `delta` amount.
+ /// Moves this vector toward <paramref name="to"/> by the fixed <paramref name="delta"/> amount.
/// </summary>
/// <param name="to">The vector to move towards.</param>
/// <param name="delta">The amount to move towards by.</param>
/// <returns>The resulting vector.</returns>
public Vector2 MoveToward(Vector2 to, real_t delta)
{
- var v = this;
- var vd = to - v;
- var len = vd.Length();
- return len <= delta || len < Mathf.Epsilon ? to : v + vd / len * delta;
+ Vector2 v = this;
+ Vector2 vd = to - v;
+ real_t len = vd.Length();
+ if (len <= delta || len < Mathf.Epsilon)
+ return to;
+
+ return v + (vd / len * delta);
}
/// <summary>
- /// Returns the vector scaled to unit length. Equivalent to `v / v.Length()`.
+ /// Returns the vector scaled to unit length. Equivalent to <c>v / v.Length()</c>.
/// </summary>
/// <returns>A normalized version of the vector.</returns>
public Vector2 Normalized()
{
- var v = this;
+ Vector2 v = this;
v.Normalize();
return v;
}
/// <summary>
- /// Returns a vector composed of the <see cref="Mathf.PosMod(real_t, real_t)"/> of this vector's components and `mod`.
+ /// Returns a vector composed of the <see cref="Mathf.PosMod(real_t, real_t)"/> of this vector's components
+ /// and <paramref name="mod"/>.
/// </summary>
/// <param name="mod">A value representing the divisor of the operation.</param>
- /// <returns>A vector with each component <see cref="Mathf.PosMod(real_t, real_t)"/> by `mod`.</returns>
+ /// <returns>
+ /// A vector with each component <see cref="Mathf.PosMod(real_t, real_t)"/> by <paramref name="mod"/>.
+ /// </returns>
public Vector2 PosMod(real_t mod)
{
Vector2 v;
@@ -404,10 +429,13 @@ namespace Godot
}
/// <summary>
- /// Returns a vector composed of the <see cref="Mathf.PosMod(real_t, real_t)"/> of this vector's components and `modv`'s components.
+ /// Returns a vector composed of the <see cref="Mathf.PosMod(real_t, real_t)"/> of this vector's components
+ /// and <paramref name="modv"/>'s components.
/// </summary>
/// <param name="modv">A vector representing the divisors of the operation.</param>
- /// <returns>A vector with each component <see cref="Mathf.PosMod(real_t, real_t)"/> by `modv`'s components.</returns>
+ /// <returns>
+ /// A vector with each component <see cref="Mathf.PosMod(real_t, real_t)"/> by <paramref name="modv"/>'s components.
+ /// </returns>
public Vector2 PosMod(Vector2 modv)
{
Vector2 v;
@@ -417,7 +445,7 @@ namespace Godot
}
/// <summary>
- /// Returns this vector projected onto another vector `b`.
+ /// Returns this vector projected onto another vector <paramref name="onNormal"/>.
/// </summary>
/// <param name="onNormal">The vector to project onto.</param>
/// <returns>The projected vector.</returns>
@@ -427,7 +455,7 @@ namespace Godot
}
/// <summary>
- /// Returns this vector reflected from a plane defined by the given `normal`.
+ /// Returns this vector reflected from a plane defined by the given <paramref name="normal"/>.
/// </summary>
/// <param name="normal">The normal vector defining the plane to reflect from. Must be normalized.</param>
/// <returns>The reflected vector.</returns>
@@ -439,11 +467,11 @@ namespace Godot
throw new ArgumentException("Argument is not normalized", nameof(normal));
}
#endif
- return 2 * Dot(normal) * normal - this;
+ return (2 * Dot(normal) * normal) - this;
}
/// <summary>
- /// Rotates this vector by `phi` radians.
+ /// Rotates this vector by <paramref name="phi"/> radians.
/// </summary>
/// <param name="phi">The angle to rotate by, in radians.</param>
/// <returns>The rotated vector.</returns>
@@ -471,7 +499,7 @@ namespace Godot
/// on the signs of this vector's components, or zero if the component is zero,
/// by calling <see cref="Mathf.Sign(real_t)"/> on each component.
/// </summary>
- /// <returns>A vector with all components as either `1`, `-1`, or `0`.</returns>
+ /// <returns>A vector with all components as either <c>1</c>, <c>-1</c>, or <c>0</c>.</returns>
public Vector2 Sign()
{
Vector2 v;
@@ -482,7 +510,7 @@ namespace Godot
/// <summary>
/// Returns the result of the spherical linear interpolation between
- /// this vector and `to` by amount `weight`.
+ /// this vector and <paramref name="to"/> by amount <paramref name="weight"/>.
///
/// Note: Both vectors must be normalized.
/// </summary>
@@ -498,24 +526,24 @@ namespace Godot
}
if (!to.IsNormalized())
{
- throw new InvalidOperationException("Vector2.Slerp: `to` is not normalized.");
+ throw new InvalidOperationException($"Vector2.Slerp: `{nameof(to)}` is not normalized.");
}
#endif
return Rotated(AngleTo(to) * weight);
}
/// <summary>
- /// Returns this vector slid along a plane defined by the given normal.
+ /// Returns this vector slid along a plane defined by the given <paramref name="normal"/>.
/// </summary>
/// <param name="normal">The normal vector defining the plane to slide on.</param>
/// <returns>The slid vector.</returns>
public Vector2 Slide(Vector2 normal)
{
- return this - normal * Dot(normal);
+ return this - (normal * Dot(normal));
}
/// <summary>
- /// Returns this vector with each component snapped to the nearest multiple of `step`.
+ /// Returns this vector with each component snapped to the nearest multiple of <paramref name="step"/>.
/// This can also be used to round to an arbitrary number of decimals.
/// </summary>
/// <param name="step">A vector value representing the step size to snap to.</param>
@@ -546,40 +574,40 @@ namespace Godot
private static readonly Vector2 _left = new Vector2(-1, 0);
/// <summary>
- /// Zero vector, a vector with all components set to `0`.
+ /// Zero vector, a vector with all components set to <c>0</c>.
/// </summary>
- /// <value>Equivalent to `new Vector2(0, 0)`</value>
+ /// <value>Equivalent to <c>new Vector2(0, 0)</c>.</value>
public static Vector2 Zero { get { return _zero; } }
/// <summary>
- /// One vector, a vector with all components set to `1`.
+ /// One vector, a vector with all components set to <c>1</c>.
/// </summary>
- /// <value>Equivalent to `new Vector2(1, 1)`</value>
+ /// <value>Equivalent to <c>new Vector2(1, 1)</c>.</value>
public static Vector2 One { get { return _one; } }
/// <summary>
- /// Infinity vector, a vector with all components set to `Mathf.Inf`.
+ /// Infinity vector, a vector with all components set to <see cref="Mathf.Inf"/>.
/// </summary>
- /// <value>Equivalent to `new Vector2(Mathf.Inf, Mathf.Inf)`</value>
+ /// <value>Equivalent to <c>new Vector2(Mathf.Inf, Mathf.Inf)</c>.</value>
public static Vector2 Inf { get { return _inf; } }
/// <summary>
/// Up unit vector. Y is down in 2D, so this vector points -Y.
/// </summary>
- /// <value>Equivalent to `new Vector2(0, -1)`</value>
+ /// <value>Equivalent to <c>new Vector2(0, -1)</c>.</value>
public static Vector2 Up { get { return _up; } }
/// <summary>
/// Down unit vector. Y is down in 2D, so this vector points +Y.
/// </summary>
- /// <value>Equivalent to `new Vector2(0, 1)`</value>
+ /// <value>Equivalent to <c>new Vector2(0, 1)</c>.</value>
public static Vector2 Down { get { return _down; } }
/// <summary>
/// Right unit vector. Represents the direction of right.
/// </summary>
- /// <value>Equivalent to `new Vector2(1, 0)`</value>
+ /// <value>Equivalent to <c>new Vector2(1, 0)</c>.</value>
public static Vector2 Right { get { return _right; } }
/// <summary>
/// Left unit vector. Represents the direction of left.
/// </summary>
- /// <value>Equivalent to `new Vector2(-1, 0)`</value>
+ /// <value>Equivalent to <c>new Vector2(-1, 0)</c>.</value>
public static Vector2 Left { get { return _left; } }
/// <summary>
@@ -603,6 +631,17 @@ namespace Godot
y = v.y;
}
+ /// <summary>
+ /// Creates a unit Vector2 rotated to the given angle. This is equivalent to doing
+ /// <c>Vector2(Mathf.Cos(angle), Mathf.Sin(angle))</c> or <c>Vector2.Right.Rotated(angle)</c>.
+ /// </summary>
+ /// <param name="angle">Angle of the vector, in radians.</param>
+ /// <returns>The resulting vector.</returns>
+ public static Vector2 FromAngle(real_t angle)
+ {
+ return new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
+ }
+
public static Vector2 operator +(Vector2 left, Vector2 right)
{
left.x += right.x;
@@ -719,6 +758,11 @@ namespace Godot
return left.x >= right.x;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this vector and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the vector and the other object are equal.</returns>
public override bool Equals(object obj)
{
if (obj is Vector2)
@@ -728,14 +772,19 @@ namespace Godot
return false;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this vector and <paramref name="other"/> are equal.
+ /// </summary>
+ /// <param name="other">The other vector to compare.</param>
+ /// <returns>Whether or not the vectors are equal.</returns>
public bool Equals(Vector2 other)
{
return x == other.x && y == other.y;
}
/// <summary>
- /// Returns true if this vector and `other` are approximately equal, by running
- /// <see cref="Mathf.IsEqualApprox(real_t, real_t)"/> on each component.
+ /// Returns <see langword="true"/> if this vector and <paramref name="other"/> are approximately equal,
+ /// by running <see cref="Mathf.IsEqualApprox(real_t, real_t)"/> on each component.
/// </summary>
/// <param name="other">The other vector to compare.</param>
/// <returns>Whether or not the vectors are approximately equal.</returns>
@@ -744,16 +793,28 @@ namespace Godot
return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y);
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="Vector2"/>.
+ /// </summary>
+ /// <returns>A hash code for this vector.</returns>
public override int GetHashCode()
{
return y.GetHashCode() ^ x.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="Vector2"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this vector.</returns>
public override string ToString()
{
return $"({x}, {y})";
}
+ /// <summary>
+ /// Converts this <see cref="Vector2"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this vector.</returns>
public string ToString(string format)
{
return $"({x.ToString(format)}, {y.ToString(format)})";
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
index 959f262f52..ca4531d885 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
@@ -21,23 +21,36 @@ namespace Godot
/// </summary>
public enum Axis
{
+ /// <summary>
+ /// The vector's X axis.
+ /// </summary>
X = 0,
+ /// <summary>
+ /// The vector's Y axis.
+ /// </summary>
Y
}
/// <summary>
- /// The vector's X component. Also accessible by using the index position `[0]`.
+ /// The vector's X component. Also accessible by using the index position <c>[0]</c>.
/// </summary>
public int x;
+
/// <summary>
- /// The vector's Y component. Also accessible by using the index position `[1]`.
+ /// The vector's Y component. Also accessible by using the index position <c>[1]</c>.
/// </summary>
public int y;
/// <summary>
/// Access vector components using their index.
/// </summary>
- /// <value>`[0]` is equivalent to `.x`, `[1]` is equivalent to `.y`.</value>
+ /// <exception cref="IndexOutOfRangeException">
+ /// Thrown when the given the <paramref name="index"/> is not 0 or 1.
+ /// </exception>
+ /// <value>
+ /// <c>[0]</c> is equivalent to <see cref="x"/>,
+ /// <c>[1]</c> is equivalent to <see cref="y"/>.
+ /// </value>
public int this[int index]
{
get
@@ -81,7 +94,7 @@ namespace Godot
/// Returns this vector's angle with respect to the X axis, or (1, 0) vector, in radians.
///
/// Equivalent to the result of <see cref="Mathf.Atan2(real_t, real_t)"/> when
- /// called with the vector's `y` and `x` as parameters: `Mathf.Atan2(v.y, v.x)`.
+ /// called with the vector's <see cref="y"/> and <see cref="x"/> as parameters: <c>Mathf.Atan2(v.y, v.x)</c>.
/// </summary>
/// <returns>The angle of this vector, in radians.</returns>
public real_t Angle()
@@ -110,9 +123,9 @@ namespace Godot
}
/// <summary>
- /// Returns the aspect ratio of this vector, the ratio of `x` to `y`.
+ /// Returns the aspect ratio of this vector, the ratio of <see cref="x"/> to <see cref="y"/>.
/// </summary>
- /// <returns>The `x` component divided by the `y` component.</returns>
+ /// <returns>The <see cref="x"/> component divided by the <see cref="y"/> component.</returns>
public real_t Aspect()
{
return x / (real_t)y;
@@ -120,7 +133,7 @@ namespace Godot
/// <summary>
/// Returns a new vector with all components clamped between the
- /// components of `min` and `max` using
+ /// components of <paramref name="min"/> and <paramref name="max"/> using
/// <see cref="Mathf.Clamp(int, int, int)"/>.
/// </summary>
/// <param name="min">The vector with minimum allowed values.</param>
@@ -136,7 +149,7 @@ namespace Godot
}
/// <summary>
- /// Returns the cross product of this vector and `b`.
+ /// Returns the cross product of this vector and <paramref name="b"/>.
/// </summary>
/// <param name="b">The other vector.</param>
/// <returns>The cross product vector.</returns>
@@ -146,7 +159,7 @@ namespace Godot
}
/// <summary>
- /// Returns the squared distance between this vector and `b`.
+ /// Returns the squared distance between this vector and <paramref name="b"/>.
/// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
/// you need to compare vectors or need the squared distance for some formula.
/// </summary>
@@ -158,7 +171,7 @@ namespace Godot
}
/// <summary>
- /// Returns the distance between this vector and `b`.
+ /// Returns the distance between this vector and <paramref name="b"/>.
/// </summary>
/// <param name="b">The other vector to use.</param>
/// <returns>The distance between the two vectors.</returns>
@@ -168,7 +181,7 @@ namespace Godot
}
/// <summary>
- /// Returns the dot product of this vector and `b`.
+ /// Returns the dot product of this vector and <paramref name="b"/>.
/// </summary>
/// <param name="b">The other vector to use.</param>
/// <returns>The dot product of the two vectors.</returns>
@@ -180,6 +193,7 @@ namespace Godot
/// <summary>
/// Returns the length (magnitude) of this vector.
/// </summary>
+ /// <seealso cref="LengthSquared"/>
/// <returns>The length of this vector.</returns>
public real_t Length()
{
@@ -224,10 +238,13 @@ namespace Godot
}
/// <summary>
- /// Returns a vector composed of the <see cref="Mathf.PosMod(int, int)"/> of this vector's components and `mod`.
+ /// Returns a vector composed of the <see cref="Mathf.PosMod(int, int)"/> of this vector's components
+ /// and <paramref name="mod"/>.
/// </summary>
/// <param name="mod">A value representing the divisor of the operation.</param>
- /// <returns>A vector with each component <see cref="Mathf.PosMod(int, int)"/> by `mod`.</returns>
+ /// <returns>
+ /// A vector with each component <see cref="Mathf.PosMod(int, int)"/> by <paramref name="mod"/>.
+ /// </returns>
public Vector2i PosMod(int mod)
{
Vector2i v = this;
@@ -237,10 +254,13 @@ namespace Godot
}
/// <summary>
- /// Returns a vector composed of the <see cref="Mathf.PosMod(int, int)"/> of this vector's components and `modv`'s components.
+ /// Returns a vector composed of the <see cref="Mathf.PosMod(int, int)"/> of this vector's components
+ /// and <paramref name="modv"/>'s components.
/// </summary>
/// <param name="modv">A vector representing the divisors of the operation.</param>
- /// <returns>A vector with each component <see cref="Mathf.PosMod(int, int)"/> by `modv`'s components.</returns>
+ /// <returns>
+ /// A vector with each component <see cref="Mathf.PosMod(int, int)"/> by <paramref name="modv"/>'s components.
+ /// </returns>
public Vector2i PosMod(Vector2i modv)
{
Vector2i v = this;
@@ -254,7 +274,7 @@ namespace Godot
/// on the signs of this vector's components, or zero if the component is zero,
/// by calling <see cref="Mathf.Sign(int)"/> on each component.
/// </summary>
- /// <returns>A vector with all components as either `1`, `-1`, or `0`.</returns>
+ /// <returns>A vector with all components as either <c>1</c>, <c>-1</c>, or <c>0</c>.</returns>
public Vector2i Sign()
{
Vector2i v = this;
@@ -283,35 +303,35 @@ namespace Godot
private static readonly Vector2i _left = new Vector2i(-1, 0);
/// <summary>
- /// Zero vector, a vector with all components set to `0`.
+ /// Zero vector, a vector with all components set to <c>0</c>.
/// </summary>
- /// <value>Equivalent to `new Vector2i(0, 0)`</value>
+ /// <value>Equivalent to <c>new Vector2i(0, 0)</c>.</value>
public static Vector2i Zero { get { return _zero; } }
/// <summary>
- /// One vector, a vector with all components set to `1`.
+ /// One vector, a vector with all components set to <c>1</c>.
/// </summary>
- /// <value>Equivalent to `new Vector2i(1, 1)`</value>
+ /// <value>Equivalent to <c>new Vector2i(1, 1)</c>.</value>
public static Vector2i One { get { return _one; } }
/// <summary>
/// Up unit vector. Y is down in 2D, so this vector points -Y.
/// </summary>
- /// <value>Equivalent to `new Vector2i(0, -1)`</value>
+ /// <value>Equivalent to <c>new Vector2i(0, -1)</c>.</value>
public static Vector2i Up { get { return _up; } }
/// <summary>
/// Down unit vector. Y is down in 2D, so this vector points +Y.
/// </summary>
- /// <value>Equivalent to `new Vector2i(0, 1)`</value>
+ /// <value>Equivalent to <c>new Vector2i(0, 1)</c>.</value>
public static Vector2i Down { get { return _down; } }
/// <summary>
/// Right unit vector. Represents the direction of right.
/// </summary>
- /// <value>Equivalent to `new Vector2i(1, 0)`</value>
+ /// <value>Equivalent to <c>new Vector2i(1, 0)</c>.</value>
public static Vector2i Right { get { return _right; } }
/// <summary>
/// Left unit vector. Represents the direction of left.
/// </summary>
- /// <value>Equivalent to `new Vector2i(-1, 0)`</value>
+ /// <value>Equivalent to <c>new Vector2i(-1, 0)</c>.</value>
public static Vector2i Left { get { return _left; } }
/// <summary>
@@ -476,16 +496,29 @@ namespace Godot
return left.x >= right.x;
}
+ /// <summary>
+ /// Converts this <see cref="Vector2i"/> to a <see cref="Vector2"/>.
+ /// </summary>
+ /// <param name="value">The vector to convert.</param>
public static implicit operator Vector2(Vector2i value)
{
return new Vector2(value.x, value.y);
}
+ /// <summary>
+ /// Converts a <see cref="Vector2"/> to a <see cref="Vector2i"/>.
+ /// </summary>
+ /// <param name="value">The vector to convert.</param>
public static explicit operator Vector2i(Vector2 value)
{
return new Vector2i(value);
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this vector and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the vector and the other object are equal.</returns>
public override bool Equals(object obj)
{
if (obj is Vector2i)
@@ -496,21 +529,38 @@ namespace Godot
return false;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this vector and <paramref name="other"/> are equal.
+ /// </summary>
+ /// <param name="other">The other vector to compare.</param>
+ /// <returns>Whether or not the vectors are equal.</returns>
public bool Equals(Vector2i other)
{
return x == other.x && y == other.y;
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="Vector2i"/>.
+ /// </summary>
+ /// <returns>A hash code for this vector.</returns>
public override int GetHashCode()
{
return y.GetHashCode() ^ x.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="Vector2i"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this vector.</returns>
public override string ToString()
{
return $"({x}, {y})";
}
+ /// <summary>
+ /// Converts this <see cref="Vector2i"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this vector.</returns>
public string ToString(string format)
{
return $"({x.ToString(format)}, {y.ToString(format)})";
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
index bdf64159e9..01e3a71bcb 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
@@ -21,28 +21,46 @@ namespace Godot
/// </summary>
public enum Axis
{
+ /// <summary>
+ /// The vector's X axis.
+ /// </summary>
X = 0,
+ /// <summary>
+ /// The vector's Y axis.
+ /// </summary>
Y,
+ /// <summary>
+ /// The vector's Z axis.
+ /// </summary>
Z
}
/// <summary>
- /// The vector's X component. Also accessible by using the index position `[0]`.
+ /// The vector's X component. Also accessible by using the index position <c>[0]</c>.
/// </summary>
public real_t x;
+
/// <summary>
- /// The vector's Y component. Also accessible by using the index position `[1]`.
+ /// The vector's Y component. Also accessible by using the index position <c>[1]</c>.
/// </summary>
public real_t y;
+
/// <summary>
- /// The vector's Z component. Also accessible by using the index position `[2]`.
+ /// The vector's Z component. Also accessible by using the index position <c>[2]</c>.
/// </summary>
public real_t z;
/// <summary>
/// Access vector components using their index.
/// </summary>
- /// <value>`[0]` is equivalent to `.x`, `[1]` is equivalent to `.y`, `[2]` is equivalent to `.z`.</value>
+ /// <exception cref="IndexOutOfRangeException">
+ /// Thrown when the given the <paramref name="index"/> is not 0, 1 or 2.
+ /// </exception>
+ /// <value>
+ /// <c>[0]</c> is equivalent to <see cref="x"/>,
+ /// <c>[1]</c> is equivalent to <see cref="y"/>,
+ /// <c>[2]</c> is equivalent to <see cref="z"/>.
+ /// </value>
public real_t this[int index]
{
get
@@ -135,7 +153,7 @@ namespace Godot
/// <summary>
/// Returns a new vector with all components clamped between the
- /// components of `min` and `max` using
+ /// components of <paramref name="min"/> and <paramref name="max"/> using
/// <see cref="Mathf.Clamp(real_t, real_t, real_t)"/>.
/// </summary>
/// <param name="min">The vector with minimum allowed values.</param>
@@ -152,7 +170,7 @@ namespace Godot
}
/// <summary>
- /// Returns the cross product of this vector and `b`.
+ /// Returns the cross product of this vector and <paramref name="b"/>.
/// </summary>
/// <param name="b">The other vector.</param>
/// <returns>The cross product vector.</returns>
@@ -160,19 +178,19 @@ namespace Godot
{
return new Vector3
(
- y * b.z - z * b.y,
- z * b.x - x * b.z,
- x * b.y - y * b.x
+ (y * b.z) - (z * b.y),
+ (z * b.x) - (x * b.z),
+ (x * b.y) - (y * b.x)
);
}
/// <summary>
- /// Performs a cubic interpolation between vectors `preA`, this vector,
- /// `b`, and `postB`, by the given amount `t`.
+ /// Performs a cubic interpolation between vectors <paramref name="preA"/>, this vector,
+ /// <paramref name="b"/>, and <paramref name="postB"/>, by the given amount <paramref name="weight"/>.
/// </summary>
/// <param name="b">The destination vector.</param>
/// <param name="preA">A vector before this vector.</param>
- /// <param name="postB">A vector after `b`.</param>
+ /// <param name="postB">A vector after <paramref name="b"/>.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The interpolated vector.</returns>
public Vector3 CubicInterpolate(Vector3 b, Vector3 preA, Vector3 postB, real_t weight)
@@ -187,24 +205,24 @@ namespace Godot
real_t t3 = t2 * t;
return 0.5f * (
- p1 * 2.0f + (-p0 + p2) * t +
- (2.0f * p0 - 5.0f * p1 + 4f * p2 - p3) * t2 +
- (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3
- );
+ (p1 * 2.0f) + ((-p0 + p2) * t) +
+ (((2.0f * p0) - (5.0f * p1) + (4f * p2) - p3) * t2) +
+ ((-p0 + (3.0f * p1) - (3.0f * p2) + p3) * t3)
+ );
}
/// <summary>
- /// Returns the normalized vector pointing from this vector to `b`.
+ /// Returns the normalized vector pointing from this vector to <paramref name="b"/>.
/// </summary>
/// <param name="b">The other vector to point towards.</param>
- /// <returns>The direction from this vector to `b`.</returns>
+ /// <returns>The direction from this vector to <paramref name="b"/>.</returns>
public Vector3 DirectionTo(Vector3 b)
{
return new Vector3(b.x - x, b.y - y, b.z - z).Normalized();
}
/// <summary>
- /// Returns the squared distance between this vector and `b`.
+ /// Returns the squared distance between this vector and <paramref name="b"/>.
/// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
/// you need to compare vectors or need the squared distance for some formula.
/// </summary>
@@ -216,8 +234,9 @@ namespace Godot
}
/// <summary>
- /// Returns the distance between this vector and `b`.
+ /// Returns the distance between this vector and <paramref name="b"/>.
/// </summary>
+ /// <seealso cref="DistanceSquaredTo(Vector3)"/>
/// <param name="b">The other vector to use.</param>
/// <returns>The distance between the two vectors.</returns>
public real_t DistanceTo(Vector3 b)
@@ -226,13 +245,13 @@ namespace Godot
}
/// <summary>
- /// Returns the dot product of this vector and `b`.
+ /// Returns the dot product of this vector and <paramref name="b"/>.
/// </summary>
/// <param name="b">The other vector to use.</param>
/// <returns>The dot product of the two vectors.</returns>
public real_t Dot(Vector3 b)
{
- return x * b.x + y * b.y + z * b.z;
+ return (x * b.x) + (y * b.y) + (z * b.z);
}
/// <summary>
@@ -245,7 +264,7 @@ namespace Godot
}
/// <summary>
- /// Returns the inverse of this vector. This is the same as `new Vector3(1 / v.x, 1 / v.y, 1 / v.z)`.
+ /// Returns the inverse of this vector. This is the same as <c>new Vector3(1 / v.x, 1 / v.y, 1 / v.z)</c>.
/// </summary>
/// <returns>The inverse of this vector.</returns>
public Vector3 Inverse()
@@ -254,9 +273,9 @@ namespace Godot
}
/// <summary>
- /// Returns true if the vector is normalized, and false otherwise.
+ /// Returns <see langword="true"/> if the vector is normalized, and <see langword="false"/> otherwise.
/// </summary>
- /// <returns>A bool indicating whether or not the vector is normalized.</returns>
+ /// <returns>A <see langword="bool"/> indicating whether or not the vector is normalized.</returns>
public bool IsNormalized()
{
return Mathf.Abs(LengthSquared() - 1.0f) < Mathf.Epsilon;
@@ -265,6 +284,7 @@ namespace Godot
/// <summary>
/// Returns the length (magnitude) of this vector.
/// </summary>
+ /// <seealso cref="LengthSquared"/>
/// <returns>The length of this vector.</returns>
public real_t Length()
{
@@ -292,7 +312,7 @@ namespace Godot
/// <summary>
/// Returns the result of the linear interpolation between
- /// this vector and `to` by amount `weight`.
+ /// this vector and <paramref name="to"/> by amount <paramref name="weight"/>.
/// </summary>
/// <param name="to">The destination vector for interpolation.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
@@ -309,7 +329,7 @@ namespace Godot
/// <summary>
/// Returns the result of the linear interpolation between
- /// this vector and `to` by the vector amount `weight`.
+ /// this vector and <paramref name="to"/> by the vector amount <paramref name="weight"/>.
/// </summary>
/// <param name="to">The destination vector for interpolation.</param>
/// <param name="weight">A vector with components on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
@@ -325,7 +345,7 @@ namespace Godot
}
/// <summary>
- /// Returns the vector with a maximum length by limiting its length to `length`.
+ /// Returns the vector with a maximum length by limiting its length to <paramref name="length"/>.
/// </summary>
/// <param name="length">The length to limit to.</param>
/// <returns>The vector with its length limited.</returns>
@@ -364,32 +384,35 @@ namespace Godot
}
/// <summary>
- /// Moves this vector toward `to` by the fixed `delta` amount.
+ /// Moves this vector toward <paramref name="to"/> by the fixed <paramref name="delta"/> amount.
/// </summary>
/// <param name="to">The vector to move towards.</param>
/// <param name="delta">The amount to move towards by.</param>
/// <returns>The resulting vector.</returns>
public Vector3 MoveToward(Vector3 to, real_t delta)
{
- var v = this;
- var vd = to - v;
- var len = vd.Length();
- return len <= delta || len < Mathf.Epsilon ? to : v + vd / len * delta;
+ Vector3 v = this;
+ Vector3 vd = to - v;
+ real_t len = vd.Length();
+ if (len <= delta || len < Mathf.Epsilon)
+ return to;
+
+ return v + (vd / len * delta);
}
/// <summary>
- /// Returns the vector scaled to unit length. Equivalent to `v / v.Length()`.
+ /// Returns the vector scaled to unit length. Equivalent to <c>v / v.Length()</c>.
/// </summary>
/// <returns>A normalized version of the vector.</returns>
public Vector3 Normalized()
{
- var v = this;
+ Vector3 v = this;
v.Normalize();
return v;
}
/// <summary>
- /// Returns the outer product with `b`.
+ /// Returns the outer product with <paramref name="b"/>.
/// </summary>
/// <param name="b">The other vector.</param>
/// <returns>A <see cref="Basis"/> representing the outer product matrix.</returns>
@@ -403,10 +426,13 @@ namespace Godot
}
/// <summary>
- /// Returns a vector composed of the <see cref="Mathf.PosMod(real_t, real_t)"/> of this vector's components and `mod`.
+ /// Returns a vector composed of the <see cref="Mathf.PosMod(real_t, real_t)"/> of this vector's components
+ /// and <paramref name="mod"/>.
/// </summary>
/// <param name="mod">A value representing the divisor of the operation.</param>
- /// <returns>A vector with each component <see cref="Mathf.PosMod(real_t, real_t)"/> by `mod`.</returns>
+ /// <returns>
+ /// A vector with each component <see cref="Mathf.PosMod(real_t, real_t)"/> by <paramref name="mod"/>.
+ /// </returns>
public Vector3 PosMod(real_t mod)
{
Vector3 v;
@@ -417,10 +443,13 @@ namespace Godot
}
/// <summary>
- /// Returns a vector composed of the <see cref="Mathf.PosMod(real_t, real_t)"/> of this vector's components and `modv`'s components.
+ /// Returns a vector composed of the <see cref="Mathf.PosMod(real_t, real_t)"/> of this vector's components
+ /// and <paramref name="modv"/>'s components.
/// </summary>
/// <param name="modv">A vector representing the divisors of the operation.</param>
- /// <returns>A vector with each component <see cref="Mathf.PosMod(real_t, real_t)"/> by `modv`'s components.</returns>
+ /// <returns>
+ /// A vector with each component <see cref="Mathf.PosMod(real_t, real_t)"/> by <paramref name="modv"/>'s components.
+ /// </returns>
public Vector3 PosMod(Vector3 modv)
{
Vector3 v;
@@ -431,7 +460,7 @@ namespace Godot
}
/// <summary>
- /// Returns this vector projected onto another vector `b`.
+ /// Returns this vector projected onto another vector <paramref name="onNormal"/>.
/// </summary>
/// <param name="onNormal">The vector to project onto.</param>
/// <returns>The projected vector.</returns>
@@ -441,7 +470,7 @@ namespace Godot
}
/// <summary>
- /// Returns this vector reflected from a plane defined by the given `normal`.
+ /// Returns this vector reflected from a plane defined by the given <paramref name="normal"/>.
/// </summary>
/// <param name="normal">The normal vector defining the plane to reflect from. Must be normalized.</param>
/// <returns>The reflected vector.</returns>
@@ -453,12 +482,12 @@ namespace Godot
throw new ArgumentException("Argument is not normalized", nameof(normal));
}
#endif
- return 2.0f * Dot(normal) * normal - this;
+ return (2.0f * Dot(normal) * normal) - this;
}
/// <summary>
- /// Rotates this vector around a given `axis` vector by `phi` radians.
- /// The `axis` vector must be a normalized vector.
+ /// Rotates this vector around a given <paramref name="axis"/> vector by <paramref name="phi"/> radians.
+ /// The <paramref name="axis"/> vector must be a normalized vector.
/// </summary>
/// <param name="axis">The vector to rotate around. Must be normalized.</param>
/// <param name="phi">The angle to rotate by, in radians.</param>
@@ -489,7 +518,7 @@ namespace Godot
/// on the signs of this vector's components, or zero if the component is zero,
/// by calling <see cref="Mathf.Sign(real_t)"/> on each component.
/// </summary>
- /// <returns>A vector with all components as either `1`, `-1`, or `0`.</returns>
+ /// <returns>A vector with all components as either <c>1</c>, <c>-1</c>, or <c>0</c>.</returns>
public Vector3 Sign()
{
Vector3 v;
@@ -503,7 +532,7 @@ namespace Godot
/// Returns the signed angle to the given vector, in radians.
/// The sign of the angle is positive in a counter-clockwise
/// direction and negative in a clockwise direction when viewed
- /// from the side specified by the `axis`.
+ /// from the side specified by the <paramref name="axis"/>.
/// </summary>
/// <param name="to">The other vector to compare this vector to.</param>
/// <param name="axis">The reference axis to use for the angle sign.</param>
@@ -518,7 +547,7 @@ namespace Godot
/// <summary>
/// Returns the result of the spherical linear interpolation between
- /// this vector and `to` by amount `weight`.
+ /// this vector and <paramref name="to"/> by amount <paramref name="weight"/>.
///
/// Note: Both vectors must be normalized.
/// </summary>
@@ -534,7 +563,7 @@ namespace Godot
}
if (!to.IsNormalized())
{
- throw new InvalidOperationException("Vector3.Slerp: `to` is not normalized.");
+ throw new InvalidOperationException($"Vector3.Slerp: `{nameof(to)}` is not normalized.");
}
#endif
real_t theta = AngleTo(to);
@@ -542,17 +571,17 @@ namespace Godot
}
/// <summary>
- /// Returns this vector slid along a plane defined by the given normal.
+ /// Returns this vector slid along a plane defined by the given <paramref name="normal"/>.
/// </summary>
/// <param name="normal">The normal vector defining the plane to slide on.</param>
/// <returns>The slid vector.</returns>
public Vector3 Slide(Vector3 normal)
{
- return this - normal * Dot(normal);
+ return this - (normal * Dot(normal));
}
/// <summary>
- /// Returns this vector with each component snapped to the nearest multiple of `step`.
+ /// Returns this vector with each component snapped to the nearest multiple of <paramref name="step"/>.
/// This can also be used to round to an arbitrary number of decimals.
/// </summary>
/// <param name="step">A vector value representing the step size to snap to.</param>
@@ -570,10 +599,10 @@ namespace Godot
/// <summary>
/// Returns a diagonal matrix with the vector as main diagonal.
///
- /// This is equivalent to a Basis with no rotation or shearing and
+ /// This is equivalent to a <see cref="Basis"/> with no rotation or shearing and
/// this vector's components set as the scale.
/// </summary>
- /// <returns>A Basis with the vector as its main diagonal.</returns>
+ /// <returns>A <see cref="Basis"/> with the vector as its main diagonal.</returns>
public Basis ToDiagonalMatrix()
{
return new Basis(
@@ -596,54 +625,54 @@ namespace Godot
private static readonly Vector3 _back = new Vector3(0, 0, 1);
/// <summary>
- /// Zero vector, a vector with all components set to `0`.
+ /// Zero vector, a vector with all components set to <c>0</c>.
/// </summary>
- /// <value>Equivalent to `new Vector3(0, 0, 0)`</value>
+ /// <value>Equivalent to <c>new Vector3(0, 0, 0)</c>.</value>
public static Vector3 Zero { get { return _zero; } }
/// <summary>
- /// One vector, a vector with all components set to `1`.
+ /// One vector, a vector with all components set to <c>1</c>.
/// </summary>
- /// <value>Equivalent to `new Vector3(1, 1, 1)`</value>
+ /// <value>Equivalent to <c>new Vector3(1, 1, 1)</c>.</value>
public static Vector3 One { get { return _one; } }
/// <summary>
- /// Infinity vector, a vector with all components set to `Mathf.Inf`.
+ /// Infinity vector, a vector with all components set to <see cref="Mathf.Inf"/>.
/// </summary>
- /// <value>Equivalent to `new Vector3(Mathf.Inf, Mathf.Inf, Mathf.Inf)`</value>
+ /// <value>Equivalent to <c>new Vector3(Mathf.Inf, Mathf.Inf, Mathf.Inf)</c>.</value>
public static Vector3 Inf { get { return _inf; } }
/// <summary>
/// Up unit vector.
/// </summary>
- /// <value>Equivalent to `new Vector3(0, 1, 0)`</value>
+ /// <value>Equivalent to <c>new Vector3(0, 1, 0)</c>.</value>
public static Vector3 Up { get { return _up; } }
/// <summary>
/// Down unit vector.
/// </summary>
- /// <value>Equivalent to `new Vector3(0, -1, 0)`</value>
+ /// <value>Equivalent to <c>new Vector3(0, -1, 0)</c>.</value>
public static Vector3 Down { get { return _down; } }
/// <summary>
/// Right unit vector. Represents the local direction of right,
/// and the global direction of east.
/// </summary>
- /// <value>Equivalent to `new Vector3(1, 0, 0)`</value>
+ /// <value>Equivalent to <c>new Vector3(1, 0, 0)</c>.</value>
public static Vector3 Right { get { return _right; } }
/// <summary>
/// Left unit vector. Represents the local direction of left,
/// and the global direction of west.
/// </summary>
- /// <value>Equivalent to `new Vector3(-1, 0, 0)`</value>
+ /// <value>Equivalent to <c>new Vector3(-1, 0, 0)</c>.</value>
public static Vector3 Left { get { return _left; } }
/// <summary>
/// Forward unit vector. Represents the local direction of forward,
/// and the global direction of north.
/// </summary>
- /// <value>Equivalent to `new Vector3(0, 0, -1)`</value>
+ /// <value>Equivalent to <c>new Vector3(0, 0, -1)</c>.</value>
public static Vector3 Forward { get { return _forward; } }
/// <summary>
/// Back unit vector. Represents the local direction of back,
/// and the global direction of south.
/// </summary>
- /// <value>Equivalent to `new Vector3(0, 0, 1)`</value>
+ /// <value>Equivalent to <c>new Vector3(0, 0, 1)</c>.</value>
public static Vector3 Back { get { return _back; } }
/// <summary>
@@ -812,6 +841,11 @@ namespace Godot
return left.x > right.x;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this vector and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the vector and the other object are equal.</returns>
public override bool Equals(object obj)
{
if (obj is Vector3)
@@ -822,14 +856,19 @@ namespace Godot
return false;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this vector and <paramref name="other"/> are equal
+ /// </summary>
+ /// <param name="other">The other vector to compare.</param>
+ /// <returns>Whether or not the vectors are equal.</returns>
public bool Equals(Vector3 other)
{
return x == other.x && y == other.y && z == other.z;
}
/// <summary>
- /// Returns true if this vector and `other` are approximately equal, by running
- /// <see cref="Mathf.IsEqualApprox(real_t, real_t)"/> on each component.
+ /// Returns <see langword="true"/> if this vector and <paramref name="other"/> are approximately equal,
+ /// by running <see cref="Mathf.IsEqualApprox(real_t, real_t)"/> on each component.
/// </summary>
/// <param name="other">The other vector to compare.</param>
/// <returns>Whether or not the vectors are approximately equal.</returns>
@@ -838,16 +877,28 @@ namespace Godot
return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y) && Mathf.IsEqualApprox(z, other.z);
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="Vector3"/>.
+ /// </summary>
+ /// <returns>A hash code for this vector.</returns>
public override int GetHashCode()
{
return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="Vector3"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this vector.</returns>
public override string ToString()
{
return $"({x}, {y}, {z})";
}
+ /// <summary>
+ /// Converts this <see cref="Vector3"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this vector.</returns>
public string ToString(string format)
{
return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)})";
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
index c96a7cf1b0..2a7771cdfc 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
@@ -21,28 +21,46 @@ namespace Godot
/// </summary>
public enum Axis
{
+ /// <summary>
+ /// The vector's X axis.
+ /// </summary>
X = 0,
+ /// <summary>
+ /// The vector's Y axis.
+ /// </summary>
Y,
+ /// <summary>
+ /// The vector's Z axis.
+ /// </summary>
Z
}
/// <summary>
- /// The vector's X component. Also accessible by using the index position `[0]`.
+ /// The vector's X component. Also accessible by using the index position <c>[0]</c>.
/// </summary>
public int x;
+
/// <summary>
- /// The vector's Y component. Also accessible by using the index position `[1]`.
+ /// The vector's Y component. Also accessible by using the index position <c>[1]</c>.
/// </summary>
public int y;
+
/// <summary>
- /// The vector's Z component. Also accessible by using the index position `[2]`.
+ /// The vector's Z component. Also accessible by using the index position <c>[2]</c>.
/// </summary>
public int z;
/// <summary>
- /// Access vector components using their index.
+ /// Access vector components using their <paramref name="index"/>.
/// </summary>
- /// <value>`[0]` is equivalent to `.x`, `[1]` is equivalent to `.y`, `[2]` is equivalent to `.z`.</value>
+ /// <exception cref="IndexOutOfRangeException">
+ /// Thrown when the given the <paramref name="index"/> is not 0, 1 or 2.
+ /// </exception>
+ /// <value>
+ /// <c>[0]</c> is equivalent to <see cref="x"/>,
+ /// <c>[1]</c> is equivalent to <see cref="y"/>,
+ /// <c>[2]</c> is equivalent to <see cref="z"/>.
+ /// </value>
public int this[int index]
{
get
@@ -89,7 +107,7 @@ namespace Godot
/// <summary>
/// Returns a new vector with all components clamped between the
- /// components of `min` and `max` using
+ /// components of <paramref name="min"/> and <paramref name="max"/> using
/// <see cref="Mathf.Clamp(int, int, int)"/>.
/// </summary>
/// <param name="min">The vector with minimum allowed values.</param>
@@ -106,7 +124,7 @@ namespace Godot
}
/// <summary>
- /// Returns the squared distance between this vector and `b`.
+ /// Returns the squared distance between this vector and <paramref name="b"/>.
/// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
/// you need to compare vectors or need the squared distance for some formula.
/// </summary>
@@ -118,8 +136,9 @@ namespace Godot
}
/// <summary>
- /// Returns the distance between this vector and `b`.
+ /// Returns the distance between this vector and <paramref name="b"/>.
/// </summary>
+ /// <seealso cref="DistanceSquaredTo(Vector3i)"/>
/// <param name="b">The other vector to use.</param>
/// <returns>The distance between the two vectors.</returns>
public real_t DistanceTo(Vector3i b)
@@ -128,7 +147,7 @@ namespace Godot
}
/// <summary>
- /// Returns the dot product of this vector and `b`.
+ /// Returns the dot product of this vector and <paramref name="b"/>.
/// </summary>
/// <param name="b">The other vector to use.</param>
/// <returns>The dot product of the two vectors.</returns>
@@ -140,6 +159,7 @@ namespace Godot
/// <summary>
/// Returns the length (magnitude) of this vector.
/// </summary>
+ /// <seealso cref="LengthSquared"/>
/// <returns>The length of this vector.</returns>
public real_t Length()
{
@@ -186,10 +206,13 @@ namespace Godot
}
/// <summary>
- /// Returns a vector composed of the <see cref="Mathf.PosMod(int, int)"/> of this vector's components and `mod`.
+ /// Returns a vector composed of the <see cref="Mathf.PosMod(int, int)"/> of this vector's components
+ /// and <paramref name="mod"/>.
/// </summary>
/// <param name="mod">A value representing the divisor of the operation.</param>
- /// <returns>A vector with each component <see cref="Mathf.PosMod(int, int)"/> by `mod`.</returns>
+ /// <returns>
+ /// A vector with each component <see cref="Mathf.PosMod(int, int)"/> by <paramref name="mod"/>.
+ /// </returns>
public Vector3i PosMod(int mod)
{
Vector3i v = this;
@@ -200,10 +223,13 @@ namespace Godot
}
/// <summary>
- /// Returns a vector composed of the <see cref="Mathf.PosMod(int, int)"/> of this vector's components and `modv`'s components.
+ /// Returns a vector composed of the <see cref="Mathf.PosMod(int, int)"/> of this vector's components
+ /// and <paramref name="modv"/>'s components.
/// </summary>
/// <param name="modv">A vector representing the divisors of the operation.</param>
- /// <returns>A vector with each component <see cref="Mathf.PosMod(int, int)"/> by `modv`'s components.</returns>
+ /// <returns>
+ /// A vector with each component <see cref="Mathf.PosMod(int, int)"/> by <paramref name="modv"/>'s components.
+ /// </returns>
public Vector3i PosMod(Vector3i modv)
{
Vector3i v = this;
@@ -218,7 +244,7 @@ namespace Godot
/// on the signs of this vector's components, or zero if the component is zero,
/// by calling <see cref="Mathf.Sign(int)"/> on each component.
/// </summary>
- /// <returns>A vector with all components as either `1`, `-1`, or `0`.</returns>
+ /// <returns>A vector with all components as either <c>1</c>, <c>-1</c>, or <c>0</c>.</returns>
public Vector3i Sign()
{
Vector3i v = this;
@@ -240,49 +266,49 @@ namespace Godot
private static readonly Vector3i _back = new Vector3i(0, 0, 1);
/// <summary>
- /// Zero vector, a vector with all components set to `0`.
+ /// Zero vector, a vector with all components set to <c>0</c>.
/// </summary>
- /// <value>Equivalent to `new Vector3i(0, 0, 0)`</value>
+ /// <value>Equivalent to <c>new Vector3i(0, 0, 0)</c>.</value>
public static Vector3i Zero { get { return _zero; } }
/// <summary>
- /// One vector, a vector with all components set to `1`.
+ /// One vector, a vector with all components set to <c>1</c>.
/// </summary>
- /// <value>Equivalent to `new Vector3i(1, 1, 1)`</value>
+ /// <value>Equivalent to <c>new Vector3i(1, 1, 1)</c>.</value>
public static Vector3i One { get { return _one; } }
/// <summary>
/// Up unit vector.
/// </summary>
- /// <value>Equivalent to `new Vector3i(0, 1, 0)`</value>
+ /// <value>Equivalent to <c>new Vector3i(0, 1, 0)</c>.</value>
public static Vector3i Up { get { return _up; } }
/// <summary>
/// Down unit vector.
/// </summary>
- /// <value>Equivalent to `new Vector3i(0, -1, 0)`</value>
+ /// <value>Equivalent to <c>new Vector3i(0, -1, 0)</c>.</value>
public static Vector3i Down { get { return _down; } }
/// <summary>
/// Right unit vector. Represents the local direction of right,
/// and the global direction of east.
/// </summary>
- /// <value>Equivalent to `new Vector3i(1, 0, 0)`</value>
+ /// <value>Equivalent to <c>new Vector3i(1, 0, 0)</c>.</value>
public static Vector3i Right { get { return _right; } }
/// <summary>
/// Left unit vector. Represents the local direction of left,
/// and the global direction of west.
/// </summary>
- /// <value>Equivalent to `new Vector3i(-1, 0, 0)`</value>
+ /// <value>Equivalent to <c>new Vector3i(-1, 0, 0)</c>.</value>
public static Vector3i Left { get { return _left; } }
/// <summary>
/// Forward unit vector. Represents the local direction of forward,
/// and the global direction of north.
/// </summary>
- /// <value>Equivalent to `new Vector3i(0, 0, -1)`</value>
+ /// <value>Equivalent to <c>new Vector3i(0, 0, -1)</c>.</value>
public static Vector3i Forward { get { return _forward; } }
/// <summary>
/// Back unit vector. Represents the local direction of back,
/// and the global direction of south.
/// </summary>
- /// <value>Equivalent to `new Vector3i(0, 0, 1)`</value>
+ /// <value>Equivalent to <c>new Vector3i(0, 0, 1)</c>.</value>
public static Vector3i Back { get { return _back; } }
/// <summary>
@@ -479,16 +505,29 @@ namespace Godot
return left.x > right.x;
}
+ /// <summary>
+ /// Converts this <see cref="Vector3i"/> to a <see cref="Vector3"/>.
+ /// </summary>
+ /// <param name="value">The vector to convert.</param>
public static implicit operator Vector3(Vector3i value)
{
return new Vector3(value.x, value.y, value.z);
}
+ /// <summary>
+ /// Converts a <see cref="Vector3"/> to a <see cref="Vector3i"/>.
+ /// </summary>
+ /// <param name="value">The vector to convert.</param>
public static explicit operator Vector3i(Vector3 value)
{
return new Vector3i(value);
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this vector and <paramref name="obj"/> are equal.
+ /// </summary>
+ /// <param name="obj">The other object to compare.</param>
+ /// <returns>Whether or not the vector and the other object are equal.</returns>
public override bool Equals(object obj)
{
if (obj is Vector3i)
@@ -499,21 +538,38 @@ namespace Godot
return false;
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this vector and <paramref name="other"/> are equal
+ /// </summary>
+ /// <param name="other">The other vector to compare.</param>
+ /// <returns>Whether or not the vectors are equal.</returns>
public bool Equals(Vector3i other)
{
return x == other.x && y == other.y && z == other.z;
}
+ /// <summary>
+ /// Serves as the hash function for <see cref="Vector3i"/>.
+ /// </summary>
+ /// <returns>A hash code for this vector.</returns>
public override int GetHashCode()
{
return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode();
}
+ /// <summary>
+ /// Converts this <see cref="Vector3i"/> to a string.
+ /// </summary>
+ /// <returns>A string representation of this vector.</returns>
public override string ToString()
{
return $"({x}, {y}, {z})";
}
+ /// <summary>
+ /// Converts this <see cref="Vector3i"/> to a string with the given <paramref name="format"/>.
+ /// </summary>
+ /// <returns>A string representation of this vector.</returns>
public string ToString(string format)
{
return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)})";
diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
index 195d766c1d..55d0b392fa 100644
--- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
+++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
@@ -138,81 +138,75 @@
<constant name="MATH_DB2LINEAR" value="40" enum="BuiltinFunc">
Convert the input from decibel volume to linear volume.
</constant>
- <constant name="MATH_POLAR2CARTESIAN" value="41" enum="BuiltinFunc">
- Converts a 2D point expressed in the polar coordinate system (a distance from the origin [code]r[/code] and an angle [code]th[/code]) to the cartesian coordinate system (X and Y axis).
+ <constant name="MATH_WRAP" value="41" enum="BuiltinFunc">
</constant>
- <constant name="MATH_CARTESIAN2POLAR" value="42" enum="BuiltinFunc">
- Converts a 2D point expressed in the cartesian coordinate system (X and Y axis) to the polar coordinate system (a distance from the origin and an angle).
+ <constant name="MATH_WRAPF" value="42" enum="BuiltinFunc">
</constant>
- <constant name="MATH_WRAP" value="43" enum="BuiltinFunc">
- </constant>
- <constant name="MATH_WRAPF" value="44" enum="BuiltinFunc">
- </constant>
- <constant name="LOGIC_MAX" value="45" enum="BuiltinFunc">
+ <constant name="LOGIC_MAX" value="43" enum="BuiltinFunc">
Return the greater of the two numbers, also known as their maximum.
</constant>
- <constant name="LOGIC_MIN" value="46" enum="BuiltinFunc">
+ <constant name="LOGIC_MIN" value="44" enum="BuiltinFunc">
Return the lesser of the two numbers, also known as their minimum.
</constant>
- <constant name="LOGIC_CLAMP" value="47" enum="BuiltinFunc">
+ <constant name="LOGIC_CLAMP" value="45" enum="BuiltinFunc">
Return the input clamped inside the given range, ensuring the result is never outside it. Equivalent to [code]min(max(input, range_low), range_high)[/code].
</constant>
- <constant name="LOGIC_NEAREST_PO2" value="48" enum="BuiltinFunc">
+ <constant name="LOGIC_NEAREST_PO2" value="46" enum="BuiltinFunc">
Return the nearest power of 2 to the input.
</constant>
- <constant name="OBJ_WEAKREF" value="49" enum="BuiltinFunc">
+ <constant name="OBJ_WEAKREF" value="47" enum="BuiltinFunc">
Create a [WeakRef] from the input.
</constant>
- <constant name="TYPE_CONVERT" value="50" enum="BuiltinFunc">
+ <constant name="TYPE_CONVERT" value="48" enum="BuiltinFunc">
Convert between types.
</constant>
- <constant name="TYPE_OF" value="51" enum="BuiltinFunc">
+ <constant name="TYPE_OF" value="49" enum="BuiltinFunc">
Return the type of the input as an integer. Check [enum Variant.Type] for the integers that might be returned.
</constant>
- <constant name="TYPE_EXISTS" value="52" enum="BuiltinFunc">
+ <constant name="TYPE_EXISTS" value="50" enum="BuiltinFunc">
Checks if a type is registered in the [ClassDB].
</constant>
- <constant name="TEXT_CHAR" value="53" enum="BuiltinFunc">
+ <constant name="TEXT_CHAR" value="51" enum="BuiltinFunc">
Return a character with the given ascii value.
</constant>
- <constant name="TEXT_STR" value="54" enum="BuiltinFunc">
+ <constant name="TEXT_STR" value="52" enum="BuiltinFunc">
Convert the input to a string.
</constant>
- <constant name="TEXT_PRINT" value="55" enum="BuiltinFunc">
+ <constant name="TEXT_PRINT" value="53" enum="BuiltinFunc">
Print the given string to the output window.
</constant>
- <constant name="TEXT_PRINTERR" value="56" enum="BuiltinFunc">
+ <constant name="TEXT_PRINTERR" value="54" enum="BuiltinFunc">
Print the given string to the standard error output.
</constant>
- <constant name="TEXT_PRINTRAW" value="57" enum="BuiltinFunc">
+ <constant name="TEXT_PRINTRAW" value="55" enum="BuiltinFunc">
Print the given string to the standard output, without adding a newline.
</constant>
- <constant name="VAR_TO_STR" value="58" enum="BuiltinFunc">
+ <constant name="VAR_TO_STR" value="56" enum="BuiltinFunc">
Serialize a [Variant] to a string.
</constant>
- <constant name="STR_TO_VAR" value="59" enum="BuiltinFunc">
+ <constant name="STR_TO_VAR" value="57" enum="BuiltinFunc">
Deserialize a [Variant] from a string serialized using [constant VAR_TO_STR].
</constant>
- <constant name="VAR_TO_BYTES" value="60" enum="BuiltinFunc">
+ <constant name="VAR_TO_BYTES" value="58" enum="BuiltinFunc">
Serialize a [Variant] to a [PackedByteArray].
</constant>
- <constant name="BYTES_TO_VAR" value="61" enum="BuiltinFunc">
+ <constant name="BYTES_TO_VAR" value="59" enum="BuiltinFunc">
Deserialize a [Variant] from a [PackedByteArray] serialized using [constant VAR_TO_BYTES].
</constant>
- <constant name="MATH_SMOOTHSTEP" value="62" enum="BuiltinFunc">
+ <constant name="MATH_SMOOTHSTEP" value="60" enum="BuiltinFunc">
Return a number smoothly interpolated between the first two inputs, based on the third input. Similar to [constant MATH_LERP], but interpolates faster at the beginning and slower at the end. Using Hermite interpolation formula:
[codeblock]
var t = clamp((weight - from) / (to - from), 0.0, 1.0)
return t * t * (3.0 - 2.0 * t)
[/codeblock]
</constant>
- <constant name="MATH_POSMOD" value="63" enum="BuiltinFunc">
+ <constant name="MATH_POSMOD" value="61" enum="BuiltinFunc">
</constant>
- <constant name="MATH_LERP_ANGLE" value="64" enum="BuiltinFunc">
+ <constant name="MATH_LERP_ANGLE" value="62" enum="BuiltinFunc">
</constant>
- <constant name="TEXT_ORD" value="65" enum="BuiltinFunc">
+ <constant name="TEXT_ORD" value="63" enum="BuiltinFunc">
</constant>
- <constant name="FUNC_MAX" value="66" enum="BuiltinFunc">
+ <constant name="FUNC_MAX" value="64" enum="BuiltinFunc">
Represents the size of the [enum BuiltinFunc] enum.
</constant>
</constants>
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index c61c3ae272..2bd7220d15 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -79,8 +79,6 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
"rad2deg",
"linear2db",
"db2linear",
- "polar2cartesian",
- "cartesian2polar",
"wrapi",
"wrapf",
"max",
@@ -194,8 +192,6 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
case MATH_SNAPPED:
case MATH_RANDF_RANGE:
case MATH_RANDI_RANGE:
- case MATH_POLAR2CARTESIAN:
- case MATH_CARTESIAN2POLAR:
case LOGIC_MAX:
case LOGIC_MIN:
case TYPE_CONVERT:
@@ -381,20 +377,6 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
case MATH_DB2LINEAR: {
return PropertyInfo(Variant::FLOAT, "db");
} break;
- case MATH_POLAR2CARTESIAN: {
- if (p_idx == 0) {
- return PropertyInfo(Variant::FLOAT, "r");
- } else {
- return PropertyInfo(Variant::FLOAT, "th");
- }
- } break;
- case MATH_CARTESIAN2POLAR: {
- if (p_idx == 0) {
- return PropertyInfo(Variant::FLOAT, "x");
- } else {
- return PropertyInfo(Variant::FLOAT, "y");
- }
- } break;
case MATH_WRAP: {
if (p_idx == 0) {
return PropertyInfo(Variant::INT, "value");
@@ -553,10 +535,6 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
case MATH_DB2LINEAR: {
t = Variant::FLOAT;
} break;
- case MATH_POLAR2CARTESIAN:
- case MATH_CARTESIAN2POLAR: {
- t = Variant::VECTOR2;
- } break;
case MATH_WRAP: {
t = Variant::INT;
} break;
@@ -874,20 +852,6 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
VALIDATE_ARG_NUM(0);
*r_return = Math::db2linear((double)*p_inputs[0]);
} break;
- case VisualScriptBuiltinFunc::MATH_POLAR2CARTESIAN: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- double r = *p_inputs[0];
- double th = *p_inputs[1];
- *r_return = Vector2(r * Math::cos(th), r * Math::sin(th));
- } break;
- case VisualScriptBuiltinFunc::MATH_CARTESIAN2POLAR: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- double x = *p_inputs[0];
- double y = *p_inputs[1];
- *r_return = Vector2(Math::sqrt(x * x + y * y), Math::atan2(y, x));
- } break;
case VisualScriptBuiltinFunc::MATH_WRAP: {
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
@@ -1229,8 +1193,6 @@ void VisualScriptBuiltinFunc::_bind_methods() {
BIND_ENUM_CONSTANT(MATH_RAD2DEG);
BIND_ENUM_CONSTANT(MATH_LINEAR2DB);
BIND_ENUM_CONSTANT(MATH_DB2LINEAR);
- BIND_ENUM_CONSTANT(MATH_POLAR2CARTESIAN);
- BIND_ENUM_CONSTANT(MATH_CARTESIAN2POLAR);
BIND_ENUM_CONSTANT(MATH_WRAP);
BIND_ENUM_CONSTANT(MATH_WRAPF);
BIND_ENUM_CONSTANT(LOGIC_MAX);
@@ -1320,8 +1282,6 @@ void register_visual_script_builtin_func_node() {
VisualScriptLanguage::singleton->add_register_func("functions/built_in/rad2deg", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RAD2DEG>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/linear2db", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LINEAR2DB>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/db2linear", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DB2LINEAR>);
- VisualScriptLanguage::singleton->add_register_func("functions/built_in/polar2cartesian", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_POLAR2CARTESIAN>);
- VisualScriptLanguage::singleton->add_register_func("functions/built_in/cartesian2polar", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_CARTESIAN2POLAR>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/wrapi", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_WRAP>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/wrapf", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_WRAPF>);
diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h
index f59a7a0f0c..26abc1e479 100644
--- a/modules/visual_script/visual_script_builtin_funcs.h
+++ b/modules/visual_script/visual_script_builtin_funcs.h
@@ -79,8 +79,6 @@ public:
MATH_RAD2DEG,
MATH_LINEAR2DB,
MATH_DB2LINEAR,
- MATH_POLAR2CARTESIAN,
- MATH_CARTESIAN2POLAR,
MATH_WRAP,
MATH_WRAPF,
LOGIC_MAX,
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 7dfb4fa270..ab32aae7aa 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -311,6 +311,8 @@ public:
virtual void tag_saved_version() override;
virtual void reload(bool p_soft) override;
virtual Array get_breakpoints() override;
+ virtual void set_breakpoint(int p_line, bool p_enable) override{};
+ virtual void clear_breakpoints() override{};
virtual void add_callback(const String &p_function, PackedStringArray p_args) override;
virtual void update_settings() override;
virtual bool show_members_overview() override;
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 5c1c3281a6..6b4a326ba7 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -977,6 +977,11 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
Vector<int> feature_versions;
if (xr_mode_index == 1 /* XRMode.OVR */) {
+ // Set degrees of freedom
+ feature_names.push_back("android.hardware.vr.headtracking");
+ feature_required_list.push_back(true);
+ feature_versions.push_back(1);
+
// Check for hand tracking
int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required
if (hand_tracking_index > 0) {
diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp
index b9e28a7937..6fbdf73cd0 100644
--- a/platform/android/export/gradle_export_util.cpp
+++ b/platform/android/export/gradle_export_util.cpp
@@ -197,6 +197,8 @@ String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset) {
String manifest_xr_features;
bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1;
if (uses_xr) {
+ manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"android.hardware.vr.headtracking\" android:required=\"true\" android:version=\"1\" />\n";
+
int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required
if (hand_tracking_index == 1) {
manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"oculus.software.handtracking\" android:required=\"false\" />\n";
@@ -228,7 +230,9 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
"tools:replace=\"android:screenOrientation\" "
"android:screenOrientation=\"%s\">\n",
orientation);
- if (!uses_xr) {
+ if (uses_xr) {
+ manifest_activity_text += " <meta-data tools:node=\"replace\" android:name=\"com.oculus.vr.focusaware\" android:value=\"true\" />\n";
+ } else {
manifest_activity_text += " <meta-data tools:node=\"remove\" android:name=\"com.oculus.vr.focusaware\" />\n";
}
manifest_activity_text += " </activity>\n";
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml
index 00e01884cf..d7bf6cef30 100644
--- a/platform/android/java/app/AndroidManifest.xml
+++ b/platform/android/java/app/AndroidManifest.xml
@@ -49,6 +49,10 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
+
+ <!-- Enable access to OpenXR on Oculus mobile devices, no-op on other Android
+ platforms. -->
+ <category android:name="com.oculus.intent.category.VR" />
</intent-filter>
</activity>
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index 896b169953..70bc73b9ad 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -295,7 +295,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
View pluginView = plugin.onMainCreate(activity);
if (pluginView != null) {
- containerLayout.addView(pluginView);
+ if (plugin.shouldBeOnTop()) {
+ containerLayout.addView(pluginView);
+ } else {
+ containerLayout.addView(pluginView, 0);
+ }
}
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
index 2dc8359615..4536c21ed3 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
@@ -191,6 +191,9 @@ public abstract class GodotPlugin {
* The plugin can return a non-null {@link View} layout in order to add it to the Godot view
* hierarchy.
*
+ * Use shouldBeOnTop() to set whether the plugin's {@link View} should be added on top or behind
+ * the main Godot view.
+ *
* @see Activity#onCreate(Bundle)
* @return the plugin's view to be included; null if no views should be included.
*/
@@ -311,6 +314,17 @@ public abstract class GodotPlugin {
}
/**
+ * Returns whether the plugin's {@link View} returned in onMainCreate() should be placed on
+ * top of the main Godot view.
+ *
+ * Returning false causes the plugin's {@link View} to be placed behind, which can be useful
+ * when used with transparency in order to let the Godot view handle inputs.
+ */
+ public boolean shouldBeOnTop() {
+ return true;
+ }
+
+ /**
* Runs the specified action on the UI thread. If the current thread is the UI
* thread, then the action is executed immediately. If the current thread is
* not the UI thread, the action is posted to the event queue of the UI thread.
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 43b7d7c1e0..f037d75fbd 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -190,6 +190,8 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
[wd.window_object setContentMinSize:NSMakeSize(0, 0)];
[wd.window_object setContentMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
+ // Force window resize event.
+ [self windowDidResize:notification];
}
- (void)windowDidExitFullScreen:(NSNotification *)notification {
@@ -217,6 +219,8 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
if (wd.on_top) {
[wd.window_object setLevel:NSFloatingWindowLevel];
}
+ // Force window resize event.
+ [self windowDidResize:notification];
}
- (void)windowDidChangeBackingProperties:(NSNotification *)notification {
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index d93107df2d..411fb2e1f0 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -34,11 +34,13 @@
Size2 CheckBox::get_icon_size() const {
Ref<Texture2D> checked = Control::get_theme_icon(SNAME("checked"));
- Ref<Texture2D> checked_disabled = Control::get_theme_icon(SNAME("checked_disabled"));
Ref<Texture2D> unchecked = Control::get_theme_icon(SNAME("unchecked"));
- Ref<Texture2D> unchecked_disabled = Control::get_theme_icon(SNAME("unchecked_disabled"));
Ref<Texture2D> radio_checked = Control::get_theme_icon(SNAME("radio_checked"));
Ref<Texture2D> radio_unchecked = Control::get_theme_icon(SNAME("radio_unchecked"));
+ Ref<Texture2D> checked_disabled = Control::get_theme_icon(SNAME("checked_disabled"));
+ Ref<Texture2D> unchecked_disabled = Control::get_theme_icon(SNAME("unchecked_disabled"));
+ Ref<Texture2D> radio_checked_disabled = Control::get_theme_icon(SNAME("radio_checked_disabled"));
+ Ref<Texture2D> radio_unchecked_disabled = Control::get_theme_icon(SNAME("radio_unchecked_disabled"));
Size2 tex_size = Size2(0, 0);
if (!checked.is_null()) {
@@ -53,6 +55,18 @@ Size2 CheckBox::get_icon_size() const {
if (!radio_unchecked.is_null()) {
tex_size = Size2(MAX(tex_size.width, radio_unchecked->get_width()), MAX(tex_size.height, radio_unchecked->get_height()));
}
+ if (!checked_disabled.is_null()) {
+ tex_size = Size2(MAX(tex_size.width, checked_disabled->get_width()), MAX(tex_size.height, checked_disabled->get_height()));
+ }
+ if (!unchecked_disabled.is_null()) {
+ tex_size = Size2(MAX(tex_size.width, unchecked_disabled->get_width()), MAX(tex_size.height, unchecked_disabled->get_height()));
+ }
+ if (!radio_checked_disabled.is_null()) {
+ tex_size = Size2(MAX(tex_size.width, radio_checked_disabled->get_width()), MAX(tex_size.height, radio_checked_disabled->get_height()));
+ }
+ if (!radio_unchecked_disabled.is_null()) {
+ tex_size = Size2(MAX(tex_size.width, radio_unchecked_disabled->get_width()), MAX(tex_size.height, radio_unchecked_disabled->get_height()));
+ }
return tex_size;
}
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 3605842224..d9acbeb828 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -674,7 +674,7 @@ void LineEdit::_notification(int p_what) {
int y_ofs = style->get_offset().y + (y_area - text_height) / 2;
Color selection_color = get_theme_color(SNAME("selection_color"));
- Color font_color = is_editable() ? get_theme_color(SNAME("font_color")) : get_theme_color(SNAME("font_uneditable_color"));
+ Color font_color = get_theme_color(is_editable() ? SNAME("font_color") : SNAME("font_uneditable_color"));
Color font_selected_color = get_theme_color(SNAME("font_selected_color"));
Color caret_color = get_theme_color(SNAME("caret_color"));
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 481e211eb3..845a2ec6c7 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -434,14 +434,14 @@ void TabContainer::_notification(int p_what) {
}
int tab_width = tab_widths[i];
- if (get_tab_disabled(index)) {
+ if (index == current) {
+ x_current = x;
+ } else if (get_tab_disabled(index)) {
if (rtl) {
_draw_tab(tab_disabled, font_disabled_color, index, size.width - (tabs_ofs_cache + x) - tab_width);
} else {
_draw_tab(tab_disabled, font_disabled_color, index, tabs_ofs_cache + x);
}
- } else if (index == current) {
- x_current = x;
} else {
if (rtl) {
_draw_tab(tab_unselected, font_unselected_color, index, size.width - (tabs_ofs_cache + x) - tab_width);
@@ -459,12 +459,13 @@ void TabContainer::_notification(int p_what) {
panel->draw(canvas, Rect2(0, header_height, size.width, size.height - header_height));
}
- // Draw selected tab in front. only draw selected tab when it's in visible range.
+ // Draw selected tab in front. Only draw selected tab when it's in visible range.
if (tabs.size() > 0 && current - first_tab_cache < tab_widths.size() && current >= first_tab_cache) {
+ Ref<StyleBox> current_style_box = get_tab_disabled(current) ? tab_disabled : tab_selected;
if (rtl) {
- _draw_tab(tab_selected, font_selected_color, current, size.width - (tabs_ofs_cache + x_current) - tab_widths[current]);
+ _draw_tab(current_style_box, font_selected_color, current, size.width - (tabs_ofs_cache + x_current) - tab_widths[current]);
} else {
- _draw_tab(tab_selected, font_selected_color, current, tabs_ofs_cache + x_current);
+ _draw_tab(current_style_box, font_selected_color, current, tabs_ofs_cache + x_current);
}
}
@@ -640,8 +641,8 @@ void TabContainer::_on_mouse_exited() {
int TabContainer::_get_tab_width(int p_index) const {
ERR_FAIL_INDEX_V(p_index, get_tab_count(), 0);
- Control *control = Object::cast_to<Control>(_get_tabs()[p_index]);
- if (!control || control->is_set_as_top_level() || get_tab_hidden(p_index)) {
+ Control *control = get_tab_control(p_index);
+ if (!control || get_tab_hidden(p_index)) {
return 0;
}
diff --git a/scene/gui/texture_progress_bar.cpp b/scene/gui/texture_progress_bar.cpp
index 5e5dec3579..286f01ee33 100644
--- a/scene/gui/texture_progress_bar.cpp
+++ b/scene/gui/texture_progress_bar.cpp
@@ -100,6 +100,15 @@ Ref<Texture2D> TextureProgressBar::get_progress_texture() const {
return progress;
}
+void TextureProgressBar::set_progress_offset(Point2 p_offset) {
+ progress_offset = p_offset;
+ update();
+}
+
+Point2 TextureProgressBar::get_progress_offset() const {
+ return progress_offset;
+}
+
void TextureProgressBar::set_tint_under(const Color &p_tint) {
tint_under = p_tint;
update();
@@ -360,6 +369,9 @@ void TextureProgressBar::draw_nine_patch_stretched(const Ref<Texture2D> &p_textu
}
}
+ if (p_texture == progress) {
+ dst_rect.position += progress_offset;
+ }
p_texture->get_rect_region(dst_rect, src_rect, dst_rect, src_rect);
RID ci = get_canvas_item();
@@ -403,20 +415,24 @@ void TextureProgressBar::_notification(int p_what) {
Size2 s = progress->get_size();
switch (mode) {
case FILL_LEFT_TO_RIGHT: {
- Rect2 region = Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y));
- draw_texture_rect_region(progress, region, region, tint_progress);
+ Rect2 region = Rect2(progress_offset, Size2(s.x * get_as_ratio(), s.y));
+ Rect2 source = Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y));
+ draw_texture_rect_region(progress, region, source, tint_progress);
} break;
case FILL_RIGHT_TO_LEFT: {
- Rect2 region = Rect2(Point2(s.x - s.x * get_as_ratio(), 0), Size2(s.x * get_as_ratio(), s.y));
- draw_texture_rect_region(progress, region, region, tint_progress);
+ Rect2 region = Rect2(progress_offset + Point2(s.x - s.x * get_as_ratio(), 0), Size2(s.x * get_as_ratio(), s.y));
+ Rect2 source = Rect2(Point2(s.x - s.x * get_as_ratio(), 0), Size2(s.x * get_as_ratio(), s.y));
+ draw_texture_rect_region(progress, region, source, tint_progress);
} break;
case FILL_TOP_TO_BOTTOM: {
- Rect2 region = Rect2(Point2(), Size2(s.x, s.y * get_as_ratio()));
- draw_texture_rect_region(progress, region, region, tint_progress);
+ Rect2 region = Rect2(progress_offset + Point2(), Size2(s.x, s.y * get_as_ratio()));
+ Rect2 source = Rect2(Point2(), Size2(s.x, s.y * get_as_ratio()));
+ draw_texture_rect_region(progress, region, source, tint_progress);
} break;
case FILL_BOTTOM_TO_TOP: {
- Rect2 region = Rect2(Point2(0, s.y - s.y * get_as_ratio()), Size2(s.x, s.y * get_as_ratio()));
- draw_texture_rect_region(progress, region, region, tint_progress);
+ Rect2 region = Rect2(progress_offset + Point2(0, s.y - s.y * get_as_ratio()), Size2(s.x, s.y * get_as_ratio()));
+ Rect2 source = Rect2(Point2(0, s.y - s.y * get_as_ratio()), Size2(s.x, s.y * get_as_ratio()));
+ draw_texture_rect_region(progress, region, source, tint_progress);
} break;
case FILL_CLOCKWISE:
case FILL_COUNTER_CLOCKWISE:
@@ -427,8 +443,9 @@ void TextureProgressBar::_notification(int p_what) {
float val = get_as_ratio() * rad_max_degrees / 360;
if (val == 1) {
- Rect2 region = Rect2(Point2(), s);
- draw_texture_rect(progress, region, false, tint_progress);
+ Rect2 region = Rect2(progress_offset, s);
+ Rect2 source = Rect2(Point2(), s);
+ draw_texture_rect_region(progress, region, source, tint_progress);
} else if (val != 0) {
Array pts;
float direction = mode == FILL_COUNTER_CLOCKWISE ? -1 : 1;
@@ -454,14 +471,14 @@ void TextureProgressBar::_notification(int p_what) {
Vector<Point2> uvs;
Vector<Point2> points;
uvs.push_back(get_relative_center());
- points.push_back(Point2(s.x * get_relative_center().x, s.y * get_relative_center().y));
+ points.push_back(progress_offset + Point2(s.x * get_relative_center().x, s.y * get_relative_center().y));
for (int i = 0; i < pts.size(); i++) {
Point2 uv = unit_val_to_uv(pts[i]);
if (uvs.find(uv) >= 0) {
continue;
}
uvs.push_back(uv);
- points.push_back(Point2(uv.x * s.x, uv.y * s.y));
+ points.push_back(progress_offset + Point2(uv.x * s.x, uv.y * s.y));
}
Vector<Color> colors;
colors.push_back(tint_progress);
@@ -484,17 +501,19 @@ void TextureProgressBar::_notification(int p_what) {
}
} break;
case FILL_BILINEAR_LEFT_AND_RIGHT: {
- Rect2 region = Rect2(Point2(s.x / 2 - s.x * get_as_ratio() / 2, 0), Size2(s.x * get_as_ratio(), s.y));
- draw_texture_rect_region(progress, region, region, tint_progress);
+ Rect2 region = Rect2(progress_offset + Point2(s.x / 2 - s.x * get_as_ratio() / 2, 0), Size2(s.x * get_as_ratio(), s.y));
+ Rect2 source = Rect2(Point2(s.x / 2 - s.x * get_as_ratio() / 2, 0), Size2(s.x * get_as_ratio(), s.y));
+ draw_texture_rect_region(progress, region, source, tint_progress);
} break;
case FILL_BILINEAR_TOP_AND_BOTTOM: {
- Rect2 region = Rect2(Point2(0, s.y / 2 - s.y * get_as_ratio() / 2), Size2(s.x, s.y * get_as_ratio()));
- draw_texture_rect_region(progress, region, region, tint_progress);
+ Rect2 region = Rect2(progress_offset + Point2(0, s.y / 2 - s.y * get_as_ratio() / 2), Size2(s.x, s.y * get_as_ratio()));
+ Rect2 source = Rect2(Point2(0, s.y / 2 - s.y * get_as_ratio() / 2), Size2(s.x, s.y * get_as_ratio()));
+ draw_texture_rect_region(progress, region, source, tint_progress);
} break;
case FILL_MODE_MAX:
break;
default:
- draw_texture_rect_region(progress, Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)), Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)), tint_progress);
+ draw_texture_rect_region(progress, Rect2(progress_offset, Size2(s.x * get_as_ratio(), s.y)), Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)), tint_progress);
}
}
if (over.is_valid()) {
@@ -585,6 +604,9 @@ void TextureProgressBar::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_tint_over", "tint"), &TextureProgressBar::set_tint_over);
ClassDB::bind_method(D_METHOD("get_tint_over"), &TextureProgressBar::get_tint_over);
+ ClassDB::bind_method(D_METHOD("set_texture_progress_offset", "offset"), &TextureProgressBar::set_progress_offset);
+ ClassDB::bind_method(D_METHOD("get_texture_progress_offset"), &TextureProgressBar::get_progress_offset);
+
ClassDB::bind_method(D_METHOD("set_radial_initial_angle", "mode"), &TextureProgressBar::set_radial_initial_angle);
ClassDB::bind_method(D_METHOD("get_radial_initial_angle"), &TextureProgressBar::get_radial_initial_angle);
@@ -604,6 +626,7 @@ void TextureProgressBar::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_under", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_under_texture", "get_under_texture");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_over", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_over_texture", "get_over_texture");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_progress", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_progress_texture", "get_progress_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_progress_offset"), "set_texture_progress_offset", "get_texture_progress_offset");
ADD_PROPERTY(PropertyInfo(Variant::INT, "fill_mode", PROPERTY_HINT_ENUM, "Left to Right,Right to Left,Top to Bottom,Bottom to Top,Clockwise,Counter Clockwise,Bilinear (Left and Right),Bilinear (Top and Bottom),Clockwise and Counter Clockwise"), "set_fill_mode", "get_fill_mode");
ADD_GROUP("Tint", "tint_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_under"), "set_tint_under", "get_tint_under");
diff --git a/scene/gui/texture_progress_bar.h b/scene/gui/texture_progress_bar.h
index d147c43a26..c508f41387 100644
--- a/scene/gui/texture_progress_bar.h
+++ b/scene/gui/texture_progress_bar.h
@@ -61,6 +61,9 @@ public:
void set_fill_mode(int p_fill);
int get_fill_mode();
+ void set_progress_offset(Point2 p_offset);
+ Point2 get_progress_offset() const;
+
void set_radial_initial_angle(float p_angle);
float get_radial_initial_angle();
@@ -100,6 +103,7 @@ public:
private:
FillMode mode = FILL_LEFT_TO_RIGHT;
+ Point2 progress_offset;
float rad_init_angle = 0.0;
float rad_max_degrees = 360.0;
Point2 rad_center_off;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 1fcfce2ea9..ca5a3915d0 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -1497,7 +1497,7 @@ void Window::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "position"), "set_position", "get_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,Fullscreen"), "set_mode", "get_mode");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_screen"), "set_current_screen", "get_current_screen");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen"), "set_current_screen", "get_current_screen");
ADD_GROUP("Flags", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index 611f7c6494..1b730567d9 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -484,7 +484,7 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
if (material_uniform_set != prev_material_uniform_set) {
// Update uniform set.
- if (RD::get_singleton()->uniform_set_is_valid(material_uniform_set)) { // Material may not have a uniform set.
+ if (material_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material_uniform_set)) { // Material may not have a uniform set.
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_uniform_set, MATERIAL_UNIFORM_SET);
}
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index 1b4052b622..276a44bc27 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -1982,7 +1982,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
if (material_uniform_set != prev_material_uniform_set) {
// Update uniform set.
- if (RD::get_singleton()->uniform_set_is_valid(material_uniform_set)) { // Material may not have a uniform set.
+ if (material_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material_uniform_set)) { // Material may not have a uniform set.
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_uniform_set, MATERIAL_UNIFORM_SET);
}
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 6267f684e3..647c348d9f 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1102,7 +1102,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
if (material_data->shader_data->version.is_valid() && material_data->shader_data->valid) {
pipeline_variants = &material_data->shader_data->pipeline_variants;
// Update uniform set.
- if (RD::get_singleton()->uniform_set_is_valid(material_data->uniform_set)) { // Material may not have a uniform set.
+ if (material_data->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material_data->uniform_set)) { // Material may not have a uniform set.
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_data->uniform_set, MATERIAL_UNIFORM_SET);
}
} else {
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index da84f615b2..c388da755c 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -288,7 +288,7 @@ void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_
// Update uniform sets.
{
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, sky_scene_state.uniform_set, 0);
- if (RD::get_singleton()->uniform_set_is_valid(p_uniform_set)) { // Material may not have a uniform set.
+ if (p_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(p_uniform_set)) { // Material may not have a uniform set.
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_uniform_set, 1);
}
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_texture_set, 2);
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 14a5a01054..ec0d25376f 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -4848,7 +4848,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_particles->particles_material_uniform_set, 1);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_particles->collision_textures_uniform_set, 2);
- if (m->uniform_set.is_valid()) {
+ if (m->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(m->uniform_set)) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, m->uniform_set, 3);
}