├── Assets ├── icon.png └── icon_no_back.png ├── libgodotsharp ├── Notification.cs ├── Extensions │ ├── RefCounted.cs │ ├── ArrayMesh.cs │ ├── Transform2D.cs │ ├── Basisc.cs │ ├── Node.cs │ ├── Transform3D.cs │ ├── NodePath.cs │ ├── Object.cs │ ├── StringName.cs │ ├── Projection.cs │ ├── MathGD.cs │ ├── Callable.cs │ ├── PackedStringArray.cs │ ├── PackedInt32Array.cs │ ├── PackedInt64Array.cs │ ├── PackedColorArray.cs │ ├── PackedFloat32Array.cs │ ├── PackedFloat64Array.cs │ ├── PackedVector2Array.cs │ ├── PackedVector3Array.cs │ ├── Array.cs │ ├── PackedByteArray.cs │ └── ArrayTyped.cs ├── Attributes │ ├── NotificationAttribute.cs │ ├── MethodAttribute .cs │ ├── SignalAttribute.cs │ ├── ExportAttribute.cs │ ├── RegisterAttribute.cs │ └── NotifyAttribute.cs ├── GDExtensionMain.cs ├── Wrapped.cs ├── StringMarshall.cs ├── ResourceHelper.cs ├── SaftyRapper.cs ├── Renamer.cs ├── AndroidTest.cs ├── LibGodotSharp.csproj ├── GenNotification.cs ├── Export.cs ├── Signal.cs ├── Generator.cs ├── Variant.cs ├── Entry.cs ├── Register.cs ├── LibGodotCustomCallable.cs ├── GenVirtual.cs └── Methods.cs ├── TemplateProject ├── Platforms │ ├── Desktop │ │ ├── icon.ico │ │ ├── icon.png │ │ ├── Program.cs │ │ └── DesktopPlatform.csproj │ └── Android │ │ ├── Resources │ │ ├── mipmap-hdpi │ │ │ ├── appicon.png │ │ │ ├── appicon_background.png │ │ │ └── appicon_foreground.png │ │ ├── mipmap-mdpi │ │ │ ├── appicon.png │ │ │ ├── appicon_background.png │ │ │ └── appicon_foreground.png │ │ ├── mipmap-xhdpi │ │ │ ├── appicon.png │ │ │ ├── appicon_background.png │ │ │ └── appicon_foreground.png │ │ ├── mipmap-xxhdpi │ │ │ ├── appicon.png │ │ │ ├── appicon_background.png │ │ │ └── appicon_foreground.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── appicon.png │ │ │ ├── appicon_background.png │ │ │ └── appicon_foreground.png │ │ ├── values │ │ │ ├── strings.xml │ │ │ └── themes.xml │ │ ├── drawable-nodpi │ │ │ ├── splash_sceen.png │ │ │ └── splash_sceen_bg_color.png │ │ ├── mipmap-anydpi-v26 │ │ │ ├── appicon.xml │ │ │ └── appicon_round.xml │ │ └── drawable │ │ │ └── main_splash_drawable.xml │ │ ├── AndroidPlatform.csproj │ │ ├── AndroidManifest.xml │ │ └── GodotApp.cs ├── README.md ├── GodotApplication │ ├── GodotApplication.csproj │ ├── DemoSpinningCubeNode.cs │ └── GodotApplication.cs └── GodotApplication.sln ├── TestAndroid ├── Resources │ ├── drawable-nodpi │ │ ├── splash.png │ │ └── splash_bg_color.png │ ├── values │ │ ├── godot_project_name_string.xml │ │ └── themes.xml │ ├── values-ar │ │ └── godot_project_name_string.xml │ ├── values-bg │ │ └── godot_project_name_string.xml │ ├── values-ca │ │ └── godot_project_name_string.xml │ ├── values-cs │ │ └── godot_project_name_string.xml │ ├── values-da │ │ └── godot_project_name_string.xml │ ├── values-de │ │ └── godot_project_name_string.xml │ ├── values-el │ │ └── godot_project_name_string.xml │ ├── values-en │ │ └── godot_project_name_string.xml │ ├── values-es │ │ └── godot_project_name_string.xml │ ├── values-fa │ │ └── godot_project_name_string.xml │ ├── values-fi │ │ └── godot_project_name_string.xml │ ├── values-fr │ │ └── godot_project_name_string.xml │ ├── values-hi │ │ └── godot_project_name_string.xml │ ├── values-hr │ │ └── godot_project_name_string.xml │ ├── values-hu │ │ └── godot_project_name_string.xml │ ├── values-in │ │ └── godot_project_name_string.xml │ ├── values-it │ │ └── godot_project_name_string.xml │ ├── values-iw │ │ └── godot_project_name_string.xml │ ├── values-ja │ │ └── godot_project_name_string.xml │ ├── values-ko │ │ └── godot_project_name_string.xml │ ├── values-lt │ │ └── godot_project_name_string.xml │ ├── values-lv │ │ └── godot_project_name_string.xml │ ├── values-nb │ │ └── godot_project_name_string.xml │ ├── values-nl │ │ └── godot_project_name_string.xml │ ├── values-pl │ │ └── godot_project_name_string.xml │ ├── values-pt │ │ └── godot_project_name_string.xml │ ├── values-ro │ │ └── godot_project_name_string.xml │ ├── values-ru │ │ └── godot_project_name_string.xml │ ├── values-sk │ │ └── godot_project_name_string.xml │ ├── values-sl │ │ └── godot_project_name_string.xml │ ├── values-sr │ │ └── godot_project_name_string.xml │ ├── values-sv │ │ └── godot_project_name_string.xml │ ├── values-th │ │ └── godot_project_name_string.xml │ ├── values-tl │ │ └── godot_project_name_string.xml │ ├── values-tr │ │ └── godot_project_name_string.xml │ ├── values-uk │ │ └── godot_project_name_string.xml │ ├── values-vi │ │ └── godot_project_name_string.xml │ ├── values-zh │ │ └── godot_project_name_string.xml │ ├── values-es-rES │ │ └── godot_project_name_string.xml │ ├── values-zh-rHK │ │ └── godot_project_name_string.xml │ ├── values-zh-rTW │ │ └── godot_project_name_string.xml │ └── drawable │ │ └── splash_drawable.xml ├── TestAndroid.csproj ├── AndroidManifest.xml └── GodotApp.cs ├── TestConsoleApp ├── Properties │ └── launchSettings.json ├── Program.cs └── TestConsoleApp.csproj ├── sharp_generator ├── Properties │ └── launchSettings.json ├── SharpGenerator.csproj ├── SconsRunner.cs ├── Documentation.cs └── GDapi.cs ├── TemplateProjectNetFramework ├── App.config ├── Program.cs ├── DemoSpinningCubeNode.cs ├── Properties │ └── AssemblyInfo.cs ├── GodotApplication.cs ├── GodotApplication.sln └── GodotApplication.csproj ├── .github ├── actions │ ├── godot-cache │ │ ├── 04975d9d18c517136ad0a27ca872b16c-uncropped_scaled_within_1536_1152.webp │ │ ├── 04975d9d18c517136ad0a27ca872b16c-uncropped_scaled_within_1536_1152.afphoto │ │ └── action.yml │ ├── upload-artifact │ │ └── action.yml │ ├── godot-deps │ │ └── action.yml │ └── godot-build │ │ └── action.yml └── workflows │ ├── linux_builds.yml │ ├── windows_builds.yml │ ├── macos_builds.yml │ ├── android_builds.yml │ └── nuget_publish.yml ├── LibGodotSharpAndroid ├── Transforms │ ├── Metadata.xml │ ├── EnumMethods.xml │ └── EnumFields.xml ├── build.bat ├── Additions │ └── AboutAdditions.txt └── LibGodotSharpAndroid.csproj ├── TestLibGodotSharp ├── TestLibGodotSharp.csproj ├── ZNode.cs ├── HelloFromLibGodot.cs ├── ANode.cs └── MainGodotGame.cs ├── LICENSE ├── README.md ├── LibGodotSharpDesktop ├── LibGodotSharp.Desktop.targets └── LibGodotSharpDesktop.csproj ├── LibGodotSharp.sln └── .gitignore /Assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/Assets/icon.png -------------------------------------------------------------------------------- /Assets/icon_no_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/Assets/icon_no_back.png -------------------------------------------------------------------------------- /libgodotsharp/Notification.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public enum Notification 4 | { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /TemplateProject/Platforms/Desktop/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Desktop/icon.ico -------------------------------------------------------------------------------- /TemplateProject/Platforms/Desktop/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Desktop/icon.png -------------------------------------------------------------------------------- /TestAndroid/Resources/drawable-nodpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TestAndroid/Resources/drawable-nodpi/splash.png -------------------------------------------------------------------------------- /libgodotsharp/Extensions/RefCounted.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public partial class RefCounted { 4 | 5 | ~RefCounted() { 6 | Unreference(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /TestAndroid/Resources/drawable-nodpi/splash_bg_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TestAndroid/Resources/drawable-nodpi/splash_bg_color.png -------------------------------------------------------------------------------- /TestConsoleApp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "TestConsoleApp": { 4 | "commandName": "Project", 5 | "nativeDebugging": true 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-hdpi/appicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-hdpi/appicon.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-mdpi/appicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-mdpi/appicon.png -------------------------------------------------------------------------------- /sharp_generator/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "SharpGenerator": { 4 | "commandName": "Project", 5 | "nativeDebugging": true 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-xhdpi/appicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-xhdpi/appicon.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-xxhdpi/appicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-xxhdpi/appicon.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-xxxhdpi/appicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-xxxhdpi/appicon.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | godot-csharp-application 4 | 5 | -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/drawable-nodpi/splash_sceen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/drawable-nodpi/splash_sceen.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-hdpi/appicon_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-hdpi/appicon_background.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-hdpi/appicon_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-hdpi/appicon_foreground.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-mdpi/appicon_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-mdpi/appicon_background.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-mdpi/appicon_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-mdpi/appicon_foreground.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-xhdpi/appicon_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-xhdpi/appicon_background.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-xhdpi/appicon_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-xhdpi/appicon_foreground.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-xxhdpi/appicon_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-xxhdpi/appicon_background.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-xxhdpi/appicon_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-xxhdpi/appicon_foreground.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-xxxhdpi/appicon_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-xxxhdpi/appicon_background.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-xxxhdpi/appicon_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/mipmap-xxxhdpi/appicon_foreground.png -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/drawable-nodpi/splash_sceen_bg_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/TemplateProject/Platforms/Android/Resources/drawable-nodpi/splash_sceen_bg_color.png -------------------------------------------------------------------------------- /TemplateProject/README.md: -------------------------------------------------------------------------------- 1 | ## Notes 2 | - Make sure to change the android build id so there is no collision with other people's projects 3 | - When updating update both the GodotApplication project and the platform projects 4 | -------------------------------------------------------------------------------- /TemplateProjectNetFramework/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /libgodotsharp/Attributes/NotificationAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = false)] 4 | public class NotificationAttribute : System.Attribute 5 | { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /.github/actions/godot-cache/04975d9d18c517136ad0a27ca872b16c-uncropped_scaled_within_1536_1152.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/.github/actions/godot-cache/04975d9d18c517136ad0a27ca872b16c-uncropped_scaled_within_1536_1152.webp -------------------------------------------------------------------------------- /.github/actions/godot-cache/04975d9d18c517136ad0a27ca872b16c-uncropped_scaled_within_1536_1152.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RhubarbVR/LibGodotSharp/HEAD/.github/actions/godot-cache/04975d9d18c517136ad0a27ca872b16c-uncropped_scaled_within_1536_1152.afphoto -------------------------------------------------------------------------------- /libgodotsharp/Attributes/MethodAttribute .cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = false)] 4 | public class MethodAttribute : System.Attribute 5 | { 6 | 7 | public MethodAttribute() { } 8 | } 9 | -------------------------------------------------------------------------------- /libgodotsharp/Attributes/SignalAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | [System.AttributeUsage(System.AttributeTargets.Delegate, AllowMultiple = false)] 4 | public class SignalAttribute : System.Attribute 5 | { 6 | 7 | public SignalAttribute() { } 8 | } 9 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-ar/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-ar 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-bg/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-bg 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-ca/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-ca 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-cs/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-cs 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-da/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-da 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-de/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-de 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-el/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-el 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-en/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-en 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-es/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-es 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-fa/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-fa 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-fi/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-fi 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-fr/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-fr 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-hi/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-hi 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-hr/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-hr 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-hu/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-hu 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-in/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-in 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-it/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-it 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-iw/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-iw 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-ja/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-ja 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-ko/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-ko 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-lt/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-lt 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-lv/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-lv 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-nb/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-nb 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-nl/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-nl 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-pl/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-pl 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-pt/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-pt 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-ro/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-ro 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-ru/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-ru 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-sk/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-sk 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-sl/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-sl 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-sr/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-sr 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-sv/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-sv 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-th/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-th 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-tl/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-tl 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-tr/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-tr 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-uk/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-uk 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-vi/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-vi 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-zh/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-zh 5 | 6 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/ArrayMesh.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public unsafe partial class ArrayMesh 4 | { 5 | public T SurfaceGetMaterial(long surf_idx = 0) where T: Material 6 | { 7 | return (T)SurfaceGetMaterial(surf_idx); 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-es-rES/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-es_ES 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-zh-rHK/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-zh_HK 5 | 6 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values-zh-rTW/godot_project_name_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | godot-project-name-zh_TW 5 | 6 | -------------------------------------------------------------------------------- /libgodotsharp/Attributes/ExportAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | [System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple = false)] 4 | public class ExportAttribute : System.Attribute 5 | { 6 | 7 | public ExportAttribute() { } 8 | } 9 | -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-anydpi-v26/appicon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/mipmap-anydpi-v26/appicon_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /sharp_generator/SharpGenerator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | 11 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /libgodotsharp/GDExtensionMain.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace GDExtension 5 | { 6 | public unsafe static class GDExtensionMain 7 | { 8 | public static Native.GDExtensionInterface extensionInterface; 9 | public static void* library; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /libgodotsharp/Attributes/RegisterAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | [System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple = false)] 4 | public class RegisterAttribute : System.Attribute 5 | { 6 | public string name; 7 | //string? icon; 8 | public bool editorOnly; 9 | 10 | public RegisterAttribute() { } 11 | } 12 | -------------------------------------------------------------------------------- /LibGodotSharpAndroid/Transforms/Metadata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/Transform2D.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public unsafe partial struct Transform2D { 4 | 5 | public Transform2D( 6 | double xAxisX, double xAxisY, 7 | double yAxisX, double yAxisY, 8 | double originX, double originY 9 | ) : this( 10 | new Vector2(xAxisX, xAxisY), 11 | new Vector2(yAxisX, yAxisY), 12 | new Vector2(originX, originY) 13 | ) { } 14 | } 15 | -------------------------------------------------------------------------------- /TestAndroid/Resources/drawable/splash_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /libgodotsharp/Attributes/NotifyAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = false)] 4 | public class NotifyAttribute : System.Attribute 5 | { 6 | public int notification; 7 | public string arguments; 8 | 9 | public NotifyAttribute(Notification notification) 10 | { 11 | this.notification = (int)notification; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /TestConsoleApp/Program.cs: -------------------------------------------------------------------------------- 1 | using GodotGame; 2 | using LibGodotSharp; 3 | 4 | namespace TestConsoleApp 5 | { 6 | internal class Program 7 | { 8 | static unsafe int Main(string[] args) 9 | { 10 | return LibGodotManager.RunGodot(Array.Empty(), TestLibGodotSharpExtensionEntry.EntryPoint, MainGodotGame.LoadScene, MainGodotGame.LoadProjectSettings, true); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/drawable/main_splash_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/Basisc.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public unsafe partial struct Basis { 4 | 5 | public Basis( 6 | double xAxisX, double xAxisY, double xAxisZ, 7 | double yAxisX, double yAxisY, double yAxisZ, 8 | double zAxisX, double zAxisY, double zAxisZ 9 | ) : this( 10 | new Vector3(xAxisX, xAxisY, xAxisZ), 11 | new Vector3(yAxisX, yAxisY, yAxisZ), 12 | new Vector3(zAxisX, zAxisY, zAxisZ) 13 | ) { } 14 | } 15 | -------------------------------------------------------------------------------- /TestAndroid/Resources/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /TemplateProjectNetFramework/Program.cs: -------------------------------------------------------------------------------- 1 | 2 | using LibGodotSharp; 3 | 4 | internal class Program 5 | { 6 | static unsafe int Main(string[] args) 7 | { 8 | var runVerbose = false; 9 | #if DEBUG 10 | runVerbose = true; 11 | #endif 12 | //Passes arguments down to godot 13 | return LibGodotManager.RunGodot(args, GodotApplicationExtensionEntry.EntryPoint, GodotApplication.LoadScene, GodotApplication.LoadProjectSettings, runVerbose); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/Resources/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/Node.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public unsafe partial class Node : Object 4 | { 5 | 6 | public T GetNode(NodePath path) where T : Node => (T)GetNode(path); 7 | 8 | public T AddChild(bool force_readable_name = (bool)false, Node.InternalMode @internal = (Node.InternalMode)0) where T : Node ,new() 9 | { 10 | var node = new T(); 11 | AddChild(node, force_readable_name, @internal); 12 | return node; 13 | } 14 | 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /TemplateProject/GodotApplication/GodotApplication.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | True 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /TemplateProject/Platforms/Desktop/Program.cs: -------------------------------------------------------------------------------- 1 | using LibGodotSharp; 2 | 3 | namespace DesktopPlatform; 4 | 5 | internal class Program 6 | { 7 | static unsafe int Main(string[] args) 8 | { 9 | var runVerbose = false; 10 | #if DEBUG 11 | runVerbose = true; 12 | #endif 13 | //Passes arguments down to godot 14 | return LibGodotManager.RunGodot(args, GodotApplicationExtensionEntry.EntryPoint, GodotApplication.LoadScene, GodotApplication.LoadProjectSettings, runVerbose); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/Transform3D.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public unsafe partial struct Transform3D { 4 | 5 | public Transform3D( 6 | double xAxisX, double xAxisY, double xAxisZ, 7 | double yAxisX, double yAxisY, double yAxisZ, 8 | double zAxisX, double zAxisY, double zAxisZ, 9 | double originX, double originY, double originZ 10 | ) : this( 11 | new Vector3(xAxisX, xAxisY, xAxisZ), 12 | new Vector3(yAxisX, yAxisY, yAxisZ), 13 | new Vector3(zAxisX, zAxisY, zAxisZ), 14 | new Vector3(originX, originY, originZ) 15 | ) { } 16 | } 17 | -------------------------------------------------------------------------------- /TestLibGodotSharp/TestLibGodotSharp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | True 8 | true 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.github/actions/upload-artifact/action.yml: -------------------------------------------------------------------------------- 1 | name: Upload Godot artifact 2 | description: Upload the Godot artifact. 3 | inputs: 4 | name: 5 | description: The artifact name. 6 | default: "${{ github.job }}" 7 | path: 8 | description: The path to upload. 9 | required: true 10 | default: "godot/bin/*" 11 | runs: 12 | using: "composite" 13 | steps: 14 | - name: Upload Godot Artifact 15 | uses: actions/upload-artifact@v3 16 | with: 17 | name: ${{ inputs.name }} 18 | path: ${{ inputs.path }} 19 | retention-days: 14 20 | -------------------------------------------------------------------------------- /LibGodotSharpAndroid/Transforms/EnumMethods.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | -------------------------------------------------------------------------------- /LibGodotSharpAndroid/build.bat: -------------------------------------------------------------------------------- 1 | cd ./../../godot-lib/ 2 | rem scons platform=android library_type=shared_library debug_symbols=yes optimize=debug target=template_debug arch=x86_64 3 | rem scons platform=android library_type=shared_library debug_symbols=yes optimize=debug target=template_debug arch=x86 4 | scons platform=android library_type=shared_library debug_symbols=yes optimize=debug target=template_debug arch=armv7 5 | scons platform=android library_type=shared_library debug_symbols=yes optimize=debug target=template_debug arch=arm64v8 6 | cd ./platform/android/java 7 | ./gradlew assemble 8 | -------------------------------------------------------------------------------- /TestConsoleApp/TestConsoleApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | True 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /TestLibGodotSharp/ZNode.cs: -------------------------------------------------------------------------------- 1 | using GDExtension; 2 | 3 | namespace GodotGame; 4 | 5 | [Register] 6 | public partial class ZNode : Node3D 7 | { 8 | [Notify(NotificationReady)] 9 | public void Ready() 10 | { 11 | SetProcess(true); 12 | var meshRender = new MeshInstance3D 13 | { 14 | Mesh = new BoxMesh() 15 | }; 16 | AddChild(meshRender); 17 | } 18 | 19 | [Notify(NotificationProcess, arguments = "GetProcessDeltaTime()")] 20 | public void Process(double delta) 21 | { 22 | RotateY(delta); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/NodePath.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public unsafe partial class NodePath { 4 | 5 | public static implicit operator NodePath(string text) => new NodePath(text); 6 | 7 | public static implicit operator string(NodePath from) { 8 | var constructor = GDExtensionMain.extensionInterface.variant_get_ptr_constructor((Native.GDExtensionVariantType)Variant.Type.String, 3); 9 | var args = stackalloc void*[1]; 10 | args[0] = from._internal_pointer; 11 | void* res; 12 | constructor(&res, args); 13 | return StringMarshall.ToManaged(res); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/Object.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public unsafe partial class Object : Wrapped { 4 | public static Object ConstructUnknown(void* ptr) { 5 | if (ptr == null) { return null!; } 6 | var o = new Object(ptr); 7 | var c = o.GetClass(); 8 | return constructors[c](ptr); 9 | } 10 | 11 | public delegate Object Constructor(void* data); 12 | public static void RegisterConstructor(string name, Constructor constructor) => constructors.Add(name, constructor); 13 | 14 | static System.Collections.Generic.Dictionary constructors = new(); 15 | } 16 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/StringName.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public unsafe partial class StringName { 4 | 5 | public static implicit operator StringName(string text) => new StringName(text); 6 | 7 | public static implicit operator string(StringName from) { 8 | var constructor = GDExtensionMain.extensionInterface.variant_get_ptr_constructor((Native.GDExtensionVariantType)Variant.Type.String, 2); 9 | var args = stackalloc void*[1]; 10 | args[0] = from._internal_pointer; 11 | void* res; 12 | constructor(&res, args); 13 | return StringMarshall.ToManaged(&res); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /TestLibGodotSharp/HelloFromLibGodot.cs: -------------------------------------------------------------------------------- 1 | using GDExtension; 2 | 3 | namespace GodotGame; 4 | 5 | [Register] 6 | public partial class HelloFromLibGodot : Node3D 7 | { 8 | [Notify(NotificationReady)] 9 | public void Ready() 10 | { 11 | SetProcess(true); 12 | var meshRender = new MeshInstance3D 13 | { 14 | Mesh = new BoxMesh() 15 | }; 16 | AddChild(meshRender); 17 | } 18 | 19 | [Notify(NotificationProcess, arguments = "GetProcessDeltaTime()")] 20 | public void Process(double delta) 21 | { 22 | RotateY(delta); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/Projection.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public unsafe partial struct Projection { 4 | 5 | public Projection( 6 | double xAxisX, double xAxisY, double xAxisZ, double xAxisW, 7 | double yAxisX, double yAxisY, double yAxisZ, double yAxisW, 8 | double zAxisX, double zAxisY, double zAxisZ, double zAxisW, 9 | double wAxisX, double wAxisY, double wAxisZ, double wAxisW 10 | ) : this( 11 | new Vector4(xAxisX, xAxisY, xAxisZ, xAxisW), 12 | new Vector4(yAxisX, yAxisY, yAxisZ, yAxisW), 13 | new Vector4(zAxisX, zAxisY, zAxisZ, zAxisW), 14 | new Vector4(wAxisX, wAxisY, wAxisZ, wAxisW) 15 | ) { } 16 | } 17 | -------------------------------------------------------------------------------- /libgodotsharp/Wrapped.cs: -------------------------------------------------------------------------------- 1 | using static GDExtension.SaftyRapper; 2 | 3 | namespace GDExtension; 4 | 5 | public unsafe class Wrapped 6 | { 7 | 8 | public void* _internal_pointer; 9 | 10 | protected Wrapped(StringName type) 11 | { 12 | _internal_pointer = GDExtensionMain.extensionInterface.classdb_construct_object(type._internal_pointer); 13 | } 14 | protected Wrapped(void* data) => _internal_pointer = data; 15 | public static unsafe void __Notification(void* instance, int what) { } 16 | public static unsafe void* __RegisterVirtual(void* userData, void* stringData) { return null; } 17 | 18 | public static void Register() { } 19 | } 20 | -------------------------------------------------------------------------------- /LibGodotSharpAndroid/Transforms/EnumFields.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/MathGD.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public static partial class MathGD { 4 | 5 | /// 6 | /// Represents the natural logarithmic base, specified by the constant, e. 7 | /// 8 | public const double E = System.Math.E; 9 | 10 | /// 11 | /// Represents the ratio of the circumference of a circle to its diameter, specified by the constant, π. 12 | /// 13 | public const double Pi = System.Math.PI; 14 | 15 | /// 16 | /// Represents the number of radians in one turn, specified by the constant, τ. 17 | /// 18 | public const double Tau = System.Math.PI * 2; 19 | 20 | /// 21 | /// Represents a value that is not a number (NaN). This field is constant. 22 | /// 23 | public const double NaN = double.NaN; 24 | } 25 | -------------------------------------------------------------------------------- /libgodotsharp/StringMarshall.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GDExtension; 4 | 5 | public unsafe static class StringMarshall 6 | { 7 | 8 | public static void* ToNative(string managed) 9 | { 10 | var x = GDExtensionMain.extensionInterface.mem_alloc(8); 11 | fixed (char* ptr = managed) 12 | { 13 | GDExtensionMain.extensionInterface.string_new_with_utf16_chars(x, (ushort*)ptr); 14 | } 15 | return x; 16 | } 17 | 18 | public static string ToManaged(void* str) 19 | { 20 | var l = (int)GDExtensionMain.extensionInterface.string_to_utf16_chars(str, null, 0); 21 | var span = stackalloc char[l]; 22 | GDExtensionMain.extensionInterface.string_to_utf16_chars(str, (ushort*)span, l); 23 | return new string(span, 0, l); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /libgodotsharp/ResourceHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace GDExtension 4 | { 5 | public static class ResourceHelper 6 | { 7 | public static byte[] GetResourceBytes(string path) 8 | { 9 | var targetAsm = Assembly.GetCallingAssembly(); 10 | using var mem = new MemoryStream(); 11 | targetAsm.GetManifestResourceStream(path).CopyTo(mem); 12 | return mem.ToArray(); 13 | } 14 | 15 | public static string[] GetResourceNames() 16 | { 17 | return Assembly.GetCallingAssembly().GetManifestResourceNames(); 18 | } 19 | 20 | public static ManifestResourceInfo GetResourceInfo(string path) 21 | { 22 | return Assembly.GetCallingAssembly().GetManifestResourceInfo(path); 23 | } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TemplateProject/Platforms/Desktop/DesktopPlatform.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | True 9 | icon.ico 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /.github/actions/godot-cache/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup Godot build cache 2 | description: Setup Godot build cache. 3 | inputs: 4 | cache-name: 5 | description: The cache base name (job name by default). 6 | default: "${{github.job}}" 7 | scons-cache: 8 | description: The scons cache path. 9 | default: "${{github.workspace}}/.scons-cache/" 10 | runs: 11 | using: "composite" 12 | steps: 13 | # Upload cache on completion and check it out now 14 | - name: Load .scons_cache directory 15 | uses: actions/cache@v3 16 | with: 17 | path: ${{inputs.scons-cache}} 18 | key: ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} 19 | restore-keys: | 20 | ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} 21 | ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} 22 | ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}} 23 | -------------------------------------------------------------------------------- /TestLibGodotSharp/ANode.cs: -------------------------------------------------------------------------------- 1 | using GDExtension; 2 | 3 | namespace GodotGame; 4 | 5 | [Register] 6 | public partial class ANode : Node3D 7 | { 8 | [Notify(NotificationReady)] 9 | public void Ready() 10 | { 11 | SetProcess(true); 12 | var meshRender = new MeshInstance3D 13 | { 14 | Mesh = new BoxMesh() 15 | }; 16 | AddChild(meshRender); 17 | } 18 | 19 | [Notify(NotificationProcess, arguments = "GetProcessDeltaTime()")] 20 | public void Process(double delta) 21 | { 22 | RotateY(delta); 23 | } 24 | 25 | public override void _Input(InputEvent @event) 26 | { 27 | if(@event is InputEventKey key) 28 | { 29 | if(key.Keycode == Key.Space) 30 | { 31 | if (key.IsPressed()) 32 | { 33 | Console.WriteLine("SPACE"); 34 | } 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /libgodotsharp/SaftyRapper.cs: -------------------------------------------------------------------------------- 1 | 2 | using System.Reflection.Metadata; 3 | using System.Runtime.CompilerServices; 4 | 5 | namespace GDExtension; 6 | 7 | public static class SaftyRapper 8 | { 9 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 10 | public unsafe static TDelegate GetDelegateForFunctionPointer(void* ptr) where TDelegate : Delegate 11 | { 12 | return Marshal.GetDelegateForFunctionPointer((IntPtr)ptr); 13 | } 14 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 15 | public static TDelegate GetDelegateForFunctionPointer(IntPtr ptr) where TDelegate : Delegate 16 | { 17 | return Marshal.GetDelegateForFunctionPointer(ptr); 18 | } 19 | 20 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 21 | public static IntPtr GetFunctionPointerForDelegate(TDelegate ptr) where TDelegate : Delegate 22 | { 23 | return Marshal.GetFunctionPointerForDelegate(ptr); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TestAndroid/TestAndroid.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net7.0-android 4 | 21 5 | Exe 6 | enable 7 | enable 8 | com.godot.game 9 | 1 10 | 1.0 11 | True 12 | 13 | 14 | Xamarin 15 | 16 | 17 | Xamarin 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /libgodotsharp/Renamer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Generators 5 | { 6 | static class Renamer 7 | { 8 | 9 | public static string ToSnake(string name) 10 | { 11 | var res = ""; 12 | if (name.StartsWith("_")) 13 | { 14 | res += "_"; 15 | name = name.Substring(1); 16 | } 17 | var upper = false; 18 | var last = name[0]; 19 | for (var i = 1; i < name.Length; i++) 20 | { 21 | var current = name[i]; 22 | if (IsUpper(current)) 23 | { 24 | res += char.ToLower(last); 25 | if (upper == false && (i + 1 < name.Length && IsUpper(name[i + 1]) || i + 1 == name.Length)) 26 | { 27 | res += "_"; 28 | } 29 | upper = true; 30 | } 31 | else 32 | { 33 | if (upper) 34 | { 35 | res += "_"; 36 | } 37 | res += char.ToLower(last); 38 | upper = false; 39 | } 40 | last = current; 41 | } 42 | return res + char.ToLower(last); 43 | } 44 | 45 | static bool IsUpper(char c) => char.IsUpper(c) || char.IsDigit(c); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /sharp_generator/SconsRunner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using static SharpGenerator.Program; 9 | 10 | namespace SharpGenerator 11 | { 12 | public static class SconsRunner 13 | { 14 | 15 | public static bool RunScons() 16 | { 17 | var argsPrepend = ""; 18 | var shellName = "/bin/bash"; 19 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) 20 | { 21 | shellName = "cmd"; 22 | argsPrepend = "/c "; 23 | } 24 | var psi = new ProcessStartInfo 25 | { 26 | FileName = shellName, 27 | Arguments = argsPrepend + "scons library_type=shared_library debug_symbols=true", 28 | WorkingDirectory = GodotRootDir 29 | }; 30 | using var process = Process.Start(psi); 31 | Console.WriteLine("Scons Running"); 32 | process.WaitForExit(); 33 | Console.WriteLine("Scons Done"); 34 | return process.ExitCode == 0; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/AndroidPlatform.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net7.0-android 4 | 21 5 | Exe 6 | enable 7 | enable 8 | com.godot.application.changethis 9 | 1 10 | 1.0 11 | True 12 | 13 | 14 | Xamarin 15 | 16 | 17 | Xamarin 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /libgodotsharp/AndroidTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace LibGodotSharp 6 | { 7 | public static class AndroidTest 8 | { 9 | static bool? isAndroid; 10 | public static bool Check() 11 | { 12 | if (isAndroid != null) return (bool)isAndroid; 13 | using var process = new System.Diagnostics.Process(); 14 | process.StartInfo.FileName = "getprop"; 15 | process.StartInfo.Arguments = "ro.build.user"; 16 | process.StartInfo.RedirectStandardOutput = true; 17 | process.StartInfo.UseShellExecute = false; 18 | process.StartInfo.CreateNoWindow = true; 19 | try 20 | { 21 | process.Start(); 22 | var output = process.StandardOutput.ReadToEnd(); 23 | isAndroid = string.IsNullOrEmpty(output) ? (bool?)false : (bool?)true; 24 | } 25 | catch 26 | { 27 | isAndroid = false; 28 | } 29 | return (bool)isAndroid; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Rhubarb VR 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /TemplateProject/GodotApplication/DemoSpinningCubeNode.cs: -------------------------------------------------------------------------------- 1 | using GDExtension; 2 | 3 | namespace Nodes; //Needs namespace for code generator 4 | 5 | /// 6 | /// Demo node to show how to register a node to godot 7 | /// 8 | [Register] // Need register attribute to know what needs to be code generator 9 | public partial class DemoSpinningCubeNode : Node3D // Needs to be a partial class for the code generator to extended it 10 | { 11 | [Notify(NotificationReady)] // Used to put actions on the Godot's notify system 12 | public void Ready() 13 | { 14 | SetProcess(true); // Need to tell godot that this node uses process loop manialy 15 | 16 | //Adds a cube mesh for a test visual 17 | var meshRender = new MeshInstance3D 18 | { 19 | Mesh = new BoxMesh() 20 | }; 21 | AddChild(meshRender); 22 | } 23 | 24 | [Notify(NotificationProcess, arguments = "GetProcessDeltaTime()")] // Can add arguments that just pass code through to the generator 25 | public void Process(double delta) 26 | { 27 | RotateY(delta); // rotate the cube to show that the process can be used 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 15 | 16 | 25 | 26 | 27 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /TemplateProjectNetFramework/DemoSpinningCubeNode.cs: -------------------------------------------------------------------------------- 1 | using GDExtension; 2 | 3 | namespace Nodes 4 | { //Needs namespace for code generator 5 | 6 | /// 7 | /// Demo node to show how to register a node to godot 8 | /// 9 | [Register] // Need register attribute to know what needs to be code generator 10 | public partial class DemoSpinningCubeNode : Node3D // Needs to be a partial class for the code generator to extended it 11 | { 12 | [Notify(NotificationReady)] // Used to put actions on the Godot's notify system 13 | public void Ready() 14 | { 15 | SetProcess(true); // Need to tell godot that this node uses process loop manialy 16 | 17 | //Adds a cube mesh for a test visual 18 | var meshRender = new MeshInstance3D 19 | { 20 | Mesh = new BoxMesh() 21 | }; 22 | AddChild(meshRender); 23 | } 24 | 25 | [Notify(NotificationProcess, arguments = "GetProcessDeltaTime()")] // Can add arguments that just pass code through to the generator 26 | public void Process(double delta) 27 | { 28 | RotateY(delta); // rotate the cube to show that the process can be used 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /TestAndroid/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 18 | 19 | 28 | 29 | 30 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## This has been deprecated for the new system in this [pull request](https://github.com/godotengine/godot/pull/72883). 2 | New system in setup to use Godot Existing C# system but still be able to run godot as a shared library still and pass though your existing Godot C# 3 | 4 | 5 | 6 |
7 |

8 | 9 | LibGodotSharp-Logo 10 | 11 | 12 |

LibGodotSharp

13 | 14 |

15 | Made by the RhubarbVR Team 16 |

17 |

18 | 19 | 20 | ## About The Project 21 | LibGodotSharps's core is built on the versatile Net Standard 2, which allows for seamless integration with either the Net Framework or Net Core/.Net, accommodating the preferences of all users. 22 | 23 | ## Used by 24 | [RhubarbVR](https://github.com/RhubarbVR/RhubarbVR) 25 | 26 | ## Preview 27 | ![image](https://user-images.githubusercontent.com/46481567/218472227-820c0188-87f7-43be-8125-dc82c6f0c907.png) 28 | 29 | ## Usage 30 | To begin using LibGodotSharp, simply copy the template folder and take note that if you're using Android, the package ID should be changed. Once you've completed these steps, you're ready to start utilizing Godot as a library! 31 | 32 | ## Todo 33 | - Web Support 34 | -------------------------------------------------------------------------------- /TestAndroid/GodotApp.cs: -------------------------------------------------------------------------------- 1 | using GodotGame; 2 | using LibGodotSharp; 3 | using Org.Godotengine.Godot; 4 | 5 | [Activity( 6 | Name = "com.godot.game.GodotApp" , 7 | Label = "@string/godot_project_name_string", 8 | Theme = "@style/GodotAppSplashTheme", 9 | LaunchMode = Android.Content.PM.LaunchMode.SingleTask, 10 | ExcludeFromRecents = false, 11 | Exported = true, 12 | ScreenOrientation = Android.Content.PM.ScreenOrientation.Landscape, 13 | ConfigurationChanges = Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.KeyboardHidden | Android.Content.PM.ConfigChanges.ScreenSize | Android.Content.PM.ConfigChanges.Density | Android.Content.PM.ConfigChanges.Keyboard | Android.Content.PM.ConfigChanges.Navigation | Android.Content.PM.ConfigChanges.ScreenLayout | Android.Content.PM.ConfigChanges.UiMode, 14 | ResizeableActivity = false, 15 | MainLauncher = true)] 16 | public class GodotApp : FullScreenGodotApp 17 | { 18 | public unsafe override void OnCreate(Bundle? savedInstanceState) 19 | { 20 | Java.Lang.JavaSystem.LoadLibrary("godot_android"); 21 | LibGodotManager.RunGodot(Array.Empty(), TestLibGodotSharpExtensionEntry.EntryPoint, MainGodotGame.LoadScene, MainGodotGame.LoadProjectSettings, true); 22 | SetTheme(TestAndroid.Resource.Style.GodotAppMainTheme); 23 | base.OnCreate(savedInstanceState); 24 | } 25 | } -------------------------------------------------------------------------------- /.github/actions/godot-deps/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup python and scons 2 | description: Setup python, install the pip version of scons. 3 | inputs: 4 | python-version: 5 | description: The python version to use. 6 | default: "3.x" 7 | python-arch: 8 | description: The python architecture. 9 | default: "x64" 10 | runs: 11 | using: "composite" 12 | steps: 13 | # Use python 3.x release (works cross platform) 14 | - name: Set up Python 3.x 15 | uses: actions/setup-python@v4 16 | with: 17 | # Semantic version range syntax or exact version of a Python version 18 | python-version: ${{ inputs.python-version }} 19 | # Optional - x64 or x86 architecture, defaults to x64 20 | architecture: ${{ inputs.python-arch }} 21 | 22 | - name: Setup scons 23 | shell: bash 24 | run: | 25 | python -c "import sys; print(sys.version)" 26 | python -m pip install scons 27 | scons --version 28 | 29 | - name: Install latest nightly 30 | uses: actions-rs/toolchain@v1 31 | with: 32 | toolchain: nightly 33 | override: true 34 | target: x86_64-pc-windows-gnu 35 | components: rustfmt, clippy 36 | 37 | - name: Checkout godot engine repo 38 | uses: actions/checkout@v3 39 | with: 40 | repository: RhubarbVR/godot-lib 41 | path: godot 42 | ref: master 43 | -------------------------------------------------------------------------------- /LibGodotSharpDesktop/LibGodotSharp.Desktop.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 18 | 19 | 24 | 25 | -------------------------------------------------------------------------------- /TemplateProject/Platforms/Android/GodotApp.cs: -------------------------------------------------------------------------------- 1 | using LibGodotSharp; 2 | using Org.Godotengine.Godot; 3 | 4 | [Activity( 5 | Label = "@string/app_name", 6 | Theme = "@style/LibGodotAppSplashTheme", 7 | LaunchMode = Android.Content.PM.LaunchMode.SingleTask, 8 | ExcludeFromRecents = false, 9 | Exported = true, 10 | ScreenOrientation = Android.Content.PM.ScreenOrientation.Landscape, 11 | ConfigurationChanges = Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.KeyboardHidden | Android.Content.PM.ConfigChanges.ScreenSize | Android.Content.PM.ConfigChanges.Density | Android.Content.PM.ConfigChanges.Keyboard | Android.Content.PM.ConfigChanges.Navigation | Android.Content.PM.ConfigChanges.ScreenLayout | Android.Content.PM.ConfigChanges.UiMode, 12 | ResizeableActivity = false, 13 | MainLauncher = true)] 14 | public class GodotApp : FullScreenGodotApp 15 | { 16 | public unsafe override void OnCreate(Bundle? savedInstanceState) 17 | { 18 | Java.Lang.JavaSystem.LoadLibrary("godot_android"); 19 | 20 | var runVerbose = false; 21 | #if DEBUG 22 | runVerbose = true; 23 | #endif 24 | //Arguments do nothing on android 25 | LibGodotManager.RunGodot(Array.Empty(), GodotApplicationExtensionEntry.EntryPoint, GodotApplication.LoadScene, GodotApplication.LoadProjectSettings, runVerbose); 26 | 27 | SetTheme(AndroidPlatform.Resource.Style.LibGodotAppMainTheme); 28 | base.OnCreate(savedInstanceState); 29 | } 30 | } -------------------------------------------------------------------------------- /libgodotsharp/Extensions/Callable.cs: -------------------------------------------------------------------------------- 1 | using LibGodotSharp; 2 | using System; 3 | using System.Reflection.Metadata; 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | using System.Xml.Linq; 7 | 8 | namespace GDExtension; 9 | 10 | public unsafe partial class Callable 11 | { 12 | protected Callable(Delegate @delegate,Object @object) 13 | { 14 | if (@delegate is null) 15 | { 16 | throw new NullReferenceException(); 17 | } 18 | _delegate = @delegate; 19 | _object = @object; 20 | gCHandle = GCHandle.Alloc(this); 21 | _internal_pointer = LibGodotCustomCallable.Libgodot_create_callable((void*)(IntPtr)gCHandle); 22 | } 23 | internal readonly GCHandle gCHandle; 24 | internal Delegate _delegate; 25 | internal Object _object; 26 | 27 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 28 | public static Callable From(T target, Object @object = null) where T : Delegate 29 | { 30 | if(target is null) 31 | { 32 | throw new NullReferenceException(); 33 | } 34 | if(target.Target is Object delobject) 35 | { 36 | @object = delobject; 37 | } 38 | if(@object is null) 39 | { 40 | throw new NullReferenceException(); 41 | } 42 | return new Callable(target, @object); 43 | } 44 | 45 | internal void Free() 46 | { 47 | gCHandle.Free(); 48 | _delegate = null; 49 | _object = null; 50 | } 51 | } -------------------------------------------------------------------------------- /TemplateProjectNetFramework/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("GodotApplication")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("GodotApplication")] 13 | [assembly: AssemblyCopyright("Copyright © 2023")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("adc18b6b-13fe-410f-a056-e1bb0a9d4d1a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/PackedStringArray.cs: -------------------------------------------------------------------------------- 1 | namespace GDExtension; 2 | 3 | public unsafe partial class PackedStringArray 4 | { 5 | 6 | public string this[int index] 7 | { 8 | get => this[(long)index]; 9 | set => this[(long)index] = value; 10 | } 11 | 12 | public string this[long index] 13 | { 14 | get 15 | { 16 | return StringMarshall.ToManaged(GDExtensionMain.extensionInterface.packed_string_array_operator_index(_internal_pointer, index)); 17 | } 18 | set 19 | { 20 | Set(index, value); 21 | } 22 | } 23 | 24 | public static implicit operator PackedStringArray(List self) 25 | { 26 | var data = new PackedStringArray(); 27 | data.Resize(self.Count); 28 | for (int i = 0; i < self.Count; i++) 29 | { 30 | data[i] = self[i]; 31 | } 32 | return data; 33 | } 34 | 35 | public static implicit operator PackedStringArray(string[] self) 36 | { 37 | var data = new PackedStringArray(); 38 | data.Resize(self.Length); 39 | for (int i = 0; i < self.Length; i++) 40 | { 41 | data[i] = self[i]; 42 | } 43 | return data; 44 | } 45 | 46 | public static implicit operator PackedStringArray(Span self) 47 | { 48 | var data = new PackedStringArray(); 49 | data.Resize(self.Length); 50 | for (int i = 0; i < self.Length; i++) 51 | { 52 | data[i] = self[i]; 53 | } 54 | return data; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/PackedInt32Array.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | namespace GDExtension; 4 | 5 | public unsafe partial class PackedInt32Array 6 | { 7 | 8 | public int this[int index] 9 | { 10 | get => this[(long)index]; 11 | set => this[(long)index] = value; 12 | } 13 | 14 | public int this[long index] 15 | { 16 | get 17 | { 18 | return Unsafe.Read(GDExtensionMain.extensionInterface.packed_int32_array_operator_index(_internal_pointer, index)); 19 | } 20 | set 21 | { 22 | Set(index, value); 23 | } 24 | } 25 | 26 | public static implicit operator PackedInt32Array(List self) 27 | { 28 | var data = new PackedInt32Array(); 29 | data.Resize(self.Count); 30 | for (int i = 0; i < self.Count; i++) 31 | { 32 | data[i] = self[i]; 33 | } 34 | return data; 35 | } 36 | 37 | public static implicit operator PackedInt32Array(int[] self) 38 | { 39 | var data = new PackedInt32Array(); 40 | data.Resize(self.Length); 41 | for (int i = 0; i < self.Length; i++) 42 | { 43 | data[i] = self[i]; 44 | } 45 | return data; 46 | } 47 | 48 | public static implicit operator PackedInt32Array(Span self) 49 | { 50 | var data = new PackedInt32Array(); 51 | data.Resize(self.Length); 52 | for (int i = 0; i < self.Length; i++) 53 | { 54 | data[i] = self[i]; 55 | } 56 | return data; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/PackedInt64Array.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | namespace GDExtension; 4 | 5 | public unsafe partial class PackedInt64Array 6 | { 7 | 8 | public long this[int index] 9 | { 10 | get => this[(long)index]; 11 | set => this[(long)index] = value; 12 | } 13 | 14 | public long this[long index] 15 | { 16 | get 17 | { 18 | return Unsafe.Read(GDExtensionMain.extensionInterface.packed_int64_array_operator_index(_internal_pointer, index)); 19 | } 20 | set 21 | { 22 | Set(index, value); 23 | } 24 | } 25 | 26 | public static implicit operator PackedInt64Array(List self) 27 | { 28 | var data = new PackedInt64Array(); 29 | data.Resize(self.Count); 30 | for (int i = 0; i < self.Count; i++) 31 | { 32 | data[i] = self[i]; 33 | } 34 | return data; 35 | } 36 | 37 | public static implicit operator PackedInt64Array(long[] self) 38 | { 39 | var data = new PackedInt64Array(); 40 | data.Resize(self.Length); 41 | for (int i = 0; i < self.Length; i++) 42 | { 43 | data[i] = self[i]; 44 | } 45 | return data; 46 | } 47 | 48 | public static implicit operator PackedInt64Array(Span self) 49 | { 50 | var data = new PackedInt64Array(); 51 | data.Resize(self.Length); 52 | for (int i = 0; i < self.Length; i++) 53 | { 54 | data[i] = self[i]; 55 | } 56 | return data; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/PackedColorArray.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | namespace GDExtension; 4 | 5 | public unsafe partial class PackedColorArray 6 | { 7 | 8 | public Color this[int index] 9 | { 10 | get => this[(long)index]; 11 | set => this[(long)index] = value; 12 | } 13 | 14 | public Color this[long index] 15 | { 16 | get 17 | { 18 | return Unsafe.Read(GDExtensionMain.extensionInterface.packed_color_array_operator_index(_internal_pointer, index)); 19 | } 20 | set 21 | { 22 | Set(index, value); 23 | } 24 | } 25 | 26 | public static implicit operator PackedColorArray(List self) 27 | { 28 | var data = new PackedColorArray(); 29 | data.Resize(self.Count); 30 | for (int i = 0; i < self.Count; i++) 31 | { 32 | data[i] = self[i]; 33 | } 34 | return data; 35 | } 36 | 37 | public static implicit operator PackedColorArray(Color[] self) 38 | { 39 | var data = new PackedColorArray(); 40 | data.Resize(self.Length); 41 | for (int i = 0; i < self.Length; i++) 42 | { 43 | data[i] = self[i]; 44 | } 45 | return data; 46 | } 47 | 48 | public static implicit operator PackedColorArray(Span self) 49 | { 50 | var data = new PackedColorArray(); 51 | data.Resize(self.Length); 52 | for (int i = 0; i < self.Length; i++) 53 | { 54 | data[i] = self[i]; 55 | } 56 | return data; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/PackedFloat32Array.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | namespace GDExtension; 4 | 5 | public unsafe partial class PackedFloat32Array 6 | { 7 | 8 | public float this[int index] 9 | { 10 | get => this[(long)index]; 11 | set => this[(long)index] = value; 12 | } 13 | 14 | public float this[long index] 15 | { 16 | get 17 | { 18 | return Unsafe.Read(GDExtensionMain.extensionInterface.packed_float32_array_operator_index(_internal_pointer, index)); 19 | } 20 | set 21 | { 22 | Set(index, value); 23 | } 24 | } 25 | 26 | public static implicit operator PackedFloat32Array(List self) 27 | { 28 | var data = new PackedFloat32Array(); 29 | data.Resize(self.Count); 30 | for (int i = 0; i < self.Count; i++) 31 | { 32 | data[i] = self[i]; 33 | } 34 | return data; 35 | } 36 | 37 | public static implicit operator PackedFloat32Array(float[] self) 38 | { 39 | var data = new PackedFloat32Array(); 40 | data.Resize(self.Length); 41 | for (int i = 0; i < self.Length; i++) 42 | { 43 | data[i] = self[i]; 44 | } 45 | return data; 46 | } 47 | 48 | public static implicit operator PackedFloat32Array(Span self) 49 | { 50 | var data = new PackedFloat32Array(); 51 | data.Resize(self.Length); 52 | for (int i = 0; i < self.Length; i++) 53 | { 54 | data[i] = self[i]; 55 | } 56 | return data; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/PackedFloat64Array.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | namespace GDExtension; 4 | 5 | public unsafe partial class PackedFloat64Array 6 | { 7 | 8 | public double this[int index] 9 | { 10 | get => this[(long)index]; 11 | set => this[(long)index] = value; 12 | } 13 | 14 | public double this[long index] 15 | { 16 | get 17 | { 18 | return Unsafe.Read(GDExtensionMain.extensionInterface.packed_float64_array_operator_index(_internal_pointer, index)); 19 | } 20 | set 21 | { 22 | Set(index, value); 23 | } 24 | } 25 | 26 | public static implicit operator PackedFloat64Array(List self) 27 | { 28 | var data = new PackedFloat64Array(); 29 | data.Resize(self.Count); 30 | for (int i = 0; i < self.Count; i++) 31 | { 32 | data[i] = self[i]; 33 | } 34 | return data; 35 | } 36 | 37 | public static implicit operator PackedFloat64Array(double[] self) 38 | { 39 | var data = new PackedFloat64Array(); 40 | data.Resize(self.Length); 41 | for (int i = 0; i < self.Length; i++) 42 | { 43 | data[i] = self[i]; 44 | } 45 | return data; 46 | } 47 | 48 | public static implicit operator PackedFloat64Array(Span self) 49 | { 50 | var data = new PackedFloat64Array(); 51 | data.Resize(self.Length); 52 | for (int i = 0; i < self.Length; i++) 53 | { 54 | data[i] = self[i]; 55 | } 56 | return data; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/PackedVector2Array.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | namespace GDExtension; 4 | 5 | public unsafe partial class PackedVector2Array 6 | { 7 | 8 | public Vector2 this[int index] 9 | { 10 | get => this[(long)index]; 11 | set => this[(long)index] = value; 12 | } 13 | 14 | public Vector2 this[long index] 15 | { 16 | get 17 | { 18 | return Unsafe.Read(GDExtensionMain.extensionInterface.packed_vector2_array_operator_index(_internal_pointer, index)); 19 | } 20 | set 21 | { 22 | Set(index, value); 23 | } 24 | } 25 | 26 | public static implicit operator PackedVector2Array(List self) 27 | { 28 | var data = new PackedVector2Array(); 29 | data.Resize(self.Count); 30 | for (int i = 0; i < self.Count; i++) 31 | { 32 | data[i] = self[i]; 33 | } 34 | return data; 35 | } 36 | 37 | public static implicit operator PackedVector2Array(Vector2[] self) 38 | { 39 | var data = new PackedVector2Array(); 40 | data.Resize(self.Length); 41 | for (int i = 0; i < self.Length; i++) 42 | { 43 | data[i] = self[i]; 44 | } 45 | return data; 46 | } 47 | 48 | public static implicit operator PackedVector2Array(Span self) 49 | { 50 | var data = new PackedVector2Array(); 51 | data.Resize(self.Length); 52 | for (int i = 0; i < self.Length; i++) 53 | { 54 | data[i] = self[i]; 55 | } 56 | return data; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/PackedVector3Array.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | namespace GDExtension; 4 | 5 | public unsafe partial class PackedVector3Array 6 | { 7 | 8 | public Vector3 this[int index] 9 | { 10 | get => this[(long)index]; 11 | set => this[(long)index] = value; 12 | } 13 | 14 | public Vector3 this[long index] 15 | { 16 | get 17 | { 18 | return Unsafe.Read(GDExtensionMain.extensionInterface.packed_vector3_array_operator_index(_internal_pointer, index)); 19 | } 20 | set 21 | { 22 | Set(index, value); 23 | } 24 | } 25 | 26 | public static implicit operator PackedVector3Array(List self) 27 | { 28 | var data = new PackedVector3Array(); 29 | data.Resize(self.Count); 30 | for (int i = 0; i < self.Count; i++) 31 | { 32 | data[i] = self[i]; 33 | } 34 | return data; 35 | } 36 | 37 | public static implicit operator PackedVector3Array(Vector3[] self) 38 | { 39 | var data = new PackedVector3Array(); 40 | data.Resize(self.Length); 41 | for (int i = 0; i < self.Length; i++) 42 | { 43 | data[i] = self[i]; 44 | } 45 | return data; 46 | } 47 | 48 | public static implicit operator PackedVector3Array(Span self) 49 | { 50 | var data = new PackedVector3Array(); 51 | data.Resize(self.Length); 52 | for (int i = 0; i < self.Length; i++) 53 | { 54 | data[i] = self[i]; 55 | } 56 | return data; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /LibGodotSharpAndroid/Additions/AboutAdditions.txt: -------------------------------------------------------------------------------- 1 | Additions allow you to add arbitrary C# to the generated classes 2 | before they are compiled. This can be helpful for providing convenience 3 | methods or adding pure C# classes. 4 | 5 | == Adding Methods to Generated Classes == 6 | 7 | Let's say the library being bound has a Rectangle class with a constructor 8 | that takes an x and y position, and a width and length size. It will look like 9 | this: 10 | 11 | public partial class Rectangle 12 | { 13 | public Rectangle (int x, int y, int width, int height) 14 | { 15 | // JNI bindings 16 | } 17 | } 18 | 19 | Imagine we want to add a constructor to this class that takes a Point and 20 | Size structure instead of 4 ints. We can add a new file called Rectangle.cs 21 | with a partial class containing our new method: 22 | 23 | public partial class Rectangle 24 | { 25 | public Rectangle (Point location, Size size) : 26 | this (location.X, location.Y, size.Width, size.Height) 27 | { 28 | } 29 | } 30 | 31 | At compile time, the additions class will be added to the generated class 32 | and the final assembly will a Rectangle class with both constructors. 33 | 34 | 35 | == Adding C# Classes == 36 | 37 | Another thing that can be done is adding fully C# managed classes to the 38 | generated library. In the above example, let's assume that there isn't a 39 | Point class available in Java or our library. The one we create doesn't need 40 | to interact with Java, so we'll create it like a normal class in C#. 41 | 42 | By adding a Point.cs file with this class, it will end up in the binding library: 43 | 44 | public class Point 45 | { 46 | public int X { get; set; } 47 | public int Y { get; set; } 48 | } -------------------------------------------------------------------------------- /LibGodotSharpDesktop/LibGodotSharpDesktop.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | icon.png 6 | https://github.com/RhubarbVR/LibGodotSharp 7 | LibGodotSharp.Desktop 8 | True 9 | This is all files for windows, macos and linux for LibGodotSharp 10 | RhubarbVR 11 | Faolan 12 | latest 13 | $(BUILD_VERSION) 14 | $(BUILD_VERSION) 15 | MIT 16 | LibGodotSharp.Desktop 17 | OpenXR C# AR VR MR XR MixedReality HoloLens Rendering 3D Vulkan OpenGL Audio UI 18 | true 19 | LibGodotSharp.Desktop 20 | README.md 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | True 29 | \ 30 | 31 | 32 | True 33 | \ 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /LibGodotSharpAndroid/LibGodotSharpAndroid.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net7.0-android;net6.0-android 4 | 1 5 | enable 6 | enable 7 | icon.png 8 | https://github.com/RhubarbVR/LibGodotSharp 9 | LibGodotSharp.Android 10 | True 11 | This is the android native files for LibGodotSharp 12 | RhubarbVR 13 | Faolan 14 | latest 15 | $(BUILD_VERSION) 16 | $(BUILD_VERSION) 17 | MIT 18 | LibGodotSharp.Android 19 | LibGodotSharp.Android 20 | OpenXR C# AR VR MR XR MixedReality HoloLens Rendering 3D Vulkan OpenGL Audio UI Android 21 | true 22 | README.md 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | True 31 | \ 32 | 33 | 34 | True 35 | \ 36 | 37 | 38 | -------------------------------------------------------------------------------- /.github/actions/godot-build/action.yml: -------------------------------------------------------------------------------- 1 | name: Build Godot 2 | description: Build Godot with the provided options. 3 | inputs: 4 | target: 5 | description: Build target (editor, template_release, template_debug). 6 | default: "editor" 7 | tests: 8 | description: Unit tests. 9 | default: false 10 | platform: 11 | description: Target platform. 12 | required: false 13 | sconsflags: 14 | default: "" 15 | scons-cache: 16 | description: The scons cache path. 17 | default: "${{ github.workspace }}/.scons-cache/" 18 | scons-cache-limit: 19 | description: The scons cache size limit. 20 | # actions/cache has 10 GiB limit, and GitHub runners have a 14 GiB disk. 21 | # Limit to 7 GiB to avoid having the extracted cache fill the disk. 22 | default: 7168 23 | runs: 24 | using: "composite" 25 | steps: 26 | - name: Scons Build 27 | shell: sh 28 | env: 29 | SCONSFLAGS: ${{ inputs.sconsflags }} 30 | SCONS_CACHE: ${{ inputs.scons-cache }} 31 | SCONS_CACHE_LIMIT: ${{ inputs.scons-cache-limit }} 32 | run: | 33 | cd godot 34 | echo "Building with flags:" platform=${{ inputs.platform }} target=${{ inputs.target }} tests=${{ inputs.tests }} ${{ env.SCONSFLAGS }} 35 | if [ "${{ inputs.target }}" != "editor" ]; then rm -rf editor; fi # Ensure we don't include editor code. 36 | export PATH="$PWD/../llvm-mingw/bin:$PATH" 37 | scons platform=${{ inputs.platform }} target=${{ inputs.target }} tests=${{ inputs.tests }} ${{ env.SCONSFLAGS }} 38 | ls -l bin/ 39 | 40 | # - name: Generate GUT tests 41 | # if: ${{ matrix.tests }} 42 | # shell: sh 43 | # run: | 44 | # godot/${{ matrix.bin }} --headless --path . -s res://addons/gut/gut_cmdln.gd --xr-mode off 45 | 46 | # - name: Publish Test Report 47 | # uses: mikepenz/action-junit-report@v3 48 | # if: ${{ matrix.tests }} 49 | # with: 50 | # report_paths: '**/vsk_default/test/results/TEST_*.xml' 51 | -------------------------------------------------------------------------------- /TemplateProjectNetFramework/GodotApplication.cs: -------------------------------------------------------------------------------- 1 | using GDExtension; 2 | 3 | using Nodes; 4 | 5 | /// 6 | /// Main class that platform used to load godot scene after godot is initialized 7 | /// - can only be renamed or put in a namespace if you also do it on each platform project 8 | /// 9 | public static class GodotApplication 10 | { 11 | /// 12 | /// Creates new demo cube at location 13 | /// 14 | /// location to put spinning cube 15 | /// 16 | public static DemoSpinningCubeNode AddDemoNode(Vector3 pos) 17 | { 18 | var demoNode = new DemoSpinningCubeNode 19 | { 20 | Position = pos 21 | }; 22 | return demoNode; 23 | } 24 | 25 | /// 26 | /// Starting point to change project settings 27 | /// 28 | /// 29 | public static void LoadProjectSettings(ProjectSettings projectSettings) 30 | { 31 | ProjectSettings.SetSetting("application/config/name", "GodotApplication"); 32 | } 33 | 34 | /// 35 | /// Main entry point for starting and using godot as a library 36 | /// 37 | /// 38 | public static void LoadScene(SceneTree scene) 39 | { 40 | //Build root node to store the 3d scene on 41 | var rootNode = new Node3D(); 42 | 43 | //Add camera to see the spinning demo cubes 44 | var camera = new Camera3D 45 | { 46 | Current = true, 47 | Position = new Vector3(0, 0, 2) 48 | }; 49 | rootNode.AddChild(camera); 50 | 51 | //Attach 3 demo cubes where the camera can see them 52 | rootNode.AddChild(AddDemoNode(new Vector3(1, 1, 1))); 53 | rootNode.AddChild(AddDemoNode(new Vector3(-1, -1, -1))); 54 | rootNode.AddChild(AddDemoNode(new Vector3(0, 1, 1))); 55 | 56 | //Finally we need to add root node to the main window for rendering 57 | scene.Root.AddChild(rootNode); 58 | } 59 | } -------------------------------------------------------------------------------- /TemplateProject/GodotApplication/GodotApplication.cs: -------------------------------------------------------------------------------- 1 | using GDExtension; 2 | 3 | using Nodes; 4 | 5 | /// 6 | /// Main class that platform used to load godot scene after godot is initialized 7 | /// - can only be renamed or put in a namespace if you also do it on each platform project 8 | /// 9 | public static class GodotApplication 10 | { 11 | /// 12 | /// Creates new demo cube at location 13 | /// 14 | /// location to put spinning cube 15 | /// 16 | public static DemoSpinningCubeNode AddDemoNode(Vector3 pos) 17 | { 18 | var demoNode = new DemoSpinningCubeNode 19 | { 20 | Position = pos 21 | }; 22 | return demoNode; 23 | } 24 | 25 | /// 26 | /// Starting point to change project settings 27 | /// 28 | /// 29 | public static void LoadProjectSettings(ProjectSettings projectSettings) 30 | { 31 | ProjectSettings.SetSetting("application/config/name", "GodotApplication"); 32 | } 33 | 34 | /// 35 | /// Main entry point for starting and using godot as a library 36 | /// 37 | /// 38 | public static void LoadScene(SceneTree scene) 39 | { 40 | //Build root node to store the 3d scene on 41 | var rootNode = new Node3D(); 42 | 43 | //Add camera to see the spinning demo cubes 44 | var camera = new Camera3D 45 | { 46 | Current = true, 47 | Position = new Vector3(0, 0, 2) 48 | }; 49 | rootNode.AddChild(camera); 50 | 51 | //Attach 3 demo cubes where the camera can see them 52 | rootNode.AddChild(AddDemoNode(new Vector3(1, 1, 1))); 53 | rootNode.AddChild(AddDemoNode(new Vector3(-1, -1, -1))); 54 | rootNode.AddChild(AddDemoNode(new Vector3(0, 1, 1))); 55 | 56 | //Finally we need to add root node to the main window for rendering 57 | scene.Root.AddChild(rootNode); 58 | } 59 | } -------------------------------------------------------------------------------- /libgodotsharp/LibGodotSharp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | enable 6 | True 7 | 11 8 | icon.png 9 | https://github.com/RhubarbVR/LibGodotSharp 10 | LibGodotSharp 11 | True 12 | This is Godot as a .net library 13 | RhubarbVR 14 | Faolan 15 | latest 16 | $(BUILD_VERSION) 17 | $(BUILD_VERSION) 18 | MIT 19 | LibGodotSharp 20 | OpenXR C# AR VR MR XR MixedReality HoloLens Rendering 3D Vulkan OpenGL Audio UI Net Standard 21 | true 22 | README.md 23 | 24 | 25 | 26 | 27 | all 28 | runtime; build; native; contentfiles; analyzers; buildtransitive 29 | 30 | 31 | 32 | 33 | 34 | 35 | True 36 | \ 37 | 38 | 39 | True 40 | \ 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /.github/workflows/linux_builds.yml: -------------------------------------------------------------------------------- 1 | name: 🐧 Linux 2 | on: [push, pull_request] 3 | 4 | # Global Settings 5 | env: 6 | # Only used for the cache key. Increment version to force clean build. 7 | GODOT_BASE_BRANCH: master 8 | SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes 9 | DOTNET_NOLOGO: true 10 | DOTNET_CLI_TELEMETRY_OPTOUT: true 11 | 12 | concurrency: 13 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-linux 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | build-linux: 18 | runs-on: "ubuntu-20.04" 19 | name: ${{ matrix.name }} 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | include: 24 | - name: Linux Libgodot X64 25 | cache-name: linux-template-release64 26 | target: template_release 27 | sconsflags: library_type=shared_library arch=x86_64 28 | bin: "godot/bin/*" 29 | arch32: false 30 | artifact: true 31 | platform: linuxbsd 32 | 33 | steps: 34 | - uses: actions/checkout@v3 35 | 36 | - name: Linux dependencies for gold linker 37 | run: | 38 | sudo apt-get install -qq binutils 39 | 40 | - name: Setup Godot build cache 41 | uses: ./.github/actions/godot-cache 42 | with: 43 | cache-name: ${{ matrix.cache-name }} 44 | continue-on-error: true 45 | 46 | - name: Setup python and scons 47 | uses: ./.github/actions/godot-deps 48 | 49 | - name: Setup GCC problem matcher 50 | uses: ammaraskar/gcc-problem-matcher@master 51 | 52 | - name: Compilation 53 | uses: ./.github/actions/godot-build 54 | with: 55 | sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }} 56 | platform: ${{ matrix.platform }} 57 | target: ${{ matrix.target }} 58 | tests: false 59 | 60 | - name: Upload artifact 61 | uses: ./.github/actions/upload-artifact 62 | if: ${{ matrix.artifact }} 63 | with: 64 | name: ${{ matrix.cache-name }} 65 | path: ${{ matrix.bin }} -------------------------------------------------------------------------------- /.github/workflows/windows_builds.yml: -------------------------------------------------------------------------------- 1 | name: 🏁 Windows Builds 2 | on: [push, pull_request] 3 | 4 | # Global Settings 5 | env: 6 | # Only used for the cache key. Increment version to force clean build. 7 | GODOT_BASE_BRANCH: master 8 | SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes 9 | DOTNET_NOLOGO: true 10 | DOTNET_CLI_TELEMETRY_OPTOUT: true 11 | 12 | concurrency: 13 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-windows 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | build-windows: 18 | runs-on: "windows-latest" 19 | name: ${{ matrix.name }} 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | include: 24 | - name: Windows Libgodot X64 25 | cache-name: windows-template-release64 26 | target: template_release 27 | sconsflags: library_type=shared_library arch=x86_64 28 | bin: "godot/bin/*" 29 | artifact: true 30 | platform: windows 31 | 32 | - name: Windows Libgodot X86 33 | cache-name: windows-template-release86 34 | target: template_release 35 | sconsflags: library_type=shared_library arch=x86 36 | bin: "godot/bin/*" 37 | artifact: true 38 | platform: windows 39 | 40 | steps: 41 | - uses: actions/checkout@v3 42 | 43 | - name: Setup Godot build cache 44 | uses: ./.github/actions/godot-cache 45 | with: 46 | cache-name: ${{ matrix.cache-name }} 47 | continue-on-error: true 48 | 49 | - name: Setup python and scons 50 | uses: ./.github/actions/godot-deps 51 | 52 | - name: Setup MSVC problem matcher 53 | uses: ammaraskar/msvc-problem-matcher@master 54 | 55 | - name: Compilation 56 | uses: ./.github/actions/godot-build 57 | with: 58 | sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }} 59 | platform: ${{ matrix.platform }} 60 | target: ${{ matrix.target }} 61 | tests: false 62 | 63 | - name: Upload artifact 64 | uses: ./.github/actions/upload-artifact 65 | if: ${{ matrix.artifact }} 66 | with: 67 | name: ${{ matrix.cache-name }} 68 | path: ${{ matrix.bin }} 69 | -------------------------------------------------------------------------------- /libgodotsharp/GenNotification.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using Microsoft.CodeAnalysis; 5 | using Microsoft.CodeAnalysis.CSharp.Syntax; 6 | 7 | namespace Generators 8 | { 9 | 10 | public static class Notification 11 | { 12 | 13 | public static bool Generate(GeneratorExecutionContext context, INamedTypeSymbol c) 14 | { 15 | var methods = c.GetMembers().Where(x => x is IMethodSymbol).Select(x => (IMethodSymbol)x); 16 | 17 | var code = $$""" 18 | using System.Runtime.CompilerServices; 19 | using System.Runtime.InteropServices; 20 | using GDExtension; 21 | namespace {{c.ContainingNamespace}} { 22 | public unsafe partial class {{c.Name}} : {{c.BaseType.Name}} { 23 | """; 24 | 25 | var notificationName = ""; 26 | foreach (var method in methods) 27 | { 28 | var notificationAttribute = method.GetAttributes().SingleOrDefault(x => x.AttributeClass.ToString() == "GDExtension.NotificationAttribute"); 29 | if (notificationAttribute != null) 30 | { 31 | notificationName = method.Name; 32 | } 33 | } 34 | if (notificationName == "") 35 | { 36 | notificationName = "_Notification"; 37 | var has = false; 38 | code += $$""" 39 | void {{notificationName}}(int what) { 40 | switch (what) { 41 | """; 42 | foreach (var method in methods) 43 | { 44 | var att = method.GetAttributes().SingleOrDefault(x => x.AttributeClass.ToString() == "GDExtension.NotifyAttribute"); 45 | 46 | 47 | if (att != null) 48 | { 49 | has = true; 50 | var args = att.NamedArguments.SingleOrDefault(x => x.Key == "arguments").Value.Value ?? ""; 51 | 52 | code += $$""" 53 | case {{att.ConstructorArguments[0].Value}}: 54 | {{method.Name}}({{args}}); 55 | break; 56 | """; 57 | } 58 | } 59 | if (has == false) 60 | { 61 | return false; 62 | } 63 | code += $$""" 64 | } 65 | } 66 | """; 67 | } 68 | code += $$""" 69 | public static unsafe new void __Notification(void* instance, int what) { 70 | var inst = ({{c.Name}})instance; 71 | {{c.BaseType.Name}}.__Notification(instance, what); 72 | inst.{{notificationName}}(what); 73 | } 74 | } 75 | } 76 | """; 77 | 78 | context.AddSource($"{c.Name}.notification.gen.cs", code); 79 | return true; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/Array.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Reflection; 4 | 5 | namespace GDExtension; 6 | 7 | public unsafe partial class Array : IList, ICollection 8 | { 9 | 10 | public object this[int index] 11 | { 12 | get => this[(long)index]; 13 | set 14 | { 15 | this[(long)index] = value; 16 | } 17 | } 18 | 19 | public object this[long index] 20 | { 21 | get 22 | { 23 | return Variant.VariantToObject(new Variant(GDExtensionMain.extensionInterface.array_operator_index(_internal_pointer, index))); 24 | } 25 | set 26 | { 27 | var varentData = Variant.ObjectToVariant(value); 28 | if (varentData is null) { return; } 29 | Variant.SaveIntoPointer(varentData, GDExtensionMain.extensionInterface.array_operator_index(_internal_pointer, index)); 30 | } 31 | } 32 | 33 | public bool IsFixedSize => false; 34 | 35 | public bool IsSynchronized => false; 36 | 37 | public object SyncRoot => this; 38 | 39 | bool IList.IsReadOnly => false; 40 | 41 | int ICollection.Count => (int)Size(); 42 | 43 | public long Length => Size(); 44 | 45 | public int Add(object value) 46 | { 47 | Append(Variant.ObjectToVariant(value)); 48 | return (int)Size() - 1; 49 | } 50 | 51 | public bool Contains(object value) 52 | { 53 | return Has(Variant.ObjectToVariant(value)); 54 | } 55 | 56 | public void CopyTo(System.Array array, int index) 57 | { 58 | var amount = System.Math.Max(Length - index, array.Length); 59 | for (int i = 0; i < amount; i++) 60 | { 61 | array.SetValue(this[i + index], i); 62 | } 63 | } 64 | 65 | public IEnumerator GetEnumerator() 66 | { 67 | for (int i = 0; i < Length; i++) 68 | { 69 | yield return this[i]; 70 | } 71 | } 72 | 73 | public int IndexOf(object value) 74 | { 75 | return (int)Find(Variant.ObjectToVariant(value)); 76 | } 77 | 78 | public void Insert(int index, object value) 79 | { 80 | Insert((long)index, Variant.ObjectToVariant(value)); 81 | } 82 | 83 | public void Remove(object value) 84 | { 85 | Erase(Variant.ObjectToVariant(value)); 86 | } 87 | 88 | public void RemoveAt(int index) 89 | { 90 | RemoveAt((long)index); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/PackedByteArray.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace GDExtension; 5 | 6 | public unsafe partial class PackedByteArray 7 | { 8 | 9 | public byte this[int index] 10 | { 11 | get => this[(long)index]; 12 | set => this[(long)index] = value; 13 | } 14 | 15 | public byte this[long index] 16 | { 17 | get 18 | { 19 | return Unsafe.Read(GDExtensionMain.extensionInterface.packed_byte_array_operator_index(_internal_pointer, index)); 20 | } 21 | set 22 | { 23 | Set(index, value); 24 | } 25 | } 26 | 27 | public static implicit operator PackedByteArray(List self) 28 | { 29 | var data = new PackedByteArray(); 30 | data.Resize(self.Count); 31 | for (int i = 0; i < self.Count; i++) 32 | { 33 | data[i] = self[i]; 34 | } 35 | return data; 36 | } 37 | 38 | public static implicit operator PackedByteArray(byte[] self) 39 | { 40 | var data = new PackedByteArray(); 41 | data.Resize(self.Length); 42 | for (int i = 0; i < self.Length; i++) 43 | { 44 | data[i] = self[i]; 45 | } 46 | return data; 47 | } 48 | 49 | public static implicit operator PackedByteArray(Span self) 50 | { 51 | var data = new PackedByteArray(); 52 | data.Resize(self.Length); 53 | for (int i = 0; i < self.Length; i++) 54 | { 55 | data[i] = self[i]; 56 | } 57 | return data; 58 | } 59 | 60 | public static implicit operator List(PackedByteArray self) 61 | { 62 | var data = new List((int)self.Size()); 63 | for (int i = 0; i < data.Count; i++) 64 | { 65 | data[i] = self[i]; 66 | } 67 | return data; 68 | } 69 | 70 | public static implicit operator byte[](PackedByteArray self) 71 | { 72 | var data = new byte[self.Size()]; 73 | for (int i = 0; i < self.Size(); i++) 74 | { 75 | data[i] = self[i]; 76 | } 77 | return data; 78 | } 79 | 80 | public static implicit operator Span(PackedByteArray self) 81 | { 82 | var data = new byte[self.Size()]; 83 | for (int i = 0; i < self.Size(); i++) 84 | { 85 | data[i] = self[i]; 86 | } 87 | return data; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /libgodotsharp/Export.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using Microsoft.CodeAnalysis; 5 | using Microsoft.CodeAnalysis.CSharp.Syntax; 6 | 7 | namespace Generators 8 | { 9 | 10 | public static class Export 11 | { 12 | 13 | record struct Data(string name, string setter, string getter, ITypeSymbol type); 14 | 15 | public static void Generate(GeneratorExecutionContext context, INamedTypeSymbol c, Methods methods) 16 | { 17 | var members = c.GetMembers(). 18 | Where(x => x is IPropertySymbol || x is IFieldSymbol). 19 | Where(x => x.GetAttributes().Where(x => x.AttributeClass.ToString() == "GDExtension.ExportAttribute").Count() > 0). 20 | Select(x => x switch { 21 | IPropertySymbol prop => new Data(prop.Name, prop.SetMethod.Name, prop.GetMethod.Name, prop.Type), 22 | IFieldSymbol field => new Data(field.Name, "set_" + field.Name, "get_" + field.Name, field.Type), 23 | _ => throw new System.NotSupportedException(), 24 | }). 25 | ToArray(); 26 | 27 | var code = $$""" 28 | using System.Runtime.CompilerServices; 29 | using System.Runtime.InteropServices; 30 | using GDExtension; 31 | using static GDExtension.Native; 32 | namespace {{c.ContainingNamespace}} { 33 | public unsafe partial class {{c.Name}} : {{c.BaseType.Name}} { 34 | static unsafe void RegisterExports() { 35 | """; 36 | 37 | for (var i = 0; i < members.Length; i++) 38 | { 39 | var member = members[i]; 40 | 41 | code += $"\t\tvar __{member.name}Info = " + Methods.CreatePropertyInfo(member.type, member.name, 2); 42 | 43 | methods.AddMethod(new Methods.Info() 44 | { 45 | name = member.setter, 46 | arguments = new (ITypeSymbol, string)[] { (member.type, "value") }, 47 | ret = null, 48 | property = member.name, 49 | }); 50 | methods.AddMethod(new Methods.Info() 51 | { 52 | name = member.getter, 53 | arguments = new (ITypeSymbol, string)[] { }, 54 | ret = member.type, 55 | property = member.name, 56 | }); 57 | code += $$""" 58 | GDExtensionMain.extensionInterface.classdb_register_extension_class_property( 59 | GDExtensionMain.library, 60 | __godot_name._internal_pointer, 61 | &__{{member.name}}Info, 62 | new StringName("{{Renamer.ToSnake(member.setter)}}")._internal_pointer, 63 | new StringName("{{Renamer.ToSnake(member.getter)}}")._internal_pointer 64 | ); 65 | """; 66 | } 67 | code += """ 68 | } 69 | }} 70 | """; 71 | context.AddSource($"{c.Name}.export.gen.cs", code); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /.github/workflows/macos_builds.yml: -------------------------------------------------------------------------------- 1 | name: 🍎 macOS and ios Builds 2 | on: [push, pull_request] 3 | 4 | # Global Settings 5 | env: 6 | # Only used for the cache key. Increment version to force clean build. 7 | GODOT_BASE_BRANCH: master 8 | SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes 9 | DOTNET_NOLOGO: true 10 | DOTNET_CLI_TELEMETRY_OPTOUT: true 11 | 12 | concurrency: 13 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-macOS 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | build-macos-ios: 18 | runs-on: "macos-latest" 19 | name: ${{ matrix.name }} 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | include: 24 | - name: Macos X64 25 | cache-name: macos-template-release64 26 | target: template_release 27 | sconsflags: library_type=shared_library arch=x86_64 28 | bin: "godot/bin/*" 29 | artifact: true 30 | platform: macos 31 | 32 | - name: Macos Arm 64 33 | cache-name: macos-template-release-Arm64 34 | target: template_release 35 | sconsflags: library_type=shared_library arch=arm64 36 | bin: "godot/bin/*" 37 | artifact: true 38 | platform: macos 39 | 40 | - name: IOS Arm 64 41 | cache-name: ios-template-release-Arm64 42 | target: template_release 43 | sconsflags: library_type=shared_library arch=arm64 44 | bin: "godot/bin/*" 45 | artifact: true 46 | platform: ios 47 | 48 | steps: 49 | - uses: actions/checkout@v3 50 | 51 | - name: Setup Godot build cache 52 | uses: ./.github/actions/godot-cache 53 | with: 54 | cache-name: ${{ matrix.cache-name }} 55 | continue-on-error: true 56 | 57 | - name: Setup python and scons 58 | uses: ./.github/actions/godot-deps 59 | 60 | - name: Setup Vulkan SDK 61 | run: | 62 | sh godot/misc/scripts/install_vulkan_sdk_macos.sh 63 | 64 | - name: Compilation 65 | uses: ./.github/actions/godot-build 66 | with: 67 | sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }} 68 | platform: ${{ matrix.platform }} 69 | target: ${{ matrix.target }} 70 | tests: false 71 | 72 | - name: Upload artifact 73 | uses: ./.github/actions/upload-artifact 74 | if: ${{ matrix.artifact }} 75 | with: 76 | name: ${{ matrix.cache-name }} 77 | path: ${{ matrix.bin }} 78 | -------------------------------------------------------------------------------- /TemplateProjectNetFramework/GodotApplication.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33403.182 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotApplication", "GodotApplication.csproj", "{ADC18B6B-13FE-410F-A056-E1BB0A9D4D1A}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "REMOVEONBUILD", "REMOVEONBUILD", "{F7A1DD5C-B2BB-40FF-B106-1020AF5B7C6B}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibGodotSharp", "..\libgodotsharp\LibGodotSharp.csproj", "{C54E000A-C104-4888-9008-572BB716A79D}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibGodotSharpDesktop", "..\LibGodotSharpDesktop\LibGodotSharpDesktop.csproj", "{37A6D2F8-CBF7-4998-B375-926A09F20404}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {ADC18B6B-13FE-410F-A056-E1BB0A9D4D1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {ADC18B6B-13FE-410F-A056-E1BB0A9D4D1A}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {ADC18B6B-13FE-410F-A056-E1BB0A9D4D1A}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {ADC18B6B-13FE-410F-A056-E1BB0A9D4D1A}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {C54E000A-C104-4888-9008-572BB716A79D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {C54E000A-C104-4888-9008-572BB716A79D}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {C54E000A-C104-4888-9008-572BB716A79D}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {C54E000A-C104-4888-9008-572BB716A79D}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {37A6D2F8-CBF7-4998-B375-926A09F20404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {37A6D2F8-CBF7-4998-B375-926A09F20404}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {37A6D2F8-CBF7-4998-B375-926A09F20404}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {37A6D2F8-CBF7-4998-B375-926A09F20404}.Release|Any CPU.Build.0 = Release|Any CPU 32 | EndGlobalSection 33 | GlobalSection(SolutionProperties) = preSolution 34 | HideSolutionNode = FALSE 35 | EndGlobalSection 36 | GlobalSection(NestedProjects) = preSolution 37 | {C54E000A-C104-4888-9008-572BB716A79D} = {F7A1DD5C-B2BB-40FF-B106-1020AF5B7C6B} 38 | {37A6D2F8-CBF7-4998-B375-926A09F20404} = {F7A1DD5C-B2BB-40FF-B106-1020AF5B7C6B} 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {55749F2E-4FA8-47F0-B872-41B81E002A16} 42 | EndGlobalSection 43 | EndGlobal 44 | -------------------------------------------------------------------------------- /libgodotsharp/Signal.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using Microsoft.CodeAnalysis; 5 | using Microsoft.CodeAnalysis.CSharp; 6 | using Microsoft.CodeAnalysis.CSharp.Syntax; 7 | 8 | namespace Generators 9 | { 10 | 11 | public static class Signal 12 | { 13 | 14 | public static void Generate(GeneratorExecutionContext context, INamedTypeSymbol c) 15 | { 16 | var events = c.GetMembers(). 17 | Where(x => x is INamedTypeSymbol). 18 | Select(x => (INamedTypeSymbol)x). 19 | Where(x => x.GetAttributes().Where(x => x.AttributeClass.ToString() == "GDExtension.GDExtensionMain.libraryAttribute").Count() > 0) 20 | .ToArray(); 21 | 22 | var code = $$""" 23 | using System.Runtime.CompilerServices; 24 | using System.Runtime.InteropServices; 25 | using GDExtension; 26 | using static GDExtension.Native; 27 | namespace {{c.ContainingNamespace}} { 28 | public unsafe partial class {{c.Name}} : {{c.BaseType.Name}} { 29 | static unsafe void RegisterSignals() { 30 | """; 31 | for (var i = 0; i < events.Length; i++) 32 | { 33 | var ev = events[i]; 34 | var m = ev.DelegateInvokeMethod; 35 | 36 | var infosName = "null"; 37 | if (m.Parameters.Length > 0) 38 | { 39 | infosName = $"infos{ev.Name}"; 40 | code += $"\t\tvar {infosName} = stackalloc GDExtensionPropertyInfo[{m.Parameters.Length}];\n"; 41 | for (var j = 0; j < m.Parameters.Length; j++) 42 | { 43 | var p = m.Parameters[j]; 44 | code += $"\t\tinfos{ev.Name}[{j}] = {Methods.CreatePropertyInfo(p.Type, p.Name, 2)}\n"; 45 | } 46 | } 47 | code += $"\t\tGDExtensionMain.extensionInterface.classdb_register_extension_class_signal(GDExtensionInterface.gdLibrary, __godot_name._internal_pointer, new StringName(\"{Renamer.ToSnake(ev.Name)}\")._internal_pointer, {infosName}, {m.Parameters.Length});\n"; 48 | } 49 | code += $$""" 50 | } 51 | """; 52 | 53 | for (var i = 0; i < events.Length; i++) 54 | { 55 | var ev = events[i]; 56 | var m = ev.DelegateInvokeMethod; 57 | code += $"\tpublic void EmitSignal{ev.Name}("; 58 | for (var j = 0; j < m.Parameters.Length; j++) 59 | { 60 | var p = m.Parameters[j]; 61 | code += $"{p.Type.Name} {p.Name}{(j < m.Parameters.Length - 1 ? ", " : "")}"; 62 | } 63 | code += $") => EmitSignal(\"{Renamer.ToSnake(ev.Name)}\""; 64 | for (var j = 0; j < m.Parameters.Length; j++) 65 | { 66 | var p = m.Parameters[j]; 67 | code += $", {p.Name}"; 68 | } 69 | code += ");\n"; 70 | } 71 | code += $$""" 72 | } 73 | } 74 | """; 75 | context.AddSource($"{c.Name}.Signal.gen.cs", code); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /TemplateProjectNetFramework/GodotApplication.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {ADC18B6B-13FE-410F-A056-E1BB0A9D4D1A} 8 | Exe 9 | GodotApplication 10 | GodotApplication 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | true 26 | false 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 10.0 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /sharp_generator/Documentation.cs: -------------------------------------------------------------------------------- 1 | using System.Xml.Serialization; 2 | namespace SharpGenerator.Documentation; 3 | #nullable enable 4 | #pragma warning disable CS8618 5 | [XmlRootAttribute("class", IsNullable = false)] 6 | public record Class 7 | { 8 | [XmlAttribute] public string name; 9 | [XmlAttribute] public string inherits; 10 | [XmlAttribute] public string version; 11 | public string brief_description; 12 | public string description; 13 | public Link[] tutorials; 14 | public Method[] methods; 15 | public Member[] members; 16 | public Signal[] signals; 17 | public Constant[] constants; 18 | } 19 | 20 | [XmlRootAttribute("class", IsNullable = false)] 21 | public record BuiltinClass 22 | { 23 | [XmlAttribute] public string name; 24 | [XmlAttribute] public string version; 25 | public string brief_description; 26 | public string description; 27 | public Link[] tutorials; 28 | public Constructor[] constructors; 29 | public Method[] methods; 30 | public Member[] members; 31 | public Constant[] constants; 32 | public Operator[] operators; 33 | } 34 | 35 | [XmlType("link")] 36 | public record Link 37 | { 38 | [XmlAttribute] public string title; 39 | [XmlText] public string link; 40 | } 41 | 42 | [XmlType("method")] 43 | public record Method 44 | { 45 | [XmlAttribute] public string name; 46 | [XmlAttribute] public string? qualifiers; 47 | public Return @return; 48 | [XmlElement("param")] public Parameter[]? parameters; 49 | public string description; 50 | } 51 | 52 | [XmlType("return")] 53 | public record Return 54 | { 55 | [XmlAttribute] public string type; 56 | } 57 | 58 | [XmlType("param")] 59 | public record Parameter 60 | { 61 | [XmlAttribute] public int index; 62 | [XmlAttribute] public string name; 63 | [XmlAttribute] public string type; 64 | } 65 | 66 | [XmlType("constant")] 67 | public record Constant 68 | { 69 | [XmlAttribute] public string name; 70 | [XmlAttribute] public string value; 71 | [XmlAttribute] public string? @enum; 72 | [XmlText] public string? comment; 73 | } 74 | 75 | [XmlType("member")] 76 | public record Member 77 | { 78 | [XmlAttribute] public string name; 79 | [XmlAttribute] public string type; 80 | [XmlAttribute] public string setter; 81 | [XmlAttribute] public string getter; 82 | [XmlAttribute] public string? @enum; 83 | [XmlAttribute] public string? @default; 84 | [XmlText] public string comment; 85 | } 86 | 87 | [XmlType("signal")] 88 | public record Signal 89 | { 90 | [XmlAttribute] public string name; 91 | [XmlArray("param")] public Parameter[] parameters; 92 | public string description; 93 | } 94 | 95 | [XmlType("constructor")] 96 | public record Constructor 97 | { 98 | [XmlAttribute] public string name; 99 | public Return @return; 100 | [XmlElement("param")] public Parameter[]? parameters; 101 | public string description; 102 | } 103 | 104 | [XmlType("operator")] 105 | public record Operator 106 | { 107 | [XmlAttribute] public string name; 108 | public Return @return; 109 | [XmlArray("param")] public Parameter[] parameters; 110 | public string description; 111 | } 112 | #pragma warning restore CS8618 113 | -------------------------------------------------------------------------------- /.github/workflows/android_builds.yml: -------------------------------------------------------------------------------- 1 | name: 🤖 Android Builds 2 | on: [push, pull_request] 3 | 4 | # Global Settings 5 | env: 6 | # Only used for the cache key. Increment version to force clean build. 7 | GODOT_BASE_BRANCH: master 8 | SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes 9 | DOTNET_NOLOGO: true 10 | DOTNET_CLI_TELEMETRY_OPTOUT: true 11 | 12 | concurrency: 13 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-android 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | build-android: 18 | runs-on: "ubuntu-20.04" 19 | name: ${{ matrix.name }} 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | include: 24 | - name: Android Build 25 | cache-name: android-template-release 26 | bin: "godot/platform/android/java/lib/build/outputs/aar/*" 27 | artifact: true 28 | 29 | steps: 30 | - uses: actions/checkout@v3 31 | 32 | - name: Set up Java 11 33 | uses: actions/setup-java@v3 34 | with: 35 | distribution: temurin 36 | java-version: 11 37 | 38 | - name: Linux dependencies for gold linker 39 | run: | 40 | sudo apt-get install -qq binutils 41 | 42 | - name: Setup Godot build cache 43 | uses: ./.github/actions/godot-cache 44 | with: 45 | cache-name: ${{ matrix.cache-name }} 46 | continue-on-error: true 47 | 48 | - name: Setup python and scons 49 | uses: ./.github/actions/godot-deps 50 | 51 | - name: Setup GCC problem matcher 52 | uses: ammaraskar/gcc-problem-matcher@master 53 | 54 | - name: Compilation (arm32) 55 | uses: ./.github/actions/godot-build 56 | with: 57 | sconsflags: ${{ env.SCONSFLAGS }} arch=arm32 library_type=shared_library 58 | platform: android 59 | target: template_release 60 | tests: false 61 | 62 | - name: Compilation (arm64) 63 | uses: ./.github/actions/godot-build 64 | with: 65 | sconsflags: ${{ env.SCONSFLAGS }} arch=arm64 library_type=shared_library 66 | platform: android 67 | target: template_release 68 | tests: false 69 | 70 | - name: Compilation (x86) 71 | uses: ./.github/actions/godot-build 72 | with: 73 | sconsflags: ${{ env.SCONSFLAGS }} arch=x86 library_type=shared_library 74 | platform: android 75 | target: template_release 76 | tests: false 77 | 78 | - name: Compilation (x64) 79 | uses: ./.github/actions/godot-build 80 | with: 81 | sconsflags: ${{ env.SCONSFLAGS }} arch=x86_64 library_type=shared_library 82 | platform: android 83 | target: template_release 84 | tests: false 85 | 86 | - name: Generate Godot templates 87 | run: | 88 | cd godot/platform/android/java 89 | ./gradlew assemble 90 | cd ../../.. 91 | ls -l bin/ 92 | 93 | - name: Upload artifact 94 | uses: ./.github/actions/upload-artifact 95 | if: ${{ matrix.artifact }} 96 | with: 97 | name: ${{ matrix.cache-name }} 98 | path: ${{ matrix.bin }} -------------------------------------------------------------------------------- /libgodotsharp/Generator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using Microsoft.CodeAnalysis; 6 | using Microsoft.CodeAnalysis.CSharp.Syntax; 7 | 8 | namespace Generators 9 | { 10 | [Generator] 11 | public class LibGodotGenerators : ISourceGenerator 12 | { 13 | 14 | public void Execute(GeneratorExecutionContext context) 15 | { 16 | #if DEBUG 17 | //if (!Debugger.IsAttached) 18 | //{ 19 | // Debugger.Launch(); 20 | //} 21 | #endif 22 | Debug.WriteLine("Execute code generator"); 23 | try 24 | { 25 | var rec = (SyntaxReciever)context.SyntaxReceiver!; 26 | var classes = new List(); 27 | foreach (var cSyntax in rec.names) 28 | { 29 | Debug.WriteLine($"Load class {cSyntax}"); 30 | var c = (INamedTypeSymbol)context.Compilation.GetSemanticModel(cSyntax.SyntaxTree).GetDeclaredSymbol(cSyntax); 31 | var methods = new Methods(); 32 | var sBase = GetSpecialBase(c); 33 | var notification = Notification.Generate(context, c); 34 | var virtualgen = GenVirtual.Generate(context, c); 35 | Export.Generate(context, c, methods); 36 | Signal.Generate(context, c); 37 | methods.Generate(context, c); 38 | var data = Register.Generate(context, c, notification, virtualgen, sBase); 39 | classes.Add(data); 40 | Debug.WriteLine($"Added class {cSyntax}"); 41 | } 42 | Debug.WriteLine($"Building Entry class"); 43 | Entry.Execute(context, classes); 44 | } 45 | catch (System.Exception e) 46 | { 47 | context.ReportDiagnostic(Diagnostic.Create(new DiagnosticDescriptor( 48 | "godot", 49 | "godotError", 50 | e.Message, 51 | "location", 52 | DiagnosticSeverity.Error, 53 | true 54 | ), null)); 55 | } 56 | } 57 | 58 | public void Initialize(GeneratorInitializationContext context) 59 | { 60 | context.RegisterForSyntaxNotifications(() => new SyntaxReciever()); 61 | } 62 | 63 | public static SpecialBase GetSpecialBase(ITypeSymbol type) 64 | { 65 | return type.Name switch 66 | { 67 | "Node" => SpecialBase.Node, 68 | "Resource" => SpecialBase.Resource, 69 | "RefCounted" => SpecialBase.RefCounted, 70 | _ => type.BaseType switch 71 | { 72 | null => SpecialBase.None, 73 | _ => GetSpecialBase(type.BaseType), 74 | }, 75 | }; 76 | } 77 | } 78 | 79 | public enum SpecialBase 80 | { 81 | None, 82 | Node, 83 | Resource, 84 | RefCounted, 85 | } 86 | 87 | class SyntaxReciever : ISyntaxReceiver 88 | { 89 | 90 | public HashSet names; 91 | 92 | public SyntaxReciever() 93 | { 94 | names = new(); 95 | } 96 | 97 | public void OnVisitSyntaxNode(SyntaxNode node) 98 | { 99 | if (node is ClassDeclarationSyntax c) 100 | { 101 | var att = GetAttribute(c, "Register"); 102 | if (att != null) 103 | { 104 | names.Add(c); 105 | } 106 | } 107 | } 108 | 109 | AttributeSyntax GetAttribute(ClassDeclarationSyntax c, string name) 110 | { 111 | return c.AttributeLists.SelectMany(x => x.Attributes).SingleOrDefault(x => x.Name.ToString() == name); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /libgodotsharp/Variant.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Runtime.CompilerServices; 4 | 5 | namespace GDExtension; 6 | 7 | public sealed unsafe partial class Variant 8 | { 9 | 10 | struct Constructor 11 | { 12 | public Native.GDExtensionVariantFromTypeConstructorFunc fromType; 13 | public Native.GDExtensionTypeFromVariantConstructorFunc toType; 14 | } 15 | 16 | static readonly Constructor[] constructors = new Constructor[(int)Type.Max]; 17 | 18 | public static void Register() 19 | { 20 | for (var i = 1; i < (int)Type.Max; i++) 21 | { 22 | constructors[i] = new Constructor() 23 | { 24 | fromType = GDExtensionMain.extensionInterface.get_variant_from_type_constructor((Native.GDExtensionVariantType)i), 25 | toType = GDExtensionMain.extensionInterface.get_variant_to_type_constructor((Native.GDExtensionVariantType)i), 26 | }; 27 | } 28 | } 29 | 30 | public static void SaveIntoPointer(object value, void* ptr) 31 | { 32 | var valCast = ObjectToVariant(value); 33 | if (valCast is null) 34 | { 35 | return; 36 | } 37 | SaveIntoPointer(valCast, ptr); 38 | } 39 | 40 | public static void SaveIntoPointer(Variant value, void* ptr) 41 | { 42 | var srcSpan = new Span(value._internal_pointer, 24); 43 | var dstSpan = new Span(ptr, 24); 44 | srcSpan.CopyTo(dstSpan); 45 | } 46 | 47 | public static void SaveIntoPointer(Object value, void* ptr) 48 | { 49 | var objectPtr = value != null ? value._internal_pointer : null; 50 | constructors[(int)Variant.Type.Object].fromType(ptr, &objectPtr); 51 | } 52 | public static Object GetObjectFromVariant(Variant _object) 53 | { 54 | void* res; 55 | constructors[(int)Type.Object].toType(&res, _object._internal_pointer); 56 | return Object.ConstructUnknown(res); 57 | } 58 | 59 | public static Object GetObjectFromPointer(void* ptr) 60 | { 61 | void* res; 62 | constructors[(int)Type.Object].toType(&res, ptr); 63 | return Object.ConstructUnknown(res); 64 | } 65 | 66 | internal void* _internal_pointer; 67 | 68 | public Type NativeType => (Type)GDExtensionMain.extensionInterface.variant_get_type(_internal_pointer); 69 | 70 | internal Variant() 71 | { 72 | _internal_pointer = GDExtensionMain.extensionInterface.mem_alloc(24); 73 | byte* dataPointer = (byte*)_internal_pointer; 74 | for (int i = 0; i < 24; i++) 75 | { 76 | dataPointer[i] = 0; 77 | } 78 | } 79 | 80 | internal Variant(void* data) 81 | { 82 | _internal_pointer = data; 83 | GC.SuppressFinalize(this); 84 | } 85 | 86 | public static Variant Nil 87 | { 88 | get { var v = new Variant(); GDExtensionMain.extensionInterface.variant_new_nil(v._internal_pointer); return v; } 89 | } 90 | 91 | public Variant(int value) : this((long)value) { } 92 | public Variant(float value) : this((double)value) { } 93 | 94 | ~Variant() 95 | { 96 | GDExtensionMain.extensionInterface.variant_destroy(_internal_pointer); 97 | GDExtensionMain.extensionInterface.mem_free(_internal_pointer); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /libgodotsharp/Entry.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using Microsoft.CodeAnalysis; 5 | 6 | namespace Generators 7 | { 8 | 9 | public static class Entry 10 | { 11 | 12 | public static void Execute(GeneratorExecutionContext context, List classes) 13 | { 14 | var registrations = ""; 15 | var editorRegistrations = ""; 16 | var unregistrations = ""; 17 | 18 | for (var i = 0; i < classes.Count; i++) 19 | { 20 | var n = classes[i]; 21 | switch (n.level) 22 | { 23 | case Register.Level.Scene: 24 | registrations += $"{n.@namespace}.{n.name}.Register();\n\t\t\t"; 25 | break; 26 | case Register.Level.Editor: 27 | editorRegistrations += $"{n.@namespace}.{n.name}.Register();\n\t\t\t"; 28 | break; 29 | } 30 | unregistrations = $"GDExtensionMain.extensionInterface.classdb_unregister_extension_class(GDExtensionMain.library, {n.@namespace}.{n.name}.__godot_name._internal_pointer);\n\t\t\t" + unregistrations; 31 | } 32 | Debug.WriteLine($"Building Entry {registrations}"); 33 | var assimblyName = context.Compilation.AssemblyName ?? "NoName"; 34 | var source = $$""" 35 | using System; 36 | using System.Runtime.CompilerServices; 37 | using System.Runtime.InteropServices; 38 | using GDExtension; 39 | using static GDExtension.Native; 40 | public static class {{assimblyName}}ExtensionEntry { 41 | public static unsafe bool EntryPoint(GDExtensionInterface @interface, void* library, GDExtensionInitialization* init) { 42 | GDExtensionMain.extensionInterface = @interface; 43 | GDExtensionMain.library = library; 44 | *init = new GDExtensionInitialization() { 45 | minimum_initialization_level = GDExtensionInitializationLevel.GDEXTENSION_INITIALIZATION_CORE, 46 | initialize = SaftyRapper.GetFunctionPointerForDelegate(Initialize), 47 | deinitialize = SaftyRapper.GetFunctionPointerForDelegate(Deinitialize), 48 | }; 49 | return true; 50 | } 51 | public static unsafe void Initialize(void* userdata, GDExtensionInitializationLevel level) { 52 | switch (level) { 53 | case GDExtensionInitializationLevel.GDEXTENSION_INITIALIZATION_CORE: 54 | GDExtension.Register.RegisterBuiltin(); 55 | GDExtension.Register.RegisterUtility(); 56 | GDExtension.Register.RegisterCore(); 57 | break; 58 | case GDExtensionInitializationLevel.GDEXTENSION_INITIALIZATION_SERVERS: 59 | GDExtension.Register.RegisterServers(); 60 | break; 61 | case GDExtensionInitializationLevel.GDEXTENSION_INITIALIZATION_SCENE: 62 | GDExtension.Register.RegisterScene(); 63 | {{registrations}}break; 64 | case GDExtensionInitializationLevel.GDEXTENSION_INITIALIZATION_EDITOR: 65 | GDExtension.Register.RegisterEditor(); 66 | {{editorRegistrations}}break; 67 | } 68 | } 69 | public static unsafe void Deinitialize(void* userdata, GDExtensionInitializationLevel level) { 70 | switch (level) { 71 | case GDExtensionInitializationLevel.GDEXTENSION_INITIALIZATION_CORE: 72 | break; 73 | case GDExtensionInitializationLevel.GDEXTENSION_INITIALIZATION_SERVERS: 74 | break; 75 | case GDExtensionInitializationLevel.GDEXTENSION_INITIALIZATION_SCENE: 76 | {{unregistrations}}break; 77 | case GDExtensionInitializationLevel.GDEXTENSION_INITIALIZATION_EDITOR: 78 | break; 79 | } 80 | } 81 | } 82 | 83 | """; 84 | context.AddSource("ExtensionEntry.gen.cs", source); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /LibGodotSharp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33205.214 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpGenerator", "sharp_generator\SharpGenerator.csproj", "{0CDCE5DC-01DC-4B15-A070-DCBCE6477487}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibGodotSharp", "libgodotsharp\LibGodotSharp.csproj", "{3BBAE65F-9139-4C0D-847D-CF36A85B0BE8}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibGodotSharpAndroid", "LibGodotSharpAndroid\LibGodotSharpAndroid.csproj", "{D1D0D531-2954-4409-AB77-A7CD74BED90F}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestAndroid", "TestAndroid\TestAndroid.csproj", "{4905CE14-C5AC-4924-B664-5B82ACAACB2B}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLibGodotSharp", "TestLibGodotSharp\TestLibGodotSharp.csproj", "{55ACC7DA-C874-407C-A608-70D7C765683A}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestConsoleApp", "TestConsoleApp\TestConsoleApp.csproj", "{23664666-0EA9-4AED-8297-AEAE43C02C91}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibGodotSharpDesktop", "LibGodotSharpDesktop\LibGodotSharpDesktop.csproj", "{4DB88310-8E50-43AC-A548-6FAF9D4267E2}" 19 | EndProject 20 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Other", "Other", "{1EBEE447-EDAD-4A2B-AFAA-35F48A08C8E7}" 21 | ProjectSection(SolutionItems) = preProject 22 | README.md = README.md 23 | EndProjectSection 24 | EndProject 25 | Global 26 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 27 | Debug|Any CPU = Debug|Any CPU 28 | Release|Any CPU = Release|Any CPU 29 | EndGlobalSection 30 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 31 | {0CDCE5DC-01DC-4B15-A070-DCBCE6477487}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 32 | {0CDCE5DC-01DC-4B15-A070-DCBCE6477487}.Debug|Any CPU.Build.0 = Debug|Any CPU 33 | {0CDCE5DC-01DC-4B15-A070-DCBCE6477487}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {0CDCE5DC-01DC-4B15-A070-DCBCE6477487}.Release|Any CPU.Build.0 = Release|Any CPU 35 | {3BBAE65F-9139-4C0D-847D-CF36A85B0BE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {3BBAE65F-9139-4C0D-847D-CF36A85B0BE8}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {3BBAE65F-9139-4C0D-847D-CF36A85B0BE8}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {3BBAE65F-9139-4C0D-847D-CF36A85B0BE8}.Release|Any CPU.Build.0 = Release|Any CPU 39 | {D1D0D531-2954-4409-AB77-A7CD74BED90F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {D1D0D531-2954-4409-AB77-A7CD74BED90F}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {D1D0D531-2954-4409-AB77-A7CD74BED90F}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {D1D0D531-2954-4409-AB77-A7CD74BED90F}.Release|Any CPU.Build.0 = Release|Any CPU 43 | {4905CE14-C5AC-4924-B664-5B82ACAACB2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 44 | {4905CE14-C5AC-4924-B664-5B82ACAACB2B}.Debug|Any CPU.Build.0 = Debug|Any CPU 45 | {4905CE14-C5AC-4924-B664-5B82ACAACB2B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 46 | {4905CE14-C5AC-4924-B664-5B82ACAACB2B}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {4905CE14-C5AC-4924-B664-5B82ACAACB2B}.Release|Any CPU.Build.0 = Release|Any CPU 48 | {4905CE14-C5AC-4924-B664-5B82ACAACB2B}.Release|Any CPU.Deploy.0 = Release|Any CPU 49 | {55ACC7DA-C874-407C-A608-70D7C765683A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 50 | {55ACC7DA-C874-407C-A608-70D7C765683A}.Debug|Any CPU.Build.0 = Debug|Any CPU 51 | {55ACC7DA-C874-407C-A608-70D7C765683A}.Release|Any CPU.ActiveCfg = Release|Any CPU 52 | {55ACC7DA-C874-407C-A608-70D7C765683A}.Release|Any CPU.Build.0 = Release|Any CPU 53 | {23664666-0EA9-4AED-8297-AEAE43C02C91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 54 | {23664666-0EA9-4AED-8297-AEAE43C02C91}.Debug|Any CPU.Build.0 = Debug|Any CPU 55 | {23664666-0EA9-4AED-8297-AEAE43C02C91}.Release|Any CPU.ActiveCfg = Release|Any CPU 56 | {23664666-0EA9-4AED-8297-AEAE43C02C91}.Release|Any CPU.Build.0 = Release|Any CPU 57 | {4DB88310-8E50-43AC-A548-6FAF9D4267E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 58 | {4DB88310-8E50-43AC-A548-6FAF9D4267E2}.Debug|Any CPU.Build.0 = Debug|Any CPU 59 | {4DB88310-8E50-43AC-A548-6FAF9D4267E2}.Release|Any CPU.ActiveCfg = Release|Any CPU 60 | {4DB88310-8E50-43AC-A548-6FAF9D4267E2}.Release|Any CPU.Build.0 = Release|Any CPU 61 | EndGlobalSection 62 | GlobalSection(SolutionProperties) = preSolution 63 | HideSolutionNode = FALSE 64 | EndGlobalSection 65 | GlobalSection(ExtensibilityGlobals) = postSolution 66 | SolutionGuid = {F5A32E29-BA17-4929-AB0D-C0C6DECC31A8} 67 | EndGlobalSection 68 | EndGlobal 69 | -------------------------------------------------------------------------------- /TemplateProject/GodotApplication.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33403.182 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AndroidPlatform", "Platforms\Android\AndroidPlatform.csproj", "{7B9F7B6B-7673-40DB-811B-B68B1382105E}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platforms", "Platforms", "{664C5C3A-9AEB-4EE2-B2E5-9660B1AB9837}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DesktopPlatform", "Platforms\Desktop\DesktopPlatform.csproj", "{D149EEF7-5D90-4AF8-914C-904DA3296C6D}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GodotApplication", "GodotApplication\GodotApplication.csproj", "{11BB66D8-BC64-4E4E-B9D9-6AEFF4907715}" 13 | EndProject 14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "REMOVEONBUILD", "REMOVEONBUILD", "{2D13262A-4BF2-45B0-92CF-3203C4F46A95}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibGodotSharp", "..\libgodotsharp\LibGodotSharp.csproj", "{95BE9533-B6BA-415C-B548-B3A2C734196D}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibGodotSharpAndroid", "..\LibGodotSharpAndroid\LibGodotSharpAndroid.csproj", "{7258ECD1-63B8-4691-B055-7DE1DC7F5740}" 19 | EndProject 20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibGodotSharpDesktop", "..\LibGodotSharpDesktop\LibGodotSharpDesktop.csproj", "{8D862275-156A-4379-BE02-8CDFA01DF2CA}" 21 | EndProject 22 | Global 23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 24 | Debug|Any CPU = Debug|Any CPU 25 | Release|Any CPU = Release|Any CPU 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {7B9F7B6B-7673-40DB-811B-B68B1382105E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {7B9F7B6B-7673-40DB-811B-B68B1382105E}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {7B9F7B6B-7673-40DB-811B-B68B1382105E}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 31 | {7B9F7B6B-7673-40DB-811B-B68B1382105E}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {7B9F7B6B-7673-40DB-811B-B68B1382105E}.Release|Any CPU.Build.0 = Release|Any CPU 33 | {7B9F7B6B-7673-40DB-811B-B68B1382105E}.Release|Any CPU.Deploy.0 = Release|Any CPU 34 | {D149EEF7-5D90-4AF8-914C-904DA3296C6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {D149EEF7-5D90-4AF8-914C-904DA3296C6D}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {D149EEF7-5D90-4AF8-914C-904DA3296C6D}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {D149EEF7-5D90-4AF8-914C-904DA3296C6D}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {11BB66D8-BC64-4E4E-B9D9-6AEFF4907715}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {11BB66D8-BC64-4E4E-B9D9-6AEFF4907715}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {11BB66D8-BC64-4E4E-B9D9-6AEFF4907715}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {11BB66D8-BC64-4E4E-B9D9-6AEFF4907715}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {95BE9533-B6BA-415C-B548-B3A2C734196D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {95BE9533-B6BA-415C-B548-B3A2C734196D}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {95BE9533-B6BA-415C-B548-B3A2C734196D}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {95BE9533-B6BA-415C-B548-B3A2C734196D}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {7258ECD1-63B8-4691-B055-7DE1DC7F5740}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {7258ECD1-63B8-4691-B055-7DE1DC7F5740}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {7258ECD1-63B8-4691-B055-7DE1DC7F5740}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {7258ECD1-63B8-4691-B055-7DE1DC7F5740}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {8D862275-156A-4379-BE02-8CDFA01DF2CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {8D862275-156A-4379-BE02-8CDFA01DF2CA}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {8D862275-156A-4379-BE02-8CDFA01DF2CA}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {8D862275-156A-4379-BE02-8CDFA01DF2CA}.Release|Any CPU.Build.0 = Release|Any CPU 54 | EndGlobalSection 55 | GlobalSection(SolutionProperties) = preSolution 56 | HideSolutionNode = FALSE 57 | EndGlobalSection 58 | GlobalSection(NestedProjects) = preSolution 59 | {7B9F7B6B-7673-40DB-811B-B68B1382105E} = {664C5C3A-9AEB-4EE2-B2E5-9660B1AB9837} 60 | {D149EEF7-5D90-4AF8-914C-904DA3296C6D} = {664C5C3A-9AEB-4EE2-B2E5-9660B1AB9837} 61 | {95BE9533-B6BA-415C-B548-B3A2C734196D} = {2D13262A-4BF2-45B0-92CF-3203C4F46A95} 62 | {7258ECD1-63B8-4691-B055-7DE1DC7F5740} = {2D13262A-4BF2-45B0-92CF-3203C4F46A95} 63 | {8D862275-156A-4379-BE02-8CDFA01DF2CA} = {2D13262A-4BF2-45B0-92CF-3203C4F46A95} 64 | EndGlobalSection 65 | GlobalSection(ExtensibilityGlobals) = postSolution 66 | SolutionGuid = {B278F6BC-38EA-4F81-B71A-7A92485BD8BC} 67 | EndGlobalSection 68 | EndGlobal 69 | -------------------------------------------------------------------------------- /libgodotsharp/Register.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using Microsoft.CodeAnalysis; 5 | using Microsoft.CodeAnalysis.CSharp; 6 | using Microsoft.CodeAnalysis.CSharp.Syntax; 7 | 8 | namespace Generators 9 | { 10 | 11 | public static class Register 12 | { 13 | 14 | public enum Level 15 | { 16 | Scene, 17 | Editor, 18 | } 19 | 20 | public struct Data 21 | { 22 | public string name; 23 | public string godotName; 24 | public string @base; 25 | public string @namespace; 26 | public Level level; 27 | } 28 | 29 | public static Data Generate(GeneratorExecutionContext context, INamedTypeSymbol c, bool notification, bool virtualgen, SpecialBase sBase) 30 | { 31 | var gdName = (string)(c.GetAttributes(). 32 | SingleOrDefault(x => x.AttributeClass.Name == "RegisterAttribute").NamedArguments. 33 | SingleOrDefault(x => x.Key == "name").Value.Value ?? c.Name 34 | ); 35 | var isRefCounted = sBase switch 36 | { 37 | SpecialBase.Resource => true, 38 | SpecialBase.RefCounted => true, 39 | _ => false, 40 | }; 41 | 42 | var source = $$""" 43 | using System.Runtime.CompilerServices; 44 | using System.Runtime.InteropServices; 45 | using GDExtension; 46 | using System; 47 | using static GDExtension.Native; 48 | namespace {{c.ContainingNamespace}} { 49 | public unsafe partial class {{c.Name}} : {{c.BaseType.Name}} { 50 | #pragma warning disable CS8618 51 | public static new StringName __godot_name; 52 | #pragma warning restore CS8618 53 | private GCHandle handle; 54 | #pragma warning disable CS8618 55 | public {{c.Name}}() { 56 | handle = GCHandle.Alloc(this {{(isRefCounted ? ", GCHandleType.Weak" : "")}}); 57 | GDExtensionMain.extensionInterface.object_set_instance(_internal_pointer, __godot_name._internal_pointer, (void*)this); 58 | } 59 | #pragma warning restore CS8618 60 | public static explicit operator void*({{c.Name}} instance) => (void*)(IntPtr)instance.handle; 61 | public static explicit operator {{c.Name}}(void* ptr) => ({{c.Name}})(GCHandle.FromIntPtr(new IntPtr(ptr)).Target!); 62 | public static {{c.Name}} Construct(void* ptr) { 63 | ptr = (void*)*(((IntPtr*)ptr) + 2); 64 | return ({{c.Name}})ptr; 65 | } 66 | public static unsafe new void Register() { 67 | __godot_name = new StringName("{{gdName}}"); 68 | var info = new GDExtensionClassCreationInfo() { 69 | is_virtual = System.Convert.ToByte(false), 70 | is_abstract = System.Convert.ToByte({{c.IsAbstract.ToString().ToLower()}}), 71 | //set_func = &SetFunc, 72 | //get_func = &GetFunc, 73 | //get_property_list_func = &GetPropertyList, 74 | //free_property_list_func = &FreePropertyList, 75 | //property_can_revert_func = &PropertyCanConvert, 76 | //property_get_revert_func = &PropertyGetRevert, 77 | notification_func = (IntPtr)({{(notification ? $"Engine.IsEditorHint()? (IntPtr)0 : SaftyRapper.GetFunctionPointerForDelegate(__Notification)" : "0")}}), 78 | //to_string_func = &ToString, 79 | //reference_func = &Reference, 80 | //unreference_func = &Unreference, 81 | create_instance_func = SaftyRapper.GetFunctionPointerForDelegate(CreateObject), 82 | free_instance_func = SaftyRapper.GetFunctionPointerForDelegate(FreeObject), 83 | get_virtual_func = (IntPtr){{(virtualgen ? "SaftyRapper.GetFunctionPointerForDelegate(__RegisterVirtual)" : "0")}}, 84 | //get_rid_func = &GetRid, 85 | }; 86 | GDExtensionMain.extensionInterface.classdb_register_extension_class(GDExtensionMain.library, __godot_name._internal_pointer, {{c.BaseType.Name}}.__godot_name._internal_pointer, info); 87 | RegisterMethods(); 88 | RegisterExports(); 89 | RegisterSignals(); 90 | GDExtension.Object.RegisterConstructor("{{c.Name}}", Construct); 91 | } 92 | static unsafe void* CreateObject(void* userdata) { 93 | var instance = new {{c.Name}}(); 94 | return (void*)instance._internal_pointer; 95 | } 96 | static unsafe void FreeObject(void* userdata, void* instancePtr) { 97 | var instance = ({{c.Name}})instancePtr; 98 | instance.handle.Free(); 99 | } 100 | } 101 | } 102 | """; 103 | 104 | context.AddSource($"{c.Name}.reg.gen.cs", source); 105 | 106 | var editorOnly = (bool)(c.GetAttributes(). 107 | SingleOrDefault(x => x.AttributeClass.Name == "RegisterAttribute").NamedArguments. 108 | SingleOrDefault(x => x.Key == "editorOnly").Value.Value ?? false 109 | ); 110 | var level = editorOnly switch 111 | { 112 | true => Level.Editor, 113 | false => Level.Scene, 114 | }; 115 | return new Data() 116 | { 117 | name = c.Name, 118 | godotName = gdName, 119 | @base = c.BaseType.Name, 120 | @namespace = c.ContainingNamespace.ToString(), 121 | level = level, 122 | }; 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /libgodotsharp/Extensions/ArrayTyped.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Reflection; 3 | 4 | namespace GDExtension; 5 | 6 | public unsafe partial class Array : Array, IList, ICollection, IEnumerable, IEnumerable 7 | { 8 | public Array() : base() 9 | { 10 | var (type, name) = GetVariantData; 11 | GDExtensionMain.extensionInterface.array_set_typed(_internal_pointer, (uint)type, name._internal_pointer, new Variant()._internal_pointer); 12 | } 13 | 14 | public Array(Array array) : base(array, (long)GetVariantData.Item1, GetVariantData.Item2, new Variant()) 15 | { 16 | } 17 | 18 | public static (Variant.Type, StringName) GetVariantData 19 | { 20 | get 21 | { 22 | if (typeof(T) == typeof(string)) 23 | { 24 | return (Variant.Type.String, new StringName()); 25 | } 26 | if ((typeof(T) == typeof(float)) || typeof(T) == typeof(double)) 27 | { 28 | return (Variant.Type.Float, new StringName()); 29 | } 30 | if ((typeof(T) == typeof(byte)) || typeof(T) == typeof(sbyte) || 31 | (typeof(T) == typeof(short)) || typeof(T) == typeof(ushort) || 32 | (typeof(T) == typeof(int)) || typeof(T) == typeof(uint) || 33 | (typeof(T) == typeof(long)) || typeof(T) == typeof(ulong)) 34 | { 35 | return (Variant.Type.Int, new StringName()); 36 | } 37 | if (Enum.TryParse(typeof(T).Name, true, out Variant.Type type)) 38 | { 39 | return (type, new StringName()); 40 | } 41 | return (Variant.Type.Object, new StringName(typeof(T).Name)); 42 | } 43 | } 44 | 45 | public new T this[int index] 46 | { 47 | get 48 | { 49 | return (T)base[index]; 50 | } 51 | set 52 | { 53 | base[index] = value; 54 | } 55 | } 56 | 57 | public new T this[long index] 58 | { 59 | get 60 | { 61 | return (T)base[index]; 62 | } 63 | set 64 | { 65 | base[index] = value; 66 | } 67 | } 68 | public static implicit operator Array(List self) 69 | { 70 | var data = new Array(); 71 | data.Resize(self.Count); 72 | for (int i = 0; i < self.Count; i++) 73 | { 74 | data[i] = self[i]; 75 | } 76 | return data; 77 | } 78 | 79 | public static implicit operator Array(T[] self) 80 | { 81 | var data = new Array(); 82 | data.Resize(self.Length); 83 | for (int i = 0; i < self.Length; i++) 84 | { 85 | data[i] = self[i]; 86 | } 87 | return data; 88 | } 89 | 90 | public static implicit operator Array(Span self) 91 | { 92 | var data = new Array(); 93 | data.Resize(self.Length); 94 | for (int i = 0; i < self.Length; i++) 95 | { 96 | data[i] = self[i]; 97 | } 98 | return data; 99 | } 100 | 101 | public static implicit operator List(Array self) 102 | { 103 | var data = new List((int)self.Size()); 104 | for (int i = 0; i < data.Count; i++) 105 | { 106 | data[i] = self[i]; 107 | } 108 | return data; 109 | } 110 | 111 | public static implicit operator T[](Array self) 112 | { 113 | var data = new T[self.Length]; 114 | for (int i = 0; i < self.Length; i++) 115 | { 116 | data[i] = self[i]; 117 | } 118 | return data; 119 | } 120 | 121 | public static implicit operator Span(Array self) 122 | { 123 | var data = new T[self.Length]; 124 | for (int i = 0; i < self.Length; i++) 125 | { 126 | data[i] = self[i]; 127 | } 128 | return data; 129 | } 130 | 131 | 132 | int ICollection.Count => (int)Size(); 133 | 134 | bool ICollection.IsReadOnly => false; 135 | 136 | public void Add(T item) 137 | { 138 | Append(Variant.ObjectToVariant(item)); 139 | } 140 | 141 | public bool Contains(T item) 142 | { 143 | return Has(Variant.ObjectToVariant(item)); 144 | } 145 | 146 | public void CopyTo(T[] array, int arrayIndex) 147 | { 148 | var amount = System.Math.Max(Length - arrayIndex, array.Length); 149 | for (int i = 0; i < amount; i++) 150 | { 151 | array[i] = this[i + arrayIndex]; 152 | } 153 | } 154 | 155 | public int IndexOf(T item) 156 | { 157 | return (int)Find(Variant.ObjectToVariant(item)); 158 | } 159 | 160 | public void Insert(int index, T item) 161 | { 162 | Insert((long)index, Variant.ObjectToVariant(item)); 163 | } 164 | 165 | public bool Remove(T item) 166 | { 167 | Erase(Variant.ObjectToVariant(item)); 168 | return true; 169 | } 170 | 171 | public new IEnumerator GetEnumerator() 172 | { 173 | for (int i = 0; i < Length; i++) 174 | { 175 | yield return this[i]; 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /TestLibGodotSharp/MainGodotGame.cs: -------------------------------------------------------------------------------- 1 | using GDExtension; 2 | using LibGodotSharp; 3 | 4 | namespace GodotGame; 5 | 6 | public class MainGodotGame 7 | { 8 | public static bool RunInVR = false; 9 | 10 | public static HelloFromLibGodot AddCube(Vector3 pos) 11 | { 12 | var meshRender = new HelloFromLibGodot 13 | { 14 | Position = pos 15 | }; 16 | return meshRender; 17 | } 18 | 19 | public static void LoadProjectSettings(ProjectSettings projectSettings) 20 | { 21 | var data = GDExtension.ProjectSettings.GetSetting("display/window/vsync/vsync_mode"); 22 | Console.WriteLine(data.NativeType); 23 | Console.WriteLine(Variant.VariantToObject(data)); 24 | ProjectSettings.SetSetting("application/config/name", "TestConsoleApp"); 25 | if (RunInVR) 26 | { 27 | ProjectSettings.SetSetting("xr/openxr/enabled", true); 28 | ProjectSettings.SetSetting("xr/shaders/enabled", true); 29 | ProjectSettings.SetSetting("display/window/vsync/vsync_mode", 0); 30 | } 31 | } 32 | 33 | static HelloFromLibGodot[] allCubes = System.Array.Empty(); 34 | 35 | public static void Message() 36 | { 37 | _counter++; 38 | 39 | Console.WriteLine($"ButtonPress {_counter}"); 40 | if ((_counter%2) == 1) 41 | { 42 | allCubes = new HelloFromLibGodot[100]; 43 | for (int i = 0; i < allCubes.Length; i++) 44 | { 45 | allCubes[i] = AddCube(new Vector3(i % 10, (i / 10) % 10, -5)); 46 | _sceneTree.Root.AddChild(allCubes[i]); 47 | } 48 | } 49 | if (_counter == 6) 50 | { 51 | var testButton = new Button 52 | { 53 | Text = "Other button", 54 | ToggleMode = true, 55 | }; 56 | testButton.SetPosition(new Vector2(100, 100)); 57 | testButton.Pressed += () => 58 | { 59 | Console.WriteLine($"LamdaPress"); 60 | }; 61 | _sceneTree.Root.AddChild(testButton); 62 | } 63 | if ((_counter % 2) == 0) 64 | { 65 | for (int i = 0; i < allCubes.Length; i++) 66 | { 67 | allCubes[i].QueueFree(); 68 | } 69 | allCubes = System.Array.Empty(); 70 | } 71 | GC.Collect(); 72 | } 73 | 74 | static int _counter = 0; 75 | 76 | public static void OtherMessage(bool trains) 77 | { 78 | Console.WriteLine($"OtherMessage {trains}"); 79 | } 80 | 81 | static SceneTree _sceneTree; 82 | 83 | public unsafe static void LoadScene(SceneTree scene) 84 | { 85 | _sceneTree = scene; 86 | 87 | foreach (var item in InputMap.GetActions()) 88 | { 89 | Console.WriteLine("InputAction "+item); 90 | } 91 | 92 | var newNode = new Node3D(); 93 | var eorgin = new XROrigin3D(); 94 | var cam = new XRCamera3D 95 | { 96 | Current = true, 97 | Position = new Vector3(0, 0, 2) 98 | }; 99 | eorgin.AddChild(cam); 100 | newNode.AddChild(eorgin); 101 | newNode.AddChild(AddCube(new Vector3(1, 1, 1))); 102 | newNode.AddChild(AddCube(new Vector3(-1, -1, -1))); 103 | newNode.AddChild(AddCube(new Vector3(0, 1, 1))); 104 | 105 | var testNode = new Node3D(); 106 | newNode.AddChild(testNode); 107 | foreach (var item in newNode.GetChildren()) 108 | { 109 | Console.WriteLine($"{item}"); 110 | } 111 | 112 | newNode.AddChild(new ANode()); // Tests funny bug 113 | newNode.AddChild(new ZNode()); 114 | 115 | var array = (PackedInt32Array)new int[] { 3, 3, 3, 3, 435, 345, 3453, 53, 2, 34, 4, 23, 4, 2, 43, 4543534, 435342, 1, 2342345, 5345, 345, 345, 43, 543, 645, 67, 5676, 8, 64534, 5, 345, 3456, 45, 67, 76, 756867, 1, 34, 534, 5, 345, 34, 534, 634, 5, 3456, 3 }; 116 | var stringArray = (PackedStringArray)new string[] { "This", "IS", "A", "Packed", "Sting", "ARRAY", "I", "AM", "Testing", "It", "By", "ADDing", "STUFF", "TO", "it", "It", "Might", "be", "COOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOL", "IFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF STUFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF JUSTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT WORKSDSDEDF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" }; 117 | array.Size(); 118 | stringArray.Size(); 119 | for (int i = 0; i < array.Size(); i++) 120 | { 121 | Console.WriteLine(array[i]); 122 | } 123 | for (int i = 0; i < stringArray.Size(); i++) 124 | { 125 | Console.WriteLine(stringArray[i]); 126 | } 127 | var testButton = new Button 128 | { 129 | Text = "testButton", 130 | ToggleMode = true 131 | }; 132 | testButton.Pressed += Message; 133 | testButton.Toggled += OtherMessage; 134 | 135 | newNode.AddChild(testButton); 136 | 137 | var e = new Label(); 138 | e.SetAnchorsPreset(Control.LayoutPreset.FullRect); 139 | var script = new GDScript 140 | { 141 | SourceCode = 142 | @" 143 | extends Label 144 | 145 | func _ready(): 146 | print(get_tree().root.get_class()) 147 | 148 | " 149 | }; 150 | script.Reload(); 151 | newNode.AddChild(e); 152 | scene.Root.UseXr = RunInVR; 153 | scene.Root.AddChild(newNode); 154 | e.SetScript(script); 155 | } 156 | } -------------------------------------------------------------------------------- /libgodotsharp/LibGodotCustomCallable.cs: -------------------------------------------------------------------------------- 1 | using GDExtension; 2 | using System.IO; 3 | using System.Reflection; 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | using static GDExtension.Native; 7 | using static LibGodotSharp.LibGodotCustomCallable; 8 | 9 | namespace LibGodotSharp 10 | { 11 | internal static unsafe class LibGodotCustomCallable 12 | { 13 | [DllImport("godot_android", EntryPoint = "libgodot_create_callable", CallingConvention = CallingConvention.StdCall)] 14 | internal static extern void* Android_libgodot_create_callable(void* customobject); 15 | 16 | [DllImport("libgodot", EntryPoint = "libgodot_create_callable", CallingConvention = CallingConvention.StdCall)] 17 | internal static extern void* Desktop_libgodot_create_callable(void* customobject); 18 | 19 | 20 | [DllImport("godot_android", EntryPoint = "libgodot_bind_custom_callable", CallingConvention = CallingConvention.StdCall)] 21 | internal static extern void Android_libgodot_bind_custom_callable(void* callable_hash_bind, void* get_as_text_bind, void* get_object_bind, void* disposes_bind, void* call_bind); 22 | 23 | [DllImport("libgodot", EntryPoint = "libgodot_bind_custom_callable", CallingConvention = CallingConvention.Cdecl)] 24 | internal static extern void Desktop_libgodot_bind_custom_callable(void* callable_hash_bind, void* get_as_text_bind, void* get_object_bind, void* disposes_bind, void* call_bind); 25 | 26 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 27 | internal static void Libgodot_bind_custom_callable(void* callable_hash_bind, void* get_as_text_bind, void* get_object_bind, void* disposes_bind, void* call_bind) 28 | { 29 | if (AndroidTest.Check()) 30 | { 31 | Android_libgodot_bind_custom_callable(callable_hash_bind, get_as_text_bind, get_object_bind, disposes_bind, call_bind); 32 | } 33 | else 34 | { 35 | Desktop_libgodot_bind_custom_callable(callable_hash_bind, get_as_text_bind, get_object_bind, disposes_bind, call_bind); 36 | } 37 | } 38 | 39 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 40 | internal static void* Libgodot_create_callable(void* customobject) 41 | { 42 | if (AndroidTest.Check()) 43 | { 44 | return Android_libgodot_create_callable(customobject); 45 | } 46 | else 47 | { 48 | return Desktop_libgodot_create_callable(customobject); 49 | } 50 | } 51 | 52 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 53 | internal delegate uint callable_hash_bind_del(void* targetObject); 54 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 55 | internal delegate void* get_as_text_bind_del(void* targetObject); 56 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 57 | internal delegate ulong get_object_bind_del(void* targetObject); 58 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 59 | internal delegate void disposes_bind_del(void* targetObject); 60 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 61 | internal delegate void call_bind_del(void* targetObject, void** args, int args_length, void* returnData, void* error); 62 | 63 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 64 | internal static Callable GetCallable(void* customobject) 65 | { 66 | return (Callable)GCHandle.FromIntPtr(new IntPtr(customobject)).Target; 67 | } 68 | 69 | internal static uint Callable_hash_bind(void* targetObject) 70 | { 71 | var target = GetCallable(targetObject); 72 | return (uint)(target._delegate?.GetHashCode() ?? target.GetHashCode()); 73 | } 74 | 75 | internal static void* Get_as_text_bind_del(void* targetObject) 76 | { 77 | var target = GetCallable(targetObject); 78 | return StringMarshall.ToNative(target._delegate?.ToString() ?? "null"); 79 | } 80 | 81 | internal static ulong Get_object_bind_del(void* targetObject) 82 | { 83 | var target = GetCallable(targetObject); 84 | return (ulong)target._object.GetInstanceId(); 85 | } 86 | 87 | internal static void Disposes_bind_del(void* targetObject) 88 | { 89 | GetCallable(targetObject).Free(); 90 | } 91 | 92 | internal static void Call_bind_del(void* targetObject, void** args, int args_length, void* returnData, void* error) 93 | { 94 | var target = GetCallable(targetObject); 95 | var callargs = new object[args_length]; 96 | for (int i = 0; i < args_length; i++) 97 | { 98 | var varenet = new Variant(args[i]); 99 | callargs[i] = Variant.VariantToObject(varenet); 100 | } 101 | var output = target._delegate.DynamicInvoke(callargs); 102 | Variant.SaveIntoPointer(output, returnData); 103 | } 104 | 105 | internal static void Init() 106 | { 107 | var callable_hash_pointer = (void*)SaftyRapper.GetFunctionPointerForDelegate(Callable_hash_bind); 108 | var get_as_text_pointer = (void*)SaftyRapper.GetFunctionPointerForDelegate(Get_as_text_bind_del); 109 | var get_object_pointer = (void*)SaftyRapper.GetFunctionPointerForDelegate(Get_object_bind_del); 110 | var disposes_pointer = (void*)SaftyRapper.GetFunctionPointerForDelegate(Disposes_bind_del); 111 | var call_pointer = (void*)SaftyRapper.GetFunctionPointerForDelegate(Call_bind_del); 112 | Libgodot_bind_custom_callable(callable_hash_pointer, get_as_text_pointer, get_object_pointer, disposes_pointer, call_pointer); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /libgodotsharp/GenVirtual.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using Microsoft.CodeAnalysis; 5 | using Microsoft.CodeAnalysis.CSharp.Syntax; 6 | 7 | namespace Generators 8 | { 9 | 10 | public static class GenVirtual 11 | { 12 | public static string TypeToVariantType(ITypeSymbol type) 13 | { 14 | return TypeToVariantType(type, LibGodotGenerators.GetSpecialBase(type)); 15 | } 16 | public static string TypeToVariantType(ITypeSymbol type, SpecialBase sBase) 17 | { 18 | return sBase switch 19 | { 20 | SpecialBase.Node => "Object", 21 | SpecialBase.Resource => "Object", 22 | _ => type.Name switch 23 | { 24 | "Boolean" => "Bool", 25 | "Int64" => "Int", 26 | "Double" => "Float", 27 | "String" => "String", 28 | "Vector2" => "Vector2", 29 | "Vector2i" => "Vector2i", 30 | "Rect2" => "Rect2", 31 | "Rect2i" => "Rect2i", 32 | "Vector3" => "Vector3", 33 | "Vector3i" => "Vector3i", 34 | "Transform2D" => "Transform2D", 35 | "Vector4" => "Vector4", 36 | "Vector4i" => "Vector4i", 37 | "Plane" => "Plane", 38 | "Quaternion" => "Quaternion", 39 | "AABB" => "AABB", 40 | "Basis" => "Basis", 41 | "Transform3D" => "Transform3D", 42 | "Projection" => "Projection", 43 | "Color" => "Color", 44 | "StringName" => "StringName", 45 | "NodePath" => "NodePath", 46 | "RID" => "RID", 47 | "Callable" => "Callable", 48 | "Signal" => "Signal", 49 | "Dictionary" => "Dictionary", 50 | "Array" => "Array", 51 | "PackedByteArray" => "PackedByteArray", 52 | "PackedInt32Array" => "PackedInt32Array", 53 | "PackedInt64Array" => "PackedInt64Array", 54 | "PackedFloat32Array" => "PackedFloat32Array", 55 | "PackedFloat64Array" => "PackedFloat64Array", 56 | "PackedStringArray" => "PackedStringArray", 57 | "PackedVector2Array" => "PackedVector2Array", 58 | "PackedVector3Array" => "PackedVector3Array", 59 | "PackedColorArray" => "PackedColorArray", 60 | _ => throw new Exception($"Unknown type: {type.Name}"), 61 | }, 62 | }; 63 | } 64 | 65 | public static bool Generate(GeneratorExecutionContext context, INamedTypeSymbol c) 66 | { 67 | var methods = c.GetMembers().Where(x => x is IMethodSymbol).Select(x => (IMethodSymbol)x); 68 | var code = $$""" 69 | using System.Runtime.CompilerServices; 70 | using System.Runtime.InteropServices; 71 | using GDExtension; 72 | namespace {{c.ContainingNamespace}} { 73 | public unsafe partial class {{c.Name}} : {{c.BaseType.Name}} { 74 | """; 75 | var addedCode = ""; 76 | var has = false; 77 | code += $$""" 78 | public static unsafe new void* __RegisterVirtual(void* user_ptr, void* name) { 79 | var cSharpString = new StringName(name); 80 | switch (cSharpString) { 81 | """; 82 | foreach (var method in methods) 83 | { 84 | if (method.IsOverride) 85 | { 86 | has = true; 87 | addedCode += $$""" 88 | private static unsafe void {{method.Name}}_Caller(void* p_instance, void** p_args, void* r_ret) { 89 | var instance = ({{c.Name}})p_instance; 90 | 91 | """; 92 | var args = ""; 93 | for (var j = 0; j < method.Parameters.Length; j++) 94 | { 95 | var arg = method.Parameters[j]; 96 | if (arg.Type.Name == "String") 97 | { 98 | args += $"StringMarshall.ToManaged(p_args[{j}])"; 99 | } 100 | else if (TypeToVariantType(arg.Type) == "Object") 101 | { 102 | args += $"({arg.Type})GDExtension.Object.ConstructUnknown(*(void**)p_args[{j}])"; 103 | } 104 | else 105 | { 106 | args += $"*({arg.Type}*)p_args[{j}]"; 107 | } 108 | if (j < method.Parameters.Length - 1) 109 | { 110 | args += ", "; 111 | } 112 | } 113 | if (method.ReturnsVoid) { 114 | addedCode += $"\t\tinstance.{method.Name}({args});\n"; ; 115 | } 116 | else 117 | { 118 | addedCode += $"\t\tvar returnData = instance.{method.Name}({args})\n"; 119 | if (TypeToVariantType(method.ReturnType) == "Object") 120 | { 121 | code += $"*(void**)r_ret = returnData._internal_pointer;"; 122 | } 123 | else 124 | { 125 | code += $"*({method.ReturnType}*)r_ret = returnData;"; 126 | } 127 | } 128 | addedCode += $$""" 129 | } 130 | """; 131 | code += $$""" 132 | case "{{Renamer.ToSnake(method.Name)}}": 133 | return (void*)SaftyRapper.GetFunctionPointerForDelegate({{method.Name}}_Caller); 134 | """; 135 | } 136 | } 137 | if (has == false) 138 | { 139 | return false; 140 | } 141 | code += $$""" 142 | } 143 | return null; 144 | } 145 | """; 146 | code += addedCode; 147 | code += $$""" 148 | } 149 | } 150 | """; 151 | 152 | context.AddSource($"{c.Name}.virtual.gen.cs", code); 153 | return true; 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | 352 | libgodotsharp/Generated/ 353 | libgodotsharp/Generated/* 354 | LibGodotSharpAndroid/godot-lib.template_debug.aar 355 | *.dll 356 | *.dylib 357 | *.so 358 | LibGodotSharpAndroid/godot-lib.template_release.aar 359 | -------------------------------------------------------------------------------- /sharp_generator/GDapi.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json; 6 | using System.Text.Json.Serialization; 7 | using System.Threading.Tasks; 8 | #nullable enable 9 | namespace SharpGenerator 10 | { 11 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "JSON Format")] 12 | public sealed class Api 13 | { 14 | public static Api? Create(string path) 15 | { 16 | var file = File.OpenRead(path); 17 | var api = JsonSerializer.Deserialize(file); 18 | file.Close(); 19 | return api; 20 | } 21 | public record struct Argument 22 | { 23 | public string name { get; set; } 24 | public string type { get; set; } 25 | [JsonPropertyName("default_value")] 26 | public string? defaultValue { get; set; } 27 | public string? meta { get; set; } 28 | } 29 | 30 | public record struct ReturnValue 31 | { 32 | public string type { get; set; } 33 | public string? meta { get; set; } 34 | } 35 | 36 | public record struct Constant 37 | { 38 | public string name { get; set; } 39 | public string type { get; set; } 40 | public string value { get; set; } 41 | } 42 | 43 | public record struct Size 44 | { 45 | public string name { get; set; } 46 | public int size { get; set; } 47 | } 48 | 49 | public record struct Signal 50 | { 51 | public string name { get; set; } 52 | public Argument[]? arguments { get; set; } 53 | } 54 | 55 | public record struct Property 56 | { 57 | public string type { get; set; } 58 | public string name { get; set; } 59 | public string setter { get; set; } 60 | public string getter { get; set; } 61 | public int? index { get; set; } 62 | } 63 | 64 | public record struct Singleton 65 | { 66 | public string name { get; set; } 67 | public string type { get; set; } 68 | } 69 | 70 | public record struct NativeStructure 71 | { 72 | public string name { get; set; } 73 | public string format { get; set; } 74 | } 75 | 76 | public record struct Header 77 | { 78 | [JsonPropertyName("version_major")] 79 | public int versionMajor { get; set; } 80 | [JsonPropertyName("version_minor")] 81 | public int versionMinor { get; set; } 82 | [JsonPropertyName("version_patch")] 83 | public int versionPatch { get; set; } 84 | [JsonPropertyName("version_status")] 85 | public string versionStatus { get; set; } 86 | [JsonPropertyName("version_build")] 87 | public string versionBuild { get; set; } 88 | [JsonPropertyName("version_full_name")] 89 | public string versionFullName { get; set; } 90 | } 91 | 92 | public record struct BuiltinClassSizes 93 | { 94 | [JsonPropertyName("build_configuration")] 95 | public string buildConfiguration { get; set; } 96 | 97 | public Size[] sizes { get; set; } 98 | } 99 | 100 | public record struct MemberOffset 101 | { 102 | public string member { get; set; } 103 | public int offset { get; set; } 104 | public string? meta { get; set; } 105 | } 106 | 107 | public record struct Member 108 | { 109 | public string name { get; set; } 110 | public string type { get; set; } 111 | } 112 | 113 | public record struct ClassOffsets 114 | { 115 | public string name { get; set; } 116 | public MemberOffset[] members { get; set; } 117 | } 118 | 119 | public record struct BuiltinClassMemberOffsets 120 | { 121 | [JsonPropertyName("build_configuration")] 122 | public string buildConfiguration { get; set; } 123 | public ClassOffsets[] classes { get; set; } 124 | } 125 | 126 | public record struct Value 127 | { 128 | public string name { get; set; } 129 | public int value { get; set; } 130 | } 131 | 132 | public record struct Enum 133 | { 134 | public string name { get; set; } 135 | [JsonPropertyName("is_bitfield")] 136 | public bool? isBitfield { get; set; } 137 | public Value[] values { get; set; } 138 | } 139 | 140 | public record struct Method 141 | { 142 | public string name { get; set; } 143 | [JsonPropertyName("return_type")] 144 | public string returnType { get; set; } 145 | [JsonPropertyName("is_vararg")] 146 | public bool isVararg { get; set; } 147 | [JsonPropertyName("is_const")] 148 | public bool isConst { get; set; } 149 | [JsonPropertyName("is_static")] 150 | public bool? isStatic { get; set; } 151 | [JsonPropertyName("is_virtual")] 152 | public bool isVirtual { get; set; } 153 | public uint? hash { get; set; } 154 | [JsonPropertyName("return_value")] public ReturnValue? returnValue { get; set; } 155 | public Argument[]? arguments { get; set; } 156 | 157 | public string? category { get; set; } 158 | } 159 | 160 | public record struct Operator 161 | { 162 | public string name { get; set; } 163 | [JsonPropertyName("right_type")] public string? rightType { get; set; } 164 | [JsonPropertyName("return_type")] public string returnType { get; set; } 165 | } 166 | 167 | public record Constructor 168 | { 169 | public int index { get; set; } 170 | public Argument[]? arguments { get; set; } 171 | } 172 | 173 | public record struct BuiltinClass 174 | { 175 | public string name { get; set; } 176 | [JsonPropertyName("is_keyed")] public bool isKeyed { get; set; } 177 | [JsonPropertyName("indexing_return_type")] public string? indexingReturnType { get; set; } 178 | public Member[]? members { get; set; } 179 | public Constant[]? constants { get; set; } 180 | public Enum[]? enums { get; set; } 181 | public Operator[]? operators { get; set; } 182 | public Method[]? methods { get; set; } 183 | public Constructor[]? constructors { get; set; } 184 | [JsonPropertyName("has_destructor")] public bool hasDestructor { get; set; } 185 | } 186 | 187 | public record struct Class 188 | { 189 | public string name { get; set; } 190 | [JsonPropertyName("is_refcounted")] public bool isRefcounted { get; set; } 191 | [JsonPropertyName("is_instantiable")] public bool isInstantiable { get; set; } 192 | public string? inherits { get; set; } 193 | [JsonPropertyName("api_type")] public string apiType { get; set; } 194 | public Value[] constants { get; set; } 195 | public Enum[] enums { get; set; } 196 | public Method[] methods { get; set; } 197 | public Signal[] signals { get; set; } 198 | public Property[] properties { get; set; } 199 | } 200 | 201 | public Header header { get; set; } 202 | [JsonPropertyName("builtin_class_sizes")] public BuiltinClassSizes[] builtinClassSizes { get; set; } = Array.Empty(); 203 | public BuiltinClassSizes? ClassSize(string build_configuration) 204 | { 205 | foreach (var item in builtinClassSizes) 206 | { 207 | if (item.buildConfiguration == build_configuration) 208 | { 209 | return item; 210 | } 211 | } 212 | return null; 213 | } 214 | [JsonPropertyName("builtin_class_member_offsets")] public BuiltinClassMemberOffsets[] builtinClassMemberOffsets { get; set; } = Array.Empty(); 215 | public BuiltinClassMemberOffsets? ClassMemberOffsets(string build_configuration) 216 | { 217 | foreach (var item in builtinClassMemberOffsets) 218 | { 219 | if (item.buildConfiguration == build_configuration) 220 | { 221 | return item; 222 | } 223 | } 224 | return null; 225 | } 226 | [JsonPropertyName("global_constants")] public object[] globalConstants { get; set; } = Array.Empty(); 227 | [JsonPropertyName("global_enums")] public Enum[] globalEnums { get; set; } = Array.Empty(); 228 | [JsonPropertyName("utility_functions")] public Method[] untilityFunction { get; set; } = Array.Empty(); 229 | [JsonPropertyName("builtin_classes")] public BuiltinClass[] builtinClasses { get; set; } = Array.Empty(); 230 | public Class[] classes { get; set; } = Array.Empty(); 231 | public Singleton[] singletons { get; set; } = Array.Empty(); 232 | [JsonPropertyName("native_structures")] public NativeStructure[] nativeStructures { get; set; } = Array.Empty(); 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /.github/workflows/nuget_publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish NuGet Package Godot4.0 2 | on: 3 | push: 4 | branches: 5 | - main 6 | 7 | env: 8 | # Only used for the cache key. Increment version to force clean build. 9 | GODOT_BASE_BRANCH: master 10 | SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes 11 | DOTNET_NOLOGO: true 12 | DOTNET_CLI_TELEMETRY_OPTOUT: true 13 | 14 | concurrency: 15 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-nugetpackages-Godot4.0 16 | cancel-in-progress: true 17 | 18 | jobs: 19 | build: 20 | runs-on: "windows-latest" 21 | environment: NugetBuildEnviroment 22 | name: 'NuGet Package Build' 23 | steps: 24 | - uses: actions/checkout@v3 25 | 26 | - name: Setup Godot build cache 27 | uses: ./.github/actions/godot-cache 28 | with: 29 | cache-name: 'windows-64-editor' 30 | continue-on-error: true 31 | 32 | - name: Setup python and scons 33 | uses: ./.github/actions/godot-deps 34 | 35 | - name: Setup MSVC problem matcher 36 | uses: ammaraskar/msvc-problem-matcher@master 37 | 38 | - name: Compilation 39 | uses: ./.github/actions/godot-build 40 | with: 41 | sconsflags: ${{ env.SCONSFLAGS }} library_type=shared_library 42 | platform: windows 43 | tests: false 44 | 45 | - name: Setup .NET 6 46 | uses: actions/setup-dotnet@v2 47 | with: 48 | dotnet-version: 6.0.x 49 | 50 | - name: Set up .NET 7 51 | uses: actions/setup-dotnet@v2 52 | with: 53 | dotnet-version: 7.0.x 54 | 55 | - name: Install MAUI Workload 56 | run: dotnet workload install maui --ignore-failed-sources 57 | 58 | - name: Restore Dependencies 59 | run: dotnet restore 60 | 61 | - name: Wait for Android Build to succeed 62 | uses: lewagon/wait-on-check-action@v1.3.1 63 | with: 64 | ref: ${{ github.ref }} 65 | check-name: 'Android Build' 66 | repo-token: ${{ secrets.GITHUB_TOKEN }} 67 | wait-interval: 10 68 | 69 | - name: Wait for Windows Libgodot X64 to succeed 70 | uses: lewagon/wait-on-check-action@v1.3.1 71 | with: 72 | ref: ${{ github.ref }} 73 | check-name: 'Windows Libgodot X64' 74 | repo-token: ${{ secrets.GITHUB_TOKEN }} 75 | wait-interval: 10 76 | 77 | - name: Wait for Windows Libgodot X86 to succeed 78 | uses: lewagon/wait-on-check-action@v1.3.1 79 | with: 80 | ref: ${{ github.ref }} 81 | check-name: 'Windows Libgodot X86' 82 | repo-token: ${{ secrets.GITHUB_TOKEN }} 83 | wait-interval: 10 84 | 85 | - name: Wait for Linux Libgodot X64 to succeed 86 | uses: lewagon/wait-on-check-action@v1.3.1 87 | with: 88 | ref: ${{ github.ref }} 89 | check-name: 'Linux Libgodot X64' 90 | repo-token: ${{ secrets.GITHUB_TOKEN }} 91 | wait-interval: 10 92 | 93 | - name: Wait for Macos X64 to succeed 94 | uses: lewagon/wait-on-check-action@v1.3.1 95 | with: 96 | ref: ${{ github.ref }} 97 | check-name: 'Macos X64' 98 | repo-token: ${{ secrets.GITHUB_TOKEN }} 99 | wait-interval: 10 100 | 101 | - name: Wait for Macos Arm 64 to succeed 102 | uses: lewagon/wait-on-check-action@v1.3.1 103 | with: 104 | ref: ${{ github.ref }} 105 | check-name: 'Macos Arm 64' 106 | repo-token: ${{ secrets.GITHUB_TOKEN }} 107 | wait-interval: 10 108 | 109 | - name: Wait for IOS Arm 64 to succeed 110 | uses: lewagon/wait-on-check-action@v1.3.1 111 | with: 112 | ref: ${{ github.ref }} 113 | check-name: 'IOS Arm 64' 114 | repo-token: ${{ secrets.GITHUB_TOKEN }} 115 | wait-interval: 10 116 | 117 | - name: Download artifact macos-template-release64 118 | uses: dawidd6/action-download-artifact@v2 119 | with: 120 | github_token: ${{secrets.GITHUB_TOKEN}} 121 | workflow: macos_builds.yml 122 | workflow_conclusion: success 123 | pr: ${{github.event.pull_request.number}} 124 | commit: ${{github.event.pull_request.head.sha}} 125 | name: 'macos-template-release64' 126 | 127 | - name: Download artifact macos-template-release-Arm64 128 | uses: dawidd6/action-download-artifact@v2 129 | with: 130 | github_token: ${{secrets.GITHUB_TOKEN}} 131 | workflow: macos_builds.yml 132 | workflow_conclusion: success 133 | pr: ${{github.event.pull_request.number}} 134 | commit: ${{github.event.pull_request.head.sha}} 135 | name: 'macos-template-release-Arm64' 136 | 137 | - name: Download artifact ios-template-release-Arm64 138 | uses: dawidd6/action-download-artifact@v2 139 | with: 140 | github_token: ${{secrets.GITHUB_TOKEN}} 141 | workflow: macos_builds.yml 142 | workflow_conclusion: success 143 | pr: ${{github.event.pull_request.number}} 144 | commit: ${{github.event.pull_request.head.sha}} 145 | name: 'ios-template-release-Arm64' 146 | 147 | - name: Download artifact windows-template-release64 148 | uses: dawidd6/action-download-artifact@v2 149 | with: 150 | github_token: ${{secrets.GITHUB_TOKEN}} 151 | workflow: windows_builds.yml 152 | workflow_conclusion: success 153 | pr: ${{github.event.pull_request.number}} 154 | commit: ${{github.event.pull_request.head.sha}} 155 | name: 'windows-template-release64' 156 | 157 | - name: Download artifact windows-template-release86 158 | uses: dawidd6/action-download-artifact@v2 159 | with: 160 | github_token: ${{secrets.GITHUB_TOKEN}} 161 | workflow: windows_builds.yml 162 | workflow_conclusion: success 163 | pr: ${{github.event.pull_request.number}} 164 | commit: ${{github.event.pull_request.head.sha}} 165 | name: 'windows-template-release86' 166 | 167 | - name: Download artifact linux-template-release64 168 | uses: dawidd6/action-download-artifact@v2 169 | with: 170 | github_token: ${{secrets.GITHUB_TOKEN}} 171 | workflow: linux_builds.yml 172 | workflow_conclusion: success 173 | pr: ${{github.event.pull_request.number}} 174 | commit: ${{github.event.pull_request.head.sha}} 175 | name: 'linux-template-release64' 176 | 177 | - name: Download artifact android-template-release 178 | uses: dawidd6/action-download-artifact@v2 179 | with: 180 | github_token: ${{secrets.GITHUB_TOKEN}} 181 | workflow: android_builds.yml 182 | workflow_conclusion: success 183 | pr: ${{github.event.pull_request.number}} 184 | commit: ${{github.event.pull_request.head.sha}} 185 | name: 'android-template-release' 186 | 187 | - name: Setting up build version 188 | run: | 189 | $version = "4.0.{0:#}" -f $("${{vars.LIB_GODOTSHARP_VERSION}}") 190 | echo "BUILD_VERSION=$version" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append 191 | 192 | - name: Run Generator 193 | run: dotnet run --project sharp_generator/SharpGenerator.csproj 194 | 195 | - name: Build the NuGet package LibGodotSharp 196 | run: dotnet build libgodotsharp/LibGodotSharp.csproj --configuration Release --output .\Package\ 197 | 198 | - name: Build the NuGet package LibGodotSharpAndroid 199 | run: dotnet build LibGodotSharpAndroid/LibGodotSharpAndroid.csproj --configuration Release --output .\Package\ 200 | 201 | - name: Build the NuGet package LibGodotSharpDesktop 202 | run: dotnet build LibGodotSharpDesktop/LibGodotSharpDesktop.csproj --configuration Release --output .\Package\ 203 | 204 | - name: Upload artifact 205 | uses: ./.github/actions/upload-artifact 206 | with: 207 | name: 'NuGet packages' 208 | path: '**/*.nupkg' 209 | 210 | - name: Upload Template Project artifact Net7 211 | uses: ./.github/actions/upload-artifact 212 | with: 213 | name: 'Template Project Net7' 214 | path: './TemplateProject/' 215 | 216 | - name: Upload Template Project artifact Net6 217 | uses: ./.github/actions/upload-artifact 218 | with: 219 | name: 'Template Project Net6' 220 | path: './TemplateProjectNet6/' 221 | 222 | - name: Upload Template Project NetFramework artifact 223 | uses: ./.github/actions/upload-artifact 224 | with: 225 | name: 'Template Project NetFramework' 226 | path: './TemplateProjectNetFramework/' 227 | -------------------------------------------------------------------------------- /libgodotsharp/Methods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using Microsoft.CodeAnalysis; 6 | using Microsoft.CodeAnalysis.CSharp.Syntax; 7 | 8 | namespace Generators 9 | { 10 | 11 | public class Methods 12 | { 13 | 14 | public struct Info 15 | { 16 | public string name; 17 | public (ITypeSymbol, string)[] arguments; 18 | public ITypeSymbol ret; 19 | public string property; 20 | } 21 | 22 | List methods; 23 | 24 | public Methods() 25 | { 26 | methods = new List(); 27 | } 28 | 29 | public void AddMethod(Info info) 30 | { 31 | methods.Add(info); 32 | } 33 | 34 | void AddAttributeMethods(GeneratorExecutionContext context, INamedTypeSymbol c) 35 | { 36 | var ms = c.GetMembers(). 37 | Where(x => x is IMethodSymbol). 38 | Select(x => (IMethodSymbol)x). 39 | Where(x => x.GetAttributes().Where(x => x.AttributeClass.ToString() == "GDExtension.MethodAttribute").Count() > 0) 40 | .ToArray(); 41 | 42 | foreach (var method in ms) 43 | { 44 | var info = new Info() 45 | { 46 | name = method.Name, 47 | arguments = method.Parameters.Select(x => (x.Type, x.Name)).ToArray(), 48 | ret = method.ReturnsVoid ? null : method.ReturnType, 49 | property = null, 50 | }; 51 | AddMethod(info); 52 | } 53 | } 54 | 55 | public void Generate(GeneratorExecutionContext context, INamedTypeSymbol c) 56 | { 57 | AddAttributeMethods(context, c); 58 | 59 | var code = $$""" 60 | using System.Runtime.CompilerServices; 61 | using System.Runtime.InteropServices; 62 | using GDExtension; 63 | using static GDExtension.Native; 64 | namespace {{c.ContainingNamespace}} { 65 | public unsafe partial class {{c.Name}} : {{c.BaseType.Name}} { 66 | static unsafe void RegisterMethods() { 67 | """; 68 | 69 | for (var i = 0; i < methods.Count; i++) 70 | { 71 | code += "\t\t{\n"; 72 | var method = methods[i]; 73 | if (method.arguments.Length > 0) 74 | { 75 | code += $"\t\t\tvar args = stackalloc GDExtensionPropertyInfo[{method.arguments.Length}];\n"; 76 | code += $"\t\t\tvar args_meta = stackalloc GDExtensionClassMethodArgumentMetadata[{method.arguments.Length}];\n"; 77 | for (var j = 0; j < method.arguments.Length; j++) 78 | { 79 | var arg = method.arguments[j]; 80 | code += $"\t\t\targs[{j}] = {CreatePropertyInfo(arg.Item1, arg.Item2, 3)}"; 81 | code += $"\t\t\targs_meta[{j}] = GDExtensionClassMethodArgumentMetadata.GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;\n"; 82 | } 83 | } 84 | if (method.ret != null) 85 | { 86 | code += $"\t\t\tvar ret = {CreatePropertyInfo(method.ret, "return", 3)}"; 87 | } 88 | 89 | code += $$""" 90 | var info = new GDExtensionClassMethodInfo() { 91 | name = new StringName("{{Renamer.ToSnake(method.name)}}")._internal_pointer, 92 | method_userdata = (void*)(new IntPtr({{i}})), 93 | call_func = SaftyRapper.GetFunctionPointerForDelegate(CallFunc), 94 | ptrcall_func = SaftyRapper.GetFunctionPointerForDelegate(CallFuncPtr), 95 | method_flags = (uint)GDExtensionClassMethodFlags.GDEXTENSION_METHOD_FLAGS_DEFAULT, 96 | has_return_value = System.Convert.ToByte({{(method.ret != null ? "true" : "false")}}), 97 | return_value_info = {{(method.ret != null ? "&ret" : "null")}}, 98 | return_value_metadata = GDExtensionClassMethodArgumentMetadata.GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE, 99 | argument_count = {{method.arguments.Length}}, 100 | arguments_info = {{(method.arguments.Length > 0 ? "args" : "null")}}, 101 | arguments_metadata = {{(method.arguments.Length > 0 ? "args_meta" : "null")}}, 102 | default_argument_count = 0, 103 | default_arguments = null, 104 | }; 105 | GDExtensionMain.extensionInterface.classdb_register_extension_class_method(GDExtensionMain.library, __godot_name._internal_pointer, info); 106 | """; 107 | code += "\t\t}\n"; 108 | } 109 | 110 | code += $$""" 111 | } 112 | static void CallFuncPtr(void* method_userdata, void* p_instance, void** p_args, void* r_ret) { 113 | var instance = ({{c.Name}})p_instance; 114 | switch ((int)method_userdata) { 115 | """; 116 | for (var i = 0; i < methods.Count; i++) 117 | { 118 | var method = methods[i]; 119 | var args = ""; 120 | for (var j = 0; j < method.arguments.Length; j++) 121 | { 122 | var arg = method.arguments[j]; 123 | if (arg.Item1.Name == "String") 124 | { 125 | args += $"StringMarshall.ToManaged(p_args[{j}])"; 126 | } 127 | else if (TypeToVariantType(arg.Item1) == "Object") 128 | { 129 | args += $"({arg.Item1})GDExtension.Object.ConstructUnknown(*(void**)p_args[{j}])"; 130 | } 131 | else 132 | { 133 | args += $"*({arg.Item1}*)p_args[{j}]"; 134 | } 135 | if (j < method.arguments.Length - 1) 136 | { 137 | args += ", "; 138 | } 139 | } 140 | code += $"\t\tcase {i}:\n\t\t\t"; 141 | if (method.ret != null) 142 | { 143 | if (TypeToVariantType(method.ret) == "Object") 144 | { 145 | code += "throw new NotImplementedException();\n"; 146 | continue; 147 | } 148 | else 149 | { 150 | code += $"*({method.ret}*)r_ret = "; 151 | } 152 | } 153 | if (method.property != null) 154 | { 155 | if (method.ret != null) 156 | { 157 | code += $"instance.{method.property};\n"; 158 | } 159 | else 160 | { 161 | code += $"instance.{method.property} = {args};\n"; 162 | } 163 | } 164 | else 165 | { 166 | code += $"instance.{method.name}({args});\n"; 167 | } 168 | code += $"\t\t\tbreak;\n"; 169 | } 170 | 171 | code += $$""" 172 | } 173 | } 174 | static void CallFunc( 175 | void* method_userdata, 176 | void* p_instance, 177 | void** p_args, 178 | long p_argument_count, 179 | void* r_return, 180 | GDExtensionCallError* r_error 181 | ) { 182 | GDExtensionMain.extensionInterface.variant_new_nil(r_return); 183 | var instance = ({{c.Name}})p_instance; 184 | switch ((int)method_userdata) { 185 | """; 186 | for (var i = 0; i < methods.Count; i++) 187 | { 188 | var method = methods[i]; 189 | var args = ""; 190 | for (var j = 0; j < method.arguments.Length; j++) 191 | { 192 | var arg = method.arguments[j]; 193 | var t = TypeToVariantType(arg.Item1); 194 | args += $"({arg.Item1})Variant.Get{t}FromPointer(p_args[{j}])"; 195 | if (j < method.arguments.Length - 1) 196 | { 197 | args += ", "; 198 | } 199 | } 200 | code += $"\t\tcase {i}: {{\n\t\t\t"; 201 | if (method.ret != null) 202 | { 203 | code += "var res = "; 204 | } 205 | if (method.property != null) 206 | { 207 | if (method.ret != null) 208 | { 209 | code += $"instance.{method.property};\n"; 210 | } 211 | else 212 | { 213 | code += $"instance.{method.property} = {args};\n"; 214 | } 215 | } 216 | else 217 | { 218 | code += $"instance.{method.name}({args});\n"; 219 | } 220 | if (method.ret != null) 221 | { 222 | var t = TypeToVariantType(method.ret); 223 | code += $"\t\t\tVariant.SaveIntoPointer(res, r_return);\n"; 224 | } 225 | code += $"\t\t\tbreak;\n"; 226 | code += "\t\t\t}\n"; 227 | } 228 | 229 | code += $$""" 230 | } 231 | } 232 | } } 233 | """; 234 | 235 | context.AddSource($"{c.Name}.methods.gen.cs", code); 236 | } 237 | 238 | public static string TypeToVariantType(ITypeSymbol type) 239 | { 240 | return TypeToVariantType(type, LibGodotGenerators.GetSpecialBase(type)); 241 | } 242 | 243 | public static string TypeToVariantType(ITypeSymbol type, SpecialBase sBase) 244 | { 245 | return sBase switch 246 | { 247 | SpecialBase.Node => "Object", 248 | SpecialBase.Resource => "Object", 249 | _ => type.Name switch 250 | { 251 | "Boolean" => "Bool", 252 | "Int64" => "Int", 253 | "Double" => "Float", 254 | "String" => "String", 255 | "Vector2" => "Vector2", 256 | "Vector2i" => "Vector2i", 257 | "Rect2" => "Rect2", 258 | "Rect2i" => "Rect2i", 259 | "Vector3" => "Vector3", 260 | "Vector3i" => "Vector3i", 261 | "Transform2D" => "Transform2D", 262 | "Vector4" => "Vector4", 263 | "Vector4i" => "Vector4i", 264 | "Plane" => "Plane", 265 | "Quaternion" => "Quaternion", 266 | "AABB" => "AABB", 267 | "Basis" => "Basis", 268 | "Transform3D" => "Transform3D", 269 | "Projection" => "Projection", 270 | "Color" => "Color", 271 | "StringName" => "StringName", 272 | "NodePath" => "NodePath", 273 | "RID" => "RID", 274 | "Callable" => "Callable", 275 | "Signal" => "Signal", 276 | "Dictionary" => "Dictionary", 277 | "Array" => "Array", 278 | "PackedByteArray" => "PackedByteArray", 279 | "PackedInt32Array" => "PackedInt32Array", 280 | "PackedInt64Array" => "PackedInt64Array", 281 | "PackedFloat32Array" => "PackedFloat32Array", 282 | "PackedFloat64Array" => "PackedFloat64Array", 283 | "PackedStringArray" => "PackedStringArray", 284 | "PackedVector2Array" => "PackedVector2Array", 285 | "PackedVector3Array" => "PackedVector3Array", 286 | "PackedColorArray" => "PackedColorArray", 287 | _ => throw new Exception($"Unknown type: {type.Name}"), 288 | }, 289 | }; 290 | } 291 | 292 | public static string TypeToHintString(ITypeSymbol type, SpecialBase sBase) 293 | { 294 | return sBase switch 295 | { 296 | SpecialBase.Node or SpecialBase.Resource => $"StringMarshall.ToNative(\"{type.Name}\")", 297 | SpecialBase.None => "StringMarshall.ToNative(\"\")", 298 | _ => throw new Exception(), 299 | }; 300 | } 301 | 302 | public static string TypeToHint(ITypeSymbol type, SpecialBase sBase) 303 | { 304 | return sBase switch 305 | { 306 | SpecialBase.Node => "PropertyHint.NodeType", 307 | SpecialBase.Resource => "PropertyHint.ResourceType", 308 | SpecialBase.None => "PropertyHint.None", 309 | _ => throw new Exception(), 310 | }; 311 | } 312 | 313 | public static string CreatePropertyInfo(ITypeSymbol type, string name, int tabs) 314 | { 315 | var sBase = LibGodotGenerators.GetSpecialBase(type); 316 | 317 | var t = new String('\t', tabs); 318 | 319 | return $$""" 320 | new GDExtensionPropertyInfo() { 321 | {{t}} type = (GDExtensionVariantType)Variant.Type.{{TypeToVariantType(type, sBase)}}, 322 | {{t}} name = new StringName("{{Renamer.ToSnake(name)}}")._internal_pointer, 323 | {{t}} class_name = __godot_name._internal_pointer, 324 | {{t}} hint = (uint){{TypeToHint(type, sBase)}}, 325 | {{t}} hint_string = {{TypeToHintString(type, sBase)}}, 326 | {{t}} usage = (uint)PropertyUsageFlags.Default, 327 | {{t}}}; 328 | """; 329 | } 330 | } 331 | } 332 | --------------------------------------------------------------------------------