summaryrefslogtreecommitdiff
path: root/modules/mono/mono_gd
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-09-08C#: Fix module builds for Windows 32-bit with mingw-w64Ignacio Roldán Etcheverry
The lambda was giving issues, so I re-wrote it as a static function.
2022-09-07C#: Replace libnethost dependency to find hostfxrIgnacio Roldán Etcheverry
We want to replace libnethost as it gives us issues with some compilers. Our implementation tries to mimic libnethost's hostfxr_resolver search logic. We try to use the same function names for easier comparing in case we need to update this in the future.
2022-08-29Rename String `plus_file` to `path_join`Aaron Franke
2022-08-29Merge pull request #65049 from paulloz/dotnet/win10-exportIgnacio Roldán Etcheverry
C#: Fix .NET export template compilation on Windows
2022-08-29Fix .NET export template compilation on Windows 10Paul Joannon
2022-08-28Fix .NET exporting in LinuxRaul Santos
- Fix platform detection after Linux OS name was renamed from `LinuxBSD` to `Linux` - Fix arch detection after renaming `64` to `x86_64` - Fix typo in `find_hostfxr`
2022-08-22Avoid trying to load non-existent assemblyRaul Santos
If the project assembly does not exist, return `false` directly instead of trying to load it. This prevents the `System.InvalidOperationException` thrown for failing to locate managed application.
2022-08-22C#: Replace P/Invoke with delegate pointersIgnacio Roldán Etcheverry
- Moves interop functions to UnmanagedCallbacks struct that contains the function pointers and is passed to C#. - Implements UnmanagedCallbacksGenerator, a C# source generator that generates the UnmanagedCallbacks struct in C# and the body for the NativeFuncs methods (their implementation just calls the function pointer in the UnmanagedCallbacks). The generated methods are needed because .NET pins byref parameters of native calls, even if they are 'ref struct's, which don't need pinning. The generated methods use `Unsafe.AsPointer` so that we can benefit from byref parameters without suffering overhead of pinning. Co-authored-by: Raul Santos <raulsntos@gmail.com>
2022-08-22C#: Use custom project setting for C# project files nameIgnacio Roldán Etcheverry
The setting is initially assigned the name of the Godot project, but it's kept freezed to prevent issues when renaming the Godot project. The user can always rename the C# project and solution manually and change the setting to the new name.
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#: 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#: Re-introduce exception logging and error stack traces in editorIgnacio Roldán Etcheverry
These two had been disabled while moving to .NET 5, as the previous implementation relied on Mono embedding APIs.
2022-08-22C#: Ensure we only create one CSharpScript per typeIgnacio Roldán Etcheverry
Previously, for each scripts class instance that was created from code rather than by the engine, we were constructing, configuring and assigning a new CSharpScript. This has changed now and we make sure there's only one CSharpScript associated to 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#: Ensure native handles are freed after switch to .NET CoreIgnacio Roldán Etcheverry
Finalizers are longer guaranteed to be called on exit now that we switched to .NET Core. This results in native instances leaking. The only solution I can think of so far is to keep a list of all instances alive to dispose when the AssemblyLoadContext.Unloading event is raised.
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-08-22C#: Restructure code prior move to .NET CoreIgnacio Roldán Etcheverry
The main focus here was to remove the majority of code that relied on Mono's embedding APIs, specially the reflection APIs. The embedding APIs we still use are the bare minimum we need for things to work. A lot of code was moved to C#. We no longer deal with any managed objects (`MonoObject*`, and such) in native code, and all marshaling is done in C#. The reason for restructuring the code and move away from embedding APIs is that once we move to .NET Core, we will be limited by the much more minimal .NET hosting. PERFORMANCE REGRESSIONS ----------------------- Some parts of the code were written with little to no concern about performance. This includes code that calls into script methods and accesses script fields, properties and events. The reason for this is that all of that will be moved to source generators, so any work prior to that would be a waste of time. DISABLED FEATURES ----------------- Some code was removed as it no longer makes sense (or won't make sense in the future). Other parts were commented out with `#if 0`s and TODO warnings because it doesn't make much sense to work on them yet as those parts will change heavily when we switch to .NET Core but also when we start introducing source generators. As such, the following features were disabled temporarily: - Assembly-reloading (will be done with ALCs in .NET Core). - Properties/fields exports and script method listing (will be handled by source generators in the future). - Exception logging in the editor and stack info for errors. - Exporting games. - Building of C# projects. We no longer copy the Godot API assemblies to the project directory, so MSBuild won't be able to find them. The idea is to turn them into NuGet packages in the future, which could also be obtained from local NuGet sources during development.
2022-08-22C#: Re-write GD and some other icalls as P/InvokeIgnacio Roldán Etcheverry
2022-08-22C#: Re-write Array, Dictionary, NodePath, String icalls as P/InvokeIgnacio Roldán Etcheverry
2022-08-22C#: Move marshaling logic and generated glue to C#Ignacio Roldán Etcheverry
We will be progressively moving most code to C#. The plan is to only use Mono's embedding APIs to set things at launch. This will make it much easier to later support CoreCLR too which doesn't have rich embedding APIs. Additionally the code in C# is more maintainable and makes it easier to implement new features, e.g.: runtime codegen which we could use to avoid using reflection for marshaling everytime a field, property or method is accessed. SOME NOTES ON INTEROP We make the same assumptions as GDNative about the size of the Godot structures we use. We take it a bit further by also assuming the layout of fields in some cases, which is riskier but let's us squeeze out some performance by avoiding unnecessary managed to native calls. Code that deals with native structs is less safe than before as there's no RAII and copy constructors in C#. It's like using the GDNative C API directly. One has to take special care to free values they own. Perhaps we could use roslyn analyzers to check this, but I don't know any that uses attributes to determine what's owned or borrowed. As to why we maily use pointers for native structs instead of ref/out: - AFAIK (and confirmed with a benchmark) ref/out are pinned during P/Invoke calls and that has a cost. - Native struct fields can't be ref/out in the first place. - A `using` local can't be passed as ref/out, only `in`. Calling a method or property on an `in` value makes a silent copy, so we want to avoid `in`. REGARDING THE BUILD SYSTEM There's no longer a `mono_glue=yes/no` SCons options. We no longer need to build with `mono_glue=no`, generate the glue and then build again with `mono_glue=yes`. We build only once and generate the glue (which is in C# now). However, SCons no longer builds the C# projects for us. Instead one must run `build_assemblies.py`, e.g.: ```sh %godot_src_root%/modules/mono/build_scripts/build_assemblies.py \ --godot-output-dir=%godot_src_root%/bin \ --godot-target=release_debug` ``` We could turn this into a custom build target, but I don't know how to do that with SCons (it's possible with Meson). OTHER NOTES Most of the moved code doesn't follow the C# naming convention and still has the word Mono in the names despite no longer dealing with Mono's embedding APIs. This is just temporary while transitioning, to make it easier to understand what was moved where.
2022-07-31create vector4, vector4i and projection for csharpantonWetzel
2022-07-25Code quality: Fix header guards consistencyRémi Verschelde
Adds `header_guards.sh` bash script, used in CI to validate future changes. Can be run locally to fix invalid header guards.
2022-07-23Implement Vector4, Vector4i, Projectionreduz
Implement built-in classes Vector4, Vector4i and Projection. * Two versions of Vector4 (float and integer). * A Projection class, which is a 4x4 matrix specialized in projection types. These types have been requested for a long time, but given they were very corner case they were not added before. Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity. **Q**: Why Projection and not Matrix4? **A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-21Rename OSX to macOS and iPhoneOS to iOS.bruvzg
2022-07-07C#: New `RPCAttribute`Raul Santos
Replace old RPC attributes with a new single `RPCAttribute` which works like the GDScript `@rpc` annotation.
2022-06-03Support explicit values in flag properties, add C# flags supportRaul Santos
- Add support for explicit values in properties using `PROPERTY_HINT_FLAGS` that works the same way it does for enums. - Fix enums and flags in VisualScriptEditor (it wasn't considering the explicit value). - Use `PROPERTY_HINT_FLAGS` for C# enums with the FlagsAttribute instead of `PROPERTY_HINT_ENUM`.
2022-05-16Replace most uses of Map by HashMapreduz
* Map is unnecessary and inefficient in almost every case. * Replaced by the new HashMap. * Renamed Map to RBMap and Set to RBSet for cases that still make sense (order matters) but use is discouraged. There were very few cases where replacing by HashMap was undesired because keeping the key order was intended. I tried to keep those (as RBMap) as much as possible, but might have missed some. Review appreciated!
2022-05-12Add a new HashMap implementationreduz
Adds a new, cleaned up, HashMap implementation. * Uses Robin Hood Hashing (https://en.wikipedia.org/wiki/Hash_table#Robin_Hood_hashing). * Keeps elements in a double linked list for simpler, ordered, iteration. * Allows keeping iterators for later use in removal (Unlike Map<>, it does not do much for performance vs keeping the key, but helps replace old code). * Uses a more modern C++ iterator API, deprecates the old one. * Supports custom allocator (in case there is a wish to use a paged one). This class aims to unify all the associative template usage and replace it by this one: * Map<> (whereas key order does not matter, which is 99% of cases) * HashMap<> * OrderedHashMap<> * OAHashMap<>
2022-04-29Rename Basis "elements" to "rows"Aaron Franke
2022-04-29Rename Transform2D "elements" to "columns"Aaron Franke
2022-04-12Narrow FileAccess scope to prevent deadlocks.bruvzg
2022-04-11Make FileAccess and DirAccess classes reference counted.bruvzg
2022-04-04Zero initialize all pointer class and struct membersRémi Verschelde
This prevents the pitfall of UB when checking if they have been assigned something valid by comparing to nullptr.
2022-03-31Fix typos with codespellRémi Verschelde
Using codespell 2.2-dev from current git. Fix a couple incorrect uses of gendered pronouns.
2022-03-11Convert uses of `DirAccess *` to `DirAccessRef` to prevent memleaksRémi Verschelde
`DirAccess *` needs to be deleted manually, and this is often forgotten especially when doing early returns with `ERR_FAIL_COND`. `DirAccessRef` is deleted automatically when it goes out of scope. Co-authored-by: bruvzg <7645683+bruvzg@users.noreply.github.com>
2022-02-16Style: Cleanup single-line blocks, semicolons, dead codeRémi Verschelde
Remove currently unused implementation of TextureBasisU, could be re-added later on if needed and ported.
2022-02-12Use EditorFileDialog instead of FileDialog in the project managerHendrik Brucker
2022-01-03Update copyright statements to 2022Rémi Verschelde
Happy new year to the wonderful Godot community!
2021-12-04Fix get_all_delegates method for generic classesRaul Santos
If the class is generic, we must get its generic type definition and use it to retrieve the delegates.
2021-11-30Don't return reference on copy assignment operatorsRémi Verschelde
We prefer to prevent using chained assignment (`T a = b = c = T();`) as this can lead to confusing code and subtle bugs. According to https://en.wikipedia.org/wiki/Assignment_operator_(C%2B%2B), C++ allows any arbitrary return type, so this is standard compliant. This could be re-assessed if/when we have an actual need for a behavior more akin to that of the C++ STL, for now this PR simply changes a handful of cases which were inconsistent with the rest of the codebase (`void` return type was already the most common case prior to this commit).
2021-11-10Move Mono unhandled exception setting to be located within a subsectionHugo Locurcio
Settings that aren't within a subsection are difficult to reach when other settings do have a subsection. This also adds documentation for the project setting.
2021-10-28clang-format: Enable `BreakBeforeTernaryOperators`Rémi Verschelde
clang-format keeps breaking the way it handles break *after* ternary operators, so I give up and go with the only style they seem to actually test.
2021-10-28clang-format: Disable alignment of operands, too unreliableRémi Verschelde
Sets `AlignOperands` to `DontAlign`. `clang-format` developers seem to mostly care about space-based indentation and every other version of clang-format breaks the bad mismatch of tabs and spaces that it seems to use for operand alignment. So it's better without, so that it respects our two-tabs `ContinuationIndentWidth`.
2021-10-20Mono: Fix build after #52940Rémi Verschelde
Chose to pass unhandled exceptions to the toaster, we might want to reconsider if those are already reported somewhere else (e.g. in the Mono panel).
2021-10-19C#: Fix property set call boxing value when unboxed was expectedIgnacio Roldán Etcheverry
2021-10-18Fix marshaling generic Godot.Object in C#Raul Santos