Even more DotNet stuff, help

This commit is contained in:
Simon Lübeß
2022-04-26 22:36:27 +02:00
parent ad1b37dc64
commit 8c53f21690
14 changed files with 821 additions and 63 deletions
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<!--<EnableDynamicLoading>true</EnableDynamicLoading>-->
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<BaseOutputPath></BaseOutputPath>
<DebugType>embedded</DebugType>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
</Project>
@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32328.378
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetScriptingHelper", "DotNetScriptingHelper.csproj", "{4B439162-2FA7-494E-A459-8F6D34FED80C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4B439162-2FA7-494E-A459-8F6D34FED80C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4B439162-2FA7-494E-A459-8F6D34FED80C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B439162-2FA7-494E-A459-8F6D34FED80C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4B439162-2FA7-494E-A459-8F6D34FED80C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {968CFBCF-61D9-404C-83CC-0F616E89DA10}
EndGlobalSection
EndGlobal
@@ -0,0 +1,23 @@
namespace DotNetScriptingHelper;
public readonly struct EcsEntity
{
// Binary Format:
// Bits: [0 - 31] [32 - 64]
// Data: Version Index
private readonly ulong _id;
internal uint Version => (uint)_id;
internal uint Index => (uint)(_id >> 32);
public EcsEntity(uint index, uint version)
{
_id = ((ulong)index << 32) | version;
}
public bool IsValid => Index != InvalidEntity.Index;
public static readonly EcsEntity InvalidEntity = new(uint.MaxValue, 0);
}
@@ -0,0 +1,16 @@
namespace DotNetScriptingHelper;
public struct Entity
{
public EcsEntity Handle { get; private set; }
// TODO: Scene
public bool IsValid => Handle.IsValid;
public Entity(EcsEntity handle)
{
Handle = handle;
}
// TODO: Get Parent, Children
}
@@ -0,0 +1,91 @@
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
namespace DotNetScriptingHelper;
public class InteropHelper
{
struct CreateArgs
{
public IntPtr Ptr;
public int Length;
public string ManagedCopy => Marshal.PtrToStringUTF8(Ptr, Length);
}
//[UnmanagedCallersOnly]
public static int SomeMethod(IntPtr args, int argLength)
{
Debug.WriteLine(typeof(InteropHelper).AssemblyQualifiedName);
return 5;
}
[UnmanagedCallersOnly]
public static IntPtr CreateInstance(IntPtr args, int argLength)
{
try
{
Debug.Assert(Marshal.SizeOf<CreateArgs>() == argLength, "Provided argument has wrong size.");
CreateArgs createArgs = Marshal.PtrToStructure<CreateArgs>(args);
string str = createArgs.ManagedCopy;
Console.WriteLine($"Trying to get type \"{str}\"");
Type? type = Type.GetType(createArgs.ManagedCopy, true);
if (type == null)
{
Console.WriteLine("Type was null.");
return IntPtr.Zero;
}
object? instance = Activator.CreateInstance(type);
if (instance == null)
return IntPtr.Zero;
GCHandle handle = GCHandle.Alloc(instance);
return GCHandle.ToIntPtr(handle);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
[UnmanagedCallersOnly]
public static void CallMethod(IntPtr instance, IntPtr methodName, int methodNameLength)
{
GCHandle handle = GCHandle.FromIntPtr(instance);
if (handle.Target == null)
throw new Exception("Handle has no target?");
Type type = handle.Target.GetType();
string name = Marshal.PtrToStringUTF8(methodName, methodNameLength);
MethodInfo? mi = type.GetMethod(name);
if (mi == null)
throw new Exception("MethodInfo is null.");
mi.Invoke(handle.Target, null);
}
public delegate void FreeInstanceEntryPoint(IntPtr instance);
[UnmanagedCallersOnly]
public static void FreeInstance(IntPtr instance)
{
GCHandle handle = GCHandle.FromIntPtr(instance);
handle.Free();
}
}
@@ -0,0 +1,59 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace DotNetScriptingHelper;
public abstract class ScriptableEntity
{
internal Entity Entity;
public virtual void OnCreate() { }
protected virtual void OnDestroy() { }
protected virtual void OnUpdate() { }
[UnmanagedCallersOnly]
public static void UpdateEntity(IntPtr entityPtr)
{
GCHandle entityHandle = GCHandle.FromIntPtr(entityPtr);
if (entityHandle.Target is ScriptableEntity entity)
{
entity.OnUpdate();
}
}
[UnmanagedCallersOnly]
public static IntPtr CreateInstance(IntPtr typeNamePtr, int typeNameLength, EcsEntity entity)
{
try
{
string typeName = Marshal.PtrToStringUTF8(typeNamePtr, typeNameLength);
Type? type = Type.GetType(typeName, true);
if (type == null)
return IntPtr.Zero;
object? instance = Activator.CreateInstance(type);
if (type == null)
return IntPtr.Zero;
Debug.Assert(instance is ScriptableEntity, "Activated instance doesn't inherit from ScriptableEntity");
if (instance is not ScriptableEntity scriptableEntity)
return IntPtr.Zero;
scriptableEntity.Entity = new Entity(entity);
scriptableEntity.OnCreate();
GCHandle handle = GCHandle.Alloc(instance);
return GCHandle.ToIntPtr(handle);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
@@ -0,0 +1,13 @@
using System.Diagnostics;
namespace DotNetScriptingHelper;
public class TestEntityScript : ScriptableEntity
{
public int Inty = 1337;
protected override void OnUpdate()
{
Debug.WriteLine($"My Number is {Inty++}");
}
}