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.

73 lines
2.6 KiB

using System;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;
public unsafe struct Id<TContext>
: IEquatable<Id<TContext>>
{
public readonly World<TContext> World;
public readonly Id Value;
public IdFlags Flags => Value.Flags;
public bool IsPair => Value.IsPair;
public bool IsWildcard => Value.IsWildcard;
public bool IsValid => ecs_id_is_valid(World, this);
public bool IsTag => ecs_id_is_tag(World, this);
public bool IsInUse => ecs_id_in_use(World, this);
public int Count => ecs_count_id(World, this);
private Id(World<TContext> world, Id id)
{ World = world; Value = id; }
public static Id<TContext> GetUnsafe(World<TContext> world, Id value)
=> new(world, value);
public static Id<TContext>? GetOrNull(World<TContext> world, Id value)
=> ecs_id_is_valid(world, value) ? new(world, value) : null;
public static Id<TContext> GetOrThrow(World<TContext> world, Id value)
=> ecs_id_is_valid(world, value) ? new(world, value) : throw new InvalidOperationException($"The id {value} is not valid");
public Entity<TContext>? AsEntity()
=> !IsPair ? World.LookupAliveOrNull(new Entity(new() { Data = Value })) : null;
public (Entity<TContext> Relation, Entity<TContext> Target)? AsPair()
=> IsPair && (World.LookupAliveOrNull(Value.RelationUnsafe) is Entity<TContext> relation) &&
(World.LookupAliveOrNull(Value.TargetUnsafe ) is Entity<TContext> target )
? (relation, target) : null;
public bool Equals(Id<TContext> other)
{
#if DEBUG
// In DEBUG mode, we additionally check if the worlds the two compared
// values are from the same world. This accounts for the world being a
// stage, hence why it might not be the cheapest operation.
if (World != other.World) throw new ArgumentException(
"The specified values are not from the same world");
#endif
return Value == other.Value;
}
public override bool Equals(object? obj)
=> (obj is Id<TContext> other) && Equals(other);
public override int GetHashCode()
=> Value.GetHashCode();
public override string? ToString()
=> ecs_id_str(World, this).FlecsToStringAndFree()!;
public static bool operator ==(Id<TContext> left, Id<TContext> right) => left.Equals(right);
public static bool operator !=(Id<TContext> left, Id<TContext> right) => !left.Equals(right);
public static implicit operator Id (Id<TContext> id) => id.Value;
public static implicit operator ecs_id_t(Id<TContext> id) => id.Value.Value;
public static implicit operator Term(Id<TContext> id) => new(id.Value);
}
[Flags]
public enum IdFlags : ulong
{
Pair = 1ul << 63,
Override = 1ul << 62,
Toggle = 1ul << 61,
And = 1ul << 60,
}