lyra-wasm-scripting-test/guests/csharp/dotnet-guest-test/ExampleWorldImpl.cs

104 lines
2.9 KiB
C#

namespace ExampleWorld;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using ExampleWorld.wit.imports.lyra.api;
[StructLayout(LayoutKind.Sequential)]
struct Vec3(float x, float y, float z)
{
/// <summary>
/// Unique TypeId of Vec3 that the host can use. This corresponds to the type id of vec3 on the host.
/// </summary>
public const ulong TypeId = 4124409524;
/// <summary>
/// The X component.
/// </summary>
public float X { get; set; } = x;
/// <summary>
/// The Y component
/// </summary>
public float Y { get; set; } = y;
/// <summary>
/// The Z component
/// </summary>
public float Z { get; set; } = z;
}
public class ExampleWorldImpl : IExampleWorld
{
internal struct AlignmentHelper<T> where T : unmanaged
{
public byte Padding;
public T Target;
}
private static int AlignmentOf<T>() where T : unmanaged
{
return (int)Marshal.OffsetOf<AlignmentHelper<T>>(nameof(AlignmentHelper<T>.Target));
}
private static byte[] GetBytes<T>([DisallowNull] T data) {
int size = Marshal.SizeOf(data);
byte[] arr = new byte[size];
IntPtr ptr = IntPtr.Zero;
try
{
ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(data, ptr, true);
Marshal.Copy(ptr, arr, 0, size);
}
finally
{
Marshal.FreeHGlobal(ptr);
}
return arr;
}
private static T? FromBytes<T>(byte[] data) where T : struct
{
var ptr = GCHandle.Alloc(data, GCHandleType.Pinned);
try {
var res = (T?) Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(T));
return res;
} finally {
ptr.Free();
}
}
public static void OnInit(IEcs.EcsWorld gameWorld, IEcs.Entity owningEntity)
{
var size = new IEcs.WasmTypeId((Vec3.TypeId, 0));
var info = new IEcs.ComponentInfo("Vec3", (ulong) Marshal.SizeOf<Vec3>(), (ulong) AlignmentOf<Vec3>(), size);
var pos = new Vec3(7.0f, 30.0f, 18.0f);
var infos = new List<IEcs.ComponentInfo>
{
info
};
IEcs.Entity entity = gameWorld.Spawn(GetBytes(pos), infos);
Console.WriteLine("C#: Spawned {0}", entity.id.id);
IEcs.EcsDynamicView res = gameWorld.View(infos);
(IEcs.Entity, byte[])? row = res.Next();
if (row.HasValue) {
Console.WriteLine("C#: Found position!!!");
var en = row.Value.Item1;
var comp = FromBytes<Vec3>(row.Value.Item2);
Console.WriteLine("C#: Found component at ({0}, {1}, {2})", comp?.X, comp?.Y, comp?.Z);
} else {
Console.WriteLine("C#: Could not find position");
}
}
public static void OnUpdate(IEcs.EcsWorld gameWorld, IEcs.Entity owningEntity)
{
throw new NotImplementedException();
}
}