namespace Ghost.Core; public interface IHandleType; public interface IIdentifierType; public interface IKeyType; public readonly struct Handle : IEquatable> where T : IHandleType { public readonly int id; public readonly int generation; public Handle(int id, int generation) { this.id = id; this.generation = generation; } public static Handle Invalid => new(-1, -1); public readonly bool IsValid => this != Invalid; public readonly bool IsNotValid => this == Invalid; public readonly override int GetHashCode() { return id + (generation << 16); } public readonly override bool Equals(object? obj) { return obj is Handle id && Equals(id); } public override string ToString() { return $"Handle<{typeof(T).Name}>({id}, {generation})"; } public readonly bool Equals(Handle other) { return id == other.id; } public readonly int CompareTo(Handle other) { return id.CompareTo(other.id); } public static bool operator ==(Handle a, Handle b) { return a.Equals(b); } public static bool operator !=(Handle a, Handle b) { return !a.Equals(b); } } public readonly struct Identifier : IEquatable> where T : IIdentifierType { public readonly int value; public Identifier(int value) { this.value = value; } public static Identifier Invalid => new(-1); public readonly bool IsValid => this != Invalid; public readonly bool IsNotValid => this == Invalid; public readonly override int GetHashCode() { return value; } public readonly override bool Equals(object? obj) { return obj is Identifier id && Equals(id); } public override string ToString() { return $"Identifier<{typeof(T).Name}>({value})"; } public readonly bool Equals(Identifier other) { return value == other.value; } public readonly int CompareTo(Identifier other) { return value.CompareTo(other.value); } public static bool operator ==(Identifier a, Identifier b) { return a.Equals(b); } public static bool operator !=(Identifier a, Identifier b) { return !a.Equals(b); } public static bool operator <(Identifier a, Identifier b) { return a.value < b.value; } public static bool operator >(Identifier a, Identifier b) { return a.value > b.value; } public static bool operator <=(Identifier a, Identifier b) { return a.value <= b.value; } public static bool operator >=(Identifier a, Identifier b) { return a.value >= b.value; } public static implicit operator int(Identifier id) => id.value; public static implicit operator Identifier(int value) => new Identifier(value); } public readonly struct Key where T : IKeyType { public readonly ulong value; public Key(ulong value) { this.value = value; } public static Key Invalid => new(0); public bool IsValid => this != Invalid; public readonly override int GetHashCode() { return value.GetHashCode(); } public readonly override bool Equals(object? obj) { return obj is Key id && Equals(id); } public readonly bool Equals(Key other) { return value == other.value; } public readonly int CompareTo(Key other) { return value.CompareTo(other.value); } public static bool operator ==(Key a, Key b) { return a.Equals(b); } public static bool operator !=(Key a, Key b) { return !a.Equals(b); } }