diff options
Diffstat (limited to 'modules/mono')
45 files changed, 984 insertions, 636 deletions
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py index c7f9b39b48..8141bc2422 100644 --- a/modules/mono/build_scripts/mono_configure.py +++ b/modules/mono/build_scripts/mono_configure.py @@ -3,11 +3,11 @@ import os.path def is_desktop(platform): - return platform in ["windows", "macos", "linuxbsd", "server", "uwp", "haiku"] + return platform in ["windows", "macos", "linuxbsd", "uwp", "haiku"] def is_unix_like(platform): - return platform in ["macos", "linuxbsd", "server", "android", "haiku", "ios"] + return platform in ["macos", "linuxbsd", "android", "haiku", "ios"] def module_supports_tools_on(platform): @@ -18,7 +18,7 @@ def configure(env, env_mono): # is_android = env["platform"] == "android" # is_javascript = env["platform"] == "javascript" # is_ios = env["platform"] == "ios" - # is_ios_sim = is_ios and env["arch"] in ["x86", "x86_64"] + # is_ios_sim = is_ios and env["arch"] in ["x86_32", "x86_64"] tools_enabled = env["tools"] @@ -82,7 +82,7 @@ def find_dotnet_app_host_dir(env): dotnet_root = env["dotnet_root"] if not dotnet_root: - dotnet_cmd = find_executable("dotnet") + dotnet_cmd = find_dotnet_executable(env["arch"]) if dotnet_cmd: sdk_path = find_dotnet_sdk(dotnet_cmd, dotnet_version) if sdk_path: @@ -128,27 +128,22 @@ def find_dotnet_app_host_dir(env): def determine_runtime_identifier(env): + # The keys are Godot's names, the values are the Microsoft's names. + # List: https://docs.microsoft.com/en-us/dotnet/core/rid-catalog names_map = { "windows": "win", "macos": "osx", "linuxbsd": "linux", - "server": "linux", # FIXME: Is server linux only, or also macos? } - - # .NET RID architectures: x86, x64, arm, or arm64 - + arch_map = { + "x86_64": "x64", + "x86_32": "x86", + "arm64": "arm64", + "arm32": "arm", + } platform = env["platform"] - if is_desktop(platform): - if env["arch"] in ["arm", "arm32"]: - rid = "arm" - elif env["arch"] == "arm64": - rid = "arm64" - else: - bits = env["bits"] - bit_arch_map = {"64": "x64", "32": "x86"} - rid = bit_arch_map[bits] - return "%s-%s" % (names_map[platform], rid) + return "%s-%s" % (names_map[platform], arch_map[env["arch"]]) else: raise NotImplementedError() @@ -186,6 +181,35 @@ def find_app_host_version(dotnet_cmd, search_version_str): return "" +def find_dotnet_arch(dotnet_cmd): + import subprocess + + try: + env = dict(os.environ, DOTNET_CLI_UI_LANGUAGE="en-US") + lines = subprocess.check_output([dotnet_cmd, "--info"], env=env).splitlines() + + for line_bytes in lines: + line = line_bytes.decode("utf-8") + + parts = line.split(":", 1) + if len(parts) < 2: + continue + + arch_str = parts[0].strip() + if arch_str != "Architecture": + continue + + arch_value = parts[1].strip() + arch_map = {"x64": "x86_64", "x86": "x86_32", "arm64": "arm64", "arm32": "arm32"} + return arch_map[arch_value] + except (subprocess.CalledProcessError, OSError) as e: + import sys + + print(e, file=sys.stderr) + + return "" + + def find_dotnet_sdk(dotnet_cmd, search_version_str): import subprocess from distutils.version import LooseVersion @@ -248,24 +272,36 @@ def find_dotnet_cli_rid(dotnet_cmd): ENV_PATH_SEP = ";" if os.name == "nt" else ":" -def find_executable(name): +def find_dotnet_executable(arch): is_windows = os.name == "nt" windows_exts = os.environ["PATHEXT"].split(ENV_PATH_SEP) if is_windows else None path_dirs = os.environ["PATH"].split(ENV_PATH_SEP) search_dirs = path_dirs + [os.getcwd()] # cwd is last in the list + for dir in path_dirs: + search_dirs += [ + os.path.join(dir, "x64"), + os.path.join(dir, "x86"), + os.path.join(dir, "arm64"), + os.path.join(dir, "arm32"), + ] # search subfolders for cross compiling + for dir in search_dirs: - path = os.path.join(dir, name) + path = os.path.join(dir, "dotnet") if is_windows: for extension in windows_exts: path_with_ext = path + extension if os.path.isfile(path_with_ext) and os.access(path_with_ext, os.X_OK): - return path_with_ext + sdk_arch = find_dotnet_arch(path_with_ext) + if sdk_arch == arch or arch == "": + return path_with_ext else: if os.path.isfile(path) and os.access(path, os.X_OK): - return path + sdk_arch = find_dotnet_arch(path) + if sdk_arch == arch or arch == "": + return path return "" diff --git a/modules/mono/config.py b/modules/mono/config.py index d156877929..b599414a2c 100644 --- a/modules/mono/config.py +++ b/modules/mono/config.py @@ -1,6 +1,6 @@ -# Prior to .NET Core, we supported these: ["windows", "macos", "linuxbsd", "server", "android", "haiku", "javascript", "ios"] +# Prior to .NET Core, we supported these: ["windows", "macos", "linuxbsd", "android", "haiku", "javascript", "ios"] # Eventually support for each them should be added back (except Haiku if not supported by .NET Core) -supported_platforms = ["windows", "macos", "linuxbsd", "server"] +supported_platforms = ["windows", "macos", "linuxbsd"] def can_build(env, platform): diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props index 652b9e8e43..ad41ab04d5 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props @@ -77,7 +77,6 @@ <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'windows' ">GODOT_WINDOWS;GODOT_PC</GodotPlatformConstants> <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'linuxbsd' ">GODOT_LINUXBSD;GODOT_PC</GodotPlatformConstants> <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'macos' ">GODOT_OSX;GODOT_MACOS;GODOT_PC</GodotPlatformConstants> - <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'server' ">GODOT_SERVER;GODOT_PC</GodotPlatformConstants> <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'uwp' ">GODOT_UWP;GODOT_PC</GodotPlatformConstants> <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'haiku' ">GODOT_HAIKU;GODOT_PC</GodotPlatformConstants> <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'android' ">GODOT_ANDROID;GODOT_MOBILE</GodotPlatformConstants> diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs index c1ae993251..3dfa8000ba 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs @@ -1,6 +1,7 @@ using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; namespace Godot.SourceGenerators { @@ -19,7 +20,7 @@ namespace Godot.SourceGenerators "must be declared with the partial modifier."; context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GODOT-G0001", + new DiagnosticDescriptor(id: "GD0001", title: message, messageFormat: message, category: "Usage", @@ -51,7 +52,7 @@ namespace Godot.SourceGenerators "containing types must be declared with the partial modifier."; context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GODOT-G0002", + new DiagnosticDescriptor(id: "GD0002", title: message, messageFormat: message, category: "Usage", @@ -78,7 +79,7 @@ namespace Godot.SourceGenerators " Remove the 'static' modifier or the '[Export]' attribute."; context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GODOT-G0101", + new DiagnosticDescriptor(id: "GD0101", title: message, messageFormat: message, category: "Usage", @@ -104,7 +105,7 @@ namespace Godot.SourceGenerators string description = $"{message}. Use a supported type or remove the '[Export]' attribute."; context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GODOT-G0102", + new DiagnosticDescriptor(id: "GD0102", title: message, messageFormat: message, category: "Usage", @@ -132,7 +133,7 @@ namespace Godot.SourceGenerators $"{message}. Exported properties must be writable."; context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GODOT-G0103", + new DiagnosticDescriptor(id: "GD0103", title: message, messageFormat: message, category: "Usage", @@ -156,7 +157,7 @@ namespace Godot.SourceGenerators string description = $"{message}. Exported properties must be readable."; context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GODOT-G0104", + new DiagnosticDescriptor(id: "GD0104", title: message, messageFormat: message, category: "Usage", @@ -181,7 +182,7 @@ namespace Godot.SourceGenerators string description = $"{message}. Rename the delegate accordingly or remove the '[Signal]' attribute."; context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GODOT-G0201", + new DiagnosticDescriptor(id: "GD0201", title: message, messageFormat: message, category: "Usage", @@ -192,7 +193,31 @@ namespace Godot.SourceGenerators location?.SourceTree?.FilePath)); } - public static void ReportSignalDelegateSignatureNotSupported( + public static void ReportSignalParameterTypeNotSupported( + GeneratorExecutionContext context, + IParameterSymbol parameterSymbol) + { + var locations = parameterSymbol.Locations; + var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault(); + + string message = "The parameter of the delegate signature of the signal " + + $"is not supported: '{parameterSymbol.ToDisplayString()}'"; + + string description = $"{message}. Use supported types only or remove the '[Signal]' attribute."; + + context.ReportDiagnostic(Diagnostic.Create( + new DiagnosticDescriptor(id: "GD0202", + title: message, + messageFormat: message, + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + description), + location, + location?.SourceTree?.FilePath)); + } + + public static void ReportSignalDelegateSignatureMustReturnVoid( GeneratorExecutionContext context, INamedTypeSymbol delegateSymbol) { @@ -200,12 +225,12 @@ namespace Godot.SourceGenerators var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault(); string message = "The delegate signature of the signal " + - $"is not supported: '{delegateSymbol.ToDisplayString()}'"; + $"must return void: '{delegateSymbol.ToDisplayString()}'"; - string description = $"{message}. Use supported types only or remove the '[Signal]' attribute."; + string description = $"{message}. Return void or remove the '[Signal]' attribute."; context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GODOT-G0202", + new DiagnosticDescriptor(id: "GD0203", title: message, messageFormat: message, category: "Usage", @@ -215,5 +240,97 @@ namespace Godot.SourceGenerators location, location?.SourceTree?.FilePath)); } + + public static readonly DiagnosticDescriptor GenericTypeArgumentMustBeVariantRule = + new DiagnosticDescriptor(id: "GD0301", + title: "The generic type argument must be a Variant compatible type", + messageFormat: "The generic type argument must be a Variant compatible type: {0}", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "The generic type argument must be a Variant compatible type. Use a Variant compatible type as the generic type argument."); + + public static void ReportGenericTypeArgumentMustBeVariant( + SyntaxNodeAnalysisContext context, + SyntaxNode typeArgumentSyntax, + ISymbol typeArgumentSymbol) + { + string message = "The generic type argument " + + $"must be a Variant compatible type: '{typeArgumentSymbol.ToDisplayString()}'"; + + string description = $"{message}. Use a Variant compatible type as the generic type argument."; + + context.ReportDiagnostic(Diagnostic.Create( + new DiagnosticDescriptor(id: "GD0301", + title: message, + messageFormat: message, + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + description), + typeArgumentSyntax.GetLocation(), + typeArgumentSyntax.SyntaxTree.FilePath)); + } + + public static readonly DiagnosticDescriptor GenericTypeParameterMustBeVariantAnnotatedRule = + new DiagnosticDescriptor(id: "GD0302", + title: "The generic type parameter must be annotated with the MustBeVariant attribute", + messageFormat: "The generic type argument must be a Variant type: {0}", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "The generic type argument must be a Variant type. Use a Variant type as the generic type argument."); + + public static void ReportGenericTypeParameterMustBeVariantAnnotated( + SyntaxNodeAnalysisContext context, + SyntaxNode typeArgumentSyntax, + ISymbol typeArgumentSymbol) + { + string message = "The generic type parameter must be annotated with the MustBeVariant attribute"; + + string description = $"{message}. Add the MustBeVariant attribute to the generic type parameter."; + + context.ReportDiagnostic(Diagnostic.Create( + new DiagnosticDescriptor(id: "GD0302", + title: message, + messageFormat: message, + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + description), + typeArgumentSyntax.GetLocation(), + typeArgumentSyntax.SyntaxTree.FilePath)); + } + + public static readonly DiagnosticDescriptor TypeArgumentParentSymbolUnhandledRule = + new DiagnosticDescriptor(id: "GD0303", + title: "The generic type parameter must be annotated with the MustBeVariant attribute", + messageFormat: "The generic type argument must be a Variant type: {0}", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "The generic type argument must be a Variant type. Use a Variant type as the generic type argument."); + + public static void ReportTypeArgumentParentSymbolUnhandled( + SyntaxNodeAnalysisContext context, + SyntaxNode typeArgumentSyntax, + ISymbol parentSymbol) + { + string message = $"Symbol '{parentSymbol.ToDisplayString()}' parent of a type argument " + + "that must be Variant compatible was not handled."; + + string description = $"{message}. Handle type arguments that are children of the unhandled symbol type."; + + context.ReportDiagnostic(Diagnostic.Create( + new DiagnosticDescriptor(id: "GD0303", + title: message, + messageFormat: message, + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + description), + typeArgumentSyntax.GetLocation(), + typeArgumentSyntax.SyntaxTree.FilePath)); + } } } 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 bac4708165..d868678179 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs @@ -177,6 +177,9 @@ namespace Godot.SourceGenerators public static bool IsGodotSignalAttribute(this INamedTypeSymbol symbol) => symbol.ToString() == GodotClasses.SignalAttr; + public static bool IsGodotMustBeVariantAttribute(this INamedTypeSymbol symbol) + => symbol.ToString() == GodotClasses.MustBeVariantAttr; + public static bool IsGodotClassNameAttribute(this INamedTypeSymbol symbol) => symbol.ToString() == GodotClasses.GodotClassNameAttr; diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs index 9ba8bb89b8..1d8ddbabf2 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs @@ -5,7 +5,11 @@ namespace Godot.SourceGenerators public const string Object = "Godot.Object"; public const string AssemblyHasScriptsAttr = "Godot.AssemblyHasScriptsAttribute"; public const string ExportAttr = "Godot.ExportAttribute"; + public const string ExportCategoryAttr = "Godot.ExportCategoryAttribute"; + public const string ExportGroupAttr = "Godot.ExportGroupAttribute"; + public const string ExportSubgroupAttr = "Godot.ExportSubgroupAttribute"; public const string SignalAttr = "Godot.SignalAttribute"; + public const string MustBeVariantAttr = "Godot.MustBeVariantAttribute"; public const string GodotClassNameAttr = "Godot.GodotClassName"; public const string SystemFlagsAttr = "System.FlagsAttribute"; } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs index ca84518c0c..831ac3bdeb 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs @@ -11,11 +11,11 @@ namespace Godot.SourceGenerators { public INamedTypeSymbol GodotObjectType { get; } - public TypeCache(GeneratorExecutionContext context) + public TypeCache(Compilation compilation) { INamedTypeSymbol GetTypeByMetadataNameOrThrow(string fullyQualifiedMetadataName) { - return context.Compilation.GetTypeByMetadataName(fullyQualifiedMetadataName) ?? + return compilation.GetTypeByMetadataName(fullyQualifiedMetadataName) ?? throw new InvalidOperationException("Type not found: " + fullyQualifiedMetadataName); } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs new file mode 100644 index 0000000000..7aaadb27be --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs @@ -0,0 +1,100 @@ +using System.Collections.Immutable; +using System.Diagnostics; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; + +namespace Godot.SourceGenerators +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public class MustBeVariantAnalyzer : DiagnosticAnalyzer + { + public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics + => ImmutableArray.Create( + Common.GenericTypeArgumentMustBeVariantRule, + Common.GenericTypeParameterMustBeVariantAnnotatedRule, + Common.TypeArgumentParentSymbolUnhandledRule); + + public override void Initialize(AnalysisContext context) + { + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + context.EnableConcurrentExecution(); + context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.TypeArgumentList); + } + + private void AnalyzeNode(SyntaxNodeAnalysisContext context) + { + var typeArgListSyntax = (TypeArgumentListSyntax)context.Node; + + // Method invocation or variable declaration that contained the type arguments + var parentSyntax = context.Node.Parent; + Debug.Assert(parentSyntax != null); + + var sm = context.SemanticModel; + + var typeCache = new MarshalUtils.TypeCache(context.Compilation); + + for (int i = 0; i < typeArgListSyntax.Arguments.Count; i++) + { + var typeSyntax = typeArgListSyntax.Arguments[i]; + var typeSymbol = sm.GetSymbolInfo(typeSyntax).Symbol as ITypeSymbol; + Debug.Assert(typeSymbol != null); + + var parentSymbol = sm.GetSymbolInfo(parentSyntax).Symbol; + + if (!ShouldCheckTypeArgument(context, parentSyntax, parentSymbol, typeSyntax, typeSymbol, i)) + { + return; + } + + if (typeSymbol is ITypeParameterSymbol typeParamSymbol) + { + if (!typeParamSymbol.GetAttributes().Any(a => a.AttributeClass?.IsGodotMustBeVariantAttribute() ?? false)) + { + Common.ReportGenericTypeParameterMustBeVariantAnnotated(context, typeSyntax, typeSymbol); + } + continue; + } + + var marshalType = MarshalUtils.ConvertManagedTypeToMarshalType(typeSymbol, typeCache); + + if (marshalType == null) + { + Common.ReportGenericTypeArgumentMustBeVariant(context, typeSyntax, typeSymbol); + continue; + } + } + } + + /// <summary> + /// Check if the given type argument is being used in a type parameter that contains + /// the <c>MustBeVariantAttribute</c>; otherwise, we ignore the attribute. + /// </summary> + /// <param name="context">Context for a syntax node action.</param> + /// <param name="parentSyntax">The parent node syntax that contains the type node syntax.</param> + /// <param name="parentSymbol">The symbol retrieved for the parent node syntax.</param> + /// <param name="typeArgumentSyntax">The type node syntax of the argument type to check.</param> + /// <param name="typeArgumentSymbol">The symbol retrieved for the type node syntax.</param> + /// <returns><see langword="true"/> if the type must be variant and must be analyzed.</returns> + private bool ShouldCheckTypeArgument(SyntaxNodeAnalysisContext context, SyntaxNode parentSyntax, ISymbol parentSymbol, TypeSyntax typeArgumentSyntax, ITypeSymbol typeArgumentSymbol, int typeArgumentIndex) + { + var typeParamSymbol = parentSymbol switch + { + IMethodSymbol methodSymbol => methodSymbol.TypeParameters[typeArgumentIndex], + INamedTypeSymbol typeSymbol => typeSymbol.TypeParameters[typeArgumentIndex], + _ => null, + }; + + if (typeParamSymbol == null) + { + Common.ReportTypeArgumentParentSymbolUnhandled(context, typeArgumentSyntax, parentSymbol); + return false; + } + + return typeParamSymbol.GetAttributes() + .Any(a => a.AttributeClass?.IsGodotMustBeVariantAttribute() ?? false); + } + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs index 1fdc04a262..5ac4f4a47e 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs @@ -49,7 +49,7 @@ namespace Godot.SourceGenerators if (godotClasses.Length > 0) { - var typeCache = new MarshalUtils.TypeCache(context); + var typeCache = new MarshalUtils.TypeCache(context.Compilation); foreach (var godotClass in godotClasses) { diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs index 12a369fd72..0c9b17d69a 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.CodeAnalysis; @@ -48,7 +49,7 @@ namespace Godot.SourceGenerators if (godotClasses.Length > 0) { - var typeCache = new MarshalUtils.TypeCache(context); + var typeCache = new MarshalUtils.TypeCache(context.Compilation); foreach (var godotClass in godotClasses) { @@ -226,6 +227,9 @@ namespace Godot.SourceGenerators foreach (var property in godotClassProperties) { + foreach (var groupingInfo in DetermineGroupingPropertyInfo(property.PropertySymbol)) + AppendGroupingPropertyInfo(source, groupingInfo); + var propertyInfo = DeterminePropertyInfo(context, typeCache, property.PropertySymbol, property.Type); @@ -237,6 +241,10 @@ namespace Godot.SourceGenerators foreach (var field in godotClassFields) { + + foreach (var groupingInfo in DetermineGroupingPropertyInfo(field.FieldSymbol)) + AppendGroupingPropertyInfo(source, groupingInfo); + var propertyInfo = DeterminePropertyInfo(context, typeCache, field.FieldSymbol, field.Type); @@ -321,6 +329,21 @@ namespace Godot.SourceGenerators .Append(" }\n"); } + private static void AppendGroupingPropertyInfo(StringBuilder source, PropertyInfo propertyInfo) + { + source.Append(" properties.Add(new(type: (Godot.Variant.Type)") + .Append((int)VariantType.Nil) + .Append(", name: \"") + .Append(propertyInfo.Name) + .Append("\", hint: (Godot.PropertyHint)") + .Append((int)PropertyHint.None) + .Append(", hintString: \"") + .Append(propertyInfo.HintString) + .Append("\", usage: (Godot.PropertyUsageFlags)") + .Append((int)propertyInfo.Usage) + .Append(", exported: true));\n"); + } + private static void AppendPropertyInfo(StringBuilder source, PropertyInfo propertyInfo) { source.Append(" properties.Add(new(type: (Godot.Variant.Type)") @@ -338,6 +361,32 @@ namespace Godot.SourceGenerators .Append("));\n"); } + private static IEnumerable<PropertyInfo> DetermineGroupingPropertyInfo(ISymbol memberSymbol) + { + foreach (var attr in memberSymbol.GetAttributes()) + { + PropertyUsageFlags? propertyUsage = attr.AttributeClass?.ToString() switch + { + GodotClasses.ExportCategoryAttr => PropertyUsageFlags.Category, + GodotClasses.ExportGroupAttr => PropertyUsageFlags.Group, + GodotClasses.ExportSubgroupAttr => PropertyUsageFlags.Subgroup, + _ => null + }; + + if (propertyUsage is null) + continue; + + if (attr.ConstructorArguments.Length > 0 && attr.ConstructorArguments[0].Value is string name) + { + string? hintString = null; + if (propertyUsage != PropertyUsageFlags.Category && attr.ConstructorArguments.Length > 1) + hintString = attr.ConstructorArguments[1].Value?.ToString(); + + yield return new PropertyInfo(VariantType.Nil, name, PropertyHint.None, hintString, propertyUsage.Value, true); + } + } + } + private static PropertyInfo? DeterminePropertyInfo( GeneratorExecutionContext context, MarshalUtils.TypeCache typeCache, diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs index 3b8ba21107..85fadaa52e 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs @@ -49,7 +49,7 @@ namespace Godot.SourceGenerators if (godotClasses.Length > 0) { - var typeCache = new MarshalUtils.TypeCache(context); + var typeCache = new MarshalUtils.TypeCache(context.Compilation); foreach (var godotClass in godotClasses) { diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs index 1b87c6e760..5a84122c4c 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs @@ -49,7 +49,7 @@ namespace Godot.SourceGenerators if (godotClasses.Length > 0) { - var typeCache = new MarshalUtils.TypeCache(context); + var typeCache = new MarshalUtils.TypeCache(context.Compilation); foreach (var godotClass in godotClasses) { diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs index 536ddb02f8..161834a4be 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs @@ -56,7 +56,7 @@ namespace Godot.SourceGenerators if (godotClasses.Length > 0) { - var typeCache = new MarshalUtils.TypeCache(context); + var typeCache = new MarshalUtils.TypeCache(context.Compilation); foreach (var godotClass in godotClasses) { @@ -148,8 +148,29 @@ namespace Godot.SourceGenerators if (invokeMethodData == null) { - // TODO: Better error for incompatible signature. We should indicate incompatible argument types, as we do with exported properties. - Common.ReportSignalDelegateSignatureNotSupported(context, signalDelegateSymbol); + if (signalDelegateSymbol.DelegateInvokeMethod is IMethodSymbol methodSymbol) + { + foreach (var parameter in methodSymbol.Parameters) + { + if (parameter.RefKind != RefKind.None) + { + Common.ReportSignalParameterTypeNotSupported(context, parameter); + continue; + } + + var marshalType = MarshalUtils.ConvertManagedTypeToMarshalType(parameter.Type, typeCache); + + if (marshalType == null) + { + Common.ReportSignalParameterTypeNotSupported(context, parameter); + } + } + + if (!methodSymbol.ReturnsVoid) + { + Common.ReportSignalDelegateSignatureMustReturnVoid(context, signalDelegateSymbol); + } + } continue; } diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs index 87549f61fe..fc325fc25b 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs @@ -75,8 +75,17 @@ namespace GodotTools.Export } else { - string bits = features.Contains("64") ? "64" : features.Contains("32") ? "32" : null; - CompileAssembliesForDesktop(exporter, platform, isDebug, bits, aotOpts, aotTempDir, outputDataDir, assembliesPrepared, bclDir); + string arch = ""; + if (features.Contains("x86_64")) { + arch = "x86_64"; + } else if (features.Contains("x86_32")) { + arch = "x86_32"; + } else if (features.Contains("arm64")) { + arch = "arm64"; + } else if (features.Contains("arm32")) { + arch = "arm32"; + } + CompileAssembliesForDesktop(exporter, platform, isDebug, arch, aotOpts, aotTempDir, outputDataDir, assembliesPrepared, bclDir); } } @@ -112,7 +121,7 @@ namespace GodotTools.Export } } - public static void CompileAssembliesForDesktop(ExportPlugin exporter, string platform, bool isDebug, string bits, AotOptions aotOpts, string aotTempDir, string outputDataDir, IDictionary<string, string> assemblies, string bclDir) + public static void CompileAssembliesForDesktop(ExportPlugin exporter, string platform, bool isDebug, string arch, AotOptions aotOpts, string aotTempDir, string outputDataDir, IDictionary<string, string> assemblies, string bclDir) { foreach (var assembly in assemblies) { @@ -126,9 +135,9 @@ namespace GodotTools.Export string outputFileName = assemblyName + ".dll" + outputFileExtension; string tempOutputFilePath = Path.Combine(aotTempDir, outputFileName); - var compilerArgs = GetAotCompilerArgs(platform, isDebug, bits, aotOpts, assemblyPath, tempOutputFilePath); + var compilerArgs = GetAotCompilerArgs(platform, isDebug, arch, aotOpts, assemblyPath, tempOutputFilePath); - string compilerDirPath = GetMonoCrossDesktopDirName(platform, bits); + string compilerDirPath = GetMonoCrossDesktopDirName(platform, arch); ExecuteCompiler(FindCrossCompiler(compilerDirPath), compilerArgs, bclDir); @@ -432,9 +441,9 @@ MONO_AOT_MODE_LAST = 1000, var androidToolPrefixes = new Dictionary<string, string> { - ["armeabi-v7a"] = "arm-linux-androideabi-", - ["arm64-v8a"] = "aarch64-linux-android-", - ["x86"] = "i686-linux-android-", + ["arm32"] = "arm-linux-androideabi-", + ["arm64"] = "aarch64-linux-android-", + ["x86_32"] = "i686-linux-android-", ["x86_64"] = "x86_64-linux-android-" }; @@ -547,9 +556,9 @@ MONO_AOT_MODE_LAST = 1000, { var androidAbis = new[] { - "armeabi-v7a", - "arm64-v8a", - "x86", + "arm32", + "arm64", + "x86_32", "x86_64" }; @@ -560,9 +569,9 @@ MONO_AOT_MODE_LAST = 1000, { var abiArchs = new Dictionary<string, string> { - ["armeabi-v7a"] = "armv7", - ["arm64-v8a"] = "aarch64-v8a", - ["x86"] = "i686", + ["arm32"] = "armv7", + ["arm64"] = "aarch64-v8a", + ["x86_32"] = "i686", ["x86_64"] = "x86_64" }; @@ -571,31 +580,25 @@ MONO_AOT_MODE_LAST = 1000, return $"{arch}-linux-android"; } - private static string GetMonoCrossDesktopDirName(string platform, string bits) + private static string GetMonoCrossDesktopDirName(string platform, string arch) { switch (platform) { case OS.Platforms.Windows: case OS.Platforms.UWP: { - string arch = bits == "64" ? "x86_64" : "i686"; return $"windows-{arch}"; } case OS.Platforms.MacOS: { - Debug.Assert(bits == null || bits == "64"); - string arch = "x86_64"; return $"{platform}-{arch}"; } case OS.Platforms.LinuxBSD: - case OS.Platforms.Server: { - string arch = bits == "64" ? "x86_64" : "i686"; return $"linux-{arch}"; } case OS.Platforms.Haiku: { - string arch = bits == "64" ? "x86_64" : "i686"; return $"{platform}-{arch}"; } default: diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index ecf363c106..e1b5530b93 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -100,7 +100,7 @@ namespace GodotTools.Export if (!DeterminePlatformFromFeatures(features, out string platform)) throw new NotSupportedException("Target platform not supported"); - if (!new[] { OS.Platforms.Windows, OS.Platforms.LinuxBSD, OS.Platforms.MacOS, OS.Platforms.Server } + if (!new[] { OS.Platforms.Windows, OS.Platforms.LinuxBSD, OS.Platforms.MacOS } .Contains(platform)) { throw new NotImplementedException("Target platform not yet implemented"); diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs index 62140d41bc..651922d019 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs @@ -15,6 +15,9 @@ namespace GodotTools.Utils [SuppressMessage("ReSharper", "InconsistentNaming")] public static class OS { + /// <summary> + /// Display names for the OS platforms. + /// </summary> private static class Names { public const string Windows = "Windows"; @@ -23,7 +26,6 @@ namespace GodotTools.Utils public const string FreeBSD = "FreeBSD"; public const string NetBSD = "NetBSD"; public const string BSD = "BSD"; - public const string Server = "Server"; public const string UWP = "UWP"; public const string Haiku = "Haiku"; public const string Android = "Android"; @@ -31,12 +33,14 @@ namespace GodotTools.Utils public const string HTML5 = "HTML5"; } + /// <summary> + /// Godot platform identifiers. + /// </summary> public static class Platforms { public const string Windows = "windows"; public const string MacOS = "macos"; public const string LinuxBSD = "linuxbsd"; - public const string Server = "server"; public const string UWP = "uwp"; public const string Haiku = "haiku"; public const string Android = "android"; @@ -44,6 +48,10 @@ namespace GodotTools.Utils public const string HTML5 = "javascript"; } + /// <summary> + /// OS name part of the .NET runtime identifier (RID). + /// See https://docs.microsoft.com/en-us/dotnet/core/rid-catalog. + /// </summary> public static class DotNetOS { public const string Win = "win"; @@ -65,7 +73,6 @@ namespace GodotTools.Utils ["LinuxBSD"] = Platforms.LinuxBSD, // "X11" for compatibility, temporarily, while we are on an outdated branch ["X11"] = Platforms.LinuxBSD, - ["Server"] = Platforms.Server, ["UWP"] = Platforms.UWP, ["Haiku"] = Platforms.Haiku, ["Android"] = Platforms.Android, @@ -81,7 +88,6 @@ namespace GodotTools.Utils [Names.FreeBSD] = Platforms.LinuxBSD, [Names.NetBSD] = Platforms.LinuxBSD, [Names.BSD] = Platforms.LinuxBSD, - [Names.Server] = Platforms.Server, [Names.UWP] = Platforms.UWP, [Names.Haiku] = Platforms.Haiku, [Names.Android] = Platforms.Android, @@ -98,7 +104,6 @@ namespace GodotTools.Utils // instead of `linux` in the runtime identifier. This would be a problem as // Godot has a single export profile for both, named LinuxBSD. [Platforms.LinuxBSD] = DotNetOS.Linux, - [Platforms.Server] = DotNetOS.Linux, [Platforms.UWP] = DotNetOS.Win10, [Platforms.Android] = DotNetOS.Android, [Platforms.iOS] = DotNetOS.iOS, @@ -129,13 +134,12 @@ namespace GodotTools.Utils new[] { Names.Linux, Names.FreeBSD, Names.NetBSD, Names.BSD }; private static readonly IEnumerable<string> UnixLikePlatforms = - new[] { Names.MacOS, Names.Server, Names.Haiku, Names.Android, Names.iOS } + new[] { Names.MacOS, Names.Haiku, Names.Android, Names.iOS } .Concat(LinuxBSDPlatforms).ToArray(); private static readonly Lazy<bool> _isWindows = new(() => IsOS(Names.Windows)); private static readonly Lazy<bool> _isMacOS = new(() => IsOS(Names.MacOS)); private static readonly Lazy<bool> _isLinuxBSD = new(() => IsAnyOS(LinuxBSDPlatforms)); - private static readonly Lazy<bool> _isServer = new(() => IsOS(Names.Server)); private static readonly Lazy<bool> _isUWP = new(() => IsOS(Names.UWP)); private static readonly Lazy<bool> _isHaiku = new(() => IsOS(Names.Haiku)); private static readonly Lazy<bool> _isAndroid = new(() => IsOS(Names.Android)); @@ -149,8 +153,6 @@ namespace GodotTools.Utils [SupportedOSPlatformGuard("linux")] public static bool IsLinuxBSD => _isLinuxBSD.Value; - [SupportedOSPlatformGuard("linux")] public static bool IsServer => _isServer.Value; - [SupportedOSPlatformGuard("windows")] public static bool IsUWP => _isUWP.Value; public static bool IsHaiku => _isHaiku.Value; diff --git a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs index 188bbb775c..069908c426 100644 --- a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs +++ b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs @@ -26,7 +26,7 @@ public partial class _CLASS_ : _BASE_ // Get the input direction and handle the movement/deceleration. // As good practice, you should replace UI actions with custom gameplay actions. Vector2 inputDir = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down"); - Vector3 direction = Transform.basis.Xform(new Vector3(inputDir.x, 0, inputDir.y)).Normalized(); + Vector3 direction = (Transform.basis * new Vector3(inputDir.x, 0, inputDir.y)).Normalized(); if (direction != Vector3.Zero) { velocity.x = direction.x * Speed; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs index 81991c6626..f2984bd1fb 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs @@ -483,7 +483,7 @@ namespace Godot.Collections /// <typeparam name="T">The type of the array.</typeparam> [SuppressMessage("ReSharper", "RedundantExtendsListEntry")] [SuppressMessage("Naming", "CA1710", MessageId = "Identifiers should have correct suffix")] - public sealed class Array<T> : + public sealed class Array<[MustBeVariant] T> : IList<T>, IReadOnlyList<T>, ICollection<T>, diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportCategoryAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportCategoryAttribute.cs new file mode 100644 index 0000000000..101e56f8d3 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportCategoryAttribute.cs @@ -0,0 +1,22 @@ +using System; + +namespace Godot +{ + /// <summary> + /// Define a new category for the following exported properties. This helps to organize properties in the Inspector dock. + /// </summary> + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public sealed class ExportCategoryAttribute : Attribute + { + private string name; + + /// <summary> + /// Define a new category for the following exported properties. + /// </summary> + /// <param name="name">The name of the category.</param> + public ExportCategoryAttribute(string name) + { + this.name = name; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportGroupAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportGroupAttribute.cs new file mode 100644 index 0000000000..3bd532cec1 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportGroupAttribute.cs @@ -0,0 +1,25 @@ +using System; + +namespace Godot +{ + /// <summary> + /// Define a new group for the following exported properties. This helps to organize properties in the Inspector dock. + /// </summary> + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public sealed class ExportGroupAttribute : Attribute + { + private string name; + private string prefix; + + /// <summary> + /// Define a new group for the following exported properties. + /// </summary> + /// <param name="name">The name of the group.</param> + /// <param name="prefix">If provided, the group would make group to only consider properties that have this prefix.</param> + public ExportGroupAttribute(string name, string prefix = "") + { + this.name = name; + this.prefix = prefix; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportSubgroupAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportSubgroupAttribute.cs new file mode 100644 index 0000000000..2ae6eb0b68 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportSubgroupAttribute.cs @@ -0,0 +1,25 @@ +using System; + +namespace Godot +{ + /// <summary> + /// Define a new subgroup for the following exported properties. This helps to organize properties in the Inspector dock. + /// </summary> + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public sealed class ExportSubgroupAttribute : Attribute + { + private string name; + private string prefix; + + /// <summary> + /// Define a new subgroup for the following exported properties. This helps to organize properties in the Inspector dock. + /// </summary> + /// <param name="name">The name of the subgroup.</param> + /// <param name="prefix">If provided, the subgroup would make group to only consider properties that have this prefix.</param> + public ExportSubgroupAttribute(string name, string prefix = "") + { + this.name = name; + this.prefix = prefix; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs new file mode 100644 index 0000000000..23088378d1 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs @@ -0,0 +1,11 @@ +using System; + +namespace Godot +{ + /// <summary> + /// Attribute that restricts generic type parameters to be only types + /// that can be marshaled from/to a <see cref="Variant"/>. + /// </summary> + [AttributeUsage(AttributeTargets.GenericParameter)] + public class MustBeVariantAttribute : Attribute { } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs index 646681a9b1..4cb9bf5758 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -618,41 +618,6 @@ namespace Godot return tr; } - /// <summary> - /// Returns a vector transformed (multiplied) by the basis matrix. - /// </summary> - /// <seealso cref="XformInv(Vector3)"/> - /// <param name="v">A vector to transform.</param> - /// <returns>The transformed vector.</returns> - public Vector3 Xform(Vector3 v) - { - return new Vector3 - ( - Row0.Dot(v), - Row1.Dot(v), - Row2.Dot(v) - ); - } - - /// <summary> - /// Returns a vector transformed (multiplied) by the transposed basis matrix. - /// - /// Note: This results in a multiplication by the inverse of the - /// basis matrix only if it represents a rotation-reflection. - /// </summary> - /// <seealso cref="Xform(Vector3)"/> - /// <param name="v">A vector to inversely transform.</param> - /// <returns>The inversely transformed vector.</returns> - public Vector3 XformInv(Vector3 v) - { - return new Vector3 - ( - Row0[0] * v.x + Row1[0] * v.y + Row2[0] * v.z, - Row0[1] * v.x + Row1[1] * v.y + Row2[1] * v.z, - Row0[2] * v.x + Row1[2] * v.y + Row2[2] * v.z - ); - } - private static readonly Basis[] _orthoBases = { new Basis(1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f), new Basis(0f, -1f, 0f, 1f, 0f, 0f, 0f, 0f, 1f), @@ -857,6 +822,41 @@ namespace Godot } /// <summary> + /// Returns a Vector3 transformed (multiplied) by the basis matrix. + /// </summary> + /// <param name="basis">The basis matrix transformation to apply.</param> + /// <param name="vector">A Vector3 to transform.</param> + /// <returns>The transformed Vector3.</returns> + public static Vector3 operator *(Basis basis, Vector3 vector) + { + return new Vector3 + ( + basis.Row0.Dot(vector), + basis.Row1.Dot(vector), + basis.Row2.Dot(vector) + ); + } + + /// <summary> + /// Returns a Vector3 transformed (multiplied) by the transposed basis matrix. + /// + /// Note: This results in a multiplication by the inverse of the + /// basis matrix only if it represents a rotation-reflection. + /// </summary> + /// <param name="vector">A Vector3 to inversely transform.</param> + /// <param name="basis">The basis matrix transformation to apply.</param> + /// <returns>The inversely transformed vector.</returns> + public static Vector3 operator *(Vector3 vector, Basis basis) + { + return new Vector3 + ( + basis.Row0[0] * vector.x + basis.Row1[0] * vector.y + basis.Row2[0] * vector.z, + basis.Row0[1] * vector.x + basis.Row1[1] * vector.y + basis.Row2[1] * vector.z, + basis.Row0[2] * vector.x + basis.Row1[2] * vector.y + basis.Row2[2] * vector.z + ); + } + + /// <summary> /// Returns <see langword="true"/> if the basis matrices are exactly /// equal. Note: Due to floating-point precision errors, consider using /// <see cref="IsEqualApprox"/> instead, which is more reliable. diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs index 8f26967dcd..6d20f95007 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs @@ -4,7 +4,7 @@ using Godot.NativeInterop; namespace Godot.Bridge; -public class GodotSerializationInfo : IDisposable +public sealed class GodotSerializationInfo : IDisposable { private readonly Collections.Dictionary _properties; private readonly Collections.Dictionary _signalEvents; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs index 8d0e77d171..1b7f5158fd 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs @@ -149,11 +149,5 @@ namespace Godot NativeFuncs.godotsharp_callable_call_deferred(callable, (godot_variant**)argsPtr, argc); } } - - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern object godot_icall_Callable_Call(ref Callable callable, object[] args); - - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void godot_icall_Callable_CallDeferred(ref Callable callable, object[] args); } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs index 68c821b447..bacf7c89e6 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs @@ -10,152 +10,152 @@ namespace Godot { // Color names and values are derived from core/math/color_names.inc internal static readonly Dictionary<string, Color> namedColors = new Dictionary<string, Color> { - {"ALICEBLUE", new Color(0.94f, 0.97f, 1.00f)}, - {"ANTIQUEWHITE", new Color(0.98f, 0.92f, 0.84f)}, - {"AQUA", new Color(0.00f, 1.00f, 1.00f)}, - {"AQUAMARINE", new Color(0.50f, 1.00f, 0.83f)}, - {"AZURE", new Color(0.94f, 1.00f, 1.00f)}, - {"BEIGE", new Color(0.96f, 0.96f, 0.86f)}, - {"BISQUE", new Color(1.00f, 0.89f, 0.77f)}, - {"BLACK", new Color(0.00f, 0.00f, 0.00f)}, - {"BLANCHEDALMOND", new Color(1.00f, 0.92f, 0.80f)}, - {"BLUE", new Color(0.00f, 0.00f, 1.00f)}, - {"BLUEVIOLET", new Color(0.54f, 0.17f, 0.89f)}, - {"BROWN", new Color(0.65f, 0.16f, 0.16f)}, - {"BURLYWOOD", new Color(0.87f, 0.72f, 0.53f)}, - {"CADETBLUE", new Color(0.37f, 0.62f, 0.63f)}, - {"CHARTREUSE", new Color(0.50f, 1.00f, 0.00f)}, - {"CHOCOLATE", new Color(0.82f, 0.41f, 0.12f)}, - {"CORAL", new Color(1.00f, 0.50f, 0.31f)}, - {"CORNFLOWERBLUE", new Color(0.39f, 0.58f, 0.93f)}, - {"CORNSILK", new Color(1.00f, 0.97f, 0.86f)}, - {"CRIMSON", new Color(0.86f, 0.08f, 0.24f)}, - {"CYAN", new Color(0.00f, 1.00f, 1.00f)}, - {"DARKBLUE", new Color(0.00f, 0.00f, 0.55f)}, - {"DARKCYAN", new Color(0.00f, 0.55f, 0.55f)}, - {"DARKGOLDENROD", new Color(0.72f, 0.53f, 0.04f)}, - {"DARKGRAY", new Color(0.66f, 0.66f, 0.66f)}, - {"DARKGREEN", new Color(0.00f, 0.39f, 0.00f)}, - {"DARKKHAKI", new Color(0.74f, 0.72f, 0.42f)}, - {"DARKMAGENTA", new Color(0.55f, 0.00f, 0.55f)}, - {"DARKOLIVEGREEN", new Color(0.33f, 0.42f, 0.18f)}, - {"DARKORANGE", new Color(1.00f, 0.55f, 0.00f)}, - {"DARKORCHID", new Color(0.60f, 0.20f, 0.80f)}, - {"DARKRED", new Color(0.55f, 0.00f, 0.00f)}, - {"DARKSALMON", new Color(0.91f, 0.59f, 0.48f)}, - {"DARKSEAGREEN", new Color(0.56f, 0.74f, 0.56f)}, - {"DARKSLATEBLUE", new Color(0.28f, 0.24f, 0.55f)}, - {"DARKSLATEGRAY", new Color(0.18f, 0.31f, 0.31f)}, - {"DARKTURQUOISE", new Color(0.00f, 0.81f, 0.82f)}, - {"DARKVIOLET", new Color(0.58f, 0.00f, 0.83f)}, - {"DEEPPINK", new Color(1.00f, 0.08f, 0.58f)}, - {"DEEPSKYBLUE", new Color(0.00f, 0.75f, 1.00f)}, - {"DIMGRAY", new Color(0.41f, 0.41f, 0.41f)}, - {"DODGERBLUE", new Color(0.12f, 0.56f, 1.00f)}, - {"FIREBRICK", new Color(0.70f, 0.13f, 0.13f)}, - {"FLORALWHITE", new Color(1.00f, 0.98f, 0.94f)}, - {"FORESTGREEN", new Color(0.13f, 0.55f, 0.13f)}, - {"FUCHSIA", new Color(1.00f, 0.00f, 1.00f)}, - {"GAINSBORO", new Color(0.86f, 0.86f, 0.86f)}, - {"GHOSTWHITE", new Color(0.97f, 0.97f, 1.00f)}, - {"GOLD", new Color(1.00f, 0.84f, 0.00f)}, - {"GOLDENROD", new Color(0.85f, 0.65f, 0.13f)}, - {"GRAY", new Color(0.75f, 0.75f, 0.75f)}, - {"GREEN", new Color(0.00f, 1.00f, 0.00f)}, - {"GREENYELLOW", new Color(0.68f, 1.00f, 0.18f)}, - {"HONEYDEW", new Color(0.94f, 1.00f, 0.94f)}, - {"HOTPINK", new Color(1.00f, 0.41f, 0.71f)}, - {"INDIANRED", new Color(0.80f, 0.36f, 0.36f)}, - {"INDIGO", new Color(0.29f, 0.00f, 0.51f)}, - {"IVORY", new Color(1.00f, 1.00f, 0.94f)}, - {"KHAKI", new Color(0.94f, 0.90f, 0.55f)}, - {"LAVENDER", new Color(0.90f, 0.90f, 0.98f)}, - {"LAVENDERBLUSH", new Color(1.00f, 0.94f, 0.96f)}, - {"LAWNGREEN", new Color(0.49f, 0.99f, 0.00f)}, - {"LEMONCHIFFON", new Color(1.00f, 0.98f, 0.80f)}, - {"LIGHTBLUE", new Color(0.68f, 0.85f, 0.90f)}, - {"LIGHTCORAL", new Color(0.94f, 0.50f, 0.50f)}, - {"LIGHTCYAN", new Color(0.88f, 1.00f, 1.00f)}, - {"LIGHTGOLDENROD", new Color(0.98f, 0.98f, 0.82f)}, - {"LIGHTGRAY", new Color(0.83f, 0.83f, 0.83f)}, - {"LIGHTGREEN", new Color(0.56f, 0.93f, 0.56f)}, - {"LIGHTPINK", new Color(1.00f, 0.71f, 0.76f)}, - {"LIGHTSALMON", new Color(1.00f, 0.63f, 0.48f)}, - {"LIGHTSEAGREEN", new Color(0.13f, 0.70f, 0.67f)}, - {"LIGHTSKYBLUE", new Color(0.53f, 0.81f, 0.98f)}, - {"LIGHTSLATEGRAY", new Color(0.47f, 0.53f, 0.60f)}, - {"LIGHTSTEELBLUE", new Color(0.69f, 0.77f, 0.87f)}, - {"LIGHTYELLOW", new Color(1.00f, 1.00f, 0.88f)}, - {"LIME", new Color(0.00f, 1.00f, 0.00f)}, - {"LIMEGREEN", new Color(0.20f, 0.80f, 0.20f)}, - {"LINEN", new Color(0.98f, 0.94f, 0.90f)}, - {"MAGENTA", new Color(1.00f, 0.00f, 1.00f)}, - {"MAROON", new Color(0.69f, 0.19f, 0.38f)}, - {"MEDIUMAQUAMARINE", new Color(0.40f, 0.80f, 0.67f)}, - {"MEDIUMBLUE", new Color(0.00f, 0.00f, 0.80f)}, - {"MEDIUMORCHID", new Color(0.73f, 0.33f, 0.83f)}, - {"MEDIUMPURPLE", new Color(0.58f, 0.44f, 0.86f)}, - {"MEDIUMSEAGREEN", new Color(0.24f, 0.70f, 0.44f)}, - {"MEDIUMSLATEBLUE", new Color(0.48f, 0.41f, 0.93f)}, - {"MEDIUMSPRINGGREEN", new Color(0.00f, 0.98f, 0.60f)}, - {"MEDIUMTURQUOISE", new Color(0.28f, 0.82f, 0.80f)}, - {"MEDIUMVIOLETRED", new Color(0.78f, 0.08f, 0.52f)}, - {"MIDNIGHTBLUE", new Color(0.10f, 0.10f, 0.44f)}, - {"MINTCREAM", new Color(0.96f, 1.00f, 0.98f)}, - {"MISTYROSE", new Color(1.00f, 0.89f, 0.88f)}, - {"MOCCASIN", new Color(1.00f, 0.89f, 0.71f)}, - {"NAVAJOWHITE", new Color(1.00f, 0.87f, 0.68f)}, - {"NAVYBLUE", new Color(0.00f, 0.00f, 0.50f)}, - {"OLDLACE", new Color(0.99f, 0.96f, 0.90f)}, - {"OLIVE", new Color(0.50f, 0.50f, 0.00f)}, - {"OLIVEDRAB", new Color(0.42f, 0.56f, 0.14f)}, - {"ORANGE", new Color(1.00f, 0.65f, 0.00f)}, - {"ORANGERED", new Color(1.00f, 0.27f, 0.00f)}, - {"ORCHID", new Color(0.85f, 0.44f, 0.84f)}, - {"PALEGOLDENROD", new Color(0.93f, 0.91f, 0.67f)}, - {"PALEGREEN", new Color(0.60f, 0.98f, 0.60f)}, - {"PALETURQUOISE", new Color(0.69f, 0.93f, 0.93f)}, - {"PALEVIOLETRED", new Color(0.86f, 0.44f, 0.58f)}, - {"PAPAYAWHIP", new Color(1.00f, 0.94f, 0.84f)}, - {"PEACHPUFF", new Color(1.00f, 0.85f, 0.73f)}, - {"PERU", new Color(0.80f, 0.52f, 0.25f)}, - {"PINK", new Color(1.00f, 0.75f, 0.80f)}, - {"PLUM", new Color(0.87f, 0.63f, 0.87f)}, - {"POWDERBLUE", new Color(0.69f, 0.88f, 0.90f)}, - {"PURPLE", new Color(0.63f, 0.13f, 0.94f)}, - {"REBECCAPURPLE", new Color(0.40f, 0.20f, 0.60f)}, - {"RED", new Color(1.00f, 0.00f, 0.00f)}, - {"ROSYBROWN", new Color(0.74f, 0.56f, 0.56f)}, - {"ROYALBLUE", new Color(0.25f, 0.41f, 0.88f)}, - {"SADDLEBROWN", new Color(0.55f, 0.27f, 0.07f)}, - {"SALMON", new Color(0.98f, 0.50f, 0.45f)}, - {"SANDYBROWN", new Color(0.96f, 0.64f, 0.38f)}, - {"SEAGREEN", new Color(0.18f, 0.55f, 0.34f)}, - {"SEASHELL", new Color(1.00f, 0.96f, 0.93f)}, - {"SIENNA", new Color(0.63f, 0.32f, 0.18f)}, - {"SILVER", new Color(0.75f, 0.75f, 0.75f)}, - {"SKYBLUE", new Color(0.53f, 0.81f, 0.92f)}, - {"SLATEBLUE", new Color(0.42f, 0.35f, 0.80f)}, - {"SLATEGRAY", new Color(0.44f, 0.50f, 0.56f)}, - {"SNOW", new Color(1.00f, 0.98f, 0.98f)}, - {"SPRINGGREEN", new Color(0.00f, 1.00f, 0.50f)}, - {"STEELBLUE", new Color(0.27f, 0.51f, 0.71f)}, - {"TAN", new Color(0.82f, 0.71f, 0.55f)}, - {"TEAL", new Color(0.00f, 0.50f, 0.50f)}, - {"THISTLE", new Color(0.85f, 0.75f, 0.85f)}, - {"TOMATO", new Color(1.00f, 0.39f, 0.28f)}, - {"TRANSPARENT", new Color(1.00f, 1.00f, 1.00f, 0.00f)}, - {"TURQUOISE", new Color(0.25f, 0.88f, 0.82f)}, - {"VIOLET", new Color(0.93f, 0.51f, 0.93f)}, - {"WEBGRAY", new Color(0.50f, 0.50f, 0.50f)}, - {"WEBGREEN", new Color(0.00f, 0.50f, 0.00f)}, - {"WEBMAROON", new Color(0.50f, 0.00f, 0.00f)}, - {"WEBPURPLE", new Color(0.50f, 0.00f, 0.50f)}, - {"WHEAT", new Color(0.96f, 0.87f, 0.70f)}, - {"WHITE", new Color(1.00f, 1.00f, 1.00f)}, - {"WHITESMOKE", new Color(0.96f, 0.96f, 0.96f)}, - {"YELLOW", new Color(1.00f, 1.00f, 0.00f)}, - {"YELLOWGREEN", new Color(0.60f, 0.80f, 0.20f)}, + { "ALICE_BLUE", new Color(0xF0F8FFFF) }, + { "ANTIQUE_WHITE", new Color(0xFAEBD7FF) }, + { "AQUA", new Color(0x00FFFFFF) }, + { "AQUAMARINE", new Color(0x7FFFD4FF) }, + { "AZURE", new Color(0xF0FFFFFF) }, + { "BEIGE", new Color(0xF5F5DCFF) }, + { "BISQUE", new Color(0xFFE4C4FF) }, + { "BLACK", new Color(0x000000FF) }, + { "BLANCHED_ALMOND", new Color(0xFFEBCDFF) }, + { "BLUE", new Color(0x0000FFFF) }, + { "BLUE_VIOLET", new Color(0x8A2BE2FF) }, + { "BROWN", new Color(0xA52A2AFF) }, + { "BURLYWOOD", new Color(0xDEB887FF) }, + { "CADET_BLUE", new Color(0x5F9EA0FF) }, + { "CHARTREUSE", new Color(0x7FFF00FF) }, + { "CHOCOLATE", new Color(0xD2691EFF) }, + { "CORAL", new Color(0xFF7F50FF) }, + { "CORNFLOWER_BLUE", new Color(0x6495EDFF) }, + { "CORNSILK", new Color(0xFFF8DCFF) }, + { "CRIMSON", new Color(0xDC143CFF) }, + { "CYAN", new Color(0x00FFFFFF) }, + { "DARK_BLUE", new Color(0x00008BFF) }, + { "DARK_CYAN", new Color(0x008B8BFF) }, + { "DARK_GOLDENROD", new Color(0xB8860BFF) }, + { "DARK_GRAY", new Color(0xA9A9A9FF) }, + { "DARK_GREEN", new Color(0x006400FF) }, + { "DARK_KHAKI", new Color(0xBDB76BFF) }, + { "DARK_MAGENTA", new Color(0x8B008BFF) }, + { "DARK_OLIVE_GREEN", new Color(0x556B2FFF) }, + { "DARK_ORANGE", new Color(0xFF8C00FF) }, + { "DARK_ORCHID", new Color(0x9932CCFF) }, + { "DARK_RED", new Color(0x8B0000FF) }, + { "DARK_SALMON", new Color(0xE9967AFF) }, + { "DARK_SEA_GREEN", new Color(0x8FBC8FFF) }, + { "DARK_SLATE_BLUE", new Color(0x483D8BFF) }, + { "DARK_SLATE_GRAY", new Color(0x2F4F4FFF) }, + { "DARK_TURQUOISE", new Color(0x00CED1FF) }, + { "DARK_VIOLET", new Color(0x9400D3FF) }, + { "DEEP_PINK", new Color(0xFF1493FF) }, + { "DEEP_SKY_BLUE", new Color(0x00BFFFFF) }, + { "DIM_GRAY", new Color(0x696969FF) }, + { "DODGER_BLUE", new Color(0x1E90FFFF) }, + { "FIREBRICK", new Color(0xB22222FF) }, + { "FLORAL_WHITE", new Color(0xFFFAF0FF) }, + { "FOREST_GREEN", new Color(0x228B22FF) }, + { "FUCHSIA", new Color(0xFF00FFFF) }, + { "GAINSBORO", new Color(0xDCDCDCFF) }, + { "GHOST_WHITE", new Color(0xF8F8FFFF) }, + { "GOLD", new Color(0xFFD700FF) }, + { "GOLDENROD", new Color(0xDAA520FF) }, + { "GRAY", new Color(0xBEBEBEFF) }, + { "GREEN", new Color(0x00FF00FF) }, + { "GREEN_YELLOW", new Color(0xADFF2FFF) }, + { "HONEYDEW", new Color(0xF0FFF0FF) }, + { "HOT_PINK", new Color(0xFF69B4FF) }, + { "INDIAN_RED", new Color(0xCD5C5CFF) }, + { "INDIGO", new Color(0x4B0082FF) }, + { "IVORY", new Color(0xFFFFF0FF) }, + { "KHAKI", new Color(0xF0E68CFF) }, + { "LAVENDER", new Color(0xE6E6FAFF) }, + { "LAVENDER_BLUSH", new Color(0xFFF0F5FF) }, + { "LAWN_GREEN", new Color(0x7CFC00FF) }, + { "LEMON_CHIFFON", new Color(0xFFFACDFF) }, + { "LIGHT_BLUE", new Color(0xADD8E6FF) }, + { "LIGHT_CORAL", new Color(0xF08080FF) }, + { "LIGHT_CYAN", new Color(0xE0FFFFFF) }, + { "LIGHT_GOLDENROD", new Color(0xFAFAD2FF) }, + { "LIGHT_GRAY", new Color(0xD3D3D3FF) }, + { "LIGHT_GREEN", new Color(0x90EE90FF) }, + { "LIGHT_PINK", new Color(0xFFB6C1FF) }, + { "LIGHT_SALMON", new Color(0xFFA07AFF) }, + { "LIGHT_SEA_GREEN", new Color(0x20B2AAFF) }, + { "LIGHT_SKY_BLUE", new Color(0x87CEFAFF) }, + { "LIGHT_SLATE_GRAY", new Color(0x778899FF) }, + { "LIGHT_STEEL_BLUE", new Color(0xB0C4DEFF) }, + { "LIGHT_YELLOW", new Color(0xFFFFE0FF) }, + { "LIME", new Color(0x00FF00FF) }, + { "LIME_GREEN", new Color(0x32CD32FF) }, + { "LINEN", new Color(0xFAF0E6FF) }, + { "MAGENTA", new Color(0xFF00FFFF) }, + { "MAROON", new Color(0xB03060FF) }, + { "MEDIUM_AQUAMARINE", new Color(0x66CDAAFF) }, + { "MEDIUM_BLUE", new Color(0x0000CDFF) }, + { "MEDIUM_ORCHID", new Color(0xBA55D3FF) }, + { "MEDIUM_PURPLE", new Color(0x9370DBFF) }, + { "MEDIUM_SEA_GREEN", new Color(0x3CB371FF) }, + { "MEDIUM_SLATE_BLUE", new Color(0x7B68EEFF) }, + { "MEDIUM_SPRING_GREEN", new Color(0x00FA9AFF) }, + { "MEDIUM_TURQUOISE", new Color(0x48D1CCFF) }, + { "MEDIUM_VIOLET_RED", new Color(0xC71585FF) }, + { "MIDNIGHT_BLUE", new Color(0x191970FF) }, + { "MINT_CREAM", new Color(0xF5FFFAFF) }, + { "MISTY_ROSE", new Color(0xFFE4E1FF) }, + { "MOCCASIN", new Color(0xFFE4B5FF) }, + { "NAVAJO_WHITE", new Color(0xFFDEADFF) }, + { "NAVY_BLUE", new Color(0x000080FF) }, + { "OLD_LACE", new Color(0xFDF5E6FF) }, + { "OLIVE", new Color(0x808000FF) }, + { "OLIVE_DRAB", new Color(0x6B8E23FF) }, + { "ORANGE", new Color(0xFFA500FF) }, + { "ORANGE_RED", new Color(0xFF4500FF) }, + { "ORCHID", new Color(0xDA70D6FF) }, + { "PALE_GOLDENROD", new Color(0xEEE8AAFF) }, + { "PALE_GREEN", new Color(0x98FB98FF) }, + { "PALE_TURQUOISE", new Color(0xAFEEEEFF) }, + { "PALE_VIOLET_RED", new Color(0xDB7093FF) }, + { "PAPAYA_WHIP", new Color(0xFFEFD5FF) }, + { "PEACH_PUFF", new Color(0xFFDAB9FF) }, + { "PERU", new Color(0xCD853FFF) }, + { "PINK", new Color(0xFFC0CBFF) }, + { "PLUM", new Color(0xDDA0DDFF) }, + { "POWDER_BLUE", new Color(0xB0E0E6FF) }, + { "PURPLE", new Color(0xA020F0FF) }, + { "REBECCA_PURPLE", new Color(0x663399FF) }, + { "RED", new Color(0xFF0000FF) }, + { "ROSY_BROWN", new Color(0xBC8F8FFF) }, + { "ROYAL_BLUE", new Color(0x4169E1FF) }, + { "SADDLE_BROWN", new Color(0x8B4513FF) }, + { "SALMON", new Color(0xFA8072FF) }, + { "SANDY_BROWN", new Color(0xF4A460FF) }, + { "SEA_GREEN", new Color(0x2E8B57FF) }, + { "SEASHELL", new Color(0xFFF5EEFF) }, + { "SIENNA", new Color(0xA0522DFF) }, + { "SILVER", new Color(0xC0C0C0FF) }, + { "SKY_BLUE", new Color(0x87CEEBFF) }, + { "SLATE_BLUE", new Color(0x6A5ACDFF) }, + { "SLATE_GRAY", new Color(0x708090FF) }, + { "SNOW", new Color(0xFFFAFAFF) }, + { "SPRING_GREEN", new Color(0x00FF7FFF) }, + { "STEEL_BLUE", new Color(0x4682B4FF) }, + { "TAN", new Color(0xD2B48CFF) }, + { "TEAL", new Color(0x008080FF) }, + { "THISTLE", new Color(0xD8BFD8FF) }, + { "TOMATO", new Color(0xFF6347FF) }, + { "TRANSPARENT", new Color(0xFFFFFF00) }, + { "TURQUOISE", new Color(0x40E0D0FF) }, + { "VIOLET", new Color(0xEE82EEFF) }, + { "WEB_GRAY", new Color(0x808080FF) }, + { "WEB_GREEN", new Color(0x008000FF) }, + { "WEB_MAROON", new Color(0x800000FF) }, + { "WEB_PURPLE", new Color(0x800080FF) }, + { "WHEAT", new Color(0xF5DEB3FF) }, + { "WHITE", new Color(0xFFFFFFFF) }, + { "WHITE_SMOKE", new Color(0xF5F5F5FF) }, + { "YELLOW", new Color(0xFFFF00FF) }, + { "YELLOW_GREEN", new Color(0x9ACD32FF) }, }; #pragma warning disable CS1591 // Disable warning: "Missing XML comment for publicly visible type or member" diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs index fa8c94ed18..95ad097192 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs @@ -352,7 +352,7 @@ namespace Godot.Collections /// </summary> /// <typeparam name="TKey">The type of the dictionary's keys.</typeparam> /// <typeparam name="TValue">The type of the dictionary's values.</typeparam> - public class Dictionary<TKey, TValue> : + public class Dictionary<[MustBeVariant] TKey, [MustBeVariant] TValue> : IDictionary<TKey, TValue>, IReadOnlyDictionary<TKey, TValue> { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs index 1dc21b6303..df0e839866 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs @@ -93,8 +93,12 @@ namespace Godot /// Negative indices access the children from the last one. /// To access a child node via its name, use <see cref="GetNode"/>. /// </summary> - /// <seealso cref="GetChildOrNull{T}(int)"/> + /// <seealso cref="GetChildOrNull{T}(int, bool)"/> /// <param name="idx">Child index.</param> + /// <param name="includeInternal"> + /// If <see langword="false"/>, internal children are skipped (see <c>internal</c> + /// parameter in <see cref="AddChild(Node, bool, InternalMode)"/>). + /// </param> /// <exception cref="InvalidCastException"> /// Thrown when the given the fetched node can't be casted to the given type <typeparamref name="T"/>. /// </exception> @@ -102,9 +106,9 @@ namespace Godot /// <returns> /// The child <see cref="Node"/> at the given index <paramref name="idx"/>. /// </returns> - public T GetChild<T>(int idx) where T : class + public T GetChild<T>(int idx, bool includeInternal = false) where T : class { - return (T)(object)GetChild(idx); + return (T)(object)GetChild(idx, includeInternal); } /// <summary> @@ -113,15 +117,20 @@ namespace Godot /// Negative indices access the children from the last one. /// To access a child node via its name, use <see cref="GetNode"/>. /// </summary> - /// <seealso cref="GetChild{T}(int)"/> + /// <seealso cref="GetChild{T}(int, bool)"/> /// <param name="idx">Child index.</param> + /// <param name="includeInternal"> + /// If <see langword="false"/>, internal children are skipped (see <c>internal</c> + /// parameter in <see cref="AddChild(Node, bool, InternalMode)"/>). + /// </param> /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam> /// <returns> /// The child <see cref="Node"/> at the given index <paramref name="idx"/>, or <see langword="null"/> if not found. /// </returns> - public T GetChildOrNull<T>(int idx) where T : class + public T GetChildOrNull<T>(int idx, bool includeInternal = false) where T : class { - return GetChild(idx) as T; + int count = GetChildCount(includeInternal); + return idx >= -count && idx < count ? GetChild(idx, includeInternal) as T : null; } /// <summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs index 9348cc1d00..9e7da7757a 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs @@ -189,8 +189,6 @@ namespace Godot /// Pushes an error message to Godot's built-in debugger and to the OS terminal. /// /// Note: Errors printed this way will not pause project execution. - /// To print an error message and pause project execution in debug builds, - /// use [code]assert(false, "test error")[/code] instead. /// </summary> /// <example> /// <code> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs index 08beff8104..41a0dd871c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs @@ -754,9 +754,10 @@ namespace Godot } /// <summary> - /// Returns the [code]value[/code] wrapped between [code]0[/code] and the [code]length[/code]. - /// If the limit is reached, the next value the function returned is decreased to the [code]0[/code] side or increased to the [code]length[/code] side (like a triangle wave). - /// If [code]length[/code] is less than zero, it becomes positive. + /// Returns the <paramref name="value"/> wrapped between <c>0</c> and the <paramref name="length"/>. + /// If the limit is reached, the next value the function returned is decreased to the <c>0</c> side + /// or increased to the <paramref name="length"/> side (like a triangle wave). + /// If <paramref name="length"/> is less than zero, it becomes positive. /// </summary> /// <param name="value">The value to pingpong.</param> /// <param name="length">The maximum value of the function.</param> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs index df16fe5718..d62cb6b0fa 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs @@ -39,22 +39,22 @@ namespace Godot } /// <summary> - /// The projections's X column. Also accessible by using the index position <c>[0]</c>. + /// The projection's X column. Also accessible by using the index position <c>[0]</c>. /// </summary> public Vector4 x; /// <summary> - /// The projections's Y column. Also accessible by using the index position <c>[1]</c>. + /// The projection's Y column. Also accessible by using the index position <c>[1]</c>. /// </summary> public Vector4 y; /// <summary> - /// The projections's Z column. Also accessible by using the index position <c>[2]</c>. + /// The projection's Z column. Also accessible by using the index position <c>[2]</c>. /// </summary> public Vector4 z; /// <summary> - /// The projections's W column. Also accessible by using the index position <c>[3]</c>. + /// The projection's W column. Also accessible by using the index position <c>[3]</c>. /// </summary> public Vector4 w; @@ -74,18 +74,6 @@ namespace Godot } /// <summary> - /// Constructs a new <see cref="Projection"/> from an existing <see cref="Projection"/>. - /// </summary> - /// <param name="proj">The existing <see cref="Projection"/>.</param> - public Projection(Projection proj) - { - x = proj.x; - y = proj.y; - z = proj.z; - w = proj.w; - } - - /// <summary> /// Constructs a new <see cref="Projection"/> from a <see cref="Transform3D"/>. /// </summary> /// <param name="transform">The <see cref="Transform3D"/>.</param> @@ -355,7 +343,7 @@ namespace Godot public int GetPixelsPerMeter(int forPixelWidth) { - Vector3 result = Xform(new Vector3(1, 0, -1)); + Vector3 result = this * new Vector3(1, 0, -1); return (int)((result.x * (real_t)0.5 + (real_t)0.5) * forPixelWidth); } @@ -588,19 +576,51 @@ namespace Godot } /// <summary> - /// Returns a vector transformed (multiplied) by this projection. + /// Returns a Vector4 transformed (multiplied) by the projection. + /// </summary> + /// <param name="proj">The projection to apply.</param> + /// <param name="vector">A Vector4 to transform.</param> + /// <returns>The transformed Vector4.</returns> + public static Vector4 operator *(Projection proj, Vector4 vector) + { + return new Vector4( + proj.x.x * vector.x + proj.y.x * vector.y + proj.z.x * vector.z + proj.w.x * vector.w, + proj.x.y * vector.x + proj.y.y * vector.y + proj.z.y * vector.z + proj.w.y * vector.w, + proj.x.z * vector.x + proj.y.z * vector.y + proj.z.z * vector.z + proj.w.z * vector.w, + proj.x.w * vector.x + proj.y.w * vector.y + proj.z.w * vector.z + proj.w.w * vector.w + ); + } + + /// <summary> + /// Returns a Vector4 transformed (multiplied) by the inverse projection. /// </summary> /// <param name="proj">The projection to apply.</param> - /// <param name="v">A vector to transform.</param> - /// <returns>The transformed vector.</returns> - public static Vector4 operator *(Projection proj, Vector4 v) + /// <param name="vector">A Vector4 to transform.</param> + /// <returns>The inversely transformed Vector4.</returns> + public static Vector4 operator *(Vector4 vector, Projection proj) { return new Vector4( - proj.x.x * v.x + proj.y.x * v.y + proj.z.x * v.z + proj.w.x * v.w, - proj.x.y * v.x + proj.y.y * v.y + proj.z.y * v.z + proj.w.y * v.w, - proj.x.z * v.x + proj.y.z * v.y + proj.z.z * v.z + proj.w.z * v.w, - proj.x.w * v.x + proj.y.w * v.y + proj.z.w * v.z + proj.w.w * v.w + proj.x.x * vector.x + proj.x.y * vector.y + proj.x.z * vector.z + proj.x.w * vector.w, + proj.y.x * vector.x + proj.y.y * vector.y + proj.y.z * vector.z + proj.y.w * vector.w, + proj.z.x * vector.x + proj.z.y * vector.y + proj.z.z * vector.z + proj.z.w * vector.w, + proj.w.x * vector.x + proj.w.y * vector.y + proj.w.z * vector.z + proj.w.w * vector.w + ); + } + + /// <summary> + /// Returns a Vector3 transformed (multiplied) by the projection. + /// </summary> + /// <param name="proj">The projection to apply.</param> + /// <param name="vector">A Vector3 to transform.</param> + /// <returns>The transformed Vector3.</returns> + public static Vector3 operator *(Projection proj, Vector3 vector) + { + Vector3 ret = new Vector3( + proj.x.x * vector.x + proj.y.x * vector.y + proj.z.x * vector.z + proj.w.x, + proj.x.y * vector.x + proj.y.y * vector.y + proj.z.y * vector.z + proj.w.y, + proj.x.z * vector.x + proj.y.z * vector.y + proj.z.z * vector.z + proj.w.z ); + return ret / (proj.x.w * vector.x + proj.y.w * vector.y + proj.z.w * vector.z + proj.w.w); } /// <summary> @@ -714,21 +734,6 @@ namespace Godot } } - /// <summary> - /// Returns a vector transformed (multiplied) by this projection. - /// </summary> - /// <param name="v">A vector to transform.</param> - /// <returns>The transformed vector.</returns> - private Vector3 Xform(Vector3 v) - { - Vector3 ret = new Vector3( - x.x * v.x + y.x * v.y + z.x * v.z + w.x, - x.y * v.x + y.y * v.y + z.y * v.z + w.y, - x.z * v.x + y.z * v.y + z.z * v.z + w.z - ); - return ret / (x.w * v.x + y.w * v.y + z.w * v.z + w.w); - } - // Constants private static readonly Projection _zero = new Projection( new Vector4(0, 0, 0, 0), diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs index 90e4e3b41e..658a14ca1d 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs @@ -313,24 +313,6 @@ namespace Godot ); } - /// <summary> - /// Returns a vector transformed (multiplied) by this quaternion. - /// </summary> - /// <param name="v">A vector to transform.</param> - /// <returns>The transformed vector.</returns> - public Vector3 Xform(Vector3 v) - { -#if DEBUG - if (!IsNormalized()) - { - throw new InvalidOperationException("Quaternion is not normalized"); - } -#endif - var u = new Vector3(x, y, z); - Vector3 uv = u.Cross(v); - return v + (((uv * w) + u.Cross(uv)) * 2); - } - // Constants private static readonly Quaternion _identity = new Quaternion(0, 0, 0, 1); @@ -358,15 +340,6 @@ namespace Godot } /// <summary> - /// Constructs a <see cref="Quaternion"/> from the given <see cref="Quaternion"/>. - /// </summary> - /// <param name="q">The existing quaternion.</param> - public Quaternion(Quaternion q) - { - this = q; - } - - /// <summary> /// Constructs a <see cref="Quaternion"/> from the given <see cref="Basis"/>. /// </summary> /// <param name="basis">The <see cref="Basis"/> to construct from.</param> @@ -461,6 +434,36 @@ namespace Godot } /// <summary> + /// Returns a Vector3 rotated (multiplied) by the quaternion. + /// </summary> + /// <param name="quaternion">The quaternion to rotate by.</param> + /// <param name="vector">A Vector3 to transform.</param> + /// <returns>The rotated Vector3.</returns> + public static Vector3 operator *(Quaternion quaternion, Vector3 vector) + { +#if DEBUG + if (!quaternion.IsNormalized()) + { + throw new InvalidOperationException("Quaternion is not normalized"); + } +#endif + var u = new Vector3(quaternion.x, quaternion.y, quaternion.z); + Vector3 uv = u.Cross(vector); + return vector + (((uv * quaternion.w) + u.Cross(uv)) * 2); + } + + /// <summary> + /// Returns a Vector3 rotated (multiplied) by the inverse quaternion. + /// </summary> + /// <param name="vector">A Vector3 to inversely rotate.</param> + /// <param name="quaternion">The quaternion to rotate by.</param> + /// <returns>The inversely rotated Vector3.</returns> + public static Vector3 operator *(Vector3 vector, Quaternion quaternion) + { + return quaternion.Inverse() * vector; + } + + /// <summary> /// Adds each component of the left <see cref="Quaternion"/> /// to the right <see cref="Quaternion"/>. This operation is not /// meaningful on its own, but it can be used as a part of a @@ -503,38 +506,6 @@ namespace Godot } /// <summary> - /// Rotates (multiplies) the <see cref="Vector3"/> - /// by the given <see cref="Quaternion"/>. - /// </summary> - /// <param name="quat">The quaternion to rotate by.</param> - /// <param name="vec">The vector to rotate.</param> - /// <returns>The rotated vector.</returns> - public static Vector3 operator *(Quaternion quat, Vector3 vec) - { -#if DEBUG - if (!quat.IsNormalized()) - { - throw new InvalidOperationException("Quaternion is not normalized."); - } -#endif - var u = new Vector3(quat.x, quat.y, quat.z); - Vector3 uv = u.Cross(vec); - return vec + (((uv * quat.w) + u.Cross(uv)) * 2); - } - - /// <summary> - /// Inversely rotates (multiplies) the <see cref="Vector3"/> - /// by the given <see cref="Quaternion"/>. - /// </summary> - /// <param name="vec">The vector to rotate.</param> - /// <param name="quat">The quaternion to rotate by.</param> - /// <returns>The inversely rotated vector.</returns> - public static Vector3 operator *(Vector3 vec, Quaternion quat) - { - return quat.Inverse() * vec; - } - - /// <summary> /// Multiplies each component of the <see cref="Quaternion"/> /// by the given <see cref="real_t"/>. This operation is not /// meaningful on its own, but it can be used as a part of a diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs index 10739c02a7..b9ee0bc278 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs @@ -59,9 +59,9 @@ namespace Godot } /// <summary> - /// Constructs a <see cref="StringName"/> from the given <paramref name="path"/> string. + /// Constructs a <see cref="StringName"/> from the given <paramref name="name"/> string. /// </summary> - /// <param name="path">String to construct the <see cref="StringName"/> from.</param> + /// <param name="name">String to construct the <see cref="StringName"/> from.</param> public StringName(string name) { if (!string.IsNullOrEmpty(name)) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs index ab2c0cd785..70cf8bbe22 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -384,31 +384,6 @@ namespace Godot return copy; } - /// <summary> - /// Returns a vector transformed (multiplied) by this transformation matrix. - /// </summary> - /// <seealso cref="XformInv(Vector2)"/> - /// <param name="v">A vector to transform.</param> - /// <returns>The transformed vector.</returns> - [Obsolete("Xform is deprecated. Use the multiplication operator (Transform2D * Vector2) instead.")] - public Vector2 Xform(Vector2 v) - { - return new Vector2(Tdotx(v), Tdoty(v)) + origin; - } - - /// <summary> - /// Returns a vector transformed (multiplied) by the inverse transformation matrix. - /// </summary> - /// <seealso cref="Xform(Vector2)"/> - /// <param name="v">A vector to inversely transform.</param> - /// <returns>The inversely transformed vector.</returns> - [Obsolete("XformInv is deprecated. Use the multiplication operator (Vector2 * Transform2D) instead.")] - public Vector2 XformInv(Vector2 v) - { - Vector2 vInv = v - origin; - return new Vector2(x.Dot(vInv), y.Dot(vInv)); - } - // Constants private static readonly Transform2D _identity = new Transform2D(1, 0, 0, 1, 0, 0); private static readonly Transform2D _flipX = new Transform2D(-1, 0, 0, 1, 0, 0); @@ -502,7 +477,7 @@ namespace Godot } /// <summary> - /// Returns a Vector2 transformed (multiplied) by transformation matrix. + /// Returns a Vector2 transformed (multiplied) by the transformation matrix. /// </summary> /// <param name="transform">The transformation to apply.</param> /// <param name="vector">A Vector2 to transform.</param> @@ -525,7 +500,7 @@ namespace Godot } /// <summary> - /// Returns a Rect2 transformed (multiplied) by transformation matrix. + /// Returns a Rect2 transformed (multiplied) by the transformation matrix. /// </summary> /// <param name="transform">The transformation to apply.</param> /// <param name="rect">A Rect2 to transform.</param> @@ -536,7 +511,7 @@ namespace Godot Vector2 toX = transform.x * rect.Size.x; Vector2 toY = transform.y * rect.Size.y; - return new Rect2(pos, rect.Size).Expand(pos + toX).Expand(pos + toY).Expand(pos + toX + toY); + return new Rect2(pos, new Vector2()).Expand(pos + toX).Expand(pos + toY).Expand(pos + toX + toY); } /// <summary> @@ -552,11 +527,11 @@ namespace Godot Vector2 to2 = new Vector2(rect.Position.x + rect.Size.x, rect.Position.y + rect.Size.y) * transform; Vector2 to3 = new Vector2(rect.Position.x + rect.Size.x, rect.Position.y) * transform; - return new Rect2(pos, rect.Size).Expand(to1).Expand(to2).Expand(to3); + return new Rect2(pos, new Vector2()).Expand(to1).Expand(to2).Expand(to3); } /// <summary> - /// Returns a copy of the given Vector2[] transformed (multiplied) by transformation matrix. + /// Returns a copy of the given Vector2[] transformed (multiplied) by the transformation matrix. /// </summary> /// <param name="transform">The transformation to apply.</param> /// <param name="array">A Vector2[] to transform.</param> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs index 810f55e150..5481225e3f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs @@ -108,7 +108,7 @@ namespace Godot public Transform3D AffineInverse() { Basis basisInv = basis.Inverse(); - return new Transform3D(basisInv, basisInv.Xform(-origin)); + return new Transform3D(basisInv, basisInv * -origin); } /// <summary> @@ -147,7 +147,7 @@ namespace Godot public Transform3D Inverse() { Basis basisTr = basis.Transposed(); - return new Transform3D(basisTr, basisTr.Xform(-origin)); + return new Transform3D(basisTr, basisTr * -origin); } /// <summary> @@ -286,43 +286,6 @@ namespace Godot )); } - /// <summary> - /// Returns a vector transformed (multiplied) by this transformation matrix. - /// </summary> - /// <seealso cref="XformInv(Vector3)"/> - /// <param name="v">A vector to transform.</param> - /// <returns>The transformed vector.</returns> - public Vector3 Xform(Vector3 v) - { - return new Vector3 - ( - basis.Row0.Dot(v) + origin.x, - basis.Row1.Dot(v) + origin.y, - basis.Row2.Dot(v) + origin.z - ); - } - - /// <summary> - /// Returns a vector transformed (multiplied) by the transposed transformation matrix. - /// - /// Note: This results in a multiplication by the inverse of the - /// transformation matrix only if it represents a rotation-reflection. - /// </summary> - /// <seealso cref="Xform(Vector3)"/> - /// <param name="v">A vector to inversely transform.</param> - /// <returns>The inversely transformed vector.</returns> - public Vector3 XformInv(Vector3 v) - { - Vector3 vInv = v - origin; - - return new Vector3 - ( - (basis.Row0[0] * vInv.x) + (basis.Row1[0] * vInv.y) + (basis.Row2[0] * vInv.z), - (basis.Row0[1] * vInv.x) + (basis.Row1[1] * vInv.y) + (basis.Row2[1] * vInv.z), - (basis.Row0[2] * vInv.x) + (basis.Row1[2] * vInv.y) + (basis.Row2[2] * vInv.z) - ); - } - // Constants private static readonly Transform3D _identity = new Transform3D(Basis.Identity, Vector3.Zero); private static readonly Transform3D _flipX = new Transform3D(new Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1), Vector3.Zero); @@ -399,12 +362,188 @@ namespace Godot /// <returns>The composed transform.</returns> public static Transform3D operator *(Transform3D left, Transform3D right) { - left.origin = left.Xform(right.origin); + left.origin = left * right.origin; left.basis *= right.basis; return left; } /// <summary> + /// Returns a Vector3 transformed (multiplied) by the transformation matrix. + /// </summary> + /// <param name="transform">The transformation to apply.</param> + /// <param name="vector">A Vector3 to transform.</param> + /// <returns>The transformed Vector3.</returns> + public static Vector3 operator *(Transform3D transform, Vector3 vector) + { + return new Vector3 + ( + transform.basis.Row0.Dot(vector) + transform.origin.x, + transform.basis.Row1.Dot(vector) + transform.origin.y, + transform.basis.Row2.Dot(vector) + transform.origin.z + ); + } + + /// <summary> + /// Returns a Vector3 transformed (multiplied) by the transposed transformation matrix. + /// + /// Note: This results in a multiplication by the inverse of the + /// transformation matrix only if it represents a rotation-reflection. + /// </summary> + /// <param name="vector">A Vector3 to inversely transform.</param> + /// <param name="transform">The transformation to apply.</param> + /// <returns>The inversely transformed Vector3.</returns> + public static Vector3 operator *(Vector3 vector, Transform3D transform) + { + Vector3 vInv = vector - transform.origin; + + return new Vector3 + ( + (transform.basis.Row0[0] * vInv.x) + (transform.basis.Row1[0] * vInv.y) + (transform.basis.Row2[0] * vInv.z), + (transform.basis.Row0[1] * vInv.x) + (transform.basis.Row1[1] * vInv.y) + (transform.basis.Row2[1] * vInv.z), + (transform.basis.Row0[2] * vInv.x) + (transform.basis.Row1[2] * vInv.y) + (transform.basis.Row2[2] * vInv.z) + ); + } + + /// <summary> + /// Returns an AABB transformed (multiplied) by the transformation matrix. + /// </summary> + /// <param name="transform">The transformation to apply.</param> + /// <param name="aabb">An AABB to transform.</param> + /// <returns>The transformed AABB.</returns> + public static AABB operator *(Transform3D transform, AABB aabb) + { + Vector3 min = aabb.Position; + Vector3 max = aabb.Position + aabb.Size; + + Vector3 tmin = transform.origin; + Vector3 tmax = transform.origin; + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + real_t e = transform.basis[i][j] * min[j]; + real_t f = transform.basis[i][j] * max[j]; + if (e < f) + { + tmin[i] += e; + tmax[i] += f; + } + else + { + tmin[i] += f; + tmax[i] += e; + } + } + } + + return new AABB(tmin, tmax - tmin); + } + + /// <summary> + /// Returns an AABB transformed (multiplied) by the inverse transformation matrix. + /// </summary> + /// <param name="aabb">An AABB to inversely transform.</param> + /// <param name="transform">The transformation to apply.</param> + /// <returns>The inversely transformed AABB.</returns> + public static AABB operator *(AABB aabb, Transform3D transform) + { + Vector3 pos = new Vector3(aabb.Position.x + aabb.Size.x, aabb.Position.y + aabb.Size.y, aabb.Position.z + aabb.Size.z) * transform; + Vector3 to1 = new Vector3(aabb.Position.x + aabb.Size.x, aabb.Position.y + aabb.Size.y, aabb.Position.z) * transform; + Vector3 to2 = new Vector3(aabb.Position.x + aabb.Size.x, aabb.Position.y, aabb.Position.z + aabb.Size.z) * transform; + Vector3 to3 = new Vector3(aabb.Position.x + aabb.Size.x, aabb.Position.y, aabb.Position.z) * transform; + Vector3 to4 = new Vector3(aabb.Position.x, aabb.Position.y + aabb.Size.y, aabb.Position.z + aabb.Size.z) * transform; + Vector3 to5 = new Vector3(aabb.Position.x, aabb.Position.y + aabb.Size.y, aabb.Position.z) * transform; + Vector3 to6 = new Vector3(aabb.Position.x, aabb.Position.y, aabb.Position.z + aabb.Size.z) * transform; + Vector3 to7 = new Vector3(aabb.Position.x, aabb.Position.y, aabb.Position.z) * transform; + + return new AABB(pos, new Vector3()).Expand(to1).Expand(to2).Expand(to3).Expand(to4).Expand(to5).Expand(to6).Expand(to7); + } + + /// <summary> + /// Returns a Plane transformed (multiplied) by the transformation matrix. + /// </summary> + /// <param name="transform">The transformation to apply.</param> + /// <param name="plane">A Plane to transform.</param> + /// <returns>The transformed Plane.</returns> + public static Plane operator *(Transform3D transform, Plane plane) + { + Basis bInvTrans = transform.basis.Inverse().Transposed(); + + // Transform a single point on the plane. + Vector3 point = transform * (plane.Normal * plane.D); + + // Use inverse transpose for correct normals with non-uniform scaling. + Vector3 normal = (bInvTrans * plane.Normal).Normalized(); + + real_t d = normal.Dot(point); + return new Plane(normal, d); + } + + /// <summary> + /// Returns a Plane transformed (multiplied) by the inverse transformation matrix. + /// </summary> + /// <param name="plane">A Plane to inversely transform.</param> + /// <param name="transform">The transformation to apply.</param> + /// <returns>The inversely transformed Plane.</returns> + public static Plane operator *(Plane plane, Transform3D transform) + { + Transform3D tInv = transform.AffineInverse(); + Basis bTrans = transform.basis.Transposed(); + + // Transform a single point on the plane. + Vector3 point = tInv * (plane.Normal * plane.D); + + // Note that instead of precalculating the transpose, an alternative + // would be to use the transpose for the basis transform. + // However that would be less SIMD friendly (requiring a swizzle). + // So the cost is one extra precalced value in the calling code. + // This is probably worth it, as this could be used in bottleneck areas. And + // where it is not a bottleneck, the non-fast method is fine. + + // Use transpose for correct normals with non-uniform scaling. + Vector3 normal = (bTrans * plane.Normal).Normalized(); + + real_t d = normal.Dot(point); + return new Plane(normal, d); + } + + /// <summary> + /// Returns a copy of the given Vector3[] transformed (multiplied) by the transformation matrix. + /// </summary> + /// <param name="transform">The transformation to apply.</param> + /// <param name="array">A Vector3[] to transform.</param> + /// <returns>The transformed copy of the Vector3[].</returns> + public static Vector3[] operator *(Transform3D transform, Vector3[] array) + { + Vector3[] newArray = new Vector3[array.Length]; + + for (int i = 0; i < array.Length; i++) + { + newArray[i] = transform * array[i]; + } + + return newArray; + } + + /// <summary> + /// Returns a copy of the given Vector3[] transformed (multiplied) by the inverse transformation matrix. + /// </summary> + /// <param name="array">A Vector3[] to inversely transform.</param> + /// <param name="transform">The transformation to apply.</param> + /// <returns>The inversely transformed copy of the Vector3[].</returns> + public static Vector3[] operator *(Vector3[] array, Transform3D transform) + { + Vector3[] newArray = new Vector3[array.Length]; + + for (int i = 0; i < array.Length; i++) + { + newArray[i] = array[i] * transform; + } + + return newArray; + } + + /// <summary> /// Returns <see langword="true"/> if the transforms are exactly equal. /// Note: Due to floating-point precision errors, consider using /// <see cref="IsEqualApprox"/> instead, which is more reliable. diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index e47efacf69..04c2ea7eb9 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -639,16 +639,6 @@ namespace Godot } /// <summary> - /// Constructs a new <see cref="Vector2"/> from an existing <see cref="Vector2"/>. - /// </summary> - /// <param name="v">The existing <see cref="Vector2"/>.</param> - public Vector2(Vector2 v) - { - x = v.x; - y = v.y; - } - - /// <summary> /// Creates a unit Vector2 rotated to the given angle. This is equivalent to doing /// <c>Vector2(Mathf.Cos(angle), Mathf.Sin(angle))</c> or <c>Vector2.Right.Rotated(angle)</c>. /// </summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs index 84790404d7..a8f42972d7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs @@ -350,27 +350,6 @@ namespace Godot } /// <summary> - /// Constructs a new <see cref="Vector2i"/> from an existing <see cref="Vector2i"/>. - /// </summary> - /// <param name="vi">The existing <see cref="Vector2i"/>.</param> - public Vector2i(Vector2i vi) - { - this.x = vi.x; - this.y = vi.y; - } - - /// <summary> - /// Constructs a new <see cref="Vector2i"/> from an existing <see cref="Vector2"/> - /// by rounding the components via <see cref="Mathf.RoundToInt(real_t)"/>. - /// </summary> - /// <param name="v">The <see cref="Vector2"/> to convert.</param> - public Vector2i(Vector2 v) - { - this.x = Mathf.RoundToInt(v.x); - this.y = Mathf.RoundToInt(v.y); - } - - /// <summary> /// Adds each component of the <see cref="Vector2i"/> /// with the components of the given <see cref="Vector2i"/>. /// </summary> @@ -674,7 +653,10 @@ namespace Godot /// <param name="value">The vector to convert.</param> public static explicit operator Vector2i(Vector2 value) { - return new Vector2i(value); + return new Vector2i( + Mathf.RoundToInt(value.x), + Mathf.RoundToInt(value.y) + ); } /// <summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index e796d2f20f..d5941d6b60 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -518,7 +518,7 @@ namespace Godot throw new ArgumentException("Argument is not normalized", nameof(axis)); } #endif - return new Basis(axis, angle).Xform(this); + return new Basis(axis, angle) * this; } /// <summary> @@ -692,17 +692,6 @@ namespace Godot } /// <summary> - /// Constructs a new <see cref="Vector3"/> from an existing <see cref="Vector3"/>. - /// </summary> - /// <param name="v">The existing <see cref="Vector3"/>.</param> - public Vector3(Vector3 v) - { - x = v.x; - y = v.y; - z = v.z; - } - - /// <summary> /// Adds each component of the <see cref="Vector3"/> /// with the components of the given <see cref="Vector3"/>. /// </summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs index 897e14ae88..eb46f36e7c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs @@ -330,29 +330,6 @@ namespace Godot } /// <summary> - /// Constructs a new <see cref="Vector3i"/> from an existing <see cref="Vector3i"/>. - /// </summary> - /// <param name="vi">The existing <see cref="Vector3i"/>.</param> - public Vector3i(Vector3i vi) - { - this.x = vi.x; - this.y = vi.y; - this.z = vi.z; - } - - /// <summary> - /// Constructs a new <see cref="Vector3i"/> from an existing <see cref="Vector3"/> - /// by rounding the components via <see cref="Mathf.RoundToInt(real_t)"/>. - /// </summary> - /// <param name="v">The <see cref="Vector3"/> to convert.</param> - public Vector3i(Vector3 v) - { - this.x = Mathf.RoundToInt(v.x); - this.y = Mathf.RoundToInt(v.y); - this.z = Mathf.RoundToInt(v.z); - } - - /// <summary> /// Adds each component of the <see cref="Vector3i"/> /// with the components of the given <see cref="Vector3i"/>. /// </summary> @@ -684,7 +661,11 @@ namespace Godot /// <param name="value">The vector to convert.</param> public static explicit operator Vector3i(Vector3 value) { - return new Vector3i(value); + return new Vector3i( + Mathf.RoundToInt(value.x), + Mathf.RoundToInt(value.y), + Mathf.RoundToInt(value.z) + ); } /// <summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs index f60033078c..20a24616ce 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs @@ -477,18 +477,6 @@ namespace Godot } /// <summary> - /// Constructs a new <see cref="Vector4"/> from an existing <see cref="Vector4"/>. - /// </summary> - /// <param name="v">The existing <see cref="Vector4"/>.</param> - public Vector4(Vector4 v) - { - x = v.x; - y = v.y; - z = v.z; - w = v.w; - } - - /// <summary> /// Adds each component of the <see cref="Vector4"/> /// with the components of the given <see cref="Vector4"/>. /// </summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs index 2802c1bb06..11c2b7234b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs @@ -258,31 +258,6 @@ namespace Godot } /// <summary> - /// Constructs a new <see cref="Vector4i"/> from an existing <see cref="Vector4i"/>. - /// </summary> - /// <param name="vi">The existing <see cref="Vector4i"/>.</param> - public Vector4i(Vector4i vi) - { - this.x = vi.x; - this.y = vi.y; - this.z = vi.z; - this.w = vi.w; - } - - /// <summary> - /// Constructs a new <see cref="Vector4i"/> from an existing <see cref="Vector4"/> - /// by rounding the components via <see cref="Mathf.RoundToInt(real_t)"/>. - /// </summary> - /// <param name="v">The <see cref="Vector4"/> to convert.</param> - public Vector4i(Vector4 v) - { - this.x = Mathf.RoundToInt(v.x); - this.y = Mathf.RoundToInt(v.y); - this.z = Mathf.RoundToInt(v.z); - this.w = Mathf.RoundToInt(v.w); - } - - /// <summary> /// Adds each component of the <see cref="Vector4i"/> /// with the components of the given <see cref="Vector4i"/>. /// </summary> @@ -638,7 +613,12 @@ namespace Godot /// <param name="value">The vector to convert.</param> public static explicit operator Vector4i(Vector4 value) { - return new Vector4i(value); + return new Vector4i( + Mathf.RoundToInt(value.x), + Mathf.RoundToInt(value.y), + Mathf.RoundToInt(value.z), + Mathf.RoundToInt(value.w) + ); } /// <summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj index 111920ecf6..aae7a5ebfa 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj +++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj @@ -53,6 +53,10 @@ <Compile Include="Core\Array.cs" /> <Compile Include="Core\Attributes\AssemblyHasScriptsAttribute.cs" /> <Compile Include="Core\Attributes\ExportAttribute.cs" /> + <Compile Include="Core\Attributes\ExportCategoryAttribute.cs" /> + <Compile Include="Core\Attributes\ExportGroupAttribute.cs" /> + <Compile Include="Core\Attributes\ExportSubgroupAttribute.cs" /> + <Compile Include="Core\Attributes\MustBeVariantAttribute.cs" /> <Compile Include="Core\Attributes\RPCAttribute.cs" /> <Compile Include="Core\Attributes\ScriptPathAttribute.cs" /> <Compile Include="Core\Attributes\SignalAttribute.cs" /> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Variant.cs b/modules/mono/glue/GodotSharp/GodotSharp/Variant.cs index eb8b061120..85ef258922 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Variant.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Variant.cs @@ -14,7 +14,7 @@ public partial struct Variant : IDisposable private object? _obj; private Disposer? _disposer; - private class Disposer : IDisposable + private sealed class Disposer : IDisposable { private godot_variant.movable _native; @@ -37,7 +37,7 @@ public partial struct Variant : IDisposable GC.SuppressFinalize(this); } - public void Dispose(bool disposing) + private void Dispose(bool disposing) { _native.DangerousSelfRef.Dispose(); diff --git a/modules/mono/glue/callable_glue.cpp b/modules/mono/glue/callable_glue.cpp deleted file mode 100644 index 521dc3dff7..0000000000 --- a/modules/mono/glue/callable_glue.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************/ -/* callable_glue.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifdef MONO_GLUE_ENABLED - -#include "../mono_gd/gd_mono_marshal.h" -#include "arguments_vector.h" - -MonoObject *godot_icall_Callable_Call(GDMonoMarshal::M_Callable *p_callable, MonoArray *p_args) { - Callable callable = GDMonoMarshal::managed_to_callable(*p_callable); - - int argc = mono_array_length(p_args); - - ArgumentsVector<Variant> arg_store(argc); - ArgumentsVector<const Variant *> args(argc); - - for (int i = 0; i < argc; i++) { - MonoObject *elem = mono_array_get(p_args, MonoObject *, i); - arg_store.set(i, GDMonoMarshal::mono_object_to_variant(elem)); - args.set(i, &arg_store.get(i)); - } - - Variant result; - Callable::CallError error; - callable.callp(args.ptr(), argc, result, error); - - return GDMonoMarshal::variant_to_mono_object(result); -} - -void godot_icall_Callable_CallDeferred(GDMonoMarshal::M_Callable *p_callable, MonoArray *p_args) { - Callable callable = GDMonoMarshal::managed_to_callable(*p_callable); - - int argc = mono_array_length(p_args); - - ArgumentsVector<Variant> arg_store(argc); - ArgumentsVector<const Variant *> args(argc); - - for (int i = 0; i < argc; i++) { - MonoObject *elem = mono_array_get(p_args, MonoObject *, i); - arg_store.set(i, GDMonoMarshal::mono_object_to_variant(elem)); - args.set(i, &arg_store.get(i)); - } - - callable.call_deferredp(args.ptr(), argc); -} - -void godot_register_callable_icalls() { - GDMonoUtils::add_internal_call("Godot.Callable::godot_icall_Callable_Call", godot_icall_Callable_Call); - GDMonoUtils::add_internal_call("Godot.Callable::godot_icall_Callable_CallDeferred", godot_icall_Callable_CallDeferred); -} - -#endif // MONO_GLUE_ENABLED diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index f746d63ce5..0532cc915b 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -517,6 +517,10 @@ bool GDMono::_load_project_assembly() { .plus_file(assembly_name + ".dll"); assembly_path = ProjectSettings::get_singleton()->globalize_path(assembly_path); + if (!FileAccess::exists(assembly_path)) { + return false; + } + String loaded_assembly_path; bool success = plugin_callbacks.LoadProjectAssemblyCallback(assembly_path.utf16(), &loaded_assembly_path); |