- `typeof(T).IsEnum` and `typeof(T).GetEnumUnderlyingType()` are intrinsified in .NET 8+ so we can simplify the code in VariantUtils a bit.
- Consider whether enum `T` is signed in VariantUtils to preserve it.
It previously returned the string itself when it should return an empty string according to the docs/examples and the C++ counterpart String::get_extension().
Changed StringName GetHashCode to call godot_string_name.GetHashCode instead of godot_string_name's (which was not overridden) as this otherwise leads to heap allocations when e.g. calling the indexer in a Dictionary with `StringName` type as Key.
- refactored and renamed String::_camelcase_to_underscore to String:_separate_compound_words
- refactored String::to_snake_case to work with the refactored String::_separate_compound_words
- created char_utils::is_hyphen to catch all hyphen variants in kebab-case conversion
- created String::to_kebab_case using the new String::_separate_compound_words
- created corresponding Documentation in String and StringName
- simplified both switch statements in EditorNode and ProjectDialog
- added new kebab-casing Option for Node Names in ProjectSettings
- added missing camelCase Options to Scene- and Node-Names in ProjectSettings
- simplified Mono RuntimeInterop Functions
- hooked up the ConnectionsDialog
- created additional Unit Tests
When reloading assemblies, we serialize the managed delegates so we can recreate the callables later. If the delegate's target is a GodotObject that has already been disposed, we can't serialize the delegate.
Before this change, trying to serialize one of these delegates throws an exception and prevents releasing its strong GCHandle, so the assembly can't be unloaded.
With this change, we don't serialize the delegates and release them anyway. This means some delegates may get lost on reloading assemblies, but if their target was already freed it's probably fine.
- Change TFM and LangVersion
- Better exception throwing (CA1510, CA1512, CA1513)
- Better exception utility method definition (CA1859)
- Prefer comparing `.Count` over calling `.Any()` (CA1860)
- Prefer `.AsSpan()` over `.Substring()` (CA1846)
- Add a few more `scoped`
- Use `RuntimeHelpers.GetUninitializedObject()` instead of `FormatterServices.GetUninitializedObject()`
- Use delegate instead of delegate pointer in variant generic conversions
- Enable EnforceExtendedAnalyzerRules in source generator projects
- Disable CS8981 on structs named movable in Godot.NativeInterop
Because of ref safety changes in the languages, all methods that return an interop struct have to have all other reference parameters marked as scoped to signal the the method does not capture that reference.
The variant change is necessary, because for some reason a type of the exact shape godot_variant is in, crashes the .NET 7 JIT, but when changing it to be sequential with the same effective layout it works.