csharp: implement ecs world resources
This commit is contained in:
parent
1d97046195
commit
3245b4dad4
|
@ -1,39 +1,10 @@
|
||||||
namespace ExampleWorld;
|
namespace ExampleWorld;
|
||||||
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using ExampleWorld.wit.imports.lyra.api;
|
using ExampleWorld.wit.imports.lyra.api;
|
||||||
using LyraApi;
|
|
||||||
using LyraApi.Ecs;
|
using LyraApi.Ecs;
|
||||||
|
using LyraApi.Engine;
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
using LyraApi.Math;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ExampleWorldImpl : IExampleWorld
|
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);
|
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)
|
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);
|
IEcs.EcsDynamicView dynamicView = Inner.View(infos);
|
||||||
return new ViewResult(comps, dynamicView).Get<T1>();
|
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>
|
</PropertyGroup>
|
||||||
|
|
||||||
<!-- Copy WIT files from LyraApi to lyra-api wit folder. -->
|
<!-- Copy WIT files from LyraApi to lyra-api wit folder. -->
|
||||||
<!-- <Target Name="CopyFolderOnBuild" BeforeTargets="WitCompile_InvokeTool">
|
<Target Name="CopyFolderOnBuild" BeforeTargets="WitCompile_InvokeTool">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<MyFiles Include="..\LyraApi\wit\**\*.wit" />
|
<MyFiles Include="..\..\rust\common-api\wit\**\*.wit" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Copy SourceFiles="@(MyFiles)" DestinationFolder="wit\deps\lyraapi\%(RecursiveDir)" />
|
<Copy SourceFiles="@(MyFiles)" DestinationFolder="wit\deps\lyraapi\%(RecursiveDir)" />
|
||||||
</Target> -->
|
</Target>
|
||||||
|
|
||||||
<!-- Remove bindgen of LyraApi WIT .-->
|
<!-- Remove bindgen of LyraApi WIT .-->
|
||||||
<!-- <Target Name="RemoveBindgenLyraApi" AfterTargets="WitCompile_InvokeTool">
|
<!-- <Target Name="RemoveBindgenLyraApi" AfterTargets="WitCompile_InvokeTool">
|
||||||
|
|
|
@ -37,6 +37,12 @@ interface ecs {
|
||||||
next: func() -> option<tuple<entity, list<u8>>>;
|
next: func() -> option<tuple<entity, list<u8>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variant world-resource-result {
|
||||||
|
none,
|
||||||
|
wasm-resource-rep(u32),
|
||||||
|
bytes(list<u8>),
|
||||||
|
}
|
||||||
|
|
||||||
resource ecs-world {
|
resource ecs-world {
|
||||||
constructor();
|
constructor();
|
||||||
|
|
||||||
|
@ -76,6 +82,8 @@ interface ecs {
|
||||||
/// Returns: A row of components serialized as bytes. The buffer is tighly packed.
|
/// 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>>;
|
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>));
|
//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
|
// Load the component from disk
|
||||||
let bytes = std::fs::read("target/wasm32-wasip1/debug/witguest-component.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 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 component = wasmtime::component::Component::new(&engine, bytes)?;
|
||||||
|
|
||||||
let (script_en, (world_res_a, world_res_b)) = {
|
let (script_en, (world_res_a, world_res_b)) = {
|
||||||
|
|
Loading…
Reference in New Issue