using System; using static flecs_hub.flecs; namespace gaemstone.ECS; public readonly struct Identifier : IEquatable { public readonly ecs_id_t Value; public bool IsPair => ecs_id_is_pair(Value); public bool IsWildcard => ecs_id_is_wildcard(Value); public IdentifierFlags Flags => (IdentifierFlags)(Value & ECS_ID_FLAGS_MASK); public Entity RelationUnsafe => new(new() { Data = (Value & ECS_COMPONENT_MASK) >> 32 }); public Entity TargetUnsafe => new(new() { Data = Value & ECS_ENTITY_MASK }); public Identifier(ecs_id_t value) => Value = value; public static Identifier Combine(IdentifierFlags flags, Identifier id) => new((ulong)flags | id.Value); public static Identifier Pair(Entity relation, Entity target) => Combine(IdentifierFlags.Pair, new( ((relation.Value.Data << 32) & ECS_COMPONENT_MASK) | ( target.Value.Data & ECS_ENTITY_MASK ))); public (EntityRef Relation, EntityRef Target)? AsPair(Universe universe) => new IdentifierRef(universe, this).AsPair(); public bool Equals(Identifier other) => Value.Data == other.Value.Data; public override bool Equals(object? obj) => (obj is Identifier other) && Equals(other); public override int GetHashCode() => Value.Data.GetHashCode(); public override string? ToString() => (Flags != default) ? $"Identifier(0x{Value.Data:X}, Flags={Flags})" : $"Identifier(0x{Value.Data:X})"; public static bool operator ==(Identifier left, Identifier right) => left.Equals(right); public static bool operator !=(Identifier left, Identifier right) => !left.Equals(right); public static implicit operator ecs_id_t(Identifier i) => i.Value; } [Flags] public enum IdentifierFlags : ulong { Pair = 1ul << 63, Override = 1ul << 62, Toggle = 1ul << 61, Or = 1ul << 60, And = 1ul << 59, Not = 1ul << 58, }