From 62c85e9e1f5dfad8f81a59c050feca200d13d4a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Fri, 21 Jul 2023 22:23:31 +0200 Subject: [PATCH] Start CoreClr from Beef and basic interaction --- BeefSpace.toml | 4 +- .../Assets/Scripts/MyTestEntity.cs | 61 ++++---- .../Assets/Scripts/Properties/AssemblyInfo.cs | 36 ----- .../Scripts/Properties/launchSettings.json | 10 ++ .../Assets/Scripts/Sandbox - Kopie.csproj | 57 ++++++++ .../Assets/Scripts/Sandbox.csproj | 65 ++------- .../Assets/Scripts/TestClass.cs | 29 ++++ GlitchyEngine/BeefProj.toml | 2 +- GlitchyEngine/src/Scripting/CoreClrHelper.bf | 133 ++++++++++++++++++ GlitchyEngine/src/Scripting/ScriptEngine.bf | 82 ++++++----- GlitchyEngine/src/Scripting/ScriptGlue.bf | 21 ++- ScriptCore/Log.cs | 8 +- ScriptCore/ScriptCore.csproj | 13 +- ScriptCore/ScriptGlue.cs | 50 +++++++ 14 files changed, 393 insertions(+), 178 deletions(-) delete mode 100644 GlitchyEditor/SandboxProject/Assets/Scripts/Properties/AssemblyInfo.cs create mode 100644 GlitchyEditor/SandboxProject/Assets/Scripts/Properties/launchSettings.json create mode 100644 GlitchyEditor/SandboxProject/Assets/Scripts/Sandbox - Kopie.csproj create mode 100644 GlitchyEditor/SandboxProject/Assets/Scripts/TestClass.cs create mode 100644 GlitchyEngine/src/Scripting/CoreClrHelper.bf diff --git a/BeefSpace.toml b/BeefSpace.toml index eb3b248..f8385f9 100644 --- a/BeefSpace.toml +++ b/BeefSpace.toml @@ -1,7 +1,7 @@ FileVersion = 1 -Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}, "Beef.Linq" = {Path = "GlitchyEngine/vendor/Beef.Linq/src"}, ScriptCore = {Path = "ScriptCore"}} +Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}, "Beef.Linq" = {Path = "GlitchyEngine/vendor/Beef.Linq/src"}, ScriptCore = {Path = "ScriptCore"}, NetHostBeef = {Path = "GlitchyEngine/vendor/NetHostBeef/NetHostBeef"}} Unlocked = ["corlib"] -WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper", "ScriptCore"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef", "Beef.Linq"]} +WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper", "ScriptCore"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef", "Beef.Linq", "NetHostBeef"]} [Workspace] StartupProject = "GlitchyEditor" diff --git a/GlitchyEditor/SandboxProject/Assets/Scripts/MyTestEntity.cs b/GlitchyEditor/SandboxProject/Assets/Scripts/MyTestEntity.cs index c9a7284..da16d3d 100644 --- a/GlitchyEditor/SandboxProject/Assets/Scripts/MyTestEntity.cs +++ b/GlitchyEditor/SandboxProject/Assets/Scripts/MyTestEntity.cs @@ -1,5 +1,4 @@ using System; -using System.Runtime.Remoting.Metadata.W3cXsd2001; using GlitchyEngine; using GlitchyEngine.Editor; using GlitchyEngine.Math; @@ -66,14 +65,14 @@ namespace Sandbox Log.Info($"Jump Force: {JumpForce}"); - _rigidBody ??= GetComponent() ?? AddComponent(); + //_rigidBody ??= GetComponent() ?? AddComponent(); - Camera = FindEntityWithName("Camera").As(); + //Camera = FindEntityWithName("Camera").As(); - if (Camera == null) - { - Log.Error("Camera not found."); - } + //if (Camera == null) + //{ + // Log.Error("Camera not found."); + //} } /// @@ -82,36 +81,38 @@ namespace Sandbox /// void OnUpdate(float deltaTime) { - float2 force = float2.Zero; + Log.Info($"On update: {deltaTime}"); - if (Input.IsKeyPressed(Key.A)) - { - force.X -= MoveForce * deltaTime; - } + //float2 force = float2.Zero; - if (Input.IsKeyPressed(Key.D)) - { - force.X += MoveForce * deltaTime; - } + //if (Input.IsKeyPressed(Key.A)) + //{ + // force.X -= MoveForce * deltaTime; + //} - if (Input.IsKeyPressed(Key.Q)) - Camera.DistanceFromPlayer -= deltaTime; + //if (Input.IsKeyPressed(Key.D)) + //{ + // force.X += MoveForce * deltaTime; + //} - if (Input.IsKeyPressed(Key.E)) - Camera.DistanceFromPlayer += deltaTime; + //if (Input.IsKeyPressed(Key.Q)) + // Camera.DistanceFromPlayer -= deltaTime; - if (Input.IsKeyPressing(Key.Space)) - { - force.Y += JumpForce; - } + //if (Input.IsKeyPressed(Key.E)) + // Camera.DistanceFromPlayer += deltaTime; - _rigidBody.ApplyForceToCenter(force); + //if (Input.IsKeyPressing(Key.Space)) + //{ + // force.Y += JumpForce; + //} - if (Input.IsMouseButtonReleasing(MouseButton.MiddleButton)) - { - Log.Info($"Ouha! {MyNumber}"); - Physics2D.Gravity *= new float2(1, -1); - } + //_rigidBody.ApplyForceToCenter(force); + + //if (Input.IsMouseButtonReleasing(MouseButton.MiddleButton)) + //{ + // Log.Info($"Ouha! {MyNumber}"); + // Physics2D.Gravity *= new float2(1, -1); + //} } /// diff --git a/GlitchyEditor/SandboxProject/Assets/Scripts/Properties/AssemblyInfo.cs b/GlitchyEditor/SandboxProject/Assets/Scripts/Properties/AssemblyInfo.cs deleted file mode 100644 index 1e0009f..0000000 --- a/GlitchyEditor/SandboxProject/Assets/Scripts/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// Allgemeine Informationen über eine Assembly werden über die folgenden -// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, -// die einer Assembly zugeordnet sind. -[assembly: AssemblyTitle("Sanbox")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Sanbox")] -[assembly: AssemblyCopyright("Copyright © 2023")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly -// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von -// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen. -[assembly: ComVisible(false)] - -// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird -[assembly: Guid("7a70819c-5317-402a-8553-95c5a001e370")] - -// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: -// -// Hauptversion -// Nebenversion -// Buildnummer -// Revision -// -// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden, -// indem Sie "*" wie unten gezeigt eingeben: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/GlitchyEditor/SandboxProject/Assets/Scripts/Properties/launchSettings.json b/GlitchyEditor/SandboxProject/Assets/Scripts/Properties/launchSettings.json new file mode 100644 index 0000000..6bc43e2 --- /dev/null +++ b/GlitchyEditor/SandboxProject/Assets/Scripts/Properties/launchSettings.json @@ -0,0 +1,10 @@ +{ + "profiles": { + "Start Editor": { + "commandName": "Executable", + "executablePath": "D:\\Development\\Projects\\Beef\\GlitchyEngine\\build\\Debug_Win64\\GlitchyEditor\\GlitchyEditor.exe", + "workingDirectory": "D:\\Development\\Projects\\Beef\\GlitchyEngine\\GlitchyEditor", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/GlitchyEditor/SandboxProject/Assets/Scripts/Sandbox - Kopie.csproj b/GlitchyEditor/SandboxProject/Assets/Scripts/Sandbox - Kopie.csproj new file mode 100644 index 0000000..962460b --- /dev/null +++ b/GlitchyEditor/SandboxProject/Assets/Scripts/Sandbox - Kopie.csproj @@ -0,0 +1,57 @@ + + + + + Debug + AnyCPU + {7A70819C-5317-402A-8553-95C5A001E370} + Library + Properties + Sandbox + Sandbox + v4.7.2 + 512 + true + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + default + + + pdbonly + true + bin\ + TRACE + prompt + 4 + default + + + + + + + + + + + + + + + + + + + {6222c226-fc78-498c-80ba-5cf10ac9123c} + ScriptCore + + + + \ No newline at end of file diff --git a/GlitchyEditor/SandboxProject/Assets/Scripts/Sandbox.csproj b/GlitchyEditor/SandboxProject/Assets/Scripts/Sandbox.csproj index 962460b..f0e4197 100644 --- a/GlitchyEditor/SandboxProject/Assets/Scripts/Sandbox.csproj +++ b/GlitchyEditor/SandboxProject/Assets/Scripts/Sandbox.csproj @@ -1,57 +1,16 @@ - - - + - Debug - AnyCPU - {7A70819C-5317-402A-8553-95C5A001E370} - Library - Properties - Sandbox - Sandbox - v4.7.2 - 512 - true - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - default - - - pdbonly - true - bin\ - TRACE - prompt - 4 - default + net7.0 + latest + bin + true + + true + true + false - - - - - - - - + - - - - - - - - {6222c226-fc78-498c-80ba-5cf10ac9123c} - ScriptCore - - - - \ No newline at end of file + + diff --git a/GlitchyEditor/SandboxProject/Assets/Scripts/TestClass.cs b/GlitchyEditor/SandboxProject/Assets/Scripts/TestClass.cs new file mode 100644 index 0000000..b68ff32 --- /dev/null +++ b/GlitchyEditor/SandboxProject/Assets/Scripts/TestClass.cs @@ -0,0 +1,29 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using GlitchyEngine; + +namespace Sandbox; + +public static class TestClass +{ + [UnmanagedCallersOnly] + public static void TestFunction() + { + Console.WriteLine("Hello from the second Assembly!"); + } + + public static void InternalTest() + { + Console.WriteLine("Ja, ich existiere in der Tat"); + + Log.Info("Yeah!"); + //Console.WriteLine("Und nun bin ich anders"); + } + + public static int Test(IntPtr arg, int sizeofArg) + { + Console.WriteLine($"YUPPYPLASDPASDOIUZASD"); + return 7; + } +} diff --git a/GlitchyEngine/BeefProj.toml b/GlitchyEngine/BeefProj.toml index 112c99d..3870305 100644 --- a/GlitchyEngine/BeefProj.toml +++ b/GlitchyEngine/BeefProj.toml @@ -1,5 +1,5 @@ FileVersion = 1 -Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", FreeType = "*", cgltf-beef = "*", msdfgen-beef = "*", ImGui = "*", ImGuiImplDX11 = "*", ImGuiImplWin32 = "*", ImGuizmo = "*", Beefy2D = "*", LodePng = "*", GlitchyEngineHelper = "*", bon = "*", box2d-beef = "*", "Beef.Linq" = "*"} +Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", FreeType = "*", cgltf-beef = "*", msdfgen-beef = "*", ImGui = "*", ImGuiImplDX11 = "*", ImGuiImplWin32 = "*", ImGuizmo = "*", Beefy2D = "*", LodePng = "*", GlitchyEngineHelper = "*", bon = "*", box2d-beef = "*", "Beef.Linq" = "*", NetHostBeef = "*"} [Project] Name = "GlitchyEngine" diff --git a/GlitchyEngine/src/Scripting/CoreClrHelper.bf b/GlitchyEngine/src/Scripting/CoreClrHelper.bf new file mode 100644 index 0000000..69446fe --- /dev/null +++ b/GlitchyEngine/src/Scripting/CoreClrHelper.bf @@ -0,0 +1,133 @@ +using NetHostBeef; +using System; +using System.Interop; + +namespace GlitchyEngine.Scripting; + +static class CoreClrHelper +{ + static HostFxr.InitializeForDotnetCommandLineFn HostFxr_Init; + static HostFxr.GetRuntimeDelegateFn HostFxr_GetDelegate; + static HostFxr.CloseFn HostFxr_Close; + + static CoreClr.LoadAssemblyAndGetFunctionPointerFn LoadAssemblyAndGetFunctionPointerFn; + static CoreClr.GetFunctionPointerFn GetFunctionPointerFn; + + private function void LoadScriptAssemblyFunc(uint8* appData, int64 appLength, uint8* pdbData, int64 pdbLength); + + //static function void(char8* path) LoadScriptAssembly; + static LoadScriptAssemblyFunc _loadScriptAssembly; + static function void() _unloadAssemblies; + + public static void Init(StringView coreAssemblyPath) + { + LoadHostFxr(); + InitAndStartRuntime(coreAssemblyPath); + + PrepareFunction(); + } + + static void LoadHostFxr() + { + char_t[256] buffer = ?; + c_size bufferSize = buffer.Count; + int rc = NetHost.get_hostfxr_path(&buffer, &bufferSize, null); + + Log.EngineLogger.AssertDebug(rc == 0, "Failed to get HostFxr path."); + + // Load hostfxr and get desired exports + void* lib = NetHostHelper.LoadLibrary(&buffer); + HostFxr_Init = NetHostHelper.GetExport(lib, "hostfxr_initialize_for_dotnet_command_line"); + HostFxr_GetDelegate = NetHostHelper.GetExport(lib, "hostfxr_get_runtime_delegate"); + HostFxr_Close = NetHostHelper.GetExport(lib, "hostfxr_close"); + + Log.EngineLogger.AssertDebug(HostFxr_Init != null && HostFxr_GetDelegate != null && HostFxr_Close != null, "Retrieving at least one HostFxr function failed."); + } + + static void InitAndStartRuntime(StringView coreAssembly) + { + char_t* ptr = NetHostHelper.GetScopedRawPtr!(coreAssembly); + + char_t*[2] args = char_t*[]( + ptr, + null + ); + + HostFxr.Handle cxt = null; + int rc = HostFxr_Init(1, &args, null, &cxt); + + if (rc != 0 || cxt == null) + { + Log.EngineLogger.Error($"Failed to initialize HostFxr: {rc}"); + HostFxr_Close(cxt); + } + + Log.EngineLogger.Assert(rc == 0, "Failed to initialize HostFxr."); + + rc = HostFxr_GetDelegate(cxt, .LoadAssemblyAndGetFunctionPointer, (void**)&LoadAssemblyAndGetFunctionPointerFn); + + Log.EngineLogger.Assert(rc == 0, scope $"Get delegate failed: {rc}. (LoadAssemblyAndGetFunctionPointer)"); + + rc = HostFxr_GetDelegate(cxt, .GetFunctionPointer, (void**)&GetFunctionPointerFn); + + Log.EngineLogger.Assert(rc == 0, scope $"Get delegate failed: {rc}. (GetFunctionPointer)"); + + HostFxr_Close(cxt); + } + + static void PrepareFunction() + { + GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "LoadScriptAssembly", + out _loadScriptAssembly); + + GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "UnloadAssemblies", + out _unloadAssemblies); + } + + public static void LoadAppAssembly(Span appAssemblyData, Span pdbData) + { + _loadScriptAssembly(appAssemblyData.Ptr, appAssemblyData.Length, pdbData.Ptr, pdbData.Length); + } + + public static void UnloadAssemblies() + { + _unloadAssemblies(); + } + + public static int GetFunctionPointer(StringView typeName, StringView methodName, StringView delegateName, out T outDelegate) where T: operator explicit void* + { + void* funPtr = null; + + int rc = GetFunctionPointerFn(NetHostHelper.GetScopedRawPtr!(typeName), + NetHostHelper.GetScopedRawPtr!(methodName), NetHostHelper.GetScopedRawPtr!(delegateName), + null, null, out funPtr); + + outDelegate = (T)funPtr; + + return rc; + } + + public static int GetFunctionPointerDefaultDelegate(StringView typeName, StringView methodName, out CoreClr.DefaultEntryPoint outDelegate) + { + void* funPtr = null; + + int rc = GetFunctionPointerFn(NetHostHelper.GetScopedRawPtr!(typeName), + NetHostHelper.GetScopedRawPtr!(methodName), null, null, null, out funPtr); + + outDelegate = (CoreClr.DefaultEntryPoint)funPtr; + + return rc; + } + + public static int GetFunctionPointerUnmanagedCallersOnly(StringView typeName, StringView methodName, out T outDelegate) where T: operator explicit void* + { + void* funPtr = null; + + int rc = GetFunctionPointerFn(NetHostHelper.GetScopedRawPtr!(typeName), + NetHostHelper.GetScopedRawPtr!(methodName), CoreClr.UNMANAGEDCALLERSONLY_METHOD, null, null, out funPtr); + + outDelegate = (T)funPtr; + + return rc; + } +} diff --git a/GlitchyEngine/src/Scripting/ScriptEngine.bf b/GlitchyEngine/src/Scripting/ScriptEngine.bf index bee290d..8277169 100644 --- a/GlitchyEngine/src/Scripting/ScriptEngine.bf +++ b/GlitchyEngine/src/Scripting/ScriptEngine.bf @@ -5,6 +5,8 @@ using System.Collections; using GlitchyEngine.Core; using GlitchyEngine.Math; using GlitchyEngine.World; +using NetHostBeef; +using System.Interop; namespace GlitchyEngine.Scripting; @@ -96,49 +98,32 @@ static class ScriptEngine { internal static MonoClass* s_ShowInEditorAttribute; } + + private static String _coreAssemblyPath = "resources/scripts/ScriptCore.dll"; + private static String _appAssemblyPath = "SandboxProject/Assets/Scripts/bin/Sandbox.dll"; public static void Init() { - InitMono(); - ScriptGlue.Init(); + CoreClrHelper.Init(_coreAssemblyPath); + + //ScriptGlue.Init(); - LoadScriptAssemblies(); + LoadScriptAssembly(); InitAssemblyWatcher(); } - static void InitMono() - { - Mono.mono_set_assemblies_path("mono/lib"); - - if (_debuggingEnabled) - { - char8*[2] options = .( - "--debugger-agent=transport=dt_socket,address=127.0.0.1:2550,server=y,suspend=n,loglevel=3,logfile=MonoDebugger.log", - "--soft-breakpoints" - ); - - Mono.mono_jit_parse_options(options.Count, &options); - Mono.mono_debug_init(.Mono); - } - - s_RootDomain = Mono.mono_jit_init("GlitchyEngineJITRuntime"); - Log.EngineLogger.Assert(s_RootDomain != null, "Failed to initialize mono root domain"); - - if (_debuggingEnabled) - { - Mono.mono_debug_domain_create(s_RootDomain); - } - - Mono.mono_thread_set_main(Mono.mono_thread_current()); - } - static void InitAssemblyWatcher() { if (_userAssemblyWatcher == null) { + String directoryPath = scope String(); + Path.GetDirectoryPath(_appAssemblyPath, directoryPath); + String fileName = scope String(); + Path.GetFileName(_appAssemblyPath, fileName); + // TODO: Obviously don't hardcode path - _userAssemblyWatcher = new FileSystemWatcher("SandboxProject/Assets/Scripts/bin/", "*/Sandbox.dll"); + _userAssemblyWatcher = new FileSystemWatcher(directoryPath, fileName); _userAssemblyWatcher.OnChanged.Add(new (fileName) => { // TODO: Temporary, we want to be able to reload while in play-mode. (+ Editor Scripts will be a thing some day) @@ -165,7 +150,7 @@ static class ScriptEngine _userAssemblyWatcher.StartRaisingEvents(); } - static void LoadScriptAssemblies() + /*static void LoadScriptAssemblies() { CreateAppDomain("GlitchyEngineScriptRuntime"); (s_CoreAssembly, s_CoreAssemblyImage) = LoadAssembly("resources/scripts/ScriptCore.dll", _debuggingEnabled); @@ -174,6 +159,28 @@ static class ScriptEngine GetEntitiesFromAssemblies(); ScriptGlue.RegisterManagedComponents(); + }*/ + + static void LoadScriptAssembly() + { + List data = new List(1024); + File.ReadAll(_appAssemblyPath, data); + + List pdbData = new List(1024); + + String pdbPath = scope .(); + Path.ChangeExtension(_appAssemblyPath, ".pdb", pdbPath); + + File.ReadAll(pdbPath, pdbData); + + CoreClrHelper.LoadAppAssembly(data, pdbData); + + delete data; + delete pdbData; + + //GetEntitiesFromAssemblies(); + + //ScriptGlue.RegisterManagedComponents(); } public static void SetContext(Scene scene) @@ -351,11 +358,14 @@ static class ScriptEngine { Debug.Profiler.ProfileFunction!(); - Mono.mono_domain_set(s_RootDomain, false); + CoreClrHelper.UnloadAssemblies(); + LoadScriptAssembly(); - Mono.mono_domain_unload(s_AppDomain); + //Mono.mono_domain_set(s_RootDomain, false); - LoadScriptAssemblies(); + //Mono.mono_domain_unload(s_AppDomain); + + //LoadScriptAssemblies(); // TODO: ScriptFields might get added // TODO: ScriptField Types may change after reload! @@ -367,13 +377,13 @@ static class ScriptEngine public static void Shutdown() { - Mono.mono_domain_set(s_RootDomain, false); + /*Mono.mono_domain_set(s_RootDomain, false); Mono.mono_domain_unload(s_AppDomain); s_AppDomain = null; Mono.mono_jit_cleanup(s_RootDomain); - s_RootDomain = null; + s_RootDomain = null;*/ } internal static void RegisterSharpType(SharpType sharpType) diff --git a/GlitchyEngine/src/Scripting/ScriptGlue.bf b/GlitchyEngine/src/Scripting/ScriptGlue.bf index 4551dc5..78e5c4a 100644 --- a/GlitchyEngine/src/Scripting/ScriptGlue.bf +++ b/GlitchyEngine/src/Scripting/ScriptGlue.bf @@ -29,7 +29,7 @@ static class ScriptGlue } } - /* Adding this attribute to a method will log method entry and returned Result errors */ + /*/* Adding this attribute to a method will log method entry and returned Result errors */ [AttributeUsage(.Method)] struct RegisterMethodAttribute : Attribute, IOnMethodInit { @@ -48,13 +48,13 @@ static class ScriptGlue } } } - } + }*/ public static void Init() { - RegisterCalls(); + //RegisterCalls(); - RegisterMathFunctions(); + //RegisterMathFunctions(); } public static void RegisterManagedComponents() @@ -67,11 +67,11 @@ static class ScriptGlue RegisterComponent("GlitchyEngine.RigidBody2D"); } - [RegisterMethod] + /*[RegisterMethod] private static void RegisterCalls() { // Generated at CompTime - } + }*/ private static void RegisterComponent(StringView cSharpClassName = "") where T : struct, new { @@ -104,13 +104,10 @@ static class ScriptGlue } [RegisterCall("Log::LogMessage_Impl")] - static void Log(int32 logLevel, MonoString* message) + [Export, LinkName("Log::LogMessage_Impl"), CallingConvention(.Cdecl)] + static void Log(int32 logLevel, char8* message) { - char8* utfMessage = Mono.mono_string_to_utf8(message); - - Log.ClientLogger.Log((LogLevel)logLevel, StringView(utfMessage)); - - Mono.mono_free(utfMessage); + Log.ClientLogger.Log((LogLevel)logLevel, StringView(message)); } #region Input diff --git a/ScriptCore/Log.cs b/ScriptCore/Log.cs index 05cc533..a6dba64 100644 --- a/ScriptCore/Log.cs +++ b/ScriptCore/Log.cs @@ -1,4 +1,5 @@ using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace GlitchyEngine; @@ -44,7 +45,8 @@ public class Log { LogMessage_Impl(LogLevel.Critical, message); } - - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern string LogMessage_Impl(LogLevel logLevel, string message); + + //[MethodImpl(MethodImplOptions.InternalCall)] + [DllImport("GlitchyEditor.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Log::LogMessage_Impl")] + public static extern void LogMessage_Impl(LogLevel logLevel, string message); } diff --git a/ScriptCore/ScriptCore.csproj b/ScriptCore/ScriptCore.csproj index 402ac00..dc17ab4 100644 --- a/ScriptCore/ScriptCore.csproj +++ b/ScriptCore/ScriptCore.csproj @@ -1,20 +1,23 @@  - netstandard2.0 + net7.0 latest true + + true + true + True + enable + + - - - - diff --git a/ScriptCore/ScriptGlue.cs b/ScriptCore/ScriptGlue.cs index 2d3b54e..ec1c70a 100644 --- a/ScriptCore/ScriptGlue.cs +++ b/ScriptCore/ScriptGlue.cs @@ -1,5 +1,11 @@ using System; +using System.Diagnostics; +using System.IO; +using System.Net.Security; +using System.Reflection; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Loader; using GlitchyEngine.Core; using GlitchyEngine.Math; @@ -74,5 +80,49 @@ internal static class ScriptGlue internal static extern float4 modf_float4(float4 x, out float4 integerPart); #endregion + + private static AssemblyLoadContext? _scriptAssemblyContext; + private static Assembly? _appAssembly; + + [UnmanagedCallersOnly] + public static unsafe void LoadScriptAssembly(byte* assemblyData, long assemblyLength, byte* pdbData, long pdbLength) + { + using UnmanagedMemoryStream assemblyStream = new(assemblyData, assemblyLength); + + using UnmanagedMemoryStream? pdbStream = (pdbData != null) ? new UnmanagedMemoryStream(pdbData, pdbLength) : null; + + LoadAssembly(assemblyStream, pdbStream); + } + + private static void LoadAssembly(Stream assemblyStream, Stream? pdbStream)//(string path) + { + try + { + _scriptAssemblyContext ??= new AssemblyLoadContext("ScriptContext", true); + + _appAssembly = _scriptAssemblyContext.LoadFromStream(assemblyStream, pdbStream); + + Debug.Assert(_appAssembly != null); + + // Test the loaded assembly + _appAssembly.GetType("Sandbox.TestClass")?.GetMethod("InternalTest")?.Invoke(null, null); + } + catch (Exception e) + { + Console.WriteLine($"Fehler: {e}"); + } + } + + [UnmanagedCallersOnly] + public static void UnloadAssemblies() + { + UnloadContext(); + } + + private static void UnloadContext() + { + _scriptAssemblyContext?.Unload(); + _scriptAssemblyContext = null; + } }