Alternative managed wrapper around flecs-cs bindings for using the ECS framework Flecs in modern .NET.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
2.1 KiB

using System;
using System.Runtime.InteropServices;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;
public unsafe struct World
: IEquatable<World>
, IDisposable
{
public ecs_world_t* Handle { get; }
public bool IsDeferred => ecs_is_deferred(this);
public bool IsQuitRequested => ecs_should_quit(this);
public World(ecs_world_t* handle)
=> Handle = handle;
public World(params string[] args)
{
[UnmanagedCallersOnly]
static void Abort() => throw new FlecsAbortException();
ecs_os_set_api_defaults();
var api = ecs_os_get_api();
api.abort_ = new FnPtr_Void { Pointer = &Abort };
ecs_os_set_api(&api);
if (args?.Length > 0) {
var ptr = Runtime.CStrings.CStringArray(args);
Handle = ecs_init_w_args(args.Length, ptr);
for (var i = 0; i < args.Length; i++)
Marshal.FreeHGlobal(ptr[i]);
} else {
Handle = ecs_init();
}
}
public bool Progress(TimeSpan delta)
=> ecs_progress(this, (float)delta.TotalSeconds);
public void Quit()
=> ecs_quit(this);
public void Dispose()
=> ecs_fini(this);
public Entity LookupAlive(Entity value)
=> new(ecs_get_alive(this, value));
public Entity LookupPath(EntityPath path, Entity parent = default,
bool throwOnNotFound = false)
=> new(EntityPath.Lookup(this, path, parent, throwOnNotFound));
// TODO: Provide overload that uses a UTF-8 byte span?
public Entity LookupSymbol(string symbol)
{
using var alloc = TempAllocator.Use();
return new(ecs_lookup_symbol(this, alloc.AllocateCString(symbol), false));
}
public bool Equals(World other)
{
if (Handle == other.Handle) return true;
return ecs_get_world((ecs_poly_t*)Handle)
== ecs_get_world((ecs_poly_t*)other.Handle);
}
public override bool Equals(object? obj)
=> (obj is World other) && Equals(other);
public override int GetHashCode()
=> ((nint)ecs_get_world((ecs_poly_t*)Handle)).GetHashCode();
public static bool operator ==(World left, World right) => left.Equals(right);
public static bool operator !=(World left, World right) => !left.Equals(right);
public static implicit operator ecs_world_t*(World w) => w.Handle;
}