1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-08 12:40:44 +00:00

C#: Upgrade to .NET 6 (5.0 -> 6.0)

This commit is contained in:
Ignacio Roldán Etcheverry
2022-02-27 21:57:50 +01:00
parent e22dd3bc6a
commit 18f805b3aa
38 changed files with 231 additions and 352 deletions

View File

@@ -105,7 +105,7 @@ jobs:
uses: actions/setup-dotnet@v1 uses: actions/setup-dotnet@v1
if: ${{ matrix.build-mono }} if: ${{ matrix.build-mono }}
with: with:
dotnet-version: '5.0.x' dotnet-version: '6.0.x'
- name: Compilation - name: Compilation
uses: ./.github/actions/godot-build uses: ./.github/actions/godot-build

View File

@@ -226,7 +226,7 @@ def build_godot_api(msbuild_tool, module_dir, output_dir):
core_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotSharp", "bin", build_config)) core_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotSharp", "bin", build_config))
editor_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotSharpEditor", "bin", build_config)) editor_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotSharpEditor", "bin", build_config))
plugins_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotPlugins", "bin", build_config, "net5.0")) plugins_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotPlugins", "bin", build_config, "net6.0"))
if not os.path.isdir(editor_api_dir): if not os.path.isdir(editor_api_dir):
assert not os.path.isfile(editor_api_dir) assert not os.path.isfile(editor_api_dir)

View File

@@ -77,7 +77,7 @@ def configure(env, env_mono):
def find_dotnet_app_host_dir(env): def find_dotnet_app_host_dir(env):
dotnet_version = "5.0" dotnet_version = "6.0"
dotnet_root = env["dotnet_root"] dotnet_root = env["dotnet_root"]

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<ProjectGuid>{639E48BD-44E5-4091-8EDD-22D36DC0768D}</ProjectGuid> <ProjectGuid>{639E48BD-44E5-4091-8EDD-22D36DC0768D}</ProjectGuid>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<LangVersion>7.2</LangVersion> <LangVersion>10</LangVersion>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<ProjectGuid>{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}</ProjectGuid> <ProjectGuid>{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}</ProjectGuid>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<LangVersion>7.2</LangVersion> <LangVersion>10</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Build" Version="15.1.548" ExcludeAssets="runtime" /> <PackageReference Include="Microsoft.Build" Version="15.1.548" ExcludeAssets="runtime" />

View File

@@ -22,7 +22,7 @@ namespace GodotTools.ProjectEditor
root.Sdk = GodotSdkAttrValue; root.Sdk = GodotSdkAttrValue;
var mainGroup = root.AddPropertyGroup(); var mainGroup = root.AddPropertyGroup();
mainGroup.AddProperty("TargetFramework", "net5.0"); mainGroup.AddProperty("TargetFramework", "net6.0");
mainGroup.AddProperty("EnableDynamicLoading", "true"); mainGroup.AddProperty("EnableDynamicLoading", "true");
string sanitizedName = IdentifierUtils.SanitizeQualifiedIdentifier(name, allowEmptyIdentifiers: true); string sanitizedName = IdentifierUtils.SanitizeQualifiedIdentifier(name, allowEmptyIdentifiers: true);

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<!-- Specify compile items manually to avoid including dangling generated items. --> <!-- Specify compile items manually to avoid including dangling generated items. -->
<EnableDefaultCompileItems>false</EnableDefaultCompileItems> <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup> </PropertyGroup>

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -42,9 +41,9 @@ namespace GodotTools.Build
var process = new Process { StartInfo = startInfo }; var process = new Process { StartInfo = startInfo };
if (stdOutHandler != null) if (stdOutHandler != null)
process.OutputDataReceived += (s, e) => stdOutHandler.Invoke(e.Data); process.OutputDataReceived += (_, e) => stdOutHandler.Invoke(e.Data);
if (stdErrHandler != null) if (stdErrHandler != null)
process.ErrorDataReceived += (s, e) => stdErrHandler.Invoke(e.Data); process.ErrorDataReceived += (_, e) => stdErrHandler.Invoke(e.Data);
process.Start(); process.Start();
@@ -102,9 +101,9 @@ namespace GodotTools.Build
var process = new Process { StartInfo = startInfo }; var process = new Process { StartInfo = startInfo };
if (stdOutHandler != null) if (stdOutHandler != null)
process.OutputDataReceived += (s, e) => stdOutHandler.Invoke(e.Data); process.OutputDataReceived += (_, e) => stdOutHandler.Invoke(e.Data);
if (stdErrHandler != null) if (stdErrHandler != null)
process.ErrorDataReceived += (s, e) => stdErrHandler.Invoke(e.Data); process.ErrorDataReceived += (_, e) => stdErrHandler.Invoke(e.Data);
process.Start(); process.Start();

View File

@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<ProjectGuid>{27B00618-A6F2-4828-B922-05CAEB08C286}</ProjectGuid> <ProjectGuid>{27B00618-A6F2-4828-B922-05CAEB08C286}</ProjectGuid>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading> <EnableDynamicLoading>true</EnableDynamicLoading>
<LangVersion>9</LangVersion> <LangVersion>10</LangVersion>
<!-- The Godot editor uses the Debug Godot API assemblies --> <!-- The Godot editor uses the Debug Godot API assemblies -->
<GodotApiConfiguration>Debug</GodotApiConfiguration> <GodotApiConfiguration>Debug</GodotApiConfiguration>
<GodotSourceRootPath>$(SolutionDir)/../../../../</GodotSourceRootPath> <GodotSourceRootPath>$(SolutionDir)/../../../../</GodotSourceRootPath>

View File

@@ -98,9 +98,6 @@ namespace GodotTools.Internals
[DllImport(GodotDllName)] [DllImport(GodotDllName)]
private static extern void godot_icall_Internal_FullExportTemplatesDir(out godot_string dest); private static extern void godot_icall_Internal_FullExportTemplatesDir(out godot_string dest);
[DllImport(GodotDllName)]
private static extern void godot_icall_Internal_SimplifyGodotPath(in godot_string path, out godot_string dest);
[DllImport(GodotDllName)] [DllImport(GodotDllName)]
private static extern bool godot_icall_Internal_IsMacOSAppBundleInstalled(in godot_string bundleId); private static extern bool godot_icall_Internal_IsMacOSAppBundleInstalled(in godot_string bundleId);

View File

@@ -8,7 +8,7 @@ namespace GodotTools.Utils
{ {
public static class FsPathUtils 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) private static bool PathStartsWithAlreadyNorm(this string childPath, string parentPath)
{ {
@@ -34,7 +34,7 @@ namespace GodotTools.Utils
public static string LocalizePathWithCaseChecked(string path) public static string LocalizePathWithCaseChecked(string path)
{ {
string pathNorm = path.NormalizePath() + Path.DirectorySeparatorChar; string pathNorm = path.NormalizePath() + Path.DirectorySeparatorChar;
string resourcePathNorm = _resourcePath.NormalizePath() + Path.DirectorySeparatorChar; string resourcePathNorm = ResourcePath.NormalizePath() + Path.DirectorySeparatorChar;
if (!pathNorm.PathStartsWithAlreadyNorm(resourcePathNorm)) if (!pathNorm.PathStartsWithAlreadyNorm(resourcePathNorm))
return null; return null;

View File

@@ -6,6 +6,7 @@ using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.Versioning;
using System.Text; using System.Text;
using GodotTools.Internals; using GodotTools.Internals;
@@ -131,43 +132,34 @@ namespace GodotTools.Utils
new[] { Names.MacOS, Names.Server, Names.Haiku, Names.Android, Names.iOS } new[] { Names.MacOS, Names.Server, Names.Haiku, Names.Android, Names.iOS }
.Concat(LinuxBSDPlatforms).ToArray(); .Concat(LinuxBSDPlatforms).ToArray();
private static readonly Lazy<bool> _isWindows = new Lazy<bool>(() => IsOS(Names.Windows)); private static readonly Lazy<bool> _isWindows = new(() => IsOS(Names.Windows));
private static readonly Lazy<bool> _isMacOS = new Lazy<bool>(() => IsOS(Names.MacOS)); private static readonly Lazy<bool> _isMacOS = new(() => IsOS(Names.MacOS));
private static readonly Lazy<bool> _isLinuxBSD = new Lazy<bool>(() => IsAnyOS(LinuxBSDPlatforms)); private static readonly Lazy<bool> _isLinuxBSD = new(() => IsAnyOS(LinuxBSDPlatforms));
private static readonly Lazy<bool> _isServer = new Lazy<bool>(() => IsOS(Names.Server)); private static readonly Lazy<bool> _isServer = new(() => IsOS(Names.Server));
private static readonly Lazy<bool> _isUWP = new Lazy<bool>(() => IsOS(Names.UWP)); private static readonly Lazy<bool> _isUWP = new(() => IsOS(Names.UWP));
private static readonly Lazy<bool> _isHaiku = new Lazy<bool>(() => IsOS(Names.Haiku)); private static readonly Lazy<bool> _isHaiku = new(() => IsOS(Names.Haiku));
private static readonly Lazy<bool> _isAndroid = new Lazy<bool>(() => IsOS(Names.Android)); private static readonly Lazy<bool> _isAndroid = new(() => IsOS(Names.Android));
private static readonly Lazy<bool> _isiOS = new Lazy<bool>(() => IsOS(Names.iOS)); private static readonly Lazy<bool> _isiOS = new(() => IsOS(Names.iOS));
private static readonly Lazy<bool> _isHTML5 = new Lazy<bool>(() => IsOS(Names.HTML5)); private static readonly Lazy<bool> _isHTML5 = new(() => IsOS(Names.HTML5));
private static readonly Lazy<bool> _isUnixLike = new Lazy<bool>(() => IsAnyOS(UnixLikePlatforms)); private static readonly Lazy<bool> _isUnixLike = new(() => IsAnyOS(UnixLikePlatforms));
// TODO SupportedOSPlatformGuard once we target .NET 6 [SupportedOSPlatformGuard("windows")] public static bool IsWindows => _isWindows.Value || IsUWP;
// [SupportedOSPlatformGuard("windows")]
public static bool IsWindows => _isWindows.Value || IsUWP;
// [SupportedOSPlatformGuard("osx")] [SupportedOSPlatformGuard("osx")] public static bool IsMacOS => _isMacOS.Value;
public static bool IsMacOS => _isMacOS.Value;
// [SupportedOSPlatformGuard("linux")] [SupportedOSPlatformGuard("linux")] public static bool IsLinuxBSD => _isLinuxBSD.Value;
public static bool IsLinuxBSD => _isLinuxBSD.Value;
// [SupportedOSPlatformGuard("linux")] [SupportedOSPlatformGuard("linux")] public static bool IsServer => _isServer.Value;
public static bool IsServer => _isServer.Value;
// [SupportedOSPlatformGuard("windows")] [SupportedOSPlatformGuard("windows")] public static bool IsUWP => _isUWP.Value;
public static bool IsUWP => _isUWP.Value;
public static bool IsHaiku => _isHaiku.Value; public static bool IsHaiku => _isHaiku.Value;
// [SupportedOSPlatformGuard("android")] [SupportedOSPlatformGuard("android")] public static bool IsAndroid => _isAndroid.Value;
public static bool IsAndroid => _isAndroid.Value;
// [SupportedOSPlatformGuard("ios")] [SupportedOSPlatformGuard("ios")] public static bool IsiOS => _isiOS.Value;
public static bool IsiOS => _isiOS.Value;
// [SupportedOSPlatformGuard("browser")] [SupportedOSPlatformGuard("browser")] public static bool IsHTML5 => _isHTML5.Value;
public static bool IsHTML5 => _isHTML5.Value;
public static bool IsUnixLike => _isUnixLike.Value; public static bool IsUnixLike => _isUnixLike.Value;
public static char PathSep => IsWindows ? ';' : ':'; public static char PathSep => IsWindows ? ';' : ':';

View File

@@ -61,19 +61,17 @@ StringBuilder &operator<<(StringBuilder &r_sb, const char *p_cstring) {
#define INDENT2 INDENT1 INDENT1 #define INDENT2 INDENT1 INDENT1
#define INDENT3 INDENT2 INDENT1 #define INDENT3 INDENT2 INDENT1
#define INDENT4 INDENT3 INDENT1 #define INDENT4 INDENT3 INDENT1
#define INDENT5 INDENT4 INDENT1
#define MEMBER_BEGIN "\n" INDENT2 #define MEMBER_BEGIN "\n" INDENT1
#define OPEN_BLOCK "{\n" #define OPEN_BLOCK "{\n"
#define CLOSE_BLOCK "}\n" #define CLOSE_BLOCK "}\n"
#define OPEN_BLOCK_L1 INDENT1 OPEN_BLOCK #define OPEN_BLOCK_L1 INDENT1 OPEN_BLOCK
#define OPEN_BLOCK_L2 INDENT2 OPEN_BLOCK #define OPEN_BLOCK_L2 INDENT2 OPEN_BLOCK
#define OPEN_BLOCK_L3 INDENT3 OPEN_BLOCK #define CLOSE_BLOCK_L1 INDENT1 CLOSE_BLOCK
#define CLOSE_BLOCK_L2 INDENT2 CLOSE_BLOCK #define CLOSE_BLOCK_L2 INDENT2 CLOSE_BLOCK
#define CLOSE_BLOCK_L3 INDENT3 CLOSE_BLOCK #define CLOSE_BLOCK_L3 INDENT3 CLOSE_BLOCK
#define CLOSE_BLOCK_L4 INDENT4 CLOSE_BLOCK
#define BINDINGS_GLOBAL_SCOPE_CLASS "GD" #define BINDINGS_GLOBAL_SCOPE_CLASS "GD"
#define BINDINGS_NATIVE_NAME_FIELD "NativeName" #define BINDINGS_NATIVE_NAME_FIELD "NativeName"
@@ -890,44 +888,44 @@ Error BindingsGenerator::_populate_method_icalls_table(const TypeInterface &p_it
} }
void BindingsGenerator::_generate_array_extensions(StringBuilder &p_output) { void BindingsGenerator::_generate_array_extensions(StringBuilder &p_output) {
p_output.append("namespace " BINDINGS_NAMESPACE ";\n\n");
p_output.append("using System;\n\n"); p_output.append("using System;\n\n");
p_output.append("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
// The class where we put the extensions doesn't matter, so just use "GD". // The class where we put the extensions doesn't matter, so just use "GD".
p_output.append(INDENT1 "public static partial class " BINDINGS_GLOBAL_SCOPE_CLASS "\n" INDENT1 "{"); p_output.append("public static partial class " BINDINGS_GLOBAL_SCOPE_CLASS "\n{");
#define ARRAY_IS_EMPTY(m_type) \ #define ARRAY_IS_EMPTY(m_type) \
p_output.append("\n" INDENT2 "/// <summary>\n"); \ p_output.append("\n" INDENT1 "/// <summary>\n"); \
p_output.append(INDENT2 "/// Returns true if this " #m_type " array is empty or doesn't exist.\n"); \ p_output.append(INDENT1 "/// Returns true if this " #m_type " array is empty or doesn't exist.\n"); \
p_output.append(INDENT2 "/// </summary>\n"); \ p_output.append(INDENT1 "/// </summary>\n"); \
p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array check.</param>\n"); \ p_output.append(INDENT1 "/// <param name=\"instance\">The " #m_type " array check.</param>\n"); \
p_output.append(INDENT2 "/// <returns>Whether or not the array is empty.</returns>\n"); \ p_output.append(INDENT1 "/// <returns>Whether or not the array is empty.</returns>\n"); \
p_output.append(INDENT2 "public static bool IsEmpty(this " #m_type "[] instance)\n"); \ p_output.append(INDENT1 "public static bool IsEmpty(this " #m_type "[] instance)\n"); \
p_output.append(OPEN_BLOCK_L2); \ p_output.append(OPEN_BLOCK_L1); \
p_output.append(INDENT3 "return instance == null || instance.Length == 0;\n"); \ p_output.append(INDENT2 "return instance == null || instance.Length == 0;\n"); \
p_output.append(INDENT2 CLOSE_BLOCK); p_output.append(INDENT1 CLOSE_BLOCK);
#define ARRAY_JOIN(m_type) \ #define ARRAY_JOIN(m_type) \
p_output.append("\n" INDENT2 "/// <summary>\n"); \ p_output.append("\n" INDENT1 "/// <summary>\n"); \
p_output.append(INDENT2 "/// Converts this " #m_type " array to a string delimited by the given string.\n"); \ p_output.append(INDENT1 "/// Converts this " #m_type " array to a string delimited by the given string.\n"); \
p_output.append(INDENT2 "/// </summary>\n"); \ p_output.append(INDENT1 "/// </summary>\n"); \
p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array to convert.</param>\n"); \ p_output.append(INDENT1 "/// <param name=\"instance\">The " #m_type " array to convert.</param>\n"); \
p_output.append(INDENT2 "/// <param name=\"delimiter\">The delimiter to use between items.</param>\n"); \ p_output.append(INDENT1 "/// <param name=\"delimiter\">The delimiter to use between items.</param>\n"); \
p_output.append(INDENT2 "/// <returns>A single string with all items.</returns>\n"); \ p_output.append(INDENT1 "/// <returns>A single string with all items.</returns>\n"); \
p_output.append(INDENT2 "public static string Join(this " #m_type "[] instance, string delimiter = \", \")\n"); \ p_output.append(INDENT1 "public static string Join(this " #m_type "[] instance, string delimiter = \", \")\n"); \
p_output.append(OPEN_BLOCK_L2); \ p_output.append(OPEN_BLOCK_L1); \
p_output.append(INDENT3 "return String.Join(delimiter, instance);\n"); \ p_output.append(INDENT2 "return String.Join(delimiter, instance);\n"); \
p_output.append(INDENT2 CLOSE_BLOCK); p_output.append(INDENT1 CLOSE_BLOCK);
#define ARRAY_STRINGIFY(m_type) \ #define ARRAY_STRINGIFY(m_type) \
p_output.append("\n" INDENT2 "/// <summary>\n"); \ p_output.append("\n" INDENT1 "/// <summary>\n"); \
p_output.append(INDENT2 "/// Converts this " #m_type " array to a string with brackets.\n"); \ p_output.append(INDENT1 "/// Converts this " #m_type " array to a string with brackets.\n"); \
p_output.append(INDENT2 "/// </summary>\n"); \ p_output.append(INDENT1 "/// </summary>\n"); \
p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array to convert.</param>\n"); \ p_output.append(INDENT1 "/// <param name=\"instance\">The " #m_type " array to convert.</param>\n"); \
p_output.append(INDENT2 "/// <returns>A single string with all items.</returns>\n"); \ p_output.append(INDENT1 "/// <returns>A single string with all items.</returns>\n"); \
p_output.append(INDENT2 "public static string Stringify(this " #m_type "[] instance)\n"); \ p_output.append(INDENT1 "public static string Stringify(this " #m_type "[] instance)\n"); \
p_output.append(OPEN_BLOCK_L2); \ p_output.append(OPEN_BLOCK_L1); \
p_output.append(INDENT3 "return \"[\" + instance.Join() + \"]\";\n"); \ p_output.append(INDENT2 "return \"[\" + instance.Join() + \"]\";\n"); \
p_output.append(INDENT2 CLOSE_BLOCK); p_output.append(INDENT1 CLOSE_BLOCK);
#define ARRAY_ALL(m_type) \ #define ARRAY_ALL(m_type) \
ARRAY_IS_EMPTY(m_type) \ ARRAY_IS_EMPTY(m_type) \
@@ -953,18 +951,18 @@ void BindingsGenerator::_generate_array_extensions(StringBuilder &p_output) {
#undef ARRAY_JOIN #undef ARRAY_JOIN
#undef ARRAY_STRINGIFY #undef ARRAY_STRINGIFY
p_output.append(INDENT1 CLOSE_BLOCK); // End of GD class. p_output.append(CLOSE_BLOCK); // End of GD class.
p_output.append(CLOSE_BLOCK); // End of namespace.
} }
void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) { void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
// Constants (in partial GD class) // Constants (in partial GD class)
p_output.append("namespace " BINDINGS_NAMESPACE ";\n\n");
p_output.append("\n#pragma warning disable CS1591 // Disable warning: " p_output.append("\n#pragma warning disable CS1591 // Disable warning: "
"'Missing XML comment for publicly visible type or member'\n"); "'Missing XML comment for publicly visible type or member'\n");
p_output.append("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK); p_output.append("public static partial class " BINDINGS_GLOBAL_SCOPE_CLASS "\n{");
p_output.append(INDENT1 "public static partial class " BINDINGS_GLOBAL_SCOPE_CLASS "\n" INDENT1 "{");
for (const ConstantInterface &iconstant : global_constants) { for (const ConstantInterface &iconstant : global_constants) {
if (iconstant.const_doc && iconstant.const_doc->description.size()) { if (iconstant.const_doc && iconstant.const_doc->description.size()) {
@@ -975,12 +973,12 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
p_output.append(MEMBER_BEGIN "/// <summary>\n"); p_output.append(MEMBER_BEGIN "/// <summary>\n");
for (int i = 0; i < summary_lines.size(); i++) { for (int i = 0; i < summary_lines.size(); i++) {
p_output.append(INDENT2 "/// "); p_output.append(INDENT1 "/// ");
p_output.append(summary_lines[i]); p_output.append(summary_lines[i]);
p_output.append("\n"); p_output.append("\n");
} }
p_output.append(INDENT2 "/// </summary>"); p_output.append(INDENT1 "/// </summary>");
} }
} }
@@ -995,7 +993,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
p_output.append("\n"); p_output.append("\n");
} }
p_output.append(INDENT1 CLOSE_BLOCK); // end of GD class p_output.append(CLOSE_BLOCK); // end of GD class
// Enums // Enums
@@ -1015,19 +1013,19 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
_log("Declaring global enum '%s' inside static class '%s'\n", enum_proxy_name.utf8().get_data(), enum_class_name.utf8().get_data()); _log("Declaring global enum '%s' inside static class '%s'\n", enum_proxy_name.utf8().get_data(), enum_class_name.utf8().get_data());
p_output.append("\n" INDENT1 "public static partial class "); p_output.append("\npublic static partial class ");
p_output.append(enum_class_name); p_output.append(enum_class_name);
p_output.append("\n" OPEN_BLOCK_L1); p_output.append("\n" OPEN_BLOCK);
} }
if (ienum.is_flags) { if (ienum.is_flags) {
p_output.append("\n" INDENT1 "[System.Flags]"); p_output.append("\n[System.Flags]");
} }
p_output.append("\n" INDENT1 "public enum "); p_output.append("\npublic enum ");
p_output.append(enum_proxy_name); p_output.append(enum_proxy_name);
p_output.append(" : long"); p_output.append(" : long");
p_output.append("\n" OPEN_BLOCK_L1); p_output.append("\n" OPEN_BLOCK);
const ConstantInterface &last = ienum.constants.back()->get(); const ConstantInterface &last = ienum.constants.back()->get();
for (const ConstantInterface &iconstant : ienum.constants) { for (const ConstantInterface &iconstant : ienum.constants) {
@@ -1036,34 +1034,32 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>(); Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
if (summary_lines.size()) { if (summary_lines.size()) {
p_output.append(INDENT2 "/// <summary>\n"); p_output.append(INDENT1 "/// <summary>\n");
for (int i = 0; i < summary_lines.size(); i++) { for (int i = 0; i < summary_lines.size(); i++) {
p_output.append(INDENT2 "/// "); p_output.append(INDENT1 "/// ");
p_output.append(summary_lines[i]); p_output.append(summary_lines[i]);
p_output.append("\n"); p_output.append("\n");
} }
p_output.append(INDENT2 "/// </summary>\n"); p_output.append(INDENT1 "/// </summary>\n");
} }
} }
p_output.append(INDENT2); p_output.append(INDENT1);
p_output.append(iconstant.proxy_name); p_output.append(iconstant.proxy_name);
p_output.append(" = "); p_output.append(" = ");
p_output.append(itos(iconstant.value)); p_output.append(itos(iconstant.value));
p_output.append(&iconstant != &last ? ",\n" : "\n"); p_output.append(&iconstant != &last ? ",\n" : "\n");
} }
p_output.append(INDENT1 CLOSE_BLOCK); p_output.append(CLOSE_BLOCK);
if (enum_in_static_class) { if (enum_in_static_class) {
p_output.append(INDENT1 CLOSE_BLOCK); p_output.append(CLOSE_BLOCK);
} }
} }
p_output.append(CLOSE_BLOCK); // end of namespace
p_output.append("\n#pragma warning restore CS1591\n"); p_output.append("\n#pragma warning restore CS1591\n");
} }
@@ -1138,17 +1134,17 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
StringBuilder cs_icalls_content; StringBuilder cs_icalls_content;
cs_icalls_content.append("namespace " BINDINGS_NAMESPACE ";\n\n");
cs_icalls_content.append("using System;\n" cs_icalls_content.append("using System;\n"
"using System.Diagnostics.CodeAnalysis;\n" "using System.Diagnostics.CodeAnalysis;\n"
"using System.Runtime.InteropServices;\n" "using System.Runtime.InteropServices;\n"
"using Godot.NativeInterop;\n" "using Godot.NativeInterop;\n"
"\n"); "\n");
cs_icalls_content.append("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK); cs_icalls_content.append("[SuppressMessage(\"ReSharper\", \"InconsistentNaming\")]\n");
cs_icalls_content.append(INDENT1 "[SuppressMessage(\"ReSharper\", \"InconsistentNaming\")]\n"); cs_icalls_content.append("[SuppressMessage(\"ReSharper\", \"RedundantUnsafeContext\")]\n");
cs_icalls_content.append(INDENT1 "[SuppressMessage(\"ReSharper\", \"RedundantUnsafeContext\")]\n"); cs_icalls_content.append("[SuppressMessage(\"ReSharper\", \"RedundantNameQualifier\")]\n");
cs_icalls_content.append(INDENT1 "[SuppressMessage(\"ReSharper\", \"RedundantNameQualifier\")]\n"); cs_icalls_content.append("[System.Runtime.CompilerServices.SkipLocalsInit]\n");
cs_icalls_content.append(INDENT1 "[System.Runtime.CompilerServices.SkipLocalsInit]\n"); cs_icalls_content.append("internal static class " BINDINGS_CLASS_NATIVECALLS "\n{");
cs_icalls_content.append(INDENT1 "internal static class " BINDINGS_CLASS_NATIVECALLS "\n" INDENT1 "{");
cs_icalls_content.append(MEMBER_BEGIN "internal static ulong godot_api_hash = "); cs_icalls_content.append(MEMBER_BEGIN "internal static ulong godot_api_hash = ");
cs_icalls_content.append(String::num_uint64(ClassDB::get_api_hash(ClassDB::API_CORE)) + ";\n"); cs_icalls_content.append(String::num_uint64(ClassDB::get_api_hash(ClassDB::API_CORE)) + ";\n");
@@ -1165,7 +1161,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
} }
} }
cs_icalls_content.append(INDENT1 CLOSE_BLOCK CLOSE_BLOCK); cs_icalls_content.append(CLOSE_BLOCK);
String internal_methods_file = path::join(base_gen_dir, BINDINGS_CLASS_NATIVECALLS ".cs"); String internal_methods_file = path::join(base_gen_dir, BINDINGS_CLASS_NATIVECALLS ".cs");
@@ -1245,19 +1241,19 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) {
StringBuilder cs_icalls_content; StringBuilder cs_icalls_content;
cs_icalls_content.append("namespace " BINDINGS_NAMESPACE ";\n\n");
cs_icalls_content.append("using System;\n" cs_icalls_content.append("using System;\n"
"using System.Diagnostics.CodeAnalysis;\n" "using System.Diagnostics.CodeAnalysis;\n"
"using System.Runtime.InteropServices;\n" "using System.Runtime.InteropServices;\n"
"using Godot.NativeInterop;\n" "using Godot.NativeInterop;\n"
"\n"); "\n");
cs_icalls_content.append("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK); cs_icalls_content.append("[SuppressMessage(\"ReSharper\", \"InconsistentNaming\")]\n");
cs_icalls_content.append(INDENT1 "[SuppressMessage(\"ReSharper\", \"InconsistentNaming\")]\n"); cs_icalls_content.append("[SuppressMessage(\"ReSharper\", \"RedundantUnsafeContext\")]\n");
cs_icalls_content.append(INDENT1 "[SuppressMessage(\"ReSharper\", \"RedundantUnsafeContext\")]\n"); cs_icalls_content.append("[SuppressMessage(\"ReSharper\", \"RedundantNameQualifier\")]\n");
cs_icalls_content.append(INDENT1 "[SuppressMessage(\"ReSharper\", \"RedundantNameQualifier\")]\n"); cs_icalls_content.append("[System.Runtime.CompilerServices.SkipLocalsInit]\n");
cs_icalls_content.append(INDENT1 "[System.Runtime.CompilerServices.SkipLocalsInit]\n"); cs_icalls_content.append("internal static class " BINDINGS_CLASS_NATIVECALLS_EDITOR "\n" OPEN_BLOCK);
cs_icalls_content.append(INDENT1 "internal static class " BINDINGS_CLASS_NATIVECALLS_EDITOR "\n" OPEN_BLOCK_L1);
cs_icalls_content.append(INDENT2 "internal static ulong godot_api_hash = "); cs_icalls_content.append(INDENT1 "internal static ulong godot_api_hash = ");
cs_icalls_content.append(String::num_uint64(ClassDB::get_api_hash(ClassDB::API_EDITOR)) + ";\n"); cs_icalls_content.append(String::num_uint64(ClassDB::get_api_hash(ClassDB::API_EDITOR)) + ";\n");
cs_icalls_content.append(MEMBER_BEGIN "private const int VarArgsSpanThreshold = 10;\n"); cs_icalls_content.append(MEMBER_BEGIN "private const int VarArgsSpanThreshold = 10;\n");
@@ -1274,7 +1270,7 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) {
} }
} }
cs_icalls_content.append(INDENT1 CLOSE_BLOCK CLOSE_BLOCK); cs_icalls_content.append(CLOSE_BLOCK);
String internal_methods_file = path::join(base_gen_dir, BINDINGS_CLASS_NATIVECALLS_EDITOR ".cs"); String internal_methods_file = path::join(base_gen_dir, BINDINGS_CLASS_NATIVECALLS_EDITOR ".cs");
@@ -1374,6 +1370,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
StringBuilder output; StringBuilder output;
output.append("namespace " BINDINGS_NAMESPACE ";\n\n");
output.append("using System;\n"); // IntPtr output.append("using System;\n"); // IntPtr
output.append("using System.Diagnostics;\n"); // DebuggerBrowsable output.append("using System.Diagnostics;\n"); // DebuggerBrowsable
output.append("using Godot.NativeInterop;\n"); output.append("using Godot.NativeInterop;\n");
@@ -1386,8 +1384,6 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output.append("\n#nullable disable\n"); output.append("\n#nullable disable\n");
output.append("\nnamespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
const DocData::ClassDoc *class_doc = itype.class_doc; const DocData::ClassDoc *class_doc = itype.class_doc;
if (class_doc && class_doc->description.size()) { if (class_doc && class_doc->description.size()) {
@@ -1395,15 +1391,15 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>(); Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
if (summary_lines.size()) { if (summary_lines.size()) {
output.append(INDENT1 "/// <summary>\n"); output.append("/// <summary>\n");
for (int i = 0; i < summary_lines.size(); i++) { for (int i = 0; i < summary_lines.size(); i++) {
output.append(INDENT1 "/// "); output.append("/// ");
output.append(summary_lines[i]); output.append(summary_lines[i]);
output.append("\n"); output.append("\n");
} }
output.append(INDENT1 "/// </summary>\n"); output.append("/// </summary>\n");
} }
} }
@@ -1411,10 +1407,10 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
// generated C# class name. This allows introspection code to find the name associated with // generated C# class name. This allows introspection code to find the name associated with
// the class. If the attribute is not present, the C# class name can be used instead. // the class. If the attribute is not present, the C# class name can be used instead.
if (itype.name != itype.proxy_name) { if (itype.name != itype.proxy_name) {
output << INDENT1 "[GodotClassName(\"" << itype.name << "\")]\n"; output << "[GodotClassName(\"" << itype.name << "\")]\n";
} }
output.append(INDENT1 "public "); output.append("public ");
if (itype.is_singleton) { if (itype.is_singleton) {
output.append("static partial class "); output.append("static partial class ");
} else { } else {
@@ -1436,7 +1432,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
} }
} }
output.append("\n" INDENT1 "{"); output.append("\n{");
// Add constants // Add constants
@@ -1449,12 +1445,12 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output.append(MEMBER_BEGIN "/// <summary>\n"); output.append(MEMBER_BEGIN "/// <summary>\n");
for (int i = 0; i < summary_lines.size(); i++) { for (int i = 0; i < summary_lines.size(); i++) {
output.append(INDENT2 "/// "); output.append(INDENT1 "/// ");
output.append(summary_lines[i]); output.append(summary_lines[i]);
output.append("\n"); output.append("\n");
} }
output.append(INDENT2 "/// </summary>"); output.append(INDENT1 "/// </summary>");
} }
} }
@@ -1490,26 +1486,26 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>(); Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
if (summary_lines.size()) { if (summary_lines.size()) {
output.append(INDENT3 "/// <summary>\n"); output.append(INDENT2 "/// <summary>\n");
for (int i = 0; i < summary_lines.size(); i++) { for (int i = 0; i < summary_lines.size(); i++) {
output.append(INDENT3 "/// "); output.append(INDENT2 "/// ");
output.append(summary_lines[i]); output.append(summary_lines[i]);
output.append("\n"); output.append("\n");
} }
output.append(INDENT3 "/// </summary>\n"); output.append(INDENT2 "/// </summary>\n");
} }
} }
output.append(INDENT3); output.append(INDENT2);
output.append(iconstant.proxy_name); output.append(iconstant.proxy_name);
output.append(" = "); output.append(" = ");
output.append(itos(iconstant.value)); output.append(itos(iconstant.value));
output.append(&iconstant != &last ? ",\n" : "\n"); output.append(&iconstant != &last ? ",\n" : "\n");
} }
output.append(INDENT2 CLOSE_BLOCK); output.append(INDENT1 CLOSE_BLOCK);
} }
// Add properties // Add properties
@@ -1526,11 +1522,11 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output.append(MEMBER_BEGIN "private static Godot.Object singleton;\n"); output.append(MEMBER_BEGIN "private static Godot.Object singleton;\n");
output << MEMBER_BEGIN "public static Godot.Object " CS_PROPERTY_SINGLETON "\n" INDENT2 "{\n" output << MEMBER_BEGIN "public static Godot.Object " CS_PROPERTY_SINGLETON "\n" INDENT1 "{\n"
<< INDENT3 "get\n" INDENT3 "{\n" INDENT4 "if (singleton == null)\n" << INDENT2 "get\n" INDENT2 "{\n" INDENT3 "if (singleton == null)\n"
<< INDENT5 "singleton = " C_METHOD_ENGINE_GET_SINGLETON "(typeof(" << INDENT4 "singleton = " C_METHOD_ENGINE_GET_SINGLETON "(typeof("
<< itype.proxy_name << itype.proxy_name
<< ").Name);\n" INDENT4 "return singleton;\n" INDENT3 "}\n" INDENT2 "}\n"; << ").Name);\n" INDENT3 "return singleton;\n" INDENT2 "}\n" INDENT1 "}\n";
output.append(MEMBER_BEGIN "private static readonly StringName " BINDINGS_NATIVE_NAME_FIELD " = \""); output.append(MEMBER_BEGIN "private static readonly StringName " BINDINGS_NATIVE_NAME_FIELD " = \"");
output.append(itype.name); output.append(itype.name);
@@ -1556,7 +1552,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
// Add native constructor static field // Add native constructor static field
output << MEMBER_BEGIN << "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n" output << MEMBER_BEGIN << "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n"
<< INDENT2 "private static readonly unsafe delegate* unmanaged<IntPtr> " << INDENT1 "private static readonly unsafe delegate* unmanaged<IntPtr> "
<< CS_STATIC_FIELD_NATIVE_CTOR " = " ICALL_CLASSDB_GET_CONSTRUCTOR << CS_STATIC_FIELD_NATIVE_CTOR " = " ICALL_CLASSDB_GET_CONSTRUCTOR
<< "(" BINDINGS_NATIVE_NAME_FIELD ");\n"; << "(" BINDINGS_NATIVE_NAME_FIELD ");\n";
} }
@@ -1565,12 +1561,12 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
// Add default constructor // Add default constructor
if (itype.is_instantiable) { if (itype.is_instantiable) {
output << MEMBER_BEGIN "public " << itype.proxy_name << "() : this(" output << MEMBER_BEGIN "public " << itype.proxy_name << "() : this("
<< (itype.memory_own ? "true" : "false") << ")\n" OPEN_BLOCK_L2 << (itype.memory_own ? "true" : "false") << ")\n" OPEN_BLOCK_L1
<< INDENT3 "unsafe\n" INDENT3 OPEN_BLOCK << INDENT2 "unsafe\n" INDENT2 OPEN_BLOCK
<< INDENT4 "_ConstructAndInitialize(" CS_STATIC_FIELD_NATIVE_CTOR ", " << INDENT3 "_ConstructAndInitialize(" CS_STATIC_FIELD_NATIVE_CTOR ", "
<< BINDINGS_NATIVE_NAME_FIELD ", CachedType, refCounted: " << BINDINGS_NATIVE_NAME_FIELD ", CachedType, refCounted: "
<< (itype.is_ref_counted ? "true" : "false") << ");\n" << (itype.is_ref_counted ? "true" : "false") << ");\n"
<< CLOSE_BLOCK_L3 CLOSE_BLOCK_L2; << CLOSE_BLOCK_L2 CLOSE_BLOCK_L1;
} else { } else {
// Hide the constructor // Hide the constructor
output.append(MEMBER_BEGIN "internal "); output.append(MEMBER_BEGIN "internal ");
@@ -1613,14 +1609,14 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
} }
output << MEMBER_BEGIN "// ReSharper disable once InconsistentNaming\n" output << MEMBER_BEGIN "// ReSharper disable once InconsistentNaming\n"
<< INDENT2 "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n" << INDENT1 "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n"
<< INDENT2 "private static readonly StringName " << INDENT1 "private static readonly StringName "
<< CS_STATIC_FIELD_METHOD_NAME_PREFIX << imethod.name << CS_STATIC_FIELD_METHOD_NAME_PREFIX << imethod.name
<< " = \"" << imethod.name << "\";\n"; << " = \"" << imethod.name << "\";\n";
output << MEMBER_BEGIN "// ReSharper disable once InconsistentNaming\n" output << MEMBER_BEGIN "// ReSharper disable once InconsistentNaming\n"
<< INDENT2 "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n" << INDENT1 "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n"
<< INDENT2 "private static readonly StringName " << INDENT1 "private static readonly StringName "
<< CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name << CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name
<< " = \"" << imethod.proxy_name << "\";\n"; << " = \"" << imethod.proxy_name << "\";\n";
} }
@@ -1632,7 +1628,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output << MEMBER_BEGIN "protected internal " << (is_derived_type ? "override" : "virtual") output << MEMBER_BEGIN "protected internal " << (is_derived_type ? "override" : "virtual")
<< " bool " CS_METHOD_INVOKE_GODOT_CLASS_METHOD "(in godot_string_name method, " << " bool " CS_METHOD_INVOKE_GODOT_CLASS_METHOD "(in godot_string_name method, "
<< "NativeVariantPtrArgs args, int argCount, out godot_variant ret)\n" << "NativeVariantPtrArgs args, int argCount, out godot_variant ret)\n"
<< INDENT2 "{\n"; << INDENT1 "{\n";
for (const MethodInterface &imethod : itype.methods) { for (const MethodInterface &imethod : itype.methods) {
if (!imethod.is_virtual) { if (!imethod.is_virtual) {
@@ -1645,17 +1641,17 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
// pointers of generated wrappers for each method, as lookup will only happen once. // pointers of generated wrappers for each method, as lookup will only happen once.
// We check both native names (snake_case) and proxy names (PascalCase) // We check both native names (snake_case) and proxy names (PascalCase)
output << INDENT3 "if ((method == " << CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name output << INDENT2 "if ((method == " << CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name
<< " || method == " << CS_STATIC_FIELD_METHOD_NAME_PREFIX << imethod.name << " || method == " << CS_STATIC_FIELD_METHOD_NAME_PREFIX << imethod.name
<< ") && argCount == " << itos(imethod.arguments.size()) << ") && argCount == " << itos(imethod.arguments.size())
<< " && " << CS_METHOD_HAS_GODOT_CLASS_METHOD << "((godot_string_name)" << " && " << CS_METHOD_HAS_GODOT_CLASS_METHOD << "((godot_string_name)"
<< CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name << ".NativeValue))\n" << CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name << ".NativeValue))\n"
<< INDENT3 "{\n"; << INDENT2 "{\n";
if (imethod.return_type.cname != name_cache.type_void) { if (imethod.return_type.cname != name_cache.type_void) {
output << INDENT4 "var callRet = "; output << INDENT3 "var callRet = ";
} else { } else {
output << INDENT4; output << INDENT3;
} }
output << imethod.proxy_name << "("; output << imethod.proxy_name << "(";
@@ -1687,32 +1683,32 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
const TypeInterface *return_type = _get_type_or_null(imethod.return_type); const TypeInterface *return_type = _get_type_or_null(imethod.return_type);
ERR_FAIL_NULL_V(return_type, ERR_BUG); // Return type not found ERR_FAIL_NULL_V(return_type, ERR_BUG); // Return type not found
output << INDENT4 "ret = " output << INDENT3 "ret = "
<< sformat(return_type->cs_managed_to_variant, "callRet", return_type->cs_type, return_type->name) << sformat(return_type->cs_managed_to_variant, "callRet", return_type->cs_type, return_type->name)
<< ";\n" << ";\n"
<< INDENT4 "return true;\n"; << INDENT3 "return true;\n";
} else {
output << INDENT4 "ret = default;\n"
<< INDENT4 "return true;\n";
}
output << INDENT3 "}\n";
}
if (is_derived_type) {
output << INDENT3 "return base." CS_METHOD_INVOKE_GODOT_CLASS_METHOD "(method, args, argCount, out ret);\n";
} else { } else {
output << INDENT3 "ret = default;\n" output << INDENT3 "ret = default;\n"
<< INDENT3 "return false;\n"; << INDENT3 "return true;\n";
} }
output << INDENT2 "}\n"; output << INDENT2 "}\n";
}
if (is_derived_type) {
output << INDENT2 "return base." CS_METHOD_INVOKE_GODOT_CLASS_METHOD "(method, args, argCount, out ret);\n";
} else {
output << INDENT2 "ret = default;\n"
<< INDENT2 "return false;\n";
}
output << INDENT1 "}\n";
// Generate HasGodotClassMethod // Generate HasGodotClassMethod
output << MEMBER_BEGIN "protected internal " << (is_derived_type ? "override" : "virtual") output << MEMBER_BEGIN "protected internal " << (is_derived_type ? "override" : "virtual")
<< " bool " CS_METHOD_HAS_GODOT_CLASS_METHOD "(in godot_string_name method)\n" << " bool " CS_METHOD_HAS_GODOT_CLASS_METHOD "(in godot_string_name method)\n"
<< INDENT2 "{\n"; << INDENT1 "{\n";
for (const MethodInterface &imethod : itype.methods) { for (const MethodInterface &imethod : itype.methods) {
if (!imethod.is_virtual) { if (!imethod.is_virtual) {
@@ -1723,26 +1719,25 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
// again, but this time with the respective proxy name (PascalCase). It's the job of // again, but this time with the respective proxy name (PascalCase). It's the job of
// user derived classes to override the method and check for those. Our C# source // user derived classes to override the method and check for those. Our C# source
// generators take care of generating those override methods. // generators take care of generating those override methods.
output << INDENT3 "if (method == " << CS_STATIC_FIELD_METHOD_NAME_PREFIX << imethod.name output << INDENT2 "if (method == " << CS_STATIC_FIELD_METHOD_NAME_PREFIX << imethod.name
<< ")\n" INDENT3 "{\n" << ")\n" INDENT2 "{\n"
<< INDENT4 "if (" CS_METHOD_HAS_GODOT_CLASS_METHOD "(" << INDENT3 "if (" CS_METHOD_HAS_GODOT_CLASS_METHOD "("
<< CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name << CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name
<< ".NativeValue.DangerousSelfRef))\n" INDENT4 "{\n" << ".NativeValue.DangerousSelfRef))\n" INDENT3 "{\n"
<< INDENT5 "return true;\n" << INDENT4 "return true;\n"
<< INDENT4 "}\n" INDENT3 "}\n"; << INDENT3 "}\n" INDENT2 "}\n";
} }
if (is_derived_type) { if (is_derived_type) {
output << INDENT3 "return base." CS_METHOD_HAS_GODOT_CLASS_METHOD "(method);\n"; output << INDENT2 "return base." CS_METHOD_HAS_GODOT_CLASS_METHOD "(method);\n";
} else { } else {
output << INDENT3 "return false;\n"; output << INDENT2 "return false;\n";
} }
output << INDENT2 "}\n"; output << INDENT1 "}\n";
} }
output.append(INDENT1 CLOSE_BLOCK /* class */ output.append(CLOSE_BLOCK /* class */);
CLOSE_BLOCK /* namespace */);
output.append("\n" output.append("\n"
"#pragma warning restore CS1591\n" "#pragma warning restore CS1591\n"
@@ -1821,12 +1816,12 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
p_output.append(MEMBER_BEGIN "/// <summary>\n"); p_output.append(MEMBER_BEGIN "/// <summary>\n");
for (int i = 0; i < summary_lines.size(); i++) { for (int i = 0; i < summary_lines.size(); i++) {
p_output.append(INDENT2 "/// "); p_output.append(INDENT1 "/// ");
p_output.append(summary_lines[i]); p_output.append(summary_lines[i]);
p_output.append("\n"); p_output.append("\n");
} }
p_output.append(INDENT2 "/// </summary>"); p_output.append(INDENT1 "/// </summary>");
} }
} }
@@ -1841,15 +1836,15 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
p_output.append(prop_cs_type); p_output.append(prop_cs_type);
p_output.append(" "); p_output.append(" ");
p_output.append(p_iprop.proxy_name); p_output.append(p_iprop.proxy_name);
p_output.append("\n" OPEN_BLOCK_L2); p_output.append("\n" OPEN_BLOCK_L1);
if (getter) { if (getter) {
p_output.append(INDENT3 "get\n" p_output.append(INDENT2 "get\n"
// TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that) // TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that)
"#pragma warning disable CS0618 // Disable warning about obsolete method\n" "#pragma warning disable CS0618 // Disable warning about obsolete method\n"
OPEN_BLOCK_L3 INDENT4); OPEN_BLOCK_L2 INDENT3);
p_output.append("return "); p_output.append("return ");
p_output.append(getter->proxy_name + "("); p_output.append(getter->proxy_name + "(");
@@ -1866,19 +1861,19 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
} }
p_output.append(");\n" p_output.append(");\n"
CLOSE_BLOCK_L3 CLOSE_BLOCK_L2
// TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that) // TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that)
"#pragma warning restore CS0618\n"); "#pragma warning restore CS0618\n");
} }
if (setter) { if (setter) {
p_output.append(INDENT3 "set\n" p_output.append(INDENT2 "set\n"
// TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that) // TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that)
"#pragma warning disable CS0618 // Disable warning about obsolete method\n" "#pragma warning disable CS0618 // Disable warning about obsolete method\n"
OPEN_BLOCK_L3 INDENT4); OPEN_BLOCK_L2 INDENT3);
p_output.append(setter->proxy_name + "("); p_output.append(setter->proxy_name + "(");
if (p_iprop.index != -1) { if (p_iprop.index != -1) {
@@ -1894,13 +1889,13 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
} }
p_output.append("value);\n" p_output.append("value);\n"
CLOSE_BLOCK_L3 CLOSE_BLOCK_L2
// TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that) // TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that)
"#pragma warning restore CS0618\n"); "#pragma warning restore CS0618\n");
} }
p_output.append(CLOSE_BLOCK_L2); p_output.append(CLOSE_BLOCK_L1);
return OK; return OK;
} }
@@ -1929,7 +1924,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
if (!p_imethod.is_static) { if (!p_imethod.is_static) {
if (p_itype.cs_in.size()) { if (p_itype.cs_in.size()) {
cs_in_statements << sformat(p_itype.cs_in, p_itype.c_type, "this", cs_in_statements << sformat(p_itype.cs_in, p_itype.c_type, "this",
String(), String(), String(), INDENT3); String(), String(), String(), INDENT2);
} }
icall_params += ", " + sformat(p_itype.cs_in_expr, "this"); icall_params += ", " + sformat(p_itype.cs_in_expr, "this");
@@ -1997,7 +1992,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
String arg_or_defval_local = iarg.name; String arg_or_defval_local = iarg.name;
arg_or_defval_local += "OrDefVal"; arg_or_defval_local += "OrDefVal";
cs_in_statements << INDENT3 << arg_cs_type << " " << arg_or_defval_local << " = " << iarg.name; cs_in_statements << INDENT2 << arg_cs_type << " " << arg_or_defval_local << " = " << iarg.name;
if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL) { if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL) {
cs_in_statements << ".HasValue ? "; cs_in_statements << ".HasValue ? ";
@@ -2024,7 +2019,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
if (arg_type->cs_in.size()) { if (arg_type->cs_in.size()) {
cs_in_statements << sformat(arg_type->cs_in, arg_type->c_type, arg_or_defval_local, cs_in_statements << sformat(arg_type->cs_in, arg_type->c_type, arg_or_defval_local,
String(), String(), String(), INDENT3); String(), String(), String(), INDENT2);
} }
if (arg_type->cs_in_expr.is_empty()) { if (arg_type->cs_in_expr.is_empty()) {
@@ -2042,7 +2037,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
} else { } else {
if (arg_type->cs_in.size()) { if (arg_type->cs_in.size()) {
cs_in_statements << sformat(arg_type->cs_in, arg_type->c_type, iarg.name, cs_in_statements << sformat(arg_type->cs_in, arg_type->c_type, iarg.name,
String(), String(), String(), INDENT3); String(), String(), String(), INDENT2);
} }
icall_params += arg_type->cs_in_expr.is_empty() ? iarg.name : sformat(arg_type->cs_in_expr, iarg.name, arg_type->c_type); icall_params += arg_type->cs_in_expr.is_empty() ? iarg.name : sformat(arg_type->cs_in_expr, iarg.name, arg_type->c_type);
@@ -2055,7 +2050,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
{ {
if (!p_imethod.is_virtual && !p_imethod.requires_object_call) { if (!p_imethod.is_virtual && !p_imethod.requires_object_call) {
p_output << MEMBER_BEGIN "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n" p_output << MEMBER_BEGIN "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n"
<< INDENT2 "private static readonly IntPtr " << method_bind_field << " = "; << INDENT1 "private static readonly IntPtr " << method_bind_field << " = ";
if (p_itype.is_singleton) { if (p_itype.is_singleton) {
// Singletons are static classes. They don't derive Godot.Object, // Singletons are static classes. They don't derive Godot.Object,
@@ -2076,12 +2071,12 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
p_output.append(MEMBER_BEGIN "/// <summary>\n"); p_output.append(MEMBER_BEGIN "/// <summary>\n");
for (int i = 0; i < summary_lines.size(); i++) { for (int i = 0; i < summary_lines.size(); i++) {
p_output.append(INDENT2 "/// "); p_output.append(INDENT1 "/// ");
p_output.append(summary_lines[i]); p_output.append(summary_lines[i]);
p_output.append("\n"); p_output.append("\n");
} }
p_output.append(INDENT2 "/// </summary>"); p_output.append(INDENT1 "/// </summary>");
} }
} }
@@ -2116,15 +2111,15 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
p_output.append(return_cs_type + " "); p_output.append(return_cs_type + " ");
p_output.append(p_imethod.proxy_name + "("); p_output.append(p_imethod.proxy_name + "(");
p_output.append(arguments_sig + ")\n" OPEN_BLOCK_L2); p_output.append(arguments_sig + ")\n" OPEN_BLOCK_L1);
if (p_imethod.is_virtual) { if (p_imethod.is_virtual) {
// Godot virtual method must be overridden, therefore we return a default value by default. // Godot virtual method must be overridden, therefore we return a default value by default.
if (return_type->cname == name_cache.type_void) { if (return_type->cname == name_cache.type_void) {
p_output.append(CLOSE_BLOCK_L2); p_output.append(CLOSE_BLOCK_L1);
} else { } else {
p_output.append(INDENT3 "return default;\n" CLOSE_BLOCK_L2); p_output.append(INDENT2 "return default;\n" CLOSE_BLOCK_L1);
} }
return OK; // Won't increment method bind count return OK; // Won't increment method bind count
@@ -2133,7 +2128,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
if (p_imethod.requires_object_call) { if (p_imethod.requires_object_call) {
// Fallback to Godot's object.Call(string, params) // Fallback to Godot's object.Call(string, params)
p_output.append(INDENT3 CS_METHOD_CALL "(\""); p_output.append(INDENT2 CS_METHOD_CALL "(\"");
p_output.append(p_imethod.name); p_output.append(p_imethod.name);
p_output.append("\""); p_output.append("\"");
@@ -2142,7 +2137,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
p_output.append(iarg.name); p_output.append(iarg.name);
} }
p_output.append(");\n" CLOSE_BLOCK_L2); p_output.append(");\n" CLOSE_BLOCK_L1);
return OK; // Won't increment method bind count return OK; // Won't increment method bind count
} }
@@ -2161,16 +2156,16 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
} }
if (return_type->cname == name_cache.type_void) { if (return_type->cname == name_cache.type_void) {
p_output << INDENT3 << im_call << "(" << icall_params << ");\n"; p_output << INDENT2 << im_call << "(" << icall_params << ");\n";
} else if (return_type->cs_out.is_empty()) { } else if (return_type->cs_out.is_empty()) {
p_output << INDENT3 "return " << im_call << "(" << icall_params << ");\n"; p_output << INDENT2 "return " << im_call << "(" << icall_params << ");\n";
} else { } else {
p_output.append(sformat(return_type->cs_out, im_call, icall_params, p_output.append(sformat(return_type->cs_out, im_call, icall_params,
return_cs_type, return_type->c_type_out, String(), INDENT3)); return_cs_type, return_type->c_type_out, String(), INDENT2));
p_output.append("\n"); p_output.append("\n");
} }
p_output.append(CLOSE_BLOCK_L2); p_output.append(CLOSE_BLOCK_L1);
} }
p_method_bind_count++; p_method_bind_count++;
@@ -2217,12 +2212,12 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
p_output.append(MEMBER_BEGIN "/// <summary>\n"); p_output.append(MEMBER_BEGIN "/// <summary>\n");
for (int i = 0; i < summary_lines.size(); i++) { for (int i = 0; i < summary_lines.size(); i++) {
p_output.append(INDENT2 "/// "); p_output.append(INDENT1 "/// ");
p_output.append(summary_lines[i]); p_output.append(summary_lines[i]);
p_output.append("\n"); p_output.append("\n");
} }
p_output.append(INDENT2 "/// </summary>"); p_output.append(INDENT1 "/// </summary>");
} }
} }
@@ -2252,7 +2247,7 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
// Cached signal name (StringName) // Cached signal name (StringName)
p_output.append(MEMBER_BEGIN "// ReSharper disable once InconsistentNaming\n"); p_output.append(MEMBER_BEGIN "// ReSharper disable once InconsistentNaming\n");
p_output.append(INDENT2 "[DebuggerBrowsable(DebuggerBrowsableState.Never)]" MEMBER_BEGIN p_output.append(INDENT1 "[DebuggerBrowsable(DebuggerBrowsableState.Never)]" MEMBER_BEGIN
"private static readonly StringName " CS_STATIC_FIELD_SIGNAL_NAME_PREFIX); "private static readonly StringName " CS_STATIC_FIELD_SIGNAL_NAME_PREFIX);
p_output.append(p_isignal.name); p_output.append(p_isignal.name);
p_output.append(" = \""); p_output.append(" = \"");
@@ -2270,7 +2265,7 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
p_output.append(delegate_name); p_output.append(delegate_name);
p_output.append(" "); p_output.append(" ");
p_output.append(p_isignal.proxy_name); p_output.append(p_isignal.proxy_name);
p_output.append("\n" OPEN_BLOCK_L2 INDENT3); p_output.append("\n" OPEN_BLOCK_L1 INDENT2);
if (p_itype.is_singleton) { if (p_itype.is_singleton) {
p_output.append("add => " CS_PROPERTY_SINGLETON ".Connect(" CS_STATIC_FIELD_SIGNAL_NAME_PREFIX); p_output.append("add => " CS_PROPERTY_SINGLETON ".Connect(" CS_STATIC_FIELD_SIGNAL_NAME_PREFIX);
@@ -2282,14 +2277,14 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
p_output.append(", new Callable(value));\n"); p_output.append(", new Callable(value));\n");
if (p_itype.is_singleton) { if (p_itype.is_singleton) {
p_output.append(INDENT3 "remove => " CS_PROPERTY_SINGLETON ".Disconnect(" CS_STATIC_FIELD_SIGNAL_NAME_PREFIX); p_output.append(INDENT2 "remove => " CS_PROPERTY_SINGLETON ".Disconnect(" CS_STATIC_FIELD_SIGNAL_NAME_PREFIX);
} else { } else {
p_output.append(INDENT3 "remove => Disconnect(" CS_STATIC_FIELD_SIGNAL_NAME_PREFIX); p_output.append(INDENT2 "remove => Disconnect(" CS_STATIC_FIELD_SIGNAL_NAME_PREFIX);
} }
p_output.append(p_isignal.name); p_output.append(p_isignal.name);
p_output.append(", new Callable(value));\n"); p_output.append(", new Callable(value));\n");
p_output.append(CLOSE_BLOCK_L2); p_output.append(CLOSE_BLOCK_L1);
} }
return OK; return OK;
@@ -2332,8 +2327,8 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
c_in_statements c_in_statements
<< sformat(c_in_vararg, return_type->c_type, c_param_name, << sformat(c_in_vararg, return_type->c_type, c_param_name,
String(), String(), String(), INDENT4) String(), String(), String(), INDENT3)
<< INDENT4 C_LOCAL_PTRCALL_ARGS "[" << itos(i) << INDENT3 C_LOCAL_PTRCALL_ARGS "[" << itos(i)
<< "] = new IntPtr(&" << c_param_name << "_in);\n"; << "] = new IntPtr(&" << c_param_name << "_in);\n";
} }
} else { } else {
@@ -2342,7 +2337,7 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
} }
if (arg_type->c_in.size()) { if (arg_type->c_in.size()) {
c_in_statements << sformat(arg_type->c_in, arg_type->c_type, c_param_name, c_in_statements << sformat(arg_type->c_in, arg_type->c_type, c_param_name,
String(), String(), String(), INDENT3); String(), String(), String(), INDENT2);
} }
c_args_var_content << sformat(arg_type->c_arg_in, c_param_name); c_args_var_content << sformat(arg_type->c_arg_in, c_param_name);
} }
@@ -2370,7 +2365,7 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
ptrcall_return_type = return_type->c_type; ptrcall_return_type = return_type->c_type;
} }
r_output << INDENT3; r_output << INDENT2;
if (return_type->is_ref_counted || return_type->c_type_is_disposable_struct) { if (return_type->is_ref_counted || return_type->c_type_is_disposable_struct) {
r_output << "using "; r_output << "using ";
@@ -2386,8 +2381,8 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
} }
if (!p_icall.is_static) { if (!p_icall.is_static) {
r_output << INDENT3 "if (" CS_PARAM_INSTANCE " == IntPtr.Zero)\n" r_output << INDENT2 "if (" CS_PARAM_INSTANCE " == IntPtr.Zero)\n"
<< INDENT4 "throw new ArgumentNullException(nameof(" CS_PARAM_INSTANCE "));\n"; << INDENT3 "throw new ArgumentNullException(nameof(" CS_PARAM_INSTANCE "));\n";
} }
String argc_str = itos(p_icall.get_arguments_count()); String argc_str = itos(p_icall.get_arguments_count());
@@ -2454,47 +2449,47 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
p_icall.get_arguments_count(); p_icall.get_arguments_count();
r_output << INDENT3 "int vararg_length = " << vararg_arg << ".Length;\n" r_output << INDENT2 "int vararg_length = " << vararg_arg << ".Length;\n"
<< INDENT3 "int total_length = " << real_argc_str << " + vararg_length;\n"; << INDENT2 "int total_length = " << real_argc_str << " + vararg_length;\n";
r_output << INDENT3 "Span<godot_variant.movable> varargs_span = vararg_length <= VarArgsSpanThreshold ?\n" r_output << INDENT2 "Span<godot_variant.movable> varargs_span = vararg_length <= VarArgsSpanThreshold ?\n"
<< INDENT4 "stackalloc godot_variant.movable[VarArgsSpanThreshold].Cleared() :\n" << INDENT3 "stackalloc godot_variant.movable[VarArgsSpanThreshold].Cleared() :\n"
<< INDENT4 "new godot_variant.movable[vararg_length];\n"; << INDENT3 "new godot_variant.movable[vararg_length];\n";
r_output << INDENT3 "Span<IntPtr> " C_LOCAL_PTRCALL_ARGS "_span = total_length <= VarArgsSpanThreshold ?\n" r_output << INDENT2 "Span<IntPtr> " C_LOCAL_PTRCALL_ARGS "_span = total_length <= VarArgsSpanThreshold ?\n"
<< INDENT4 "stackalloc IntPtr[VarArgsSpanThreshold] :\n" << INDENT3 "stackalloc IntPtr[VarArgsSpanThreshold] :\n"
<< INDENT4 "new IntPtr[total_length];\n"; << INDENT3 "new IntPtr[total_length];\n";
r_output << INDENT3 "using var variantSpanDisposer = new VariantSpanDisposer(varargs_span);\n"; r_output << INDENT2 "using var variantSpanDisposer = new VariantSpanDisposer(varargs_span);\n";
r_output << INDENT3 "fixed (godot_variant* varargs = &MemoryMarshal.GetReference(varargs_span).DangerousSelfRef)\n" r_output << INDENT2 "fixed (godot_variant* varargs = &MemoryMarshal.GetReference(varargs_span).DangerousSelfRef)\n"
<< INDENT3 "fixed (IntPtr* " C_LOCAL_PTRCALL_ARGS " = " << INDENT2 "fixed (IntPtr* " C_LOCAL_PTRCALL_ARGS " = "
"&MemoryMarshal.GetReference(" C_LOCAL_PTRCALL_ARGS "_span))\n" "&MemoryMarshal.GetReference(" C_LOCAL_PTRCALL_ARGS "_span))\n"
<< OPEN_BLOCK_L3; << OPEN_BLOCK_L2;
r_output << c_in_statements.as_string(); r_output << c_in_statements.as_string();
r_output << INDENT4 "for (int i = 0; i < vararg_length; i++) " OPEN_BLOCK r_output << INDENT3 "for (int i = 0; i < vararg_length; i++) " OPEN_BLOCK
<< INDENT5 "varargs[i] = " C_METHOD_MANAGED_TO_VARIANT "(" << vararg_arg << "[i]);\n" << INDENT4 "varargs[i] = " C_METHOD_MANAGED_TO_VARIANT "(" << vararg_arg << "[i]);\n"
<< INDENT5 C_LOCAL_PTRCALL_ARGS "[" << real_argc_str << " + i] = new IntPtr(&varargs[i]);\n" << INDENT4 C_LOCAL_PTRCALL_ARGS "[" << real_argc_str << " + i] = new IntPtr(&varargs[i]);\n"
<< CLOSE_BLOCK_L4; << CLOSE_BLOCK_L3;
generate_call_and_return_stmts(INDENT4);
r_output << CLOSE_BLOCK_L3;
} else {
r_output << c_in_statements.as_string();
r_output << INDENT3 "void** " C_LOCAL_PTRCALL_ARGS " = stackalloc void*["
<< argc_str << "] { " << c_args_var_content.as_string() << " };\n";
generate_call_and_return_stmts(INDENT3); generate_call_and_return_stmts(INDENT3);
}
} else {
generate_call_and_return_stmts(INDENT3);
}
r_output << CLOSE_BLOCK_L2; r_output << CLOSE_BLOCK_L2;
} else {
r_output << c_in_statements.as_string();
r_output << INDENT2 "void** " C_LOCAL_PTRCALL_ARGS " = stackalloc void*["
<< argc_str << "] { " << c_args_var_content.as_string() << " };\n";
generate_call_and_return_stmts(INDENT2);
}
} else {
generate_call_and_return_stmts(INDENT2);
}
r_output << CLOSE_BLOCK_L1;
return OK; return OK;
} }

View File

@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<LangVersion>9</LangVersion> <LangVersion>10</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -706,11 +706,7 @@ namespace Godot.Bridge
} }
else else
{ {
#if NET6_0_OR_GREATER interopProperties = ((godotsharp_property_info*)NativeMemory.Alloc((nuint)length))!;
interopProperties = ((godotsharp_property_info*)NativeMemory.Alloc(length))!;
#else
interopProperties = ((godotsharp_property_info*)Marshal.AllocHGlobal(length))!;
#endif
} }
try try
@@ -746,13 +742,7 @@ namespace Godot.Bridge
interopProperties[i].Dispose(); interopProperties[i].Dispose();
if (!useStack) if (!useStack)
{
#if NET6_0_OR_GREATER
NativeMemory.Free(interopProperties); NativeMemory.Free(interopProperties);
#else
Marshal.FreeHGlobal((IntPtr)interopProperties);
#endif
}
} }
} }
catch (Exception e) catch (Exception e)
@@ -836,11 +826,7 @@ namespace Godot.Bridge
} }
else else
{ {
#if NET6_0_OR_GREATER interopDefaultValues = ((godotsharp_property_def_val_pair*)NativeMemory.Alloc((nuint)length))!;
interopDefaultValues = ((godotsharp_property_def_val_pair*)NativeMemory.Alloc(length))!;
#else
interopDefaultValues = ((godotsharp_property_def_val_pair*)Marshal.AllocHGlobal(length))!;
#endif
} }
try try
@@ -871,13 +857,7 @@ namespace Godot.Bridge
interopDefaultValues[i].Dispose(); interopDefaultValues[i].Dispose();
if (!useStack) if (!useStack)
{
#if NET6_0_OR_GREATER
NativeMemory.Free(interopDefaultValues); NativeMemory.Free(interopDefaultValues);
#else
Marshal.FreeHGlobal((IntPtr)interopDefaultValues);
#endif
}
} }
} }
catch (Exception e) catch (Exception e)

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Godot.NativeInterop; using Godot.NativeInterop;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
namespace Godot namespace Godot

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
namespace Godot namespace Godot

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -1603,7 +1603,7 @@ namespace Godot
/// <seealso cref="XMLUnescape(string)"/> /// <seealso cref="XMLUnescape(string)"/>
/// <param name="instance">The string to escape.</param> /// <param name="instance">The string to escape.</param>
/// <returns>The escaped string.</returns> /// <returns>The escaped string.</returns>
public static string? XMLEscape(this string instance) public static string XMLEscape(this string instance)
{ {
return SecurityElement.Escape(instance); return SecurityElement.Escape(instance);
} }

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -1,8 +1,3 @@
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View File

@@ -0,0 +1,5 @@
#if REAL_T_IS_DOUBLE
global using real_t = System.Double;
#else
global using real_t = System.Single;
#endif

View File

@@ -4,7 +4,7 @@
<OutputPath>bin/$(Configuration)</OutputPath> <OutputPath>bin/$(Configuration)</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<RootNamespace>Godot</RootNamespace> <RootNamespace>Godot</RootNamespace>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<DocumentationFile>$(OutputPath)/$(AssemblyName).xml</DocumentationFile> <DocumentationFile>$(OutputPath)/$(AssemblyName).xml</DocumentationFile>
<EnableDefaultItems>false</EnableDefaultItems> <EnableDefaultItems>false</EnableDefaultItems>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@@ -97,6 +97,7 @@
<Compile Include="Core\Vector3i.cs" /> <Compile Include="Core\Vector3i.cs" />
<Compile Include="Core\Vector4.cs" /> <Compile Include="Core\Vector4.cs" />
<Compile Include="Core\Vector4i.cs" /> <Compile Include="Core\Vector4i.cs" />
<Compile Include="GlobalUsings.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<!-- <!--

View File

@@ -4,11 +4,11 @@
<OutputPath>bin/$(Configuration)</OutputPath> <OutputPath>bin/$(Configuration)</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<RootNamespace>Godot</RootNamespace> <RootNamespace>Godot</RootNamespace>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<DocumentationFile>$(OutputPath)/$(AssemblyName).xml</DocumentationFile> <DocumentationFile>$(OutputPath)/$(AssemblyName).xml</DocumentationFile>
<EnableDefaultItems>false</EnableDefaultItems> <EnableDefaultItems>false</EnableDefaultItems>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>9</LangVersion> <LangVersion>10</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<DefineConstants>$(DefineConstants);GODOT</DefineConstants> <DefineConstants>$(DefineConstants);GODOT</DefineConstants>