csharp: implement ecs world resources
This commit is contained in:
parent
1d97046195
commit
3245b4dad4
|
@ -1,39 +1,10 @@
|
|||
namespace ExampleWorld;
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using ExampleWorld.wit.imports.lyra.api;
|
||||
using LyraApi;
|
||||
|
||||
using LyraApi.Ecs;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct Vec3(float x, float y, float z) : IComponent
|
||||
{
|
||||
/// <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 static string HostName => "Vec3";
|
||||
public static ulong HostSize => (ulong)Marshal.SizeOf<Vec3>();
|
||||
public static ulong HostAlignment => (ulong)MarshalUtils.AlignmentOf<Vec3>();
|
||||
public static ulong TypeId => 4124409524;
|
||||
|
||||
public static object? TakeFromBytes(byte[] bytes)
|
||||
{
|
||||
byte[] taken = bytes.Take((int)HostSize).ToArray();
|
||||
return MarshalUtils.FromBytes<Vec3>(taken);
|
||||
}
|
||||
}
|
||||
using LyraApi.Engine;
|
||||
using LyraApi.Math;
|
||||
|
||||
public class ExampleWorldImpl : IExampleWorld
|
||||
{
|
||||
|
@ -47,6 +18,11 @@ public class ExampleWorldImpl : IExampleWorld
|
|||
{
|
||||
Console.WriteLine("C#: Found entity at ({0}, {1}, {2})", comp.X, comp.Y, comp.Z);
|
||||
}
|
||||
|
||||
DeltaTime? dt = world.GetResource<DeltaTime>();
|
||||
if (dt != null) {
|
||||
Console.WriteLine($"C#: Delta time: {dt?.Seconds:0.##}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnUpdate(IEcs.EcsWorld gameWorld, IEcs.Entity owningEntity)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
using static ExampleWorld.wit.imports.lyra.api.IEcs;
|
||||
|
||||
namespace LyraApi.Ecs;
|
||||
|
||||
public interface IResource
|
||||
{
|
||||
public abstract static ulong TypeId { get; }
|
||||
|
||||
public abstract static object? FromWasmResult(WorldResourceResult result);
|
||||
}
|
|
@ -27,4 +27,10 @@ public class World(IEcs.EcsWorld world)
|
|||
IEcs.EcsDynamicView dynamicView = Inner.View(infos);
|
||||
return new ViewResult(comps, dynamicView).Get<T1>();
|
||||
}
|
||||
|
||||
public T? GetResource<T>() where T : IResource
|
||||
{
|
||||
IEcs.WorldResourceResult result = Inner.GetResource(Utils.ToWasmTypeId(T.TypeId));
|
||||
return (T?) T.FromWasmResult(result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using LyraApi;
|
||||
using LyraApi.Ecs;
|
||||
using static ExampleWorld.wit.imports.lyra.api.IEcs;
|
||||
|
||||
namespace LyraApi.Engine;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DeltaTime : IResource {
|
||||
public float Seconds;
|
||||
|
||||
public static ulong TypeId => 83716348954;
|
||||
|
||||
public static object? FromWasmResult(WorldResourceResult result)
|
||||
{
|
||||
return result.Tag switch
|
||||
{
|
||||
WorldResourceResult.NONE | WorldResourceResult.WASM_RESOURCE_REP => null,
|
||||
WorldResourceResult.BYTES => MarshalUtils.FromBytes<DeltaTime>(result.AsBytes),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using LyraApi.Ecs;
|
||||
|
||||
namespace LyraApi.Math;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct Vec3(float x, float y, float z) : IComponent
|
||||
{
|
||||
/// <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 static string HostName => "Vec3";
|
||||
public static ulong HostSize => (ulong)Marshal.SizeOf<Vec3>();
|
||||
public static ulong HostAlignment => (ulong)MarshalUtils.AlignmentOf<Vec3>();
|
||||
public static ulong TypeId => 4124409524;
|
||||
|
||||
public static object? TakeFromBytes(byte[] bytes)
|
||||
{
|
||||
byte[] taken = bytes.Take((int)HostSize).ToArray();
|
||||
return MarshalUtils.FromBytes<Vec3>(taken);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
using static ExampleWorld.wit.imports.lyra.api.IEcs;
|
||||
|
||||
internal static class Utils {
|
||||
public static WasmTypeId ToWasmTypeId(ulong typeId)
|
||||
{
|
||||
return new WasmTypeId((typeId, 0));
|
||||
}
|
||||
}
|
|
@ -18,12 +18,12 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<!-- Copy WIT files from LyraApi to lyra-api wit folder. -->
|
||||
<!-- <Target Name="CopyFolderOnBuild" BeforeTargets="WitCompile_InvokeTool">
|
||||
<Target Name="CopyFolderOnBuild" BeforeTargets="WitCompile_InvokeTool">
|
||||
<ItemGroup>
|
||||
<MyFiles Include="..\LyraApi\wit\**\*.wit" />
|
||||
<MyFiles Include="..\..\rust\common-api\wit\**\*.wit" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(MyFiles)" DestinationFolder="wit\deps\lyraapi\%(RecursiveDir)" />
|
||||
</Target> -->
|
||||
</Target>
|
||||
|
||||
<!-- Remove bindgen of LyraApi WIT .-->
|
||||
<!-- <Target Name="RemoveBindgenLyraApi" AfterTargets="WitCompile_InvokeTool">
|
||||
|
|
|
@ -37,6 +37,12 @@ interface ecs {
|
|||
next: func() -> option<tuple<entity, list<u8>>>;
|
||||
}
|
||||
|
||||
variant world-resource-result {
|
||||
none,
|
||||
wasm-resource-rep(u32),
|
||||
bytes(list<u8>),
|
||||
}
|
||||
|
||||
resource ecs-world {
|
||||
constructor();
|
||||
|
||||
|
@ -76,6 +82,8 @@ interface ecs {
|
|||
/// Returns: A row of components serialized as bytes. The buffer is tighly packed.
|
||||
view-one: func(en: entity, component-infos: list<component-info>) -> option<list<u8>>;
|
||||
|
||||
get-resource: func(type-id: wasm-type-id) -> world-resource-result;
|
||||
|
||||
//with_system: func(stage: string, component-infos: list<component-info>, system: func(components: list<u8>));
|
||||
}
|
||||
}
|
|
@ -462,8 +462,8 @@ async fn main() -> wasmtime::Result<()> {
|
|||
);
|
||||
|
||||
// Load the component from disk
|
||||
let bytes = std::fs::read("target/wasm32-wasip1/debug/witguest-component.wasm")?;
|
||||
//let bytes = std::fs::read("guests/csharp/dotnet-guest-test/bin/Debug/net9.0/wasi-wasm/native/dotnet-guest-test.wasm")?;
|
||||
//let bytes = std::fs::read("target/wasm32-wasip1/debug/witguest-component.wasm")?;
|
||||
let bytes = std::fs::read("guests/csharp/dotnet-guest-test/bin/Debug/net9.0/wasi-wasm/native/dotnet-guest-test.wasm")?;
|
||||
let component = wasmtime::component::Component::new(&engine, bytes)?;
|
||||
|
||||
let (script_en, (world_res_a, world_res_b)) = {
|
||||
|
|
Loading…
Reference in New Issue