diff options
Diffstat (limited to 'modules/mono')
8 files changed, 113 insertions, 71 deletions
diff --git a/modules/mono/SdkPackageVersions.props b/modules/mono/SdkPackageVersions.props index 396443f30e..df3ebe581c 100644 --- a/modules/mono/SdkPackageVersions.props +++ b/modules/mono/SdkPackageVersions.props @@ -1,6 +1,6 @@ <Project> <PropertyGroup> - <PackageVersion_Godot_NET_Sdk>4.0.0-dev4</PackageVersion_Godot_NET_Sdk> - <PackageVersion_Godot_SourceGenerators>4.0.0-dev1</PackageVersion_Godot_SourceGenerators> + <PackageVersion_Godot_NET_Sdk>4.0.0-dev5</PackageVersion_Godot_NET_Sdk> + <PackageVersion_Godot_SourceGenerators>4.0.0-dev2</PackageVersion_Godot_SourceGenerators> </PropertyGroup> </Project> diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 4fca80fca0..43f57a7caa 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -328,7 +328,7 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin String script_template = "using " BINDINGS_NAMESPACE ";\n" "using System;\n" "\n" - "public class %CLASS% : %BASE%\n" + "public partial class %CLASS% : %BASE%\n" "{\n" " // Declare member variables here. Examples:\n" " // private int a = 2;\n" @@ -2018,22 +2018,20 @@ void CSharpInstance::connect_event_signals() { // TODO: Use pooling for ManagedCallable instances. auto event_signal_callable = memnew(EventSignalCallable(owner, &event_signal)); - owner->connect(signal_name, Callable(event_signal_callable)); + Callable callable(event_signal_callable); + connected_event_signals.push_back(callable); + owner->connect(signal_name, callable); } } void CSharpInstance::disconnect_event_signals() { - for (const Map<StringName, CSharpScript::EventSignal>::Element *E = script->event_signals.front(); E; E = E->next()) { - const CSharpScript::EventSignal &event_signal = E->value(); - - StringName signal_name = event_signal.field->get_name(); - - // TODO: It would be great if we could store this EventSignalCallable on the stack. - // The problem is that Callable memdeletes it when it's destructed... - auto event_signal_callable = memnew(EventSignalCallable(owner, &event_signal)); - - owner->disconnect(signal_name, Callable(event_signal_callable)); + for (const List<Callable>::Element *E = connected_event_signals.front(); E; E = E->next()) { + const Callable &callable = E->get(); + auto event_signal_callable = static_cast<const EventSignalCallable *>(callable.get_custom()); + owner->disconnect(event_signal_callable->get_signal(), callable); } + + connected_event_signals.clear(); } void CSharpInstance::refcount_incremented() { diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 40f7ed4552..dd93a86d7a 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -271,6 +271,8 @@ class CSharpInstance : public ScriptInstance { Ref<CSharpScript> script; MonoGCHandleData gchandle; + List<Callable> connected_event_signals; + bool _reference_owner_unsafe(); /* diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj index ef8add0ba8..4e9e7184da 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj @@ -23,11 +23,12 @@ <ItemGroup> <!-- Package Sdk\Sdk.props and Sdk\Sdk.targets file --> - <None Include="Sdk\Sdk.props" Pack="true" PackagePath="Sdk" Visible="false" /> - <None Include="Sdk\Sdk.targets" Pack="true" PackagePath="Sdk" Visible="false" /> + <None Include="Sdk\Sdk.props" Pack="true" PackagePath="Sdk" /> + <None Include="Sdk\Sdk.targets" Pack="true" PackagePath="Sdk" /> <!-- SdkPackageVersions.props --> - - <None Include="..\..\..\SdkPackageVersions.props" Pack="true" PackagePath="Sdk" Visible="false" /> + <None Include="..\..\..\SdkPackageVersions.props" Pack="true" PackagePath="Sdk"> + <Link>Sdk\SdkPackageVersions.props</Link> + </None> </ItemGroup> <Target Name="CopyNupkgToSConsOutputDir" AfterTargets="Pack"> diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs index c3e74822d5..e16f72f43a 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs @@ -82,5 +82,8 @@ namespace Godot.SourceGenerators public static string FullQualifiedName(this INamedTypeSymbol symbol) => symbol.ToDisplayString(NullableFlowState.NotNull, FullyQualifiedFormatOmitGlobal); + + public static string FullQualifiedName(this INamespaceSymbol namespaceSymbol) + => namespaceSymbol.ToDisplayString(FullyQualifiedFormatOmitGlobal); } } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs index 150e59e414..a51728e221 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs @@ -69,7 +69,7 @@ namespace Godot.SourceGenerators IEnumerable<ClassDeclarationSyntax> classDeclarations ) { - var attributesBuilder = new StringBuilder(); + var attributes = new StringBuilder(); // Remember syntax trees for which we already added an attribute, to prevent unnecessary duplicates. var attributedTrees = new List<SyntaxTree>(); @@ -81,28 +81,54 @@ namespace Godot.SourceGenerators attributedTrees.Add(cds.SyntaxTree); - if (attributesBuilder.Length != 0) - attributesBuilder.Append("\n "); + if (attributes.Length != 0) + attributes.Append("\n"); - attributesBuilder.Append(@"[ScriptPathAttribute(""res://"); - attributesBuilder.Append(RelativeToDir(cds.SyntaxTree.FilePath, godotProjectDir)); - attributesBuilder.Append(@""")]"); + attributes.Append(@"[ScriptPathAttribute(""res://"); + attributes.Append(RelativeToDir(cds.SyntaxTree.FilePath, godotProjectDir)); + attributes.Append(@""")]"); } - string classNs = symbol.ContainingNamespace.Name; string className = symbol.Name; - var source = $@"using Godot; -namespace {classNs} -{{ - {attributesBuilder} - partial class {className} - {{ - }} -}} -"; - context.AddSource(classNs + "." + className + "_ScriptPath_Generated", - SourceText.From(source, Encoding.UTF8)); + INamespaceSymbol namespaceSymbol = symbol.ContainingNamespace; + string classNs = namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace ? + namespaceSymbol.FullQualifiedName() : + string.Empty; + bool hasNamespace = classNs.Length != 0; + + string uniqueName = hasNamespace ? + classNs + "." + className + "_ScriptPath_Generated" : + className + "_ScriptPath_Generated"; + + var source = new StringBuilder(); + + // using Godot; + // namespace {classNs} { + // {attributesBuilder} + // partial class {className} { } + // } + + source.Append("using Godot;\n"); + + if (hasNamespace) + { + source.Append("namespace "); + source.Append(classNs); + source.Append(" {\n\n"); + } + + source.Append(attributes); + source.Append("\n partial class "); + source.Append(className); + source.Append("\n{\n}\n"); + + if (hasNamespace) + { + source.Append("\n}\n"); + } + + context.AddSource(uniqueName, SourceText.From(source.ToString(), Encoding.UTF8)); } private static void AddScriptTypesAssemblyAttr(GeneratorExecutionContext context, diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index b1875aec3f..b48e5df9eb 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -3631,11 +3631,44 @@ void BindingsGenerator::_initialize() { initialized = true; } +static String generate_all_glue_option = "--generate-mono-glue"; +static String generate_cs_glue_option = "--generate-mono-cs-glue"; +static String generate_cpp_glue_option = "--generate-mono-cpp-glue"; + +static void handle_cmdline_options(String glue_dir_path, String cs_dir_path, String cpp_dir_path) { + BindingsGenerator bindings_generator; + bindings_generator.set_log_print_enabled(true); + + if (!bindings_generator.is_initialized()) { + ERR_PRINT("Failed to initialize the bindings generator"); + return; + } + + if (glue_dir_path.length()) { + if (bindings_generator.generate_glue(glue_dir_path) != OK) { + ERR_PRINT(generate_all_glue_option + ": Failed to generate the C++ glue."); + } + + if (bindings_generator.generate_cs_api(glue_dir_path.plus_file(API_SOLUTION_NAME)) != OK) { + ERR_PRINT(generate_all_glue_option + ": Failed to generate the C# API."); + } + } + + if (cs_dir_path.length()) { + if (bindings_generator.generate_cs_api(cs_dir_path) != OK) { + ERR_PRINT(generate_cs_glue_option + ": Failed to generate the C# API."); + } + } + + if (cpp_dir_path.length()) { + if (bindings_generator.generate_glue(cpp_dir_path) != OK) { + ERR_PRINT(generate_cpp_glue_option + ": Failed to generate the C++ glue."); + } + } +} + void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) { const int NUM_OPTIONS = 2; - String generate_all_glue_option = "--generate-mono-glue"; - String generate_cs_glue_option = "--generate-mono-cs-glue"; - String generate_cpp_glue_option = "--generate-mono-cpp-glue"; String glue_dir_path; String cs_dir_path; @@ -3643,6 +3676,8 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) int options_left = NUM_OPTIONS; + bool exit_godot = false; + const List<String>::Element *elem = p_cmdline_args.front(); while (elem && options_left) { @@ -3654,6 +3689,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) elem = elem->next(); } else { ERR_PRINT(generate_all_glue_option + ": No output directory specified (expected path to '{GODOT_ROOT}/modules/mono/glue')."); + exit_godot = true; } --options_left; @@ -3665,6 +3701,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) elem = elem->next(); } else { ERR_PRINT(generate_cs_glue_option + ": No output directory specified."); + exit_godot = true; } --options_left; @@ -3676,6 +3713,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) elem = elem->next(); } else { ERR_PRINT(generate_cpp_glue_option + ": No output directory specified."); + exit_godot = true; } --options_left; @@ -3685,37 +3723,11 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) } if (glue_dir_path.length() || cs_dir_path.length() || cpp_dir_path.length()) { - BindingsGenerator bindings_generator; - bindings_generator.set_log_print_enabled(true); - - if (!bindings_generator.initialized) { - ERR_PRINT("Failed to initialize the bindings generator"); - Main::cleanup(true); - ::exit(0); - } - - if (glue_dir_path.length()) { - if (bindings_generator.generate_glue(glue_dir_path) != OK) { - ERR_PRINT(generate_all_glue_option + ": Failed to generate the C++ glue."); - } - - if (bindings_generator.generate_cs_api(glue_dir_path.plus_file(API_SOLUTION_NAME)) != OK) { - ERR_PRINT(generate_all_glue_option + ": Failed to generate the C# API."); - } - } - - if (cs_dir_path.length()) { - if (bindings_generator.generate_cs_api(cs_dir_path) != OK) { - ERR_PRINT(generate_cs_glue_option + ": Failed to generate the C# API."); - } - } - - if (cpp_dir_path.length()) { - if (bindings_generator.generate_glue(cpp_dir_path) != OK) { - ERR_PRINT(generate_cpp_glue_option + ": Failed to generate the C++ glue."); - } - } + handle_cmdline_options(glue_dir_path, cs_dir_path, cpp_dir_path); + exit_godot = true; + } + if (exit_godot) { // Exit once done Main::cleanup(true); ::exit(0); diff --git a/modules/mono/mono_gd/support/android_support.cpp b/modules/mono/mono_gd/support/android_support.cpp index cba29d63cd..c65353dfd1 100644 --- a/modules/mono/mono_gd/support/android_support.cpp +++ b/modules/mono/mono_gd/support/android_support.cpp @@ -415,8 +415,7 @@ GD_PINVOKE_EXPORT int32_t monodroid_get_system_property(const char *p_name, char if (r_value) { if (len >= 0) { *r_value = (char *)malloc(len + 1); - if (!*r_value) - return -1; + ERR_FAIL_NULL_V_MSG(*r_value, -1, "Out of memory."); memcpy(*r_value, prop_value_str, len); (*r_value)[len] = '\0'; } else { @@ -637,6 +636,7 @@ GD_PINVOKE_EXPORT int32_t _monodroid_get_dns_servers(void **r_dns_servers_array) if (dns_servers_count > 0) { size_t ret_size = sizeof(char *) * (size_t)dns_servers_count; *r_dns_servers_array = malloc(ret_size); // freed by the BCL + ERR_FAIL_NULL_V_MSG(*r_dns_servers_array, -1, "Out of memory."); memcpy(*r_dns_servers_array, dns_servers, ret_size); } |