diff options
Diffstat (limited to 'modules/mono')
22 files changed, 212 insertions, 12 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index bee4e0e1fb..622838b308 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -2807,7 +2807,8 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage GD_MONO_ASSERT_THREAD_ATTACHED; if (p_variant_type == Variant::INT && p_type.type_encoding == MONO_TYPE_VALUETYPE && mono_class_is_enum(p_type.type_class->get_mono_ptr())) { - r_hint = PROPERTY_HINT_ENUM; + MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); + r_hint = GDMonoUtils::Marshal::type_has_flags_attribute(reftype) ? PROPERTY_HINT_FLAGS : PROPERTY_HINT_ENUM; Vector<MonoClassField *> fields = p_type.type_class->get_enum_fields(); @@ -2844,7 +2845,8 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage uint64_t val = GDMonoUtils::unbox_enum_value(val_obj, enum_basetype, r_error); ERR_FAIL_COND_V_MSG(r_error, -1, "Failed to unbox '" + enum_field_name + "' constant enum value."); - if (val != (unsigned int)i) { + unsigned int expected_val = r_hint == PROPERTY_HINT_FLAGS ? 1 << i : i; + if (val != expected_val) { uses_default_values = false; } diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index e602396ede..960d2fe27c 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -1652,7 +1652,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte p_output.append("static "); } - p_output.append(prop_itype->cs_type); + String prop_cs_type = prop_itype->cs_type + _get_generic_type_parameters(*prop_itype, proptype_name.generic_type_parameters); + + p_output.append(prop_cs_type); p_output.append(" "); p_output.append(p_iprop.proxy_name); p_output.append("\n" INDENT2 OPEN_BLOCK); @@ -1762,6 +1764,8 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf "Invalid default value for parameter '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'."); } + String arg_cs_type = arg_type->cs_type + _get_generic_type_parameters(*arg_type, iarg.type.generic_type_parameters); + // Add the current arguments to the signature // If the argument has a default value which is not a constant, we will make it Nullable { @@ -1773,7 +1777,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf arguments_sig += "Nullable<"; } - arguments_sig += arg_type->cs_type; + arguments_sig += arg_cs_type; if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL) { arguments_sig += "> "; @@ -1800,7 +1804,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf String arg_in = iarg.name; arg_in += "_in"; - cs_in_statements += arg_type->cs_type; + cs_in_statements += arg_cs_type; cs_in_statements += " "; cs_in_statements += arg_in; cs_in_statements += " = "; @@ -1820,7 +1824,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf cs_in_statements += " : "; } - String cs_type = arg_type->cs_type; + String cs_type = arg_cs_type; if (cs_type.ends_with("[]")) { cs_type = cs_type.substr(0, cs_type.length() - 2); } @@ -1837,7 +1841,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf // Escape < and > in the attribute default value String param_def_arg = def_arg.replacen("<", "<").replacen(">", ">"); - default_args_doc.append(MEMBER_BEGIN "/// <param name=\"" + param_tag_name + "\">If the parameter is null, then the default value is " + param_def_arg + "</param>"); + default_args_doc.append(MEMBER_BEGIN "/// <param name=\"" + param_tag_name + "\">If the parameter is null, then the default value is <c>" + param_def_arg + "</c>.</param>"); } else { icall_params += arg_type->cs_in.is_empty() ? iarg.name : sformat(arg_type->cs_in, iarg.name); } @@ -1903,7 +1907,9 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf p_output.append("virtual "); } - p_output.append(return_type->cs_type + " "); + String return_cs_type = return_type->cs_type + _get_generic_type_parameters(*return_type, p_imethod.return_type.generic_type_parameters); + + p_output.append(return_cs_type + " "); p_output.append(p_imethod.proxy_name + "("); p_output.append(arguments_sig + ")\n" OPEN_BLOCK_L2); @@ -1914,7 +1920,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf p_output.append("return;\n" CLOSE_BLOCK_L2); } else { p_output.append("return default("); - p_output.append(return_type->cs_type); + p_output.append(return_cs_type); p_output.append(");\n" CLOSE_BLOCK_L2); } @@ -1956,7 +1962,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf } else if (return_type->cs_out.is_empty()) { p_output.append("return " + im_call + "(" + icall_params + ");\n"); } else { - p_output.append(sformat(return_type->cs_out, im_call, icall_params, return_type->cs_type, return_type->im_type_out)); + p_output.append(sformat(return_type->cs_out, im_call, icall_params, return_cs_type, return_type->im_type_out)); p_output.append("\n"); } @@ -2517,6 +2523,42 @@ const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_placehol return &placeholder_types.insert(placeholder.cname, placeholder)->value; } +const String BindingsGenerator::_get_generic_type_parameters(const TypeInterface &p_itype, const List<TypeReference> &p_generic_type_parameters) { + if (p_generic_type_parameters.is_empty()) { + return ""; + } + + ERR_FAIL_COND_V_MSG(p_itype.type_parameter_count != p_generic_type_parameters.size(), "", + "Generic type parameter count mismatch for type '" + p_itype.name + "'." + + " Found " + itos(p_generic_type_parameters.size()) + ", but requires " + + itos(p_itype.type_parameter_count) + "."); + + int i = 0; + String params = "<"; + for (const TypeReference ¶m_type : p_generic_type_parameters) { + const TypeInterface *param_itype = _get_type_or_placeholder(param_type); + + ERR_FAIL_COND_V_MSG(param_itype->is_singleton, "", + "Generic type parameter is a singleton: '" + param_itype->name + "'."); + + if (p_itype.api_type == ClassDB::API_CORE) { + ERR_FAIL_COND_V_MSG(param_itype->api_type == ClassDB::API_EDITOR, "", + "Generic type parameter '" + param_itype->name + "' has type from the editor API." + + " Core API cannot have dependencies on the editor API."); + } + + params += param_itype->cs_type; + if (i < p_generic_type_parameters.size() - 1) { + params += ", "; + } + + i++; + } + params += ">"; + + return params; +} + StringName BindingsGenerator::_get_int_type_name_from_meta(GodotTypeInfo::Metadata p_meta) { switch (p_meta) { case GodotTypeInfo::METADATA_INT_IS_INT8: @@ -2832,6 +2874,9 @@ bool BindingsGenerator::_populate_object_type_interfaces() { ERR_FAIL_COND_V_MSG(bad_reference_hint, false, String() + "Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'." + " Are you returning a reference type by pointer? Method: '" + itype.name + "." + imethod.name + "'."); + } else if (return_info.type == Variant::ARRAY && return_info.hint == PROPERTY_HINT_ARRAY_TYPE) { + imethod.return_type.cname = Variant::get_type_name(return_info.type); + imethod.return_type.generic_type_parameters.push_back(TypeReference(return_info.hint_string)); } else if (return_info.hint == PROPERTY_HINT_RESOURCE_TYPE) { imethod.return_type.cname = return_info.hint_string; } else if (return_info.type == Variant::NIL && return_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { @@ -2861,6 +2906,9 @@ bool BindingsGenerator::_populate_object_type_interfaces() { iarg.type.is_enum = true; } else if (arginfo.class_name != StringName()) { iarg.type.cname = arginfo.class_name; + } else if (arginfo.type == Variant::ARRAY && arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) { + iarg.type.cname = Variant::get_type_name(arginfo.type); + iarg.type.generic_type_parameters.push_back(TypeReference(arginfo.hint_string)); } else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { iarg.type.cname = arginfo.hint_string; } else if (arginfo.type == Variant::NIL) { @@ -2966,6 +3014,9 @@ bool BindingsGenerator::_populate_object_type_interfaces() { iarg.type.is_enum = true; } else if (arginfo.class_name != StringName()) { iarg.type.cname = arginfo.class_name; + } else if (arginfo.type == Variant::ARRAY && arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) { + iarg.type.cname = Variant::get_type_name(arginfo.type); + iarg.type.generic_type_parameters.push_back(TypeReference(arginfo.hint_string)); } else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { iarg.type.cname = arginfo.hint_string; } else if (arginfo.type == Variant::NIL) { @@ -3549,13 +3600,14 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.name = "Array"; itype.cname = itype.name; itype.proxy_name = itype.name; + itype.type_parameter_count = 1; itype.c_out = "\treturn memnew(Array(%1));\n"; itype.c_type = itype.name; itype.c_type_in = itype.c_type + "*"; itype.c_type_out = itype.c_type + "*"; itype.cs_type = BINDINGS_NAMESPACE_COLLECTIONS "." + itype.proxy_name; itype.cs_in = "%0." CS_SMETHOD_GETINSTANCE "()"; - itype.cs_out = "return new " + itype.cs_type + "(%0(%1));"; + itype.cs_out = "return new %2(%0(%1));"; itype.im_type_in = "IntPtr"; itype.im_type_out = "IntPtr"; builtin_types.insert(itype.cname, itype); @@ -3565,13 +3617,14 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.name = "Dictionary"; itype.cname = itype.name; itype.proxy_name = itype.name; + itype.type_parameter_count = 2; itype.c_out = "\treturn memnew(Dictionary(%1));\n"; itype.c_type = itype.name; itype.c_type_in = itype.c_type + "*"; itype.c_type_out = itype.c_type + "*"; itype.cs_type = BINDINGS_NAMESPACE_COLLECTIONS "." + itype.proxy_name; itype.cs_in = "%0." CS_SMETHOD_GETINSTANCE "()"; - itype.cs_out = "return new " + itype.cs_type + "(%0(%1));"; + itype.cs_out = "return new %2(%0(%1));"; itype.im_type_in = "IntPtr"; itype.im_type_out = "IntPtr"; builtin_types.insert(itype.cname, itype); diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index fb7e0e5a81..f0ba2b18e4 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -87,6 +87,8 @@ class BindingsGenerator { StringName cname; bool is_enum = false; + List<TypeReference> generic_type_parameters; + TypeReference() {} TypeReference(const StringName &p_cname) : @@ -206,6 +208,8 @@ class BindingsGenerator { String name; StringName cname; + int type_parameter_count; + /** * Identifier name of the base class. */ @@ -679,6 +683,8 @@ class BindingsGenerator { const TypeInterface *_get_type_or_null(const TypeReference &p_typeref); const TypeInterface *_get_type_or_placeholder(const TypeReference &p_typeref); + const String _get_generic_type_parameters(const TypeInterface &p_itype, const List<TypeReference> &p_generic_type_parameters); + StringName _get_int_type_name_from_meta(GodotTypeInfo::Metadata p_meta); StringName _get_float_type_name_from_meta(GodotTypeInfo::Metadata p_meta); diff --git a/modules/mono/editor/script_templates/EditorScenePostImport/basic_import_script.cs b/modules/mono/editor/script_templates/EditorScenePostImport/basic_import_script.cs new file mode 100644 index 0000000000..0690205d01 --- /dev/null +++ b/modules/mono/editor/script_templates/EditorScenePostImport/basic_import_script.cs @@ -0,0 +1,18 @@ +// meta-description: Basic import script template + +#if TOOLS +using _BINDINGS_NAMESPACE_; +using System; + +[Tool] +public partial class _CLASS_ : _BASE_ +{ + public override Object _PostImport(Node scene) + { + // Modify the contents of the scene upon import. For example, setting up LODs: +// scene.GetNode<MeshInstance3D>("HighPolyMesh").DrawDistanceEnd = 5.0 +// scene.GetNode<MeshInstance3D>("LowPolyMesh").DrawDistanceBegin = 5.0 + return scene // Return the modified root node when you're done. + } +} +#endif diff --git a/modules/mono/editor/script_templates/EditorScenePostImport/no_comments.cs b/modules/mono/editor/script_templates/EditorScenePostImport/no_comments.cs new file mode 100644 index 0000000000..4e2d9b7088 --- /dev/null +++ b/modules/mono/editor/script_templates/EditorScenePostImport/no_comments.cs @@ -0,0 +1,15 @@ +// meta-description: Basic import script template (no comments) + +#if TOOLS +using _BINDINGS_NAMESPACE_; +using System; + +[Tool] +public partial class _CLASS_ : _BASE_ +{ + public override Object _PostImport(Node scene) + { + return scene + } +} +#endif diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs index ef135da51a..2febf37f05 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs @@ -2,17 +2,27 @@ using System; namespace Godot { + /// <summary> + /// An attribute that determines if an assembly has scripts. If so, what types of scripts the assembly has. + /// </summary> [AttributeUsage(AttributeTargets.Assembly)] public class AssemblyHasScriptsAttribute : Attribute { private readonly bool requiresLookup; private readonly System.Type[] scriptTypes; + /// <summary> + /// Constructs a new AssemblyHasScriptsAttribute instance. + /// </summary> public AssemblyHasScriptsAttribute() { requiresLookup = true; } + /// <summary> + /// Constructs a new AssemblyHasScriptsAttribute instance. + /// </summary> + /// <param name="scriptTypes">The specified type(s) of scripts.</param> public AssemblyHasScriptsAttribute(System.Type[] scriptTypes) { requiresLookup = false; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs index e93bc89811..0b00878e8c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs @@ -2,6 +2,9 @@ using System; namespace Godot { + /// <summary> + /// An attribute that disables Godot Generators. + /// </summary> [AttributeUsage(AttributeTargets.Class)] public class DisableGodotGeneratorsAttribute : Attribute { } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportAttribute.cs index 6adf044886..46eb128d37 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportAttribute.cs @@ -2,12 +2,20 @@ using System; namespace Godot { + /// <summary> + /// An attribute used to export objects. + /// </summary> [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public class ExportAttribute : Attribute { private PropertyHint hint; private string hintString; + /// <summary> + /// Constructs a new ExportAttribute Instance. + /// </summary> + /// <param name="hint">A hint to the exported object.</param> + /// <param name="hintString">A string representing the exported object.</param> public ExportAttribute(PropertyHint hint = PropertyHint.None, string hintString = "") { this.hint = hint; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/GodotMethodAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/GodotMethodAttribute.cs index 55848769d5..8d4ff0fdb7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/GodotMethodAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/GodotMethodAttribute.cs @@ -2,6 +2,9 @@ using System; namespace Godot { + /// <summary> + /// An attribute for a method. + /// </summary> [AttributeUsage(AttributeTargets.Method)] internal class GodotMethodAttribute : Attribute { @@ -9,6 +12,10 @@ namespace Godot public string MethodName { get { return methodName; } } + /// <summary> + /// Constructs a new GodotMethodAttribute instance. + /// </summary> + /// <param name="methodName">The name of the method.</param> public GodotMethodAttribute(string methodName) { this.methodName = methodName; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs index b8b9bc660c..f0d37c344d 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs @@ -2,9 +2,15 @@ using System; namespace Godot { + /// <summary> + /// Constructs a new AnyPeerAttribute instance. Members with the AnyPeerAttribute are given authority over their own player. + /// </summary> [AttributeUsage(AttributeTargets.Method)] public class AnyPeerAttribute : Attribute { } + /// <summary> + /// Constructs a new AuthorityAttribute instance. Members with the AuthorityAttribute are given authority over the game. + /// </summary> [AttributeUsage(AttributeTargets.Method)] public class AuthorityAttribute : Attribute { } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs index 12eb1035c3..3ebb6612de 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs @@ -2,11 +2,18 @@ using System; namespace Godot { + /// <summary> + /// An attribute that contains the path to the object's script. + /// </summary> [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class ScriptPathAttribute : Attribute { private string path; + /// <summary> + /// Constructs a new ScriptPathAttribute instance. + /// </summary> + /// <param name="path">The file path to the script</param> public ScriptPathAttribute(string path) { this.path = path; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs index 072e0f20ff..6475237002 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs @@ -4,9 +4,16 @@ namespace Godot { public static class Dispatcher { + /// <summary> + /// Implements an external instance of GodotTaskScheduler. + /// </summary> + /// <returns>A GodotTaskScheduler instance.</returns> [MethodImpl(MethodImplOptions.InternalCall)] private static extern GodotTaskScheduler godot_icall_DefaultGodotTaskScheduler(); + /// <summary> + /// Initializes the synchronization context as the context of the GodotTaskScheduler. + /// </summary> public static GodotSynchronizationContext SynchronizationContext => godot_icall_DefaultGodotTaskScheduler().Context; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs index c01c926e82..1b599beab5 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs @@ -14,6 +14,9 @@ namespace Godot _queue.Add(new KeyValuePair<SendOrPostCallback, object>(d, state)); } + /// <summary> + /// Calls the Key method on each workItem object in the _queue to activate their callbacks. + /// </summary> public void ExecutePendingContinuations() { while (_queue.TryTake(out var workItem)) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs index 8eaeea50dc..408bed71b2 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs @@ -6,11 +6,25 @@ using System.Threading.Tasks; namespace Godot { + /// <summary> + /// GodotTaskScheduler contains a linked list of tasks to perform as a queue. Methods + /// within the class are used to control the queue and perform the contained tasks. + /// </summary> public class GodotTaskScheduler : TaskScheduler { + /// <summary> + /// The current synchronization context. + /// </summary> internal GodotSynchronizationContext Context { get; } + + /// <summary> + /// The queue of tasks for the task scheduler. + /// </summary> private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); + /// <summary> + /// Constructs a new GodotTaskScheduler instance. + /// </summary> public GodotTaskScheduler() { Context = new GodotSynchronizationContext(); @@ -53,12 +67,19 @@ namespace Godot } } + /// <summary> + /// Executes all queued tasks and pending tasks from the current context. + /// </summary> public void Activate() { ExecuteQueuedTasks(); Context.ExecutePendingContinuations(); } + /// <summary> + /// Loops through and attempts to execute each task in _tasks. + /// </summary> + /// <exception cref="InvalidOperationException"></exception> private void ExecuteQueuedTasks() { while (true) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Interfaces/IAwaitable.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Interfaces/IAwaitable.cs index 0397957d00..e747e03c1e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Interfaces/IAwaitable.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Interfaces/IAwaitable.cs @@ -1,10 +1,17 @@ namespace Godot { + /// <summary> + /// An interface that requires a GetAwaiter() method to get a reference to the Awaiter. + /// </summary> public interface IAwaitable { IAwaiter GetAwaiter(); } + /// <summary> + /// A templated interface that requires a GetAwaiter() method to get a reference to the Awaiter. + /// </summary> + /// <typeparam name="TResult">A reference to the result to be passed out.</typeparam> public interface IAwaitable<out TResult> { IAwaiter<TResult> GetAwaiter(); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Interfaces/IAwaiter.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Interfaces/IAwaiter.cs index d3be9d781c..dec225eb29 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Interfaces/IAwaiter.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Interfaces/IAwaiter.cs @@ -2,6 +2,9 @@ using System.Runtime.CompilerServices; namespace Godot { + /// <summary> + /// An interface that requires a boolean for completion status and a method that gets the result of completion. + /// </summary> public interface IAwaiter : INotifyCompletion { bool IsCompleted { get; } @@ -9,6 +12,10 @@ namespace Godot void GetResult(); } + /// <summary> + /// A templated interface that requires a boolean for completion status and a method that gets the result of completion and returns it. + /// </summary> + /// <typeparam name="TResult">A reference to the result to be passed out.</typeparam> public interface IAwaiter<out TResult> : INotifyCompletion { bool IsCompleted { get; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Interfaces/ISerializationListener.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Interfaces/ISerializationListener.cs index c3fa2f3e82..90b4d1b8d3 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Interfaces/ISerializationListener.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Interfaces/ISerializationListener.cs @@ -1,5 +1,8 @@ namespace Godot { + /// <summary> + /// An interface that requires methods for before and after serialization. + /// </summary> public interface ISerializationListener { void OnBeforeSerialize(); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs index ee4d0eed08..50ae2eb112 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs @@ -80,6 +80,11 @@ namespace Godot private static bool TypeIsGenericIDictionary(Type type) => type.GetGenericTypeDefinition() == typeof(IDictionary<,>); /// <summary> + /// Returns <see langword="true"/> if the <see cref="FlagsAttribute"/> is applied to the given type. + /// </summary> + private static bool TypeHasFlagsAttribute(Type type) => type.IsDefined(typeof(FlagsAttribute), false); + + /// <summary> /// Returns the generic type definition of <paramref name="type"/>. /// </summary> /// <exception cref="InvalidOperationException"> diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index d8fd244067..44a8e26b8f 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -176,6 +176,7 @@ void CachedData::clear_godot_api_cache() { methodthunk_MarshalUtils_TypeIsGenericIEnumerable.nullify(); methodthunk_MarshalUtils_TypeIsGenericICollection.nullify(); methodthunk_MarshalUtils_TypeIsGenericIDictionary.nullify(); + methodthunk_MarshalUtils_TypeHasFlagsAttribute.nullify(); methodthunk_MarshalUtils_GetGenericTypeDefinition.nullify(); @@ -300,6 +301,7 @@ void update_godot_api_cache() { CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIEnumerable, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIEnumerable", 1)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericICollection, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericICollection", 1)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIDictionary", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeHasFlagsAttribute, GODOT_API_CLASS(MarshalUtils)->get_method("TypeHasFlagsAttribute", 1)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GetGenericTypeDefinition, GODOT_API_CLASS(MarshalUtils)->get_method("GetGenericTypeDefinition", 2)); diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index 4000342c94..92136e1f41 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -147,6 +147,7 @@ struct CachedData { GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIEnumerable; GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericICollection; GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIDictionary; + GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeHasFlagsAttribute; GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_GetGenericTypeDefinition; diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 25678be624..1983d6ebe2 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -614,6 +614,14 @@ bool type_is_generic_idictionary(MonoReflectionType *p_reftype) { return (bool)res; } +bool type_has_flags_attribute(MonoReflectionType *p_reftype) { + NO_GLUE_RET(false); + MonoException *exc = nullptr; + MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeHasFlagsAttribute).invoke(p_reftype, &exc); + UNHANDLED_EXCEPTION(exc); + return (bool)res; +} + void get_generic_type_definition(MonoReflectionType *p_reftype, MonoReflectionType **r_generic_reftype) { MonoException *exc = nullptr; CACHED_METHOD_THUNK(MarshalUtils, GetGenericTypeDefinition).invoke(p_reftype, r_generic_reftype, &exc); diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index 4c2c2c93c2..246a1cd31e 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -61,6 +61,7 @@ bool type_is_system_generic_dictionary(MonoReflectionType *p_reftype); bool type_is_generic_ienumerable(MonoReflectionType *p_reftype); bool type_is_generic_icollection(MonoReflectionType *p_reftype); bool type_is_generic_idictionary(MonoReflectionType *p_reftype); +bool type_has_flags_attribute(MonoReflectionType *p_reftype); void get_generic_type_definition(MonoReflectionType *p_reftype, MonoReflectionType **r_generic_reftype); |