summaryrefslogtreecommitdiff
path: root/modules/mono/editor/Godot.NET.Sdk
AgeCommit message (Collapse)Author
2022-10-30C#: Remove need for reflection to invoking callable delegatesIgnacio Roldán Etcheverry
We aim to make the C# API reflection-free, mainly for concerns about performance, and to be able to target NativeAOT in refletion-free mode, which reduces the binary size. One of the main usages of reflection still left was the dynamic invokation of callable delegates, and for some time I wasn't sure I would find an alternative solution that I'd be happy with. The new solution uses trampoline functions to invoke the delegates: ``` static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret) { if (args.Count != 1) throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}."); string res = ((Func<int, string>)delegateObj)( VariantConversionCallbacks.GetToManagedCallback<int>()(args[0]) ); ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res); } Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline); ``` Of course, this is too much boilerplate for user code. To improve this, the `Callable.From` methods were added. These are overloads that take `Action` and `Func` delegates, which covers the most common use cases: lambdas and method groups: ``` // Lambda Callable.From((int num) => "Foo" + num); // Method group string AppendNum(int num) => "Foo" + num; Callable.From(AppendNum); ``` Unfortunately, due to limitations in the C# language, implicit conversions from delegates to `Callable` are not supported. `Callable.From` does not support custom delegates. These should be uncommon, but the Godot C# API actually uses them for event signals. As such, the bindings generator was updated to generate trampoline functions for event signals. It was also optimized to use `Action` instead of a custom delegate for parameterless signals, which removes the need for the trampoline functions for those signals. The change to reflection-free invokation removes one of the last needs for `ConvertVariantToManagedObjectOfType`. The only remaining usage is from calling script constructors with parameters from the engine (`CreateManagedForGodotObjectScriptInstance`). Once that one is made reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
2022-10-22Use `.generated` suffix for generated C# codeRaul Santos
Use the `.generated` suffix instead of `_Generated` so .NET marks C# file generated by Godot source generators as generated code.
2022-09-30Fix typos with codespellRémi Verschelde
Using codespell 2.3-dev from current git. And fix typo in `methods.py` for `vsproj=yes` option (still won't work though).
2022-09-22Merge pull request #66253 from raulsntos/dotnet/assembly-may-be-nullIgnacio Roldán Etcheverry
C#: Guard against null assemblies
2022-09-22C#: Suppress EventHandler suffix diagnostic for signalsRaul Santos
Suppress CA1711 for signal delegates because they are used in events so the naming follows the guidelines.
2022-09-22C#: Guard against null assembliesRaul Santos
A symbol's containing assembly will be null if the symbol is shared across multiple assemblies.
2022-09-19Merge pull request #65879 from magian1127/4.0GenSDocRémi Verschelde
inheritdoc the "///" comment from EventHandler to the generated event
2022-09-18C#: inheritdoc the "///" comment from EventHandler to the generated eventMagian
2022-09-17don't marshal multidimensional arraysantonWetzel
2022-09-15Fix NuGet fallback folder packagesRaul Santos
- Creates a `Godot.Offline.Config` file to configurate NuGet with Godot's fallback folder. This is easier because now we can assume we can override the entire file since user config will likely be in the default `NuGet.Config` file or an additional `*.config` file. - Ensure the NuGet fallback folder is created at the same time it is added to the NuGet configuration so future builds don't fail. - Add `GodotSharp` and `GodotSharpEditor` packages to the fallback folder. - Add `.nupkg.metadata` file to packages in fallback folder. - Refer to `Godot.SourceGenerators` using the specific non-floating version since floating versions don't seem to work with fallbackPackageFolders.
2022-09-06Merge pull request #65433 from neikeq/fix-mustbevariant-omittedtypeargRémi Verschelde
2022-09-06C#: Make MustBeVariantAnalyzer ignore OmittedTypeArgumentIgnacio Roldán Etcheverry
Fixes assertion error in the analyzer.
2022-09-06C# Modify the MemberName generated for the user scriptMagian
2022-09-04Add float arg to build_assemblies.pyAlmighty Laxz
2022-09-01C#: Assume 64-bit types when type has no metaRaul Santos
When the C# bindings generator finds a type without meta assume the type refers to the 64-bit version of the type: - `float` is converted to `double` - `int` is converted to `long`
2022-08-29C#: Fix exported game crash because of uninitialized callbacksIgnacio Roldán Etcheverry
This was a regression from 2c180f62d985194060f1a8d2070c130081177c90, where I forgot to update the source generator.
2022-08-29[Web] Rename JavaScript platform to Web.Fabio Alessandrelli
Also rename export name from "HTML5" to "Web".
2022-08-29Merge pull request #64956 from raulsntos/dotnet/format-ciRémi Verschelde
Add `dotnet format` to CI to check C# style
2022-08-29Merge pull request #64900 from raulsntos/dotnet/fix-exceptionsIgnacio Roldán Etcheverry
Fix various C# exceptions
2022-08-28C#: Ignore property indexers and report if exportedRaul Santos
Ignore property indexers since they are unsupported and report a diagnostic if an user tries to export it.
2022-08-27Fix C# style with `dotnet format`Raul Santos
2022-08-26Fix various C# exceptionsRaul Santos
- Replace `IndexOutOfRangeException` with `ArgumentOutOfRangeException` - Replace `Exception` with a more specific exception - Add the parameter name to argument exception - Update documentation for methods that throw exceptions - Use `StringBuilder` to build exception messages - Ensure exception messages end with a period
2022-08-26Remove `[Signal]` attribute from eventsRaul Santos
- Remove event as a valid target of `SignalAttribute` - Stop adding the `[Signal]` attribute to events in bindings_generator - Make bindings_generator use the `EventHandler` suffix to be consistent with the C# source generator - Remove obsolete comment about the signal's delegate name
2022-08-25C#: Preserve order of exported fields/categoriesPaul Joannon
2022-08-25Merge pull request #64731 from raulsntos/dotnet6-variant-generics-analyzerRémi Verschelde
C#: Add `MustBeVariant` attribute and analyzer
2022-08-25Add MustBeVariant attribute and analyzerRaul Santos
- MustBeVariant attribute can be used to enforce that generic types must be a marshable from/to Variant. - Also renames all diagnostic ids to be valid unicode identifiers.
2022-08-24Remove mentions of the Server platform from the Mono moduleAaron Franke
2022-08-24Merge pull request #64742 from zaevi/csharp_add_grouping_attributesIgnacio Roldán Etcheverry
C#: Add grouping attributes for properties.
2022-08-22Improve C# signal analyzer errorsRaul Santos
Report the specific parameters that are not supported.
2022-08-23C#: Add grouping attributes for properties.Zae
2022-08-22C#: Re-introduce generic Godot Array and DictionaryIgnacio Roldán Etcheverry
This new version does not support the following type arguments: - Generic types - Array of Godot Object (Godot.Object[]) or derived types The new implementation uses delegate pointers to call the Variant conversion methods. We do type checking only once in the static constructor to get the conversion delegates. Now, we no longer need to do type checking every time, and we no longer have to box value types. This is the best implementation I could come up with, as C# generics don't support anything similar to C++ template specializations.
2022-08-22C#: Array, Dictionary and marshaling refactoringIgnacio Roldán Etcheverry
- Array and Dictionary now store `Variant` instead of `System.Object`. - Removed generic Array and Dictionary. They cause too much issues, heavily relying on reflection and very limited by the lack of a generic specialization. - Removed support for non-Godot collections. Support for them also relied heavily on reflection for marshaling. Support for them will likely be re-introduced in the future, but it will have to rely on source generators instead of reflection. - Reduced our use of reflection. The remaining usages will be moved to source generators soon. The only usage that I'm not sure yet how to replace is dynamic invocation of delegates.
2022-08-22C#: Add dedicated Variant struct, replacing System.ObjectIgnacio Roldán Etcheverry
2022-08-22C#: Add source generator for method listIgnacio Roldán Etcheverry
2022-08-22C#: Add source generator for signals as eventsIgnacio Roldán Etcheverry
Changed the signal declaration signal to: ``` // The following generates a MySignal event [Signal] public delegate void MySignalEventHandler(int param); ```
2022-08-22C#: Re-implement assembly reloading with ALCsIgnacio Roldán Etcheverry
2022-08-22C#: Make GodotSharp API a NuGet packageIgnacio Roldán Etcheverry
In the past, the Godot editor distributed the API assemblies and copied them to project directories for projects to reference them. This changed with the move to .NET 5/6. Godot no longer copies the assemblies to project directories. However, the project Sdk still tried to reference them from the same location. From now on, the GodotSharp API is distributed as a NuGet package, which the Sdk can reference. Added an option to `build_assemblies.py` to copy all Godot NuGet packages to an existing local NuGet source. This will be needed during development, while packages are not published to a remote NuGet repository. This option also makes sure to remove packages of the same version installed (~/.nuget/packages). Very useful during development, when packages change, to make sure the package being used by a project is the same we just built and not one from a previous build. A local NuGet source can be created like this: ``` mkdir ~/MyLocalNuGetSource && \ dotnet nuget add source ~/MyLocalNuGetSource/ -n MyLocalNuGetSource ```
2022-08-22C#: Initial NativeAOT supportIgnacio Roldán Etcheverry
This commit adds initial support for games exported as NativeAOT shared libraries. At this moment, the NativeAOT runtime is experimental. Additionally, Godot is not trim-safe as it still makes some use of reflection. For the time being, a rd.xml file is needed to prevent code triming: ``` <Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata"> <Application> <Assembly Name="GodotSharp" Dynamic="Required All" /> <Assembly Name="GAME_ASSEMBLY" Dynamic="Required All" /> </Application> </Directives> ``` These are the csproj changes for publishing: ``` <PropertyGroup> <NativeLib>Shared</NativeLib> </PropertyGroup> <ItemGroup> <RdXmlFile Include="rd.xml" /> <PackageReference Include="Microsoft.DotNet.ILCompiler" Version="7.0.0-*" /> </ItemGroup> ``` More info: - https://github.com/dotnet/runtimelab/blob/feature/NativeAOT/docs/using-nativeaot/compiling.md - https://github.com/dotnet/runtimelab/tree/feature/NativeAOT/samples/NativeLibrary - https://github.com/dotnet/runtimelab/blob/feature/NativeAOT/docs/using-nativeaot/rd-xml-format.md
2022-08-22C#: Upgrade to .NET 6 (5.0 -> 6.0)Ignacio Roldán Etcheverry
2022-08-22C#: Static marshaling for bindings and source generatorsIgnacio Roldán Etcheverry
Previously, we added source generators for invoking/accessing methods, properties and fields in scripts. This freed us from the overhead of reflection. However, the generated code still used our dynamic marshaling functions, which do runtime type checking and box value types. This commit changes the bindings and source generators to include 'static' marshaling. Based on the types known at compile time, now we generate the appropriate marshaling call for each type.
2022-08-22C#: Add source generator for properties and exports default valuesIgnacio Roldán Etcheverry
The editor no longer needs to create temporary instances to get the default values. The initializer values of the exported properties are still evaluated at runtime. For example, in the following example, `GetInitialValue()` will be called when first looks for default values: ``` [Export] int MyValue = GetInitialValue(); ``` Exporting fields with a non-supported type now results in a compiler error rather than a runtime error when the script is used.
2022-08-22C#/netcore: Add base desktop game export implementationIgnacio Roldán Etcheverry
This base implementation is still very barebones but it defines the path for how exporting will work (at least when embedding the .NET runtime). Many manual steps are still needed, which should be automatized in the future. For example, in addition to the API assemblies, now you also need to copy the GodotPlugins assembly to each game project.
2022-08-22C#: Add initial implementation of source generator for script membersIgnacio Roldán Etcheverry
This replaces the way we invoke methods and set/get properties. This first iteration rids us of runtime type checking in those cases, as it's now done at compile time. Later it will also stop needing the use of reflection. After that, we will only depend on reflection for generic Godot Array and Dictionary. We're stuck with reflection in generic collections for now as C# doesn't support generic/template specialization. This is only the initial implementation. Further iterations are coming, specially once we switch to the native extension system which completely changes the way members are accessed/invoked. For example, with the native extension system we will likely need to create `UnmanagedCallersOnly` invoke wrapper methods and return function pointers to the engine. Other kind of members, like event signals will be receiving the same treatment in the future.
2022-08-22C#: Begin move to .NET CoreIgnacio Roldán Etcheverry
We're targeting .NET 5 for now to make development easier while .NET 6 is not yet released. TEMPORARY REGRESSIONS --------------------- Assembly unloading is not implemented yet. As such, many Godot resources are leaked at exit. This will be re-implemented later together with assembly hot-reloading.
2022-07-21Rename OSX to macOS and iPhoneOS to iOS.bruvzg
2021-12-05Bump Godot.NET.Sdk and SourceGenerators versionsRaul Santos
Bump `Godot.NET.Sdk` to version 4.0.0-dev6. Bump `Godot.SourceGenerators` to version 4.0.0-dev3. Use floating version 4.0.*-* for package references in Sdk.
2021-12-05Fix Godot.SourceGenerators for generic classesRaul Santos
Fix invalid C# generated by source generators for generic classes and add generic classes to the Sample project for testing.
2021-07-23Add a simple C# .editorconfigAaron Franke
2021-03-13C#: Fix ScriptPathAttribute generator with none or nested namespacesIgnacio Etcheverry
The following two bugs were fixed: - For classes without namespace we were still generating `namespace {` without a namespace identifier, causing a syntax error. - For classes with nested namespaces we were generating only the innermost part of the namespace was being generated, e.g.: for `Foo.Bar` we were generating `namespace Bar {` instead of `namespace Foo.Bar {`. This wasn't causing any build error, but because of the wrong namespace Godot wasn't able to find the class associated with the script.
2021-03-06Add C# source generator for a new ScriptPath attributeIgnacio Etcheverry
This source generator adds a newly introduced attribute, `ScriptPath` to all classes that: - Are top-level classes (not inner/nested). - Have the `partial` modifier. - Inherit `Godot.Object`. - The class name matches the file name. A build error is thrown if the generator finds a class that meets these conditions but is not declared `partial`, unless the class is annotated with the `DisableGodotGenerators` attribute. We also generate an `AssemblyHasScripts` assembly attribute which Godot uses to get all the script classes in the assembly, eliminating the need for Godot to search them. We can also avoid searching in assemblies that don't have this attribute. This will be good for performance in the future once we support multiple assemblies with Godot script classes. This is an example of what the generated code looks like: ``` using Godot; namespace Foo { [ScriptPathAttribute("res://Player.cs")] // Multiple partial declarations are allowed [ScriptPathAttribute("res://Foo/Player.cs")] partial class Player {} } [assembly:AssemblyHasScripts(new System.Type[] { typeof(Foo.Player) })] ``` The new attributes replace script metadata which we were generating by determining the namespace of script classes with a very simple parser. This fixes several issues with the old approach related to parser errors and conditional compilation. It also makes the task part of the MSBuild project build, rather than a separate step executed by the Godot editor.